teruノート

ROSでロボットとか。Ubuntuで困ったこととか。

bluetooth PAN NAP構築(Ubuntu 16.04)

ロボコンの競技規則で無線通信はBluetoothのみという事態がルール補足情報により発覚し、WiFiでROSトピック飛ばそうと思っていた構想が砕け散りました。

bluetoothの仮想シリアルポートでrosserialノードを使用する手が真っ先に浮かびましたが、bluetoothでネットワークを作れないかと試行錯誤してみました。ドライバ壊してOS何度もインスコし直しました。

サーバ側、クライアント側でいろいろと準備が必要です。

試した環境は、サーバ側はUbuntu 16.04のPC、クライアント側はlubuntu 16.04のRaspberry Pi 3です。


Ubuntu 16.04でbluetoothのPAN(Personal area network)を使うには、bluemanの最新版をソースからビルドする必要があります。
(パッケージ化されている2.0.4でもサポートされているみたいですが、IPアドレスの取得ができず接続失敗となります…)

ここからソースをダウンロードして適当な場所に解凍 or cloneします。
github.com


こんな流れ↓でビルドするんですが、autogenやconfigureであれが足りないこれが足りないと言われるので逐次インストールします。
ソースに入っているDependencies.mdに依存関係が載ってるので一通りインストールしたほうが近道ですね。

./autogen.sh
./configure
make
sudo make install

たとえばD-BUSがないと言われたらこれをインストールします。

sudo apt-get install libdbus-1-dev

Bluezがないと言われたら、libbluetooth-devをインストールします。bluezをインストールしただけではだめだったので、これがなかなか解決に時間かかりました。

sudo apt-get install libbluetooth-dev

ほかにもlibudev-devなどが必要だったと思います。

また、isc-dhcp-serverとudhcpdもインストールしておきます。


bluemanのインストールが終わったら、dashからbluetoothマネージャを起動します。

メニューのローカルサービスを開き、NAPを有効にします。DHCPサーバはudhcpdを選択します。
f:id:ub2_memo:20170301111133p:plain

あとは、ペアリングをすればネットワークアクセスポイントとして接続できるようになります。


接続が確立したらifconfigで確認します。

サーバ側はpan1というブリッジにIPが振られ、クライアント側はbnep0デバイスにIPが振られているのでそれを確認し、pingでも飛ばしてみましょう。


なぜかssh接続しようと思ったらうまくいかなかった。LAN経由でもできなくなってた。

bluetoothドライバ壊してUbuntu入れなおしたりしたんですが、なぜかsshインストールしたらssh使えるようになりました。
今まで特に何もせず使えてたはずでしたが…。


ともかく、bluetoothでネットワークを構築し、ROSのトピックも飛んだのでなによりです!

STM32F429i-discoでrosserial

STM32F429i-discoはmbedに対応しているので、rosserial_mbedをインポートしてROSにつなげてみました。


mbed IDEでrosserial_mbedをインポートして、ローカルのSW4STM32で開発しています。

joyトピックをsubscribeするコードを書いてみます。

肝心のSTM側のシリアルポートは、デフォルトでUSART1(PA9,PA10), 57600bpsで初期化されます。
このコードではボーレートを921600に変更しています。sensor_msgs::Joy型のサイズが意外と大きく、57600bpsだと遅延がかなり感じられます。

  ros::NodeHandle nh;
  ros::Subscriber<sensor_msgs::Joy> sub("joy", &joy_callback);
  nh.getHardware()->setBaud(921600);
  nh.initNode();
  nh.subscribe(sub);

  while(1) {
    nh.spinOnce();
  }

トピックが送られてきた時に呼び出されるcallback関数は、とりあえずボタンの情報をLCDに表示するものにしました。

void joy_callback(const sensor_msgs::Joy &joy)
{
	int button_size = joy.buttons_length;
	char time_stamp[128];
	for(int i=0; i<button_size; i++) {
		if(joy.buttons[i]) {
			lcd.DisplayStringAt(lcd.GetFont()->Width * i, LINE(3), (uint8_t *)"1", LEFT_MODE);
		}
		else {
			lcd.DisplayStringAt(lcd.GetFont()->Width * i, LINE(3), (uint8_t *)"0", LEFT_MODE);
		}
	}
	sprintf(time_stamp, "%d", (int)joy.header.stamp.sec);
	lcd.DisplayStringAt(0, LINE(4), (uint8_t *)time_stamp, LEFT_MODE);

}

ROS側では、roscoreを起動してからまずrosserialノードを起動します。デフォルトのポートはttyUSB0です。

rosrun rosserial_python serial_node.py _baud:=921600

接続されると、STMのsubscriberの情報が表示されます。

[INFO] [1485587675.953141]: ROS Serial Python Node
[INFO] [1485587675.968201]: Connecting to /dev/ttyUSB0 at 921600 baud
[INFO] [1485587678.111717]: Note: subscribe buffer size is 512 bytes
[INFO] [1485587678.112621]: Setup subscriber on joy [sensor_msgs/Joy]

あとはDualshock3などジョイスティックデバイスをPCに接続し、joyノードを起動すればSTM側にsensor_msgs::Joy型のトピックが届きます!

rosrun joy joy_node 

Ubuntu 16.04でeclipseが異常にCPUを占有する

Ubuntu 16.04にeclipseベースのSystem workbench for STM32をインストールしたところ、異常に重くてほとんど使えませんでした。

topコマンドで調べるとjavaプロセスがCPUをほぼ100%使っている状態でした。


解決策はここで見つかりました。GTK3に起因するバグらしいです。

askubuntu.com

eclipse.iniを開き、--launcher.appendVmargsの行より上に次の2行を追加します。

--launcher.GTK_version
2


これでようやくPCもおとなしくなりました…