ROSプラグイン¶
ROSプラグインとは¶
ROSプラグインは、choreonoid_rosパッケージに含まれるChoreonoid用のプラグインです。
このプラグインの基本的な役割は、C++からROSの機能を使用するためのライブラリである "roscpp" をChoreonoid上でも利用できるようにすることにあります。そのためのビルド環境がchoreonoid_rosパッケージによって整備され、ROSプラグインの中ではroscppの初期化がまず行われるようになっています。
この仕組みによって、Choreonoidフレームワークの構成要素であるビューやアイテム、あるいはシミュレーション機能の構成要素であるコントローラやサブシミュレータ等において、ROSで通信を行うコントローラによってロボットを制御したり、ROS上でのデータを可視化・編集したりといったことが、Choreonoid上で可能となるわけです。
これを実現する第一の手段は、ユーザが必要な機能をC++プログラムとして自前でコーディングすることです。roscppはよく設計されたライブラリであり、ドキュメントも充実しているため、rosccppを用いてROSの機能を利用するソフトウェアを実装することはそれほど難しいことではありません。ROSとC++に慣れている場合は、この手段によって目的を達成することを考えてください。
一方で、よく使われるROSのメッセージやサービスについては、それをロボットの制御に利用したり、可視化や編集を行うといった機能が、デフォルトで備わっていると便利です。これによって、標準的な利用方法であれば、コーディングを行うこと無く手軽に利用できるようになるからです。Choreonoidではそのような機能をアイテムやビューのかたちで実装することができるので、ROSプラグインにはそのようなアイテムやビューを提供する役割を持たせたく思っています。
とは言え、現状のROSプラグインはほぼ前者のための機能しか備えておらず、ROS連携に関して自前のコーディングが必要となります。実は以前産総研で開発された choreonoid_ros_pkg に含まれるROSプラグインは、ロボットのシミュレーションにおいて利用できる機能が標準で搭載されており( マニュアル参照 )、後者をある程度実現できていたのですが、現在公式にサポートされているROSプラグインでは、まだそのような機能の移行ができていない状態です。この点は今後改善していきたいと考えていますし、この件に関するご協力やご支援をいただける場合は フォーラム などでぜひご連絡いただければと思います。
ROSプラグインの読み込み¶
ROSプラグインは chorenoid_ros パッケージに含まれています。ROSプラグインを利用するためには、choreonoid_ros が提供するROSノードとしてChoreonoidを起動する必要があります。これをChoreonoidノードと呼ぶことにします。
Choreonoidの起動 でも述べたように、Choreonoidノードは他のROSノードと同様にrosrunコマンドを用いて
rosrun choreonoid_ros choreonoid
とすることで起動できます。もちろん、ROSノードを起動する他の方法として、roslaunch等も利用可能です。
このようにROSノードとして起動されたChoreonoidでは、ROSプラグインが読み込まれており、利用できるようになっています。その場合、起動されたChoreonoidのメッセージビュー内に、
ROSプラグインが読み込まれました.
というメッセージが出力されます。
このメッセージが出力されていない場合、ROSプラグインは読み込まれておらず、Choreonoid上でROSの機能を利用することはできませんので、ご注意ください。(ROSとは独立してインストールしたChoreonoidを通常の方法で起動した場合は、そのようになります。)
なお、Choreonoidノード起動時に、メッセージビューに
Warning: The ROS master is not found.
と表示されることがあります。この場合、ROSのマスターが起動されておらず、やはりROSの機能を利用することはできません。
この場合はまず ROSマスターの起動 を行うようにしてください。
ROSプラグインによるroscppの初期化¶
ROSプラグインが読み込まれると、プラグインの初期化関数にて、以下のコードに相当する処理が実行されます。
ros::init(argc, argv, "choreonoid", ros::init_options::NoSigintHandler
auto spinner = new ros::AsyncSpinner(0);
spinner->start();
まず ros::init 関数でroscppの初期化を行います。ノード名は標準で "choreonoid" となるようにしています。また、Choreonoidノードの起動時に与えたROS関連のコマンドラインオプションが、argc、argvに格納されており、この初期化関数に渡されます。これによって、ノード名やトピック名などのリマップも処理されます。
初期化完了後、ros::AsyncSpinner が作成され、ROSのコールバックキューのバックグラウンド処理が開始します。これにより、Choreonoidノード内で生成されたSubscriber等の処理が、バックグラウンドスレッドで行われるようになります。Choreonoidのメインスレッド上では通常通りGUI等を処理するためのメインループが動作しますが、それと並行してROSの処理が行われるようになっています。
以上の初期化処理により、Choreonoid上でros::NodeHandle等を用いてPublisherやSubscriber等を自由に生成して使用することが可能となります。逆にroscppの初期化はROSプラグインが担当するので、Choreonoid上で動作する他のモジュールで初期化関数などを実行してはいけません。
また、上記のようにコールバックキューの処理はメインスレッドとは別のスレッドで行われるため、各コールバック関数が実行されるスレッドもメインスレッドとは異なります。コールバック関数の実装においてはこの点に注意し、必要に応じて排他制御を入れるようにしてください。
ros::NodeHandle等の具体的な使用方法については、 ROS版Tankチュートリアル にて解説します。