☰
鲁棒控制实战:从不确定性建模到MATLAB鲁棒性分析
2026/10/22 4:20:59 网站建设 项目流程

简介:面向控制系统学习者的鲁棒控制实践资源包,以多个真实控制对象为背景,集中展示鲁棒控制从建模到实现的完整过程。内容包括质量块-阻尼器-弹簧系统的鲁棒控制设计、火箭稳定控制的H无穷方法,以及若干鲁棒函数与实例程序;同时配有课程作业文档、仿真模型和PDF说明,便于结合理论对照学习。压缩包共八十六个文件,以七十四份MATLAB脚本为主体,兼有六份Word文档、三份Simulink模型、两份PDF资料和一份SLX模型,整体大小仅三点七二兆字节,按实例分类组织目录,查找方便。已有四百七十四人浏览学习,适合自动化与控制工程专业学生、备考研究生及从事不确定性系统设计的工程师。通过学习可掌握系统建模、不确定性量化、控制器参数计算与阶跃响应评估等关键技能,运行代码即可观察不同参数对动态性能的影响,深化对鲁棒控制理论的理解。

1. 鲁棒.zip 背后的东西:模型不准时,凭什么控制器还能稳

经常能在工程分享里看到标着鲁棒.zip 的资料包,里面不外乎 robust control 的函数脚本和一堆实例。但大多数拿到手的人,解压、跑通 Demo、截图,就停在了原地。真正的问题不是函数怎么调用,而是:模型不准的时候,凭什么这个控制器还能稳。鲁棒控制(robust control)解决的就是这件事,它不追求在某个工作点上性能极致,而是保证参数漂移、未建模动态、外部扰动同时存在时,闭环依然稳定、性能不塌。标题里的鲁棒函数、鲁棒控制实例,也都围绕同一个目标,把不确定性边界先画出来,再让控制器在这个边界内活得下去。

这篇笔记用一条完整的链路往下走:从一个最简单的质量弹簧阻尼系统出发,先讲不确定性怎么建模,再讲怎么用鲁棒函数综合控制器,最后用鲁棒性分析和一组真实踩坑记录收尾。每一步都有可复现代码,你不需要额外的硬件,只要能跑 MATLAB 就能跟着走完。新手可以按顺序复现,熟手可以重点看第 5 章的边界和参数坑。

2. 模型不确定性到底在哪:从标称模型到不确定集合

2.1 参数摄动与未建模动态:两类不确定性的数学描述

PID 翻车通常不是调参问题,而是模型失真。鲁棒控制的第一步,是把「模型不准」这件事拆成两类:参数摄动,和未建模动态。这两类在数学上长得完全不一样,处理方式也不同。

参数摄动指物理参数在一个区间内变化,比如质量弹簧阻尼系统里,负载质量从 0.8 到 1.2,弹簧用久了刚度下降 15%,阻尼随温度漂移。这类不确定性是实数的、带边界的,可以用一个不确定性参数 m 来描述:m ∈ [0.8, 1.2]。在数学上它进入系统矩阵的系数,影响的是极点的位置。

未建模动态则是模型根本没包含的那部分行为,典型的是高频柔性模态、执行器延迟、传感器噪声的某些频段特性。工程上很难说清楚它的具体传递函数,只能给一个范数上界:真实系统相对模型的偏差,在某个频率范围内不超过多少。于是用一个归一化的复数块 Δ(s) 来覆盖它,||Δ||∞ ≤ 1,再乘一个加权函数控制它在不同频段的强度。

在 MATLAB 的鲁棒控制工具箱里,这两类分别对应 ureal 和 ultidyn。下面这段代码把两者组合成一个不确定被控对象:

