资讯动态

固定翼无人机MATLAB仿真:圆形盘旋编队与集群中心估计

发布时间:2026/9/15 21:12:14 来源:尧图企业网站定制
简介这是一份面向固定翼无人机控制学习者的 MATLAB 代码包聚焦多无人机协同路径规划、圆弧轨迹计算与集群区域覆盖等场景既可用于课程实验验证也适合初学者对照核心函数理解底层控制逻辑。压缩包共 54 个文件以 m 脚本为主辅以 zbak 备份文件、asv 自动保存文件及说明 txt核心 MAIN.m 与 calculate_point_line_cir.m、update_uav_set.m、cluster_area_overlap_descent.m 等函数清晰划分了初始化、轨迹生成、集群更新与重叠面积计算等模块整体仅 48KB轻量便携。代码来自网络分享包含不同半径调整与初始版本等变体便于对比参数变化对控制效果的影响并附有说明文档。已有 33 人学习下载适合机器人、飞行器控制方向的本科生或研究者快速搭建仿真基础、开展二次开发。1. 固定翼无人机MATLAB仿真把绕心盘旋做成工程闭环固定翼无人机不像多旋翼那样可以原地悬停想让它持续观察某个地面目标最省操纵量的方式就是绕着一个圆飞。这个从文件夹名MatlabInitVersionRunUAV3Radius200、RunUAV3RadiusChange、RunUAV4RadiusChange里能直接看出来同一套仿真被演进成了固定半径 200 米、变半径、集群中心在线估计三个版本。整个代码包的核心解决的是三件事——在圆上实时取跟踪点、根据机群分布估计动态中心、以及让盘旋半径随集群状态自适应变化。这套代码的典型适用场景是巡飞弹编队、中继通信节点滞空、以及单架固定翼对地面移动目标的持续覆盖。如果你正在做多固定翼协同盘旋仿真或者刚接触无人机集群路径规划想找一个能在 MATLAB 里直接跑的基线版本这个包值得拆开来读。MAIN.m是入口其余全是围绕圆形编队拆出来的离散功能函数。需要提醒的是它是网络分享的学习资源不附带商业授权拿去跑实验没问题直接用于产品交付需要自己重写底层与合规性检查。2. 圆形轨道生成与航迹几何calculateTargetPointOnCircle、calculate_point_line_cir与弧长计算固定翼盘旋控制不能只给一个圆心和半径就完事控制回路里需要的是一条在当前状态下可以追踪的参考轨迹。这个工程里跟轨迹几何强相关的三个函数是calculateTargetPointOnCircle.m、calculate_point_line_cir.m和calculateArcLength.m它们分别解决参考点怎么取、几何关系怎么判定、飞行距离怎么算的问题。2.1 在圆上取跟踪点的几何思路calculateTargetPointOnCircle.m实现的是“圆上目标点生成”。最容易想到的做法是把无人机当前位置投影到圆周上但这样会导致投影点随着飞机摆动而抖动舵面会一直来回打。工程上更稳的方式是前瞻法沿当前航向方向外推一定距离再把这个前瞻点映射到圆周上。简单实现可以写成function pt calculateTargetPointOnCircle(center, radius, courseAngle, lookahead) % center : 圆心坐标 [x, y] % radius : 盘旋半径 % courseAngle: 当前航向角单位弧度 % lookahead : 前瞻距离一般取 0.3~0.6 倍转弯半径 current center radius * [cos(courseAngle), sin(courseAngle)]; dtheta lookahead / radius; % 前瞻距离折算成圆心角增量 pt center radius * [cos(courseAngle dtheta), sin(courseAngle dtheta)]; enddtheta lookahead / radius这一行的物理含义是固定翼在一个曲率半径为radius的圆弧上飞行时每前进 1 米航向角变化1/radius弧度。这个线性近似在小角度下精度足够当前瞻距离超过半圈时需要做角度归一化否则会绕到反方向去。这个文件在三个版本里都存在说明它的核心地位。实际仿真中MAIN.m每个控制周期会先调用它拿到圆上目标点再交给下一层的航向跟踪控制器去逼近。这样可以和底层无人机动力学解耦想换固定翼气动模型时不需要动参考点生成逻辑。2.2 点、线、圆投影的底层判定函数calculate_point_line_cir.m是一个几何判定工具函数。从名字和工程惯例推断它实现的是“点到直线距离”、“直线与圆的交点”以及“点是否在圆弧范围内”这三类判定中的一种或多种。在多机协同盘旋里最常见的需求是判断无人机是否越过了任务扇区边界或者计算当前点到某条期望进入线段的侧偏距。标准做法是向量投影function [dist, t] pointLineProjection(P, A, B) % P 为待判定点A、B 为线段端点 AB B - A; AP P - A; t dot(AP, AB) / dot(AB, AB); t max(0, min(1, t)); % 钳位到线段范围 closest A t * AB; dist norm(P - closest); endt的含义是投影点在线段上的归一化位置t0在 A 点t1在 B 点。钳位操作很重要否则点在延长线之外时会把距离算小。这个函数在集群更新前后检测“新编队构型是否与禁飞线冲突”时可以直接复用。2.3 弧长计算的参数陷阱calculateArcLength.m在三个版本中反复出现说明它服务于航程预估、时间同步和剩余油量推算。最简实现是半径乘以圆心角function L calculateArcLength(radius, theta) % radius: 圆弧半径 % theta : 圆心角单位弧度 theta mod(theta, 2*pi); % 归约到 0~2pi if theta 0 theta theta 2*pi; end L radius * theta; end这个函数有两个容易被忽略的参数问题。第一theta必须显式归约不然无人机转了 3 圈后航程会算成3*2πr而不是当前的剩余弧长。第二mod(theta, 2*pi)在 MATLAB 里对负数的行为和多数 C 语言实现一致结果为非负所以第二行的if theta 0看似是双保险实际上只在手写循环累加角度时才会触发。参数推荐值说明radius200固定版本小于最小转弯半径会进入失稳区lookahead0.3R ~ 0.6R太大导致切弧太小导致抖动theta必须归约到[0, 2π)否则航程和时间预估会漂移3. 集群中心在线估计与成员更新cluster_area_overlap_descent与update_uav_set固定翼集群在滞空监视时地面站或目标可能是移动的所以圆心不能是一开始定的那个点。这个工程给出了一个不太常见的解法用多个无人机的感知覆盖圆的重叠面积下降法来反向估计真正的集群中心。同时用update_uav_set.m处理编队成员的动态变化。3.1 为什么不能直接取机群几何中心平均所有无人机的位置作为圆心看起来简单但问题在于如果一架无人机因为侧风飘到编队边缘几何中心会瞬间被拉偏而真正应该跟踪的目标可能根本没动。更合理的假设是每个无人机携带一个”感知范围圆“这些圆在目标位置附近重叠最多。于是中心估计变成一个最优化问题找一点p使得以p为圆心、某固定半径 R 的圆与所有无人机感知范围的交叠面积之和最大。cluster_area_overlap_descent.m的命名正好对应这个思路用梯度下降迭代逼近。3.2 圆重叠面积的下降法估计两个圆相交的重叠面积有解析表达不必做蒙特卡洛function overlap circlesOverlapArea(d, r1, r2) if d r1 r2 overlap 0; return; end if d abs(r1 - r2) overlap pi * min(r1, r2)^2; return; end % 标准圆交叠面积公式 part1 r1^2 * acos((d^2 r1^2 - r2^2) / (2*d*r1)); part2 r2^2 * acos((d^2 r2^2 - r1^2) / (2*d*r2)); part3 0.5 * sqrt((-dr1r2)*(dr1-r2)*(d-r1r2)*(dr1r2)); overlap part1 part2 - part3; end下降法迭代时把每个无人机位置centers(i,:)与候选中心p的距离代入上面的公式求所有两两交叠面积之和的负梯度沿梯度反方向更新p。这里我通常做两层循环而不是直接向量化原因是要对每对圆判断d r1r2的提前退出矩阵化写法在无人机数量少于 10 架时反而更慢可读性也更差。注意地面站位置和速度是独立的update_mgus_pos_vel.m在推进它维护的是运动学状态位置、速度、加速度而重叠面积估出来的是目标中心两者在judge_whether_or_not_update_center.m里做融合判决。3.3judge_whether_or_not_update_center的触发条件中心更新不能每一帧都做否则圆心会在噪声下来回振荡。合理的工程做法是设置滞后触发只有当新估计位置与当前圆心距离超过某个阈值例如 25 米并且连续 M5 帧都满足这个条件时才把圆心切换过去。function flag judge_whether_or_not_update_center(estCenter, curCenter, threshold, persistCnt) % threshold : 距离触发阈值 % persistCnt: 连续超阈值帧数 d norm(estCenter - curCenter); if d threshold persistCnt persistCnt 1; else persistCnt 0; end flag (persistCnt 5); end引入persistCnt是为了排除单帧野值。如果取消滞后判据圆心会在编队内部噪声和地面站移动的双重作用下出现高频抖动进而使第 2 章的calculateTargetPointOnCircle输出的参考点来回跳变。3.4update_uav_set的编队重组策略update_uav_set.m处理的是编队中无人机数量变化的情况某架飞机燃料不足脱离编队、通信链路中断、或者新无人机加入。它的基本执行顺序是检查每架无人机与当前圆心的距离是否超过允许半径上限的 1.5 倍。超限且持续 10 个仿真步则将该无人机从编队集合中移除。移除后重新编号保证剩余无人机的索引连续并同步更新各自的目标相位角。这个函数带一个.zbak备份文件说明作者在调试过程中大概率改过。一个常见的坑是删除编队成员时没有同步更新圆周上的相位角分配导致剩余的飞机全部挤向同一个圆弧段。我会在更新后加一步强制相位重排N size(uavSet, 1); phase (0:N-1) * (2*pi / N); % 按新编队数量均匀分配相位 uavSet(:, 3) phase; % 第三列存目标相位角如果缺少这一步几架飞机会在圆上追逐同一个目标点互相绕飞仿真画面表现为两架飞机的航迹反复交叉。4. 动态半径调整与主循环集成从calculate_radius_uavs到MAIN.m第三个文件夹RunUAV4RadiusChange里有calculate_radius_uavs.m和findFarthestPoints.m说明作者把半径从固定值改成了动态计算。变半径的核心约束是固定翼的最小转弯半径半径太小会导致失速或侧滑半径太大会失去对地面目标的监视精度。4.1 最小转弯半径约束固定翼的最小转弯半径由空速和最大坡度角决定function rMin calcMinTurnRadius(velocity, bankAngleDeg) % velocity : 飞行速度 m/s % bankAngleDeg : 最大允许坡度角单位度 g 9.8; bank deg2rad(bankAngleDeg); rMin velocity^2 / (g * tan(bank)); end一架速度 35 m/s、最大坡度 30° 的固定翼最小转弯半径约为 216 米。这意味着Radius200版本里默认的 200 米半径是贴着物理极限跑的实际飞行中大概率会掉高度。换成动态半径版本之后系统会根据当前速度和坡度实时抬高半径下限。4.2 最远点驱动的半径更新findFarthestPoints.m的逻辑是找出机群中距离当前圆心最远的那架无人机然后calculate_radius_uavs.m以它为基准计算新的盘旋半径。这样每个无人机都能保持在感知范围内同时避免让编队为了少数掉队飞机无限扩大。function newR calculate_radius_uavs(uavSet, center, margin) % uavSet: 无人机状态矩阵 % center: 当前估计中心 % margin: 冗余余量建议取最小转弯半径的 0.1~0.2 dist vecnorm(uavSet(:,1:2) - center, 2, 2); rMin calcMinTurnRadius(35, 30); newR max(max(dist), rMin) * (1 margin); end这个函数的巧妙之处在于它同时满足两个约束max(dist)兜住编队完整性的下限rMin兜住飞机动力学的下限。两个约束取大值再加冗余就不会出现为了照顾掉队飞机而让所有飞机进入大半径、低覆盖率的状态。4.3MAIN.m的执行顺序主程序是典型的离散时间步进仿真循环。从代码文件命名反推一次完整循环的顺序是for k 1 : totalSteps % 1. 用当前圆心生成每架无人机的圆上参考点 for i 1 : nUAV targetPts(i,:) calculateTargetPointOnCircle(center, radius, uavSet(i,4), lookahead); end % 2. 调用动力学或几何更新推进无人机位置 update_uav_set(uavSet, targetPts, dt); % 3. 推进地面站运动学 update_mgus_pos_vel(mgus, dt); % 4. 判断是否需要更新圆心需要则用重叠下降法重估 if judge_whether_or_not_update_center(estCenter, center, 25, 5) center cluster_area_overlap_descent(uavSet(:,1:2), sensingRadius); end % 5. 动态半径版本每 N 步重算一次半径 if mod(k, radiusUpdateInterval) 0 radius calculate_radius_uavs(uavSet, center, 0.15); end end模块函数调用频率参考点生成calculateTargetPointOnCircle每步几何判定calculate_point_line_cir每步中心重估cluster_area_overlap_descent满足触发条件时半径更新calculate_radius_uavs每 N50 步编队维护update_uav_set每步版本迭代信息藏在备份文件里calculate_radius_uavs.m.zbak和.asv并存说明作者改过多次自动保存文件且有一版是废弃逻辑。Radius200是定半径排查版RadiusChange有两个分支RunUAV4比RunUAV3多了findFarthestPoints.m变化在于从“均匀覆盖”转向了“最远点兜底”。5. 用备份文件恢复代码、验证圆弧收敛与避开常见运行坑这一类网传代码包最常见的致命伤不是算法不好而是拿到手后在当前 MATLAB 版本上跑不通。这一部分给出三个最实用的收尾技巧。5.1 从.asv和.zbak恢复误改文件.asv是 MATLAB 编辑器自动保存的版本.zbak是作者手动备份的版本。如果你修改后无法运行先用文件对比恢复cp calculate_radius_uavs.m.zbak calculate_radius_uavs.m也可以用 MATLAB 内置比较工具visdiff(calculate_radius_uavs.m.zbak, calculate_radius_uavs.m)如果.zbak版本能跑而当前版不能差异通常集中在函数签名或返回值个数上visdiff会把变量名变更情况直接标出来。5.2 验证弧长计算与半径收敛写一段断言代码确保圆弧计算没有出现跳变r 200; theta [0, pi/2, pi, 2*pi0.1, -pi/2]; L zeros(size(theta)); for i 1 : length(theta) L(i) calculateArcLength(r, theta(i)); end expected [0, 100*pi, 200*pi, 0.1*200, 300*pi]; assert(norm(L - expected) 1e-9, 弧长计算异常);对半径收敛性验证输出历史曲线观察radius是否稳定在一个物理可飞的值域内是否出现高频振荡。如果半径每个更新周期都跳变超过 10%优先检查findFarthestPoints里是否把掉队飞机纳入了最远点计算。5.3 常见运行问题定位提示“未定义函数”确认当前文件夹在 MATLAB 路径中addpath(genpath(pwd))可临时解决。报索引越界update_uav_set删除了编队成员但外部循环仍按原数量迭代检查size(uavSet,1)是否被循环变量硬编码。仿真轨迹呈现“8”字交叉两个无人机的初始相位角相同按 3.4 节强制相位重排。老版本.m代码在 R2023b 以上打开出现语法警告.*与*混用导致隐式扩展问题用visdiff逐个核对矩阵维度。这套代码的学习价值在于它把一个完整的固定翼集群盘旋问题拆成了可独立测试的单元调通MAIN.m之后再按 2 到 4 的顺序替换自己的动力学模型就能从几何参考生成平滑迁移到飞行控制与集群协同的联合仿真。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价