この記事はROS2アドベントカレンダー2022、12/18 の記事です。
同じアドベントカレンダーでcomposable nodeを含むlaunchをPythonからxmlに置き換える記事が出ています。
qiita.com
記事中の 冗長なPythonのlaunchを書く必要があったのですが、HumbleからはXMLで記述できるようになりました。
を見て、
これは、yamlについて書かなくては…! と思ったので私もまた言及しようと思いました。
(ちなみに、composable_nodeをyamlで呼び出すこと自体は半年前の記事にあります。)
YAMLでComposableNodeを起動する(ROS2・launch_yaml) - えいあーるれいの技術日記
バージョンを重ねるたびに機能が追加されており、composable_nodeはROS-Humbleからの機能です。
launch_rosでは、Pythonからのlaunch操作は直接呼び出して、それ以外はParserを介して解釈させます。
解釈されたタグをもとに @expose_action(node_container)
などのデコレータ関数に飛ばします。
github.com
仕組みがコレなので、XMLとYAMLの仕様は同一というわけです。
XMLで使えるものはYAMLでも使える(はず)です。
解釈部分については launch 内の launch_yaml と launch_xml に記載されています。
github.com
でも、XMLとYAMLはぱっと見る感じ全然違う雰囲気があるのですぐ乗り換えるのはな〜…と思いがちですが、
いくつかポイントを押さえれば簡単です。
(元記事の「XMLでの記述方法」を参考に説明します。)
qiita.com
ハッシュ
ハッシュとは、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の名前空間を入れ子にする際に使用します。
例えば、以下のように書かれている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>)
は使えませんでした。
サンプルが少ないので流行りにくさは感じますが、かなりスッキリとかけると思います。