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にあります。これと以下のドキュメントとソースコードやユニットテストを参考にすると、大体わかった気になれました。

おそらくですが、ROS2特有のライフサイクルノードやノードコンポジションに対応したXML記法はまだ用意されていないようです。PRチャンスですね。

XMLによる記述例

ROS1のLaunchファイルに似ているようで、属性名が少し違います。pkgはパッケージ名、execは実行ファイル名です。ノード名を書く必要がありません。また、ROS2からパラメータはグローバルではなくノードごとに持つようになったので、paramタグはnodeタグ内に書く必要があります。直接値を記述するだけでなく、外部ファルを渡す方法も用意されています。

<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ファイルの欠点が解決されました。

<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レポジトリのソースコードを読んで理解しています。

https://github.com/ros2/demos

残念ながら、今回のXML記法を使った例はまだなかったので、ついでに実装してプルリクエストにしてみました。 demo_nodes_cppパッケージのlaunchファイルのXML版を作成して、launch_xmlパッケージを依存パッケージに追加しただけです。

https://github.com/ros2/demos/pull/419

YAML記法を使ったLaunchシステム

ROS2ではPython3、XMLだけでなく、YAML記法でも書けるようになったのですが、YAML記法の方はドキュメントもユニットテストも少なく、まだ試していません。