Skip to content

Launch 文件不同格式

ROS 2 launch 文件支持 XML、YAML 和 Python 三种格式。本指南将用三种格式实现同一功能,并讨论各自的适用场景。

下面是用 XML、YAML 和 Python 编写的 launch 文件。 每个 launch 文件完成以下操作:

  • 设置带默认值的命令行参数
  • 包含另一个 launch 文件
  • 在另一个命名空间中包含另一个 launch 文件
  • 启动一个节点并设置其命名空间
  • 启动一个节点,设置其命名空间,并通过 args 设置参数
  • 启动一个节点并将消息从一个话题重映射到另一个话题
<?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 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"
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, GroupAction, IncludeLaunchDescription
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from launch_ros.actions import Node, PushROSNamespace
from 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 文件都可以用 ros2 launch 运行。要在本地试用,你可以创建一个新包,然后使用:

Terminal window
ros2 launch <package_name> <launch_file_name>

或者通过指定 launch 文件的路径直接运行:

Terminal window
ros2 launch <path_to_launch_file>

要向 launch 文件传递参数,请使用 key:=value 语法。例如,设置 background_r 的值:

Terminal window
ros2 launch <package_name> <launch_file_name> background_r:=255

或:

Terminal window
ros2 launch <path_to_launch_file> background_r:=255

要测试重映射是否正常工作,你可以在另一个终端中运行以下命令来控制乌龟:

Terminal window
ros2 run turtlesim turtle_teleop_key --ros-args --remap __ns:=/turtlesim1

XML、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 更复杂、更冗长。