VirtualBox(Host OS=Mountain Lion, Guest OS=Ubuntu 12.04)上でArduino UNOと通信する方法

長ったらしいタイトルだが、すっかりハマってしまったのと、かなり特殊な事例のようなので書き残しておく。
まず、目的を述べておくと、MacBookAir上のMountain Lionで動作させたVirtualBox上のUbuntu 12.04LTSで、Arduino UNOのプログラムを開発できるようにすること。なんでこんなことをしたいかというと、Ubuntu上でROSを動かしており、rosserialでArduinoと通信させたいからである。
当初は簡単に思えたが、結構ハマって時間がかかってしまった。
最初に思いついたのは、VirtualBoxの方でUSBコントローラを生かしておき、ArduinoのUSBデバイスをUbuntu側で認識させるというもの。このやり方だと認識はうまくいきUbuntu側のArduino IDEでコンパイルまではうまくいくものの、プログラムを転送する段になってエラーで止まってしまう。
ググってみても解決方法は見当たらないので、別の方法を試すことにした。
次の案は、VirtualBoxの仮想シリアルポートの機能を使うこと。VirtualBox VMの設定を見回したところ、シリアルポートを有効化して「ホストデバイス」なる指定を行うとうまくいきそうな感じである。実際、Host=Windowsであればうまくいく例もあるようだ。
Macの場合、シリアルポートのポート1を有効化してポートモードをホストデバイスに切り替え、ポート/ファイルパスを「/dev/cu.usbmodem621」に設定したところ、みごとUbuntuで/dev/ttyS0として認識され、問題なくプログラムが転送されるようになった。
ハマったのは最初はMac上のArduino IDEで認識される「/dev/tty.usbmodem621」を設定したところ、VirtualBox VMが起動せずにフリーズする現象にあったことだ。まだcuとttyの違いがよくわからない。
なお、621という数値部分は環境によって変わるかもしれない。うまくいかなければターミナル等で「ls /dev/cu.*」を実行して似たようなのを探すべきだろう。
とりあえずすっきりした。rosserialについては別記事にまとめる予定。

MacでArduinoを使う(2)

久しぶりにMacでArduinoを使うべく、ソフトウェアのインストールを行った。

ダウンロードとインストール

Arduinoのサイトで、Downloadの欄のMac OS Xをクリックし、zipファイル(現時点では、arduino-1.0.4-macosx.zip)をダウンロードする。
次にzipファイルをダブルクリックして解凍し、生成されたArduinoというファイルをアプリケーションにコピーする。
アプリケーションフォルダのArduinoファイルをダブルクリックして起動すると、すぐには起動せずにアップデートの確認ダイアログが現れて、Java for Mac OS Xがインストールされた。確認ダイアログをOKした後でArduinoが起動した。

Arduinoの接続

起動したArduinoを終了させ、USBケーブルでArduinoとMacを接続する。本来だとここでネットワーク接続のダイアログが出るはずだが、何もでない。ネットワーク環境設定の画面を開くと、既にArduino Unoのエントリが作成されていた。多分、以前に導入したときのものがTimeMachineのバックアップに残っていたのだろう。
スクリーンショット 2013-04-06 22.47.37
Arduinoを起動するとArduino Uno on COM1と表示されている。ファイルメニューから、スケッチの例 – 01.Basics – Blinkを選んでサンプルのスケッチを開き、上段にある右向きの矢印(マイコンボードに書き込む)をクリックすると、COM1が見つからないとのエラーメッセージとともにデバイス選択のダイアログが現れた。
スクリーンショット 2013-04-06 22.46.01
(画面はエラーを再現すべくケーブルを抜いた後で転送させたときのもの)
どれが正しいのかわからなかったが、勘で /dev/tty.usbmodem411 を選んだら接続されてスケッチが転送され、Arduino上でプログラムが動き出してオレンジ色のLEDが点滅を繰り返し始めた。

rosbridge経由でPharo 2.0からROSに接続する

PharoからROSに接続するのに、以前はrospharoというパッケージを作っていたが、古いバージョン用(diamondback)でありアップデートも面倒臭いので、今回はrosbridgeを用いて接続することにした。rosbridge V2.0ではWebSocketを用いて接続するので、Pharo 2.0から接続するには両者のインストールが必要となる。
rosbridgeとWebSocketのセットアップは以下にある。