% 标称模型:质量-弹簧-阻尼,m=1, c=1, k=1 m0 = 1; c0 = 1; k0 = 1; G0 = tf(1, [m0 c0 k0]); % 参数摄动:质量在 0.8 到 1.2 之间,用百分比定义 m_unc = ureal('m', m0, 'Percentage', 20); % 参数摄动后的对象,注意 tf 会自动提升为不确定对象 G_unc = tf(1, [m_unc c0 k0]); % 未建模动态:范数有界的归一化复数块,上界 0.1 delta = ultidyn('Delta', [1 1], 'Bound', 0.1); % 乘性不确定性:真实对象 = 参数摄动模型 * (1 + Delta) G_plant = G_unc * (1 + delta);

这里值得注意几个细节。ureal 的 Percentage 选项是相对标称值的百分比,20 表示质量在 [0.8, 1.2] 区间内摄动;它创建的是一个不确定实数对象,最终会进入系统矩阵。ultidyn 的 Bound 是 H∞ 范数上界,0.1 代表未建模动态最多相当于 10% 的相对模型误差;第二个参数 [1 1] 是块维度,SISO 系统就是 1×1。

乘性结构 (1 + Δ) 是工程上最常见的表示方式,因为它描述相对误差:低频时模型可信,Δ 几乎不起作用;高频时柔性模态、延迟效应放大,Δ 的作用增强。如果你只关心参数摄动而不关心高频动态,直接用 G_unc 就行;但如果把 Δ 丢掉,你的鲁棒控制器对高频未建模动态就是裸奔。还有一个常见误区:有人把参数摄动和未建模动态混在一起,全部用一个 ultidyn 块盖住。这样虽然也能算,但丢掉了参数摄动的结构信息,综合出来的控制器会过度保守,性能白丢。

2.2 H∞ 与 μ 综合:两条主流鲁棒控制路线怎么选

不确定性建模完成之后,下一步是综合控制器。鲁棒控制综合有两条主流路线:H∞ 控制和 μ 综合。两者的目标分层不同:鲁棒稳定性要求在所有可能的不确定性内闭环都稳定;鲁棒性能则进一步要求某个性能指标——通常是灵敏度函数或闭环增益——在所有不确定性内都不超过设定值。

H∞ 控制的思路,是把扰动输入到性能输出的系统增益压到最小。它把频率需求通过加权函数转换成范数约束,得到一个形式上很干净的凸优化问题,计算快、实现也简单。但它有一个结构性缺陷:标准 H∞ 综合把不确定性当成一个整体的范数界来处理,不区分内部结构。换句话说,它不知道你的不确定性是三个参数各自独立摄动,还是一整块未知动态,所以结果必然保守。多个参数同时摄动、每个参数区间还很大时,保守性会非常明显。

μ 综合则是专门为结构化不确定性准备的。它引入结构化奇异值 μ,把每个参数摄动块、每个未建模动态块都单独建模,D-K 迭代在「固定控制器求 μ」和「固定 D 尺度求控制器」之间来回迭代。优点是不保守,能利用不确定性的结构信息;代价是计算量大,控制器阶数高,迭代还可能不收敛。选型上我一般遵循下表:

场景推荐路线理由
外部扰动明确、说不清哪个参数变H∞计算快,保守性可接受
3~5 个参数有明确摄动区间μ 综合利用结构化信息,不保守
高频未建模动态明显、参数漂移小H∞ + ultidyn 覆盖乘性块足够覆盖高频
控制器要部署在嵌入式设备H∞ + 降阶阶数可控,验证链路短

实践经验是先跑 H∞,用 robstab 看临界摄动大小,如果保守到无法接受,再换 μ 综合。不要一上来就 D-K 迭代,那是在给自己找罪受。

2.3 鲁棒函数全家桶:从建模到验证的一条命令链

鲁棒控制工具箱里的函数是分层的,理解分层比背函数签名重要得多。建模层有 ureal、ultidyn、ucomplex、umat、uss,管的是「怎么描述不确定性」;综合层有 hinfsyn、musyn,管的是「怎么算出控制器」;分析层有 robstab、robgain、usample、diskmargin,管的是「算出来的控制器到底稳不稳、性能够不够」。

