Tech Sketch Bucket of Technical Chips by TIS Inc.

ROS + Dockerを使ったロボットアプリケーション入門(1)準備編

Pocket

ROSという言葉を聞いたことはありますか?ROSとは、ロボット用のアプリケーションを作成するためのシステム、豊富なライブラリ、可視化・ビルドツールなど、幅広い機能を提供している、ロボット開発者に大人気のオープンソースフレームワークです。

本連載では、ROSをより手軽に使うために、ROSが公式で配布しているDockerイメージを使ってロボットアプリケーションを作成する方法を紹介します。

今回は準備編として、ROSのDockerイメージを使って、ROSに標準で付属してるビューア(Rvizなど)やセンサ(XtionやUSBカメラ)をコンテナ内で使う方法を紹介します。その後、センサのキャプチャ処理と描画処理をコンテナ毎に分離することで、簡単な分散処理を行ってみたいと思います。

docker-ros-logo

ROSとは

ここではROSについて簡単に紹介します。ROSはRobot Operating Systemの略語ですが、実際にはOSではなくロボット用のオープンソースフレームワークです。ROSは世界中で非常に多くの研究者・ロボット開発者に使われており、移動ロボット・産業用ロボットなど多くのロボットに対応しています。SoftbankのPepperもROSに対応したと最近アナウンスがありました。

人気の理由としては、大きく二つあると筆者は考えています。一つ目は、ROSで簡単に分散システムが構築できる点です。ROSではノードと呼ばれるある機能を持ったプロセスを複数起動して連携することで、一つのアプリケーションとして動作します。開発者は各ノードを実装する必要がありますが、ノード同士は疎結合になるようにROSで設計されているため他のノードのAPIのみ確認すれば、開発者は現在開発しているノードにのみに注力できます。これは、ROSがノード間通信を取り持つことにより簡単にプロセス間連携できるしくみをもっているためです。このしくみにより、ロボットの部品としての再利用性を高めることができます。

もう1つは、ROSコミュニティで開発されている豊富なパッケージが存在することです。世界中のROSユーザが開発した非常に多くのパッケージがこちらで公開されており、それを自分のロボットに簡単に組み込んで使うという仕組みがROSには用意されています。例えば、ほんの数行のコマンドで自律移動機能を自分のロボットに追加でき、開発者はより高次な開発に注力することができます。ほかにも、可視化・デバッグツールが強力である点や、開発可能な言語が多いこと、他のライブラリとの相性の良さなどが挙げられます。

ROSはドキュメント(wiki)が非常に充実していますので、もしこれからROSを始めようとされている方や開発中にわからないところが出てきたら適宜読むことをおすすめします(このページの最後におススメページを少し紹介しています)。

ROS + Dockerで何が嬉しいのか?

では、ROSのDockerコンテナを使用することによるメリット・デメリットにはどのようなものが挙げられるでしょうか?Dockerを使わず、マシンにROSを直接インストールした場合(ROSネイティブと表記)と比較することで確認したいと思います。

メリット デメリット
ROSネイティブ マシンのリソースをフルに使うことができる ROSのインストール可能な環境は実質Ubuntuのみ。一度構築したROS環境の移植は大変
ROS in コンテナ Dockerが動けば基本的にどこでも動くため、環境が変わってもすぐに使うことができる。既存のマシンのソフトウェア環境を汚す心配がない 1台のマシンにコンテナが複数起動していると、リソースを取られる

 

上の表からもわかるように、Dockerを使えばROSをPCに直接インストールする必要がないため既存の環境を汚すことなくROSを気軽に使うことができます。また、ROSでロボットアプリケーションを開発してゆくと多くのパッケージをインストールしますが、docker commitコマンドで構築したROS環境を新規にDockerイメージとして作成すれば、別のPCへと移植することも容易に出来るというメリットがあります。

ROSのDockerイメージを使ってみよう

概要

では、今回の概要を簡単に説明します。下記のような順番でROSのDockerイメージを使います。手順が下にあるものは上の手順の説明を元にしていますので、上から順番にやってみてください。

  1. ROS公式のDockerイメージのダウンロード
  2. ROSのDockerイメージの動作確認
  3. Dockerコンテナ内でGUIツール(Rviz)を使おう
  4. Dockerコンテナ内でセンサ(USBカメラ, Xtion)を使おう
  5. Dockerコンテナ間で分散処理(画像のキャプチャ処理と描画処理の分離)にチャレンジ