rosbridgeのサイトではChromiumブラウザのWebSocket接続機能を使って動作確認を行っているが、やはりPharoerとしてはPharoから動作確認したい。そこで、まずROS側で適当なTopicをPublishしておいて、それをPharo側でSubscribeして動作確認することにした。以下、ROS側とPharo側で分けて説明する。

ROS側の作業

前述のrosbridgeの導入の通り、roscoreおよびrosbridgeを起動しておく。
turtle_teleop_keyは、タートルグラフィックスシミュレータのタートルをカーソルキーで操作するためのNodeである。手近なところでPublishできるノードを思いつかなかったので、これを使うことにした。
別のターミナルなどを用いてturtle_teleop_keyを起動する。
rosrun turtlesim turle_teleop_key
更に別のターミナルなどで以下を入力する。
$ rostopic list
/rosout
/rosout_agg
/turtle1/command_velocity

/turtle1/command_velocityというトピックが現れているのがわかる。以下を入力してどんなメッセージかを調べる。
$ rostopic type /turtle1/command_velocity
turtlesim/Velocity

/turtle1/command_velocityトピックではturtlesim/Velocityというメッセージが使われている。より詳細に調べるには以下のようにする。
$ rosmsg show turtlesim/Velocity
float32 linear
float32 angular

turtlesim/Velocityメッセージは、2個のfloat32型変数linear, angularで構成されていることがわかる。
ちゃんとturtlesim/Velocityメッセージが来るかどうかチェックする。
$ rostopic echo /turtle1/command_velocity
ここで、turle_teleop_keyを起動したターミナルでカーソルキーを入力する。上下左右のカーソルキーを順に入力すると、ターミナルに以下のように表示される。
$ rostopic echo /turtle1/command_velocity
linear: 2.0
angular: 0.0
---
linear: -2.0
angular: 0.0
---
linear: 0.0
angular: 2.0
---
linear: 0.0
angular: -2.0
---

Pharo側の作業

WebSocketをインストールしたPharoを起動し、適当なワークスペースを開き、以下を入力する。なお、以下の説明ではrosbridgeの動いているPCのIPアドレスを192.168.254.68としている。
rs := ZnWebSocket to: 'ws://192.168.254.68:9090'.
rs sendMessage: '{"op": "subscribe", "topic": "\/turtle1\/command_velocity", "type": "turtlesim\/Velocity"}'.

1行目でrosbridgeへWebSocket経由で接続している。2行目では/turtle1/command_velocityトピックをSubscribeしている。このときメッセージタイプも指定している。なお、rosbridgeとのやりとりにはJSON形式のデータを送る。
上記をDo itすると、rosbridgeのターミナルに以下のようなログが出力される。
[INFO] [WallTime: 1363827799.919737] [Client 0] Subscribed to /turtle1/command_velocity
続いてワークスペースで以下を入力してPrint itする。
rs readMessage.
タイムアウトになる前にturle_teleop_keyのターミナルに戻って、上カーソルキーを押すとPrint itの結果が表示される。
'{"topic":"\/turtle1\/command_velocity","msg":{"linear":2.0,"angular":0.0},"op":"publish"}'
opコードにpublishが、msgにlinearとangularの値が入ったJSON形式のデータが返ってくる。
トピックのsubscribeをやめ、rosbridgeとの接続を解除するには以下のようにする。
rs sendMessage: '{"op": "unsubscribe", "topic": "\/turtle1\/command_velocity"}'.
rs close.

ちゃんとrosbridge経由で通信できることが確認できた。

Pharo 2.0にWebSocketをインストールする

rosbridgeとの接続にはWebSocketを用いるのでWebSocketをPharoにインストールする。
WebSocketはZincのパッケージにあるが、Pharo 2.0のデフォルトの配布パッケージには入っていないので別途インストールする。
Monticelloを起動して+RepositoryでHTTPを選び、以下を入力する。
MCHttpRepository
location: 'http://www.squeaksource.com/ZincHTTPComponents'
user: ''
password: ''

Openでリポジトリを開き、左側のペインからZinc-WebSocket-CoreとZinc-WebSocket-Testsを選んで最新版をLoadする。
とりあえずテストして動作確認する。
(proxy環境だと一部のテストに失敗するが気にしない)

