ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

移动机器人路径规划:A*、RRT与DWA算法原理及融合实战

移动机器人路径规划:A*、RRT与DWA算法原理及融合实战

一个移动机器人要从A点走到B点,中途有人走过来,地面上多了临时堆放的纸箱,你要是没给机器人配好路径规划,它就只能面临两个结局:要么直愣愣撞上去,要么停在原地死等,直到障碍自己消失。路径规划算法要解决的就是这个绕不开的问题,而在这个领域里,A*、RRT、DWA 是三个绕不开的名字:A* 负责在地图上找出一条不撞墙的宏观路线,RRT 负责在没有完整地图时也能探出一条可达的路,DWA 负责盯着眼前这一两秒,让底盘既避障、又走得不毛躁。我是做移动机器人导航的,这几年和这三个算法打了太多交道,踩过的坑能装满一抽屉。这篇文章想做的只有一件事:把它们的原理拆碎,讲透各自擅长什么、死穴在哪,再把“A* 全局规划 + DWA 局部避障”这个最常见的融合方案怎么落地、怎么调参、怎么排故,从头到尾给你捋一遍。刚接触自主导航的人可以把它当成一张入门地图,已经在调导航参数的人,可以直接跳到后面的速查表和排故清单。

1. 三个算法先站稳:全局、采样、局部各管哪一段

1.1 A* 是地图上的“路线规划师”

A* 不是某个机器人专用的算法,它是图搜索家族的明星,也是我做全局规划时最先上手的方案。你手里有一张栅格地图,每个格子要么可走、要么有障碍,机器人要从起点格挪到终点格,A* 做的就是告诉你沿哪一串格子走代价最小。

它的思路朴素但好用:维护两个集合,open list 和 close list。每轮从 open list 里挑一个 f 值最小的格子扩展,f = g + h。g 是从起点走到当前格已经花掉的真实代价,h 是从当前格到终点的一个乐观估计代价,常用欧几里得距离。每扩展一个格子,就把它的邻居丢进 open list,同时把父节点指向当前格子,循环直到终点被扩展。一句话总结:它是从所有候选路径里优先探索“看起来最有希望”的那几条。

类比一下。你在陌生城市赶去一家饭店,手里有地图。你不会把所有路口都走一遍,而是先估算哪些路口方向离饭店最近,优先走过去。A* 的 h 就是这个估算,它能把搜索方向强烈地拽向终点,所以比 Dijkstra 那种无差别扫描通常要快一个量级。

补充一些实用考虑。网格邻居用四邻居还是八邻居,直接决定路径是只能横竖走还是可以斜穿。用八邻居时,斜向移动的代价要按 sqrt(2) 倍计算,否则地图上会出现“斜着走和横着走一样快”的错觉,路径会失真。另一个常被忽略的点是启发式函数的权重:如果地图很大,可以给 h 乘一个大于 1 的权重来提速,这叫加权 A*。我试过把权重从 1.0 拉到 1.5 左右,在大地图上规划耗时能明显下降,路径长度只多出百分之几。但权重太大就会牺牲最优性,甚至看起来像“贪心”,所以别一味求快。

1.2 RRT 是“摸着石头过河”的探险家

RRT 和 A* 长相完全不同,它不依赖栅格,也不需要先建一张完整的环境图。它的工作方式是从起点长一棵随机树:随机撒一个点,在树上找离它最近的节点,沿这个方向按固定步长生长出一个新节点,如果新节点和父节点之间的线段没有碰到障碍,就把它挂上树。这个循环重复几百上千次,树会慢慢长满整个搜索空间,等某个新节点距离终点足够近,就顺着父节点回溯出一条完整路径。

这个机制让它天然适合 A* 难以建模的问题。比如机械臂在关节空间里找运动轨迹,每个关节角度都是维度,栅格化代价极高;再比如地图外沿有大量未知区域,建图本身就很勉强。这类问题里,RRT 只需要判断“两点之间能不能走”,不要求全局地图完整,往往是更现实的选择。

但随机性是把双刃剑。同一张地图跑十次,RRT 给出的路径每次都完全不一样,而且很容易带一堆无用拐角,路径长度也可能明显差于最优解。工程上很少直接用裸 RRT,一般会用它的两个改进版本。RRT* 在每次插入新节点后会把附近节点的父指针重新优化,让解渐近收敛到最优;双向 RRT 则从起点和终点同时向中间长树,遇到狭窄通道时成功率提升明显。从我实际调试的经验看,如果你急着让一个粗糙但能用的导航系统跑起来,双向 RRT 加简单路径裁剪,性价比其实很高。

