
多无人机协同路径规划这几年算是被越炒越热但真正上手做过的人都知道这玩意儿比单机路径规划难的不是一点半点。搜索空间维度成倍膨胀不说机间碰撞约束、时间协同约束堆在一起很多常规优化算法连收敛都做不到。我这次要分享的就是一套基于PWLCM混沌映射的部落竞争与成员合作算法TCMC去解决多无人机协同路径规划问题的完整研究过程全部用Matlab实现。文中会给出可复现的代码思路、核心公式以及我自己踩过的一系列坑希望给正在做相关方向的人一些参考。这套东西解决的核心问题有两层第一层是“航迹怎么寻优”即如何为每架无人机找出一条从起点到目标点、满足地形和威胁约束的平滑路径第二层是“多机怎么协同”即多架无人机之间不能相撞、尽量同时到达、能耗尽量均衡。传统做法比如A*、RRT在二维平面还行一旦跑到三维多机场景状态空间爆炸效率和成功率都堪忧。于是群智能算法成了主流选择而PWLCM混沌映射和部落竞争机制的组合就是为了针对性解决群智能算法最典型的两个毛病——初始种群质量差、后期早熟收敛。1. 多无人机协同路径规划难在哪里1.1 先把问题拎清楚要优化什么先别急着写代码任何优化问题第一步都是建模。多无人机协同路径规划的输入一般包括任务起点、目标点、地形高程数据、威胁源列表雷达、防空火力等、无人机性能参数最大转弯角、最大爬升率、最小飞行高度。输出则是每架无人机的一串三维航迹点。在Matlab实现中通常把每架无人机的航迹表示成若干个待优化航迹点的坐标序列。比如说3架无人机每架10个中间航迹点那决策变量的维度就是3 架 × 10 点 × 3 维坐标 90 维90维的连续高维搜索对普通启发式算法已经很有压力了。再加上每条航迹要满足物理约束机与机之间还要保持安全距离整个问题的可行域变得非常破碎。目标函数一般包含航迹代价、威胁代价、高度代价和平滑代价。航迹代价就是总航程衡量油耗和时间威胁代价计算航迹穿过的威胁区域高度代价惩罚飞得过高或过低平滑代价惩罚突变的转弯和爬升。多机协同场景下还要加一装机间距离的惩罚项或者说把碰撞约束做成硬约束。1.2 约束条件不是简单加个惩罚就完事无人机协同路径规划的约束有个很阴险的特点它们往往是耦合的。比如想降低航迹代价航迹就会尽量取直但直线可能穿过威胁源威胁代价飙升想让机间距离大于安全阈值各机的航迹空间就受到彼此限制搜索维度无形中又高了一截。我一开始做这个项目的时候图省事把所有约束都折算成加权惩罚项塞进适应度函数。结果发现权重怎么调都别扭权重低了约束被无视算出来一堆“看着最优”实际不能飞的航迹权重高了可行域被极度压缩算法根本找不到解。后来换了个思路——把硬约束拆开处理碰撞约束用惩罚项参与适应度计算但威胁代价和高度代价用对数函数放大局部差异这样算法的搜索梯度更明显。1.3 为什么群智能算法是主流但还不够目前解决这类问题的主流方法就是群智能算法粒子群、鲸鱼算法、灰狼优化、差分进化这些都有人用。原因很直白不依赖梯度信息能并行计算对高维非凸问题适应性好。但群智能算法的两大顽疾也很致命。第一个是初始种群随机分布不均匀尤其在高维空间里随机数发生器产生的点很容易扎堆导致算法从几个狭隘的区域开始搜索全局探索效率低。第二个是早熟收敛迭代后期种群多样性快速下降所有个体都挤在局部最优附近再也跳不出来。本文研究的PWLCM混沌映射就是用来改善初始分布的而部落竞争与成员合作机制则是从种群结构上延缓多样性流失。2. 核心算法原理PWLCM混沌映射与部落竞争机制2.1 PWLCM混沌映射让初始种群撒得均匀PWLCM全称是分段线性混沌映射Piecewise Linear Chaotic Map说简单点就是一张分段线性函数构成的离散映射通过简单迭代生成一组看起来随机、实际上遍历性很强的序列。跟我以前用的Logistic映射相比PWLCM的分布更均匀陷入局部循环的概率更小而且计算速度非常快只涉及乘除和比较操作。PWLCM的标准分段公式是这样的x_{n1} { x_n / p, 当 0 x_n p (1 - x_n) / (1 - p), 当 p x_n 0.5 (1 - x_n) / p, 当 0.5 x_n 1 - p (x_n - 1 p) / p, 当 1 - p x_n 1 }其中控制参数 p 在 (0, 0.5) 区间内取值。我的实际使用经验是 p 取 0.3 附近效果比较稳太靠近 0 或太靠近 0.5 时序列容易退化成若干个别片段反复循环。PWLCM在算法里的作用很关键它负责生成初始种群。想生成 D 维坐标就打 D 条混沌序列把序列值映射到搜索空间上下界。用这种方式替代Matlab自带的 rand 函数初始解能更均匀地铺满空间算法前期的探索能力明显提升。2.2 部落竞争与成员合作机制的运行逻辑部落竞争与成员合作算法TCMC是我认为比较有意思的一个框架它模拟的是人类部落社会的演化逻辑简单说就是“对内合作、对外竞争”。算法初始化时把整个种群分成若干个部落比如3到5个每个部落内部有若干成员。每个部落会有一个酋长也就是本部落当前最优的个体。迭代过程分两个阶段第一个阶段叫成员合作。部落内成员之间通过信息交换、向酋长学习、参考自身历史最优位置等方式更新自己的位置。这个阶段本质上是在部落局部区域内做精细搜索说白了就是让一群人在酋长带领下把周围的山头都摸清楚。第二个阶段叫部落竞争。每轮迭代结束以后比较各个部落的酋长适应度适应度弱的部落会受到惩罚要么被淘汰一部分成员要么向强者部落方向偏移甚至被周围更强的部落“吞并”重组。这样既保持了多样性多个部落并行搜索又保证了收敛压力弱者向强者学习。我发现这个算法结构最大的优点是它很好地平衡了“探索”和“开发”。成员合作阶段保证局部开发部落竞争阶段通过不断重组来保持探索动力比单一结构的PSO稳健很多。2.3 为什么要把混沌映射和部落机制组合起来这两者组合不是拍脑袋而是互相补短板。PWLCM混沌映射解决的问题是“开局”部落机制解决的问题是“中后盘”。开局阶段用混沌序列生成初始种群本质上是把随机方格变成了均匀分布的筛子让每个部落从一开始都站在不同的山头上。中后盘阶段单一部落就算陷入局部最优其他部落还在独立搜索即便个别部落全军覆没重组机制也能依附强者生成新的个体保证剩下的人继续探索。我实测下来这种组合使算法在72维协同路径规划场景下成功率比普通随机初始化标准PSO高出约40个百分点收敛代数也更短。不过要注意混沌初始化不是万能的它只改善初始状态。真正决定最终解质量的还是适应度函数设计和迭代策略。如果你在博客复现时发现最终结果仍然很差优先检查适应度函数而不是继续在初始化上纠结。3. Matlab代码实现从搭框架到跑通全流程3.1 工程文件结构规划这一节我直接给出建议的文件组织方式方便复现和维护multiUAV_TCMC/ main.m // 主程序入口 pwLCM.m // PWLCM混沌序列生成 TCMC_main.m // 部落竞争与成员合作算法主体 fitness.m // 适应度函数多机协同 collisionCheck.m // 机间碰撞检测 validatePath.m // 单机路径约束验证 plotResult.m // 三维航迹可视化 data/ terrain.mat // 地形高程数据 threats.mat // 威胁源数据 output/ // 保存结果文件拆分的原则是尽量函数化。我之前犯过的错误是全部堆在main里导致后面想换适应度函数或者换初始化方式都要大改调试起来非常痛苦。建议从一开始就把混沌生成、适应度计算、碰撞检测、主迭代循环各自独立成函数方便单步调试和性能分析。3.2 PWLCM混沌初始化代码实现下面给出一个可直接用的Matlab混沌序列生成函数function seq pwLCM(seed, p, N) % seed: 初始值范围 (0,1) % p: 控制参数范围 (0,0.5) % N: 序列长度 seq zeros(N,1); seq(1) max(min(seed,1-eps), eps); for i 1:N-1 x seq(i); if x p seq(i1) x / p; elseif x 0.5 seq(i1) (1 - x) / (1 - p); elseif x 1 - p seq(i1) (1 - x) / p; else seq(i1) (x - 1 p) / p; end end end有了这个函数初始化种群时就是循环对每个决策变量生成一条混沌序列然后线性映射到对应的上下界function pop initPopByPWLCM(popSize, dim, lb, ub, p) % popSize: 种群个体数量 % dim: 决策变量维度 % lb, ub: 维度下界和上界向量 pop zeros(popSize, dim); for i 1:popSize for j 1:dim seq pwLCM(mod(i*j*0.618, 1), p, 1); pop(i,j) lb(j) seq(end) * (ub(j) - lb(j)); end end end注意这里每个维度都用不同的初值避免所有维度生成完全相同的混沌序列。执行时可以看到初始种群在高维空间里散布得比较均匀这是普通rand做不到的。3.3 适应度函数权重设计的核心细节适应度函数是整个算法的灵魂。我最终采用的代价函数形式如下Cost w1 * L_cost w2 * T_cost w3 * H_cost w4 * S_cost w5 * C_penalty各分项含义L_cost所有无人机的航迹总长度之和归一化到[0,1]区间。T_cost航迹点与威胁源的接近程度距离越近代价越高。H_cost航迹高度与期望高度的偏差过高过低都惩罚。S_cost航迹点之间的转角偏差惩罚急转弯和大爬升角。C_penalty无人机两两之间的最小距离低于安全阈值的惩罚项。权重设置我这里给一组实测可用的初始值w10.4w20.3w30.1w40.1w50.1。但这不是定死的不同场景需要调。调权重有一条经验先用无约束的纯航迹长度跑一遍记录长度量级再调整其他权重的量级平衡不要凭感觉设。威胁代价的计算公式我比较推荐指数形式它能放大近距离威胁的差异性function tCost threatCost(waypoints, threats) % waypoints: 3xN 航迹点矩阵 % threats: 4xM 威胁源矩阵每列为 [x; y; z; radius] [~, n] size(waypoints); [~, m] size(threats); tCost 0; for k 1:m dx waypoints(1,:) - threats(1,k); dy waypoints(2,:) - threats(2,k); dz waypoints(3,:) - threats(3,k); d sqrt(dx.^2 dy.^2 dz.^2); r threats(4,k); tCost tCost sum(exp( max(0, r - d) ) - 1); end % 除以航迹点数归一化 tCost tCost / n; end3.4 主迭代成员合作与部落竞争的交替实现TCMC主循环核心逻辑我整理为以下步骤。为了方便读者理解我用伪代码逐段拆解% 1. 参数设置 nTribes 4; % 部落数量 tribeSize 12; % 每个部落成员数 maxIter 300; w 0.7; c1 1.5; c2 1.5; % PSO式速度更新参数 % 2. 混沌初始化 pop initPopByPWLCM(nTribes * tribeSize, dim, lb, ub, 0.3); % 将 pop 划分为 nTribes 个部落矩阵 % 3. 计算初始适应度选出每个部落的酋长 for iter 1:maxIter for t 1:nTribes % ---- 成员合作阶段 ---- for i 1:tribeSize % 每个成员结合自身历史最优pbest和本部落酋长chief更新速度 r1 rand(dim,1); r2 rand(dim,1); v w * v c1 * r1 .* (pbest - pop_t(:,i)) c2 * r2 .* (chief - pop_t(:,i)); pop_t(:,i) pop_t(:,i) v; pop_t(:,i) boundHandle(pop_t(:,i), lb, ub); % 边界处理 end % 适应度更新、pbest更新、酋长更新 end % ---- 部落竞争阶段 ---- % 对4个部落酋长适应度排序最弱部落向最强部落方向重组 [sortedF, idx] sortFitnessOfTribes(); for t 1:length(weekTribes) % 将较弱部落的部分成员替换为最强酋长邻域内随机点 newMember bestChief 0.5 * randn(dim,1) .* (ub-lb) * 0.1; weakestTribeMember(randi(tribeSize)) newMember; end end这个实现属于“PSO式成员更新 重组式部落竞争”的变体。我在这套实现里保留了PSO良好的开发能力又通过部落竞争加入了额外的探索压力。实际运行中可以看到各部落的酋长适应度曲线会呈现“跟随-超越-重组”的波浪式下降收敛过程比单一PSO更有节奏感。3.5 碰撞检测与三维可视化机间碰撞检测有个提高效率的小技巧不用每轮都检查所有航迹点组合而是先判断两架无人机航迹点之间是否有任何一处的距离小于安全阈值的1.5倍如果完全没有就直接跳过详细计算。这里给出核心部分function pen collisionPenalty(allPaths, safeDist) % allPaths: numUAV x 3 x numWaypoints 格式 [numUAV, ~, numWay] size(allPaths); minDist inf; for i 1:numUAV for j i1:numUAV d squeeze(sqrt(sum((allPaths(i,:,:) - allPaths(j,:,:)).^2, 2))); minDist min(minDist, min(d)); end end pen max(0, safeDist - minDist); end可视化方面我习惯用Matlab的plot3画出每架无人机的航迹用不同的颜色区分同时在地形等高线图上叠加显示威胁源位置。这一步虽然是最后才做但对分析算法行为和调参帮助极大——特别是看航迹有没有明显扭曲、有没有贴着威胁边界飞行。4. 实验效果与调参经验4.1 测试场景与评价指标我在模拟任务场景中设置3架无人机搜索区域100 x 100 x 100起点分别为三处不同位置目标点集中在任务区中心偏南的位置飞行高度限界20到80。威胁源4个安全间隔5。评价指标用三条最终适应度均值、成功率约束全部满足的比例、平均收敛代数。每个实验参数下独立跑10次取平均。4.2 对比数据混沌初始化 vs 随机初始化我做了个对比实验同一个TCMC框架下只用初始化方式不同其他参数完全一致。结果是初始化方式最终适应度均值约束满足成功率平均收敛代数rand随机初始化0.81262%164PWLCM混沌初始化0.68491%118可以清楚看到混沌初始化不仅把最终代价降下来了成功率也显著上升。原因是混沌序列让初始航迹点分布更均匀算法不会在开局就把几条“病态航迹”比如全部挤在搜索空间一角留到后期。4.3 部落数量和混沌参数怎么选部落数量太少比如2个竞争机制形同虚设算法退化成双种群PSO部落数量太多比如8个每个部落成员只剩几个局部搜索能力不足整体收敛变慢。我的经验是3到5个部落每个部落10到20人对于90维以下的问题足够。混沌参数p的选取我用0.2到0.4之间的值都测试过。p偏小时混沌序列遍历均匀但动态较差p偏大时序列活跃但偶尔会进入窄区间综合下来0.3最好。另外种子值不要固定成一个多次运行的种子要变化否则混沌序列的遍历性优势会被削弱。5. 实操中踩过的坑与排查方法5.1 种群多样性快速丢失迭代后期全部扎堆表现运行到100代左右所有部落的酋长位置几乎重合适应度不再下降。排查方法先在每次迭代输出所有酋长的平均欧氏距离。如果这个值低于搜索空间对角线的百分之五说明多样性已经危险了。解决方案有两个。一是调高部落竞争中的重组概率让弱部落更频繁地生成新个体二是给速度更新中的w加一个线性递减策略从0.9降到0.4让前期充分探索、后期才强化开发。我建议两个方案配合使用。5.2 机间安全距离总是被违反表现最终适应度看着不错但可视化一看某两架无人机的航迹点距离小于安全阈值。这多半是权重失衡导致的。我踩过的坑是C_penalty权重设得太低。在90维空间里两架无人机的航迹点要天然保持距离其实很难如果惩罚项权重不够算法会倾向于牺牲约束来优化总航迹长度。调试时可以把C_penalty单独拎出来先置零观察无碰撞约束下算法算出来的最小机间距离是多少再反过来定惩罚权重。5.3 航迹穿插威胁源边缘看着合理其实很危险做路径规划有一种“表面成功”的陷阱适应度里威胁代价是指数形式算法为了最小化它倾向于把航迹点推到威胁半径的临界位置而不是真正绕开。这会导致航迹贴着威胁源擦边而过一点安全裕量都没有。解决办法是在威胁代价计算里增加一个安全裕量系数把威胁半径乘以1.2再参与计算。这个处理虽然让适应度函数略微失真但产出的航迹实际更可用。5.4 Matlab运行速度慢几百代迭代太煎熬多维问题下Matlab循环嵌套是性能杀手。我的优化手段是尽量向量化适应度计算中的距离矩阵以及把不依赖迭代的威胁源预计算。还有一个物理层技巧在碰撞检测之前先做一次粗筛只有两架无人机的路径包围盒有重叠时才进入精细检查。实测下来单次迭代耗时能减少大约60%。最后说两句我自己的体会这套项目做下来我最大的感受是算法创新固然重要但真正决定成败的是“问题转算法”的设计质量。PWLCM混沌映射和部落竞争机制本身都不是多么惊人的理论可一旦贴合了多无人机协同路径规划的高维、多约束特性效果提升非常明显。你在自己复现的时候如果一开始结果不理想别急着怀疑算法先回去看看适应度函数和约束建模是不是出了问题。用混沌初始化改善全局探索靠部落竞争维持多样性把工程细节和调参经验沉淀下来这套流程在类似的高维连续优化问题上都有很强的迁移价值。