rosbridge V2.0の導入

ROSにrosbridgeを導入する。最近はV2.0に移行しており以前のものとはプロトコルが異なるとともに、WebSocketに対応している。
2013-5-10追記
rosbridge v2.0はROSの正式なパッケージとなったようだ。
http://ros.org/wiki/rosbridge_suite
導入手順は簡単で、以下だけでOK。
sudo apt-get install ros-groovy-rosbridge-server
rosbridgeサーバーの起動は少し変わって以下のようになった。
roslaunch rosbridge_server rosbridge_websocket.launch
以下の情報は古い
ROS/groovyをインストールしたマシン上にrosbridgeをインストールする。手順は以下のサイトを参考にした。
http://rosbridge.org/doku.php?id=downloading_rosbridge
あらかじめrosパッケージ用のディレクトリを作成し、パッケージのPATHも通しておく。
mkdir ~/ros
export ROS_PACKAGE_PATH=~/ros:$ROS_PACKAGE_PATH

gitで最新のソースツリーを取り込む。
git clone http://kforge.ros.org/rosbridge/git rosbridge
makeする。
rosmake rosbridge
以上でrosbridgeのパッケージが作成される。
動作確認のためにrosbridgeサーバーを起動する。
roscore &
rosrun rosbridge_server rosbridge.py

起動すると以下のようなメッセージが表示される。
[INFO] [WallTime: 1363825226.008247] Rosbridge server started on port 9090
続いてクライアント側を整備して接続を行ってみる。

Kinectの画像を得る(2)

あらためてTurtleBotに積んだKinectと格闘する。ググってみたら良さそうな例があったので試してみた。
http://bi.snu.ac.kr/Courses/4ai12s/Projects/KinectWithROSTutorial.pdf
上記に書かれていたopenni-launchというパッケージがインストールされていなかったので、インストールする。
apt-get install ros-groovy-openni-launch
書かれているとおりにopenni_launchを起動する。
roslaunch openni_launch openni.launch
モニタ用のPCから以下を起動する。
rosrun image_view image_view image:=/camera/rgb/image_color
すると、Kinectのカメラによるカラー画像が表示された。
続いて、以下を起動する。
rosrun image_view disparity_view image:=/camera/depth_registered/disparity
今度はdepth画像が表示された。前に試したやり方ではregisteredの画像が表示できなかったのだが、あっさりと表示された。
kinectview
先ほどのドキュメントの最後の方にrvizは便利だけど不安定でバギーだから気をつけろと書いてあった。うまくいかなかったのがそのせいなのかはわからないが、とりあえずKinectもちゃんと動くことを確認できて一安心。
そろそろちゃんとロボットのプログラムを書き始めよう。

SimpleGraphと簡単なドキュメントを公開しました

SmalltalkHubにSimpleGraphの最初のリリースを公開しました。
http://smalltalkhub.com/#!/~EiichiroIto/SimpleGraph
また、公開にあわせてインストール方法と簡単な使い方について説明したドキュメントも公開しました。

ご意見、ご要望、ご質問などはtwitter(https://twitter.com/razdan3)にてお願いいたします。

Kinectの情報を得る

TurtleBotにはKinectが接続されている。本体の動作に成功してからずっと、Kinectの画像を表示させようと試みていたが、全てうまくいかなかった。ASUS Xtion Proでも試してみても同じ。トラブルシューティングをググってもほとんど似たケースはなかった。そこで、思い切ってubuntuのバージョンを12.10から12.04LTSに落としてみたら、うまくRGB画像が表示されるようになった。
12.10のときはlsusbでKinectのMotorしか認識されなかったのだが、12.04LTSに変更したら3つのデバイスが表示されるようになった。おそらくOSが原因でKinectの認識に失敗していたのだろう。当面、12.04LTSを使うことにする。
Kinectを動作させるには、https://ros.org/wiki/turtlebot_bringup/Tutorials/groovy/3D%20Visualisationを参考にコマンドを入力すればよい。表示されるrVizの画面でImageにチェックを入れたらRGB画像が表示される。ただし、Laser ScanやDepthCloudにチェックを入れても何も表示されない。まだどこかおかしいようだ。先は長い。