1.3 DWA 盯着“下一秒怎么走”

DWA 的视角和上面两个完全不同。A* 和 RRT 都在回答“从全局看走哪条路”,DWA 则在回答“下一个控制周期,底盘该给多大线速度和角速度”。它不评估远方,只看眼前一小段。

算法流程是这样的:根据当前速度、底盘最大加速度、控制周期,算出一个下一周期可行的速度组合窗口;对窗口里的每一组速度,按恒定速度向前模拟一小段轨迹;然后给每条轨迹打分,主要看它会不会撞障碍、末端朝向是不是趋近目标、速度够不够快;最后选得分最高的速度组合发给电机。每个控制周期都重新算一遍,因此对动态障碍物的反应很快,这也是它成为局部规划主力的原因。

DWA 的“动态窗口”这四个字,指的就是每步约束出来的可行速度集合。这个集合不是凭空来的,而是由当前运动状态和机器人物理极限共同决定的。明白了这一点,就明白 DWA 为什么会出那些经典毛病:只看脚下,路径会陷入局部最优;目标太远时,容易对着墙反复试探。这也是为什么生产级方案几乎不会单独用 DWA,而是把它挂在全局路径后面。

1.4 选型参考:什么场景用谁

直接把三种算法放进应用场景里对比:

场景特征推荐组合原因
地图完整、环境基本静止A* + DWAA* 能给出最短且稳定的全局路线,DWA 负责沿途避障
地图未知或频繁变化双向 RRT + DWA不依赖全局精确栅格,能快速摸出可达路径
人流多、动态障碍密集A* + 强化局部规划全局路线让机器人不绕远,局部层要留足反应空间
机械臂等关节空间规划RRT/RRT*高维空间难以栅格化,采样法几乎是唯一实用选项

选型不是比谁更高级,而是看环境缺什么信息、底盘缺什么约束。对绝大多数轮式移动机器人来说,第一行“A* + DWA”就是最稳的起点。先把它跑通,再谈别的,这套组合也是后面要展开的融合主线。

2. A* 和 RRT 的全局规划实战:原理与抠参数

2.1 A* 的代价函数怎么写最稳

直接给你一段可以反复用的伪代码骨架:

# A* 主循环(伪代码) open_list = [start] closed_list = [] while open_list: current = open_min_f(open_list) # 每次取 f 最小的节点 if current == goal: return reconstruct_path(current) open_list.remove(current) closed_list.append(current) for neighbor in get_neighbors(current): if neighbor in closed_list: continue tentative_g = current.g + distance(current, neighbor) if tentative_g < neighbor.g or neighbor not in open_list: neighbor.g = tentative_g neighbor.h = heuristic(neighbor, goal) neighbor.parent = current open_list.add(neighbor)

对有经验的读者来说,这段代码太“标准”了,但标准正好说明核心逻辑简单。真正影响效果的是后面三件容易被忽略的事。

启发式函数选型:八邻居网格里用欧几里得距离是自然选择,曼哈顿距离只能用在四邻居场景,否则会严重高估移动代价。h 权重大于 1 时规划更快但结果次优,我一般在大地图上把权重压在 1.2~1.5 之间。

open list 的实现方式:节点很多时,线性扫描取最小值会明显变慢。工程上建议用二叉堆,数据量大再考虑更复杂的数据结构。我见过有人拿着基础实现处理 500×500 的地图,一帧规划卡了 300 多毫秒,换成堆之后降到十几毫秒,这是纯数据结构的收益,不是算法本身变高级了。

闭合检查也要留意:neighbor 同时由多条路径到达时,要正确比较并更新 g,否则路径可能在角落反复横跳。细节虽小,但出问题时会表现为地图上出现“同一点被反复选中”的卡顿,排查起来容易怀疑人生。

2.2 栅格分辨率、膨胀半径和路径毛刺

实际导航中,A* 的问题通常不在搜索算法本身,而在“地图喂得对不对”。一个常见组合是:地图分辨率 0.05 米,机器人半径 0.3 米,膨胀半径设 0.35 米。这个配置下,A* 找出来的路径一般会离障碍物半米左右,局部规划器跟起来很舒服。

分辨率如果改到 0.2 米,效果就开始变质。窄通道在地图上可能只剩一个格子,机器人物理尺寸根本过不去,但 A* 不知道,路径照样从那里穿过去。所以地图分辨率要和机器人尺寸挂钩,经验上单个栅格边长别超过机器人外接圆半径的一半。地图精度也不是越高越好,0.02 米和 0.05 米在大多数室内场景根本没区别,但计算量会暴涨。