今回動作を確認した環境は以下の通りです。

OS Dockerバージョン
Ubuntu 14.04 LTS Docker v1.8.2

1. ROSのDockerイメージのダウンロード

まず、Docker HubからROS(バージョンはindigo)のデスクトップ用Dockerイメージをダウンロードします(2GB以上あるため時間がかかります)。これは、ROSが提供する様々な機能(ROSのベース機能、2D/3Dビューア、シミュレータ、自律移動・認識パッケージなど)を含んでいます。

2. ROSのDockerイメージの動作確認

では次に、ダウンロードしたROSのDockerコンテナを利用して、コンテナ同士でメッセージのやりとりを行います。ここでの目的は、1コンテナにつき1つのノードを作成して、コンテナ間でメッセージの受け渡しができることを確認することです(1コンテナに1つのノードというのは今回のための特別な構成で、通常は用いられません。通常は1コンテナにつき1アプリケーション、又は1モジュールくらいのノード数がよいでしょう)

ROSでは、ノードと言われるある機能を持ったプロセスを複数起動し、その間をトピックといわれるメッセージで非同期通信するというのが、よく使われる構成です(サービスといわれる同期通信にも対応しています)。これはいわゆるPub/Subモデルというもので、各ノードはmasterといわれる特別なノードに自分自身の情報を登録することにより、この通信を実現しています。

今回はROS公式のチュートリアルで使われるパッケージを使用しますが、動作は非常に簡単なものです。具体的には、文字列を配信(publish)するノードと、文字列を購読(subscribe)するノードを起動し、二つのノード間でトピック(ここでは/chatterというトピック名の文字列)を非同期で受け渡すというものです。

では、さっそくはじめてみましょう。ダウンロードしてきたROSのDockerイメージから、三つのコンテナ(それぞれmaster, talker、listener用)を起動させ、その後、talker,listener間でメッセージをやりとりさせてみます。下図のような構成になります。

docker-ros-2-1

まず、masterという名前のコンテナを起動します。その際、環境変数ROS_HOSTNAMEにもmasterという名前をつけておくことで、ほかのコンテナがmasterというホスト名で参照できるようにします。そして、roscoreコマンドでROSのマスターを起動します。(下記コマンドはそれぞれ別のターミナルで入力してください)

次に、メッセージをpublishするtalkerという名前のコンテナを作成します。環境変数ROS_HOSTNAMEにはtalker、ROS_MASTER_URIには先ほど作成したマスターのホスト名を挿入して指定しています。そして、talkerノードを起動します。

最後に、メッセージをsubscribeするlistenerという名前のコンテナを作成します。talkerと同じように、環境変数ROS_HOSTNAMEにはlistener、ROS_MASTER_URIには先ほど作成したマスターのホスト名を挿入して指定しています。そして、listenerノードを起動します。

 

以下のようにtalkerの送った文字列がlistener側に表示されれば成功です。

docker-ros-2

3. Dockerコンテナ内でGUIツール(Rviz)を使おう

では、次にROSに付属したGUIツールを起動する方法を紹介します。ROSは標準でrqt(2D),Rviz(3D)という、ロボットアプリケーション作成において非常に役に立つビューアが付属しています。通常ROSを使ってロボットアプリケーションを開発する場合は、これらのビューアを使うことが多いため、今回のようにROSのDockerイメージを使う場合でもそれらのGUIツールを使いたいという要望は多いはずです。ここでは一例としてRvizの起動方法を紹介します。

まず、2.と同じようにmasterを起動しておきます。

次に、ビューアのコンテナを起動します。この時、可視化の機能を有効にします。

もし以下のように出た場合は、

以下のように打って全てのホストからXサーバにアクセスできるようにしてください。(より安全な方法は、下記参考文献のサイトを参照してください)

下図のように、Rvizが起動すれば成功です。

docker-ros-3

4. Dockerコンテナ内でセンサ(USBカメラ, Xtion)を使おう

では次に、センサによって得られたデータを、先ほど起動したビューアに描画したいと思います。センサには、USBカメラとXtionを使います。Xtionは、Microsoft Kinectと非常によく似たセンサで、2DのRGBイメージや3Dの点群データを取得することができ、Rviz上にRGBイメージや点群データを表示することができます。今回は、USB カメラとXtionを使って、rqt, Rvizで描画する方法を紹介します。

 

