
简介本资源是一份面向控制理论学习者与工程实践者的H2/H∞混合控制仿真教学包聚焦于线性系统鲁棒控制设计与MATLAB/Simulink实现适用于自动化、航空航天及精密机电等领域的高年级本科生、研究生及初级控制工程师。压缩包共17个文件49KB包含4个核心MATLAB脚本如simu_K.m用于控制器参数计算、3个Simulink模型文件含H2_Hinf.mdl和h2_hinf_simulation.mdl支持H2与H∞混合控制器搭建与对比仿真、5个结果可视化fig图如gama_H2.fig、turb_W.fig等直观呈现性能指标与扰动响应以及2个.r13备份模型和1份hslogic.txt逻辑说明文档。已有313人学习下载资源结构清晰、模块分工明确建模→控制器设计→多场景仿真→结果分析形成闭环可直接运行复现H2最优性能与H∞鲁棒边界验证过程特别适合理解Roofa67典型被控对象下的控制律构造、γ参数整定及仿真结果解读。 做控制的人迟早会跟H2控制和H∞控制打照面。不管是做四旋翼的姿态环、机械臂的力控还是伺服系统的速度环只要模型是多输入多输出的、还带着一堆不确定性和扰动传统PID就很容易调到头。我这一两年大部分精力都花在一个代号叫roofa67的小型飞行平台上一开始也是PID和LQR轮着上直到把H2/H∞控制器设计的完整流程在MATLAB里跑通、再搬到Simulink仿真里验证之后才真正想明白现代鲁棒控制在一个具体对象上到底该怎么落地。这篇文章就把我在roofa67上从建模、控制器设计到仿真验证的全过程复盘一遍适合刚接触鲁棒控制、想用MATLAB把H2/H∞控制器真正跑起来、或者正在折腾多变量飞行器控制器的朋友。1. 先搞清roofa67是什么以及为什么非要用H2/H∞不可1.1 roofa67一个强耦合MIMO对象的模型化过程roofa67是我手头一个微型四旋翼验证平台的代号整机质量1.5公斤左右轴距约360mm。这种对象最麻烦的地方在于通道之间耦合严重俯仰角一变前向速度跟着变总拉力一加高度变化的同时机身俯仰也会受影响。想用几个独立PID环把六个自由度全稳住不是不行但调试量巨大而且飞起来手感始终差口气。H2/H∞这类现代控制方法第一步要求我们把对象写成状态空间模型。我在做roofa67时不是直接拿完整12阶模型硬刚而是先做工作点线性化。在悬停点把纵向通道和垂直通道拿出来忽略横滚和偏航的耦合得到一个5阶模型。状态定义为( u )机体前向速度单位m/s( w )机体垂向速度单位m/s( q )俯仰角速率单位rad/s( \theta )俯仰角单位rad( h )高度偏差相对悬停点单位m控制输入是两个通道的指令( \delta_e )是俯仰力矩通道( \delta_t )是总拉力增量。线性化之后的状态矩阵是这样一组数值A [-0.15 0 0 -9.81 0; 0 -0.25 0 0 0; 0 0 -0.8 0 0; 0 0 1 0 0; 0 -1 0 0 0];B [0 0; 0 0.667; 7.2 0; 0 0; 0 0];C [0 0 0 0 1; 0 0 0 1 0];D zeros(2, 2);这里A矩阵里的-9.81来自重力项-0.15和-0.25是电机桨气动阻力带来的速度阻尼-0.8是俯仰阻尼B矩阵里7.2是俯仰力矩增益除以俯仰转动惯量0.667是拉力增益除以质量。这套参数不神秘就是机理建模加简单风洞/悬停实测辨识出来的。我说这些是想强调一点H2/H∞控制器设计的质量极大程度上取决于状态空间模型的准确性。你给控制器喂一个错误的对象模型后面公式推得再漂亮也是白搭。在工程里建模工作至少要占整个项目一半时间这不是夸张。1.2 H2与H∞的分工一个管能量最优一个管最坏情况既然模型有了为什么不用LQR完事非要折腾H2和H∞关键在于这两个控制器回答的问题不一样。H2控制简单理解就是让闭环系统对外部白噪声输入的能量增益最小。它优化的是平均值是方差是大多数情况下的综合表现。LQG其实是H2方法在状态估计和状态反馈框架下的一种实现。所以如果你的扰动可以用白噪声刻画关心的指标是响应方差、控制能耗那H2是很自然的选择。H∞控制则完全是另一套思路它要保证的是在最坏情况下系统增益仍然被压制在一个指定水平以下。它的数学语言是给定系统的传递函数G(s)H∞范数定义为|G|\infty \sup\omega \bar{\sigma}(G(j\omega))也就是在全频段上系统增益的最大奇异值峰值。H∞控制器设计的目标是让这个峰值尽量小或者至少小到一个满足性能要求的阈值γ。打个比方H2像是一辆跑市区通勤的车追求的是平均油耗最低H∞像是一辆要求在任何极端路况下都不能翻车的越野车追求的是最坏情况下的生存能力。在roofa67这种无人机平台上风扰、气流、载重变化都是不好建模的东西我更关心的是突然来一阵侧风能不能稳住而不是平均功耗最低所以H∞在工程上更常用。但H2并非没用它常被当作一个基准、一个初值甚至是混合控制器设计中的一部分。2. 控制器设计背后的关键数学这里讲人话版2.1 H2控制器Riccati方程与LQG的渊源H2控制器的标准问题框架是给定广义被控对象P(s)设计控制器K(s)让闭环系统内部稳定并极小化从外部输入w到性能输出z的闭环传递函数T_zw的H2范数。数学上H2范数定义是|T_{zw}|2^2 \frac{1}{2\pi}\int{-\infty}^{\infty} \text{trace}[T_{zw}(j\omega)^* T_{zw}(j\omega)] d\omega直观理解这衡量的是系统在白噪声输入下输出的总能量/方差。求解H2问题核心是两个代数Riccati方程。让我把结论直接摆出来不绕弯子。假设广义对象的状态空间实现为\dot{x} Ax B_1 w B_2 u z C_1 x D_{11} w D_{12} u y C_2 x D_{21} w D_{22} u在满足一系列条件比如(A, B_2)能镇定、(C_2, A)能检测、(A, B_1)能镇定、(C_1, A)能检测等等的前提下H2最优控制器由两个Riccati方程的解给出。一个来自全状态反馈问题一个来自状态观测器问题两者合在一起结构就是卡尔曼滤波 LQR增益这正是LQG的框架。我在实际中很少手推Riccati方程因为MATLAB的h2syn函数直接就能解。但理解原理有一个实打实的好处当你看到h2syn报出Riccati solution not found之类错误时你会知道是系统的可镇定/可检测性质出了问题而不是傻乎乎去改控制器参数。2.2 H∞控制器从范数到加权函数H∞控制器的标准问题是在同样的广义对象框架下寻找控制器K使得闭环系统内部稳定并且|T_{zw}|_\infty \gamma求解方法有两种主流路线一是基于Riccati方程的双线性变换迭代也就是MATLAB hinfsyn的老实现思路二是基于LMI线性矩阵不等式。在工程使用层面我们不关心求解器内部是走哪条路但必须清楚一个核心问题性能要求是通过加权函数来表达的。这就是H∞控制器与LQR/H2最大的不同。H∞设计你不能直接说我很关心高度别让它超调你得把这句人话翻译成加权函数W1、W2、W3然后构建增广被控对象。加权函数选得不好H∞控制器就各种别扭。我常用的输出混合灵敏度结构是性能输出z [z1; z2; z3]其中z1 W1 * e e是跟踪误差/测量输出希望它在低频段被压下去 z2 W2 * u u是控制输入限制控制量的幅值 z3 W3 * y y是测量输出约束高频增益、保证鲁棒性W1一般是低通滤波器形状低频增益高才能迫使闭环灵敏度函数在低频段小于1实现跟踪和抗扰W2一般选高通或常数限制高频控制动作W3也是高通压制高频噪声放大。这三个权重的交界频率直接决定了控制器的带宽和鲁棒性取向。2.3 混合H2/H∞鱼和熊掌如何兼得有时候我们既希望闭环对白噪声有良好的平均性能又希望对最坏情况有硬性保证。这就引出了混合H2/H∞控制在闭合环满足|T_{zw}|\infty \gamma\infty的前提下极小化另一个通道的H2性能指标。这本质是一个带约束的多目标优化问题工程上通常用LMI工具去数值求解。我在roofa67上其实做过一次混合设计把高度跟踪性能放在H2指标里优化把俯仰通道的鲁棒稳定性放在H∞约束里保证。效果是有改善但说实话调参难度比单独H∞高不少。如果你不是有明确的硬约束需求我不建议一上来就上混合设计先把H2和H∞分别吃透比直接用混合方案靠谱得多。3. 用MATLAB把H2/H∞控制器真正跑起来roofa67完整实例3.1 检查系统基本性质从状态空间到可控可观性任何控制器设计之前我习惯先跑一遍系统基本性质检查。这一步看似不起眼能省下后面一大半排错时间。完整代码骨架如下% roofa67 状态空间模型 A [-0.15 0 0 -9.81 0; 0 -0.25 0 0 0; 0 0 -0.8 0 0; 0 0 1 0 0; 0 -1 0 0 0]; B [0 0; 0 0.667; 7.2 0; 0 0; 0 0]; C [0 0 0 0 1; 0 0 0 1 0]; D zeros(2, 2); G ss(A, B, C, D); % 可控性与可观性 co ctrb(G); ob obsv(G); fprintf(rank(ctrb) %d, rank(obsv) %d\n, rank(co), rank(ob)); % 极点 pole(G) % 系统是否最小实现 G minreal(G);我在roofa67上跑出来的结果是可控矩阵秩为5、可观矩阵秩为5系统是最小实现所有开环极点在左半平面附近但有积分环节拖尾。这说明用H2/H∞设计在结构上是可行的后面如果跑出no stabilizing controller的报错就得回头仔细检查是不是加权函数把某些不利极点带进了广义对象。3.2 H2控制器设计h2syn实战H2设计我习惯用灵敏度加权结构但不加太复杂的整形。roofa67上我的做法是% 加权函数 W1 tf(0.8*[1 2], [1 0.02]); % 低频高增益压跟踪误差 W2 tf(0.1*[1 10], [1 100]); % 高频惩罚限制控制动作 W3 tf(0.2, 1); % 常数鲁棒加权 % 构建广义被控对象 P augw(G, W1, W2, W3); % H2控制器设计 nmeas 2; % 测量输出数量 [h, θ] ncont 2; % 控制输入数量 [δ_e, δ_t] [K_h2, CL_h2, gamma_h2] h2syn(P, nmeas, ncont); % 查看控制器阶数 size(K_h2)augw这个函数是把对象G和三个加权函数按标准结构拼成广义被控对象P这是整个流程里最容易出错的地方。很多人不知道augw拼出来的P内部输入输出顺序是什么导致后面h2syn和hinfsyn的nmeas、ncont填错。我的经验是先用size(P)看一眼再对照augw的文档确认输入输出含义别凭感觉填。设计完之后我会立即看闭环特性% 闭环灵敏度函数 S_h2 feedback(1, G*K_h2); stepinfo(S_h2) % 对输出端阶跃 step(feedback(G*K_h2, eye(2)), 5)在roofa67上H2控制器给出的γ值是1.68左右H2范数别和H∞γ混淆。阶跃响应表现是高度通道大概1.2秒内跟上无稳态误差俯仰角最大偏离0.3弧度左右控制量比较平缓没有高频抖动。整体手感偏温这是H2的典型气质它优化的是白噪声下的综合方差不追求极致的快速性。3.3 H∞控制器设计hinfsyn实战H∞设计的重头戏在加权函数。同样的augw框架换成hinfsyn调用% 调整加权函数H∞要更关注带宽和高频滚降 W1 tf([1 3], [1 0.01]); % 低频增益更高、带宽更宽 W2 tf(0.08*[1 20], [1 200]); % 控制惩罚频率点拉高 W3 tf(0.5*[1 50], [1 500]); % 高频鲁棒加权 P augw(G, W1, W2, W3); gamma_try 1.0; % 目标γ [K_hinf, CL_hinf, gamma_hinf, info] hinfsyn(P, nmeas, ncont, gamma_try); % 如果不指定γ范围也可以让 hinfsyn 自动迭代 % [K_hinf, CL_hinf, gamma_hinf, info] hinfsyn(P, nmeas, ncont);hinfsyn的返回值里gamma_hinf是实际达到的闭环H∞范数。如果gamma_hinf远大于1说明加权函数要求太苛刻控制器做不到如果远小于1说明性能要求松了可以收紧W1或W2。我在roofa67上把目标γ设为1.0最终跑出的gamma_hinf约0.82说明所有加权的性能指标基本都满足了。H∞控制器在阶跃响应的表现和H2完全不同高度通道0.6秒内就能跟上响应快很多但控制量前期有一个明显的脉冲式冲击对执行器其实不太友好。这正是为什么H∞控制器设计之后一定要评估控制输入的幅值和变化率必要时在W2上加大高频惩罚。3.4 Simulink闭环仿真与结果对比MATLAB里验证完我习惯再搭一个Simulink模型做带非线性和限幅的仿真。模型结构不复杂一个roofa67的LTI模块或者更完整的非线性模型、一个控制器模块从K_h2/K_hinf离散化得到、饱和限幅模块、扰动注入模块、示波器和性能统计模块。关键设置是控制器必须用离散模块采样时间按实际飞控取值。roofa67的飞控采样率是500Hz也就是Ts0.002秒。离散化代码Ts 0.002; K_h2_d c2d(K_h2, Ts, tustin); K_hinf_d c2d(K_hinf, Ts, tustin);我分别跑了两组仿真给定高度阶跃2米注入1m/s的风速阶跃扰动等效为俯仰通道扰动力矩。结果对比整理成一张表指标H2控制器H∞控制器高度上升时间1.1s0.55s高度超调量8%22%扰动力矩下最大高度偏差0.35m0.12m控制量峰值平稳无尖峰初始有明显尖峰高频噪声灵敏度低中等靠W3压制这组对比很典型H∞更快、抗扰更强但代价是控制更激进、超调更大H2更温和、超调小但抗扰反应慢。工程师在两者之间的取舍本质上是在性能的上限和鲁棒性的下限之间找一个工程可接受的平衡点。这也是为什么H∞调加权函数时我会在W1的带宽和W2的惩罚强度之间反复横跳每调一次就跑一次Simulink看完整闭环行为光看Bode图和γ值是不够的。4. 仿真和实调中踩过的坑问题排查技巧实录4.1 常见问题速查表跑H2/H∞控制仿真的人十有八九都遇到过下面几个经典问题我自己在roofa67上几乎全踩了一遍。整理成速查表方便你对照排查现象可能原因处理办法hinfsyn返回gammaInf或无法收敛加权函数使广义对象不满足正则性条件通常是D11非零或加权不适当检查augw构建的P是否正则调整W2/W3的高频行为h2syn报no stabilizing controller系统存在不可镇定或不可检测模态检查(A,B2)能镇定和(C2,A)能检测先做可控可观性分解仿真闭环出现高频抖振W2的高频惩罚不够控制器放大了测量噪声增大W2高频增益或者降低W1带宽控制器阶数爆炸式增长加权函数阶数再加上对象阶数一般有10阶以上用balancmr、redschur做平衡截断降阶参数变化后闭环失稳标称设计没有覆盖实际模型不确定性增大W3、加宽鲁棒性加权频段或改用μ综合反馈符号接反仿真发散控制器输出和对象输入的符号定义没对齐先在开环下核对正负方向再闭合回路4.2 高阶控制器的降阶与离散化H∞控制器做出来通常都不是小而美的控制器。比如roofa67的5阶对象加上三个加权函数后控制器阶数能到十几阶。工程上没必要把这十几阶直接部署到飞控里高阶控制器在离散化、数值实现和代码审查时都是负担。我的习惯是先降阶再离散化。降阶用平衡截断% 平衡截断降阶保留4阶 K_hinf_red balancmr(K_hinf, 4); % 或者基于Hankel范数近似 K_hinf_red hankelmr(K_hinf, 4);降阶之后要用sigma对比原控制器和降阶控制器的闭环特性如果闭环灵敏度函数在中低频段几乎没变化就可以放心用。我在roofa67上把控制器从12阶降到4阶闭环性能几乎没有损失γ从0.82涨到0.87仍然满足要求。离散化注意两点一是Tustin变换会把频响压到离散域边界高频特性可能变形二是离散控制器在仿真和实测中都要特别留意抗饱和、初始化问题。我的习惯是Simulink里用Discrete State-Space模块实现控制器初值设成稳态工作点的平衡值避免一上电就给出一个大的控制指令。4.3 加权函数调参的独家心得加权函数的调参没有标准答案但我从roofa67上总结出一套比较实用的初值思路可以作为起点。W1的零极点频率按系统的带宽需求来定。如果希望闭环带宽在1~2Hz附近无人机姿态环的典型值W1的穿越频率就放在这个区间附近低频增益做到20dB以上用来压制稳态误差W2的转折频率比W1高一个数量级就行初始增益给到0.1左右别一上来就给0.01否则控制器会变得过于激进W3的高频段增益从0.1到1之间试如果对象不确定性主要来自高频模型误差就加大W3的增益。还有一个非常容易被忽视的点augw构造的广义对象P必须在无穷远处满足正则条件。也就是说整个回路在高频段的增益要滚降下去W2和W3在高频不能是纯常数且同时D12不为零导致D矩阵结构问题。如果hinfsyn报错说对象不是正则的可以给W2或W3加上一个远高于控制带宽的极点比如分母上加个s/10001让它在高频段仍然滚降问题往往就解决了。调参过程中人很容易陷入死磕γ值的误区。我前几次做H∞设计总想把γ压到0.5以下结果W1带宽越加越大、W2惩罚越来越小控制器越来越疯Simulink一跑就抖振。后来我明白了γ只是一个数学指标工程上γ在0.8到1.2之间都是可以接受的设计真正要盯的是闭环Bode图、阶跃响应和控制量幅值。把γ从0.9降到0.7远不如把闭环超调从30%压到15%来得实在。5. 从roofa67推开去H2/H∞在工程选型中的定位5.1 和PID、LQR、滑模、MPC放一起怎么选控制器设计工具越来越多容易挑花眼。我在roofa67上把主流方法都用过一遍之后形成了一个比较务实的选型判断放一张对比表方法优点缺点最合适的场景PID简单、成熟、调参工具多多变量耦合难处理无鲁棒性保证SISO回路、低要求、快速原型LQR多变量、能处理耦合状态反馈形式清晰需要全状态可测本身无鲁棒性保证全状态可测、二次型性能指标明确H2/LQG白噪声环境下方差最优和卡尔曼滤波天然契合对最坏情况没有保证LQG类问题、导航/估计与控制的联合设计H∞对模型不确定性和最坏扰动有硬性保证加权函数调参难、控制器阶数高不确定性大、安全边界严格滑模控制对匹配干扰有强不敏感性和有限时间收敛抖振问题、对非匹配扰动敏感强非线性、干扰大但可建模为匹配扰动MPC天然处理约束预测能力强在线计算量大、依赖模型精度有约束、慢速系统如化工、轨迹规划你看没有哪个方法是银弹。在roofa67飞控里我最后实际部署的是H∞设计提供基准降阶实现抗饱和保护的组合。姿态内环用H∞保证鲁棒性位置外环反而用了简化的PID因为外环模型不确定性更大、观测延迟也更明显强行H∞未必划算。5.2 这套方法的适用场景与不适用场景从roofa67的经验往外推H2/H∞这套方法最适合的场景大概有三个特征第一对象是多变量、强耦合的PID环环相扣很难调第二模型可以建立到一定可信度至少能给出状态空间表达不需要精确到每个参数但要能捕捉主要动力学第三系统运行环境存在不能简单忽略的扰动或模型变化需要鲁棒性保证。反过来如果系统是单输入单输出、线性度好、运行环境稳定那PID往往性价比最高。如果模型根本没把握、系统是高度非线性的H∞这类线性方法做出的线性控制器只能在一个工作点附近有效这时候滑模、反步法之类非线性控制可能更合适。H2/H∞不是万能钥匙它是一套需要在合适场景下才能发挥价值的精密工具。我个人在roofa67上折腾了这么久最大的体会是别神话H∞也别把它当洪水猛兽。它的数学门槛看着高但现代工具已经把求解器封装得很好了真正的难点在于理解加权函数表达的设计意图、在仿真和实测里反复校准模型。每次看到gamma收敛、闭环阶跃响应平顺、扰动测试通过的那一刻你会觉得前面建模和调参花掉的时间全都值了。最后再分享一个小技巧所有H2/H∞控制器上线实测之前一定先在Simulink里做一次参数摄动扫描把你认为最可能的模型误差范围加大一倍跑一遍如果闭环还稳得住再去动真机不迟。这一步能帮你避掉绝大多数仿真能过、上机就炸的尴尬。本文还有配套的精品资源点击获取