膨胀本身也会带来问题。膨胀半径设得太大,A* 会认为所有路都被堵死,在地图上找不到解;设得太小,路径贴着墙走,给局部规划器留的调整空间不足。比较稳的做法是:膨胀半径 = 机器人外接圆半径 + 安全余量 + 定位误差。安全余量通常给 5~10 厘米,定位误差按实际传感器水平估。

然后是路径毛刺。A* 在栅格上搜出来的路径由一串相邻格子组成,折角多,斜线少。直接拿给 DWA 跟,轮子会频繁修正方向。后期可以做一个剪枝:从起点开始,往前找能无碰撞直连的最远点,删掉中间点;再对剩下的点做轻量平滑。这个步骤不用引入复杂的曲线优化,就能把路径长度和角度跳变降下来一大截。

2.3 RRT 的关键参数:步长、碰撞检测与迭代次数

RRT 的参数比 A* 少很多,但并不代表好调。步长是最关键的一个:太大,新节点可能一步跨过窄缝,漏掉可行路径;太小,树长得慢,到达终点要更多迭代,规划耗时增加。按地图尺度来定,比如地面机器人场景,步长取 0.5 米左右是一个常用起点,再按地图障碍密度微调。

碰撞检测也要注意。判断“节点之间能否直连”时,不能只检查两个端点,要在线段上均匀采样,逐点看是不是处于障碍或膨胀区域。采样太粗会漏检,路径看着能通过,实际会撞。我习惯把采样间隔设成地图栅格分辨率的二分之一以下。

迭代次数决定成功率。迭代太少,树还没有覆盖到终点方向,容易超时失败;迭代太多,耗时白白浪费。工程上可以先跑一次,看第多少次迭代找到解,然后把这个数字乘 1.5 作为上限。

如果你用的是 RRT*,还要额外关心重连半径和优化迭代次数。重连半径太小,节点优化效果基本为零;太大,每次插入节点都扫描一堆邻居,耗时上升。我在二维平面上常用“步长的 2~3 倍”作为起始值,再根据实测调整。

2.4 全局规划怎么打分

规划结果好不好,不能靠感觉。我自己评估全局规划主要看四个指标:规划耗时、路径长度、平滑性(累计转角)、成功率。

算法耗时路径长度平滑性适用场景
基础 A*中短一般栅格完整、可重复规划
加权 A*短略长一般大图、实时要求高
RRT*中较长差高维空间、连续空间
双向 RRT中较长差狭窄通道、地图不完整

路径长度和平滑性往往是一对矛盾。过分追求最短,路径必然贴障碍、折角多;追求平滑,路径会变长。全局规划层只需要求“大致合理”,把大量平滑工作交给局部规划层去处理,这是分层架构的核心思想,也是后面融合方案的出发点。

3. DWA 局部规划器拆解:速度窗口、轨迹模拟与评分

3.1 速度窗口怎么算

DWA 的第一步是确定“动态窗口”。假设机器人当前线速度是 0.2 米/秒,最大线加速度是 0.5 米/秒²,控制周期是 0.1 秒,那么下一周期能达到的线速度范围就是 0.15~0.25 米/秒。角速度也一样,由当前角速度和最大角加速度约束。这个范围还要和机器人允许的绝对速度上限取交集,比如底盘最高线速度 0.8 米/秒,你就不能算出一个 0.9 的采样点。

如果问题只有加减速约束,DWA 还算简单。真正复杂的是刹车约束:就算某个速度组合在加减速范围内,如果机器人以上这个速度冲出去,在可预测的距离内刹不住、会撞上障碍,那它也是不可行的。所以窗口最终是“加速度窗口 ∩ 速度极限 ∩ 刹车安全区”。这个逻辑就是 DWA 被称为“动态”的根源:窗口不是固定值,而是随当前状态不断变化。

给个直观例子。机器人正以 0.5 米/秒冲向一个 0.4 米外的箱子,最大减速度 0.8 米/秒²,那它至少需要 0.156 米的刹车距离(按匀减速公式 v²/(2a) 算),勉强来得及,但任何加速选项都会被剔除。如果箱子在 0.2 米外,能用的速度选项基本就只剩下“原地制动”了。

3.2 轨迹模拟与预测时间

