跳到主要内容

前言

Launch 文件是 ROS2 中用于 “描述如何启动整个系统” 的配置文件”。它能够一次性启动多个节点,并集中管理参数、命名空间和话题重映射,是构建可复现、工程化 ROS2 系统的核心工具。通过 launch 文件,可以明确系统需要运行哪些节点、如何运行它们、以及应当传递哪些参数,从而使同一组件在不同的配置和运行场景下都能够方便而灵活地复用。

编写并使用启动文件

在工作空间(ros2_ws)下面创建一个新目录 launch。使用 turtlesim 功能包及其可执行文件来编写一个 ROS2 启动文件。 如上所述,这可以是 XML、YAML 或 Python 格式。对于 ROS2,使用 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'
),
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'),
]
)
])

代码解释

上述启动文件启动了一个由三个节点组成的系统,所有节点都来自 turtlesim 功能包。上述代码的目标是启动两个 turtlesim 窗口,并让一个海龟模仿另一个海龟运动。

在启动两个 turtlesim 节点时,它们之间唯一的区别是它们的命名空间值。不同的命名空间允许系统启动两个节点,而不会出现节点名称或话题名称冲突。这两个海龟都在同一个话题上接收命令,并在同一个话题上发布它们的姿态。通过不同的命名空间,可以区分不同海龟的消息。

最后一个节点也来自 turtlesim 功能包,但是一个不同的可执行文件:mimic。这个节点形式为重映射。mimic/input/pose 话题被重映射到 /turtlesim1/turtle1/pose,它的 /output/cmd_vel 话题被重映射到 /turtlesim2/turtle1/cmd_vel。这意味着 mimic 将订阅 turtlesim1 的姿态,并重新发布它,以便 turtlesim2 的速度话题可以订阅。换句话说,turtlesim2 将模仿 turtlesim1 的运动。

下面这些语句引入了一些 Python 启动模块。 LaunchDescription 将定义启动文件的顶层结构,包含多个启动任务, Node 定义单个节点的启动配置,包括功能包名称、可执行文件名、节点名称、命名空间等。

from launch import LaunchDescription
from launch_ros.actions import Node

接下来是启动描述命令:

def generate_launch_description():
return LaunchDescription([
Node(),
])

启动描述命令中的前两个 Node 是启动两个 turtlesim 窗口:

        Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim'
),

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

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

使用 ros2 launch

要运行上面创建的启动文件,进入之前创建的目录(ros2_ws/launch),然后运行以下命令:

ros2 launch turtlesim_mimic_launch.py

注意: 可以直接运行启动文件(如上所示),也可以在功能包中运行启动文件,后面章节会介绍。

在两个 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}}"

我们会看到两个海龟沿着相同的路径移动。

将启动文件集成到功能包中

在上一节内容中,我们看到了如何编写一个独立的启动文件。该部分内容将展示如何向现有功能包中添加启动文件。

1. 创建一个功能包

为功能包创建一个工作空间:

mkdir -p launch_ws/src
cd launch_ws/src
ros2 pkg create --build-type ament_python --license Apache-2.0 py_launch_example

2. 创建存放启动文件的结构 (python)

按照约定,功能包的所有启动文件都存储在功能包内的 launch 目录中。 在刚刚创建的功能包的最上层目录中创建一个 launch 目录。对于Python包,功能包的目录应该如下所示:

src/
py_launch_example/
launch/
package.xml
py_launch_example/
resource/
setup.cfg
setup.py
test/

为了使 colcon 能够定位和使用启动文件,我们需要通进行如下设置。 对于python的功能包,打开setup.py文件,在顶部添加必要的 import 语句,并将启动文件包含到 setupdata_files参数中:

import os
from glob import glob
# 其他导入...

package_name = 'py_launch_example'

setup(
# 其他参数...
data_files=[
# ... 其他数据文件
# 包含所有的启动文件。
(os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.[pxy][yma]*'))),
]
)

对于C++功能包,功能包的目录应该如下所示:

src/
  cpp_launch_example/
    launch/
    package.xml
    CMakeLists.txt/
    src/
    include/

只需要在功能包中CMakeLists文件的结尾(ament_package())前添加如下内容:

# Install launch files.
install(DIRECTORY
  launch
  DESTINATION share/${PROJECT_NAME}/
)

3. 编写启动文件

launch 目录中,创建一个新的名为 my_script_launch.py 启动文件。 _launch.py 是推荐但不是必需的启动文件后缀。 然而,启动文件名需要以 launch.py 结尾,才能被 ros2 launch 识别和自动补全。编写的启动文件应该定义 generate_launch_description() 函数,该函数返回一个launch.LaunchDescription(),由 ros2 launch 命令使用。

import launch
import launch_ros.actions

def generate_launch_description():
return launch.LaunchDescription([
launch_ros.actions.Node(
package='demo_nodes_cpp',
executable='talker',
name='talker'),
])

4. 构建和运行启动文件

前往工作空间的根目录进行构建:colcon build 成功后,加载工作空间,运行如下启动文件:

ros2 launch py_launch_example my_script_launch.py