十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于MATLAB的H∞控制器仿真:从增广建模到发散排查

基于MATLAB的H∞控制器仿真:从增广建模到发散排查 简介这是一份MATLAB的H∞控制器仿真源码面向控制理论与工程方向的在校学生、科研人员及工程师解决鲁棒控制器设计落地难、缺少可运行样例的问题。H∞控制以最小化系统对不确定性及扰动的敏感性为目标利用状态空间模型结合LMI方法完成控制器求解源码通过单个M脚本呈现完整主流程包括被控对象建模、控制器设计函数调用与仿真设置紧凑且便于直接运行调试。压缩包共1个文件类型为.m脚本包体仅749B将H∞控制器设计的关键环节浓缩在一个文件内省去复杂工程配置适合快速理解核心逻辑。该资源已有286人学习浏览具备一定参考热度。通过学习这份源码能上手hinfstruct或hinfsyn函数的实际调用方式掌握从系统模型定义到仿真输出的基本链路也可作为后续Simulink联合仿真或课程实验的起步模板对入门鲁棒控制实践很有帮助。1. 拿到 H∞ 控制器仿真源码先想清楚这四件事一个典型场景你负责的伺服台架在低频段受阶跃扰动后要快速回零但系统里有未建模的柔性模态和参数漂移。PID 调了三版幅值裕度够的时候相位裕度不够超调压下去了抗扰能力又没了。此时“基于 MATLAB 的 H∞ 控制器仿真源码”这类标题频繁出现在搜索结果里说明需求很集中——不是要用 H∞ 证明什么理论而是要尽快跑通一条从被控对象模型到控制器验证的完整链路。H∞ 控制器的意义在于把设计目标收敛成一个优化问题找到控制器 K使闭环传递函数从扰动 w 到性能输出 z 的 H∞ 范数最小同时满足稳定性和可实现性约束。这比手工调增益要符合工程直觉因为你只需要把“哪里要硬、哪里要软”翻译成权重函数。本文面向有控制理论基础、但没完整走完一遍 H∞ 设计流程的工程师用 MATLAB 的 Control System Toolbox尤其是 hinfsyn 和 augw作为主线穿插仿真发散排查、权重函数调整和模型降阶等实战问题。全文不依赖任何商业工具箱之外的功能代码在 R2018b 及以上版本均可运行。2. 增广被控对象模型H∞ 仿真的地基是权重函数和 augw 拼装2.1 先搭一个能跑的被控对象双质量弹簧阻尼系统H∞ 控制器设计的第一步不是写控制器而是把被控对象整理成标准形式z 是性能输出w 是外部扰动u 是控制输入y 是量测输出。我在工程里最常用的测试模型是一个双质量弹簧阻尼系统用它可以复现大多数伺服机构在柔性传动下的动态特性。假设质量 m1 和 m2 通过刚度 k 和阻尼 c 耦合控制力 F 作用于 m1扰动 d 作用于 m2量测输出是 m2 的位移和速度性能输出是 m2 的位移和 m1 的控制力。% plant_setup.m % 双质量弹簧阻尼系统柔性传动下的典型被控对象 m1 2.5; % kg驱动侧质量 m2 1.2; % kg负载侧质量 k 800; % N/m连接刚度 c 3; % N.s/m阻尼系数 % 状态变量x1, v1, x2, v2 A [0 1 0 0; -k/m1 -c/m1 k/m1 c/m1; 0 0 0 1; k/m2 c/m2 -k/m2 -c/m2]; B1 [0; 0; 0; 1/m2]; % 扰动 d 作用在负载侧 B2 [0; 1/m1; 0; 0]; % 控制力 F 作用在驱动侧 % 量测输出负载位移和负载速度 C2 [1 0 0 0; 0 0 1 0]; D21 [0; 0]; D22 [0; 0]; % 性能输出负载位移 z1、控制力 u 的加权 z2 C1 [1 0 0 0; 0 0 0 0]; D11 [0; 0]; D12 [0; 1/m1]; % 控制力直接进入性能输出 Pnom ss(A, [B1 B2], [C1; C2], [D11 D12; D21 D22]); Pnom.StateName {x1,v1,x2,v2};B1是扰动到状态量的输入通道B2是控制通道这两个通道在增广后必须严格区分因为权重函数只对指定的通道生效。C2是量测输出代表控制器真实拿得到的信息。C1是性能输出它决定了你的优化目标优先级——这里我希望负载位移尽量小所以把x2放进C1。D12不为零是因为控制力本身也是性能指标的一部分如果不加入这个项求解器会因为控制量无约束而给出非常大的控制器增益。提示ss组装时B矩阵按列拼接的规则是[B1 B2]D矩阵按四象限拼接[D11 D12; D21 D22]。行列数一旦对不上后面augw和hinfsyn的输入输出维度校验就会报错。2.2 权重函数怎么选性能权重 Wp 和控制权重 Wu 的配合现在进入 H∞ 仿真的核心环节——增广被控对象。常见做法是用augw完成输入权重、性能权重和控制权重的拼接。augw需要的权重对象有三种类型Wp是性能权重通常是一个高通或低通滤波器决定干扰抑制的频带Wu是控制权重限制控制量的大小Wn是噪声权重如果不考虑传感器噪声可以用很窄带的低通代替避免求解器在极端频段做无意义的优化。性能权重Wp的设计准则是在需要抑制扰动的频段取高增益其他频段取低增益。最常见的一阶形式是% weight_design.m % 性能权重低频高增益抑制 10 rad/s 以下的扰动 wp_bw 10; % 期望的扰动抑制带宽 wp_eps 0.01; % 允许的稳态误差比例 Wp tf([1/wp_bw wp_eps], [1/wp_bw wp_eps]); Wp ss(Wp); % 控制权重限制控制量带宽避免高频颤振 Wu tf(0.01 * [1 20], [1 200]); Wu ss(Wu); % 噪声权重传感器噪声在 100 rad/s 以上按白噪声处理 Wn ss(tf(0.001));Wp的低频增益是1/wp_eps加入后闭环系统在扰动频段的灵敏度函数被压到wp_eps以下对应稳态扰动抑制比约 1%。wp_bw对应开环穿越频率的上界它和系统的右半平面零点或延迟时间有直接关系设得过高会让求解器找不到可行解。很多场景下你不需要手动调出完美的 Wp只要跑通闭环后观察灵敏度函数再作修正即可这一点后面仿真发散排查一节会细讲。Wu的作用是过滤控制量指令里的高频成分。如果系统里存在未建模的高频模态而你没有加Wu求解出来的控制器会在高频处产生很大的控制速率仿真时表现为控制力震荡或发散。2.3 用 augw 拼装标准型维度信息是仿真排错的第一现场augw的调用形式是Paug augw(Pnom, Wp, Wu, Wn)其中性能通道、控制通道、噪声通道按顺序对应Pnom的第一个输入扰动、第二个输入控制和第一个输出性能、第二个输出量测来拼装。如果你希望同时压抑制两个不同频段的扰动可以自行手动拼装P不再用augw的简写形式而是把两个权重对角放入广义被控对象。% aug_plant.m Paug augw(Pnom, Wp, Wu, Wn); % 查看增广后的 I/O 名称确认通道顺序 Paug.InputName拼装完成后用size(Paug)检查输入个数是 3扰动 w、控制 u、噪声 wn输出个数是 3性能 z、量测 y。记住这个数字因为后面hinfsyn里必须显式指定ny量测输出个数和nu控制输入个数这两个参数错了求解结果就是乱的。常见的坑是直接用Pnom的输入输出个数去套augw后的矩阵导致后续systf或lft互联时维度不匹配报错信息又长又难读。我的习惯是拼装后立刻执行[P_, nw, nu_, nz, ny_] ltiblock.Utilities.checkSignals(Paug);不需要手动记忆这些变量但要在工作区里盯着Paug的状态数和 I/O 个数。状态数超过 20 时后面求解会变慢甚至出现数值坏条件此时考虑对Paug做平衡截断降阶这个技巧在第 5 章展开。3. 用 hinfsyn 求解 H∞ 控制器并搭闭环仿真参数、γ 迭代与验证3.1 最小可复现命令从增广模型到控制器只差 3 行增广模型就绪后标准解法是用hinfsyn直接求解 Riccati 方程。这里我遇到过最多的问题不是控制器设计本身而是调用参数遗忘hinfsyn的输入是(P, ny, nu)其中P必须是增广后的广义被控对象ny是量测输出个数C2的行数nu是控制输入个数B2的列数。这是最容易写错的地方。% hinfsyn_solve.m ny 2; % 量测输出负载位移、速度 nu 1; % 控制输入力 F gam_range [0.01, 20]; % γ 搜索范围 [K, CL, ginfo] hinfsyn(Paug, ny, nu, gam_range(1), gam_range(2), 0.001);逻辑说明hinfsyn做的是带 γ 迭代的 Riccati 求解。它先检查 γ 区间内是否存在可行的控制器然后按tol0.001做二分搜索找到使闭环 H∞ 范数最小的 γ 值。K返回的是控制器对象状态空间形式CL是闭环传递函数矩阵ginfo里包含 γ 值上下界和最终的 γ 达到值。求解完成后务必查看ginfo.gfin它表示实际达到的性能水平通常略大于理论上界。γ 迭代的物理含义是γ 越小闭环系统对扰动的抑制能力越强但控制器增益和带宽会越高。当hinfsyn报告不可行时优先检查gam_range(1)是否过小导致 Riccati 解不存在。此时可以把gam_range改成[0.1, 50]重试。3.2 闭环搭建与频域验证用灵敏度函数和补灵敏度函数定位性能边界求解完成后不能直接投入仿真验证。我的习惯是先搭一个干净的开环互联做频域分析再进时域仿真。控制器K和被控对象Pnom互联时存在正负反馈习惯问题MATLAB 的feedback默认负反馈但hinfsyn返回的K是在正反馈约定下求解的所以互联时需要加负号。% close_loop_check.m % 注意hinfsyn 的控制器用在负反馈回路时要串一个负号 K_neg -K; CL_s feedback(Pnom * K_neg, eye(ny)); % 灵敏度函数 S 1/(1PK) S 1 / (1 Pnom * K_neg); S minreal(S); % 消除零极点相消 % 画出灵敏度函数的奇异值 sigma(S, logspace(-2, 3, 500)); grid on; xlabel(Frequency (rad/s)); ylabel(Singular Values (dB)); title(Sensitivity Function S(s));逻辑说明灵敏度函数S的低频增益直接对应扰动抑制能力。如果仿真发散或稳态误差偏大第一步是画S看低频段是否低于 0 dB——如果低频段大于 0 dB说明扰动不但没被抑制反而被放大问题出在权重或控制器极性上。minreal在这里不能省略因为hinfsyn产生的控制器会和被控对象发生零极点相消保留相消对后续采样仿真会留下数值隐患。3.3 时域仿真验证阶跃扰动和控制量饱和需要分别检查频域验证通过后进时域仿真。最直接的验证方式是取一组有代表性的扰动信号用lsim看闭环响应。这里要注意控制器是连续时间状态空间仿真步长要足够小以避免离散化误差。控制量饱和是另一个重点H∞ 控制器在理论上不感知饱和但真实系统一定存在饱和所以要在仿真里单独抽出控制量通道看是否存在幅值越界。% time_domain_sim.m t 0:0.001:5; % 仿真时长 5s采样步长 1ms d ones(size(t)); % 常值扰动 % 闭环系统对扰动的响应从第二个输入扰动到第一个输出负载位移 sys_d2x1 CL_s(1, 2); [y, tsim, x] lsim(sys_d2x1, d, t); % 控制量通道需要重新搭一个从扰动到控制输出的传递 % 控制器输出 u K * y其中 y 是闭环量测输出 sys_d2u -K_neg * (Pnom(2,:) * (1 / (1 Pnom * K_neg))); [uc, ~] lsim(sys_d2u, d, t); figure; subplot(2,1,1); plot(tsim, y, LineWidth, 1.2); ylabel(负载位移 (m)); grid on; subplot(2,1,2); plot(tsim, uc, LineWidth, 1.2); ylabel(控制力 (N)); grid on;这里sys_d2u的推导略绕但常用做法不是手工算这个传递函数而是直接用K_neg和Pnom的闭环互联函数取出所有通道CL_all lft(Paug, K);lft直接给出闭环广义系统所有通道的 I/O 关系一目了然。推荐用这种方式少折腾符号推导。验证项方法通过标准H∞ 范数norm(CL_all, Inf)小于等于设定的 γ低频扰动抑制sigma(S, w)取低频值低于 -20 dB高频补灵敏度sigma(T, w)取高频值低于 6 dB控制量峰值lsim提取控制通道低于执行器上限4. 仿真发散排查从 γ 值到模型数值坏条件的 4 个检查点4.1 双质量模型里的隐形发散源代数环和状态数失控lsim或sim跑着跑着结果炸掉这是 H∞ 仿真里最磨人的问题。很多人第一反应是控制器参数不对但以我的经验发散多发生在以下 4 个环节。发散源之一hinfsyn返回的闭环模型里存在未消除的数值坏条件状态。增广模型中权重的极点如果特别靠近虚轴比如Wp的极点设在1e-7这个量级Riccati 解会给出极大的内部状态离散化后一个步长就溢出。解决方法是把权重极点的实部设到1e-3以上。发散源之二控制器K和Pnom互联时正负号错导致正反馈。hinfsyn默认正反馈约定直接用feedback(Pnom, K)会得到正反馈回路稳定裕度立刻崩掉。这类发散的特征是仿真前几步就有巨大超调且与仿真步长无关。发散源之三量测输出y包含直接馈通项D22非零而控制器内部也有直接馈通构成代数环。大多数实际系统D22为零如果你搭建的ss模型中不小心让D22出现非零小值闭环仿真时会遇到隐式代数环求解失败lsim直接报错simulink则在代数环求解器上卡死。发散源之四γ 搜索区间设置不当。gam_range(1)设得过低会让hinfsyn在每次迭代时都解不出 Riccati 方程最终返回的控制器是边缘状态仿真时一步就发散。这种情况ginfo.gfin会等于或非常接近gam_range(1)这是一个明确的诊断信号。4.2 三个必查指标返回 γ 值、灵敏度峰值、控制带宽排查项诊断方法典型问题γ 是否贴近区间边界ginfo.gfinvsgam_range(1)贴近下界说明性能被压到极限需要放宽灵敏度峰值norm(S, Inf)大于 26dB时系统对参数摄动很敏感控制器带宽bandwidth(K)大于被控对象右半平面零点的 2 倍时仿真易发散排查顺序建议从控制器带宽入手。H∞ 求解器会把控制器带宽推向权重允许的上限如果控制器带宽是系统刚性的 5 倍以上仿真里稍微有一点数值噪声就会激励出高频振荡随后迅速发散。这种情况通常在Wp或Wu上强行压低高频增益即可缓解。4.3 实用招术对权重和模型做平衡截断后再跑仿真另一个频繁使用的技巧是平衡截断。augw拼装后系统的状态数是Pnom加上两个权重滤波器加总很容易到 2030 阶。除非你刻意做全阶 H∞否则这个阶数对仿真验证没有任何帮助反而引入数值风险。我的习惯是求解前先对Pnom做balred降阶到 6 阶以内求解后再对控制器做一次模型降阶最后做闭环验证。% model_reduce.m % 对被控对象和控制器的平衡截断降阶 rP balred(Pnom, 6); % 保留前 6 阶主导模态 % 重新增广并求解 Paug_r augw(rP, Wp, Wu, Wn); [Kr, CLr, ginfor] hinfsyn(Paug_r, ny, nu, 0.01, 20, 0.001); % 比较降阶前后闭环响应 CL_orig lft(Paug, K); CL_reduced lft(Paug_r, Kr);降阶后仿真发散的风险显著降低。但要注意balred只能处理稳定模型如果你的Pnom本身含积分环节如电机轴系先在Pnom外部加一个小的阻尼项或拆出积分模式再降阶。提示不要对含纯积分器的模型直接调用balred它会因不稳定模式拒绝执行。常见做法是把积分模式剥离开只降阶有阻尼的动态部分仿真时再串回积分器。5. 参数化 H∞ 控制器与工业级仿真验证的衔接技巧5.1 用 hinfstruct 替换 hinfsyn把固定结构控制器约束进仿真如果你拿到的不是简单的全阶问题而是要求控制器必须是二阶或三阶比如嵌入现有 PLC 或运动控制卡hinfsyn返回的全阶状态空间控制器就没法直接用。此时要用hinfstruct它能对固定结构控制器调参但需要把被控对象包装成genss。% hinfstruct_example.m % 固定结构控制器PI 一阶低通 K0 tunableSS(K, 3, 1, 2); % 3 阶控制器1 输入 2 量测 % 闭环系统组装 CL lft(Paug, K0); % 设定性能约束H∞ 范数小于 2 opt hinfstructOptions(Display, final, RandomStart, 5); [Kt, fval] hinfstruct(CL, opt);hinfstruct的输出不是状态空间对象而是genss块里的可调参数值——这里直接Kt就是调整后的控制器。它在仿真里的价值在于你可以直接把它接到simulink的LTI System块里跑硬件在环仿真控制器的阶数不会让实时目标机的计算负担失控。配合hinfstructOptions的RandomStart可以从多组初值里选择收敛结果最好的那个。5.2 仿真验证的收尾技巧把离散化时机从控制器求解后推迟到验证通过后最后分享一个很实用但容易被忽视的做法。很多人习惯在初始阶段就把控制器离散化然后用离散控制器的仿真结果来验证性能。但离散化引入的相位滞后应该在验证闭环后的时域响应后再做而不是提前叠加。原因是当你看到响应振荡或发散时你得在连续时间层面判断是H∞ 设计本身的问题还是离散化引起的相位裕度损失。分开验证可以省去一多半排查时间。% discretize_last.m Ts 0.002; % 控制周期 2ms对应 Nyquist 频率约 1570 rad/s Kd c2d(K_neg, Ts, tustin); % 双线性变换保持频率响应形状 % 与连续控制器对比检查离散化后的灵敏度函数是否仍然满足要求 Sd 1 / (1 c2d(Pnom, Ts, zoh) * Kd); sigma(S, Sd, logspace(-2, 3, 500)); legend(连续, 离散);这里tustin适合 H∞ 控制器因为它能保持连续域的频率响应畸变最小。检查离散和连续的灵敏度曲线如果两者在交叉频率附近有明显偏差说明你的采样周期相对控制器带宽过高——调整办法是减小Ts或重新设计Wu以降低控制器带宽。等两条曲线贴合良好再接入真实的 Simulink 离散仿真或半实物平台后续的模型验证工作就可以完全基于这个离散控制器展开了。本文还有配套的精品资源点击获取
返回列表