确定速度窗口后,DWA 会对每个可行速度组合做一次短时模拟:假设在接下来的一小段时间里,机器人保持这个速度不变,沿着一条圆弧或直线前进,生成一条模拟轨迹。模拟的预测时间一般取 0.5~1.5 秒,这是个很讲究的参数。

预测时间太短,机器人只看得见眼前一小段,障碍稍微远一点就“看不见”,会显得反应过激,频繁急停;预测时间太长,它又会过度考虑远期轨迹是否撞墙,在通道里容易犹豫不决,明明贴着墙就可以过,它却觉得前面会撞。我用来回测试的起点通常是 1.0 秒,障碍密集时缩短到 0.6 秒,开阔环境拉到 1.2 秒。

另一个容易被忽略的点是采样分辨率。线速度采样 5 档、角速度采样 10 档,就有 50 条模拟轨迹,每个控制周期都要重新算一遍,计算量完全可接受。但采样太粗时,速度选择不连续,相邻周期可能从“猛转”跳到“直行”,机器人就会抖。采样太细则差异太小,容易在几个相似选项中反复横跳。实际操作中,观察模拟轨迹的疏密,再对比机器人实际路径的平稳度,就能大致判断该往哪边调。

3.3 评价函数的三项:方向、距离、速度

每条模拟轨迹的得分由三个量决定:

score = α × 方向偏差 + β × 障碍距离 + γ × 速度

方向偏差衡量轨迹末端朝向和目标的夹角,障碍距离衡量轨迹与最近障碍的间距,速度项则奖励走得快。如果一个轨迹会撞上障碍,分数直接记负无穷或直接淘汰。

权重配平是 DWA 调试的核心。α 过大,机器人会特别“犟”,非要正对目标不可,结果贴着障碍边缘硬挤;β 过大,机器人安全第一,绕远路也不在乎,在窄通道里会墨迹;γ 过大,机器人贪快,动态障碍高发区容易刹不住。我建议的初始配平顺序是:先把 β 固定在一个中间值,比如 0.8,再调 α 和 γ 的比值。一组能跑通大多数室内场景的起始权重是 α=0.5、β=0.8、γ=0.3,但这不是万能值。

有一个关键改动要从融合的角度理解:在纯 DWA 里,“目标方向”直接指向终点;一旦把它挂在全局路径后面,“目标”应该改为局部前瞻点方向,而不是远方的最终终点。否则机器人会在接近终点前就开始犹豫,或者在岔路口做出不合理的转向。这个改动一句话就能说完,但很多人融合失败就是栽在这。

3.4 DWA 三个经典故障和处理方向

原地旋转不停:常见原因是目标方向项权重 α 太大,机器人还没往前挪就急着转向,或者局部目标点离机器人太近,速度小、转向要求又高。先试着降低 α,或把速度项权重提上去;也要看是不是局部目标一直贴在机器人正前方很近处。

左右抖动:相邻控制周期选出的速度组合频繁跳变。处理办法通常是把预测时间拉长一点,或者把采样分辨率调粗,也可以给速度输出加限制,让每个周期的变化量不能超过某个比例。

速度全部被拒绝:日志里找不到可发送的可行速度,机器人直接死锁。优先检查目标点是不是被代价地图膨胀成了障碍,其次看当前速度窗口是不是太小,最后看刹车距离计算有没有因为减速度设置太小而把所有选项都掐死。

4. A* + DWA 融合落地:路径跟随、前瞻目标与参数联动

4.1 为什么不直接让 DWA 追终点

把终点直接丢给 DWA,理论上也能走,但实际表现很糟:距离远时,终点方向在机器人坐标系里的变化很慢,DWA 缺少“远方该绕哪儿”的指引,遇到第一个障碍就可能被带偏。局部规划的每一步都只保证“这一秒最优”,多个“这一秒最优”拼起来,整体路线往往不是最短,甚至会在障碍前磨蹭。

融合的基本结构可以理解成一个“宏观意志下放”的过程:A* 在地图上算出一条全局路径,这条路径被切分成一串离散点;机器人实时找回离自己最近的点,把前方一段距离外的那个点当作临时目标;DWA 只需要负责把这个临时目标吃进评价函数,输出速度。这样全局的绕行决策和局部的避障动作就自然分开了。

这样的分层架构还有个额外好处:地图更新时不需要让局部规划器重新思考全局。全局规划以较低频率重算,局部规划器每个控制周期都允许动态障碍改变它的决策,两者节奏不一,各司其职。

4.2 实现流程:路径重采样、目标切换与坐标对齐

