01 nav2_bringup——一键启动脚本包
nav2_bringup — 系统启动包深度解读
一句话:Nav2 的"总电源开关",自身零算法代码,只有 launch 文件和配置文件,负责把所有节点按正确顺序、正确配置拉起来。
1. 文件结构总览
nav2_bringup/
├── CMakeLists.txt ← 只做安装,不编译任何代码
├── package.xml ← 依赖声明
├── launch/ ← 11个launch文件(核心)
│ ├── bringup_launch.py ← 总入口★
│ ├── navigation_launch.py ← 导航10节点★
│ ├── localization_launch.py ← 定位2节点★
│ ├── slam_launch.py ← SLAM模式★
│ ├── rviz_launch.py ← 可视化
│ ├── tb3_simulation_launch.py ← TurtleBot3 Gazebo仿真
│ ├── tb4_simulation_launch.py ← TurtleBot4 Gazebo仿真
│ ├── tb3_loopback_simulation.launch.py ← TB3 轻量仿真
│ ├── tb4_loopback_simulation.launch.py ← TB4 轻量仿真
│ ├── cloned_multi_tb3_simulation_launch.py ← 多机器人(克隆)
│ └── unique_multi_tb3_simulation_launch.py ← 多机器人(唯一命名空间)
├── params/ ← 参数配置(核心)
│ ├── nav2_params.yaml ← 全栈默认参数(470行)★
│ ├── nav2_multirobot_params_1.yaml ← 多机器人实例1
│ ├── nav2_multirobot_params_2.yaml ← 多机器人实例2
│ └── nav2_multirobot_params_all.yaml ← 多机器人共享参数
├── maps/ ← 内置测试地图
│ ├── tb3_sandbox.pgm/.yaml ← TurtleBot3 沙盒地图
│ ├── depot.pgm/.yaml ← 仓库地图
│ └── warehouse.pgm/.yaml ← 大型仓库地图
└── rviz/ ← RViz配置文件
├── nav2_default_view.rviz ← 单机默认视图
└── nav2_namespaced_view.rviz ← 多机命名空间视图
2. CMakeLists.txt 解读
find_package(ament_cmake REQUIRED)
find_package(nav2_common REQUIRED) ← 引入 nav2_package() 宏
find_package(navigation2 REQUIRED) ← 确保 Nav2 全栈已安装
nav2_package() ← nav2_common 提供的宏,设置编译标准等
# 四个目录全部安装到 share/nav2_bringup/
install(DIRECTORY launch DESTINATION share/${PROJECT_NAME})
install(DIRECTORY maps DESTINATION share/${PROJECT_NAME})
install(DIRECTORY rviz DESTINATION share/${PROJECT_NAME})
install(DIRECTORY params DESTINATION share/${PROJECT_NAME})
关键点:没有 add_library / add_executable,纯粹只是把文件夹复制到安装目录。
安装后路径:/opt/ros/jazzy/share/nav2_bringup/launch/bringup_launch.py 等。
3. launch 文件体系
3.1 总入口:bringup_launch.py
这是用户最常用的入口,内部做三路分支:
ros2 launch nav2_bringup bringup_launch.py [参数...]
│
▼
┌───────────────────────────────────────────────────┐
│ bringup_launch.py │
│ │
│ ① 启动 nav2_container(仅 use_composition=True) │
│ │
│ ② 定位分支(三选一,由 slam + use_localization 决定)│
│ ├─ slam=True → slam_launch.py │
│ ├─ slam=False → localization_launch.py │
│ └─ use_localization=False → 跳过(纯导航) │
│ │
│ ③ 始终执行 navigation_launch.py │
└───────────────────────────────────────────────────┘
所有可配置参数(带默认值)
| 参数名 | 默认值 | 含义 |
|---|---|---|
namespace | '' | 机器人命名空间(多机器人用) |
use_namespace | false | 是否启用命名空间 |
slam | False | 是否使用 SLAM 建图(vs 已有地图定位) |
map | '' | 地图文件路径(localization模式用) |
use_localization | True | 是否启用定位子系统 |
use_sim_time | false | 是否使用仿真时钟(Gazebo需设True) |
params_file | nav2_params.yaml | 参数文件路径 |
autostart | true | 启动后自动执行生命周期 startup |
use_composition | True | 是否用 Component Container(进程内通信) |
use_respawn | False | 节点崩溃后是否自动重启(非 composition 模式) |
log_level | info | 日志级别(debug/info/warn/error) |
多机器人命名空间替换机制
# 用户在 nav2_multirobot_params.yaml 里写占位符:
# <robot_namespace>/amcl
#
# launch 时自动替换:
params_file = ReplaceString(
source_file=params_file,
replacements={'<robot_namespace>': ('/', namespace)},
condition=IfCondition(use_namespace),
)
# 结果:/robot1/amcl(当 namespace='robot1' 时)
3.2 navigation_launch.py — 导航10节点
启动整个导航核心,有两种部署模式:
模式A:独立进程模式(use_composition=False)
每个节点 = 独立的 Linux 进程
节点间通信 = 走 DDS 网络(序列化/反序列化)
优点:隔离性好,一个崩溃不影响其他
缺点:通信有序列化开销,数据需要拷贝
启动的10个节点:
节点名 包 功能
─────────────────────────────────────────────────────────────────
controller_server nav2_controller 局部控制服务器
smoother_server nav2_smoother 路径平滑服务器
planner_server nav2_planner 全局规划服务器
route_server nav2_route 拓扑路网路由服务器
behavior_server nav2_behaviors 恢复行为服务器
bt_navigator nav2_bt_navigator 行为树导航调度器
waypoint_follower nav2_waypoint_follower 多航点导航
velocity_smoother nav2_velocity_smoother 速度指令平滑
collision_monitor nav2_collision_monitor 安全守护
docking_server opennav_docking 自动对接充电桩
──────────────────────────────────────────────────────────────────
lifecycle_manager_navigation nav2_lifecycle_manager 管理以上10个节点
模式B:组合节点模式(use_composition=True)
所有节点 = 加载到同一个 component_container_isolated 进程
节点间通信 = 直接函数调用(零拷贝)
优点:性能更高,延迟更低(对实时控制有意义)
缺点:一个崩溃可能带崩整个容器
启动流程:
bringup_launch.py 先创建容器节点 nav2_container
↓
navigation_launch.py 用 LoadComposableNodes 把10个节点加载进去
ComposableNode 写法示例:
ComposableNode(
package='nav2_controller',
plugin='nav2_controller::ControllerServer', # ← C++类名
name='controller_server',
parameters=[configured_params],
)
# vs 独立进程写法:
Node(
package='nav2_controller',
executable='controller_server', # ← 可执行文件名
name='controller_server',
)
cmd_vel 重映射
remappings=remappings + [('cmd_vel', 'cmd_vel_nav')]
controller_server、behavior_server、velocity_smoother 都把 cmd_vel 重映射到 cmd_vel_nav,原因:
cmd_vel_nav ← controller/behavior 输出的"原始"速度
↓
velocity_smoother (加速度限幅)
↓
cmd_vel_smoothed
↓
collision_monitor (最后防线,必要时减速/急停)
↓
cmd_vel ← 机器人实际执行
3.3 localization_launch.py — 定位2节点
启动节点:
map_server ← 加载静态地图
amcl ← 粒子滤波定位,广播 map→odom TF
lifecycle_manager_localization ← 管理以上2个节点
map_server 的条件启动:
map 参数为空 → 用 yaml 里配置的地图路径
map 参数非空 → 用命令行传入的地图路径(覆盖 yaml)
为什么定位单独一个 lifecycle_manager?
lifecycle_manager_localization 管理:map_server + amcl
lifecycle_manager_navigation 管理:controller + planner + ... (10个)
独立的好处:
AMCL 崩了 → 只重启定位子系统,不影响导航节点
导航节点崩了 → 不影响 AMCL 继续定位
可以单独 pause/resume 定位(换地图时)
3.4 slam_launch.py — SLAM建图模式
启动节点:
slam_toolbox (online_sync_launch.py) ← 外部包,实时同步SLAM
map_saver_server ← 随时保存当前地图
lifecycle_manager_slam ← 管理 map_saver
特殊逻辑:
检测 params_file 里是否有 slam_toolbox 段落(HasNodeParams)
有 → 把 params_file 传给 slam_toolbox
没有 → slam_toolbox 用自己的默认参数(避免传空yaml报错)
4. nav2_params.yaml 解读(470行默认参数)
这是整个 Nav2 的"出厂设置",每个节点的参数都在这里集中配置。
4.1 文件结构
amcl: ← AMCL定位参数
ros__parameters:
...
bt_navigator: ← 行为树导航参数
ros__parameters:
...
controller_server: ← 控制服务器 + MPPI参数
ros__parameters:
controller_frequency: 20.0
FollowPath:
plugin: "nav2_mppi_controller::MPPIController"
...
local_costmap: ← 局部代价地图(3m×3m滚动窗口)
...
global_costmap: ← 全局代价地图(整张地图)
...
planner_server: ← 规划服务器(默认用 NavFn,不是 Hybrid-A*!)
...
smoother_server: ← 平滑服务器
behavior_server: ← 恢复行为
waypoint_follower: ← 多航点导航
route_server: ← 拓扑路网
velocity_smoother: ← 速度平滑
collision_monitor: ← 碰撞监控
docking_server: ← 对接充电桩
loopback_simulator: ← 轻量仿真器
4.2 重要默认值速查
| 参数 | 默认值 | 注意 |
|---|---|---|
| 控制器 | MPPIController | 20Hz |
| 规划器 | NavfnPlanner(Dijkstra) | 不是 Hybrid-A*,需手动换 |
| 平滑器 | SimpleSmoother | 不是 ConstrainedSmoother |
| 机器人半径 | 0.22m | TurtleBot3 的半径,实际使用要改 |
| 膨胀半径 | 0.7m | local/global costmap 都是 0.7m |
| MPPI batch_size | 2000 | (比之前分析的1000更多) |
| MPPI time_steps | 56 步 × 0.05s = 2.8s | 预测时域 |
| AMCL 粒子数 | 500~2000 | KLD 自适应 |
| 目标容差 | xy=0.25m, yaw=0.25rad | 判断"到达目标" |
4.3 cmd_vel 完整流水线(从参数看)
collision_monitor:
cmd_vel_in_topic: "cmd_vel_smoothed" ← 从 velocity_smoother 接收
cmd_vel_out_topic: "cmd_vel" ← 输出给机器人底盘
完整链路:
controller_server → cmd_vel_nav
behavior_server → cmd_vel_nav
↓
velocity_smoother(订阅 cmd_vel_nav,发布 cmd_vel_smoothed)
↓
collision_monitor(订阅 cmd_vel_smoothed,发布 cmd_vel)
↓
机器人底盘
5. 地图文件格式解读
以 tb3_sandbox.yaml 为例:
image: tb3_sandbox.pgm ← 对应的图像文件(灰度图)
resolution: 0.050000 ← 每像素=0.05m,即5cm分辨率
origin: [-10.0, -10.0, 0.0] ← 地图左下角在世界坐标系中的位置
negate: 0 ← 0=白色是自由空间(正常),1=反转
occupied_thresh: 0.65 ← 像素值换算的占用概率>0.65 → 障碍
free_thresh: 0.196 ← 占用概率<0.196 → 自由空间
← 0.196~0.65之间 → 未知
pgm 图像编码规则:
像素值 255(白)→ 占用概率 ≈ 0 → 自由空间(FREE)
像素值 0 (黑)→ 占用概率 ≈ 1 → 障碍(LETHAL)
像素值 205(灰)→ 占用概率 ≈ 0.2 → 未知(UNKNOWN)
6. package.xml 关键依赖
<build_depend>nav2_common</build_depend> ← 提供 nav2_package() CMake宏
<build_depend>navigation2</build_depend> ← 编译时确保全栈可用
<exec_depend>slam_toolbox</exec_depend> ← SLAM模式需要
<exec_depend>ros_gz_sim</exec_depend> ← Gazebo仿真需要
<exec_depend>nav2_minimal_tb3_sim</exec_depend> ← TB3仿真模型
<exec_depend>nav2_minimal_tb4_sim</exec_depend> ← TB4仿真模型
注意:nav2_bringup 是少数几个依赖 navigation2(meta包) 的包之一,因为它需要在编译时确认整个 Nav2 栈都存在。
7. 一图总结 nav2_bringup 的作用
用户输入:ros2 launch nav2_bringup bringup_launch.py map:=my_map.yaml
│
bringup_launch.py(总调度)
│ │ │
▼ ▼ ▼
slam=False (条件) navigation_launch.py
use_loc=True 不启动 │
│ SLAM │ 启动10个导航节点
▼ │ + lifecycle_manager
localization_launch.py │
│ │
├── map_server ▼
├── amcl controller_server(MPPI)
└── lifecycle_manager_localization planner_server(NavFn)
bt_navigator
behavior_server
velocity_smoother
collision_monitor
...
全部读取 nav2_params.yaml 作为参数来源
全部输出日志到 screen
8. 一句话总结
nav2_bringup是 Nav2 的"一键启动脚本包":11个 launch 文件按不同场景组合启动节点,1个 470 行的 nav2_params.yaml 集中管理所有默认参数,3张测试地图开箱即用。自身零算法代码,全是"胶水"。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)