第3章 全局路径规划与局部路径规划

Global Planner vs Local Planner · 规划器如何协同工作

做机器人导航这几年,我见过太多人把全局规划和局部规划割裂开来看。其实它们就像人的「大脑」和「小脑」——一个负责大方向,一个负责脚下每一步。今天咱们就把这对搭档彻底聊透。

🌍 全局规划器 Global Planner A* / Dijkstra / NavFn 📍 局部规划器 Local Planner DWA / TEB / MPC 参考路径 🗺️ 代价地图层(Costmap) 静态层 · 障碍层 · 膨胀层 · 规划器层 ⇄ 协同:全局定方向 · 局部避障碍

1. 全局规划器:负责「去哪儿」

全局规划器的任务很简单——从起点到终点找一条可行路径。它基于静态地图(通常是SLAM构建的栅格图)做搜索,不考虑临时出现的障碍物。

我个人习惯把全局规划比作「导航地图里的路线规划」。你从北京到上海,高德给你一条高速路线,这就是全局路径。但它不知道路上哪段在临时施工,对吧?

常用全局规划算法:
A*(最经典,有启发式搜索)、Dijkstra(保证最优但慢一点)、NavFn(ROS默认,带梯度下降)。

关键参数速览:

参数作用我的经验值
allow_unknown是否允许通过未知区域室内建议 false,室外可 true
planner_window_x/y规划搜索窗口大小别设太大,否则卡顿;我一般设 3~5m
default_tolerance目标点容差0.25m 比较稳,太小容易来回震荡

2. 局部规划器:负责「怎么走」

局部规划器拿到全局路径后,会把它切成一段段「短时窗口」。它实时处理激光雷达、深度相机等传感器数据,在几米范围内做速度与方向决策。

说白了,局部规划器就是机器人的「条件反射」。遇到突然窜出来的障碍物,全局规划来不及反应,局部规划必须立刻刹车或绕行。

💡 避坑指南: 我曾经把局部规划器的目标距离设得太大(5m),结果机器人总想「看太远」,在走廊里频繁摇摆。后来缩到 2.5m,立刻稳了。

主流局部规划器对比:

规划器特点适合场景
DWA (Dynamic Window Approach)速度空间采样,轻量快速室内、差速轮、动态不太剧烈
TEB (Timed Elastic Band)带时间信息的弹性带,可优化路径狭窄通道、阿克曼转向、需要平滑轨迹
MPC (Model Predictive Control)预测控制,计算量大高速移动、全向平台

3. 规划器如何协同工作?

这是本章的核心。很多新手以为全局规划完,局部规划照着走就行了。其实没那么简单——它们之间有一个「反馈-更新」的循环。

  1. 全局规划器发布一条 nav_msgs/Path 消息(包含一系列位姿)。
  2. 局部规划器订阅这条路径,并把它「裁剪」到局部代价地图范围内。
  3. 局部规划器每帧(通常 10~20Hz)计算控制指令 geometry_msgs/Twist。
  4. 如果局部规划器发现当前路径被障碍物完全堵死(比如有人突然站在路中间),它会触发重规划请求。
  5. 全局规划器收到请求后,基于最新的代价地图重新计算路径。
⚠️ 常见卡顿根源: 重规划频率太高!我遇到过一台机器人每秒重规划 8~10 次,CPU 直接拉满,导航卡成PPT。后来把 planner_frequency 限制到 0.5Hz,问题解决。

4. 协同调参实战要点

嗯,这里要注意——两个规划器不是独立调参的。它们通过代价地图和规划频率耦合在一起。

  • 全局路径平滑度:如果全局路径拐角太锐利,局部规划器会拼命修正,导致抖动。我习惯在全局规划器里开启 smooth_path 或使用 NavFn::smooth。
  • 局部规划器前视距离:这个值决定了局部规划器「看多远」。设太短,机器人容易在拐弯时迷路;设太长,又对动态障碍反应迟钝。我个人经验:室内 1.5~2.5m,室外 3~4m。
  • 规划器超时:如果全局规划超过 1~2 秒没算出路径,导航堆栈会报错。我一般设 planner_timeout: 1.5,并配合恢复行为。
一句话总结协同逻辑:
全局规划负责「不撞墙的大方向」,局部规划负责「不撞人的小动作」。两者通过代价地图和重规划机制形成闭环。

你想想看,如果全局规划器每 5 秒才更新一次,而局部规划器每秒决策 20 次,那大部分时间局部规划都在「自由发挥」。所以调参时一定要关注两个频率的匹配。

我记得有一次在工厂项目里,机器人总是在一个 1.2m 宽的门口卡住。全局路径明明穿过了门,但局部规划器因为膨胀层参数太保守,认为门太窄过不去。后来我把 inflation_radius 从 0.5 降到 0.3,机器人就顺畅通过了。你看,这就是全局和局部参数打架的典型案例。