3. Nav2框架解析:整体架构与核心模块

Nav2这个框架,说白了就是ROS2机器人导航的"大脑"和"四肢"组合。我最早接触Nav2时,第一反应是"怎么这么多节点?"但用久了你会发现,这种模块化设计其实非常优雅。每个模块各司其职,出了问题也好排查。

嗯,咱们先看整体架构,再拆开细聊四个核心模块:BT Navigator、Planner、Controller、Recovery。

Nav2 核心架构图 BT Navigator (行为树导航器) 任务编排与决策核心 Planner (规划器) 全局路径规划 A* / Dijkstra / Smac Controller (控制器) 局部路径跟踪 DWB / Regulated Pure Pursuit Recovery (恢复器) 异常处理与自恢复 旋转/后退/清除代价地图 Costmap (代价地图) 全局代价地图 + 局部代价地图 传感器输入层 激光雷达 / 里程计 / 深度相机 / IMU 决策层 地图层 感知层

3.1 整体架构:插件化设计的魅力

Nav2的架构,我习惯把它理解成一个"乐高积木系统"。每个模块都是一个插件,你可以自由组合、替换。比如你今天想用A*做全局规划,明天想换成Smac Planner,改个参数就行,不用动代码。

整个流程是这样的:

  • 行为树导航器接收导航目标,然后像项目经理一样,调度下面的模块干活
  • Planner负责"看地图,找大路"——生成全局路径
  • Controller负责"看脚下,躲障碍"——跟踪局部路径
  • Recovery是"救火队"——卡住了就自己想办法脱困

核心思想:Nav2把导航任务拆成了"规划-控制-恢复"三个独立环节,每个环节都可以独立替换。这种设计让调试变得非常方便——哪个环节出问题,就盯着哪个环节查。

3.2 BT Navigator:行为树导航器

BT Navigator是Nav2的大脑。它不直接控制机器人,而是用行为树来编排整个导航流程。

什么是行为树?你可以把它想象成一个"流程图+决策树"的混合体。每个节点代表一个动作或条件,节点之间用"顺序"、"选择"、"并行"等控制节点连接。

我个人习惯把行为树比作"导航剧本"——机器人按照剧本一步步演:先规划路径,再跟踪路径,如果遇到障碍就尝试恢复,恢复不了就上报失败。

实战经验:我在调试一个仓储机器人时,发现机器人每次卡住都要等5秒才触发恢复。后来查了行为树配置,发现是"等待超时"节点设得太长了。把超时从5秒改成1.5秒,问题立刻解决。所以,行为树的参数调优,往往比算法调参更立竿见影。

BT Navigator支持多种行为树模板,最常用的是navigate_to_pose和navigate_through_poses。前者是"去一个点",后者是"经过一系列点"。

3.3 Planner:全局路径规划器

Planner的任务很简单:给你一张地图,一个起点,一个终点,算出一条能走的路。

Nav2内置了几种规划器:

规划器名称 算法核心 适用场景 我踩过的坑
NavFn Planner Dijkstra / A* 通用场景,稳定可靠 地图大了容易慢,建议限制搜索范围
Smac Planner Hybrid-A* / Lattice 需要考虑车辆运动学 参数多,调起来费劲,但效果确实好
Theta* Planner Theta* (任意角度) 需要更平滑的路径 计算量比A*大,适合离线规划

嗯,这里要注意:Planner生成的路径是"全局参考",它不考虑动态障碍物。动态避障是Controller的事。

曾经踩过的坑:有一次我在一个狭窄走廊里测试,Planner算出来的路径贴着墙走,机器人稍微偏一点就撞上了。后来发现是代价地图的膨胀半径设得太小。记住:Planner的路径质量,很大程度上取决于代价地图的参数。

3.4 Controller:局部路径控制器

Controller是真正"开车"的模块。它拿到Planner给的全局路径,然后结合实时传感器数据,算出速度指令(线速度+角速度),让机器人沿着路径走。

Nav2里最常用的两个控制器:

  • DWB Controller(Dynamic Window Approach的升级版):它会模拟未来几秒内的各种速度组合,选一条最安全、最接近目标路径的。我一般用这个,因为它对动态障碍物的反应比较灵敏。
  • Regulated Pure Pursuit:纯追踪算法的改进版。它会在路径上选一个"前瞻点",然后控制机器人追着那个点走。优点是参数少、调起来简单;缺点是在狭窄空间里容易来回摆动。

你想想看,Controller其实是在做"平衡"——既要跟得上全局路径,又要躲得开突然出现的障碍物。这个平衡点,往往需要通过实际跑车来调。

我的调试习惯:先让机器人走一条没有障碍物的直线,调好PID参数。然后加一个静态障碍物,调避障参数。最后才上动态障碍物。一步步来,别想一口吃成胖子。

3.5 Recovery:异常恢复机制

Recovery模块,说白了就是"机器人自救指南"。当Controller发现走不动了(比如被障碍物卡住、路径被完全堵死),就会触发恢复行为。

Nav2内置了几种恢复行为:

  1. 旋转恢复:原地转一圈,重新扫描周围环境。很多时候,转一下就能找到新路。
  2. 后退恢复:向后倒退一段距离,给重新规划留出空间。
  3. 清除代价地图:把代价地图上的"记忆"清掉,重新从传感器获取数据。有时候是地图上的"幽灵障碍"导致卡住。

我曾经在一个工厂项目里遇到过:机器人每次经过一个金属货架旁边就会卡住。查了半天,发现是激光雷达在金属表面产生了多路径反射,导致代价地图上出现了一个"假障碍"。后来加了清除代价地图的恢复行为,问题就解决了。

关键点:恢复行为不是万能的。如果连续触发恢复超过一定次数(默认3次),BT Navigator会判定导航失败,上报错误。这时候就需要人工介入了。

3.6 模块间的协作流程

最后,咱们串一下整个流程:

  1. 用户下发导航目标(比如"去坐标(5, 3)")
  2. BT Navigator启动行为树,先调用Planner
  3. Planner查询全局代价地图,算出一条全局路径
  4. BT Navigator把路径交给Controller
  5. Controller结合局部代价地图和传感器数据,实时计算速度指令
  6. 如果Controller发现路径被堵,触发Recovery
  7. Recovery尝试自救,成功后重新规划或继续跟踪
  8. 到达目标点,BT Navigator返回成功

这个流程看起来简单,但每个环节都有很多细节。后面几章我们会逐个模块深入调试。记住一句话:Nav2的调试,本质上是"代价地图参数 + 行为树配置 + 算法参数"三者的平衡。