2、全局路径规划参数:A*算法核心参数、代价地图膨胀半径、路径权重因子
全局路径规划,说白了就是给机器人找一条从A到B的“大路”。它不关心路上有没有临时出现的椅子,只管地图上已知的静态障碍。我做了这么多年导航,发现很多人一上来就调PID,却忽略了全局路径的参数——结果路径本身就不对,局部规划再怎么调也白搭。
这一章,咱们就聊透三个核心参数: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.3mcost_scaling_factor控制代价衰减速度,值越大,远离障碍物时代价下降越快neutral_cost和cost_factor共同决定路径权重,我一般先固定neutral_cost=66,然后调cost_factor
一个小技巧:在调试时,把publish_potential设为true,然后在RViz里看代价地图的势场图。颜色越红的地方代价越高,路径自然会绕开。这个可视化比看日志直观一百倍。
2.5 常见问题与避坑指南
做全局路径规划,有几个坑我踩过不止一次:
- 膨胀半径和地图分辨率不匹配。比如分辨率10cm,膨胀半径设8cm——实际上膨胀半径小于一个格子,等于没膨胀。我建议膨胀半径至少是分辨率的3倍。
- 启发因子选错导致路径诡异。有一次我用曼哈顿距离,结果机器人走“之”字形,因为启发函数鼓励先走完x方向再走y方向。换成对角距离就好了。
- 权重因子调太大,路径绕到隔壁房间。嗯,这个真发生过。权重因子超过2.0后,机器人宁愿绕一大圈也不愿靠近障碍物,反而增加了碰撞风险。
最后说一句:全局路径规划的参数不是调一次就完事的。换一个地图、换一个机器人,参数就得重新来过。我每次接手新项目,都会花至少半天时间专门调全局路径——这半天省下来的,是后面几十天的局部规划调试时间。