
“狼牙”这个无人机算法项目最终止步于复活赛用现在的话说就是“寄了”。但比赛结果不等于技术复盘的全部。真正值得记住的是整个项目在无人机路径规划算法这条链路里踩过的坑算法选型、仿真调优、实机迁移、失败排查每一个环节都藏着大量细节。如果你正在做无人机算法准备比赛或者想从仿真走到实机这篇复盘比一张获奖证书更有参考价值。先说结论这类项目真正难的地方不是某个算法本身而是如何让路径规划算法在真实环境中稳定运行。纯仿真里能跑通的方案换到实机经常会失败原因往往不在规划而在定位、通信、算力这些“外围条件”。下面的内容我会按照最常见的翻车顺序把无人机路径规划算法的常见问题和处理思路完整过一遍。1. 复盘“狼牙”之前无人机算法项目最容易在哪里翻车1.1 无人机算法不是算法单点问题而是链路问题很多刚接触无人机算法的团队接到任务后的第一反应是该选 A* 还是 RRT是先做全局规划还是先做局部避障这个方向没错但不完整。一架无人机要从 A 点飞到 B 点真正参与工作的环节至少包括定位模块GPS、IMU、视觉里程计或其他传感器给出当前位姿。地图模块静态地图或实时构建的栅格、点云、八叉树地图。路径规划模块在给定地图和约束下计算可行路径。控制模块把路径转成速度指令和姿态指令。通信模块机载电脑、飞控、地面站之间的数据交换。任何一个环节出问题最终都会表现为“路径不对”“飞机不动”“突然绕远路”。在复盘狼牙项目时我发现很多问题的根因根本不在规划模块而是地图坐标没有对齐或者传感器数据有几十毫秒的延迟看起来像规划失败其实是别的环节出了故障。所以如果你的无人机算法项目出现了诡异现象不要先把问题归到“规划算法不好用”上。先把整条链路的数据流画一遍确认每一步输入输出是否正常再决定要不要动算法。1.2 失败项目普遍存在的最小闭环缺失复盘了很多类似项目我发现一个共性团队花大量时间实现各种高级功能却连“单机单任务的最小闭环”都没有真正跑稳。什么是最小闭环就是在地图已知、起终点确定、没有复杂动态障碍物的前提下让路径规划模块稳定输出一条可执行路径并且让无人机能按这条路径完成飞行。这个基础闭环不跑稳后面的一切功能都是空中楼阁。狼牙项目的问题和很多项目类似总是在全局规划、局部避障、多机协同等模块之间来回切换却没有把最简单场景的成功率做到稳定。结果就是一到比赛复杂的场景触发某个没有被充分测试的边界条件整个系统就崩了。正确的做法是先固定一个最简单的场景把基础路径规划跑稳连续验证 50 次以上记录成功率、耗时、路径长度再逐步增加复杂度。每一步增加一个变量比如先加静态障碍物再加动态障碍物最后才考虑多机。1.3 没有验收指标调参就是凭感觉另一个普遍问题是“验收靠感觉”。路径规划跑一次看到一条还不错的线就说“通了”换一个地图路径穿墙或者很绕就说“失败”。这种判断方式最大的问题是不可重复也没有改进依据。在做无人机路径规划项目时我建议至少建立三个层次的指标第一层功能指标。能不能找到路径成功率是多少。第二层性能指标。单次规划耗时多少路径长度是多少资源占用高不高。第三层质量指标。路径是否平滑是不是贴近障碍物乘客或拍摄载荷是否能接受这种轨迹。这三层指标不需要定得很精确但一定要有具体数值。比如“成功率不低于 90%”“平均耗时低于 300 毫秒”“路径长度不超过理论最短路径的 1.2 倍”。有了这些数值你才能判断每次修改是变好还是变差。否则团队很容易在“看起来不错”和“感觉不对”之间反复拉扯。2. 路径规划算法选型全局规划、局部避障和代价函数2.1 全局规划与局部避障必须分开设计路径规划算法不是只有一个模块。做选型前先分清两个层级。第一层全局路径规划。负责在已知地图上计算一条从起点到终点的粗略路线。这里的“已知”可以是预设地图也可以是建图模块提供的完整地图。常见算法有 A*、Dijkstra、RRT、RRT* 等。这一层的计算量大一些也没关系因为不需要在每一帧都重新搜索。第二层局部路径规划。负责处理飞行过程中实时出现的新障碍物。无人机不能假设整个环境一成不变所以局部规划器要根据传感器数据在很短的时间内生成一条可执行的修正路径。常见方案有 DWA、TEB或者直接用局部地图做重规划。这两层一定要分开设计。一个常见的错误是把局部避障和全局规划写在同一套循环里遇到一个新障碍物就全图重新搜索。这样做有两个后果一是计算耗时会变得很高二是路径会因为地图更新频繁而抖动。正确做法是让全局规划器以较低频率计算基准路径局部规划器在高频循环里负责避障和跟踪。2.2 常见路径规划算法对比与适用场景下面这张表是经常用到的选择对照适用于大部分无人机路径规划项目。算法类型优点缺点适合场景Dijkstra全局搜索保证最短路径节点多、耗时长小地图、静态环境A*全局搜索比 Dijkstra 快启发式搜索需要调启发函数地图变化要重跑栅格地图、静态路径规划RRT采样搜索高维空间有效路径不光滑、非最优三维空间、复杂环境RRT*采样搜索渐进最优计算量大、迭代次数多离线优化、路径质量要求高DWA局部避障实时性好、输出速度指令易陷入局部极小值地面机器人和无人机水平面避障TEB局部优化能考虑时间和轨迹优化目标近时可能振荡局部路径优化人工势场局部避障实现简单局部极小值、目标不可达辅助方法不推荐单独使用选型时不要只看名字要结合你的地图表示方式、传感器频率和计算资源。比如你的环境是二维栅格地图A* 是最容易上手的也是效果比较稳定的如果地图是三维点云需要处理的是高维空间搜索RRT 系列会更合适如果你对路径质量要求很高可以先用 A* 或 RRT 找一条可行路径再用 TEB 或专门的平滑算法做轨迹优化。2.3 地图表示、代价函数与膨胀半径算法选好之后真正影响路径质量的是地图和代价函数。地图表示方式常见的有栅格地图、八叉树地图、点云地图。栅格地图最简单每个格子标记为“可通行”或“不可通行”八叉树地图适合三维环境内存占用更少点云地图包含丰富几何信息但搜索起来复杂度更高。不管用哪种地图都要在路径规划前做一件事障碍物膨胀。如果你直接把传感器得到的障碍物区域标成不可通行那么路径往往会紧贴着障碍物边缘。实际无人机是有尺寸的机翼、旋翼、机身都可能碰到障碍物。膨胀的意义就是把每个障碍物向四周扩大一定半径让规划路径自动避开飞行器本身的物理尺寸。膨胀半径怎么定至少等于飞行器最大外形半径再加上安全余量。安全余量取决于定位精度和传感器噪声。GPS 定位误差大就把余量放大一点室内视觉定位精度高可以适当缩小。在狼牙项目的复盘里路径贴障碍物这个问题绝大多数时候不是算法问题而是膨胀半径没有设置正确。代价函数则决定了路径的“偏好”。如果只按距离计算代价路径会尽量短但可能会贴着墙壁走如果加入风险惩罚比如距离障碍物越近代价越高路径就会自动偏向安全区域。代价函数的权重需要根据任务调。巡检任务可能更看重安全性路径绕一点没关系竞速任务更看重时间可以适当放松安全余量。2.4 一个最小可运行的路径规划示例这里给出一个通用的 A* 伪代码结构不绑定具体框架# 伪代码示例栅格地图 A* 路径搜索 def plan_path(start, goal, grid): open_list [start] came_from {} g_score {start: 0} while open_list: current min(open_list, keylambda cell: g_score[cell] heuristic(cell, goal)) if current goal: return reconstruct_path(came_from, current) open_list.remove(current) for neighbor in get_neighbors(current, grid): new_cost g_score[current] cost(current, neighbor) if new_cost g_score.get(neighbor, float(inf)): came_from[neighbor] current g_score[neighbor] new_cost if neighbor not in open_list: open_list.append(neighbor) return None这段代码只解决了“能不能找到路径”的问题。实际项目中你在cost函数里加入距离障碍物的惩罚在get_neighbors里加入飞行器运动约束在reconstruct_path之后加平滑处理才能得到一条无人机能真正飞出来的路径。3. 仿真环境与参数调优先用单条路径把成功率跑到 90%3.1 仿真环境选择关键是可复现无人机路径规划算法不建议一上来就实机调试。先在仿真里跑通能省下大量炸机成本。常见的仿真环境有好几种MATLAB/Simulink适合算法逻辑快速验证内置很多路径规划工具箱画图方便。Gazebo ROS物理仿真能力强支持多传感器建模是无人机算法开发的标准组合之一。AirSim基于虚幻引擎视觉信息逼真适合视觉导航和路径规划联调。自研轻量环境用 Python 写一个地图生成器和可视化脚本验证核心算法足够用。选择标准不是“哪个更高级”而是能不能快速复现同一个场景。如果每次运行地图都一样、起点终点都一样、参数都一样你才能比较算法改动前后的差异。Gazebo 这类环境适合整链路验证但每次启动和运行都偏重自研轻量环境适合快速迭代。我一般会两者都用轻量环境跑参数重量环境跑系统。3.2 核心参数怎么调分辨率、膨胀半径、迭代次数仿真阶段常见的参数问题有三个。地图分辨率。分辨率越高障碍物细节越清楚但搜索节点数也越多。举个例子一张 100x100 的栅格地图如果分辨率提高一倍格子数量会变成 200x200搜索空间扩大四倍。低配电脑跑起来会非常吃力。我建议先用低分辨率验证逻辑确认正确后再逐步提高。膨胀半径。前面已经提到这个参数直接影响路径与障碍物的距离。设置太小路径会贴障碍物设置太大可行区域变少复杂场景下可能找不到路径。验证方法很简单把规划路径画到地图上检查路径与障碍物的最小距离是否满足飞行器尺寸。最大迭代次数。RRT 类算法必须有这个限制防止地图复杂导致搜索时间过长。如果达到迭代上限仍找不到路径说明需要调整搜索步长、起点终点合理性或地图参数而不是无限等下去。这些参数是互相影响的。调分辨率会影响搜索时间调膨胀半径会影响可行域调迭代次数会影响成功率和耗时。所以调参的时候一次只动一个因素。3.3 控制变量法调参记录指标再改参数在仿真调试阶段我最推荐的方式是控制变量。先固定同一张地图、同一组起终点。然后用默认参数连续运行 50 次记录三个数字成功率、平均耗时、平均路径长度。接着修改一个参数比如把膨胀半径从 0.3 米改成 0.5 米再运行同样的 50 次对比指标变化。如果成功率下降说明膨胀半径过大如果路径仍然贴障碍物说明膨胀半径还不够。这里有一个容易被忽略的点成功率不是越高越好而是和任务要求匹配即可。比如巡检任务成功率当然越高越好但如果是快速赛道有时反而需要放宽成功率来换取更短的路径和更低的耗时。关键是先定标准再调参数。注意仿真阶段不要急着调“看起来更漂亮”的路径。先把“能不能稳定生成有效路径”这个问题解决。路径美观是下一步的事情。3.4 物理仿真和纯数学地图的差异纯数学地图里障碍物是完美的矩形或圆形传感器没有噪声定位是理想值。Gazebo 这类物理仿真环境里传感器模型、物理引擎、控制频率都会影响实际轨迹路径规划器输出的路径飞机不一定能完全跟踪。所以我建议在仿真阶段保留两个环境一个是纯数学地图环境专门用来快速调参和验证算法逻辑另一个是 Gazebo 或 AirSim 这类带物理引擎的环境用来验证整链路效果。两者都应该保存航迹和日志。调试效率高不高很多时候取决于你能否快速回放同一个场景。4. 从仿真到实机算力、通信、传感器噪声一起处理4.1 机载电脑算力与规划耗时仿真跑通后进入实机阶段第一步就是重新评估资源占用。很多算法在开发机上跑得很快换到机载电脑后性能直线下降。原因包括 CPU 主频低、内存带宽有限、散热限制、实时任务调度复杂。我能给的判断标准是把规划模块单独跑在机载电脑上连续运行 100 次统计平均耗时、最大耗时和 CPU 占用。如果平均耗时和最大耗时之间差距很大说明算法在某些输入上存在性能拐点需要重点排查。如果 CPU 占用长期超过 80%那么规划模块就可能挤压其他模块的资源影响整体稳定性。低配机载电脑不是不能跑路径规划而是要把地图分辨率、搜索范围、重规划频率都降下来。狼牙项目复盘