第1章 · Nav2概览

导航栈架构、核心组件介绍、行为树基础。

Nav2 导航栈核心架构 行为树 (Behavior Tree) · 导航任务编排 全局规划器 (Global Planner) 局部规划器 (Local Planner) 代价地图 (Costmap) · 障碍物层 / 膨胀层 传感器 / 激光雷达 / 深度相机 里程计 (Odometry) / TF

1.1 导航栈架构 —— 从传感器到控制指令

Nav2 是 ROS2 官方维护的导航框架。说白了,它把机器人从 A 点移动到 B 点这件事,拆成了几个互相配合的模块。我个人习惯把导航栈想象成一个「三层漏斗」:最上层是行为树,中间是规划器,底层是代价地图和传感器数据。

你想想看,一个机器人要导航,首先得知道自己在哪(定位),然后要知道周围环境(地图),接着规划一条路(全局规划),再边走边躲开突然出现的障碍(局部规划)。Nav2 把这些步骤都标准化了。

核心设计理念: 模块化 + 可替换。全局规划器、局部规划器、代价地图、行为树都可以按需更换。我在项目中遇到过很多团队只换一个局部规划器,就把避障效果提升了一大截。

1.2 核心组件介绍

Nav2 里最重要的几个组件,我列个表,你一看就明白。

组件职责我的一点经验
全局规划器基于静态地图生成全局路径(A* / NavFn)调启发式权重能明显改变路径平滑度
局部规划器实时避障,跟踪全局路径(DWB / MPPI / TEB)MPPI 对动态障碍物更鲁棒,但计算量大
代价地图融合传感器数据,标记障碍物与膨胀区域膨胀半径设太大容易把路堵死,设太小又容易刮蹭
行为树编排导航任务(重规划、恢复、等待)用 XML 写行为树,比硬编码灵活太多了
定位模块AMCL / 里程计融合粒子滤波参数调不好,机器人容易「飘移」

嗯,这里要注意:代价地图其实分全局代价地图和局部代价地图。全局的用于规划,局部的用于避障。我刚开始做的时候把两个混为一谈,结果机器人老是急刹车。

1.3 行为树基础 —— 导航的大脑

行为树不是 Nav2 独有的,但 Nav2 把它用到了极致。你可以把行为树理解成「导航流程图」。每个节点是一个动作或条件,组合起来就是完整的导航逻辑。

举个例子,一个简单的导航行为树:

Sequence (主任务)
├── ComputePathToPose (规划全局路径)
├── FollowPath (执行路径跟踪)
└── 如果失败 → Recovery (旋转、清理代价地图)

为什么会用行为树?因为导航过程中经常出现意外:路径被堵、定位丢失、传感器超时。用行为树可以优雅地处理这些「异常流」。我记得有一次在工厂现场,机器人被叉车挡住,行为树自动触发「原地旋转 + 重规划」,五秒后就绕过去了。要是用传统状态机,那代码得写一箩筐。

💡 个人小技巧: 刚开始学行为树,别急着写复杂逻辑。先跑通 Nav2 自带的 nav2_tree.xml,然后改一两个节点,看看行为变化。我习惯用 bt_loop 工具可视化树结构,调试效率翻倍。

1.4 避坑指南 & 常见误解

  • 误解一:「全局规划器选 A* 就够了」—— 其实在窄通道环境,Hybrid-A* 或 Smac Planner 更安全。我曾经在仓库里用 A*,结果路径贴着货架,机器人根本过不去。
  • 误解二:「行为树越复杂越好」—— 恰恰相反。保持树深度不超过 4 层,否则调试时你会疯掉。我见过一个团队写了 30 个节点的树,最后自己都看不懂。
  • 误解三:「代价地图更新频率越高越好」—— 不是的。更新太快会导致 CPU 飙高,而且局部规划器来不及响应。我一般设 2~5 Hz,动态环境可以提到 10 Hz。
⚠️ 曾经踩过的坑: 有一次我把全局代价地图的膨胀半径设成了 0.8 米,结果机器人永远找不到穿过走廊的路径。后来才发现,膨胀层把整个走廊都堵死了。记住:膨胀半径一定要小于通道宽度的一半。

好了,这一章我们快速过了一遍 Nav2 的骨架。你心里应该有个整体印象了:行为树负责「决策」,规划器负责「路径」,代价地图负责「环境感知」。不过别急,先把这些概念消化掉。