この記事ではROS 2 Humbleから使えるlaunch xmlの記述方法について紹介したいと思います。
ROS 2におけるlaunchの形式
ROS 2で使えるlaunchの形式はPython, XML, YAMLの3つがあります。
ただしすべて同じ機能が使えるわけではなく、すべての機能はPythonで実装されており、
expose_action/expose_substitutionのデコレーターが付与されてるものが、
XML/YAMLでtag/keyとして使えるようになっています。
Galacticまでは、composable nodeのloadやcontainerの起動をするには、
冗長なPythonのlaunchを書く必要があったのですが、Humbleからは
XMLで記述できるようになりました。(私の同僚の@kenji-miyake さんが実装してくれました。)
Pythonでの記述方法
まずは従来のPythonでの記述方法から見ていきます。
from launch import LaunchDescription
from launch_ros.actions import LoadComposableNodes, ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
def generate_launch_description():
container = ComposableNodeContainer(
name="my_container",
package="rclcpp_components",
executable="component_container",
namespace="",
arguments="test_args",
composable_node_descriptions=[
ComposableNode(
package="demo_nodes_cpp",
plugin="demo_nodes_cpp::ParameterBlackboard",
name="board1",
parameters=[
{"test": "aaa"}
],
extra_arguments=[{"use_intra_process_comms": True}],
),
],
output="screen",
)
load_composable_nodes = LoadComposableNodes(
target_container="my_container",
composable_node_descriptions=[
ComposableNode(
package="demo_nodes_cpp",
plugin="demo_nodes_cpp::ParameterBlackboard",
name="board2",
namespace="test_namespace",
parameters=[
{"test": "aaa"}
],
extra_arguments=[{"use_intra_process_comms": True}],
),
],
)
return LaunchDescription([
container,
load_composable_nodes,
])
ComposableNodeContainer
がcomposable nodeをloadするためのcontainerです。
composable_node_descriptions
にloadするcomposable nodeを記述します。
またすでにcontainerが起動している場合は、LoadComposableNodes
でtarget_container
にcomposable nodeをloadしたいcontainerを指定することで、composable_node_descriptions
に記述したnode群をloadすることができます。
XMLでの記述方法
上記のPythonで記述されたlaunchをXMLで置き換えたものが以下になります。
<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" />
</composable_node>
</node_container>
<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>
</launch>
PythonのclassとXMLのtagの対応関係は以下のようになっています。
-
ComposableNodeContainer
→node_container
(exposeの実装) -
ComposableNode
→composable_node
-
LoadComposableNodes
→load_composable_node
(exposeの実装)
(composable_node
のみnode_container
/load_composable_node
の下のcomposable_node
entityを読みにいくという実装だったため、exposeの記述はありませんでした。実装箇所)
コードの記述量が減り、だいぶスッキリしました。