很多人把 robstab 这类函数当黑匣子,跑出来一个数字就贴进报告,从来不问数字怎么来的。其实这些函数背后都是 LMI、割线法、凸优化,输入输出都是标准的 ss/uss 对象。会读返回变量比会调函数本身重要得多:hinfsyn 返回的 γ 告诉你性能有没有达标,robstab 返回的 wcu 告诉你最坏的摄动点在哪,musyn 返回的 bnd 告诉你迭代收敛得怎么样。

这条命令链在工程上的标准走法,我总结为一句话:augw 组广义对象、hinfsyn 或 musyn 求控制器、robstab 验稳定、usample 看时域、不满意就回去改权函数。第 3 章的鲁棒函数,就是把这个流程固化下来的产物。别把每一步拆成孤立的脚本片段,那样参数一多你根本管不过来。

3. 用鲁棒函数搭最小闭环:一个 SISO 实例从建模到控制器输出

3.1 标称模型与不确定参数:用 ureal 与 ultidyn 搭 G(s)

第 2 章的建模代码是一段演示,这一节把它变成能跑出控制器的工作版本。还是那个质量弹簧阻尼系统,m=1、c=1、k=1,质量有 20% 摄动,高频未建模动态上界 10%。在综合控制器之前,先要把不确定对象和性能通道组装成广义对象 P,augw 就是干这个的。

% 不确定被控对象:参数摄动 + 乘性未建模动态 m_unc = ureal('m', 1, 'Percentage', 20); G_unc = tf(1, [m_unc 1 1]); delta = ultidyn('Delta', [1 1], 'Bound', 0.1); G_plant = G_unc * (1 + delta); % 灵敏度权:低频增益 100(压稳态误差),穿越频率 10 rad/s,高频增益 0.5 W1 = makeweight(100, 10, 0.5); % 补灵敏度权:限制高频增益,避免控制器放大噪声 W3 = makeweight(0.5, 50, 2); % 广义对象:标称版本用于 H∞ 综合,不确定版本用于后续鲁棒性验证 P0 = augw(G0, W1, [], W3); P_unc = augw(G_plant, W1, [], W3);

augw 的输入参数是 (被控对象, W1, W2, W3),分别对应灵敏度、控制量、补灵敏度三个性能通道。第二个参数传 [] 表示不约束控制量,这是 SISO 系统里很常见的做法,先保证稳定性和抗扰动能力,控制量的事留到后面看仿真结果再说。

makeweight 的三个参数是 (直流增益, 穿越频率, 高频增益),它自动生成一个二阶权函数。W1 设成直流增益 100,意思是稳态时希望灵敏度是 1/100,即静态误差控制在 1% 以内;穿越 10 rad/s 是在告诉综合算法「10 rad/s 以下是你的性能区」;高频增益 0.5 表示高频段不追求性能,别为了压低高频灵敏度而牺牲稳定裕度。

这里有一个容易忽略的细节:P0 和 P_unc 结构相同,区别只在被控对象是否含不确定性。H∞ 综合用标称 P0,鲁棒性分析用不确定 P_unc,两者不能混用。如果你拿 P_unc 直接喂给 hinfsyn,工具箱确实能算,但你会丢掉权函数之外的某些处理逻辑,得到的结果也不便于解释。

3.2 hinfsyn 求 H∞ 控制器:加权函数与关键参数

广义对象组装完毕,综合这一步就简单了。hinfsyn 的签名是 hinfsyn(P, nmeas, ncont),P 是广义对象,nmeas 是测量输出个数,ncont 是控制输入个数。SISO 系统两个都是 1。

% H∞ 综合:以标称广义对象 P0 为输入,测量输出 1 个,控制输入 1 个 [K_hinf, CL_nom, gamma] = hinfsyn(P0, 1, 1); % 降阶:控制器阶数通常偏高,先看到 4 阶,再重新验证 K_red = balred(K_hinf, 4);

gamma 是这次综合达到的性能水平。gamma 小于 1,说明闭环性能严格满足了加权函数的要求,还有余量;gamma 大于 1,说明性能被加权函数压得超出了系统能力,需要回去调权函数——通常是降低 W1 的穿越频率或减小直流增益,而不是继续加权硬压。

