2、全局路径规划参数:A*算法核心参数、代价地图膨胀半径、路径权重因子

全局路径规划,说白了就是给机器人找一条从A到B的“大路”。它不关心路上有没有临时出现的椅子,只管地图上已知的静态障碍。我做了这么多年导航,发现很多人一上来就调PID,却忽略了全局路径的参数——结果路径本身就不对,局部规划再怎么调也白搭。

这一章,咱们就聊透三个核心参数:A*算法的启发因子、代价地图的膨胀半径、还有路径权重因子。嗯,这三个东西调好了,你的机器人走路就有“大局观”了。

核心观点:全局路径的质量决定了导航的上限。局部规划只能修修补补,全局路径歪了,机器人怎么绕都别扭。

全局路径规划参数体系 全局路径规划 A* 核心参数 代价地图膨胀半径 路径权重因子 启发因子 h(n) 网格分辨率 机器人半径 + 安全余量 路径平滑度 vs 最短距离 三个参数相互影响:膨胀半径大 → 路径绕远 → 权重因子需配合调整 调参顺序建议:先定膨胀半径 → 再调A*启发因子 → 最后微调权重

2.1 A*算法核心参数:启发因子与网格分辨率

A*算法本质上是个“有脑子的搜索”。它不像Dijkstra那样盲目扩散,而是用启发函数指引方向。启发因子就是那个“脑子”的聪明程度。

我个人习惯把启发因子分成三档来试:

启发因子类型 计算公式 效果 适用场景
曼哈顿距离 |dx| + |dy| 路径有直角拐弯,搜索快 网格地图、仓库AGV
欧几里得距离 √(dx² + dy²) 路径更自然,搜索稍慢 开放环境、服务机器人
对角距离 max(|dx|, |dy|) 折中方案,兼顾速度和路径质量 大多数室内场景

我的经验:别迷信欧几里得距离。在栅格地图上,曼哈顿距离往往更“诚实”——它不会低估路径代价。我曾经在一个仓库项目里用欧几里得距离,结果A*算出来的路径穿墙而过,就是因为启发函数高估了实际可达性。

网格分辨率这个参数,很多人不重视。分辨率太高(比如1cm),A*要搜几百万个节点,慢得离谱;分辨率太低(比如50cm),路径精度不够,机器人贴着墙走都算不出来。

我一般这样选:

  • 室内服务机器人:5cm~10cm分辨率,平衡精度和速度
  • 室外巡检机器人:20cm~50cm,地图大,没必要太细
  • 狭窄通道场景:至少比机器人宽度小一个数量级,比如机器人宽60cm,分辨率设5cm

2.2 代价地图膨胀半径:安全第一

膨胀半径,说白了就是把障碍物“变胖”。为什么要变胖?因为机器人不是质点,它有尺寸。你想想看,如果地图上障碍物就是实际大小,路径规划出来的线可能贴着墙——机器人一开过去就撞了。

膨胀半径的计算公式很简单:

膨胀半径 = 机器人内切圆半径 + 安全余量

但实际调参时,这个“安全余量”才是关键。我遇到过最坑的一次:在实验室里跑得好好的,换到工厂地面,因为地面有油污,机器人打滑,原本刚好能过的通道就撞上了。从那以后,我的安全余量至少加5cm。

场景 机器人半径 推荐膨胀半径 说明
家庭服务 20cm 25~30cm 家具多,需要灵活通过
仓储AGV 30cm 35~40cm 通道固定,可适当缩小余量
户外巡检 40cm 50~60cm 地面不平,需要更大安全空间

注意:膨胀半径不是越大越好。半径太大,狭窄通道会被完全堵死,机器人只能绕远路。我曾经见过一个项目,膨胀半径设了机器人直径的两倍,结果机器人连门都出不去——因为门在代价地图上被“膨胀”成墙了。

2.3 路径权重因子:平滑度 vs 最短距离

路径权重因子,就是让机器人在“走最短的路”和“走最顺的路”之间做选择。这个参数在ROS的navfn或global_planner里通常叫neutral_cost或lethal_cost的缩放系数。

我习惯把它理解成一个“绕路容忍度”:

  • 权重因子 = 1.0:标准模式,路径尽量短,但可能紧贴障碍物
  • 权重因子 > 1.0:倾向于远离障碍物,路径会绕一点,但更安全
  • 权重因子 < 1.0:追求最短路径,适合开阔环境

举个例子。我在做商场导引机器人时,一开始权重因子设1.0,结果机器人总爱贴着展台走,顾客看着都害怕。后来调到1.5,路径自动往通道中间靠,虽然多走了半米,但观感好太多了。

调参口诀:先定膨胀半径保安全,再调启发因子提效率,最后用权重因子做微调。别一上来就三个参数一起动,你会疯的。

2.4 实战:ROS中的参数配置示例

在ROS的move_base框架里,这些参数通常在costmap_common_params.yaml和global_planner_params.yaml里配置。我贴一个我常用的配置模板:

# costmap_common_params.yaml
robot_radius: 0.20
inflation_radius: 0.30
cost_scaling_factor: 10.0

# global_planner_params.yaml
use_dijkstra: false
use_quadratic: true
use_grid_path: false
old_navfn_behavior: false
lethal_cost: 253
neutral_cost: 66
cost_factor: 0.55
publish_potential: true
orientation_mode: 0
orientation_window_size: 1

这里有几个关键点:

  • inflation_radius就是膨胀半径,我设了0.3m
  • cost_scaling_factor控制代价衰减速度,值越大,远离障碍物时代价下降越快
  • neutral_cost和cost_factor共同决定路径权重,我一般先固定neutral_cost=66,然后调cost_factor

一个小技巧:在调试时,把publish_potential设为true,然后在RViz里看代价地图的势场图。颜色越红的地方代价越高,路径自然会绕开。这个可视化比看日志直观一百倍。

2.5 常见问题与避坑指南

做全局路径规划,有几个坑我踩过不止一次:

  1. 膨胀半径和地图分辨率不匹配。比如分辨率10cm,膨胀半径设8cm——实际上膨胀半径小于一个格子,等于没膨胀。我建议膨胀半径至少是分辨率的3倍。
  2. 启发因子选错导致路径诡异。有一次我用曼哈顿距离,结果机器人走“之”字形,因为启发函数鼓励先走完x方向再走y方向。换成对角距离就好了。
  3. 权重因子调太大,路径绕到隔壁房间。嗯,这个真发生过。权重因子超过2.0后,机器人宁愿绕一大圈也不愿靠近障碍物,反而增加了碰撞风险。

最后说一句:全局路径规划的参数不是调一次就完事的。换一个地图、换一个机器人,参数就得重新来过。我每次接手新项目,都会花至少半天时间专门调全局路径——这半天省下来的,是后面几十天的局部规划调试时间。