USBカメラで画像表示する

まず、USBカメラをPCに挿します。次に、認識されたデバイスのパスを読み込み/書き込み許可します。

次に、下記のコマンドでコンテナを起動します。 コンテナ起動時にデバイスのパスを--deviceで指定することで、ホスト側に挿したデバイスをコンテナ内でアクセスすることができます。

上記のコマンドではコンテナ内に入るだけで、まだどのノードも起動していません。下記コマンドは、すべて上記で起動したコンテナ内で行います。具体的な処理内容としては、tmuxで複数ウィンドウでコマンドライン入力できるようにした後、カメラ用のドライバパッケージのインストールを行い、各ノードを起動します。

最後の行を入力後、イメージビューアが起動し、USBカメラ画像が表示されれば成功です。

docker-ros-3-10

 

Xtionで3D表示する

まず、XtionをPCに挿します。次に、lsusbコマンドで、ASUS XtionがどのUSBパスにマウントされているか確認します。例えば下図の場合、ASUSは下から二番目に表示されており、Busの001, デバイスの006ですので、この番号をメモしておきます。

ros-docker-3-23

メモした情報をもとに、デバイスを読み込み/書き込み許可します。

次に、下記のコマンドでコンテナを起動します。 コンテナ起動時にデバイスのパスを--deviceで指定することで、ホスト側に挿したデバイスをコンテナ内でアクセスすることができます。

上記のコマンドではコンテナ内に入るだけで、まだどのノードも起動していません。下記コマンドは、すべて上記で起動したコンテナ内で行います。具体的な処理内容としては、tmuxで複数ウィンドウでコマンドライン入力できるようにした後、Xtion用のドライバパッケージのインストールを行い、各ノードを起動します。

最後の行を入力すると、Rvizが起動するはずです。この後は、Rvizの左パネルのDisplaysで、表示したいトピックを選択します。

例えば、下図のように表示するには、まずFixed Frameでcamera_linkを選択します。次に、下にあるAddボタンをクリックして、表示するトピックの型をPointCloud2を選択します。追加されたPointCloud2の項目のうち、Topicで/camera/depth_registered/pointsを選択すれば、3Dの点群データがRviz上に出力されます。図のように点群にRGB値も付加する場合はColorTransformerをRGB8に設定してください。同じく、Addボタンで追加するトピックの型としてImage,トピックの名前として/camera/rgb/image_rawを選択すれば、2DのRGB画像がRviz上に出力されます。

docker-ros-3-24

docker-ros-3-22

5. Dockerコンテナ間で分散処理(画像のキャプチャ処理と描画処理の分離)にチャレンジ

最後に、上記2.と4.で行った処理を組み合わせて分散処理をより体験できるようにしてみます。具体的には、4.で起動した三つのノード(masterノード, カメラキャプチャ用ノード(群)、ビューアノード)を、2.のようにそれぞれ別々のコンテナで起動し、カメラキャプチャ用コンテナとビューア用コンテナに分離します。

 

docker-ros-4

まず、master用のコンテナを起動します。(下記コマンドはそれぞれ別のターミナルで入力してください)

次に、カメラキャプチャ用のコンテナを別のターミナルで起動します。ROS用のopenni2-launchパッケージをインストールする必要があるため、一度コンテナに入ってからインストールした後、ノードを起動します。

最後に、ビューア用コンテナを別のターミナルで起動します。

ビューア起動後の手順は、4.のXtionを使った場合と同じです。無事に3D点群が表示されれば成功です!

まとめ

ROSのDockerイメージを使って、ROSに付属してるビューアやセンサをコンテナ内で使う方法を紹介しました。これにより、ROSを使った開発でDockerイメージの利用の幅が広がったと思います。

今回は1台のPC内に複数のコンテナを起動することで簡単な分散処理を行いましたが、複数台で行うとより分散処理を体感できます。しかし、Dockerのみを使ってマルチホストのコンテナ間通信を行う場合、現時点では残念ながら容易ではなく複雑な通信設定が必要になりそうです。Dockerのマルチホスト間通信については、下記の参考サイトが詳しいので是非ご覧になってください。

次回は、今回使ったROSのDockerイメージを使いながら、ロボットアプリケーションをより実感できるアプリを実際に作成したいと思います。

参考文献

エンジニア採用中!私たちと一緒に働いてみませんか?