第2章:Nav2核心架构解析

好,咱们直接切入正题。Nav2这个框架,说白了就是一套让机器人能自己找路、自己走的完整解决方案。我刚开始接触它的时候,第一反应是「这玩意儿怎么这么复杂?」后来拆开一看,其实核心逻辑非常清晰。

今天我就带你把它拆开揉碎,看看里面到底装了些什么。

2.1 Nav2整体框架:一个「大脑」和四个「器官」

Nav2的架构,我习惯把它比作一个机器人导航的「大脑」。这个大脑接收外部指令(比如「去厨房」),然后协调各个器官协同工作。

整体来看,它由以下几个核心部分组成:

  • 行为树导航器(BT Navigator):这是大脑的「决策中枢」。它不直接干活,但它决定什么时候该让谁干活。
  • 规划器(Planner):负责「想」——从A点到B点,全局路径怎么走。
  • 控制器(Controller):负责「做」——沿着规划好的路径,控制机器人实际移动。
  • 恢复器(Recovery):负责「救场」——出问题了怎么办?比如卡住了、迷路了。

这四个模块通过ROS2的通信机制(话题、服务、动作)紧密配合。嗯,这里要注意,它们不是各自为战,而是有严格的执行顺序。

核心要点:Nav2不是一个大而全的「单体」程序,而是一组可插拔的模块。你可以替换任何一个模块,只要它遵循相同的接口。我在项目中就曾把默认的DWB控制器换成纯PID控制器,效果还不错。

下面这张图,是我自己画的Nav2核心数据流。你看一眼,心里就有谱了。

Nav2核心架构与数据流 BT Navigator 行为树导航器 Planner 全局规划器 Controller 局部控制器 Recovery 恢复器 导航动作请求 路径跟踪指令 异常触发信号 全局路径 传感器数据输入:激光雷达 / 里程计 / 地图 速度指令 (cmd_vel)

2.2 BT Navigator:导航的「总指挥」

BT Navigator是Nav2里最容易被忽视、但最重要的模块。它不直接做路径规划,也不直接控制电机。它的工作是什么?是「决策」。

举个例子:你让机器人去厨房。BT Navigator会先问Planner:「路规划好了吗?」Planner说好了。然后它告诉Controller:「沿着这条路走。」Controller走了一半,发现前面有椅子挡住了。BT Navigator就会触发Recovery:「尝试原地旋转,看看能不能绕过去。」

你看,它就像一个项目经理,协调各个组员干活。

我的经验:很多人觉得BT Navigator只是个「调度器」,随便配配就行。我曾经也这么想,直到有一次机器人在走廊里反复横跳——后来发现是行为树里「重规划」的条件设置得太敏感了。调整一下阈值,问题就解决了。

BT Navigator的核心是行为树(Behavior Tree)。它用XML文件描述导航逻辑。比如:

<root main_tree_to_execute="MainTree">
  <BehaviorTree ID="MainTree">
    <Sequence>
      <ComputePathToPose goal="{goal}" path="{path}" />
      <FollowPath path="{path}" controller_id="FollowPath" />
    </Sequence>
  </BehaviorTree>
</root>

这段代码的意思是:先规划路径,再沿着路径走。简单明了。

2.3 Planner:全局路径的「设计师」

Planner负责生成从起点到终点的全局路径。它用的是全局代价地图(Global Costmap),这张地图包含了障碍物信息。

常见的Planner算法有:

算法 特点 适用场景
NavFn 基于Dijkstra,稳定可靠 大多数室内场景
Theta* 路径更平滑,拐角少 需要美观路径的场景
Smac Planner 支持混合A*,可处理非完整约束 差速/阿克曼底盘

我个人习惯用NavFn做默认,因为它最稳定。如果你需要更平滑的路径,可以试试Theta*。但要注意,平滑往往意味着计算量更大。

2.4 Controller:局部路径的「执行者」

Planner画好了大方向,Controller负责具体怎么走。它用的是局部代价地图(Local Costmap),实时感知周围环境。

Controller的核心任务是:在跟随全局路径的同时,避开动态障碍物。

常用的Controller有:

  • DWB Controller:Nav2默认的控制器,基于动态窗口法(DWA)的改进版。它会在每个控制周期内采样多组速度,选最优的一组。
  • MPPI Controller:基于模型预测控制(MPC),效果更好,但计算量也更大。
  • Regulated Pure Pursuit:纯追踪算法的改进版,适合低速场景。

注意:Controller的参数调优是Nav2里最磨人的环节。我曾经在一个项目里,为了调好DWB的「最大线速度」和「最大角速度」,整整花了两天。建议你从保守的参数开始,慢慢放开。

2.5 Recovery:导航的「救火队」

Recovery模块负责处理异常情况。导航不可能永远一帆风顺,总会有意外。

常见的恢复行为包括:

  • 原地旋转:清除局部代价地图中的「假障碍物」(比如传感器噪声导致的误检测)。
  • 后退:如果前方被堵死,尝试后退一段距离。
  • 重规划:放弃当前路径,重新规划一条新路径。
  • 等待:如果障碍物是动态的(比如行人),等它离开。

这些恢复行为也是通过行为树组织的。你可以自定义恢复策略,比如「先旋转三次,不行就后退,再不行就原地等待并报警」。

2.6 数据流与通信机制

Nav2各模块之间怎么通信?全靠ROS2的三大件:话题(Topic)、服务(Service)、动作(Action)。

我简单梳理一下:

  • 话题(Topic):用于持续的数据流。比如传感器数据(/scan)、里程计(/odom)、速度指令(/cmd_vel)。
  • 服务(Service):用于一次性的请求-响应。比如加载地图、获取代价地图信息。
  • 动作(Action):用于需要持续反馈的任务。比如导航到某个点(/navigate_to_pose),它会返回当前状态、反馈和最终结果。

举个例子,当你通过RVIZ点击「导航到某点」时,流程是这样的:

  1. RVIZ通过动作客户端发送 /navigate_to_pose 请求给BT Navigator。
  2. BT Navigator收到后,通过动作调用Planner的 /compute_path_to_pose 服务。
  3. Planner返回路径后,BT Navigator再通过动作调用Controller的 /follow_path 服务。
  4. Controller开始控制机器人移动,同时通过话题发布 /cmd_vel 速度指令。
  5. 如果Controller遇到问题,BT Navigator会触发Recovery模块。

你看,整个流程清晰得像流水线一样。

避坑指南:我曾经遇到过一个问题:机器人导航到一半突然停了,没有任何报错。排查了半天,发现是动作超时时间设置得太短。Planner计算路径稍微慢了一点,BT Navigator就认为它「死掉了」。所以,记得检查动作的超时参数。

好了,这一章的内容就到这里。Nav2的核心架构其实不复杂,关键是要理解各个模块的职责和它们之间的协作关系。下一章我们会深入行为树,看看怎么自定义导航逻辑。

可可精品资料库