把前面说的结构落到代码上,可以拆成四个步骤:

  1. 全局路径重采样,把 A* 产出的一串稠密格点按固定间距(比如 0.2 米)转成离散点序列。
  2. 计算机器人当前位置到每个路径点的距离,找到最近点。
  3. 从最近点向前取一段距离,这个位置作为局部目标。前瞻距离通常取 1~2 个车身长度,或者按“当前线速度 × 1.5~2 秒”估算。
  4. 把局部目标点从全局坐标转换到机器人坐标系,再交给 DWA 的评价函数使用。

这里最关键的是前瞻距离的选择。前瞻太短,机器人对全局路径的跟随太“粘”,路径稍微有波动就跟着急刹,走过直角弯时会一顿一顿;前瞻太长,则过弯时机器人会切内线,离障碍物很近,甚至把全局路径的弯道“拉直”了。

我调试时有个快速经验:如果机器人过弯顺畅但路径贴边,就把前瞻距离拉大一点;如果机器人频繁停车、转弯迟钝,就把前瞻距离缩近一点。这个参数通常不需要精确公式,而是根据实测路径形态反推。

4.3 更高级的融合:低分辨率 A* + RRT* + 局部规划

A* + DWA 是“栅格世界的标准答案”,但当环境里局部障碍非常复杂、栅格图又不可靠时,可以再加一层 RRT*。

一种可行的混合策略是:全局层用低分辨率 A*,以很低的频率更新,给出一个大致方向上的粗路径;当机器人进入障碍密集区域时,局部层用 RRT* 在这个区域快速重规划出一条无碰撞的短线段,替代原来那一段的全局路径;DWA 继续负责把这条短线段平滑地执行出来。背后的思路是分层降低不确定性:A* 提供方向稳定性,RRT* 提供对复杂局部的“可绕过”判断,DWA 提供底盘物理约束下的平滑执行。

这种三明治结构比两层结构复杂得多,代价地图也要分多层维护,但它确实能处理很多“A* 认为走得通、实际现场却乱成一团”的场景。如果你刚开始做融合,我不建议一上来就搞三层,先把 A* + DWA 调顺,再考虑往里塞 RRT*,否则出问题都不知道去哪一层找。

4.4 参数联动:控制周期、最大速度、前瞻距离怎么一起调

融合系统的参数不是独立存在的,必须联动调整。我习惯按照下面顺序取数:

  1. 控制周期由底盘接口决定,通常是 0.05~0.1 秒。
  2. 最大线速度由现场安全要求决定,取值时得保证紧急刹停距离远小于传感器可视范围。
  3. 前瞻距离按“最大线速度 × 1.5~2 秒”估算。比如最大线速度 0.5 米/秒,前瞻距离约 0.8~1.0 米。
  4. 最大加速度取一个让单周期速度增量不超过最大线速度 10%~15% 的值,这样底盘起步、刹车都相对平稳。

举个例子。我在一个模拟巡检项目里用过这组配置:控制周期 0.1 秒,最大线速度 0.5 米/秒,最大角速度 1.0 弧度/秒,最大线加速度 0.4 米/秒²,最大角加速度 2.0 弧度/秒²,前瞻距离 0.9 米,预测时间 1.0 秒。这个组合跑起来整体平顺,动态障碍从侧面插进来时,DWA 也能在 1 米左右的距离做出明显的减速避让。注意这只是起点,不同底盘和传感器下差异很大,一定要按自己的机器人实测。

5. 避坑经验、排故速查与调试心得

5.1 地图分辨率与机器人尺寸不匹配

很多人第一次翻车都翻在这:地图用 0.2 米分辨率,机器人外接圆半径却接近 0.35 米。A* 规划出来的路径,在地图上看着穿过了某个窄口,实际上机器人物理上根本挤不进去;由于膨胀半径当时没包含机器人尺寸,路径也会贴着墙角走,导致局部规划器一路疯狂修正。

对策分两层:地图分辨率尽量满足单格边长小于机器人半径的一半,这是硬指标;膨胀半径一定要含上机器人外接圆半径、安全余量和定位误差。否则你调再多的 DWA 权重也救不回来,因为问题的根源在“地图对机器人来说压根不可通行”。

5.2 DWA 死锁:所有采样轨迹都被判失败

现象比较典型:机器人停在原地,速度始终为零,日志刷满了“找不到可行轨迹”。我排查这个问题时一般按顺序做三件事。

