本节摘要:地图有了,本节让机器人自主走起来。Nav2 是 ROS2 官方导航栈,本节抓它的三个核心机制:代价地图如何把"哪里危险"量化成分层叠加的网格,全局规划与局部控制如何分工处理"走哪条路"与"这一秒怎么动",行为树导航器如何组织任务与恢复。全程以 NavigateToPose 动作为主线——你将看到第 3 章动作三段式的教科书级实战。
给机器人一个目标点,它要做的事比"走过去"多得多:现在在哪(定位)、路怎么走(规划)、眼前这秒怎么动(控制)、卡住了怎么办(恢复)。Nav2 把这四件事拆成一组独立的生命周期节点,用行为树编排。理解它的最快路径不是读参数表,而是跟着一次真实的导航任务走完全程,看数据如何在节点间流动。
Nav2 的核心数据结构是代价地图——一张与地图同分辨率的网格,每格一个代价值:空闲可走、未知、致命(障碍本体)、膨胀(离障碍越近代价越高)。机器人规划时绕开高代价区域,就像水流绕开石头。
代价地图不是一张图而是多层叠加,每层回答一个问题:
| 层 | 回答的问题 | 数据来源 | 更新频率 |
|---|---|---|---|
| 静态层 | 墙在哪 | map_server 的地图 | 不更新 |
| 障碍层 | 新出现的障碍在哪 | 雷达或点云滚动标记与清除 | 传感器频率 |
| 膨胀层 | 靠障碍多近会危险 | 由上面两层计算 | 随源层更新 |
| 体素层(可选) | 三维障碍(桌沿)在哪 | 三维点云 | 传感器频率 |
膨胀半径是最值得花时间调的参数:它应当等于"机器人外接圆半径加安全余量"。设小了机器人家具蹭墙,设大了窄走廊直接判死路——很多"明明能过却绕路"的问题,病灶就是膨胀半径贪大。另一个高发误区是把它当成速度相关量:其实决定安全余量的是控制精度与感知延迟,高速场景该调的是控制频率,不是无脑加膨胀。
Nav2 把"走过去"拆成两级。全局规划器(如 NavFn 或 Smac)在静态代价地图上算一条从当前位置到目标的路径——它管战略,只在目标下发或路径失效时重算,频率低。局部控制器(默认 DWB)只负责跟踪这条路径的"下一小段"——它管战术,以 20 Hz 的频率在局部代价地图上实时微调速度指令,躲开突然出现的行人。
# 用动作接口下发一次导航(3.2 节的动作在实战中的样子) ros2 action send_goal /navigate_to_pose nav_msgs/action/NavigateToPose \ "{pose: {header: {frame_id: map}, pose: {position: {x: 3.2, y: 1.5}}}}" --feedback # feedback 流(节选) # distance_remaining: 2.87 # estimated_time_remaining: 11.5 # number_of_recoveries: 0 # 结果 # status: SUCCEEDED
反馈流是调试导航的黄金观测点:distance_remaining 不减说明机器人在原地打转;number_of_recoveries 持续增长说明路径反复失效。两级分工的失败语义也不同:全局失败(起点或终点在致命区)立刻返回失败;局部失败(当前段被堵)先触发恢复行为,恢复无效才升级为任务失败。
导航器内部是一棵行为树:主干是"规划、跟随、若失败则恢复、重试"。恢复行为按代价从低到高排队:先清除代价地图(可能是传感器噪声污染了障碍层),再原地旋转(可能是雷达盲区作祟),最后后退重规划(路真的被堵了)。这个排序的哲学是便宜优先——能靠"揉揉眼睛"解决的,不动腿。

Nav2 的参数文件以长闻名(数百行),但真正决定成败的就三组。控制器组:最大速度加速度要匹配底盘实际能力,虚高的上限会让控制器输出底盘执行不了的指令,表现为走蛇形。膨胀组:前面说过,半径加代价缩放系数。恢复组:各类恢复的触发次数与超时,太敏感则任务动辄中断,太迟钝则卡死不报。
Launch 侧用 4.3 节的组合:nav2_bringup 提供现成的导航启动文件,把 map_yaml、参数文件、autostart 传进去即可;所有服务器由 lifecycle_manager 编排激活——4.1 与 4.4 的知识在这里全面兑现。
⚠️ 常见坑:use_sim_time 在仿真与实车间切换时最容易漏改——仿真里时间来自 /clock 话题,实车来自系统钟。忘了改,TF 查询会因时间戳体系不一致而超时,症状与"定位挂了"一模一样,却是纯配置问题。
参数之外,导航栈跑起来后的日常观测集中在三个信号上,它们分别回答"走得动吗""走得对吗""卡不卡"。
信号一:控制频率的真实值。局部控制器的标称周期是参数里写的,实际执行周期要用 hz 实测——计算超载或回调阻塞会让它悄悄掉到一半,轨迹跟踪质量随之劣化,而日志不会告诉你。信号二:恢复行为的触发频率。行为树日志里恢复行为的触发记录是系统健康的直接指标:偶尔触发正常,频繁触发说明环境、定位或膨胀参数有问题——机器人频繁"揉眼睛",多半是看得不清。信号三:路径的抖动。RViz 里全局路径如果每次重算都大幅跳动,说明代价地图不稳定(障碍层噪声、定位抖动)或目标附近代价梯度混乱,控制器追着抖动的路径跑,速度指令必然抖。
三个信号组成一个粗筛漏斗:频率掉先查算力与回调,恢复频繁先查定位与传感器,路径抖先查代价地图稳定性。多数"导航忽好忽坏"的报告,用这个漏斗走一遍,十分钟内能把问题归到具体一层——比笼统地"调参数"高效得多。
最后补一条配置纪律:任何一组调好的导航参数,都应与一份录制的现场数据(7.4 节)配对归档。参数是答案,数据是题目;只存答案不存题目,下次换环境调参时连"当初为什么这么设"都无从考证。
轮式机器人会走了。下一节换一个主角:机械臂如何在三维空间里规划出无碰撞的轨迹。