简介一份面向航空控制领域研究者的固定翼容错控制与控制分配Matlab资源包聚焦多操纵面飞行器在传感器或执行机构故障下的重构与控制分配问题覆盖故障检测与诊断、容错控制器设计、基于LMI/优化算法的控制分配等关键环节。包内含99个文件主要包含Simulink模型slx、Matlab脚本m、数据文件mat以及两篇控制分配方向的文献caj/pdf另有辅助的slxc与xml配置和zip压缩包整体大小约5.84MB。已有288人学习使用。资料不仅提供x_33_model.m、QP_FXP_PI Para.m等可直接运行的代码还包含QP_FXP_2016a.slx等Simulink仿真模型可用于复现多操纵面飞行器受限控制分配与重构研究配套的郭梦旭、张栋等参考文献便于追溯理论依据。适合正在研究飞行控制重构、控制分配算法的研究生或工程师借此可直接上手仿真验证加速算法设计与对比分析。1. 固定翼容错控制与控制分配故障发生后谁在负责改舵面指令做固定翼六自由度仿真时我遇到过最经典的一次翻车右副翼模拟卡死控制器还在按原来的分配表把滚转指令发给它飞机在几秒内滚转、侧滑、掉高度一起出现。事后复盘发现问题不在控制器而在分配器——它不知道右侧副翼已经失去了响应。固定翼容错控制与控制分配解决的就是哪个舵面不行了、剩下的舵面怎么重新出力这件事。控制分配负责把一个虚拟控制力矩滚转、俯仰、偏航三个通道拆成多个舵面的偏转指令容错控制负责感知故障并调整分配的依据。用 Matlab 做这套仿真链路不需要先懂很多前沿理论把执行器故障模型、分配算法、重构逻辑串起来就能看到效果。适合正在做飞控方向的毕业生以及想给自研固定翼飞控加一层保底逻辑的工程师。2. 先搭执行器故障模型四类故障模式和效率矩阵参数化2.1 固定翼舵面与力矩通道的效率矩阵 B固定翼控制分配的第一步是拿到一张舵面偏度 → 力矩的映射表。常见做法是把六自由度非线性方程在某个配平点线性化得到状态空间里的输入矩阵习惯上记作 B。舵面向量 u 通常写成 [左副翼、右副翼、升降舵、方向舵]力矩向量 v 对应 [滚转力矩 L、俯仰力矩 M、偏航力矩 N] 三个通道。那么 v B * u。以一个常规布局固定翼为例B 的结构大致是% 示意3 个力矩通道4 个舵面单位 N*m/rad % 行滚转 L、俯仰 M、偏航 N % 列左副翼、右副翼、升降舵、方向舵 B [ 0.35 0.35 0.00 -0.05 ; 0.00 0.00 0.62 0.00 ; 0.02 -0.02 0.00 -0.28 ];这个矩阵看起来简单但它的每一列都来自气动导数。副翼主要产生滚转力矩同时还附带一点偏航力矩方向舵主要产生偏航力矩大侧滑时也带滚转。升降舵相对独立。实际工程里这些系数从风洞数据、CFD 或线性化工具箱里取不要在仿真里拍脑袋写。B 矩阵是后面所有容错逻辑的地基故障发生本质上就是 B 的某些列变了控制分配器却还在用旧 B 算指令。2.2 卡死、松浮、部分失效、饱和故障在方程里长什么样执行器故障有四种经典模式建模时一定要分开因为它们对分配器的影响不一样故障模式数学表达对分配器的影响卡死Lock-in-Placeu_i(t) δf常数效率矩阵对应列失效且额外产生一个固定力矩松浮Floatingη_i ≈ 0舵面随风摆动效率矩阵对应列接近零部分失效LoEη_i ∈ (0,1)效率矩阵对应列按比例缩小饱和Saturation指令超出位置或速率限制等效于一个时变的效率下降把这四类统一写成一个参数化表达式最方便的做法是% 执行器故障统一表达u_act E * u_cmd u_bias % E diag(eta)eta 是逐舵面健康系数1 为健康0 为完全失效 % u_bias 是卡死位置偏置健康舵面为 0设计故障模型时需要为每个舵面设置几个参数健康系数 eta、卡死偏置 bias、位置上下限 umin/umax、速率限制 rmax。注意卡死和失效的区别卡死舵面虽然指令控制不了它但它仍然钉在某个角度持续产生一个固定力矩而松浮舵面基本不产生力矩。分配器重构时前者要做力矩补偿后者只需把对应列清零。2.3 用 Matlab 把故障注入做成一个函数我一般会把执行器故障封装成一个独立的 Matlab 函数放在 Simulink 的 MATLAB Function 模块里调用这样故障注入和物理执行器模型可以共用一份代码。函数签名和核心逻辑如下function u_act act_fault_model(u_cmd, mode, params, u_prev, Ts) % 固定翼舵面故障模型 % mode: healthy | lock | floating | loe | saturation % params: 结构体含 eta, bias, umin, umax, rmax u_cmd u_cmd(:); n length(u_cmd); switch mode case lock % 卡死输出固定在 bias指令完全不通过 eta zeros(n,1); bias params.bias; case floating % 松浮效率归零无额外偏置 eta zeros(n,1); bias zeros(n,1); case loe % 部分失效eta 逐舵面给定比如右副翼只剩 60% eta params.eta; bias zeros(n,1); otherwise % 健康 eta ones(n,1); bias zeros(n,1); end % 位置层面的指令通过效率矩阵 u_int diag(eta) * u_cmd bias; % 速率限制把上一时刻位置 u_prev 考虑进来 u_act max(min(u_int, u_prev params.rmax * Ts), ... u_prev - params.rmax * Ts); % 位置饱和限幅 u_act max(params.umin, min(params.umax, u_act)); end这个函数的重点是卡死模式下 eta 全为 0指令被掐断但 bias 保留舵面位置钉在故障角度LoE 模式下 eta 是 0 到 1 之间的向量可以只让某一侧副翼降效速率限制放在位置饱和之前避免出现指令一步跳变到新值的理想化情形。在仿真里给这个函数传入不同 mode就能在设定时刻模拟出固定翼最常见的执行器故障。参数设置上rmax 一般取舵机实际角速度上限比如 60 deg/s位置限制按舵面机械行程取两者不要一起忽略否则后面验证重构逻辑时会得到过度乐观的结果。3. 控制分配算法从伪逆到二次规划怎么写进 Matlab 还能跑闭环3.1 伪逆分配的边界约束去哪儿了控制分配最直观的算法是伪逆法。已知 v B * u当 B 是行数小于列数的矩阵时最小范数解是% 伪逆分配把期望力矩拆到所有健康舵面上 u pinv(B) * v; % 等价于 u B * inv(B * B) * v当 B 满行秩时伪逆法实现简单B 固定时计算结果就是一组最小舵面偏度。它在固定翼仿真里有个明显问题完全不考虑舵面的位置饱和和速率限制。如果期望力矩接近包线边缘伪逆给出的指令里某个舵面可能超过机械行程飞机实际得到的力矩和期望值差一大截。另一个问题是伪逆会把指令分配给所有非零列包括效率低下的舵面——故障后如果忘了更新 B指令会继续流向已经卡死的舵面。所以伪逆只适合做健康情况下的快速原型或者作为后面更严谨算法的初值。3.2 加权最小范数与二次规划把约束装进去把位置约束和速率约束一起接进来常见且工程上收敛稳定的是加权二次规划QP形式。目标函数和约束如下% 目标最小化 力矩分配误差 舵面偏度代价 % J (B*u - v) * Wv * (B*u - v) ... % (u - u_ref) * Wu * (u - u_ref) % 约束umin u umax % |u - u_prev| rmax * Ts在 Matlab 里可以直接用 quadprog 求解。我一般写成独立函数方便在 Simulink 里按离散周期调用function u alloc_qp(B, v, u_ref, u_prev, Wu, Wv, ... umin, umax, rmax, Ts) % 控制分配加权二次规划 % B : 3x4 控制效率矩阵 % v : 3x1 期望力矩来自外环控制器 % u_ref : 4x1 舵面偏好位置通常取配平舵面或 0 n size(B, 2); % 构造 QP 的 H 和 f % quadprog 目标为 0.5*u*H*u f*u H B * Wv * B Wu 1e-8 * eye(n); f -B * Wv * v - Wu * u_ref; % 位置约束和速率约束合并为上下界 lb max(umin, u_prev - rmax * Ts); ub min(umax, u_prev rmax * Ts); opts optimoptions(quadprog, ... Display, none, ... Algorithm, interior-point-convex); u quadprog(H, f, [], [], [], [], lb, ub, [], opts); end这段代码里有几个关键点。H 里的 1e-8 正则项是为了防止 BWvB 在故障后接近奇异时数值发散。速率约束没有写成 Aineq 不等式而是直接并进 lb/ub因为单个舵面的速率限制只和上一时刻位置有关等价于上下界的收紧。Wv 和 Wu 是分配器的手感如果想让滚转力矩优先被精确满足就把 Wv 的第一个对角线元素调大如果想让升降舵少动就把 Wu 对应对角线元素调大。常见的做法是先把 Wv 设为对角单位阵让 Wu 的权重比 Wv 低两个量级避免约束冲突时最优解偏向舵面不动。3.3 分配器里的偏好与滚转-偏航耦合固定翼控制分配很容易出现一个现象左右副翼和方向舵在同一个优化问题里打架。比如要一个偏航力矩方向舵可以出左右副翼差动也能出一点伪逆法会把两者都用上导致副翼产生额外的滚转方向舵又去补偏航舵面来回消耗。工程上解决这个问题有两种习惯做法一是在 u_ref 里给方向舵一个中位偏好让优化器在满足力矩要求的前提下尽量少用方向舵二是显式设置加权矩阵 Wu方向舵对应的权重设大。这两种做法在效果上等价我一般直接改 u_ref因为四舵面布局里方向舵的铰链力矩和偏航效率都不如主翼面保持它在中位附近更安全。另一个容易被轻视的点是滚转-偏航耦合。方向舵偏转会带来少量滚转力矩副翼差动也会产生诱导偏航B 矩阵的非对角元素就是这两条耦合通道。如果手写分配逻辑时把滚转和偏航拆成两个独立问题分别求逆侧滑角一大实际力矩和期望值对不上飞机就会出现滚转指令给足了但飞机转不动的体验。QP 分配天然处理了这种耦合因为它是对整个三轴力矩向量求最小二乘。所以我的建议是只要舵面之间存在交叉力矩就不要做分通道分配直接保持 v 为三维向量、B 为完整矩阵让优化器自己去权衡。4. 主动容错重构链路从故障检测到分配权重切换4.1 故障检测的两条路舵面位置回读与模型残差要在分配之前做容错得先知道哪个舵面坏了。固定翼工程里最常见、也最可靠的办法是读舵机位置反馈。舵机自带电位计或编码器时把 u_fbk 和 u_cmd 逐拍比较连续超过阈值一段时间就判定对应舵面故障。这里的关键是连续超过而不是单拍超限否则一个瞬时扰动就会误报。function fd_flag actuator_fdd(u_cmd, u_fbk, tol_pos, Ts, hold_time) % 执行器故障检测指令-反馈持续偏差 % tol_pos : 位置偏差阈值单位 rad % hold_time: 持续超差时间超过才确认故障单位 s err abs(u_fbk - u_cmd); persistent cnt; if isempty(cnt) cnt zeros(size(err)); end cnt(err tol_pos) cnt(err tol_pos) 1; cnt(err tol_pos) 0; fd_flag cnt hold_time / Ts; end第二种方案是模型残差法。用当前舵面指令和状态量通过气动模型算出预期角加速度再和惯导实测值比较。残差持续偏大就说明某个舵面效率下降。这种方法不依赖位置反馈适合舵机没有传感器、或者只想在仿真里做被动容错验证的场景。但它的误报率明显更高因为气动模型本身有误差机动时残差本来就大。我会用位置回读做主判据用残差法做交叉验证两个通道同时报警才切换分配器这样能过滤掉大量假信号。4.2 重构逻辑效率矩阵修正和卡死力矩补偿检测到故障后重构逻辑要做三件事把故障舵面的效率列清零、调整分配权重、补偿卡死舵面带来的常值力矩。以一个卡死舵面为例它的实际偏角固定在 bias 处仍然产生 B0(:,i) * bias 这个力矩。这个力矩不属于任何指令如果不抵消飞机会被它带着偏。正确的做法是让它从期望力矩 v 里减掉再把剩余力矩交给分配器function [B_est, Wu_new, v_eff] reconfigure(B0, health, bias_f, v) % health: 4x1 逻辑向量1 健康0 故障 % bias_f: 4x1 故障舵面的卡死偏置健康舵面为 0 % 1. 效率矩阵修正故障列清零 B_est B0; for i 1:length(health) if health(i) 0.5 B_est(:, i) 0; end end % 2. 分配权重故障舵面给极大惩罚避免指令再流向它 Wu_new diag(1 10 * (1 - health)); % 3. 卡死力矩补偿从期望力矩中扣掉故障舵面的固定贡献 v_eff v - B0 * bias_f; end重构逻辑里最容易写错的是第三步。很多人只做了 B_est 清零忘了扣 bias 力矩结果飞机在故障后仍然朝一个方向偏无论分配器怎么调都拉不回来。扣掉 B0 * bias_f 之后分配器就只需要让健康舵面去产生期望力矩减去故障扰动的净力矩飞机才能在新的平衡点附近稳定。注意补偿力矩用的是原始 B0不是清零后的 B_est因为卡死舵面确实在物理上出力了只是这部分力不受控。4.3 把重构和外环控制器解耦控制器不需要重新设计主动容错与控制分配之间有一层容易被忽略的关系重构逻辑只需改舵面指令的生成方式不需要碰外环姿态控制器。固定翼外环控制器输出的是期望力矩 v它不关心这些力矩由哪几个舵面产生。故障发生时飞行状态会变化外环控制器会自然修正期望力矩分配器只需要确保给定的 v 尽量被剩余舵面实现。这种结构在工程上是极大的解脱——控制器参数不需要随故障切换重构逻辑只需要在 B 和权重上做文章调试边界清晰。有一个前提条件外环控制器必须有余量也就是故障后剩余舵面还能提供足够的控制力矩。如果卡死的是一个关键舵面且剩余舵面全部饱和重构逻辑能做的只是优雅地降级不可能无中生有。所以在仿真里验证容错方案时第一件事就是检查故障后 B_est 的秩和舵面裕度别把容错控制当成无限推力。5. 固定翼分配仿真的踩坑清单五条血泪经验5.1 效率矩阵当成常数换飞行点直接翻车现象在配平点 A 调好的分配器切到高速或大攻角状态后力矩指令虽然没变但飞机侧滑越来越大。原因B 矩阵的数值本质上是气动导数乘以动压动压随空速变化非常明显。把 B 当成常矩阵等于假设飞行状态永远贴着配平点走大机动时分配结果和真实力矩严重不符。解决把 B 拆成常数系数矩阵和动压标量两部分。线性化得到的系数先按动压归一化使用分配器时乘以当前动压或者直接做成 B(q) q * B_coeff按马赫数/攻角查表插值。注意故障重构时也要用当前的 B 估算不能用配平点 B 去补偿卡死力矩。5.2 重构权重硬切换舵面抖到怀疑人生现象故障注入后分配权重瞬间从 0 跳到 10健康舵面的偏角也瞬间跳变仿真里舵机速率限制被顶满机身出现高频抖动。原因权重硬切换相当于给分配器输入了一个阶跃所有健康舵面同时重新分配负载指令出现跳变。解决给重构权重加一个时间斜坡常见做法是把切换过程拉长到 0.10.2 秒让健康舵面逐步接管。实现上可以在 Simulink 里用斜坡发生器或者一阶惯性环节处理 Wu_new也可以直接在重构函数里做一个权重插值。这是我调容错逻辑时花时间最多的地方斜坡时间太短依旧抖太长则故障后的瞬态掉高度控制不住。5.3 pinv 写进连续子系统代数环玄学现象同一个 QP 分配器单独测试正常放进 Simulink 连续模型后报代数环错误或者仿真步长被压得极慢。原因把 B 的伪逆或 quadprog 求解直接写在连续子系统的前向通路里分配器的输出又反馈到同一个子系统状态量上形成了瞬时依赖环。解决让分配器在离散采样周期内运行。最朴素的做法是把整个分配子系统设为离散模块Ts 取 1020 ms或者在一个连续子系统内为 u_prev 加一个 Memory 块把速率约束里的上一时刻位置真正存下来。固定翼飞行控制本来就是数字飞控分配器按离散周期跑完全符合实际。5.4 零空间被浪费副翼和方向舵互相顶牛现象分配结果健康力矩指令也算对了但左右副翼持续差动、方向舵偏到极限舵面利用率极高一遇到饱和就控制不住。原因伪逆法求的是最小范数解不是最小舵面消耗解。当偏航力矩可以由副翼差动和方向舵共同产生时解不唯一最小范数解会把指令稀释到所有幸存的舵面上。解决在 QP 目标函数里加 u_ref 偏好项或者把 Wu 设成非均匀权重。对固定翼我习惯把方向舵权重设高、副翼权重设低迫使分配器优先用副翼做滚转、方向舵只在必要时出偏航力矩。这样既节省方向舵行程也降低了操纵耦合带来的风险。5.5 故障检测延迟飞机已经在掉高度了现象故障注入 2 秒后重构逻辑才动作期间飞机高度损失了 50 米最后虽然恢复姿态但已经触发了最低安全高度逻辑。原因FDD 的确认时间太长。检测阈值设得紧容易误报设得松则故障确认慢。工程上经常默认连续超差 100 ms 就确认但真机里舵机偶尔会有瞬时超差这个逻辑不能照搬。解决把故障确认时间分成两级——第一级是疑似只抬高分配器对对应舵面的权重不改变 B_est第二级是确认才做效率矩阵清零和卡死补偿。疑似阶段不剥夺舵面控制权可以用很小的代价换取响应速度。故障注入验证时把确认时间从 50 ms 到 500 ms 都扫一遍看你最关心的高度损失指标落在哪个区间。6. 闭环验证的进阶做法故障注入矩阵与分配器带宽6.1 用故障注入脚本把故障组合跑一遍容错控制最容易出现的问题是在一个故障点调好了换一个故障点就崩。所以我习惯在仿真验证阶段写一个故障注入脚本把故障类型、故障舵面、发生时间、卡死幅值排列组合批量跑蒙特卡洛仿真。故障注入矩阵大致是故障舵面故障类型注入时刻卡死角度左副翼卡死5 s10 deg右副翼LoE 50%8 s-方向舵卡死6 s-5 deg升降舵松浮10 s-每个组合下记录三组指标姿态角峰值误差、高度损失、健康舵面的饱和时间占比。饱和时间占比超过 30% 的组合说明剩余控制裕度不足重构逻辑再完美也救不回来这类结果要在报告里单独标出。6.2 分配器带宽和舵机带宽留一个十倍间隔分配器本质上是一个带约束的静态优化器但仿真里它跑在离散采样步上也存在带宽问题。我一般把分配器的采样率设为舵机带宽的十倍以上。如果舵机模型的时间常数是 5 rad/s分配器至少跑到 50 Hz搭配 100 Hz 的控制器更新率更稳妥。QP 分配器在每次采样里都要调用 quadprog求解耗时是主要瓶颈所以在验证阶段我会先在脚本里批量跑一遍单步求解统计最坏耗时确认不超过采样周期的 20%再放进仿真回路。这个检查能避免后期发现故障瞬间分配器算不完一场仿真的尴尬。我自己踩过的一次教训先调外环控制器、后调分配器重构逻辑结果飞机每次在故障后都先剧烈抖动我一直以为是控制器参数问题反复调大调了小半个月换成先固定控制器、只改分配权重和补偿项之后两个星期就收敛了。控制分配和容错逻辑是一体的但调试顺序千万别反。分配器是把虚拟力矩落成舵面偏角的那一道闸门固定翼容错方案的成败七成在故障模型和 B 矩阵估计上剩下的三成才知道控制器有多能扛。希望帮到你。本文还有配套的精品资源点击获取