CL_nom 是标称闭环系统,先别关,后面验证标称时域响应会用到。balred 是模型降阶,H∞ 综合出来的控制器阶数等于广义对象阶数减 1,权函数一旦取高阶,控制器阶数很容易冲到十几阶。降阶到 4 阶通常是 SISO 系统比较舒服的形态,但降阶是有代价的:它会让鲁棒性变差,所以降阶之后必须重新跑 robstab。这一条怎么强调都不过分,我在第 5 章还会专门展开。

3.3 把流程封装成鲁棒函数:一键完成综合与检验

标题里的「鲁棒函数」在工程里有两层含义:一层是工具箱自带的那些函数,另一层是你自己封装的、把综合流程固化的函数。后者才是真正提高效率的地方。我习惯把上一节的操作封装成一个函数,输入是系统参数和权函数参数,输出是控制器和鲁棒性分析结果。这样批量试参数、对比方案的时候,就不用反复复制粘贴脚本。

function out = robust_syn(m_nom, c_nom, k_nom, m_pct, delta_bnd, w1, w3) % robust_syn: 一个把建模、综合、验证流程封装在一起的最小鲁棒函数 % m_nom,c_nom,k_nom: 标称参数;m_pct: 质量摄动百分比;delta_bnd: 未建模动态上界 % w1 = [直流增益, 穿越频率, 高频增益];w3 同结构 G0 = tf(1, [m_nom c_nom k_nom]); m_unc = ureal('m', m_nom, 'Percentage', m_pct); G_unc = tf(1, [m_unc c_nom k_nom]); delta = ultidyn('Delta', [1 1], 'Bound', delta_bnd); G_plant = G_unc * (1 + delta); W1 = makeweight(w1(1), w1(2), w1(3)); W3 = makeweight(w3(1), w3(2), w3(3)); P0 = augw(G0, W1, [], W3); [K, ~, gamma] = hinfsyn(P0, 1, 1); CL = lft(G_plant, K); [stabmargin, wcu] = robstab(CL); out = struct('K', K, 'gamma', gamma, ... 'stabmargin', stabmargin, ... 'wcu', wcu, 'G_plant', G_plant); end

调用时直接换参数就行:

out1 = robust_syn(1, 1, 1, 20, 0.1, [100 10 0.5], [0.5 50 2]); out2 = robust_syn(1, 1, 1, 40, 0.3, [100 10 0.5], [0.5 50 2]);

out1 是基准方案,out2 把质量摄动拉到 40%、未建模动态上界拉到 0.3,用来对比不确定性增大后控制器的表现。返回结果里 stabmargin 是鲁棒稳定裕度,wcu 是最坏摄动点——这两个字段是衡量「控制器值不值得用」的核心依据。

我在实际工作中会把 return 的 struct 再扩充,加进标称闭环的阶跃响应数据和灵敏度峰值,这样一次调用就能输出一份完整的设计报告。函数缝得越细,你越愿意反复跑参数扫描,也就越容易看出权函数和不确定性之间的真实关系。

4. 鲁棒性验证:控制器的稳定裕度、性能裕度与蒙特卡洛表现

4.1 robstab 与 robgain:两个最容易被读错的数字

综合出控制器只是开始,验证才是重头戏。robstab 是鲁棒稳定性分析的入口,它返回的 stabmargin 是最容易读错的数字:大于 1 说明在指定摄动范围内闭环必然稳定,这个没问题;但它的绝对值不能被当作「安全系数」来理解。stabmargin 等于 1.05,不代表还有 5% 的安全余量,而是表明系统在不确定性边界附近已经快要触碰到失稳面了。这个临界性质,决定了它的倒数比它本身更值得关注——缺口越大,可容纳的实际摄动越小。

% 把控制器与不确定被控对象组成闭环 CL = lft(out1.G_plant, out1.K); % 鲁棒稳定裕度:返回值 wcu 是最坏摄动点 [stabmargin, wcu] = robstab(CL); % 在指定频率网格上算最坏摄动下的闭环增益上界 perf_bnd = robgain(CL, logspace(-1, 2, 200));

