なにするの
ここではDockerをつかって、ROSのチュートリアルを動かしてみようと思います。
ROSをDocker上で動かすメリットとしては、以下があります。
- OSの環境を汚さない
- Dockerさえ動いていれば、環境/マシンが変わっても動作できる
デメリットとしては以下の問題もあります。
- マシンのリソースをフルに使えない
Docker上でROSを動作させることに魅力を感じるのであれば、この記事に納得できると思います!
チュートリアルでやること
master
, talker
, listener
の3つを動作させて、
talkerが発するメッセージをlistenerが聞くだけです。
もちろん、talkerとlistenerだけがいてもメッセージのやり取りはできないのでmasterが必要ですね。
まずはdockerイメージのpullから
docker pull ros:kinetic
ドキュメント: https://hub.docker.com/r/_/ros/
pullするのはros
だけでも良いです。
たくさんのtagが用意されているので、お好きなディストリビューションのrosを入れましょう。
(kineticは2016/11/13現在で最新)
tutorialsファイルをインストール
Dockerfileを作ってbuildします。
FROM ros:kinetic
# install ros tutorials packages
RUN apt-get update && apt-get install -y
RUN apt-get install -y ros-kinetic-ros-tutorials \
ros-kinetic-common-tutorials \
&& rm -rf /var/lib/apt/lists/
注意:
インストールするチュートリアルのパッケージは、
ROSのディストリビューションによって名前が違います。
上のDockerfile
の例ではros-kinetic-ros-tutorials
というようにkinetic
のものをインストールしています。
indigoならindigoのものに書き換えましょう。
チュートリアルのインストールができたイメージは、元のイメージと区別するためにros-tutorials
というtagをつけます。
docker build --tag ros:ros-tutorials .
Dockerのネットワークを作成
これから動かすmaster
, talker
, listener
を同じネットワークに入れたいです。
ここではrosnet
という名前でネットワークを作っておきましょう。
docker network create rosnet
起動してみましょう!
masterを起動
hostをmasterにする必要があるため-h master
をつけます。
また、--net rosnet
で先程つくったネットワークに所属させましょう。
docker run -it --rm --net rosnet --name master ros:ros-tutorials roscore
talkerを起動
masterとほぼ同じです。
docker run -it --rm --net rosnet --name talker --env ROS_HOSTNAME=talker --env ROS_MASTER_URI=http://master:11311 ros:ros-tutorials rosrun roscpp_tutorials talker
こんな出力が出ると思います
[ INFO] [1478972564.886917267]: hello world 0
[ INFO] [1478972564.987402593]: hello world 1
[ INFO] [1478972565.087038287]: hello world 2
[ INFO] [1478972565.187424574]: hello world 3
[ INFO] [1478972565.289820280]: hello world 4
[ INFO] [1478972565.388935922]: hello world 5
...
listenerを起動
docker run -it --rm --net rosnet --name listener --env ROS_HOSTNAME=listener --env ROS_MASTER_URI=http://master:11311 ros:ros-tutorials rosrun roscpp_tutorials listener
先にtalkerを起動していれば、talkerのメッセージを受信して、
こんな出力が出ると思います。
[ INFO] [1478972565.088147030]: I heard: [hello world 2]
[ INFO] [1478972565.189187089]: I heard: [hello world 3]
[ INFO] [1478972565.291535690]: I heard: [hello world 4]
[ INFO] [1478972565.390682548]: I heard: [hello world 5]
...
これで疎通は確認できました!
チュートリアルとしては以上です、あとは自身のプログラムに載せ替えましょう!
おまけ:Docker Composeする
同じマシンですべて起動するなら、docker-composeでぱぱっとやってしまうこともできます
docker-composeするとネットワークも自動でつくられ、全てのコンテナが作られたネットワークに入れられます。
以下のようなymlファイルをDockerfileと同じディレクトリに作成しましょう。
version: '2'
services:
master:
build: .
container_name: master
command:
- roscore
talker:
build: .
container_name: talker
environment:
- "ROS_HOSTNAME=talker"
- "ROS_MASTER_URI=http://master:11311"
command: rosrun roscpp_tutorials talker
listener:
build: .
container_name: listener
environment:
- "ROS_HOSTNAME=listener"
- "ROS_MASTER_URI=http://master:11311"
command: rosrun roscpp_tutorials listener
作成できたら、
docker-compose up
でdocker build
からrun
までやってくれます!