☰
自抗扰控制仿真实例汇总:从ESO搭建到参数整定避坑指南
2026/10/22 7:57:20 网站建设 项目流程

简介:这是一份针对自抗扰控制(ADRC)理论与工程应用的仿真实例合集,面向正在学习现代控制理论的高校学生、科研人员以及需要快速搭建仿真验证环境的控制工程师。压缩包共62个文件、总大小约67.32MB,文件类型涵盖Simulink模型(slx)、MATLAB脚本(m)、PDF论文、CAJ期刊文献、Word技术说明、演示视频及绘图辅助文件,目录结构清晰,便于按主题查找。内容从LESO与NESO的对比、fhan与fsun参数设置,延伸到永磁同步电机双闭环调速、单轴云台指向控制、上拉式磁悬浮等工程场景,每个示例均配有可运行的Simulink模型或说明文档,既覆盖核心理论又贴近实际应用。特别是PMSM双闭环示例展示了ADRC在电机速度与位置控制中的实现方式,云台与磁悬浮案例则突出强扰动抑制能力。配套的中文文献与英文综述可帮助系统理解扩展状态观测器、扰动抑制及带宽调节等关键机理,非线性函数等高线绘制文件则辅助分析控制律特性。目前已有1700余人学习下载,适合需要从零搭建ADRC仿真、对照不同控制策略效果的中高级学习者。

1. 为什么“自抗扰控制仿真实例汇总,很全”并不意味着开箱即用

“自抗扰控制仿真实例汇总,很全”这类资源,我这两年接过不止一次。压缩包里有十几个模型文件,从一阶惯性到四旋翼姿态都有,目录结构也规整,看着确实心动。但你按默认参数随手点开一个模型,结果往往是两条路:要么仿真直接发散,要么勉强能跑但控制量抖得像锯齿。问题大多不在ADRC算法本身,而在示例之间的单位制、b0定义、仿真步长、离散化方式完全不统一。

这篇笔记要解决的,就是拿到这类“很全”的汇总之后,怎么看懂它、怎么挑出能复用的骨架、怎么把它改造成适配自己对象的仿真实例。读者里一类是刚接触ADRC、想在仿真环境里快速跑通闭环的新手;另一类是拿ADRC去评估现有控制方案、需要判断“值不值得用”的一线工程师。下面按“结构拆解 → 实例怎么搭 → 参数怎么调 → 坑在哪里 → 怎么验证”这条线往下走。

2. ADRC仿真里的三个核心模块:ESO、TD、NLSEF各自扮演什么角色

2.1 线性ADRC还是非线性ADRC:先想清楚再动手

ADRC标准结构由三个模块组成:跟踪微分器(TD)、扩张状态观测器(ESO)、非线性状态误差反馈(NLSEF)。但打开一份实例汇总后,最先要做的不是逐个模块读代码,而是先判断这份实例走的是线性路线还是非线性路线。

工程仿真里最常见的是线性ADRC(LADRC)。ESO用线性增益,控制律用类似PD的形式,可调参数就三组:观测器带宽ωo、控制器带宽ωc、控制增益估计b0。带宽法直接给公式:β1=3ωo,β2=3ωo²,β3=ωo³,kp=ωc²,kd=2ωc。这意味着你不用去试凑十几个参数,先按公式算初值,再微调即可。我一般建议第一次搭建或快速评估方案时,先用LADRC把闭环跑通。

非线性ADRC会引入fal(e,α,δ)这类函数和更多可调增益,在强非线性对象和大幅扰动下极限抗扰能力更好,但参数之间耦合严重。有人把fal的线性区间宽度从0.01改成0.02,波形就从收敛变成等幅振荡。尤其在一份大而全的汇总里,非线性版本往往是在线性骨架上套了几层函数,骨架没跑通时非线性版本更难排查。所以我的做法是:先线性后非线性,别一上来就挑战最高配。

2.2 在Simulink里把ESO搭出来:从状态方程到积分器链

