この記事はROS2アドベントカレンダー2022、12/18 の記事です。
同じアドベントカレンダーでcomposable nodeを含むlaunchをPythonからxmlに置き換える記事が出ています。
記事中の 冗長なPythonのlaunchを書く必要があったのですが、HumbleからはXMLで記述できるようになりました。
を見て、
これは、yamlについて書かなくては…! と思ったので私もまた言及しようと思いました。
(ちなみに、composable_nodeをyamlで呼び出すこと自体は半年前の記事にあります。)
YAMLでComposableNodeを起動する(ROS2・launch_yaml) - えいあーるれいの技術日記
バージョンを重ねるたびに機能が追加されており、composable_nodeはROS-Humbleからの機能です。
LaunchのYAMLとXML(仕様)
launch_rosでは、Pythonからのlaunch操作は直接呼び出して、それ以外はParserを介して解釈させます。
解釈されたタグをもとに @expose_action(node_container)
などのデコレータ関数に飛ばします。
仕組みがコレなので、XMLとYAMLの仕様は同一というわけです。
LaunchのYAMLとXML(記法)
でも、XMLとYAMLはぱっと見る感じ全然違う雰囲気があるのですぐ乗り換えるのはな〜…と思いがちですが、
いくつかポイントを押さえれば簡単です。
(元記事の「XMLでの記述方法」を参考に説明します。)
ハッシュ
ハッシュとは、YAMLの キーワード: 値
の組み合わせのことです。
要素数は一つだけでなく、複数にすることもできます。
# ハッシュの例 a: b b: c: d d: e f: g
XMLの属性(abc="def"
のように記述するやつ)はすべてハッシュで記述されます。
例えば、以下のように書かれているxmlがあるとします。
<node_container pkg="rclcpp_components" exec="component_container" name="my_container" namespace="" args="test_args"/>
これをYAMLに直すと次のようになります。
node_container: pkg: "rclcpp_components" exec: "component_container" name: "my_container" namespace: "" args: "test_args"
配列
配列は -
で接続された主に複数の要素を記述するものです。
例えば、以下のように書かれているxmlがあるとします。
<load_composable_node target="my_container"> <composable_node pkg="demo_nodes_cpp" plugin="demo_nodes_cpp::ParameterBlackboard" name="board2" namespace="test_namespace"> <param name="test" value="aaa" /> <extra_arg name="use_intra_process_comms" value="true" /> </composable_node> </load_composable_node>
これをYAMLに直すと次のようになります。
- load_composable_node: target: "my_container" composable_node: - pkg: demo_nodes_cpp plugin: "demo_nodes_cpp::ParameterBlackboard" name: "board2" param: - name: "test" value: "aaa" extra_arg: - name: "use_intra_process_comms" value: "true"
値が紐づけられない名前空間の接続は全て配列になっています。
以上を踏まえて、先の記事のXMLからYAMLに変換したコードを以下に示します。
launch: - node_container: pkg: "rclcpp_components" exec: "component_container" name: "my_container" namespace: "" args: "test_args" composable_node: - pkg: demo_nodes_cpp plugin: "demo_nodes_cpp::ParameterBlackboard" name: "board1" namespace: "test_namespace" param: - name: "test" value: "aaa" extra_arg: - name: "use_intra_process_comms" value: "true" - load_composable_node: target: "my_container" composable_node: - pkg: demo_nodes_cpp plugin: "demo_nodes_cpp::ParameterBlackboard" name: "board2" namespace: "test_namespace" param: - name: "test" value: "aaa" extra_arg: - name: "use_intra_process_comms" value: "true"
demo_nodes_cpp の talker_listener.launch.py も次のように書けます。
launch: - node_container: pkg: "rclcpp_components" exec: "component_container" name: "my_container" namespace: "" composable_node: - pkg: "demo_nodes_cpp" plugin: "demo_nodes_cpp::Talker" name: "node_talker" remap: - from: /chatter to: /talker_listener - pkg: "demo_nodes_cpp" plugin: "demo_nodes_cpp::Listener" name: "node_listener" remap: - from: /chatter to: /talker_listener
まだまだある!?オプション
launch/test_executable.py at galactic · ros2/launch · GitHubより
launch: - executable: cmd: ls -l -a -s cwd: '/' name: my_ls shell: true output: log 'launch-prefix': $(env LAUNCH_PREFIX '') env: - name: var value: '1'
ls コマンドをルートディレクトリに対して行うlaunch.yamlです。executable
キーを使用して実行するみたいです。
launch/test_include.py at humble · ros2/launch · GitHub(xml)より
launch: - let: { name: launch_path, value: "/opt/ros/humble/share/demo_nodes_cpp/launch/topics/" } - include: file: "$(var launch_path)talker_listener.launch.py"
他のlaunchファイルもyamlで実行できます。
includeもとを辿る方法は見つけられませんでした…
ROS1で見られた
$(find <pkg>)
は使えませんでした。
サンプルが少ないので流行りにくさは感じますが、かなりスッキリとかけると思います。