第一,看局部目标点。代价地图的膨胀层可能把目标点附近的区域全标成了障碍,目标点本身不可达,这时机器人不管怎么采样都“撞墙”。处理办法是让全局规划把终点或局部目标改成最近的自由格点。第二,看膨胀半径是不是过大。机器人明明离障碍还有 30 厘米,但代价地图认为已经是禁区,也会把可行速度全掐断。第三,看刹车约束计算。最大减速度设得太小会让刹车距离变大,动态窗口被进一步压缩,速度选项就少了。把减速度调大一点,再给原地转向留一条可选速度,死锁往往会解除。

5.3 全局路径贴墙,局部规划蛇形走位

这种现象表现为:机器人路线总体正确,但轮子一直在左右修方向,走起来像蛇。先别急着怪 DWA,多半是全局路径本身离障碍太近。A* 的代价函数只优化距离,不优化“安全间距”,所以如果膨胀半径没设置好,或者加权 A* 权重太大导致路径靠墙抄近路,就必然出现这种结果。

处理办法是给全局层的障碍距离加权,或者干脆把膨胀半径再加大一圈,让 A* 主动绕开“刚刚好能过”的区域。我还会在后处理阶段对路径做一次“向外推”的轻量操作:把每个路径点往远离最近障碍物的方向挪一小段距离,再重新检测碰撞。这个操作在走廊环境里尤其有用。

5.4 重规划震荡:机器人左右摆头

融合系统跑起来后,最常见的动态问题不是撞,而是“左右摆”。A* 全局路径不变,但每个控制周期算出来的局部目标点都在细微变化;DWA 的评分对目标方向非常敏感,于是速度指令来回跳,底盘表现为左右摆头。

给目标切换加一个滞回区,问题能消掉大半。具体做法是:当前局部目标点与上一个目标点的距离小于某个阈值(比如 0.1 米)时,继续沿用旧目标,不切新的。这本质上是给离散控制加了一点“惯性”,让决策不要因为微小扰动而来回翻转。另一个辅助手段是略微降低角速度采样分辨率,减少相邻周期速度指令的跳变幅度。

5.5 排故速查表

现象可能原因检查点处理方向
机器人怼墙地图分辨率过低,路径穿过不可行窄缝栅格边与机器人半径比提高地图精度,加大膨胀
原地死锁DWA 评分全失败目标点是否被膨胀,减速度设置修正目标点,调大减速度
蛇形走位全局路径贴障碍、折角多膨胀半径、路径采样点加大膨胀,路径平滑
左右摆头局部目标频繁切换前瞻距离、目标切换逻辑加滞回区,降低采样分辨率
规划超时卡顿A* 在大地图上搜索过慢open list 数据结构、h 权重换二叉堆、用加权 A*

排故的核心思路是分层定位:先分清是全局路径的问题,还是局部执行的问题,再动参数。不要一上来就调 DWA 的权重,很多时候根子在前面那层。

5.6 调试心得:把内部状态画出来,比盲调参数快十倍

这是我最想强调的一点。调导航参数时,不要只看机器人最终跑得好不好,要把中间状态全部可视化:全局路径点、当前局部目标、DWA 模拟出来的几十条轨迹、代价地图、还有每条轨迹的评分,全都画在同一张图上。

一旦机器人出现怪动作,先通过画面定位是哪一层的问题。全局路径在障碍物里穿,说明 A* 这层错了;全局路线上局部目标乱跳,说明前瞻逻辑有问题;全局路径没问题但模拟轨迹全贴着障碍,那就去调 DWA 的评价函数。我见过很多开发者凭感觉在参数文件里来回改,改半天也不知道是哪一层导致,就是因为没看到中间状态。

另外一个容易出效果的小操作是:把 DWA 的预测时间临时调大,比如从 1.0 秒调到 2.0 秒,你就能在可视化面板里看到机器人“预判”的轨迹到底倾向哪边,这时候评分的倾向性一目了然。看完再调回实际值,调参效率会高很多。

我个人这几年做下来,最大的体会是:路径规划这个领域,真正难的从来不是某个算法本身的公式,而是怎么让不同工作节奏的算法在一台机器人身上协同工作。A* 想的是全局要不要绕路,RRT 想的是到底有没有一条路,DWA 想的是这一秒怎么走稳。把这三层接好之后,机器人才会像一个有判断力的司机,而不只是条件反射的避障器。

最后再分享一个很小的习惯:每次只改一个参数,改完把评分日志打出来对比数据,别一次动三四个参数。路径规划这种系统,牵一发动全身,盲改参数翻车之后,你连复现问题都困难。数据说话,比手感可靠得多。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进