ROS meets Docker

MacOS Yosemite上のDocker内のROSからArduinoにシリアル通信する。
ROSを使う時、apt-getとか使うとシステムがいっぱい汚れる。
辛みしかないのでDockerを使う。
ROSもpythonのvirtualenvみたいのあるよ!ってことなら教えて欲しいです。

Dockerをインストールする

基本的に公式に従う
Installation on Mac OS X

やることは下記からpkgを落としてきてインストールするだけ。
Release v1.5.0 · boot2docker/osx-installer · GitHub

boot2dockerのアイコンができるのでそれをクリックするとターミナルが立ち上がる。*1
VirtualBox上にboot2dockerという名前でLinuxが走るので、この上でゲストOSを走らせることになる。

USBの設定

このままではUSBが使えないので設定をする。

VirtualBox上からboot2dockerを終了させる

右クリック->閉じる->電源オフでいいと思います。

Extension Packをインストールする

下記からExtension Packをダウンロードしてきてインストールする。
Downloads – Oracle VM VirtualBox

boot2dockerの設定を変更する

VirtualBoxGUI上にあるUSBの項目のチェックボックスを入れる。
右のプラスアイコンからフィルターの項目を追加できる。
このフィルターというのが認識させるUSBデバイスになるので認識させたいデバイスを追加する。

Docker imageを作成する

ubuntuのイメージの取得

ゲストOSとしてubuntuを使用したいためこのイメージをダウンロードする。
boot2dockerのアイコンをクリックする。
立ち上がったbashから下記でimageをダウンロードする。

docker pull ubuntu:trusty

imageの一覧は下記になるので、欲しいバージョンに合わせて書き換えて欲しい。
Docker Hub

以下でローカルのimageの一覧が見れる。

docker images

ROS用imageの作成

適当なディレクトリにDockerfileというファイルを作る。
ファイルの中身は下記のように、imageの作成にあたり実行して欲しいスクリプトを書く。

# install ROS indigo
# based ubuntu 14.04 trusty
FROM ubuntu:trusty
 
# prepare install ROS
RUN apt-get update -q \
    && apt-get install -yq wget
 
# install ROS
RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
RUN wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add -
RUN apt-get update \
    && apt-get install -y ros-indigo-desktop-full \
    python-rosinstall
 
RUN rosdep init 
 
# vnc
RUN apt-get install -y x11vnc xvfb
# create passwd after create working user
 
# develop env
RUN apt-get install -y byobu \
    zsh \
    git
    
# create user
RUN adduser --disabled-password --gecos '' --shell `which zsh` rosuser
RUN adduser rosuser sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER rosuser
WORKDIR /home/rosuser
 
# user indivisual developing env
## vnc
RUN mkdir .vnc
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
 
# ros env
RUN rosdep update
RUN echo "source /opt/ros/indigo/setup.zsh" >> ~/.zshrc

このDockerfile内で全てやらないといけないかというとそうではなく、
docker commitしてもimageに反映されるのでそれだけで作っても良い。
ただ、秘伝のimageになるのを避けるため、なるべくDockerfileに書きましょう。

以下でhogeという名前のimageがDockerfileから作られる。

 docker build -t hogeimage .

プロセスの作成

USBを使いたいのでboot2dockerがUSBをどこで認識してるか確認する。
下記でboot2dockerの中に入れる。

boot2docker ssh

適当にls /dev/tty*とかでそれっぽいのを探す。
今回は/dev/ttyACM0でした。

以下でプロセスを作成する。
vnc用にportとUSB用にdeviceを指定している。
これでゲストOS上で/dev/ttyUSB0にUSBがマウントされる。

docker run -it -p 5900 --device=/dev/ttyACM0:/dev/ttyUSB0:rwm  --name hogeprocess hogeimage

実行するとゲストOSに入る。
rosuserでUSBを使いたいのでdeviceにchmodしておく。

chmod 666 /dev/ttyUSB0

ゲストOSから抜けるときはexitで抜けれる。
再度入りたいときでプロセスが生きている場合(docker ps -aして、まだいる場合)
下記で入れる。

docker start -i hogeprocess

Arudinoの準備

Arudino用のros_libを作成する。
rosserial_arduino/Tutorials/Arduino IDE Setup - ROS Wiki

docker cpでros_libをMacOSにコピー、Arudino IDEに読み込ませる。
ros_libの中にサンプルコードが入っているので、BlinkというのをArudinoに焼く。

通信

ほぼここに従う
rosserial_arduino/Tutorials/Blink - ROS Wiki

rosuserになって下記を実行する。*2*3

roscore
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0

ここでうまくいくとArudinoのRXとTXがチカチカし始める。
下記を実行するとNo13のLEDの付けたり消したりできる。

rostopic pub toggle_led std_msgs/Empty --once


この記事を書くためにboot2docker立ち上げたり落としてたりしたらプロセスに入れなくなった。
docker commitでイメージにしましょうという教訓を得た。

*1:byobu設定してるとターミナルがどっかいっちゃうのbyobuの自動起動解除しとくと良さそう

*2:別にrootでやっても良いですが…

*3:byobuとか使うと良い