wcu 这个返回值是很多人忽略的宝藏:它具体告诉你是哪一组参数组合、哪一个频率点上出了问题。如果 wcu 里的 m 已经压到 0.8 的下边界,说明质量变小是主要威胁;如果问题集中在某段频率,说明未建模动态在那个频段上被放大了。这些信息比一个孤零零的 stabmargin 数字有用得多。

robgain 返回的是最坏摄动下的闭环增益上界,它对应鲁棒性能这个层面——稳定归稳定,性能指标守不守得住是另一回事。读它时不要死记硬背某个阈值,重点看两件事:一是相对趋势,降阶、改权函数之后它有没有明显变差;二是和 wcu 配套使用,定位性能最容易被打穿的频率点。我习惯在报告里同时给 stabmargin 和 perf_bnd 的曲线,只说「哪里贴着边界」,不给出脱离场景的绝对判断。

4.2 蒙特卡洛采样验证:40 条阶跃响应里看鲁棒性

解析分析能给出最坏情况的保证,但工程人员更想看直观的时域表现。usample 可以从不确定对象里抽取样本,生成一批具体的、可仿真的 LTI 系统,把它们逐一和控制器闭环后画阶跃响应,一眼就能看出鲁棒性在时域上的真实样子。

% 从不确定被控对象里采 40 个样本 Gs = usample(out1.G_plant, 40); figure; hold on; for i = 1:40 CL_s = feedback(Gs(:,:,i) * out1.K, 1); step(CL_s, 5); end

这一步的解读有个关键要领:如果 40 条曲线聚合得很紧、超调量接近,说明控制器对该摄动范围内的所有情况都有稳定且一致的响应;如果曲线尾巴发散得很厉害、出现一部分样本振荡,说明控制器的鲁棒性正在贴着边界。此时无论 stabmargin 是不是大于 1,都应该回头检查 wcu 给出的最坏摄动点。

但要清醒一点:usample 采的是 Δ 的频率响应样本和不确定参数的随机组合,不是均匀遍历参数空间。多个参数同时取到边界的极端组合,随机采样极难命中。所以蒙特卡洛只能给你「大概率看不到炸」的信心,不能替代 robstab 的边界保证。最坏情况要看 wcu,时域分布看 usample,两者配合才是完整的验证。

4.3 频域三件套:灵敏度峰值、带宽与互补灵敏度

频域验证是鲁棒控制设计里最后一道关。三个指标最常用:灵敏度函数 S 的峰值、开环穿越频率、补灵敏度函数 T 的峰值。它们的表达式和经验参考值如下表,注意经验值不是某个标准的强制要求,它们是工程上用来快速判断异常的信号。

指标表达式经验参考异常信号
灵敏度峰值 Ms||S||∞不超过 2(约 6dB)阶跃超调大、噪声放大明显
开环穿越频率 ωc|L(jω)|=1接近期望闭环带宽响应太慢或抖动
补灵敏度峰值 Mt||T||∞不超过 1.5对未建模动态敏感
% 标称闭环的灵敏度与补灵敏度曲线 S = feedback(1, out1.K * out1.G_plant); T = 1 - S; sigma(S, T, logspace(-2, 2, 200));

sigma 是画奇异值曲线的函数,SISO 系统下就是幅值 Bode 图。M_s 超过 6dB 通常意味着阻尼比已经掉到不可接受的水平,系统对模型误差极为敏感;M_t 过高则意味着控制器的输出在高频段没有充分衰减,任何一点噪声或未建模动态都可能被放大成实际振荡。我在每次改完权函数后都会把这组曲线重画一遍,确认三件套都在参考区间内,才敢把控制器交给下一步。

5. 鲁棒控制实例避坑:阶数爆炸、迭代不收敛与离散化翻车

5.1 控制器阶数爆炸:现象、原因与降阶思路

