Skip to content

创建 Launch 文件

目标: 编写 launch 文件来运行复杂的 ROS 2 系统。

教程级别: 中级

时间: 10 分钟

本教程使用 rqt_graph 和 turtlesim 包。

你还需要使用你偏好的文本编辑器。

一如既往,不要忘记在每个新打开的终端中 source ROS 2。

ROS 2 的 launch 系统帮助用户描述系统配置,并按描述执行。 配置内容包括运行哪些程序、在哪里运行、传递哪些参数,以及 ROS 特有的约定——通过为每个组件设置不同配置,使其能在整个系统中被复用。 此外,它还负责监控已启动进程的状态,并在进程状态发生变化时报告或响应。

用 XML、YAML 或 Python 编写的 launch 文件可以启动和停止不同的节点,以及触发和响应各种事件。 有关不同格式的说明,请参阅 Launch 文件不同格式。 提供此框架的包是 launch_ros,它底层使用了非 ROS 特定的 launch 框架。

设计文档详细说明了 ROS 2 launch 系统的设计目标(并非所有功能目前都可用)。

创建一个新目录来存储你的 launch 文件:

Terminal window
mkdir launch

下面使用 turtlesim 包及其可执行文件来编写一个 ROS 2 launch 文件。 如上所述,可以用 XML、YAML 或 Python 编写。

XML 版本

将完整代码复制并粘贴到 launch/turtlesim_mimic_launch.xml 文件中:

<?xml version="1.0" encoding="UTF-8"?>
<launch>
<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim1" args="--ros-args --log-level info" />
<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim2" ros_args="--log-level warn" />
<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 版本

将完整代码复制并粘贴到 launch/turtlesim_mimic_launch.yaml 文件中:

%YAML 1.2
---
launch:
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "sim"
namespace: "turtlesim1"
args: "--ros-args --log-level info"
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "sim"
namespace: "turtlesim2"
ros_args: "--log-level warn"
- 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 版本

将完整代码复制并粘贴到 launch/turtlesim_mimic_launch.py 文件中:

from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim',
arguments=['--ros-args', '--log-level', 'info']
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim',
ros_arguments=['--log-level', 'warn']
),
Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
])

上面的所有 launch 文件都启动了一个由三个节点组成的系统,全部来自 turtlesim 包。 该系统的目标是启动两个 turtlesim 窗口,并让一只乌龟模仿另一只的运动。

启动两个 turtlesim 节点时,它们之间的主要区别在于命名空间值。 唯一的命名空间允许系统启动两个节点而不会产生节点名称或话题名称冲突。 系统中的两只乌龟通过相同的话题接收命令,也通过相同的话题发布各自的位姿。 有了唯一的命名空间,就可以区分发往不同乌龟的消息。

两个 turtlesim 节点还展示了向节点传递参数的不同方式。 第一个节点使用 args 直接向可执行文件传递参数,对于 ROS 特定的参数需要使用 --ros-args 标志。 第二个节点使用 ros_args(在 Python 中为 ros_arguments),专门用于 ROS 参数。 当混合使用 ROS 参数和非 ROS 参数时(例如 my_custom_arg --ros-args --log-level info),请使用 args;如果只有 ROS 参数(如重映射、参数或日志级别),则使用 ros_args,语法更为简洁。

最后一个节点同样来自 turtlesim 包,但是一个不同的可执行文件:mimic。 该节点添加了重映射形式的配置。 mimic 的 /input/pose 话题被重映射到 /turtlesim1/turtle1/pose,其 /output/cmd_vel 话题被重映射到 /turtlesim2/turtle1/cmd_vel。 这意味着 mimic 会订阅 /turtlesim1/sim 的位姿话题,并将速度命令发布到 /turtlesim2/sim 的速度命令话题上供其订阅。 换句话说,turtlesim2 会模仿 turtlesim1 的运动。

XML 版本详解

前两个动作使用不同的参数传递方式启动两个 turtlesim 窗口:

<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim1" args="--ros-args --log-level info" />
<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim2" ros_args="--log-level warn" />

最后一个动作启动带有重映射的 mimic 节点:

<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>

YAML 版本详解

前两个动作使用不同的参数传递方式启动两个 turtlesim 窗口:

- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "sim"
namespace: "turtlesim1"
args: "--ros-args --log-level info"
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "sim"
namespace: "turtlesim2"
ros_args: "--log-level warn"

最后一个动作启动带有重映射的 mimic 节点:

- 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 版本详解

这些导入语句引入了一些 Python launch 模块:

from launch import LaunchDescription
from launch_ros.actions import Node

接下来是 launch 描述本身的开始:

def generate_launch_description():
return LaunchDescription([

launch 描述中的前两个动作使用不同的参数传递方式启动两个 turtlesim 窗口:

Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim',
arguments=['--ros-args', '--log-level', 'info']
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim',
ros_arguments=['--log-level', 'warn']
),

最后一个动作启动带有重映射的 mimic 节点:

Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
])

要运行上面创建的 launch 文件,进入你之前创建的目录并运行以下命令:

XML

Terminal window
cd launch
ros2 launch turtlesim_mimic_launch.xml

YAML

Terminal window
cd launch
ros2 launch turtlesim_mimic_launch.yaml

Python

Terminal window
cd launch
ros2 launch turtlesim_mimic_launch.py

注意: 可以直接启动一个 launch 文件(如上面所做的那样),也可以启动由包提供的 launch 文件。 当由包提供时,语法为:

Terminal window
ros2 launch <package_name> <launch_file_name>

你可以在创建你的第一个 ROS 2 包中了解如何创建包。

注意: 对于包含 launch 文件的包,建议在包的 package.xml 中添加对 ros2launch 包的 exec_depend 依赖:

<exec_depend>ros2launch</exec_depend>

这有助于确保在构建你的包之后 ros2 launch 命令可用。 它还确保所有 launch 文件格式都能被识别。

两个 turtlesim 窗口将会打开,你会看到以下 [INFO] 消息,指示 launch 文件启动了哪些节点:

[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [turtlesim_node-1]: process started with pid [11714]
[INFO] [turtlesim_node-2]: process started with pid [11715]
[INFO] [mimic-3]: process started with pid [11716]

要查看系统的运行效果,打开一个新终端,在 /turtlesim1/turtle1/cmd_vel 话题上运行 ros2 topic pub 命令来让第一只乌龟移动:

Terminal window
ros2 topic pub -r 1 /turtlesim1/turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: -1.8}}"

你会看到两只乌龟沿着相同的路径移动。

模仿

当系统仍在运行时,打开一个新终端并运行 rqt_graph,以更好地了解 launch 文件中节点之间的关系。

运行命令:

Terminal window
ros2 run rqt_graph rqt_graph

模仿关系图

一个隐藏的节点(即你运行的 ros2 topic pub 命令)正在向左侧的 /turtlesim1/turtle1/cmd_vel 话题发布数据,/turtlesim1/sim 节点则订阅该话题。 图的其余部分与前面描述的内容一致:mimic 订阅 /turtlesim1/sim 的位姿话题,并向 /turtlesim2/sim 的速度命令话题发布数据。

Launch 文件简化了包含大量节点和复杂配置的系统启动过程。 你可以使用 XML、YAML 或 Python 创建 launch 文件,并用 ros2 launch 命令运行它们。