ROS 2 EloquentのXML記法を使ったLaunchシステム
ROS2 Advent Calendar 6日目の記事を担当します。今日から毎週金曜日に投稿する予定です。 Advent Calendarの流儀があまりよくわかっていませんが、普段通り久しぶりにブログを書いていこうと思います。
ROS 2 Eloquent Eluser
ROS2の最新ディストリビューションであるROS 2 2 Eloquent Eluserが11月末にリリースされました。 一つ前の2年サポートのROS 2 Dashing Diademataと違い、Eloquentは1年サポートです。Crystalのサポート期間は終了しました。
Eloquentは新機能や改善もたくさん含まれるようです。
- LaunchファイルのXML/YAML記述対応
- Launchシステムを使ったテスト実装の改善
- コマンドラインインタフェースからのパラメータ付与
- ノードごとのロギング、ストリーミングロギングマクロ(
rclcpp
) ros2doctor
コマンドの追加- セットアップスクリプトの速度改善
RViz2
のプラグイン追加rqt
のプラグイン追加turtlesim
のROS2移行- RMW実装の改善(ゼロコピー通信、CycloneDDS対応)
- 環境変数
ROS_LOCALHOST_ONLY
を使ったlocalhost限定通信 - macOS Mojaveサポート
rcl
,rclcpp
の実行状態監視(Trace, Instrumentation)対応
その他にも、以前のディストリビューションとはAPI互換性のない変更が加えられているようです。ROS2本レポジトリのEloquent対応も進めないといけませんね。
XML記法を使ったLaunchシステム
ROS 2 Eloquentの新機能の中で僕が一番気になったのが、XML記法を使ったLaunchシステムなので、早速試してみました。
DashingまではPython3で書く必要がありましたが、かなり冗長な記述となり、ROS1のLaunchファイルを知っていると、個人的には逆につらく感じることも多かったです。C++ノードを書いたのに、それを呼び出すにはPython3スクリプトを書かないといけないのも、変な感じがしていました。とても短く宣言的に書けるXML記法の復活は大歓迎です。
XMLスキーマの設計文章はROS 2 Designにあります。これと以下のドキュメントとソースコードやユニットテストを参考にすると、大体わかった気になれました。
- https://index.ros.org/doc/ros2/Tutorials/Launch-files-migration-guide/
- https://github.com/ros2/launch/blob/master/launch_xml/README.md
おそらくですが、ROS2特有のライフサイクルノードやノードコンポジションに対応したXML記法はまだ用意されていないようです。PRチャンスですね。
XMLによる記述例
ROS1のLaunchファイルに似ているようで、属性名が少し違います。pkg
はパッケージ名、exec
は実行ファイル名です。ノード名を書く必要がありません。また、ROS2からパラメータはグローバルではなくノードごとに持つようになったので、param
タグはnode
タグ内に書く必要があります。直接値を記述するだけでなく、外部ファルを渡す方法も用意されています。
1
2
3
4
5
6
<launch>
<node ns="/my_awesome_ns" pkg="demo_nodes_cpp" exec="parameter_event">
<param name="foo" value="5"/>
<param from="path/to/file.yml"/>
</node>
</launch>
ROS1でよく使われていたarg
タグはvalue
属性を持つことができなくなりました。value
属性を使って、Launchファイル内で変数のように使うことが多かったのですが、変数扱いなのかLaunchファイルの引数扱いなのかが、曖昧だったこともあったためだと思われます。
変数として使うには、新しく追加されたlet
タグを使います。let
タグの良いところはgroup
タグで囲った中だけのスコープを持つことです。プログラミング言語の変数スコープのようなことがXMLでも記述できるようになりました。 これにより、全ての変数がグローバル変数となってしまうROS1のLaunchファイルの欠点が解決されました。
1
2
3
4
5
6
7
8
<launch>
<arg name="use_time_prefix_in_talker" default="0"/>
<group>
<let name="launch-prefix" value="time" if="$(var use_time_prefix_in_talker)"/>
<node pkg="demo_nodes_cpp" exec="talker"/>
</group>
<node pkg="demo_nodes_cpp" exec="listener"/>
</launch>
他にも
- 他のLaunchファイル(Python3、XML、YAMLでも大丈夫)を読む
include
タグ - 環境変数のための
env
,set_env
,unset_env
タグ - ノード以外の任意の実行ファイルを実行する
executable
タグ
などがあります。総じて、ROS1の抱えていた課題を上手く解決しつつ、可読性も向上させているように感じられます。素晴らしい。
demo_nodes_cpp
パッケージへのプルリクエスト
僕はROS2の新機能を何か試すときは、ros2/demos
レポジトリのソースコードを読んで理解しています。
残念ながら、今回のXML記法を使った例はまだなかったので、ついでに実装してプルリクエストにしてみました。 demo_nodes_cpp
パッケージのlaunchファイルのXML版を作成して、launch_xml
パッケージを依存パッケージに追加しただけです。
https://github.com/ros2/demos/pull/419
YAML記法を使ったLaunchシステム
ROS2ではPython3、XMLだけでなく、YAML記法でも書けるようになったのですが、YAML記法の方はドキュメントもユニットテストも少なく、まだ試していません。
Comments powered by Disqus.