目标:学习使用 ROS 2 启动文件管理大型项目的最佳实践。
教程级别:中级
时间:20 分钟
目录
背景
先决条件
简介
编写启动文件
1. 顶层组织
2.参数
在启动文件中设置参数
加载 YAML 文件中的参数
在 YAML 文件中使用通配符
3. 命名空间
4. 复用节点
5 .参数覆盖
6. 重映射
7 个配置文件
8 个环境变量
运行启动文件
1. 更新 setup.py
2. 建立并运行
摘要
背景
本教程介绍了一些针对大型项目编写启动文件的技巧。重点是如何构建启动文件,以便在不同情况下尽可能多地复用。此外,它还涵盖了不同 ROS 2 启动工具的使用示例,如参数、YAML 文件、重映射、命名空间、默认参数和 RViz 配置。
先决条件
本教程使用 turtlesim 和 turtle_tf2_py 包。本教程还假设您已经创建了一个名为 launch_tutorial
的 ament_python
类型的新包。
简介
在机器人上的大型应用通常涉及几个相互连接的节点,每个节点都可以有许多参数。多乌龟模拟器中的多乌龟模拟可以作为一个很好的例子。乌龟模拟由多个乌龟节点、世界配置以及 TF 广播器和监听器节点组成。在所有这些节点之间,有大量的 ROS 参数影响这些节点的行为和外观。ROS 2 启动文件允许我们在一个地方启动所有节点并设置相应的参数。在教程的最后,你将在 launch_tutorial
包中构建 launch_turtlesim_launch.py
启动文件。这个启动文件将启动负责两个 turtlesim 模拟的不同节点,启动 TF 广播器和监听器,加载参数,并启动一个 RViz 配置。在本教程中,我们将讨论这个启动文件及其所有相关功能。
编写启动文件
1. 顶层组织
在编写启动文件的过程中,一个目标应该是使它们尽可能地可重用。这可以通过将相关的节点和配置聚集到单独的启动文件中来完成。之后,可以编写一个专用于特定配置的顶层启动文件。这将允许在相同的机器人之间移动而根本不需要更改启动文件。即使是从真实的机器人移动到模拟的机器人这样的更改,也只需做少量的更改。
我们现在将讨论使这成为可能的顶层启动文件结构。首先,我们将创建一个启动文件,该文件将调用单独的启动文件。为此,让我们在我们的 launch_tutorial
包的 /launch
文件夹中创建一个 launch_turtlesim_launch.py
文件。
import os # 导入os模块,这个模块提供了很多与操作系统交互的函数
from ament_index_python.packages import get_package_share_directory # 从ament_index_python.packages导入get_package_share_directory函数,这个函数用于获取包的共享目录
from launch import LaunchDescription # 从launch导入LaunchDescription,这是ROS2中用于描述启动过程的类
from launch.actions import IncludeLaunchDescription # 从launch.actions导入IncludeLaunchDescription,这是一个动作,用于包含其他的启动描述
from launch.launch_description_sources import PythonLaunchDescriptionSource # 从launch.launch_description_sources导入PythonLaunchDescriptionSource,这是一个描述源,用于从Python文件中加载启动描述
def generate_launch_description(): # 定义一个函数,用于生成启动描述
turtlesim_world_1 = IncludeLaunchDescription( # 创建一个IncludeLaunchDescription动作,用于包含turtlesim_world_1的启动描述
PythonLaunchDescriptionSource([os.path.join( # 使用PythonLaunchDescriptionSource从Python文件中加载启动描述
get_package_share_directory('launch_tutorial'), 'launch'), # 使用get_package_share_directory函数获取'launch_tutorial'包的共享目录,然后加上'launch'子目录
'/turtlesim_world_1_launch.py']) # 加上启动文件的名称,得到完整的文件路径
)
turtlesim_world_2 = IncludeLaunchDescription( # 创建一个IncludeLaunchDescription动作,用于包含turtlesim_world_2的启动描述
PythonLaunchDescriptionSource([os.path.join( # 使用PythonLaunchDescriptionSource从Python文件中加载启动描述
get_package_share_directory('launch_tutorial'), 'launch'), # 使用get_package_share_directory函数获取'launch_tutorial'包的共享目录,然后加上'launch'子目录
'/turtlesim_world_2_launch.py']) # 加上启动文件的名称,得到完整的文件路径
)
broadcaster_listener_nodes = IncludeLaunchDescription( # 创建一个IncludeLaunchDescription动作,用于包含broadcaster_listener_nodes的启动描述
PythonLaunchDescriptionSource([os.path.join( # 使用PythonLaunchDescriptionSource从Python文件中加载启动描述
get_package_share_directory('launch_tutorial'), 'launch'), # 使用get_package_share_directory函数获取'launch_tutorial'包的共享目录,然后加上'launch'子目录
'/broadcaster_listener_launch.py']), # 加上启动文件的名称,得到完整的文件路径
launch_arguments={'target_frame': 'carrot1'}.items(), # 设置启动参数,这些参数会传递给被包含的启动描述
)
mimic_node = IncludeLaunchDescription( # 创建一个IncludeLaunchDescription动作,用于包含mimic_node的启动描述
PythonLaunchDescriptionSource([os.path.join( # 使用PythonLaunchDescriptionSource从Python文件中加载启动描述
get_package_share_directory('launch_tutorial'), 'launch'), # 使用get_package_share_directory函数获取'launch_tutorial'包的共享目录,然后加上'launch'子目录
'/mimic_launch.py']) # 加上启动文件的名称,得到完整的文件路径
)
fixed_frame_node = IncludeLaunchDescription( # 创建一个IncludeLaunchDescription动作,用于包含fixed_frame_node的启动描述
PythonLaunchDescriptionSource([os.path.join( # 使用PythonLaunchDescriptionSource从Python文件中加载启动描述
get_package_share_directory('launch_tutorial'), 'launch'), # 使用get_package_share_directory函数获取'launch_tutorial'包的共享目录,然后加上'launch'子目录
'/fixed_broadcaster_launch.py']) # 加上启动文件的名称,得到完整的文件路径
)
rviz_node = IncludeLaunchDescription( # 创建一个IncludeLaunchDescription动作,用于包含rviz_node的启动描述
PythonLaunchDescriptionSource([os.path.join( # 使用PythonLaunchDescriptionSource从Python文件中加载启动描述
get_package_share_directory('launch_tutorial'), 'launch'), # 使用get_package_share_directory函数获取'launch_tutorial'包的共享目录,然后加上'launch'子目录
'/turtlesim_rviz_launch.py']) # 加上启动文件的名称,得到完整的文件路径
)
return LaunchDescription([ # 创建一个LaunchDescription,包含了所有的启动动作
turtlesim_world_1,
turtlesim_world_2,
broadcaster_listener_nodes,
mimic_node,
fixed_frame_node,
rviz_node
])
此启动文件包含一组其他启动文件。这些包含的启动文件中的每一个都包含节点、参数,可能还包含嵌套的包含,这些都与系统的某一部分相关。确切地说,我们启动了两个 turtlesim 仿真世界、TF 广播器、TF 监听器、mimic、固定帧广播器和 RViz 节点。
便条
设计提示:顶层启动文件应该简短,包括对应用程序子组件的其他文件的包含,以及常见的更改参数。
以这种方式编写启动文件可以轻松地更换系统的一部分,正如我们稍后将看到的。然而,由于性能和使用原因,有些节点