本日は、ROS Japan UG #11 LT大会で私が発表したROS 2とDockerのエコシステムを組み合わせて実験したフォールトトレランスの実験結果を取り上げます。 発表資料のアップロードが遅れてすみません。もう少しお待ちください。

https://rosjp.connpass.com/event/58755/

具体的にはDockerの異常終了時、自動再起動オプションを使って実現しています。

https://docs.docker.com/engine/admin/start-containers-automatically/

準備

まずは実験に使うソースコードをビルドしなくてはなりません。 今回使うソースコードはros2/demosを修正して作成しました。GitHubにプッシュしてあります。 ROS 2のワークスペースは~/ros2/youtalkにオーバーレイしているという想定です。

$ mkdir -p ~/ros2/youtalk/src
$ ~/ros2/youtalk/src
$ git clone git@github.com:youtalk/demos.git -b abortable-talker-listener
$ docker run -it -v `pwd`/youtalk:/youtalk youtalk/ros2:beta2 /bin/bash -c 'cd /youtalk'
root@28b5fe731034:/youtalk# ament build --only-packages demo_nodes_cpp

ホストPCのワークスペースをDockerコンテナのデータボリュームに指定するところがミソです。 ホストPCでワークスペースを構築、管理しつつ、ROS 2のビルド環境が整ったDockerコンテナでビルド、実行すれば、ソースコードは慣れた手元のエディタなり、IDEなりで編集できますし、ホストPCがどんなOSでも大丈夫です。 ちなみに私はmacOS Sierraで実行しています。

次にDockerコンテナ同士(つまりROSノード同士)が通信できるように、ネットワークを作成します。

$ docker network create ros2

実験

talker

Publisherの方はros2/demostalkerノードをそのまま使います。

$ docker run -it --rm --net ros2 youtalk/ros2:beta2 /bin/bash -c 'ros2 run demo_nodes_cpp talker'
Publishing: 'Hello World: 1'
Publishing: 'Hello World: 2'
Publishing: 'Hello World: 3'
Publishing: 'Hello World: 4'

abortable_listener

サイコロを振って出た目の数だけSubscribeした後、異常終了するabortable_listenerノードを作成しました。

https://github.com/youtalk/demos/blob/abortable-talker-listener/demo_nodes_cpp/src/topics/abortable_listener.cpp

これを使ってtalkerと接続してみましょう。

$ docker run --restart=on-failure --net ros2 -v `pwd`/youtalk:/youtalk youtalk/ros2:beta2 /bin/bash -c 'cd /youtalk; . install/local_setup.bash; ros2 run demo_nodes_cpp abortable_listener'
$ docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                        PORTS               NAMES
b0bc341c4aa4        youtalk/ros2:beta2   "/ros2_entrypoint...."   2 minutes ago       Up 2 minutes                                      focused_shaw
a070bf0a6070        youtalk/ros2:beta2   "/ros2_entrypoint...."   12 minutes ago      Up 2 minutes                                      sad_yalow
$ docker logs focused_shaw
Dice value: 1
I heard: [Hello World: 1]
Aborted
Dice value: 1
I heard: [Hello World: 12]
Aborted
Dice value: 3
I heard: [Hello World: 30]
I heard: [Hello World: 31]
I heard: [Hello World: 32]
Aborted

Dockerコンテナの標準出力のログを見ると、たしかにabortable_listnerノードが異常終了しても、自動的に再起動し、再びtalkerノードと接続、Subscribeし直していることがわかります。

Dockerのエコシステムを使うだけで、ROS 2は非常に頑健なシステムとして構築できることがわかりました。 将来、Quality of Service (QoS)も交えて、もう少し実践的な内容でも実験してみたいですね。

abortable_talker

上記とは逆にPublisherを異常終了させるノードのプログラムも作成してあります。

https://github.com/youtalk/demos/blob/abortable-talker-listener/demo_nodes_cpp/src/topics/abortable_talker.cpp

時間の関係で説明を省きますが、こちらもお試しください。