现象:hinfsyn 综合完,控制器 16 阶、18 阶,仿真跑起来慢,部署到嵌入式更是想都别想。很多人第一反应是「模型阶数高所以控制器阶数高」,然后去折腾模型降阶。

原因:H∞ 控制器的阶数约等于广义对象 P 的阶数减 1。而你给 augw 传的权函数每多一阶,广义对象就多一阶。makeweight 本身是二阶,被控对象二阶,两个权一加,P 已经六阶以上,控制器阶数上两位数毫不奇怪。真正的元凶往往是权函数选得太复杂,而不是被控对象本身。

解决:先用最低阶的权函数跑通整个链路,确认综合和验证流程都没问题,再逐步增加权函数阶数。降阶要用 balred,但降阶之后必须重跑 robstab——这一步是大多数翻车现场的分水岭:很多人降完阶直接看 Bode 图,形状差不多就部署了,结果现场一上电就抖。降阶会同时改变回补灵敏度,尤其在高频段,这是 Bode 图肉眼看不出来的。

K_red = balred(K_hinf, 4); CL_red = lft(out1.G_plant, K_red); [stabmargin_red, ~] = robstab(CL_red);

如果 stabmargin_red 掉到 1 以下,不要继续裸降阶,回去简化权函数才是正路。控制器阶数的锅,八成在权函数不在系统。

5.2 D-K 迭代不收敛:γ 不降反升怎么办

现象:musyn 迭代了五六轮,γ 从 1.2 一路涨到 2.5,或者上下震荡永远不收敛。这时很多人开始怀疑是不是不确定模型建错了。

原因:D-K 迭代里 D 尺度的拟合阶数不够,或者不确定性块的配置和权函数不匹配。最常见的情况是模型里有两个 ultidyn 块,但你给它们共用一个加权结构,D-K 迭代必须用一个 D 去同时近似两个频率特性完全不同的块,自然会振荡。

解决:把混合不确定性拆开,每个块单独加权;用 musynOptions 提高 D 拟合阶数,或者限制迭代次数先看趋势。

opt = musynOptions('MaxIter', 10, 'Display', 'iter'); [K_mu, ~, bnd] = musyn(P_unc, 1, 1, opt);

bnd 返回每次迭代的 μ 上下界,第一列是下界、第二列是上界。看它比看 γ 更本质:上下界打开又合不上,说明问题在 D 尺度拟合;上下界都在缓慢下降,说明方向对了,只是迭代次数不够。另外一个实用技巧:先跑一次 H∞ 拿到一个可行 γ,把它作为 musyn 的初始控制器,能显著改善收敛行为。

5.3 鲁棒稳定性过了、时域仿真还是振荡

现象:robstab 给了 1.2 的裕度,理论上很安全,但 usample 出来的阶跃响应里,有一部分样本出现高频振荡。

原因:鲁棒稳定性只保证闭环在不确定性范围内不发散,不保证性能。摄动到最坏情况时,极点确实还在左半平面,但阻尼比可能已经掉到 0.05 以下。这是鲁棒稳定性和鲁棒性能脱节造成的,也是初学鲁棒控制最容易踩的坑。

解决:给广义对象加上性能通道,别让到底时域仿真才发现。augw 里的 W1 就是干这个的,但很多人把它设成很弱的默认值,等于没加。另外,wcu 指定的最坏摄动点可以直接拿来单独验证:构造一组具体参数,把闭环拉出来跑一次阶跃响应,马上能看到振荡长什么样。这个 wcu 样本比任何一组随机采样都有代表性。

5.4 离散化之后鲁棒裕度直接跌破 1

现象:连续域设计时 stabmargin 还有 1.3,c2d 离散化之后重跑 robstab,跌到 0.9。同一个控制器,换了个域就叛变了。

原因:零阶保持器天然引入相位滞后,高频段约等于一个纯延迟的相位损失。这个损失在连续域设计时根本没出现在模型里,离散化之后它以未建模动态的形式偷袭进来,和原本的 Δ 叠加,稳定裕度自然被吃掉了。

