简介:这份MATLAB项目实例面向无人机开发者、科研人员及智能系统技术从业者,采用灰狼-粒子群混合算法(GWO-PSO)解决复杂三维环境下的无人机自主路径规划问题。项目覆盖环境建模、多目标适应度函数设计、动态参数自适应调整、路径平滑处理等关键环节,并配套完整GUI界面与代码详解,兼顾工程实用性与算法创新性。资源包共1个docx文档,约75KB,内含项目背景、模型架构、核心代码示例、项目特点与创新点分析,整体采用模块化设计,便于读者定位和二次扩展。已有255人学习下载,文档从三维环境建模到结果分析逐步展开,可帮助具备MATLAB基础的读者快速掌握混合群智能算法在三维路径规划中的实现思路、排错要点与优化方向。
1. 为什么无人机三维路径规划首选 GWO-PSO 混合算法
做无人机航迹规划的人大多有过这种体验:经典 A* 在二维栅格里很好用,一旦把高度、障碍物、威胁区一起塞进三维空间,搜索空间直接膨胀到天文数字;而纯粒子群(PSO)收敛快是快,却经常一头扎进局部最优,飞出来的路径贴着障碍物走,根本不敢真让飞机去飞。灰狼算法(GWO)的优点是全局搜索能力强,但后期收敛慢,迭代到两三百代时位置更新幅度还是很大,路径抖动明显。把两者按一定策略混合成 GWO-PSO,正是冲着「前期靠灰狼拉开搜索广度、后期靠粒子群精细收敛」这个互补性去的。
这篇文章要拆的就是一套完整的 MATLAB 实现方案:从三维环境建模、适应度函数设计,到 GWO-PSO 混合机制的代码写法、GUI 交互界面搭建,以及参数整定和常见坑的排查。内容按「先懂原理、再能复现、后能改参」的顺序展开,适合正在做毕业设计、竞赛作品或者项目预研的工程师阅读。
2. 三维路径规划的问题建模与 GWO-PSO 核心机制
2.1 三维路径规划的数学描述:从航迹点到适应度函数
无人机三维路径规划本质上是一个带约束的优化问题。设起点为 (P_s=(x_s,y_s,z_s)),终点为 (P_t=(x_t,y_t,z_t)),路径由 (N) 个中间航迹点 (P_i=(x_i,y_i,z_i)) 组成。常见的做法是先把起点到终点的直线段投影到 XY 平面,沿投影方向均匀取 (N) 个断面,每个断面上允许航迹点在垂直于投影线的方向上偏移,同时在该断面的高度区间内取值。这样路径就被参数化为一组决策变量,GWO-PSO 要优化的就是这些偏移量和高度值。
适应度函数通常由三部分加权组成:路径长度代价、安全代价和平滑代价。路径长度代价取相邻航迹点之间的欧氏距离累加;安全代价根据航迹点与障碍物中心的距离判断是否进入威胁半径,距离越近代价越高,必要时用阶跃函数直接淘汰;平滑代价则计算相邻三个航迹点构成的夹角变化量,用于抑制频繁转弯。综合表达式为:
[ J = w_1 \cdot L + w_2 \cdot S + w_3 \cdot C ]
其中 (L) 为归一化路径长度,(S) 为安全代价,(C) 为平滑代价,(w_1,w_2,w_3) 为权重系数。权重设置的常见起点是 (w_1=0.4, w_2=0.4, w_3=0.2),实际要根据地图规模和威胁分布调整。注意一点:如果权重和不为 1,算法依然能运行,但种群适应度的数值范围不稳定,后期设置收敛阈值时会比较麻烦。
2.2 灰狼算法的三种追捕行为在路径搜索中的角色
灰狼算法模拟狼群的社会等级和狩猎行为。种群分为 (\alpha)、(\beta)、(\delta) 三只头狼和其余 (\omega) 狼。位置更新公式如下:
D_alpha = abs(C1 * X_alpha - X(i)) D_beta = abs(C2 * X_beta - X(i)) D_delta = abs(C3 * X_delta - X(i)) X1 = X_alpha - A1 * D_alpha X2 = X_beta - A2 * D_beta X3 = X_delta - A3 * D_delta X(i) = (X1 + X2 + X3) / 3其中 A 和 C 是系数向量,A = 2a·r1 - a,C = 2·r2,a 从 2 线性递减到 0。看这段代码就能明白,灰狼算法的核心思想是让种群中每个个体都向三只头狼的加权中心移动,而不是像 PSO 那样只向个体历史最优和全局最优学习。这个差异在路径规划里很关键:路径搜索空间是连续的,而且存在大量局部凹坑,多领导者的引导方式不容易让整群狼同时陷入同一个狭窄的局部极值。
2.3 粒子群算法的速度-位置更新公式及其局限
PSO 的更新公式大家很熟悉:
v(i) = w*v(i) + c1*r1*(pbest(i) - x(i)) + c2*r2*(gbest - x(i)) x(i) = x(i) + v(i)w 是惯性权重,c1、c2 是学习因子。标准 PSO 有个明显问题:当全局最优解 gbest 落在一个局部极值附近时,所有粒子都会被它吸引过去,一旦粒子群聚集,多样性急剧下降,再想跳出来就非常困难。在三维路径规划场景下,这表现为算法跑完以后路径虽然很短,但会从两个障碍物之间的狭窄缝隙中穿过,实际上无人机根本飞不过去。单纯增大 c1 或者 c2 并不能根治,因为问题出在种群多样性维护机制上。
2.4 混合策略设计:串行切换还是并行融合
GWO-PSO 的混合方式主要有两种。第一种是串行切换:前 60% 迭代用 GWO 做全局探索,后 40% 切换为 PSO 做局部精修。这种做法的好处是逻辑简单,代码里只需要一个迭代次数判断,但缺点是切换瞬间种群位置会发生跳变,因为 GWO 的搜索半径和 PSO 的速度尺度不匹配。第二种是并行融合:每一次迭代中,种群的一部分个体按 GWO 公式更新,另一部分按 PSO 公式更新,同时让 gbest 和 α 狼相互传递信息。这种方案更平滑,实际效果也更好,推荐在 MATLAB 实现中使用并行融合。
我们项目里用的是在 PSO 速度更新公式中引入 GWO 的位置引导项,改造后的速度更新公式为:
v(i) = w*v(i) + c1*r1*(pbest(i) - x(i)) + c2*r2*(gbest - x(i)) + c3*r3*(alpha_pos - x(i))其中 alpha_pos 是灰狼群体的 α 狼位置。新增的第三项让粒子在学习自身经验和全局最优的同时,也向 GWO 的领导者靠拢,相当于在 PSO 的搜索机制中嵌入了一个全局探索漂移项。c3 一般设置在 0.3 到 0.6 之间,过大会导致粒子被 α 狼牵制而丧失自身搜索能力,过小则混合效果不明显。
3. MATLAB 实现 GWO-PSO 无人机路径规划:完整程序框架
3.1 三维地图建模:山峰障碍物生成与威胁区定义
先写环境构建函数,这里用高斯型山峰函数模拟地形和障碍物。常见做法是把地图定义为一个网格矩阵,每个网格点存储该位置的地形高度,山峰用多个高斯函数叠加生成:
function map = createMap(mapSize, peaks) % mapSize: [x_len, y_len],地图平面尺寸 % peaks: 每行为一个山峰 [cx, cy, height, sigma] x = 1:mapSize(1); y = 1:mapSize(2); [X, Y] = meshgrid(x, y); map = zeros(size(X)); for i = 1:size(peaks, 1) cx = peaks(i, 1); cy = peaks(i, 2); h = peaks(i, 3); s = peaks(i, 4); map = map + h * exp(-((X - cx).^2 + (Y - cy).^2) / (2 * s^2)); end end这段代码里 meshgrid 生成二维网格坐标,高斯函数的 sigma 控制山峰的坡度,sigma 越小山峰越陡峭。如果想让障碍物更接近真实地形,可以在峰值位置附近叠加一个偏置项,或者直接读入 DEM 数据替换 map 矩阵,后续路径规划算法完全不感知地形是怎么生成的,只要提供getHeight(x, y)接口就好。
3.2 路径编码与种群初始化:把路径参数化为决策向量
路径编码是 GWO-PSO 实现的核心数据结构。假设路径有 N 个中间点,每个中间点在三维空间中有三个自由度,那么每个个体就是一个长度为 3N 的向量。但直接对 x、y、z 同时编码会导致搜索空间过大,而且难以保证路径不穿越障碍物。更实用的做法是先在 XY 平面固定 N 个断面位置,只对每个断面上垂直于起点-终点连线的偏移量和高度值编码:
function pop = initPopulation(popSize, dim, lb, ub) % popSize: 种群规模 % dim: 决策变量维度,等于 2 * N(每个中间点两个参数) % lb, ub: 决策变量下界和上界 pop = lb + (ub - lb) .* rand(popSize, dim); endlb 和 ub 的取值需要根据地图尺寸计算。偏移量方向上的上下界设为垂直于航线方向的地图边界距离,高度方向的上下界设为无人机允许飞行的最低和最高高度值。这里有个经验值:如果地图是 100×100 的网格,飞行高度限幅在 0 到 50 之间,那么 x 方向偏移量上下界取 [-20, 20],y 方向取 [-20, 20],z 方向取 [10, 45],留出安全裕量。
3.3 适应度计算与碰撞检测
适应度函数要在计算路径长度的同时评估碰撞风险和平滑度。代码实现如下:
function cost = fitnessFunction(individual, map, startPt, endPt, N) % 解码:恢复航迹点坐标 path = decodePath(individual, startPt, endPt, N); % 1. 路径长度代价 L = 0; for i = 1:size(path, 1) - 1 L = L + norm(path(i+1, :) - path(i, :)); end % 2. 安全代价:检查航迹点及线段是否穿越障碍物 S = 0; for i = 1:size(path, 1) h_terrain = getMapHeight(map, path(i, 1), path(i, 2)); if path(i, 3) < h_terrain + safeDist S = S + 100; % 高度低于地形,惩罚 end end % 3. 平滑代价:相邻三点夹角 C = 0; for i = 2:size(path, 1) - 1 v1 = path(i, :) - path(i-1, :); v2 = path(i+1, :) - path(i, :); cosAngle = dot(v1, v2) / (norm(v1) * norm(v2) + eps); C = C + (1 - cosAngle); end % 组合加权 w1 = 0.4; w2 = 0.4; w3 = 0.2; cost = w1 * L / (mapSize(1) + mapSize(2)) + w2 * S + w3 * C; end注意路径长度做了归一化处理,除以地图对角线长度,这样三个量纲不同的代价项才能合理相加。安全代价用的是硬惩罚,一旦低于地形高度就加 100 分,这样在 GWO-PSO 的搜索过程中,凡是有碰撞风险的个体会被迅速淘汰。更精细的做法是使用连续惩罚函数,比如高度差值平方的倒数,这样也能保留一些离障碍物较近但对全局搜索有引导作用的中间解。
3.4 GWO-PSO 混合主循环的完整代码
主循环是整个算法的引擎,同时维护灰狼群体的 α、β、δ 和 PSO 粒子的 pbest、gbest。这里给出核心迭代代码:
function [bestPath, bestCost, convergence] = gwoPSO(...) % 初始化 positions = initPopulation(popSize, dim, lb, ub); velocities = zeros(popSize, dim); pbest = positions; pbestCost = arrayfun(@(i) fitnessFunction(positions(i,:), ...), 1:popSize); [gbestCost, gbestIdx] = min(pbestCost); gbest = positions(gbestIdx, :); alpha = gbest; alphaCost = gbestCost; beta = positions(1, :); betaCost = pbestCost(1); delta = positions(2, :); deltaCost = pbestCost(2); for iter = 1:maxIter a = 2 - 2 * iter / maxIter; % 线性递减控制参数 w = 0.9 - 0.5 * iter / maxIter; % 惯性权重衰减 for i = 1:popSize % GWO 位置更新 r1 = rand(dim, 1); r2 = rand(dim, 1); A1 = 2*a*r1 - a; C1 = 2*r2; D_alpha = abs(C1 .* alpha - positions(i,:)'); X1 = alpha' - A1 .* D_alpha; % 对 beta、delta 类似计算 X2、X3... X_gwo = (X1 + X2 + X3) / 3; % PSO 速度更新 r3 = rand(dim, 1); r4 = rand(dim, 1); r5 = rand(dim, 1); velocities(i,:) = w * velocities(i,:) ... + 1.5 * r3' .* (pbest(i,:) - positions(i,:)) ... + 1.5 * r4' .* (gbest - positions(i,:)) ... + 0.5 * r5' .* (alpha' - positions(i,:))'; positions(i,:) = positions(i,:) + velocities(i,:); positions(i,:) = max(lb, min(ub, positions(i,:))); % 边界约束 % 混合:一部分个体采用 GWO 更新,一部分采用 PSO 更新 if mod(i, 2) == 0 positions(i,:) = X_gwo'; end % 更新 pbest cost_i = fitnessFunction(positions(i,:), ...); if cost_i < pbestCost(i) pbest(i,:) = positions(i,:); pbestCost(i) = cost_i; end end % 更新全局最优和灰狼层级 [bestIdx, bestVal] = min(pbestCost); if bestVal < gbestCost gbest = pbest(bestIdx, :); gbestCost = bestVal; end alpha = gbest; alphaCost = gbestCost; % 更新 beta 和 delta ... convergence(iter) = gbestCost; end end关键点在于第 28 行的混合策略:序号为偶数的个体用 GWO 更新结果覆盖 PSO 更新结果,奇数个体保持 PSO 更新。这种按个体序号交替的融合方式能保证种群中始终存在约一半个体在进行全局探索,另一半在做局部开发。实际测试中,这种方式比串行切换的收敛曲线更平滑,不会出现迭代中期适应度突变回弹的现象。
4. GUI 设计与交互:把路径规划做成可操作的工具
4.1 GUI 整体布局与控件设计
MATLAB 的 GUI 构建有两种路径:一种是使用 GUIDE 工具拖拽控件生成 .fig 文件,另一种是纯代码用 uifigure 和 uicontrol 构建。GUIDE 在较新版本中已经不再推荐,建议直接用 App Designer 或者手写 uicontrol。对于本项目的三维路径规划界面,最核心的模块包括:地图参数输入区、算法参数输入区、开始/暂停按钮、三维路径显示区、适应度收敛曲线显示区。
典型布局如下:
+------------------------------------------------------+ | 地图参数 | 三维路径显示区域 | | 山峰数量 | | | 威胁半径 | | +------------+-----------------------------------------+ | 算法参数 | 适应度收敛曲线显示区域 | | 种群大小 | | | 迭代次数 | | | 权重设置 | [开始规划] [重置] [保存路径] | +------------------------------------------------------+4.2 使用 uicontrol 构建可交互 GUI 的完整代码
这里给出一个最小可运行版的 GUI 骨架,控件回调函数里嵌入了 GWO-PSO 的调用逻辑:
function gwoPsoGUI() fig = uifigure('Name', 'GWO-PSO 无人机三维路径规划', ... 'Position', [100 100 1100 700]); % 左侧参数面板 panel = uipanel(fig, 'Title', '参数设置', ... 'Position', [0.02 0.05 0.2 0.9]); lbl1 = uilabel(panel, 'Text', '种群规模', ... 'Position', [20 320 80 20]); edt1 = uieditfield(panel, 'numeric', ... 'Value', 50, 'Position', [100 320 60 20]); lbl2 = uilabel(panel, 'Text', '最大迭代数', ... 'Position', [20 280 80 20]); edt2 = uieditfield(panel, 'numeric', ... 'Value', 200, 'Position', [100 280 60 20]); btn = uibutton(panel, 'Text', '开始规划', ... 'Position', [40 50 100 30], ... 'ButtonPushedFcn', @(btn, event) runPlanning(edt1.Value, edt2.Value)); % 右侧三维显示区 ax = uiaxes(fig, 'Position', [0.25 0.3 0.7 0.65]); xlabel(ax, 'X (m)'); ylabel(ax, 'Y (m)'); zlabel(ax, 'Z (m)'); grid(ax, 'on'); view(ax, 3); hold(ax, 'on'); end function runPlanning(popSize, maxIter) % 调用 GWO-PSO 核心函数并绘制 [bestPath, ~, ~] = gwoPSO('popSize', popSize, 'maxIter', maxIter); plot3(ax, bestPath(:,1), bestPath(:,2), bestPath(:,3), ... 'LineWidth', 2, 'Color', 'r'); title(ax, sprintf('GWO-PSO 路径规划结果 (Iter=%d)', maxIter)); end注意 uieditfield 的 Value 类型是 double,在按钮回调里直接传递数值即可。绘制路径时要用 plot3 而不是 plot,否则三维效果会丢失。如果 GUIDE 环境想兼容旧版本,可以把 uifigure 换成 figure,uiaxes 换成 axes,逻辑不变。
4.3 GUI 与算法之间的数据传递模式
GUI 和算法函数之间常见的问题是参数传递作用域。在 MATLAB 中,回调函数内部访问不到其他函数工作区的变量,因此需要采用两种模式:第一种是把句柄结构体 handles 传递到回调函数,所有控件值通过 guidata 读取;第二种是把参数打包成结构体 option 传入算法函数。推荐第二种,因为算法函数通常需要多次调试和单测,不想被 GUI 控件绑定。
一个兼容写法是:
options = struct('popSize', 50, 'maxIter', 200, ... 'c1', 1.5, 'c2', 1.5, 'c3', 0.5, ... 'wStart', 0.9, 'wEnd', 0.4, ... 'mapSize', [100 100], ... 'startPt', [10 10 20], 'endPt', [90 90 15]);然后算法函数只接收 options 一个参数,内部解析各字段。这样 GUI 控件的任何改动只需要修改 options 的字段值,不需要改动核心算法代码。
5. 参数整定与可视化收敛性验证
5.1 六个必调参数的取值范围推荐与整定方法
GWO-PSO 混合算法涉及的主要参数如下:
| 参数 | 含义 | 推荐范围 | 调参方向 |
|---|---|---|---|
| popSize | 种群规模 | 30~80 | 地图复杂时增大 |
| maxIter | 最大迭代次数 | 100~500 | 看收敛曲线是否达到平缓 |
| wStart | PSO 初始惯性权重 | 0.9~1.0 | 过大则搜索发散 |
| wEnd | PSO 终止惯性权重 | 0.3~0.4 | 过小则收敛过早 |
| c1 / c2 | PSO 学习因子 | 1.2~2.0 | c2 大则加快收敛 |
| c3 | GWO 引导系数 | 0.3~0.6 | 大则全局探索强,路径抖动大 |
| a 递减速率 | GWO 控制参数 | 线性 2→0 | 非线性递减更平滑 |
调参时最忌讳一次同时改两个参数。一般先固定 c1、c2、c3,只调 wStart 和 wEnd,看收敛曲线是否出现长时间平台期;如果平台期出现太早,说明惯性权重下降过快,把 wEnd 提高;如果后期曲线还在剧烈震荡,说明群体多样性保持得过高,适当增大 c2 让粒子加速向全局最优靠拢。经验法则是每调整一个参数跑五次取中位数,避免单次随机性干扰判断。
5.2 三维路径绘制与障碍物渲染
将最优路径绘制到三维地图上,使用 mesh 绘制地形表面,并用红色加粗线绘制规划出的路径:
figure; mesh(X, Y, map, 'FaceAlpha', 0.6, 'EdgeColor', 'none'); hold on; plot3(bestPath(:,1), bestPath(:,2), bestPath(:,3), ... 'r-o', 'LineWidth', 2, 'MarkerSize', 4); plot3(startPt(1), startPt(2), startPt(3), 'go', 'MarkerSize', 10); plot3(endPt(1), endPt(2), endPt(3), 'ro', 'MarkerSize', 10); xlabel('X (m)'); ylabel('Y (m)'); zlabel('Z (m)'); view(45, 30); legend('地形', '规划路径', '起点', '终点');mesh 的 FaceAlpha 控制地形表面透明度,设成 0.6 可以同时看到地形起伏和路径穿越关系。有个可视化上的坑:如果地图的 z 轴比例尺与 x/y 不一致,路径看起来会特别陡峭或者特别平缓,此时可以手动调整 axis 的 zlim 范围,或者用 daspect([1 1 0.5]) 设置三轴比例。
5.3 收敛曲线分析和混合算法的增益量化
收敛曲线是判断混合算法是否有效的直接依据。记录每次迭代的全局最优适应度值,绘制半对数坐标曲线:
figure; semilogy(1:length(convergence), convergence, 'LineWidth', 1.5); xlabel('迭代次数'); ylabel('全局最优适应度 (log)'); grid on; title('GWO-PSO 收敛过程');注意图中能反映出的关键问题是:前期曲线下降速度是否足够快、中后期是否存在长时间平台震荡、最终是否收敛到一条稳定的直线。如果对比纯 GWO 和纯 PSO 运行同一地图场景,GWO-PSO 的最终适应度通常比纯 PSO 低 8%~15%,比纯 GWO 低 5%~10%,这只是经验量级,不等同于所有场景的保证。
5.4 障碍物边距和高度约束的验证方法
路径安全性不能只看适应度数值,必须绘制路径经过位置处的地形剖面。常见验证方法是把路径按等距采样成密集点,逐点比较飞行高度与地形高度:
samplePts = resamplePath(bestPath, 500); for i = 1:size(samplePts, 1) h_terrain = getMapHeight(map, samplePts(i, 1), samplePts(i, 2)); if samplePts(i, 3) < h_terrain + 5 % 5米安全距离 warning('第 %d 个采样点穿越障碍物', i); end end在这个验证步骤中,安全距离设成 5 还是 10 取决于无人机的尺寸和定位误差。小型四旋翼取 2~5,固定翼取 8~15,因为固定翼转弯半径更大,靠近障碍物时纠正动作需要更长的提前量。验证不通过时优先调整安全代价函数的权重,而不是盲目增大障碍物范围。
6. 让 GWO-PSO 从「能跑」到「好用」的四个关键技巧
6.1 障碍物威胁区建模:把硬约束改成连续惩罚项
很多初版代码把碰撞检测写成 if 判断,一旦碰撞直接给一个极大的惩罚值。这种做法会让搜索空间出现大量不可行区域,GWO 和 PSO 的粒子在迭代过程中一旦进入这些区域就被判死刑,只能靠随机扰动跳出来,效率很低。更实用的做法是使用连续惩罚项,比如:
penalty = exp(-(distance - safeRadius) / sigma);其中 distance 是航迹点到障碍物中心的距离,safeRadius 是安全半径,sigma 控制惩罚函数的衰减速度。当距离小于安全半径时,penalty 迅速增大;大于安全半径时,penalty 缓慢趋近于零。这样即使路径稍微贴近障碍物,粒子依然能获得梯度信息,知道往哪个方向调整能降低代价。实测中连续惩罚项的收敛速度比硬惩罚快 30% 以上,而且最终路径与障碍物的距离更均匀。
6.2 多峰障碍场景下分段权重策略
当一张地图里既有山峰障碍又有禁飞区,它们的威胁特性不同。山峰是高度信息,禁飞区是平面范围信息。可以在适应度函数的两个项里分别设置不同权重,但更精细的做法是把整个飞行过程中按航段分段计算安全代价,起点和终点附近的安全权重低,中段的安全权重要调高。原因是无人机起飞和降落阶段允许近距离贴地飞行,而巡航阶段必须保持安全高度。分段权重通过引入一个随航迹点序号变化的分段函数实现:
weightFactor(i) = 0.5 + 0.5 * sin(pi * (i-1) / (Nsample - 1));这样路径中间点的安全代价权重比两端高,多次测试后发现规划出的路径在起点和终点附近有更自然的爬升和下降曲线,而不是一路上都保持同样的安全距离。
6.3 MATLAB 性能优化:向量化计算代替 for 循环
GWO-PSO 适应度函数会被调用无数次,如果每次循环都重算地图高度、逐点计算距离,跑 500 代、80 个种群规模可能会花上三五分钟。优化思路是把高度查询向量化。把地形矩阵 map 直接用于插值,用 interp2 一次计算所有航迹点的地形高度:
h_terrain = interp2(X, Y, map, path(:,1), path(:,2), 'cubic');这比逐点 getMapHeight 再 for 循环快一个数量级。另一个优化点是路径长度的计算使用 diff 加 vecnorm:
segments = diff(path, 1, 1); L = sum(vecnorm(segments, 2, 2));这样做不仅简洁,还避免了每次循环的 norm 调用开销。种群规模大时,这些细节能把整体运行时间从分钟级压到秒级,对于需要反复调参的场景影响非常大。
6.4 路径平滑后处理:B 样条与轨迹可飞性修正
即使 GWO-PSO 已经收敛到一条无碰撞路径,直接给无人机飞控系统执行仍然不够,因为航迹点之间是直线连接,无人机在转弯处需要机动的角加速度很大,GB 以下的小型无人机根本跟不住。标准做法是输出路径后接一个 B 样条平滑步骤:
knots = linspace(0, 1, size(bestPath, 1)); sp = spap2(3, 4, knots, bestPath'); % 三次B样条拟合 tq = linspace(0, 1, 1000); smoothPath = fnval(sp, tq)';B 样条的阶数取 3 就能保证曲率连续,更高阶的曲线虽然更光滑但会偏离原路径点,有可能重新穿越障碍物。平滑后需要再次运行碰撞检测,如果平滑路径与障碍物发生碰撞,可考虑把安全距离上调 2~3 米再重新规划,或者在平滑过程中引入障碍物惩罚项,但这后一种做法已经接近轨迹优化范畴,这里不展开。
最终可飞路径的验证标准是:相邻航迹点之间的转弯角小于无人机最大转弯角约束,飞行高度始终高于地形至少一个安全距离,且总长度与 GWO-PSO 原始路径相差不超过 5%。这三条都满足,GWO-PSO 规划得到的路径才算真正具备下发给飞控执行的条件。
本文还有配套的精品资源,点击获取