启动 Launch
ROS 2 启动文件允许您同时启动和配置多个包含 ROS 2 节点的可执行文件。
便条
如果您来自 ROS 1,您可以使用 ROS 启动迁移指南来帮助您将启动文件迁移到 ROS 2。
目标:创建一个启动文件来运行一个复杂的 ROS 2 系统。
教程级别:中级
时间:10 分钟
先决条件
背景
任务
1. 设置
2. 编写启动文件
3 ros2 启动
4 使用 rqt_graph 内省系统
摘要
先决条件
本教程使用 rqt_graph 和 turtlesim 包。https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/Introducing-Turtlesim.html
您还需要使用您喜欢的文本编辑器。
始终不要忘记在您打开的每个新终端中获取 ROS 2 的源。https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.html
背景
ROS 2 中的启动系统负责帮助用户描述其系统的配置,然后按照描述执行。系统配置包括运行哪些程序,在哪里运行它们,传递给它们什么参数,以及 ROS 特定的约定,这些约定通过为系统中的每个组件提供不同的配置,使得重用组件变得容易。它还负责监控启动的进程的状态,并报告或/和对这些进程状态的变化做出反应。
使用 Python、XML 或 YAML 编写的启动文件可以启动和停止不同的节点,以及触发和响应各种事件。有关不同格式的描述,请参见 ROS 2 启动文件的 Python、XML 和 YAML 使用方法https://docs.ros.org/en/jazzy/How-To-Guides/Launch-file-different-formats.html 。提供此框架的软件包是 launch_ros ,它下面使用的是非 ROS 特定的 launch 框架。
设计文档https://design.ros2.org/articles/roslaunch.html 详细说明了 ROS 2 启动系统设计的目标(目前并非所有功能都可用)。
任务
1. 设置
mkdir launch
编写启动文件
让我们使用 turtlesim 包及其可执行文件,一起创建一个 ROS 2 启动文件。如上所述,这可以是 Python、XML 或 YAML。
将完整代码复制并粘贴到 launch/turtlesim_mimic_launch.py 文件中:
# 导入LaunchDescription模块,用于描述启动配置
from launch import LaunchDescription
# 导入Node模块,用于描述一个ROS节点
from launch_ros.actions import Node
# 定义一个函数,用于生成启动描述
def generate_launch_description():
# 返回一个启动描述,其中包含了三个节点
return LaunchDescription([
# 定义第一个节点,包名为'turtlesim',命名空间为'turtlesim1',可执行文件为'turtlesim_node',节点名为'sim'
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim'
),
# 定义第二个节点,包名为'turtlesim',命名空间为'turtlesim2',可执行文件为'turtlesim_node',节点名为'sim'
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim'
),
# 定义第三个节点,包名为'turtlesim',可执行文件为'mimic',节点名为'mimic',并进行了两个话题的重映射
Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
# 将'/input/pose'重映射为'/turtlesim1/turtle1/pose'
('/input/pose', '/turtlesim1/turtle1/pose'),
# 将'/output/cmd_vel'重映射为'/turtlesim2/turtle1/cmd_vel'
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
])
XML
<launch>
<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim1"/>
<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim2"/>
<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:
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "sim"
namespace: "turtlesim1"
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "sim"
namespace: "turtlesim2"
- node:
pkg: "turtlesim"
exec: "mimic"
name: "mimic"
remap:
-
from: "/input/pose"
to: "/turtlesim1/turtle1/pose"
-
from: "/output/cmd_vel"
to: "/turtlesim2/turtle1/cmd_vel"
2.1 检查启动文件
所有上述启动文件都在启动一个由 turtlesim 包中的三个节点组成的系统。该系统的目标是启动两个 turtlesim 窗口,并让一个乌龟模仿另一个乌龟的动作。
当启动两个 turtlesim 节点时,它们之间唯一的区别是它们的命名空间值。唯一的命名空间允许系统启动两个节点,而不会出现节点名称或主题名称冲突。在此系统中的两只乌龟都通过相同的主题接收命令,并在相同的主题上发布它们的姿态。有了唯一的命名空间,就可以区分出为不同乌龟准备的消息。
最后一个节点也来自 turtlesim 包,但是一个不同的可执行文件: mimic 。这个节点增加了重映射的配置细节。 mimic 的 /input/pose 主题被重映射到 /turtlesim1/turtle1/pose ,它的 /output/cmd_vel 主题重映射到 /turtlesim2/turtle1/cmd_vel 。这意味着 mimic 将订阅 /turtlesim1/sim 的姿态主题,并重新发布它,供 /turtlesim2/sim 的速度命令主题订阅。换句话说, turtlesim2 将模仿 turtlesim1 的动作。
Python:
这些导入语句引入了一些 Python launch 模块。
from launch import LaunchDescription
from launch_ros.actions import Node
接下来,启动描述本身开始:
def generate_launch_description():
return LaunchDescription([
])
启动描述中的前两个动作将启动两个 turtlesim 窗口:
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim'
),
最终操作启动具有重映射的模仿节点:
Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
XML:
前两个操作启动了两个 turtlesim 窗口:
<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim1"/>
<node pkg="turtlesim" exec="turtlesim_node" name="sim" namespace="turtlesim2"/>
最终操作启动具有重映射的模仿节点:
<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"
- node:
pkg: "turtlesim"
exec: "turtlesim_node"
name: "sim"
namespace: "turtlesim2"
最终操作启动具有重映射的模仿节点:
- node:
pkg: "turtlesim"
exec: "mimic"
name: "mimic"
remap:
-
from: "/input/pose"
to: "/turtlesim1/turtle1/pose"
-
from: "/output/cmd_vel"
to: "/turtlesim2/turtle1/cmd_vel"
3 ros2 启动
Python:
cd launch
ros2 launch turtlesim_mimic_launch.py
XML:
cd launch
ros2 launch turtlesim_mimic_launch.xml
YAML:
cd launch
ros2 launch turtlesim_mimic_launch.yaml
便条
可以直接启动一个启动文件(如上所述),或者由一个包提供。当它由一个包提供时,语法是:
ros2 launch <package_name> <launch_file_name>
您在“创建包”中学习了如何创建包。https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Creating-Your-First-ROS2-Package.html
便条
对于带有启动文件的包,在包的 package.xml 中添加对 ros2launch 包的 exec_depend 依赖是一个好主意:
<exec_depend>ros2launch</exec_depend>
这有助于确保在构建包后 ros2 launch 命令可用。它还确保所有启动文件格式都被识别。
两个 turtlesim 窗口将会打开,你将看到以下 [INFO] 消息,告诉你启动文件已经启动了哪些节点:
[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]
要查看系统的操作,请打开一个新的终端并运行 ros2 topic pub 命令在 /turtlesim1/turtle1/cmd_vel 主题上以使第一只乌龟开始移动:
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}}"
您将看到两只乌龟沿着同一条路径行进。
4 使用 rqt_graph 自省系统
在系统仍在运行时,打开一个新终端并运行 rqt_graph ,以更好地了解启动文件中节点之间的关系。
执行命令:
一个隐藏节点(您运行的 ros2 topic pub 命令)正在向左侧的 /turtlesim1/turtle1/cmd_vel 主题发布数据, /turtlesim1/sim 节点已订阅此主题。图的其余部分显示了之前描述的内容: mimic 订阅了 /turtlesim1/sim 的姿态主题,并向 /turtlesim2/sim 的速度命令主题发布数据。
摘要
启动文件简化了运行具有许多节点和特定配置细节的复杂系统。您可以使用 Python、XML 或 YAML 创建启动文件,并使用 ros2 launch 命令运行它们。