dockerでROSを試したい

## DockerでROSを試したい
ROSのインストールが色々と面倒そうなので、Docker使うと手っ取り早いかな・・・と思いました。
ググってみると、[日本語の良記事](http://tech-sketch.jp/2015/10/ros-docker-1.html)を見つけました。

この記事に書いてあることを基にしてROSの新しいバージョンであるjadeをコンテナで試そうとしました。
なお、環境はUbuntu 14.04 LTS、dockerは1.6.2です。

## 早速動かしてみる
まずはdocker imageをpullしてきます。docker pullに限らず、dockerコマンド使うときはユーザをdockerのgroupに所属させるか、sudo付けてdockerコマンドを実行するかしてください。

```:imageをpullする
docker pull osrf/ros:jade-desktop-full
```

次に以下のdockerコマンドを使い、roscoreが動作するコンテナを起動します。

```:roscoreを動かす
docker run -it --rm --name master --env ROS_HOSTNAME=master osrf/ros:jade-desktop-full roscore
```

```text:実行結果
... 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](http://answers.ros.org/question/201225/roscore-fails-to-start/)を見つけました。

ところが、ここに書かれている方法では、確かにroscoreは動くものの、[先ほどの記事](http://tech-sketch.jp/2015/10/ros-docker-1.html)に書かれているtalkerとlistener(ROSのノード)が動きません。
roscoreがlocalhostなので、talkerとlistenerがroscoreを見つけることができないためだと思われます。

実際にroscoreを実行させずにシェルだけ立ち上げて確認すると、コンテナのhostnameは意図したhostname(master)になっていません。

```
root@cd41badef483:/# hostname
cd41badef483
```

## では、どうしたらよい？
先のQ&Aで問題になっているのは、「コンテナのhostnameが意図と異なるhostnameになっている」ことです。
なら、**コンテナのhostnameを明示的に指定**すれば良さそうです。

[dockerのリファレンス](https://docs.docker.com/engine/reference/run/)を調べると「Similarly the operator can set the hostname with -h.」とあるので、以下のように-hオプションを追加します。

```:hostnameを指定してrun
sudo docker run -h master -it --rm --name master --env ROS_HOSTNAME=master osrf/ros:jade-desktop-full roscore
```

これで、無事コンテナのhostnameがmasterになり、roscoreを立ち上げることができました。

## ノード用のコンテナ立ち上げ
次のコンテナ(talkerノード分)を立ち上げると、以下のようなエラーメッセージを吐いてtalkerノードが意図通り動きません。

```text:実行結果
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のリファレンス](https://docs.docker.com/engine/reference/run/)を見ると

```
--add-host=""    : Add a line to /etc/hosts (host:IP)
```

と書いてありますので、以下のように--add-hostでmasterとそのIPアドレスを静的に指定して対応します。

```:add-host(talkerノード実行)
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の分も必要になることに気をつけてください。

```:add-host(listenerノード実行)
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
```

これでうまく動きました。次のステップに進めそうです。