固定翼与四旋翼整合自主飞行:Matlab建模、控制分配与航线跟踪实战
简介这份资源面向计算机、电子信息工程、数学等专业的大学生及无人机控制方向研究者提供固定翼与四旋翼整合的垂直起降飞行器VTOL自主飞行设计与控制Matlab代码可用于课程设计、期末大作业或毕业设计帮助理解复杂系统的建模、仿真与控制策略。压缩包共22个文件约11.74MB以9个m脚本为核心配合7张png与2个gif展示状态轨迹和输入响应另有pdf说明文档、md与txt使用说明及p文件覆盖动力学建模、NLMPC控制、轨迹动画等模块。代码采用参数化编程参数可方便更改思路清晰且注释详尽并附赠案例数据可直接运行省去从零搜集数据与编写代码的时间。目前已有131人学习下载适合希望快速上手VTOL飞行器仿真与控制的读者参考。1. 垂直起降飞行器的设计与控制固定翼和四旋翼整合自主飞行到底难在哪固定翼和四旋翼整合自主飞行说白了就是让一架既能像多旋翼一样垂直起降悬停、又能像固定翼一样巡航省电的飞行器在 Matlab 里跑通从建模、控制分配到自主航线跟踪的完整链路。这个方向最近被反复提起是因为纯四旋翼续航短、纯固定翼起降场地要求高而整合方案能同时吃掉两边的好处。它适合做毕设、课题预研、飞控算法验证的工程师也适合手里有 Matlab 但不知道怎么把气动、电机、控制律串成闭环的人。标题里那个 .rar 包本质是一套可复现的仿真工程骨架不是飞控固件别指望直接烧进板子。真正值钱的是它背后的建模思路和控制分配逻辑把这两块吃透你换任何机型都能自己搭。2. 从构型到状态量整合飞行器建模的取舍2.1 三种主流整合构型与选型理由做整合自主飞行第一步不是写代码是决定你的飞行器长什么样。常见做法有三种尾座式、倾转旋翼式、升力巡航分离式。尾座式整机垂直起降时靠机身立起来平飞时整个机身转成水平结构最轻但过渡段控制最难俯仰角要扫过 90 度气动模型在过渡区高度非线性。倾转旋翼式是旋翼短舱相对机翼转动过渡平顺控制分配可以做得很细代价是机构复杂、重量上去。升力巡航分离式就是固定翼上额外挂一套多旋翼动力两套系统各干各的控制上最省心但死重最大、巡航效率被拖累。我一般建议预研阶段先做升力巡航分离式因为它的动力学可以近似解耦垂直段用多旋翼模型巡航段用固定翼模型过渡段用权重混合。这样你在 Matlab 里能先把两条链路各自调通再处理混合逻辑翻车概率低很多。等控制律稳了再往倾转或尾座迁移迁移时主要改的是力和力矩的合成矩阵控制框架不用推倒重来。选型时还要看你的执行机构数量。四旋翼加固定翼舵面典型配置是 4 个旋翼电机加 2 到 3 个舵面总共 6 到 7 个控制输入而飞行器有 6 个自由度属于过驱动。过驱动的好处是控制分配有冗余坏处是分配矩阵可能奇异尤其在某些姿态下。Matlab 里做分配时一定要检查分配矩阵的条件数别等仿真发散了才回头找。2.2 六自由度方程与状态量定义整合飞行器的刚体动力学核心还是牛顿-欧拉方程但坐标系定义要提前统一否则后面全是符号错误。我习惯用地面坐标系 NED 和机体坐标系前右下状态量取 12 个位置三轴、速度三轴、姿态欧拉角三个、机体角速度三个。气动力和力矩在机体坐标系下算重力在地面系下算最后统一到机体系做积分。下面是一段最小可跑的六自由度积分骨架用 Matlab 写状态量顺序是 [pn pe pd u v w phi theta psi p q r]。function dstate vtail_dynamics(state, Fb, Mb, m, I) % state: 12x1, [pn pe pd u v w phi theta psi p q r] % Fb, Mb: 机体坐标系下的合外力(N)与合外力矩(N*m) % m: 质量(kg), I: 3x3 惯量矩阵 pn state(1); pe state(2); pd state(3); u state(4); v state(5); w state(6); phi state(7); theta state(8); psi state(9); p state(10); q state(11); r state(12); % 欧拉角转旋转矩阵机体到地面 R [cos(theta)*cos(psi), sin(phi)*sin(theta)*cos(psi)-cos(phi)*sin(psi), cos(phi)*sin(theta)*cos(psi)sin(phi)*sin(psi); cos(theta)*sin(psi), sin(phi)*sin(theta)*sin(psi)cos(phi)*cos(psi), cos(phi)*sin(theta)*sin(psi)-sin(phi)*cos(psi); -sin(theta), sin(phi)*cos(theta), cos(phi)*cos(theta)]; % 位置导数机体速度转到地面系 dpos R * [u; v; w]; % 速度导数机体系下牛顿方程含哥氏项 dvel Fb/m - cross([p; q; r], [u; v; w]); % 姿态导数欧拉角运动学 datt [1, sin(phi)*tan(theta), cos(phi)*tan(theta); 0, cos(phi), -sin(phi); 0, sin(phi)/cos(theta), cos(phi)/cos(theta)] * [p; q; r]; % 角速度导数欧拉方程 dw I \ (Mb - cross([p; q; r], I*[p; q; r])); dstate [dpos; dvel; datt; dw]; end这段代码里有两个容易忽略的点。第一姿态运动学矩阵在 theta 接近正负 90 度时 tan 会爆掉尾座式过渡段正好经过这个区域所以要么用四元数要么在过渡段做角度限幅和切换。第二哥氏项 cross([p;q;r],[u;v;w]) 不能省尤其在大角速度机动时省了会导致能量不守恒、仿真漂移。参数上m 和 I 必须和你的气动模型、电机推力模型一致I 建议用 CAD 导出或实测摆锤法别随手填。2.3 气动与推力模型的拼接方式固定翼部分的气动系数常见做法是用升力线斜率加诱导阻力或者直接查表。Matlab 里可以用 griddedInterpolant 做二维查表输入迎角和马赫数输出 CL、CD、Cm。四旋翼部分用桨叶动量理论或螺旋桨实验曲线推力近似正比于转速平方反扭矩正比于转速平方乘以一个系数。拼接的关键是过渡段的权重函数。我一般用空速做调度变量空速低于某个阈值时全用多旋翼模型高于另一个阈值时全用固定翼模型中间做平滑插值。权重函数用 smoothstep 或余弦过渡都行但过渡区间不能太窄否则控制量会跳变。下面是一个权重混合的写法。function [Fb, Mb] mix_aero(Va, alpha, beta, rpm, defl, params) % Va: 空速(m/s), alpha/beta: 迎角侧滑角(rad) % rpm: 4x1 旋翼转速, defl: 舵面偏角 V1 params.V_trans_low; % 例如 8 m/s V2 params.V_trans_high; % 例如 14 m/s s min(max((Va - V1)/(V2 - V1), 0), 1); w 0.5 - 0.5*cos(pi*s); % 平滑权重0 偏多旋翼1 偏固定翼 [F_mr, M_mr] multirotor_force(rpm, params); [F_fw, M_fw] fixedwing_force(Va, alpha, beta, defl, params); Fb (1-w)*F_mr w*F_fw; Mb (1-w)*M_mr w*M_fw; endV_trans_low 和 V_trans_high 这两个参数是玄学重灾区。设得太低固定翼还没建立足够升力就接管飞机会掉高度设得太高多旋翼在高速下阻力剧增能耗爆炸。我的血泪经验是先用配平计算估一个失速速度把 V_trans_low 设在 1.2 倍失速速度附近V_trans_high 设在 1.5 倍左右然后仿真里看过渡段的高度损失超过 5 米就往上调。3. 控制分配与自主航线跟踪的落地实现3.1 串级 PID 加控制分配的框架整合飞行器的控制主流还是串级结构外环位置控制出姿态指令和总推力内环姿态控制出力矩指令最后控制分配把总推力和力矩映射到各个执行机构。这样分层的好处是每层可以单独调外环慢、内环快调试时先锁内环。外环位置控制水平方向用 PID 出期望加速度再反解期望姿态角高度方向用 PID 出总推力。反解姿态时有个小角度近似phi_des 约等于 ay/gtheta_des 约等于 -ax/g大机动时误差会大可以加前馈或改用非线性几何控制。内环姿态用四元数或旋转矩阵做误差比欧拉角串级稳尤其在大角度时。控制分配我一般用伪逆加权重。分配矩阵 B 把执行机构向量映射到 [T, Mx, My, Mz]执行机构有上下限所以伪逆解出来还要做饱和处理和重分配。下面是一个带饱和的分配示例。function u control_allocate(wrench_des, B, u_min, u_max, W) % wrench_des: 4x1, [T; Mx; My; Mz] % B: 4xN 分配矩阵, W: NxN 权重矩阵 % u_min/u_max: Nx1 执行机构上下限 N size(B, 2); % 加权伪逆 u W * B * ((B * W * B) \ wrench_des); % 饱和 u min(max(u, u_min), u_max); % 饱和后残差再分配一次简单迭代 for k 1:3 res wrench_des - B * u; if norm(res) 1e-6, break; end du W * B * ((B * W * B) \ res); u min(max(u du, u_min), u_max); end end权重矩阵 W 用来告诉分配器哪些执行机构更可信。比如旋翼响应快但效率低舵面效率高但响应慢过渡段可以动态调 W让低速时旋翼权重高、高速时舵面权重高。B 矩阵的条件数要盯着超过 1e4 就说明接近奇异得换构型或加约束。3.2 航线跟踪从航点到制导律自主飞行的航线跟踪常见做法是 L1 制导或非线性制导。L1 制导用一个前视距离 L1在航段上找参考点算出侧向加速度指令。L1 太小会震荡太大切弯会抄近道。我一般取 L1 为 2 到 3 倍翼展过渡段适当加大。航点切换逻辑要处理到达判定和掉头。到达半径别设太小固定翼掉头需要空间半径小于 3 倍转弯半径就会画圈。下面是一个简化的 L1 侧向制导。function a_cmd l1_guidance(pos, wp_prev, wp_next, Va, L1) % pos: 当前位置, wp_prev/wp_next: 当前航段两端 seg wp_next(1:2) - wp_prev(1:2); seg seg / norm(seg); rel pos(1:2) - wp_prev(1:2); along dot(rel, seg); ref wp_prev(1:2) along * seg; d pos(1:2) - ref; dist norm(d); if dist 1e-3 a_cmd 0; return; end % 侧向加速度方向垂直于航段 eta atan2(d(2), d(1)) - atan2(seg(2), seg(1)); eta wrapToPi(eta); a_cmd 2 * Va^2 / L1 * sin(eta); endL1 和到达半径这两个参数建议在仿真里扫一遍。固定翼部分用 Va 做调度多旋翼段可以直接用位置 PID因为悬停时没有空速概念。过渡段制导要降速否则 L1 算出来的加速度指令会超过姿态限制。3.3 仿真步长、求解器与实时性Matlab 里跑六自由度ode45 是默认选择但整合飞行器有过驱动切换和饱和ode45 在切换点会缩步长仿真时间可能很长。我一般用 ode4 固定步长步长 0.002 到 0.005 秒配合零阶保持器模拟飞控周期。飞控周期典型 400 Hz 到 1 kHz仿真步长要小于飞控周期的一半。实时性方面如果你要做硬件在环控制律里的查表和矩阵运算要预分配别在循环里动态扩容。Matlab 的 persistent 变量或对象属性可以缓存插值对象。另外atan2、wrapToPi 这些函数在代码生成时要注意支持包别到烧录阶段才发现不能用。4. 避坑与排查整合飞行仿真里最容易翻车的五件事4.1 过渡段高度掉得厉害现象从悬停切到平飞高度掉 10 米以上甚至触地。原因通常是权重函数切换太快固定翼升力还没建立多旋翼推力已经按巡航配平降下来了。解决把 V_trans_low 往上调过渡区间拉长同时在过渡段给总推力加一个前馈补偿补偿量按空速平方乘以一个系数估。4.2 控制分配解出饱和后姿态发散现象某个执行机构打满姿态误差反而变大。原因是伪逆解在饱和后没有正确重分配残差被忽略。解决用带残差迭代的分配或者改用二次规划把饱和作为约束。权重矩阵 W 也要检查别让某个执行机构权重过大导致其他机构不动。4.3 欧拉角在 90 度附近数值爆炸现象尾座式过渡时 theta 接近 90 度姿态导数出现 Inf 或 NaN。原因是欧拉角运动学在奇点无定义。解决内环改用四元数外环需要欧拉角时再做转换转换时做限幅。或者用旋转矩阵直接做误差避免角度提取。4.4 气动查表外插导致力突变现象迎角超出表格范围插值函数外插出离谱的 CL。原因是 griddedInterpolant 默认线性外插。解决把查表范围设得比预期迎角大或者在外插时做限幅超出范围就取边界值。仿真里加一个迎角监视超限就报警。4.5 仿真跑得动但代码生成失败现象Simulink 或 Matlab 脚本仿真正常生成 C 代码报错。原因是用了不支持的函数比如某些匿名函数、动态字段名、eval。解决控制律里只用代码生成支持的子集查表用 interp2 或预生成断点别用 griddedInterpolant 的高级选项。提前用 coder.screener 扫一遍。5. 进阶技巧用配平计算反推过渡段参数配平计算是整合飞行器设计里最被低估的一步。很多人直接调 PID调不出来就怪模型其实先做配平能省一半时间。配平就是解一组非线性方程让飞行器在给定空速、给定航迹角下合力和合力矩为零求出此时的姿态角、油门和舵面偏角。Matlab 里可以用 fsolve 做配平。状态量取 [alpha, theta, rpm_hover, defl_elev, thrust_total]方程是力和力矩的残差。下面是一个配平骨架。function res trim_residual(x, Va, gamma, params) % x [alpha, theta, rpm, elev, T] alpha x(1); theta x(2); rpm x(3); elev x(4); T x(5); beta 0; phi 0; [F_fw, M_fw] fixedwing_force(Va, alpha, beta, elev, params); [F_mr, M_mr] multirotor_force(rpm*ones(4,1), params); Fb F_fw F_mr params.m * params.g * [-sin(theta); 0; cos(theta)]; Mb M_fw M_mr; % 航迹角约束速度方向与期望一致 res [Fb(1); Fb(3); Mb(2); Mb(3); Fb(2)]; end配平解出来之后把不同空速下的配平油门和舵面偏角存成表过渡段直接用这个表做前馈PID 只负责修正残差。这样过渡段的高度损失能压到 2 米以内。我现在的习惯是任何新构型先跑一遍配平扫描把空速从 0 到巡航速度扫 20 个点看配平解是否连续不连续的地方就是过渡段的危险区控制参数要重点照顾。另一个技巧是用配平结果反推权重函数。如果某个空速下多旋翼和固定翼的配平推力差异很大说明这个区间两套模型打架权重过渡要更慢。这个判断比拍脑袋设 V_trans_low 靠谱得多。最后说个验证方法把配平表代回仿真开环跑一遍看飞行器能不能沿配平航迹滑行。如果开环就发散闭环肯定调不出来。这个开环测试是我每次改模型后的固定动作能挡掉大部分低级错误。希望帮到你。本文还有配套的精品资源点击获取