DockerでROSを試したい
ROSのインストールが色々と面倒そうなので、Docker使うと手っ取り早いかな・・・と思いました。
ググってみると、日本語の良記事を見つけました。
この記事に書いてあることを基にしてROSの新しいバージョンであるjadeをコンテナで試そうとしました。
なお、環境はUbuntu 14.04 LTS、dockerは1.6.2です。
早速動かしてみる
まずはdocker imageをpullしてきます。docker pullに限らず、dockerコマンド使うときはユーザをdockerのgroupに所属させるか、sudo付けてdockerコマンドを実行するかしてください。
docker pull osrf/ros:jade-desktop-full
次に以下のdockerコマンドを使い、roscoreが動作するコンテナを起動します。
docker run -it --rm --name master --env ROS_HOSTNAME=master osrf/ros:jade-desktop-full roscore
... logging to /root/.ros/log/9e1cfde6-e859-11e5-aaef-0242ac110002/roslaunch-903e750fb602-1.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
Unable to contact my own server at [http://master:47759/].
This usually means that the network is not configured properly.
A common cause is that the machine cannot ping itself. Please check
for errors by running:
ping master
For more tips, please see
http://www.ros.org/wiki/ROS/NetworkSetup
The traceback for the exception was written to the log file
どうやらネットワーク周りでトラブっている様子。ROSのWikiを調べると、こんなQ&Aを見つけました。
ところが、ここに書かれている方法では、確かにroscoreは動くものの、先ほどの記事に書かれているtalkerとlistener(ROSのノード)が動きません。
roscoreがlocalhostなので、talkerとlistenerがroscoreを見つけることができないためだと思われます。
実際にroscoreを実行させずにシェルだけ立ち上げて確認すると、コンテナのhostnameは意図したhostname(master)になっていません。
root@cd41badef483:/# hostname
cd41badef483
では、どうしたらよい?
先のQ&Aで問題になっているのは、「コンテナのhostnameが意図と異なるhostnameになっている」ことです。
なら、コンテナのhostnameを明示的に指定すれば良さそうです。
dockerのリファレンスを調べると「Similarly the operator can set the hostname with -h.」とあるので、以下のように-hオプションを追加します。
sudo docker run -h master -it --rm --name master --env ROS_HOSTNAME=master osrf/ros:jade-desktop-full roscore
これで、無事コンテナのhostnameがmasterになり、roscoreを立ち上げることができました。
ノード用のコンテナ立ち上げ
次のコンテナ(talkerノード分)を立ち上げると、以下のようなエラーメッセージを吐いてtalkerノードが意図通り動きません。
Couldn't find an AF_INET address for [master]
Couldn't find an AF_INET address for [master]
Couldn't find an AF_INET address for [master]
Couldn't find an AF_INET address for [master]
(以下同じ)
どうやらmasterの名前解決ができてない様子。dockerのリファレンスを見ると
--add-host="" : Add a line to /etc/hosts (host:IP)
と書いてありますので、以下のように--add-hostでmasterとそのIPアドレスを静的に指定して対応します。
sudo docker run --add-host="master:masterのIPアドレス" -h talker -it --rm --name talker --env ROS_HOSTNAME=talker --env ROS_MASTER_URI=http://master:11311 osrf/ros:jade-desktop-full talker
これで意図通り動きました。
最後は、listenerです。--add-hostするのはmasterだけでなく、talkerの分も必要になることに気をつけてください。
sudo docker run -it -h listener --add-host="master:masterのIPアドレス" --add-host="talker:talkerのIPアドレス" --rm --name listener --env ROS_HOSTNAME=listener --env ROS_MASTER_URI=http://master:11311 osrf/ros:jade-desktop-full listener
これでうまく動きました。次のステップに進めそうです。