解决:两个思路。一个是在连续域建模时就把等效延迟包含进去,用 pade 近似一个 0.01s 的延迟块,和不确定对象串联,让综合算法在源头上就为相位损失留余量。另一个是用离散域的鲁棒综合函数直接设计,一步到位。我一般用第一种,因为连续域设计工具链成熟、调试反馈快,但建模阶段就要把延迟写进去。

Td = 0.01; % 等效延迟,按采样周期的一半估算 delay = pade(Td, 2); % 二阶 Pade 近似 G_delay = G_plant * delay; % 带延迟的不确定被控对象

Pade 近似是有限维的,可以直接进 augw 和 hinfsyn。做完这一步再离散化,stabmargin 通常能保持住。记住这条经验:连续域设计完成后,c2d 这一步不是流程终点,而是新的验证起点。

5.5 采样数不够:蒙特卡洛与最坏情况的偏差

现象:usample 采了 20 个样本,全部稳定,曲线都很干净,但 robstab 硬说 stabmargin 只有 0.95,在摄动范围内存在失稳点。直觉上觉得是 robstab 太保守,其实是你的采样根本没有撞上最坏情况。

原因:参数摄动的最坏情况几乎总是出现在参数组合的角点——所有参数同时压到边界上。随机采样在一个连续空间里均匀分布,撞到角点的概率极低,除非你采样几千次,否则根本看不见那个让系统失稳的极端组合。

解决:把 wcu 里的最坏摄动值手动构造出来,直接闭环仿真,你立刻能看到 robstab 为什么说它不稳。也别把 usample 的采样数从 20 加到 2000,那是事倍功半的蛮力路线。

% 用 wcu 里的最坏参数构造一组具体系统,直接看时域 G_worst = usubs(out1.G_plant, 'm', out1.wcu.m); CL_worst = feedback(G_worst * out1.K, 1); step(CL_worst, 5);

usubs 可以把不确定对象里某个参数替换成具体值,wcu 里的字段名和建模时的 ureal 名字一致。用这种方式验证最坏情况,比堆采样数要靠谱一个量级。记住:robstab 给的是边界,usample 给的是分布,两者要对着看,而不是用分布的乐观去否定边界的警告。

6. 把经验固化:一套可复用的权函数模板与降阶验证流程

6.1 权函数初值模板:一个起点胜过十次瞎调

每次新建一个鲁棒控制项目,我都是从同一套权函数初值开始的。它不是万能解,但绝大多数 SISO 系统在这个起点上都能跑通,然后再按实际需求调:

权函数初值模板调节方向
W1 灵敏度权makeweight(100, 10, 0.5)穿越频率降,性能收;直流增益升,稳态误差压
W2 控制量权留空 []饱和明显时改为 makeweight(0.1, 100, 1)
W3 补灵敏度权makeweight(0.5, 50, 2)高频噪声敏感时,把穿越频率降到 20 附近

三个权函数是互相耦合的。改 W1 的穿越频率时,W3 必须同步调整,否则灵敏度曲线和补灵敏度曲线会在穿越频率附近打架。我只动一个参数的调法,调完必翻车。

6.2 一套固定验证顺序

我现在每设计一个鲁棒控制器,都按同一套顺序走完才敢交付:先 robstab 记下 stabmargin 和 wcu,再看 robgain 检查性能通道有没有被打穿,接着 usample 采 40 个样本看时域分布,再把 wcu 最坏情况拉出来单独验证,最后 c2d 离散化之后重跑一遍 robstab。balred 降阶之后,从头再来一遍这套流程。中间任何一步翻车,都回到权函数去改,而不是在控制器上打补丁。

这套流程看起来繁琐,但它能拦住绝大多数「仿真没炸、现场炸了」的问题。我把这套代码和模板函数打进一个自用的函数包,命名就叫 robust_ctl_lib——对应别人传的那类鲁棒.zip,我的理解是:真正值得传播的不是几个算好的控制器,而是这套能反复复现、能改参数、能看出边界在哪的流程。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询