搞过论文复现的朋友应该都有这种体会看论文的时候觉得作者写得明明白白公式推导清清楚楚一到自己动手写代码全是坑。最近我花了大概两周时间用 Matlab 复现了一篇有关“空地多无人平台协同路径规划”的算法从公式到代码一点点啃整个流程踩了不少坑也攒了些经验。这篇博文就把整个复现过程、核心算法拆解和调试心得完整记录下来给同样在复现这类论文的朋友一个参考。我先简单交代一下这个项目是干什么的所谓“空地多无人平台协同”就是让无人机和地面无人车或者地面机器人在同一个任务场景里配合行动。无人机飞得高、视野广负责侦察和全局地图感知地面平台载重大、续航久负责实际执行运输、抵近检测等任务。两者单独拿出来都有明显的短板一旦组合起来就能形成一套“天上看、地上跑”的完整作业链。我复现的这篇论文核心就是解决这套组合系统里的路径规划问题——怎么给每一个平台规划出一条从起点到目标点的可行路线同时保证多平台之间既不会撞在一起又能整体效率最高。项目最终用 Matlab 实现了全套仿真输入一张栅格地图输出所有平台的运动轨迹和协调策略。这篇博文适合三类人看一是正在写毕业论文、需要复现路径规划算法的同学二是做多智能体仿真、想了解空地协同怎么落地实现的工程师三是对无人系统感兴趣、想看看 Matlab 到底能把这些论文算法玩到什么程度的爱好者。我会按项目推进的顺序来写从问题建模、算法选型、代码实现一直到调试避坑尽量把每一个“为什么这么做”讲透让看完的人能直接照着思路自己动手。1. 项目背景与问题建模1.1 空地协同路径规划到底在解决什么问题先把这个场景讲具体一点。假设某个区域发生了灾情需要无人机先飞过去拍一圈传回现场图像然后一辆地面无人车根据图像信息开进去执行物资投放或者环境采样。这里有两个层级的问题第一层是单个平台的路径规划。无人机和无人车各有自己的起点和目标点要在地图里找到一条避开障碍物的路线。不同平台的运动约束还不一样无人机可以自由转弯、爬升但飞行能量消耗大无人车必须在道路上行驶转弯半径受限速度也慢。规划出来的路径必须要能贴合各自的运动学特性否则就是画了一条理论好看、实际根本走不了的轨迹。第二层是多平台之间的协同。两个平台共享同一片空间如果无人机规划的航线和无人车规划的路线在某段时间里重叠了怎么办更复杂的情况是三架无人机、两辆无人车同时执行任务还要分先后去访问不同的目标点谁先飞、谁后跑、谁在哪等这些都必须在规划阶段就协调好不能等到了现场再临时避让。所以论文题目里的“协同路径规划”实际是要把两个问题放在一个框架里求解一个约束苛刻的路径搜索问题加上一个多智能体的资源分配和时序协调问题。这也是它比单机器人路径规划难一个数量级的原因。我一开始读论文的时候也踩了误区以为协同就是每个平台各自用算法算一条路最后画在图上就是协同。结果跑出来的轨迹乱成一团两辆车在中途撞了个满怀——不是真实碰撞是仿真里路线交叉了。这才意识到协同的核心在于“多平台共享信息、互相考虑对方”而不是简单的叠加。1.2 把路径规划转化为计算机能算的问题要让计算机处理路径规划第一步就是把现实场景抽象成数学模型。最常用的做法是栅格地图英文里叫 occupancy grid map。具体来说把地图划分成一个个方格每个格子要么是自由空间用 0 表示要么是障碍物用 1 表示。每个平台占据一个格子或者几个格子每次移动从当前格子跳到相邻格子。路径规划就变成了从起点格子出发经过一连串相邻的格子到达目标格子并且全程不能踩到值为 1 的格子。这个抽象方式虽然简单但极其通用。它把连续空间问题离散化了让计算机可以在有限的状态集合里做搜索。离散化的代价是精度取决于格子大小——格子设得越小地图越精细但计算量也指数级上升。论文复现的时候我花了不少时间在这个格子尺寸的选择上后面专门写一节讲这个。有了栅格地图之后路径规划问题就可以用一个标准的数学形式来描述给定有向图 $G (V, E)$其中 $V$ 是所有自由格子的集合$E$ 是所有相邻关系的集合每条边有一个代价 $w_{ij}$我们要找到一条从起点 $v_s$ 到目标点 $v_g$ 的路径使得路径上所有边的代价之和最小。这里的代价 $w_{ij}$ 可以很简单——比如就是两点之间的距离也可以很复杂——比如把飞行高度变化、转弯消耗、风险区域惩罚都算进去。至于多平台协同同样可以数学化。最简单的方式是把任务分配看成一个二分图匹配问题有 $M$ 个待执行的目标$N$ 个平台每对平台-目标之间有一个综合代价飞行时间 能耗 风险目标是让总代价最小的分配方案。这就是经典的指派问题匈牙利算法就能解。复杂一点的协同策略还会加入时间维度给每条路径加上一个“到达窗口”要求平台在规定时间窗内抵达目标点避免冲突。这个思路在我的复现里起到了关键作用后面细说。1.3 为什么复现这类论文首选 Matlab可能有人会问现在深度学习、强化学习都是 Python 的天下为什么我偏要用 Matlab 来复现路径规划论文说实话这是我权衡之后的决定理由有三点。Matlab 对矩阵和数组操作的支持是碾压级的。栅格地图本质上就是一个二维矩阵路径就是一组坐标索引序列这些数据结构和矩阵运算天然契合。写路径规划算法时频繁要用到的操作比如判断一个格子是不是障碍、更新一组邻居节点的代价、在图上叠加显示多条路径Python 要写十几行Matlab 里几行就搞定了。我自己统计过同样的 A* 算法Matlab 版本的核心代码比 Python 版本的还要短三分之一。Matlab 自带了一套非常成熟的可视化和仿真工具。论文复现很重要的一项工作是画图——论文里那种坐标轴上有地形、有障碍、有平滑曲线的精美轨迹图Matlab 用 plot、scatter、patch 这几个函数就能组合出来还可以很方便地做成动画。对搞研究的人来说图就是成果的体现这一步省很多事。Matlab 的 Robotics 和 Navigation 工具箱里有大量现成的路径规划算法实现从最基础的 A*、Dijkstra到 RRT、PRM再到用于局部避障的 DWA全都开箱即用。复现论文时工具箱函数可以帮我们快速验证哪个算法适合作为论文算法的基准对比省下大把写基础算法的时间。当然选 Matlab 也是有一些代价的最主要就是性能。纯 for 循环跑大尺寸地图的搜索会很慢我后面会讲怎么通过向量化和预分配把速度提上来。另外 Matlab 的并行计算工具箱需要额外配置不过好在路径规划这种任务用多线程也有点重通常不需要上并行。2. 核心算法选型与协同策略拆解2.1 单平台路径规划从 Dijkstra 到 A* 到 RRT*路径规划算法是这座城堡的地基。论文里通常不会只用一种算法而是会在不同层级用不同的算法组合。我这次复现时经历了一个从基础到高级、从盲目到清晰的过程先把几个主流的算法梳理一下。Dijkstra 是最经典的单源最短路径算法核心思路很朴素从起点出发每次扩展当前代价最小的节点直到扩展到终点。它的优点是保证找到最优解缺点是搜索范围过大漫无目的地向四周扩展效率比较低。A* 算法在 Dijkstra 的基础上加了一个启发函数让搜索具有方向性。它评估每个节点的总代价 $f(n) g(n) h(n)$其中 $g(n)$ 是从起点到当前节点的实际消耗$h(n)$ 是当前节点到目标点的估计消耗。只要启发函数满足一致性条件A* 不仅能找到最优路径搜索范围还比 Dijkstra 小得多。我复现的论文里无人机全局路径规划用的就是 A* 系列的改良算法。RRT 系列算法是为高维空间设计的采样类算法它不遍历地图而是随机撒点把地图上的可行点不断生长成树形结构直到树碰到目标点。RRT* 在此基础上增加了重连接rewiring操作让生成的路径渐进最优。这类算法特别适合无人机的三维空间路径规划因为三维栅格地图的节点规模太大了A* 有时候会爆内存RRT 靠采样就没有这个烦恼。那难道直接用 RRT* 替代 A* 不行吗也不是这么回事。RRT* 虽然在大维度空间占优但它生成的是随机路径品质不稳定而且规划结果每次都不一样。我在复现实验里发现论文作者通常的做法是二维平面内用 A*/Dijkstra 这类确定性算法保证稳定的最优路径三维空间或复杂动态场景再用 RRT 变种来突破维度或是用改进的改进多种群粒子群、遗传算法做不低于二维的路径平滑与寻优。我给大家一个算法选型的决策表这是我复现之后整理出来的直接抄作业用场景推荐算法理由二维栅格地图小规模Dijkstra / A*确定最优实现简单二维栅格地图大规模A* 变种启发函数可加速内存可控三维空间静态障碍RRT* / RRT-Connect采样法在高维空间有优势三维空间动态障碍RRT* 局部避障全局规划结合局部重规划多目标点访问遗传算法 A*用智能算法解决组合优化问题2.2 多平台协同任务分配与冲突消解的真实难度读完论文的算法框架图你会发现真正的创新其实不在单平台路径规划上——因为 A*、RRT* 这类基础算法大家都熟。论文的核心卖点在于协同机制也就是怎么让多平台之间有序配合。这部分我拆解成两个子问题来说。第一个是任务分配问题。假设有 $K$ 个目标点需要被执行有 $N$ 个无人平台无人机加无人车。到底让谁去执行哪个目标最简单的办法是贪心给每个目标分配一个离它最近的平台。但贪心经常会引发连锁反应——离目标 A 最近的平台去 A 了导致目标 B 只能由更远的平台去总体效率反而变差了。论文里常用的是全局最优分配把问题建模成最小代价匹配用匈牙利算法来解。我复现时直接调用了自定义的匈牙利函数输入是“每个平台到每个目标的代价矩阵”输出就是一个个不冲突的指派结果。当平台数大于目标数时任务分配后再把剩余平台作为协同避障或二次支援力量这一点在现实中很重要。第二个是路径协调问题。任务分配完之后每个平台会独立规划一条最优路径但多条最优路径放在一起就会打架——两条路径可能在某条狭窄通道交汇。要消解这种冲突常见的思路有三种优先级法、时间窗法、速度协调法。优先级法给每个平台设定优先级低优先级平台遇到高优先级平台时主动避让或重新规划路径。时间窗法每个平台经过共享节点时要求在其他平台的时间窗之外通过相当于给路径加上了预约机制。速度协调法路径不变但调节每个平台的速度曲线让它们在冲突区域错开时间。我复现论文里用的是“任务分配 时间窗”的组合方案。任务分配阶段决定谁去哪个目标时间窗协调在规划阶段加入了每个平台在共享节点的经过时间约束把原来“各自跑各自的”变成了“有序地错峰到达”。这样整体效率最优而且不会产生中途急刹、倒车的尴尬情况。2.3 复现论文时如何从公式翻译出代码论文复现最难受的一步是把数学公式翻译成代码。这个坎跨不过去一切都白搭。我总结了一套自己的翻译方法写在这里供大家参考。方法论核心就是“先把公式结构化再逐块对照变量名”。对付一个数学公式我先做三件事第一找出输入变量和输出变量搞清公式的边界第二把求和、求导、迭代这些运算符号翻译成代码里的循环或向量运算第三把论文里没交代清楚的量值比如各种系数、阈值先记在一边等调试的时候再统一标定。打个比方RRT* 算法里最核心的重连接那一步论文里通常写的是“对距离小于半径 $r$ 的邻居节点如果通过新节点到达的路径代价更小则重新接上”。这段描述看起来很简单但实际写代码时你会遇到三个问题邻居半径 $r$ 应该取多大代价函数到底包含哪些项重新连接之后父节点更新需不需要考虑后续航线的可行性论文里往往一带而过留给你自己去琢磨。这时候我的做法是在初始阶段根据地图尺寸设置 $r$然后跑几个不同取值做对比实验最后把结果与论文原算法的实验曲线比对逐步把各个参数标定到合理范围。这一步就是论文复现和普通代码编写的本质区别——你要让代码跑出论文曲线而不是光让它能运行。3. Matlab 代码实现与关键仿真细节3.1 栅格地图构建与参数约定先上代码这是最基础的地图生成部分。我用一个二维数组来定义地图0 代表可通行区域1 代表障碍物2 代表起点/终点等特殊位置。% 地图尺寸50x50 栅格 map_size [50, 50]; % 随机生成障碍物密度 0.3 obstacle_density 0.3; map zeros(map_size); random_map rand(map_size); map(random_map obstacle_density) 1; % 手动设置起点和终点 start_point [2, 2]; end_point [48, 48]; map(start_point(1), start_point(2)) 0; map(end_point(1), end_point(2)) 0;这里有几个细节要提醒。随机生成障碍物地图时必须手动把起点和终点对应格子重置为 0否则这两个位置可能生成在障碍物上后面的路径搜索直接失败。另外随机地图里可能出现孤立区域——障碍物围了一圈进去就出不来。我是在主程序里加了一个连通性检查确保起点和终点位于同一个连通分量内否则就重新生成地图。这个坑我浪费了一个小时才意识到。还有一种更贴近论文场景的地图构造方式不用纯随机阻塞而是人为设定若干条“走廊”和“障碍块”模拟城市街区或者野外山地。我的做法是先用零矩阵再用几个矩形区域赋值为 1最后添加一些稀疏噪声点。这种地图更符合实际任务场景规划出来的路径也更接近人的直观判断。3.2 单平台路径规划函数的设计我最开始采用的单平台路径搜索算法是 A*因为论文对比实验的基准就是 A*。我把 A* 做成了一个独立的函数输入地图、起点、终点和平台类型无人机或无人车输出路径。无人机和无人车的区别体现在搜索时允许的邻域扩展方式上无人机可以采用 8 邻域扩展上下左右加四个对角甚至可以加垂直维度的层间移动。无人车只能走 4 邻域而且对角移动的代价比直线移动更高因为它转弯难。A* 的核心代码逻辑如下function path a_star(map, start, goal, allow_diagonal) % 定义启发函数欧几里得距离 heuristic (pos) sqrt((pos(1) - goal(1))^2 (pos(2) - goal(2))^2); % 初始化 cost_g inf(size(map)); cost_g(start) 0; parents zeros([size(map), 2]); % 用 open list 保存待扩展节点 open_list zeros(5000, 2); open_count 1; open_list(1, :) start; % 主循环略... end这里有个细节值得单独拿出来讲open list 的数据结构选择。初学者习惯用一个数组存所有待扩展节点每次取最小代价节点时用 min 函数遍历整个数组。这样做在小地图30x30上没问题地图一旦超过 200x200每次遍历的耗时就会变成瓶颈。我在第二次迭代优化时把 open list 改成了最小堆实现的优先队列单次运行的耗时直接降了一个数量级。虽然 Matlab 里没有内置的堆结构但可以用容器类加上几个自定义函数模拟代码量不大收益非常大。启发函数的选择也需要注意。我一开始用曼哈顿距离两点横纵坐标差之和规划出来的路径带有明显的“先走直线再转弯”的阶段性折痕路径长度虽然最优但看起来很不自然尤其无人机飞行的轨迹根本没法看。后来改成欧几里得距离路径就变得平顺多了。这里给大家提个醒启发函数必须满足一致性consistent条件A* 才能保证全局最优欧几里得距离满足这个条件曼哈顿距离在某些栅格对角移动代价设置下不一定满足需要先算好代价值来验证。3.3 多平台协同仿真从各自跑到一起跑单平台路径规划跑通之后我满怀期待地把三架无人机和两辆无人车的路径画在同一张图上结果发现两条轨迹在某个通道口撞在一起了。这个问题的根源就是我在 2.2 节说的路径冲突。接下来就是协同部分的重头戏。我复现的协同框架采用“任务分配 → 独立规划 → 冲突检测 → 时间窗调整”四步流水线。任务分配用匈牙利算法得到平台到目标的指派矩阵独立规划阶段每个平台调用各自的单机路径搜索函数冲突检测阶段扫描所有路径找出哪些节点和路段被多个平台占用时间窗调整阶段给后进入冲突区域的平台增加出发延迟让它等先锋平台通过后再出发。仿真层面的实现有一个很关键的地方要让每个平台有自己的状态更新循环同时共享一个全局时钟。我的做法是用一个仿真主循环每个时间步长 dt 里更新所有平台的位置同时检查任意两台平台的相对距离如果小于安全距离阈值就触发冲突处理逻辑。这里的 dt 和安全距离阈值都是可以调的实验参数论文里一般会做参数敏感性分析我也是在反复实验后确定的一组取值。% 多平台仿真主循环 dt 0.1; safe_dist 1.5; for t 0:dt:sim_time for i 1:num_platforms % 按路径点推进位置 platform(i).pos move_along(platform(i).path, platform(i).vel, dt); end % 冲突检测 for i 1:num_platforms for j i1:num_platforms if norm(platform(i).pos - platform(j).pos) safe_dist % 进入冲突消解逻辑 resolve_conflict(platform(i), platform(j)); end end end end这个双层循环在平台数不超过 2、3 个的时候没问题一旦平台数增加到 10 个以上每帧都要做 45 次距离计算还没算路径重规划性能就开始拉胯了。优化思路是把地图划分成网格只检测相邻网格里的平台对这个叫空间哈希。我后来又做了一次升级综合效果还不错。3.4 可视化把结果画得像个论文图论文复现实验里图例美观度的重要性不亚于算法正确性。评审看一眼仿真图就能直观判断这项工作完成度如何。我用 Matlab 的可视化功能做了三张图全局地图与所有规划路径图、平台运动轨迹动画、协同避碰关键帧放大图。全局路径图用 plot 函数画各个平台的颜色区分轨迹再叠加静止障碍物网格网格用 rectangle 或 patch 画。为了让障碍物显示更立体我用了 fill 函数填充色块并在每个色块边缘加了细线。动画效果的核心是用循环 drawnow 配合延时函数。先把地图画好然后用 plot 的句柄更新机制每帧移动平台位置标记。Matlab 的动画性能比较一般平台数量多的时候明显卡顿我的经验是减少不必要的绘图对象数量比如提前把路径线和目标点一次性画完平台标记用单独的散点句柄更新这样能省一半以上的绘图开销。轨迹动画的代码结构大致是figure(Position, [100, 100, 800, 600]); hold on; % 画地图背景和障碍物 draw_map(map); % 画所有规划好的路径 for i 1:num_platforms plot(paths{i}(:, 2), paths{i}(:, 1), LineWidth, 1.5); end % 用散点句柄表示平台当前位置 handles scatter(zeros(num_platforms, 1), zeros(num_platforms, 1), 80, filled); for t 1:num_frames for i 1:num_platforms pos interpolate_path(paths{i}, t / num_frames); set(handles(i), XData, pos(2), YData, pos(1)); end drawnow; end最终生成的效果图和论文原图放一起对比肉眼可见地接近。为了做到这一点我还专门调了主题配色、线条粗细、字体大小这些细节放在第 4 章讲排图技巧时一起说。4. 调试、性能优化与避坑实录4.1 参数调优的真实经验栅格尺寸与启发权重整篇论文复现下来调试参数是最耗时的一环。我把踩过的关键参数坑集中写在一张表里方便大家对照。参数初始值调试后的推荐值调试心得栅格大小10.5地图太粗会把狭窄通道填平太细会导致搜索爆炸启发函数权重11.0~1.2大于 1 时搜索更快但可能牺牲最优性1.0 最稳安全距离阈值1.52.5太小导致路径互相贴近太大浪费可通行空间时间窗步长20 秒10 秒步长太大导致时序协调失败太小导致调度冗余转弯代价02不加转弯代价的路径全是锯齿不适合无人车执行栅格尺寸的选择值得展开说。设到 1.0 时地图上 3 格宽的通道刚好能过无人车但实际车辆外形如果占 1.5 格就会擦着障碍物边缘走非常危险。后来我把地图栅格尺寸细化成 0.5同时把无人车的碰撞体半径设为 0.8 个地图单位路径安全裕量就出来了。这个取舍的本质是计算复杂度和安全裕度之间的平衡论文里一般不会写这么细只能靠自己去试。启发函数权重这块我最初试图用 $f(n) 1.5g(n) h(n)$ 这种“贪婪加速”的做法以为能更快收敛结果跑出来路径长度比最优解长了 20%而且由于启发函数不再一致A* 甚至偶尔会重复扩展同一节点。论文里如果要严格保证最优解权重就别动只要近似解可以适度调到 1.2 左右搜索速度能明显提升。4.2 多机避碰的死锁与震荡问题多平台仿真最常见也最隐蔽的坑就是死锁和震荡。死锁的典型场景是这样的两辆无人车在一段窄巷子里面对面相遇谁也不让谁——让了之后自己就没有满意路径了结果两边都在原地等待任务卡住。震荡则更像两个平台在相遇点附近反复“谦让”你让我、我让你走来走去始终在原地打转。这两个问题在代码里表现出来的行为相似但根源完全不同。死锁的根源是路径规划阶段没有考虑对方的动态占用信息。两个平台各自规划的路径在窄巷子里重叠等到了执行阶段才发现“路被堵了”这时候再想重规划已经晚了。我采用的解法是前面说的时间窗法在任务规划阶段就给共享路段加上占用时间窗口。任何平台的时间窗与已有占用窗口重叠时就自动将出发时间向后平移。这样两个平台在规划完成后已经天然地“约好了”谁先走谁后走执行阶段就不会在窄巷子里死磕。震荡的根源则是局部避碰策略设计得太“贪心”。两个平台的距离小于安全阈值时让其中一个平台原地等待这条策略听起来没什么问题但如果等待条件频繁切换比如 A 等 B 走、B 等 A 走就会形成震荡。我的处理方式是在避碰逻辑里加了一个最小等待时间也就是说一旦决定某平台等待至少等满 3 秒才有权重新决策。这样虽然引入了轻微的延迟但彻底消掉了震荡现象。这个技巧看似微不足道但在我跑过的 20 组随机地图里加了这 3 秒之后冲突重规划次数下降了约七成。4.3 仿真性能优化矩阵化与预分配代号Matlab 虽然擅长矩阵运算但它的循环可没比别的脚本语言快多少。我第一次跑 50x50 地图、4 个平台、200 个时间步的仿真总共花了 40 多秒其中光 A* 的单次规划就要 3 秒。针对这个问题我做了三个层面的优化。第一层是向量化。把凡是能不用 for 循环的地方全部改写成矩阵运算。典型例子是计算所有自由格子到某个目标的启发值时原来是一格格算后来直接用一个二维网格坐标矩阵一次性算完。这个改动让启发值计算这块的时间复杂度从 $O(n)$ 降到接近常数级。第二层是预分配。Matlab 里在循环中动态扩充数组是最致命的速度杀手。我原先用 open_list [open_list; new_node] 的方式扩容跑起来慢得离谱。改成预先分配一个足够大的矩阵再用一个计数器记录当前存储了多少个节点速度快了不是一点点。这里有一个小技巧open list 的容量设得非常充足比如地图上自由格子总数为 1 万就分配 1.5 万行避免动态扩容。第三层是用编译后的函数。对运行瓶颈集中的核心函数——A* 主搜索循环我尝试过使用 code 生成器把它编译成 MEX 函数再调用用 C 的速度执行。改造之后单次 A* 规划从 3 秒降到了 0.4 秒左右整个项目的实验迭代速度有了质的提升。MEX 这玩意调试比较麻烦不建议在开发初期就引入务必先保证算法逻辑完全正确再去琢磨性能。另外还有一个容易被忽视的点绘图 obj 的刷帧开销。如果仿真里要输出动画Map 和路径的静态元素不要每一帧都重画只更新动态平台的位置即可。drawnow 的调用频率也可以适当降低比如每 5 个仿真步才刷新一次界面肉眼完全分辨不出来但 CPU 占用会降低很多。4.4 论文图复现的排版技巧与成图输出最后分享一下论文图复现时的一些偏门技巧。做科研的同学都知道论文里的仿真图不仅要数据正确还要排版美观。我总结了三条经验。配色要克制。图里的障碍物统一用灰色系路径用颜色区分但避免大红大绿尽量选色相差异大而饱和度适中的颜色比如藏青、深绿、酒红。坐标轴、网格线、背景全都调成浅色系人看起来不刺眼。调色的代码核心就一行colormap([0.85 0.85 0.85; 0.3 0.3 0.3]); % 自由空间浅灰, 障碍物深灰字体和线宽要全局设定。我用了一个统一的风格配置脚本把坐标轴字体设为无衬线字体、字号设置为 12路径线宽设置成 1.8平台标记的边线加粗。这样做的好处是多张图放在一起对比时视觉风格统一论文审稿人看了会舒服很多。输出图片分辨率要够。Matlab 用 exportgraphics 或 print 导出图片时记得指定分辨率我一般用 300 DPI 导出 PNG 或 PDF。导出之前把所有图例、标题、标签都摆好位置不要导出之后再拿外部工具裁剪那样会导致字体和线条变形得不偿失。结语一些碎碎念这次论文复现做下来我最深的感触是论文里的数学推导是骨架真正的血肉都在代码细节里。算法名称谁都知道A*、RRT*、匈牙利匹配翻翻教材就有但要把它们组合成一个能端到端运行、可重复出图的系统需要解决的全是上面这些看似琐碎、实则致命的问题——栅格尺寸怎么设、时间窗怎么填、死锁怎么解、成本函数怎么标定。这些恰恰是论文里不写的部分。另一个让我印象深刻的点是空地协同问题的难点并不在于某个平台的技术而在于多个平台之间的时序和空间协调。单平台路径规划的技术早已成熟但一旦牵扯到多平台共享环境问题的维度一下子变了这也是为什么“协同”这两个字在题目里如此重要。最后再分享一个小技巧如果你也想复现类似的论文先别急着翻开代码建议先用纸笔把整个仿真流程的时间线画清楚——谁在什么时刻规划、谁在什么时刻运动、谁在什么时刻等待。这张时间线图能帮你解决 90% 的协调逻辑问题。我当时就是因为没画这个多花了一整天在调试死锁问题。好了这篇记录就写到这里。项目代码我已经整理完毕所有仿真结果可以稳定复现实验曲线也都能重新生成。如果你也正在做路径规划甚至多无人系统的复现和研究希望这篇内容能帮你少走点弯路。有问题欢迎在评论区交流看到必回。
阅读完成 · 觉得有帮助?