ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

基于粒子群优化的多无人机区域优先路径规划与MATLAB实现

基于粒子群优化的多无人机区域优先路径规划与MATLAB实现 简介这是面向多无人机区域优先级路径规划的MATLAB实现适用于无人机协同控制、智能优化算法方向的课程设计、期末大作业与毕业设计。代码采用参数化编程用户仅需调整区域优先级权重、任务区域坐标、无人机数量等参数即可快速适配不同应用场景注释详细便于逐步理解算法思路。压缩包共10个文件以8个.m源码为核心涵盖主程序、粒子群优化、更新策略、地形绘制、适应度计算等模块另含README说明与license文件整体仅14KB轻量易读。已有33人学习浏览。实现中以粒子群优化为核心根据区域优先级动态调整多机飞行路径在保障高优先级区域优先响应的同时优化总体任务耗时可作为研究区域优先级路径规划问题的可靠基线与教学演示工具也适合在此基础上进行二次开发与算法改进。1. 多无人机路径规划为什么必须带区域优先级做多无人机任务规划时最容易被忽视的一环是区域优先级。比如一片区域同时出现多个任务点有些区域要求无人机必须提前到达普通区域则可以靠后。如果只按最短路径搜索得到的结果可能让高优先级区域的到达时间变得不可控任务整体失败。这个项目把粒子群优化(PSO)和区域优先级融合在一起在 MATLAB 中完成多无人机路径生成。核心做法是把优先级写进适应度函数让每一轮迭代都朝“重要区域先覆盖”的方向收敛。适合正在做无人机路径规划课设、毕业设计或者想了解 PSO 怎么从示例代码改造成工程应用的工程师。2. 粒子群优化(PSO)在路径规划里的数学模型与代码映射2.1 PSO 的基本原理与区域优先级融合粒子群优化模仿鸟群觅食每个粒子代表一个完整解。对于路径规划解就是一条或者一组航点序列。假设有 M 架无人机每架有 N 个航点粒子位置就是一个长度为M * N * 2的向量。粒子在解空间里飞行靠个体最优 pbest 和群体最优 gbest 不断更新自己的速度和位置。区域优先级不能等路径算完再叠加上去必须写进适应度函数。常见做法是构造一个加权代价函数cost λ1 * 路径长度 λ2 * 地形威胁惩罚 λ3 * 区域优先级奖励优先级惩罚的设计很关键。我的习惯是把任务区域定义成[cx, cy, radius, weight]weight越大代表该区域越重要。如果规划的航点没有进入这些区域惩罚值随距离线性增加如果进入了惩罚为零。这种连续惩罚比硬编码“必须先访问区域 A”更稳定因为 PSO 本身是连续优化平滑的惩罚函数能让粒子群逐步向高优先级区域靠拢而不是靠随机撞运气。项目里的fitness.m就是这套逻辑的入口。下面是我基于该文件常见结构拆出来的核心代码你可以对照自己的版本来读。2.2 从 fitness.m 看代价函数的权重设计function cost fitness(x, map, prioRegion) % x: 粒子位置包含 M 架无人机的航点 % map: 地形矩阵值为海拔高度 % prioRegion: [cx, cy, radius, weight; ...] M 2; % 无人机数量 dim numel(x) / M / 2; % 每架无人机的航点数 pathLen 0; terrainPen 0; prioPen 0; for k 1:M seg x((k-1)*2*dim1 : k*2*dim); pts reshape(seg, 2, dim); len sum(sqrt(sum(diff(pts).^2, 2))); pathLen pathLen len; % 地形约束航点高程超过安全阈值则加大惩罚 for i 1:dim px round(pts(i,1)); py round(pts(i,2)); if px 1 py 1 px size(map,1) py size(map,2) if map(px, py) 50 terrainPen terrainPen 1e4; end end end end % 区域优先级检查每个航点是否进入高优先级区域 for r 1:size(prioRegion,1) cx prioRegion(r,1); cy prioRegion(r,2); R prioRegion(r,3); w prioRegion(r,4); for k 1:M seg x((k-1)*2*dim1 : k*2*dim); pts reshape(seg, 2, dim); d sqrt((pts(:,1)-cx).^2 (pts(:,2)-cy).^2); if min(d) R prioPen prioPen 0; % 已覆盖不惩罚 else prioPen prioPen w * (min(d) - R); end end end cost pathLen 100 * terrainPen 2 * prioPen; end这段代码里100和2是权重具体数值要按地图尺寸调整。路径长度是主代价量级大概在几十到几百地形惩罚设成1e4确保任何穿过山峰的粒子直接被淘汰区域优先级惩罚系数设为2避免优先级权重压过距离代价导致路径畸形。如果地图尺寸变大路径长度也会变大区域优先级惩罚的系数要同步缩小否则算法会为了让航线蹭到高优先级区域而严重绕路。fitness.m接收的x是一维行向量前半段是第一架无人机的航点后半段是第二架这样在粒子更新时只需要维护一个向量不需要为多机单独维护一套坐标边界。区域优先级在这里体现为“距离差”而不是简单的二值判断这也是它能配合 PSO 连续搜索的关键。2.3 代码核心pso.m 和 updateSAI.m 的参数更新pso.m负责整个迭代框架。它先生成粒子群计算每个粒子的适应度再持续更新 pbest 和 gbest。这个项目里容易被忽略的是updateSAI.m它承担速度和位置的具体更新。SAI 通常指 Self-Adaptive Inertia即自适应惯性权重的意思。function [v, x] updateSAI(v, x, pbest, gbest, w, c1, c2, bound, dim) % w 可在外部按迭代次数做线性递减 r1 rand(size(v)); r2 rand(size(v)); v w.*v c1.*r1.*(pbest - x) c2.*r2.*(gbest - x); % 速度钳制防止粒子飞出搜索空间 vmax bound * 0.2; v(v vmax) vmax; v(v -vmax) -vmax; x x v; % 边界处理 x(x bound) bound; x(x 0) 0; end这里的w是惯性权重c1是个体学习因子c2是群体学习因子。标准 PSO 常用w0.7c1c21.5但放在区域优先级场景里我一般会让w从 0.9 线性递减到 0.4。前期让粒子充分探索整个任务地图后期再集中修正航点位置避免早熟收敛到一条没经过高优先级区域的路径。pso.m的主循环骨架大致如下for iter 1:maxIter for i 1:NP cost fitness(x(i,:), map, prioRegion); if cost pbestCost(i) pbest(i,:) x(i,:); pbestCost(i) cost; end end [gbestCost, idx] min(pbestCost); gbest pbest(idx,:); w 0.9 - 0.5 * (iter / maxIter); for i 1:NP [v(i,:), x(i,:)] updateSAI(v(i,:), x(i,:), pbest(i,:), gbest, w, c1, c2, bound, dim); end end注意bound要设成地图尺寸的最大值。之前见过有人把所有坐标缩放到 [0,1]但地形栅格是整数精度缩放后取整误差很大最终路径会明显偏离地形约束。建议直接在地图真实尺寸范围内搜索这样fitness.m里的round才有意义。3. 基于区域优先级的路径生成与地形约束处理3.1 环境建模terrain_figure.m 与 f_cell.m 的作用路径规划的第一步是构建环境terrain_figure.m负责生成地形。它通常用 MATLAB 自带的peaks函数或者插值工具生成一个二维高程矩阵然后画成三维曲面。常见实现是返回一个矩阵 Z方便后续fitness直接调用function [Z, x, y] terrain_figure() t -3:0.25:3; [X, Y] meshgrid(t); Z 5 * peaks(X, Y) 30; end这里把peaks放大 5 倍使山峰高度差达到 40 左右再加上 30 作为基准高度。如果无人机最大飞行高度只设 50那么部分山峰就会成为障碍地形约束才算真正起作用。如果 Z 变化太小fitness.m里的高度阈值判断就会失效规划出来的路径会直接穿过山峰。f_cell.m的作用是把连续坐标映射到地形栅格单元。因为 PSO 产生的坐标是浮点数而地形矩阵的索引是整数直接用round转换可能越界所以最好写一个安全的映射函数function cellValue f_cell(terrain, x, y) [rows, cols] size(terrain); xi max(1, min(rows, round(x))); yi max(1, min(cols, round(y))); cellValue terrain(xi, yi); end这种映射函数看起来简单但在迭代过程中能省掉大量 index 越界报错。粒子群的中间位置经常会跑到地图外没有这层保护整个循环会在几十次迭代后崩溃。3.2 多无人机任务分配与优先级如何影响起始点多无人机和单机最大的区别是起始点不同。通常每架无人机从不同基地起飞起始点固定不参与优化。但区域优先级会直接影响任务分配。例如两架无人机一架离高优先级区近另一架离得远合理的方案应该是让离得近的那架优先深入高优先级区域另一架去覆盖普通区域。在粒子编码里我们可以把每架无人机的航点拼成一个完整向量起始点单独存放在另一个矩阵中。fitness.m计算时再根据起始点把路径补全。下面是一个参数示例M 2; % 无人机数量 dim 5; % 每架无人机航点数 pstart [10 10; 50 80]; % 两架无人机的起飞点区域优先级的数据结构我习惯用[cx, cy, radius, weight]weight 越大代表该区域越重要。在实际调试中你会发现 weight 太大会导致路径过度绕行所有粒子都围着高优先级区域盘旋普通区域反而没人去。合理的做法是把 weight 设成 0.5 到 1.5 之间让算法在满足优先级和缩短总里程之间做折中。优先级方式轨迹特点适用场景硬约束必须经过路径绕行严重易陷入局部最优极小规模任务软约束权重惩罚路径平滑整体效率高多机协同、动态区域动态权重迭代中调整前期探索后期聚焦效果好复杂地形这个项目采用的是软约束也就是在fitness.m中计算惩罚值。如果你想改成硬约束可以直接在粒子初始化时强制生成通过高优先级区域的航点但那样会显著降低搜索效率。我一般不建议一上来就改硬约束先把软约束的权重调明白再决定。3.3 路径平滑Altd.m 的局部调整Altd.m的文件名很容易猜到是 Altitude Adjust高度调整。粒子群给出的原始路径往往带着不必要的突刺或者某些航点高度和地形贴合得太紧。Altd.m常见作用是做局部高度修正把低于安全高度的航点抬起来。function newpath Altd(path, terrain, safeAltitude) newpath path; for i 2:size(path,1)-1 h f_cell(terrain, path(i,1), path(i,2)); if h safeAltitude newpath(i,3) h 10; % 假设第三列是高度 end end end如果项目里 path 是二维的只有 x/y 坐标那么Altd.m更可能是在做等间隔插值把两个航点之间补上中间点让轨迹更平滑。打开文件后先确认路径矩阵有几列。如果只有两列那第三列高度不存在直接做路径长度方向的插值即可。这个函数对最终可视化影响很大因为不经过平滑处理的 PSO 原始路径看起来像折线真实任务中无法直接下发给飞控。4. 在 MATLAB 中运行与调参的完整步骤4.1 项目文件结构与运行入口 main2.m解压 zip 后目录下会看到这些文件文件作用main2.m主脚本设置参数并启动 PSOpso.m粒子群主循环fitness.m适应度函数f_cell.m连续坐标转栅格单元updateSAI.m速度与位置更新Altd.m高度/路径平滑调整plotfigure.m绘制地形和规划结果terrain_figure.m地形数据生成直接运行main2.m就能看到结果。要注意把 MATLAB 当前路径切到解压目录并确认README.md里要求的工具箱有没有缺少。如果plotfigure.m用了新版绘图函数而你用的是 MATLAB 2014a可能会报函数未定义。见到这种错误优先检查figure相关函数把surf或plot3换成旧版兼容写法。4.2 参数化编程哪些参数可以改项目强调参数化编程意思是核心算法不动只改参数就能换场景。打开main2.m重点找这组变量mapSize [100 100]; % 地图尺寸 M 2; % 无人机数量 dim 8; % 每架无人机航点数 maxIter 200; % 最大迭代次数 NP 40; % 粒子群规模 bound 100; % 坐标搜索边界 c1 1.5; % 个体学习因子 c2 1.5; % 群体学习因子 prioRegion [30 30 10 1.0; 70 70 12 0.6];mapSize一定要和terrain_figure.m生成的地图尺寸一致否则fitness.m里size(map,1)可能越界。M和dim改动时最稳妥的做法是让fitness.m也通过参数接收这两个值而不是硬编码。否则你改完main2.m忘了改fitness.m粒子长度和解析逻辑就会错位程序报错时还很难察觉。prioRegion是最重要的调参区域。举例来说如果你想让东侧区域优先就把东侧区域的 weight 调高其他区域调低。但是注意 weight 过高会导致路径严重绕行整体任务时间拉长。建议先用 0.5 开始试看生成路径有没有偏转不够再往上加一次加 0.2。4.3 结果可视化plotfigure.m 怎么读图运行完后plotfigure.m会输出一张三维地形图上面叠加了无人机路径。和普通路径规划图不同这个图里能体现区域优先级。于是你得读出两个信息路径是否真的覆盖了高优先级区域以及多机之间有没有明显交叉。如果默认图里没有画优先级区域可以自己加。常见做法是用半透明球体表示高优先级区域hold on; for r 1:size(prioRegion,1) [X, Y, Z] sphere(20); rad prioRegion(r,3); X X * rad prioRegion(r,1); Y Y * rad prioRegion(r,2); Z Z * rad max(terrain(:)) * 0.5; surf(X, Y, Z, FaceAlpha, 0.2, EdgeColor, none); end如果 MATLAB 版本较老FaceAlpha可能不生效但至少能画出球体轮廓。判断路径是否合理不要只看终点要看航点是否进入高优先级区域的半径范围。有时候 PSO 会在高优先级区域附近绕圈看起来覆盖了但实际并没有真正进入目标区域这时需要提高区域惩罚权重。5. 常见坑与验证技巧多无人机优化结果怎么判断好坏5.1 收敛曲线与路径冲突检查优化结束后的第一步不是看路径图而是看收敛曲线。在main2.m里加一行gbestHistory(iter) gbestCost;绘制gbestHistory可以看到代价下降过程。如果曲线在几十代内就水平说明粒子群有效收敛如果后期还在大幅震荡说明速度钳制不够或者w衰减太快。正常的收敛曲线应该是前期陡降、后期平滑。多机冲突检查也很重要。常见做法是把每条路径按航点插值成时间序列再比较同一时刻两架无人机的位置距离。如果最小距离小于安全半径就说明存在碰撞风险。注意 PSO 本身不包含时间维度路径空间交叉不一定等于实际碰撞但两条航线空间距离太近仍然要警惕因为无人机飞控不一定能保证精确的同步避让。5.2 参数敏感性惯性权重与学习因子调参时一次只动一个参数。以下是我在多场景下得到的经验参考具体数值要结合地图尺寸调整参数设置效果w0.9 恒定全局探索强前期搜索快后期震荡大w0.3 恒定局部开发强收敛快容易陷入局部最优w 从0.9减到0.4先粗后精轨迹质量最好c12.0, c20.5个体主导路径多样性差c10.5, c22.0群体主导收敛快但可能错过高优先级区我一般用w线性递减c1前期大后期小c2前期小后期大。这样前期粒子更多参考自己的历史最优扩大覆盖面后期群体最优更有参考价值把粒子拉向高优先级区域。updateSAI.m如果支持修改按这个思路实现时变参数效果会更稳。最后一个技巧是针对fitness.m里优先级惩罚的量纲问题。如果地图尺寸很大距离数值上百优先级惩罚w * (min(d) - R)的量级也很大有可能压过路径长度代价导致粒子的主要优化方向变成“靠近优先级区域”而非“缩短总路径”。这时候把距离做归一化normDist min(d) / maxMapDiameter; prioPen prioPen w * max(0, normDist - 0.2);这样优先级惩罚被限制在可解释的范围内地图尺寸变化不影响权重含义。判断优化效果时可以把高优先级区域内的路径长度除以总路径长度算出一个“优先级覆盖率”。如果这个比率明显高于高优先级区域的面积占比说明算法确实把区域优先级落到了航路上而不只是fitness数值在下降。下次跑新场景时先用这组参数试再根据覆盖率微调权重。本文还有配套的精品资源点击获取
返回列表