第四章:全局规划器:NavFn、Smac Planner(2D与Hybrid-A*)、规划器配置与调优

全局规划器,说白了就是给机器人画一条从A到B的“大路线图”。它不考虑路上的小障碍,只看全局地图。我刚开始接触Nav2时,觉得这玩意儿不就是个路径搜索吗?后来才发现,选不对规划器,机器人要么绕远路,要么直接卡死。

今天咱们就聊聊Nav2里三个主流的全局规划器:NavFn、Smac Planner 2D和Smac Planner Hybrid-A*。嗯,每个都有自己的脾气,你得摸透了才能用好。

核心观点: 没有最好的规划器,只有最合适的规划器。选型取决于你的机器人运动模型、地图大小和实时性要求。
全局规划器选型决策树 全局规划器 NavFn (Dijkstra/A*) 优点:轻量、快速 缺点:无运动学约束 适用:差速/全向机器人 Smac Planner 2D (A* 网格) 优点:支持代价地图 缺点:无运动学约束 Hybrid-A* 优点:带运动学约束 缺点:计算量大 适用:阿克曼/汽车 选择依据:机器人类型 → 地图大小 → 实时性要求

4.1 NavFn:老牌经典,轻量之选

NavFn是Nav2里最基础的全局规划器。它本质上就是Dijkstra或A*算法,在栅格地图上做路径搜索。我个人习惯在简单场景下用它——比如室内平地、差速机器人。

核心特点:

  • 基于代价地图的2D网格搜索
  • 支持A*(默认)和Dijkstra两种算法
  • 计算速度快,资源消耗低
  • 不包含机器人运动学约束
我的经验: 如果你用的是全向轮或差速机器人,且地图不大(比如100x100米以内),NavFn完全够用。我曾经在一个仓库项目里用它,跑了半年没出过问题。

配置示例:

# nav2_params.yaml 中的 NavFn 配置
planner_server:
  ros__parameters:
    planner_plugins: ["GridBased"]
    GridBased:
      plugin: "nav2_navfn_planner/NavfnPlanner"
      tolerance: 0.5          # 路径容差(米)
      use_astar: true         # 使用A*算法
      allow_unknown: false    # 是否允许通过未知区域

这里有个坑:tolerance参数。它表示如果目标点被障碍物占据,规划器会在多大半径内寻找替代点。我建议设成0.5米左右,太大容易让机器人走奇怪的位置。

4.2 Smac Planner 2D:NavFn的升级版

Smac Planner是Nav2后来引入的规划器,2D版本说白了就是NavFn的“Pro版”。它同样做网格搜索,但多了不少实用功能。

相比NavFn的优势:

  • 支持自定义启发式函数
  • 可以设置路径平滑度权重
  • 支持代价地图的动态更新
  • 路径更平滑,拐角更少
什么时候用Smac 2D? 当你觉得NavFn的路径太“锯齿状”,或者需要更精细的代价控制时。我在一个医院导航项目里换用Smac 2D后,路径平滑度提升了30%以上。

配置示例:

# Smac Planner 2D 配置
planner_server:
  ros__parameters:
    planner_plugins: ["GridBased"]
    GridBased:
      plugin: "nav2_smac_planner/SmacPlanner2D"
      tolerance: 0.5
      downsample_costmap: false  # 是否降采样代价地图
      smooth_path: true          # 启用路径平滑
      smooth_path_radius: 0.3    # 平滑半径(米)
      max_iterations: 1000000    # 最大迭代次数
注意: downsample_costmap如果设为true,会降低地图分辨率来加速计算。但代价是路径精度下降。我建议只在超大地图(500x500米以上)时开启。

4.3 Smac Planner Hybrid-A*:带运动学约束的规划

Hybrid-A*是Smac Planner的“完全体”。它不光搜索路径,还考虑了机器人的运动学约束——比如最小转弯半径、前进方向等。说白了,它生成的路径是机器人真正能走的。

为什么需要Hybrid-A*?

你想想看,差速机器人可以原地转弯,但阿克曼转向的汽车不行。如果用NavFn给汽车规划路径,结果可能是:路径上有个90度直角弯,汽车根本拐不过去。Hybrid-A*就是为了解决这个问题。

核心参数:

参数名 说明 建议值
minimum_turning_radius 最小转弯半径(米) 0.4(根据车型调整)
reverse_penalty 倒车惩罚系数 2.0(越大越避免倒车)
change_penalty 方向变化惩罚 0.5(越大路径越直)
analytic_expansion_ratio 解析扩展比例 3.0(越大路径越优)
避坑指南: 我曾经在一个AGV项目里把minimum_turning_radius设得太小(0.2米),结果规划出来的路径全是急转弯,实际车辆根本走不了。后来改成0.6米才正常。记住:这个值一定要比实际转弯半径大10%-20%。

配置示例:

# Hybrid-A* 配置
planner_server:
  ros__parameters:
    planner_plugins: ["GridBased"]
    GridBased:
      plugin: "nav2_smac_planner/SmacPlannerHybrid"
      tolerance: 0.5
      minimum_turning_radius: 0.4
      reverse_penalty: 2.0
      change_penalty: 0.5
      analytic_expansion_ratio: 3.0
      max_iterations: 1000000
      smooth_path: true
      smooth_path_radius: 0.3

4.4 规划器调优实战

调优规划器,说白了就是平衡三个东西:路径质量、计算速度、可行性。我一般按这个步骤来:

  1. 先确定机器人类型:差速/全向用NavFn或Smac 2D,阿克曼用Hybrid-A*
  2. 调整代价地图:膨胀半径、障碍物代价等(这个后面章节会细讲)
  3. 试跑默认参数:看看路径是否合理,有没有绕路或穿墙
  4. 微调关键参数:比如tolerance、smooth_path、reverse_penalty
  5. 压力测试:在复杂场景下反复测试,看规划时间是否超标
我的调优口诀: “先看能不能走,再看好不好走,最后看快不快。”

常见问题与解决:

  • 路径穿墙:检查代价地图膨胀半径,或者增大tolerance
  • 规划超时:减小地图尺寸,或者用NavFn代替Hybrid-A*
  • 路径太绕:增大change_penalty或reverse_penalty
  • 无法规划:检查起点/终点是否在障碍物内,或者增大max_iterations
重要提醒: 不要盲目追求最优路径。有时候一条次优但稳定的路径,比一条最优但计算超时的路径强得多。我在一个实时性要求高的项目里,甚至故意把max_iterations设小,保证规划器能在100ms内返回结果。

嗯,全局规划器的内容差不多就这些。记住:选对规划器是第一步,调好参数才是关键。多试、多跑、多观察,慢慢你就能摸透每个参数的脾气了。