こんにちはshotaです。
2021年9月にROSCon JP 2021という、ROSのユーザや開発者が集まるイベントに参加しました。
このブログ記事では、ROSCon JP 2021の企業展示ブースで動かした「ROS 2で動くミニ工場」がどういう仕組みで動いているのかを紹介します。
ROS 2で動くミニ工場とは
この展示では、アールティの製品である、Raspberry Pi Mouse(ラズベリーパイマウス)、CRANE+ V2(クラインプラスブイツー)、CRANE-X7(クラインエックスセブン)の、合計3台のロボットが連携して小さな箱を運びます。
実際に動かした様子は次の動画をご覧ください。
作業の流れは次の図のとおりです。
それでは、展示の各要素と使用しているROS 2パッケージを合わせてご紹介します。
Raspberry Pi Mouseによるライントレース
まず紹介するのはRaspberry Pi Mouseによるライントレースです。
ロボット前方に取り付けられたライトセンサでラインを検出し、箱を運びます。
使用しているROS 2パッケージはrt-net/raspimouse2です。
ライントレースはラズパイマウスROS 2サンプル集(rt-net/raspimouse_ros2_examples)のサンプルを流用しています。
※ライントレース用にRaspberry Pi Mouse オプションキット No.3を取り付けています。
※Raspberry Pi Mouseに箱を乗せられるように、Raspberry Pi Mouse オプションキットNo.8を使用しています。
CRANE+ V2によるピック&プレース
CRANE+ V2はターンテーブルの上にある箱を掴み、Raspberry Pi Mouseに乗せます。
使用しているROS 2パッケージはrt-net/crane_plusです。
crane_plusパッケージは、アームロボットの軌道計算でよく使われているMoveIt 2や、ロボットの制御によく使われているros2_controlパッケージを使用しています。
CRANE-X7によるピック&プレース
CRANE-X7はRaspberry Pi Mouseの上にある箱を掴み、ターンテーブルに乗せます。
CRANE-X7は7軸で構成されているので、障害物を避けたり、箱の姿勢を変えたりなど、より複雑な動きができます。
使用しているROS 2パッケージは現在開発中です。公開までもうしばらくお待ちください。こちらのパッケージもMoveIt 2とros2_controlを使用しています。
DYNAMIXELで回るターンテーブル
ターンテーブルはROBOTIS社製のDYNAMIXEL XM540-W150サーボモータで回しています。
DYNAMIXELサーボモータはDYNAMIXEL SDKを用いることで、C++やPython等で書かれたプログラミングから操作できます。
ROS 2の主な開発言語もC++とPythonのため、DYNAMIXELとROS 2の相性は良いです。
この展示ではPythonを用いてDYNAMIXELを操作しています。
カメラによるターンテーブル上の箱の検出
USBカメラはターンテーブルを撮影し、箱を検出します。
カメラ画像をROSトピックへ変換するために、usb_camパッケージを使用しています。
また、カメラ画像にひずみ補正をかけるために、image_procパッケージを使用しています。
箱を検出するための画像処理にはOpenCVを使用しています。
こちらもC++とPython用のライブラリが用意されているので、OpenCVとROS 2は相性が良いです。
箱の位置座標・姿勢は検出していません。
箱の位置・姿勢情報無しで連続して箱を運ぶために、展示開始前にピック&プレースの目標位置を微調整しました(ROSCon JPで一番頑張ったところです)。
Integration Serviceによる複数ロボットの連携
複数のロボットを同時に動かすために使用したソフトウェアがeProsima社が公開するIntegration Serviceです。
Integration Serviceは、ROS 1、ROS 2、WebSocket、Fast DDSなどの異なるミドルウェア同士の通信を抽象化し、接続してくれるソフトウェアです。
なかでも、ROS 2における異なるROS_DOMAIN_ID同士のトピックやサービス通信を接続する機能が活躍しました。
ROSやROS 2で複数のロボットを同時に動かす場合、それぞれのロボットが同じ名前のトピックやサービスを使わないように、トピック・サービス名を変更したり、ネームスペースを分けたりすることが多いです。
経験則ですが、このトピック・サービス名を変更する作業は簡単ではありません。
ROS 2では、ロボットごとにROS_DOMAIN_IDという環境変数を設定することでネットワークを分離できます。
これにより、トピックやサービス名が被る問題は解決しますが、ネットワークが完全に分離されるためロボット同士を連携させることが難しくなります。
Integration Serviceを使えば、つぎのような設定ファイルを用意するだけで、異なるROS_DOMAIN_ID間でも通信できるようになります。
systems: x7_server_domain: { type: ros2, domain: 2, node_name: "is_x7_server_node" } x7_client_domain: { type: ros2, domain: 3, node_name: "is_x7_client_node" } routes: x7_server: server: x7_server_domain clients: x7_client_domain services: crane_x7_command: { request_type: DemoCommand_Request, reply_type: DemoCommand_Response, route: x7_server, remap: { x7_server_domain: { request_type: "roscon_demo_msgs/DemoCommand:request", reply_type: "roscon_demo_msgs/DemoCommand:response" }, x7_client_domain: { request_type: "roscon_demo_msgs/DemoCommand:request", reply_type: "roscon_demo_msgs/DemoCommand:response" } } }
次のようにIntegration Serviceをビルドすれば、自作のメッセージ型にも対応します。
$ colcon build --symlink-install --cmake-args -DMIX_ROS2_PACKAGES="roscon_demo_msgs"
詳しい使い方は、Integration Serviceのドキュメントを参照してください。
ノードとROS_DOMAIN_IDの構成
ROSノードとROS_DOMAIN_IDの構成は次の図のようになりました。
具体的なトピック、サービスの内容は省略しています。
CRANE+ V2とCRANE-X7は似たパッケージ構成のため、使用するトピック、サービス名が被ります。それぞれに異なるROS_DOMAIN_IDを割り当てることで、名前の衝突を防いでいます。
さらに、Integration Serviceを使うことでデモプログラムがCRANE+ V2とCRANE-X7に対して指示を出せるようになります。
まとめ
ROSCon JP 2021ではROS 2で動く複数のロボットを連携させました。最後に、使用したパソコンの情報を記載します。
展示で動かしたロボットは複数ですが、ROS 2を実行するために用意したパソコンは1台のみです。(厳密に言うとRaspberry Pi MouseのRaspberry Pi 4と合わせて2台です。)
第8世代のCore i5を搭載したノートパソコンですが、なんとかロボットを動かすことができました。
展示の動きを早くさせたり、より複雑な画像処理を実行する場合は、もっとスペックの高いパソコンが必要かもしれません。
今回の記事が、ROS 2未経験の方のROS 2を始めてみるキッカケになると嬉しいです。
2021/10/20 追記:無料webセミナーを開催します
2021年10月27日(水)に、ROSConJP 2021展示レポートをテーマにした無料webセミナーを開催します。
ミニ工場についても紹介するので、ぜひご参加下さい。