Help us understand the problem. What is going on with this article?

Docker + ROS(kinetic)でチュートリアル

More than 1 year has passed since last update.

なにするの

ここでは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と同じディレクトリに作成しましょう。

docker-compose.yml
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までやってくれます!

参考文献

Leonardo-mbc
UX に興味ある LINE のフロントエンジニア
http://blog.leonardo-mbc.blue
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away