Launch 文件不同格式
ROS 2 launch 文件支持 XML、YAML 和 Python 三种格式。本指南将用三种格式实现同一功能,并讨论各自的适用场景。
Launch 文件示例
Section titled “Launch 文件示例”下面是用 XML、YAML 和 Python 编写的 launch 文件。 每个 launch 文件完成以下操作:
- 设置带默认值的命令行参数
- 包含另一个 launch 文件
- 在另一个命名空间中包含另一个 launch 文件
- 启动一个节点并设置其命名空间
- 启动一个节点,设置其命名空间,并通过 args 设置参数
- 启动一个节点并将消息从一个话题重映射到另一个话题
XML 版本
Section titled “XML 版本”<?xml version="1.0" encoding="UTF-8"?><launch> <!-- args that can be set from the command line or a default will be used --> <arg name="background_r" default="0" /> <arg name="background_g" default="255" /> <arg name="background_b" default="0" /> <arg name="chatter_py_ns" default="chatter/py/ns" /> <arg name="chatter_xml_ns" default="chatter/xml/ns" /> <arg name="chatter_yaml_ns" default="chatter/yaml/ns" />
<!-- include another launch file --> <include file="$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py" />
<!-- include a Python launch file in the chatter_py_ns namespace--> <group> <!-- push_ros_namespace to set namespace of included nodes --> <push_ros_namespace namespace="$(var chatter_py_ns)" /> <include file="$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py" /> </group>
<!-- include a xml launch file in the chatter_xml_ns namespace--> <group> <!-- push_ros_namespace to set namespace of included nodes --> <push_ros_namespace namespace="$(var chatter_xml_ns)" /> <include file="$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.xml" /> </group>
<!-- include a yaml launch file in the chatter_yaml_ns namespace--> <group> <!-- push_ros_namespace to set namespace of included nodes --> <push_ros_namespace namespace="$(var chatter_yaml_ns)" /> <include file="$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.yaml" /> </group>
<!-- start a turtlesim_node in the turtlesim1 namespace and use args to set the log level --> <node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim1" args="--ros-args --log-level info" />
<!-- start another turtlesim_node in the turtlesim2 namespace, use ros_args to set the log level, and child elements to set the parameters --> <node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim2" ros_args="--log-level warn"> <param name="background_r" value="$(var background_r)" /> <param name="background_g" value="$(var background_g)" /> <param name="background_b" value="$(var background_b)" /> </node>
<!-- perform remap so both turtles listen to the same command topic --> <node pkg="turtlesim" exec="mimic" name="mimic"> <remap from="/input/pose" to="/turtlesim1/turtle1/pose" /> <remap from="/output/cmd_vel" to="/turtlesim2/turtle1/cmd_vel" /> </node></launch>YAML 版本
Section titled “YAML 版本”%YAML 1.2---launch:# args that can be set from the command line or a default will be used- arg: name: "background_r" default: "0"- arg: name: "background_g" default: "255"- arg: name: "background_b" default: "0"- arg: name: "chatter_py_ns" default: "chatter/py/ns"- arg: name: "chatter_xml_ns" default: "chatter/xml/ns"- arg: name: "chatter_yaml_ns" default: "chatter/yaml/ns"
# include another launch file- include: file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py"
# include a Python launch file in the chatter_py_ns namespace- group: - push_ros_namespace: namespace: "$(var chatter_py_ns)" - include: file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py"
# include a xml launch file in the chatter_xml_ns namespace- group: - push_ros_namespace: namespace: "$(var chatter_xml_ns)" - include: file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.xml"
# include a yaml launch file in the chatter_yaml_ns namespace- group: - push_ros_namespace: namespace: "$(var chatter_yaml_ns)" - include: file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.yaml"
# start a turtlesim_node in the turtlesim1 namespace and use args to set the log level- node: pkg: "turtlesim" exec: "turtlesim_node" name: "sim" namespace: "turtlesim1" args: "--ros-args --log-level info"
# start another turtlesim_node in the turtlesim2 namespace, use ros_args to set the log level, and param to set the parameters- node: pkg: "turtlesim" exec: "turtlesim_node" name: "sim" namespace: "turtlesim2" ros_args: "--log-level warn" param: - name: "background_r" value: "$(var background_r)" - name: "background_g" value: "$(var background_g)" - name: "background_b" value: "$(var background_b)"
# perform remap so both turtles listen to the same command topic- node: pkg: "turtlesim" exec: "mimic" name: "mimic" remap: - from: "/input/pose" to: "/turtlesim1/turtle1/pose" - from: "/output/cmd_vel" to: "/turtlesim2/turtle1/cmd_vel"Python 版本
Section titled “Python 版本”from launch import LaunchDescriptionfrom launch.actions import DeclareLaunchArgument, GroupAction, IncludeLaunchDescriptionfrom launch.substitutions import LaunchConfiguration, PathJoinSubstitutionfrom launch_ros.actions import Node, PushROSNamespacefrom launch_ros.substitutions import FindPackageShare
def generate_launch_description(): launch_dir = PathJoinSubstitution([FindPackageShare('demo_nodes_cpp'), 'launch', 'topics']) return LaunchDescription([ # args that can be set from the command line or a default will be used DeclareLaunchArgument('background_r', default_value='0'), DeclareLaunchArgument('background_g', default_value='255'), DeclareLaunchArgument('background_b', default_value='0'), DeclareLaunchArgument('chatter_py_ns', default_value='chatter/py/ns'), DeclareLaunchArgument('chatter_xml_ns', default_value='chatter/xml/ns'), DeclareLaunchArgument('chatter_yaml_ns', default_value='chatter/yaml/ns'),
# include another launch file IncludeLaunchDescription( PathJoinSubstitution([launch_dir, 'talker_listener_launch.py']) ),
# include a Python launch file in the chatter_py_ns namespace GroupAction( actions=[ # push_ros_namespace first to set namespace of included nodes for following actions PushROSNamespace('chatter_py_ns'), IncludeLaunchDescription( PathJoinSubstitution([launch_dir, 'talker_listener_launch.py'])), ] ),
# include a xml launch file in the chatter_xml_ns namespace GroupAction( actions=[ # push_ros_namespace first to set namespace of included nodes for following actions PushROSNamespace('chatter_xml_ns'), IncludeLaunchDescription( PathJoinSubstitution([launch_dir, 'talker_listener_launch.xml'])), ] ),
# include a yaml launch file in the chatter_yaml_ns namespace GroupAction( actions=[ # push_ros_namespace first to set namespace of included nodes for following actions PushROSNamespace('chatter_yaml_ns'), IncludeLaunchDescription( PathJoinSubstitution([launch_dir, 'talker_listener_launch.yaml'])), ] ),
# start a turtlesim_node in the turtlesim1 namespace and use arguments to set the log level Node( package='turtlesim', namespace='turtlesim1', executable='turtlesim_node', name='sim', arguments=['--ros-args', '--log-level', 'info'] ),
# start another turtlesim_node in the turtlesim2 namespace, # use ros_arguments to set the log level, and parameters to set the parameters Node( package='turtlesim', namespace='turtlesim2', executable='turtlesim_node', name='sim', ros_arguments=['--log-level', 'warn'], parameters=[{ 'background_r': LaunchConfiguration('background_r'), 'background_g': LaunchConfiguration('background_g'), 'background_b': LaunchConfiguration('background_b'), }] ),
# perform remap so both turtles listen to the same command topic Node( package='turtlesim', executable='mimic', name='mimic', remappings=[ ('/input/pose', '/turtlesim1/turtle1/pose'), ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'), ] ), ])从命令行使用 Launch 文件
Section titled “从命令行使用 Launch 文件”上面的任何 launch 文件都可以用 ros2 launch 运行。要在本地试用,你可以创建一个新包,然后使用:
ros2 launch <package_name> <launch_file_name>或者通过指定 launch 文件的路径直接运行:
ros2 launch <path_to_launch_file>要向 launch 文件传递参数,请使用 key:=value 语法。例如,设置 background_r 的值:
ros2 launch <package_name> <launch_file_name> background_r:=255或:
ros2 launch <path_to_launch_file> background_r:=255要测试重映射是否正常工作,你可以在另一个终端中运行以下命令来控制乌龟:
ros2 run turtlesim turtle_teleop_key --ros-args --remap __ns:=/turtlesim1XML、YAML 还是 Python:应该使用哪种?
Section titled “XML、YAML 还是 Python:应该使用哪种?”注意: ROS 1 中的 launch 文件是用 XML 编写的,因此对于从 ROS 1 迁移过来的用户来说,XML 可能是最熟悉的。 要了解变化内容,你可以访问 迁移 Launch 文件。
对于大多数应用来说,选择哪种 ROS 2 launch 格式主要取决于个人偏好。不过,如果 XML 或 YAML 无法满足你对灵活性的需求,可以选择用 Python 编写。Python 格式主要有两大优势:
- Python 是一种脚本语言,你可以在 launch 文件中直接利用 Python 语言本身及其丰富的标准库。
- ros2/launch(通用 launch 功能)和 ros2/launch_ros(ROS 2 特定的 launch 功能)都是用 Python 编写的,因此你可以接触到 XML 和 YAML 可能未暴露的底层 launch 功能。
不过,Python 格式的 launch 文件往往比 XML 或 YAML 更复杂、更冗长。