ESO是ADRC里最有“黑匣子”气质的一块。它只依赖对象输出y和控制输入u,实时估计“内部动态+外部扰动”打包而成的总扰动。对一个二阶对象:

y'' = f(y, y', d, t) + b·u

其中b是真实控制增益,f是内部动态和外部扰动之和。令b0为b的估计值,ESO状态方程写成:

ż1 = z2 - β1(z1-y)
ż2 = z3 - β2(z1-y) + b0·u
ż3 = -β3(z1-y)

z1跟踪y,z2跟踪y',z3跟踪总扰动。β1、β2、β3按带宽法取。在Simulink里搭这个ESO时,用三个积分器串起来:第一个积分器输出z1,输入是z2减去β1倍误差;第二个积分器输出z2,输入是z3减去β2倍误差再加上b0·u;第三个积分器输出z3,输入是负的β3倍误差。把y引出来与z1做差得到误差,分别乘三个增益反馈回去即可。

下面给一段能直接运行的MATLAB脚本,模拟二阶伺服对象加LADRC的闭环:

% 二阶对象 + 线性ADRC 最小离散仿真(欧拉法) h = 0.001; % 仿真步长,单位秒 T = 5; % 总时长 N = round(T/h); % 对象参数:单轴伺服机构 J = 0.002; % 转动惯量 kg·m^2 c = 0.001; % 阻尼系数 N·m·s/rad Kt = 0.5; % 力矩系数 N·m/A b0 = Kt / J; % 控制增益估计,关键参数 % LADRC参数(带宽法) wo = 30; % 观测器带宽 rad/s wc = 10; % 控制器带宽 rad/s beta1 = 3 * wo; beta2 = 3 * wo^2; beta3 = wo^3; kp = wc^2; kd = 2 * wc; % 状态初始化 y = 0; dy = 0; % 对象实际状态 z1 = 0; z2 = 0; z3 = 0; % ESO状态 u = 0; % 控制量 d = 0; % 外部扰动 for k = 1:N ref = 1; % 阶跃参考 ddy = (Kt*u + d - c*dy) / J; % 对象动态 dy = dy + h*ddy; y = y + h*dy; e = z1 - y; % ESO观测误差 dz1 = z2 - beta1*e; dz2 = z3 - beta2*e + b0*u; dz3 = -beta3*e; z1 = z1 + h*dz1; z2 = z2 + h*dz2; z3 = z3 + h*dz3; % 控制律:PD + 扰动补偿 u0 = kp*(ref - z1) + kd*(0 - z2); % ref的微分为0 u = (u0 - z3) / b0; if k == round(2/h) d = 1.0; % 第2秒加阶跃扰动 end end

这段代码里最值得反复确认的是b0 = Kt/J。实际J只有一个粗略值,如果写大10倍,ESO会把控制量u对状态的贡献放大,z3严重偏离真实总扰动,最终控制量发散。另一个数值坑是步长h与ωo的乘积:常见要求是h·ωo < 0.1,ωo=30时h取0.001到0.003比较安全,取0.01则两三秒后z3就开始振荡。我习惯用固定步长仿真器,避免变步长在ESO快慢动态之间来回切换,得到表面收敛但实际不可信的结果。

2.3 控制律和扰动补偿:TD、PD与“把对象变成积分器”

整个ADRC的控制律由两部分组成:一部分是反馈控制u0,另一部分是扰动补偿z3。u0 = kp·(v1-z1) + kd·(v2-z2),其中v1、v2是参考及其导数。如果直接用阶跃作为参考,v2常取0,但这样初始阶段控制量会很大,容易把ESO的暂态拉爆。工程上更稳妥的方式是加一个TD,把阶跃参考安排成平滑过渡的轨迹。

TD的离散形式可以理解为两个状态:v1跟踪参考信号,v2跟踪v1的导数。TD里有一个速度因子r,r越大跟踪越快,但会给对象带来更大的初始加速度需求。在实例汇总里常见两种做法:一种带TD,适合需要限制超调和初始控制力的对象;另一种省略TD,参考直接进控制器,适合对响应快速性要求高、且对象本身不过冲的场景。选哪种取决于你的对象,而不是哪个更先进。

扰动补偿的含义更关键:u = (u0 - z3)/b0。z3估计的是总扰动,把它从控制量里减掉,相当于把原对象中所有不确定的动态“抵消”掉,让控制器看到的是一个纯积分器串联对象。这也是ADRC仿真的核心价值所在:你可以在不精确知道对象模型的情况下,把未知项当作扰动处理,用观测器估计并补偿。理解了这条链路,看任何一份实例都不会再觉得ESO是个玄学黑盒。

3. 整理一份能照着复现的ADRC仿真清单:从一阶惯性到欠驱动系统

3.1 一阶惯性加延迟:ADRC的入门示例怎么搭

一阶惯性加延迟是温度、压力、流量等过程控制里最常见的对象形式,也是ADRC示例里出镜率最高的入门素材。对象写成:

τ·y' = -y + K·u + d

K是增益,τ是时间常数。这种一阶对象配的ESO是二阶的:z1跟踪y,z2跟踪总扰动。控制律只需要比例项,微分项可以不要,因为对象本身就有一阶惯性。下面是精简版的可运行代码:

% 一阶惯性对象 + LADRC 最小可运行示例 h = 0.002; T = 6; N = round(T/h); K = 2; % 对象增益 tau = 0.8; % 时间常数 b0 = K / tau; % 控制增益估计 wo = 20; % 观测器带宽 wc = 5; % 控制器带宽 beta1 = 2*wo; beta2 = wo^2; kp = wc; y = 0; z1 = 0; z2 = 0; u = 0; d = 0; ref = 1; for k = 1:N dy = (-y + K*u + d) / tau; y = y + h*dy; % 对象更新 e = z1 - y; dz1 = z2 - beta1*e + b0*u; dz2 = -beta2*e; z1 = z1 + h*dz1; z2 = z2 + h*dz2; u0 = kp*(ref - z1); u = (u0 - z2) / b0; if k == round(3/h) d = 0.5; % 第3秒加扰动 end end

一阶对象ESO的增益公式与二阶不同,这一点很容易在汇总里搞混:二阶对象ESO用β1=3ωo、β2=3ωo²、β3=ωo³,而一阶对象只用β1=2ωo、β2=ωo²。b0在这里是K/τ,也就是稳态输入输出关系的增益。如果对象模型不准确,b0偏差在50%以内ADRC仍能稳住;偏差超过这个范围,补偿方向就可能出问题。

延迟对象稍微复杂一点。在Simulink里可以在对象输出后面串一个Transport Delay块,步长设成固定值,避免变步长带来的延迟抖动。ESO输入用的是延迟后的输出,也就是说ESO观测的是延迟之后的y,控制器面对的是一个“看起来滞后了τ0秒”的对象。延迟越大,ωo越要压低,否则ESO会把延迟误判成高频扰动,引起控制量抖动。

3.2 二阶机械系统:b0怎么估,参数怎么对应对象

二阶机械系统是电机、机械臂、伺服转台等场景的公共骨架,也是大多数“很全”实例汇总里最能复用的那部分。典型模型是:

J·θ'' + c·θ' = Kt·u + d

θ是转角,J是转动惯量,c是粘性阻尼,Kt是力矩系数。这个对象在ADRC里按二阶处理,ESO取三阶,控制律取PD加扰动补偿。跟一阶对象相比,二阶系统的参数映射更依赖b0的准确估计。

下面是一张我常用的参数对照表,把对象物理参数和ADRC参数对应起来:

参数物理含义估算方式调大影响调小影响
b0控制增益估计Kt/J 或 稳态输入输出反算补偿减弱,扰动抑制下降补偿过度,控制量振荡
ωo观测器带宽取对象动态频率的5~10倍ESO收敛快,噪声放大估计滞后,抗扰变差
ωc控制器带宽取你期望闭环响应频率的1~2倍响应变快,超调增大响应变慢,系统变钝
h仿真步长满足h·ωo<0.1数值更稳,仿真更慢离散误差大,ESO发散

b0有两种常见估法。一种是从物理参数求:b0=Kt/J,J取标称值即可。另一种更推荐,就是做开环测试:给对象一个恒定控制量u_ss,等速度或位置变化率稳定后,用稳态变化率除以u_ss得到b0的粗略值。像伺服机构这类机械对象,摩擦力、齿隙、电气时间常数都会影响真实增益,开环反算比查手册更可靠。我在某伺服项目X里就用这种方法,b0估计误差从30%降到了5%以内。

二阶对象调参时的顺序也有讲究。先固定b0不动,把ωo从低往高调,观察z3对已知扰动的估计速度和噪声水平;然后再调ωc,按照期望的闭环带宽设定初值,若超调偏大就略微下调kd或加TD。不少实例汇总里默认参数是直接给全的,但如果换到自己的对象上,物理单位一变,这些参数全部要重算,不能直接复用。

3.3 常见示例场景的取舍:电机、飞行器、温度控制

一份大而全的ADRC汇总里,场景往往能分成几类,但背后的仿真骨架可能是同一套。最常见的是三类:

第一类是电机控制,无论永磁同步电机的速度环还是电流环,模型本质就是二阶机械系统加电气动态。速度环ADRC可以直接套用3.2的骨架,把对象换成电机状态方程;电流环时间尺度快,ωo需要设计得更高,同时要注意电流环采样周期小,离散步长要跟着缩小。

第二类是飞行器姿态和高度控制,属于欠驱动系统。这类实例看起来复杂,悬停点附近高度通道近似为二阶积分器,姿态内环近似为二阶模型。ADRC的ESO会把通道间的耦合当成扰动估计掉,但前提是内环带宽要明显高于外环,否则耦合导致的“总扰动”变化太快,ESO估计滞后。飞行器仿真里最常翻车的是扰动量纲不统一,比如角速度用rad/s,扰动用deg,z3对应的物理量就会错位。

第三类是温度等大惯性过程对象,模型回归到3.1的一阶惯性加延迟。这类对象时间常数大,ADRC的优势是对模型误差不敏感,但延迟时间长了ωo必须压低,否则控制量会持续抖动。我的原则是:先判断对象微分方程的阶次,再决定ESO阶数,不要被场景名称带跑。所有场景的取舍其实只有一句话——找到真正的被控量微分方程,ADRC的骨架就是通用的。

4. 避坑实录:ADRC仿真中常踩的五个坑及排查路径

4.1 ESO数值发散,仿真中途直接卡死

现象:仿真运行到某个时刻,z3突然冲到1e6,甚至变成NaN,求解器报错。 原因:最常见的是ωo设置过大,ESO带宽接近离散采样频率,导致数值不稳定。其次是仿真步长太大,欧拉法的误差在高增益下指数级放大。还有一种是b0的符号写反,ESO会把控制输入的作用方向估计反,直接爆掉。 解决:先把步长降下来,满足h·ωo<0.1;再把ωo降到对象动态频率的5~10倍;最后检查b0正负号和控制量单位。这三个检查顺序不要颠倒,因为改b0符号的影响最隐蔽。

4.2 控制量高频抖振,波形像锯齿

现象:闭环能稳定,输出波形也正常,但控制量u上叠加了高频锯齿,幅度还不小。 原因:一种情况是fal函数的线性区间宽度设小了,非线性增益在零点附近被放大,微小的观测误差直接激励控制量。另一种情况是测量噪声被ESO高带宽放大,进入控制律后形成高频分量。TD速度因子过大也会造成参考轨迹的导数出现尖峰。 解决:如果用了非线性ADRC,把fal的δ从0.01加到0.02试试;如果是噪声问题,在ESO输入前加一阶低通滤波,或者在控制律输出端加饱和限制;如果TD速度因子过猛,降低r值,让参考轨迹的加速度曲线更平滑。

4.3 加了扰动反而更差,抗扰效果与预期完全相反

现象:没加扰动时系统稳定,在第3秒加了阶跃扰动后,输出不但没被抑制,反而向错误方向偏移。 原因:b0与实际控制增益偏差过大。b0偏大,补偿量(u0-z3)/b0被过度缩小,扰动补偿不足;b0偏小,补偿量被放大,扰动被“过度补偿”,看起来就像加了一个反向扰动。 解决:先做一次开环阶跃测试反算b0,不依赖标称参数。具体做法是固定u为某常值,等对象输出变化率稳定,用Δ输出变化率除以u得到b0。另一个辅助手段是观察z3曲线,如果z3在稳态时明显偏离0,且方向与已知扰动相反,说明b0标定有问题。

4.4 连续仿真正常,离散化到控制器后性能劣化

现象:Simulink连续模型跑得很好,换成离散求解器或导出C代码后,闭环性能明显变差,甚至发散。 原因:ESO的离散化方式不对。很多人直接把连续状态方程用欧拉法离散,当ωo高、采样率低时,离散误差会产生相位滞后,扰动补偿变成扰动激励。另一个原因是ωo本身设计超过了采样频率的1/5。 解决:在仿真阶段就用定步长离散求解器,把采样周期设为实际控制器运行周期,别用连续模型验证完再改离散。ωo按小于ωs/5来设定,离散ESO建议用零阶保持器离散或直接采用文献里的离散扩张状态观测器形式,不要用简单的前向欧拉。

4.5 从汇总里拿A示例的ESO拼到B示例对象上,结果发散

现象:两份实例单独跑都正常,把第一份的ESO块复制到第二份的对象模型上,闭环直接发散。 原因:每个实例的b0基准不同,单位制不同,甚至状态变量的定义都不同。有的模型用标幺值,有的用国际单位,z3的物理意义从电流变成力矩,直接拼接必然出错。 解决:拿到任何汇总后先建一个“参数基准表”,记录每个示例的b0、对象增益、单位制、采样周期。拼接前先检查被控对象的输入量和输出量单位,确保b0对应的是“从u到被控量微分”的增益,而不是某个中间环节的增益。最后先跑通原始示例,验证环境,再做任何模块替换。

5. 用分离验证法给ADRC仿真做体检:一个能查出多数“跑得动但不对”的技巧

很多ADRC仿真的问题不是跑不通,而是跑出来的结果不能信。输出收敛了,但ESO的z3和真实总扰动差很大;抗扰效果有了,但换一组扰动幅值就失灵。这种“能跑但不对”的状态,最有效的排查方法是分离验证法,把ESO、反馈控制、扰动补偿三部分分别单独验证。

第一步验证ESO。把控制量u强制置0,给对象一个已知阶跃扰动,同时记录对象输出y和ESO的z3,把理论总扰动曲线与z3曲线画在同一张图里。如果两者幅值和趋势对不上,说明b0或ESO增益有问题。这里注意,理论总扰动可以通过对象模型离线反算,不需要实时求解。

第二步验证反馈控制。暂时把z3补偿断开,控制律只用u0除以b0,看纯PD闭环是否稳定。如果这一步系统就不稳定,问题在kp、kd或参考轨迹的过渡过程设计,跟扰动观测无关。

第三步验证补偿效果。接回z3补偿,观察抗扰性能是否明显改善。如果改善了但动态过程仍有残余振荡,多半是ESO的收敛速度不够,适当提高ωo;如果改善为零甚至变差,回到4.3检查b0。

还有一个习惯值得养成:拿到任何ADRC示例后,第一件事不是看波形,而是把z1、z2、z3的曲线全部拉出来,先看观测器是否先于控制器稳定。如果z3在系统达到稳态后仍然缓慢漂移,说明模型里有未补偿的非线性因素,比如摩擦力或间隙,这时候调整ωo意义有限,要把对象模型里的已知非线性项显式建模。这套验证流程虽然多花十分钟,但能帮你避开一半以上的ADRC仿真翻车。希望帮到你。

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

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

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

立即咨询