在 ROS 2 导航框架 Nav2 中,bringup_launch.py 是连接硬件、地图和导航算法的核心。本文基于官方源码及社区文档,解析命名空间隔离、动态组合、条件启动等高级配置技巧,适用于多机器人系统或资源受限的嵌入式部署。
一、bringup 文件结构概览
bringup_launch.py 分为三部分:参数声明、条件启动判断、动作组定义。
1.1 参数声明
文件开头声明了以下参数(默认值因版本而异,此处仅说明功能):
python namespace = LaunchConfiguration('namespace') use_namespace = LaunchConfiguration('use_namespace') slam = LaunchConfiguration('slam') map_yaml_file = LaunchConfiguration('map') use_sim_time = LaunchConfiguration('use_sim_time') params_file = LaunchConfiguration('params_file') autostart = LaunchConfiguration('autostart') use_composition = LaunchConfiguration('use_composition') use_respawn = LaunchConfiguration('use_respawn') log_level = LaunchConfiguration('log_level') use_localization = LaunchConfiguration('use_localization')
| 参数 | 作用 |
|---|---|
| namespace | 设置节点所在的命名空间,例如 robot1 |
| use_namespace | 是否启用 namespace,为 true 时节点和相对话题名会放入该命名空间 |
| slam | 是否选择 SLAM 模式 |
| map | 地图 YAML 文件的完整路径 |
| use_localization | 是否启动定位相关部分 |
| use_sim_time | 是否使用仿真时钟 |
| params_file | 所有相关节点使用的 ROS 参数 YAML 文件路径 |
| autostart | 是否自动启动 Nav2 的生命周期节点 |
| use_composition | 是否使用组合节点方式运行 Nav2 |
| use_respawn | 进程退出后是否自动重启(非组合模式下有效) |
| log_level | 日志级别 |
1.2 条件启动
通过 IfCondition 和 PythonExpression 决定是否启动子 launch 文件:
slam_launch.py:当slam与use_localization同时为真时启动,用于 SLAM 建图。localization_launch.py:当slam为假且use_localization为真时启动,用于 AMCL 定位。navigation_launch.py:无条件启动,负责所有导航节点的生命周期管理。
二、命名空间:多机器人系统的隔离基石
ROS 2 的命名空间可避免不同机器人之间的话题、节点重名。通过 namespace 和 use_namespace 参数,可将所有启动的节点和相对话题名放入指定命名空间。
2.1 全局话题重映射
文件开头定义了重映射:
python remappings = [('/tf', 'tf'), ('/tf_static', 'tf_static')]
将全局话题 /tf、/tf_static 转换为相对话题 tf、tf_static。相对话题会继承节点所在的命名空间,因此在多机器人场景下,每个机器人的 TF 数据不会互相冲突。
2.2 参数文件中的命名空间适配
启用命名空间时,参数文件需经过两步处理:
- ReplaceString:将参数文件中的占位符
<robot_namespace>替换为实际的命名空间值。 - RewrittenYaml:将处理后的 YAML 文件以命名空间作为根键。例如,默认结构:
yaml controller_manager: ros__parameters: update_rate: 100
处理后(命名空间为 robot1)变为:
yaml robot1: controller_manager: ros__parameters: update_rate: 100
这样,节点加载参数时会自动查找正确的命名空间路径。
2.3 PushRosNamespace 与 GroupAction
在动作组中使用 PushRosNamespace 为一组节点设置命名空间:
python bringup_cmd_group = GroupAction([ PushRosNamespace( condition=IfCondition(use_namespace), namespace=namespace), # ... 其他节点和启动描述 ])
GroupAction 将多个动作组合在一起,PushRosNamespace 将指定命名空间压入当前上下文,其作用域仅限于该组动作。组动作结束时命名空间自动弹出。
三、组合模式:进程内通信优化
组合(Composition)将多个节点运行在同一个进程中,减少进程间通信开销,适合资源受限的嵌入式系统。
3.1 组合容器
当 use_composition 为 True 时,启动名为 nav2_container 的组合容器节点:
python Node( condition=IfCondition(use_composition), name='nav2_container', package='rclcpp_components', executable='component_container_isolated', parameters=[configured_params, {'autostart': autostart}], arguments=['--ros-args', '--log-level', log_level], remappings=remappings, output='screen', )
该容器加载所有 Nav2 组件(如 controller_server、planner_server 等),组件在同一进程中通过内存共享通信。
3.2 组合与独立启动的权衡
动态组合是默认启用的,可通过命令行参数 use_composition:=False 禁用。禁用后各节点以独立进程启动,便于调试和版本兼容。
已知问题:使用 clang 编译器从源码构建 Nav2 并启用组合时,可能遇到
MultiLibraryClassLoader错误,导致StaticLayer无法实例化(Issue #5025)。此时设置use_composition:=False可绕过该问题。
四、条件启动:灵活切换建图与定位
通过 slam 和 use_localization 参数可在运行时选择功能:
- 启动
slam_launch.py:条件为slam and use_localization,用于在线建图。 - 启动
localization_launch.py:条件为not slam and use_localization,用于已有地图时的定位。 - 启动
navigation_launch.py:无条件启动,始终运行导航节点。
示例命令:
bash
已知地图环境
ros2 launch nav2_bringup bringup_launch.py
slam:=false
use_localization:=true
map:=/path/to/map.yaml
未知环境建图
ros2 launch nav2_bringup bringup_launch.py
slam:=true
use_localization:=true
五、参数文件处理:命名空间适配详解
当启用命名空间时,参数文件需经过两步处理:
- 字符串替换:使用
ReplaceString将<robot_namespace>替换为实际命名空间。 - YAML 重写:使用
RewrittenYaml将根键设置为命名空间,确保参数隔离。
六、已知问题与注意事项
6.1 clang 编译器与组合模式的冲突
根据 Issue #5025,使用 clang 编译并启用组合时可能出现初始化失败:
MultiLibraryClassLoader: Could not create object of class type nav2_costmap_2d::StaticLayer as no factory exists for it.
解决方案:临时将 use_composition 设置为 False,或等待官方修复。
6.2 多机器人仿真中的 TF 重映射限制
官方 README 指出,启动文件中直接重映射 /tf 和 /tf_static 对 spawn_entity 节点无效。正确的做法是在 SDF 文件中为每个插件单独设置重映射:
xml <remapping>/tf:=tf</remapping> <remapping>/tf_static:=tf_static</remapping>
否则不同机器人的 TF 数据可能混淆。
七、实践建议与下一步
- 初学者:使用默认配置启动,尝试不同参数组合,观察命名空间和组合模式的效果。
- 多机器人开发者:启用
use_namespace,利用cloned_multi_tb3_simulation_launch.py等工具进行仿真测试。 - 嵌入式用户:资源允许时启用组合模式以优化性能;遇到编译或运行时错误,尝试禁用组合或切换编译器。
通过本文,您应能自信地配置和调试 Nav2 启动系统。下一步可阅读 Nav2 官方文档中的 Getting Started 页面,或深入研究各个子 launch 文件的源码。