全局路径规划器调参:A*与Dijkstra算法原理、规划器参数详解、路径平滑度优化

说到全局路径规划,很多新手容易把它和局部规划搞混。我简单解释一下:全局规划是「看地图找路」,局部规划是「看传感器躲障碍」。今天咱们就聚焦前者,把A*和Dijkstra这两个老牌算法聊透。

一、A*与Dijkstra:两个核心算法的本质区别

先问个问题:你从北京去上海,是走直线快,还是绕道南京快?

Dijkstra的做法是:把所有可能的路都走一遍,最后告诉你最短的那条。A*则聪明一些——它知道上海在东边,所以优先往东走,西边的路基本不碰。

算法核心差异

  • Dijkstra:只考虑「已走距离」(g值),保证找到最短路径,但搜索范围大
  • A*:考虑「已走距离 + 预估距离」(g + h),用启发函数引导搜索方向

我在项目中遇到过一个问题:用Dijkstra规划10km×10km的地图,跑了3秒才出结果。换成A*后,同样的地图0.3秒就搞定了。你想想看,对于实时性要求高的机器人,这个差距意味着什么。

关键公式

A*的代价函数:f(n) = g(n) + h(n)

其中h(n)是启发式估计,常见的有欧几里得距离、曼哈顿距离

二、规划器参数详解:ROS中的navfn与global_planner

ROS里常用的全局规划器有两个:navfn和global_planner。我个人习惯用global_planner,因为它更灵活,参数也更丰富。

参数名 默认值 说明 我的建议
use_dijkstra false true用Dijkstra,false用A* 地图小于500×500用A*,更大用Dijkstra
use_quadratic true 二次近似,影响路径平滑度 建议开启,路径更自然
lethal_cost 253 障碍物代价值 别改太小,否则路径会贴墙
neutral_cost 50 自由空间代价值 调大可以让路径更居中
cost_factor 0.55 代价缩放因子 我一般设0.6~0.8,路径更安全

嗯,这里要注意:use_quadratic这个参数很多人忽略。它控制的是代价的衰减方式。开启后,路径会倾向于走「中间」,而不是贴着障碍物边缘。我在做仓储机器人时,就因为没开这个参数,机器人老是蹭着货架走,看着都揪心。

三、路径平滑度优化:让机器人走得更像人

A*规划出来的路径有个毛病——全是直角转弯。你想想看,机器人走到墙角突然来个90度急转,不仅看着别扭,轮子磨损也大。

优化方法一:路径剪枝

去掉路径中不必要的中间点。比如三个点A→B→C,如果A到C的连线不碰障碍,就把B去掉。

def prune_path(path):
    pruned = [path[0]]
    for i in range(1, len(path) - 1):
        if not in_line_of_sight(pruned[-1], path[i+1]):
            pruned.append(path[i])
    pruned.append(path[-1])
    return pruned

优化方法二:贝塞尔曲线插值

在转弯处插入控制点,生成平滑曲线。我常用的做法是每三个路径点生成一段二次贝塞尔曲线。

实战技巧

我曾经在AGV项目里遇到一个问题:路径平滑后,机器人反而撞到了障碍物。排查发现是平滑后的曲线穿过了障碍物边缘。解决方案是:平滑后做一次碰撞检测,如果碰撞就回退到原始路径。

优化方法三:代价地图膨胀

在规划前,把障碍物膨胀一圈。这样规划出来的路径天然就离障碍物远,平滑后也不容易碰撞。

避坑指南

我曾经把膨胀半径设得太大,结果机器人过不了门。后来学乖了:膨胀半径 = 机器人半径 + 安全余量(0.1~0.2m)。别贪心,安全余量太大反而走不了窄路。

四、知识体系总览

下面这张图是我自己整理的全局路径规划调参思路,你可以照着这个流程来排查问题。

全局路径规划调参知识体系 算法选择 A* 算法 Dijkstra 算法 参数配置 代价地图设置 路径平滑度优化 路径剪枝 贝塞尔曲线 代价膨胀

说白了,全局路径规划调参就三步:选算法、调参数、做平滑。每一步都有坑,但踩过一次就记住了。我刚开始做的时候,光调cost_factor就花了两天,后来发现是地图分辨率设错了——你说冤不冤?

最后分享一个经验:调参时别一次改太多。每次只改一个参数,记录下效果。这样出了问题也知道回退到哪。我见过有人一口气改了五个参数,结果路径乱成一锅粥,最后只能重装系统——别学他。

可可精品资料库