自抗扰控制(ADRC)仿真实例全解析:从原理到参数整定避坑指南 简介面向自动控制与电机驱动方向学习者的自抗扰控制ADRCSimulink仿真实例合集既能帮助刚接触ADRC的学生建立直观认识也为需要调试观测器和控制律的工程师提供了可直接运行的模型与对比素材。压缩包共62个文件、约67.32MB以15篇PDF文献、7个SLX仿真模型、12个MAT数据文件为主体另含CAJ论文、M脚本、DOCX技术文档、AVI演示录像及P文件等目录按LESO/NESO对比、PMSM双闭环、单轴云台、磁悬浮等主题划分便于按需查找。典型实例覆盖永磁同步电机速度与电流控制、单轴云台指向、上拉式磁悬浮等工程对象并通过线性扩展状态观测器与非线性扩展状态观测器、fhan与fsun两种非线性控制函数的对比展示不同扰动观测方式和非线性调节策略对控制性能的影响配套的调参脚本、技术笔记与PMSM专题文献可帮助读者理解ESO带宽、跟踪微分器以及抗扰性能之间的内在关系。该资源已有1715人学习适合需要快速搭建ADRC仿真环境并系统掌握其设计方法的自动化、电气工程相关专业学生及工程师。1. 自抗扰控制仿真实例到底“全”在哪里一个能直接复现的参数库自抗扰控制ADRC的仿真实例网上其实不少但真正称得上“很全”的很少要么藏在论文里只给波形不给参数要么给了一组参数但换一个被控对象就发散。这篇笔记把我这几年在设备控制仿真里反复验证过的 ADRC 实例按对象难度汇总起来一阶、二阶、纯时滞、非线性对象全都有可抄的模型和参数。适合正在做控制系统仿真、打算把 PID 换成 ADRC 试水的工程师也适合被导师丢给“自抗扰控制”课题但不知道从哪下手的初学者。看完你应该能回答三个问题这东西到底解决什么问题参数从哪来仿真里最常见的翻车点怎么避开。2. 自抗扰控制的核心逻辑为什么模型给不准也能压住扰动2.1 总扰动的概念把“模型不准”变成可观测的状态ADRC 最反直觉的一点是它不追求精确的模型反而故意把模型偏差当成扰动的一部分。常规 PID 是看见误差再消除误差而 ADRC 是把“外扰 模型偏差 内部耦合”打包成一个总扰动 f然后用扩张状态观测器把这个 f 实时估出来在控制量里直接补偿掉。这意味着你不需要知道对象的精确微分方程只需要知道一个大致的控制增益 b0 就行剩下的差值全部算进总扰动里。比如一个一阶对象实际是 dot y 6.25 u d但你在控制器里写的增益是 b0 5那么 1.25 u 这个偏差就会被 ESO 当成扰动的一部分估计出来。只要 ESO 收敛够快这个偏差就不会破坏闭环稳定性。这一点和自适应控制、鲁棒控制的思路都不一样ADRC 不调整模型参数而是绕开模型直接估计影响。从实用角度看这个特性非常值钱。工业现场里你拿到的对象模型往往是辨识得到的低频增益能对个七八成就不错了加上执行机构老化、负载变化模型失配是常态。ADRC 允许 b0 有偏差还能稳定工作这比 PID 整定对工况变化的容忍度高得多。2.2 ESO 到底在观测什么二阶对象的扩张状态方程扩张状态观测器的“扩张”二字指的就是把总扰动 f 当成一个新的状态变量加进原始状态方程。以二阶对象 dot x1 x2dot x2 a x1 b x2 b0 u f 为例ESO 的方程写作dot z1 z2 - beta1 (z1 - y) dot z2 z3 b0 u - beta2 (z1 - y) dot z3 -beta3 (z1 - y)其中 z1 跟踪输出 yz2 跟踪速度 x2z3 跟踪总扰动 f。三个增益 beta1、beta2、beta3 决定观测器收敛速度和噪声放大程度。这里没有玄学它就是 Luenberger 观测器套在扩张系统上只不过把“标称模型”换成“标称增益 b0 未知扰动 f”。注意 ESO 的输入是控制量 u 和输出 y不依赖对象微分方程的精确参数所以它天然适合模型不准的场合。代价是 ESO 本身有带宽限制离散化步长太大或者物理量测噪声太强z3 会抖得很厉害。这部分我在第 5 章避坑清单里会专门展开。2.3 三块结构如何配合安排过渡过程、估计扰动、误差反馈完整 ADRC 通常由三块组成跟踪微分器 TD、扩张状态观测器 ESO、非线性状态误差反馈 NLSEF。TD 的作用是把突变的阶跃给定变成平滑的过渡信号避免一开始就把控制量打满ESO 负责估计总扰动误差反馈则对输出误差做比例和微分组合。工程上我很少用真正的“非线性”反馈因为非线性反馈的增益难调、离散化后容易振铃。大多数场景用线性形式就够也就是常说的 LADRC反馈增益只留两个系数 k1 wc^2k2 2 wc观测器增益用 beta1 3 wobeta2 3 wo^2beta3 wo^3。这里的 wc 是控制器带宽wo 是观测器带宽。我一般会给团队定一个默认选型标准对象模型失配在 50% 以内、扰动变化不太剧烈、没有明显的量测噪声全部先用 LADRC只有要求大范围跟踪或者被控对象是明显非线性比如带摩擦、带间隙时才考虑加 TD 和非线性反馈。因为 LADRC 只有 wo、wc、b0 三个参数仿真阶段一周就能摸熟而完整 ADRC 牵扯到 TD 的速度因子和非线性参数的幂次调参时间成倍增加。3. 从零搭一个最小 ADRC 仿真MATLAB 和 Python 两套可跑代码3.1 用 MATLAB 脚本跑通一阶对象的最小 LADRC先上一段可以直接复制进 MATLAB 的脚本对象是一阶惯性加一个阶跃扰动。这段代码我习惯作为所有仿真的起点换对象只改三行参数。% adrc_minimal.m —— 一阶惯性对象的最小 LADRC 仿真 h 0.001; % 固定步长 1ms t 0:h:6; % 仿真 6 秒 N length(t); K 5.0; T 0.8; % 被控对象 G(s) 5/(0.8s1) B_ACT K / T; % 对象实际增益 6.25 b0 B_ACT * 1.2; % 控制器故意留 20% 失配 wc 8.0; wo 30.0; % 控制器/观测器带宽 beta1 2 * wo; beta2 wo * wo; % 一阶 ESO 两个增益 kp wc; % 一阶反馈比例增益 x1 0; x2 0; % 对象状态x1 是输出x2 是扰动 z1 0; z2 0; % ESO 估计状态 u 0; r 1; % 控制量和阶跃给定 y_hist zeros(1, N-1); for k 1:N-1 d 0.5 * (t(k) 2.0); % 第 2 秒加入阶跃扰动 x1 x1 h * (B_ACT * u d); % 欧拉法更新对象 y x1; e z1 - y; z1 z1 h * (z2 b0 * u - beta1 * e); z2 z2 h * (-beta2 * e); u (kp * (r - z1) - z2) / b0; % LADRC 控制律 y_hist(k) y; end plot(t(1:end-1), y_hist); grid on;这段代码里最容易被抄错的是控制律。u (kp * (r - z1) - z2) / b0注意 kp 这一项也要除以 b0这样闭环回路增益才等于 kp 本身。如果写成 u kp * (r - z1) - z2 / b0系统的实际闭环带宽会变成 b0 * kp当你 b0 和真实增益偏差较大时阶跃响应快慢会和你预期的 wc 完全对不上。这个坑出现在很多入门笔记里调试时第一眼看响应速度不对先回来检查这一条。参数说明wc 8 意味着期望闭环时间常数约 1/8 秒阶跃响应大概 0.5 秒进稳态wo 30 让 ESO 比控制器快 3 到 5 倍才能把扰动在影响输出之前就补偿掉。b0 故意设成真实增益的 1.2 倍用来模拟模型失配仿真结果依然能回到给定值说明 ESO 把差值当扰动处理了。3.2 用 Python 对照实现无 Simulink 环境下跑通同一套逻辑很多团队没有 MATLAB 授权或者只想快速验证算法用 Python 加 numpy 就够了。代码逻辑和 MATLAB 版本完全一致只是改成了 numpy 数组循环。import numpy as np import matplotlib.pyplot as plt h 0.001 t np.arange(0, 6 h, h) N t.size K, T 5.0, 0.8 B_ACT K / T b0 B_ACT * 1.2 wc, wo 8.0, 30.0 beta1 2 * wo beta2 wo * wo kp wc x1, x2 0.0, 0.0 z1, z2 0.0, 0.0 u 0.0 r 1.0 y_hist [] for k in range(N - 1): d 0.5 if t[k] 2.0 else 0.0 x1 x1 h * (B_ACT * u d) y x1 e z1 - y z1 z1 h * (z2 b0 * u - beta1 * e) z2 z2 h * (-beta2 * e) u (kp * (r - z1) - z2) / b0 y_hist.append(y) plt.plot(t[:-1], y_hist) plt.grid(True) plt.show()跑出来的曲线应该是0 到 2 秒输出平滑接近 12 秒时受扰动出现一个小低谷或小峰然后在 0.5 秒以内回到 1。如果看不到这个特征先检查 beta1、beta2 是不是按 wo 计算的再看采样步长 h 和 wo 的乘积是否小于 0.2。对比两个版本除了语言差异外几乎没有区别。我建议仿真验证阶段先用 Python 做批量调参因为方便写循环自动搜索 wo 和 wc定稿后再把最终参数搬进 MATLAB 做 Simulink 联调。这样只维护一份算法逻辑不会两边调出两套结论来。4. 仿真实例汇总一阶、二阶、时滞到非线性对象的关键参数4.1 一阶惯性对象实例参数表与波形验证点一阶惯性对象是最简单的验证对象适合入门也适合快速验证 ESO 的补偿效果。典型模型是 G(s) K / (T s 1)状态方程 dot y (K/T) u f对应一阶 LADRCbeta1 2 wobeta2 wo^2控制律只保留比例项加扰动补偿。对象参数KTb0 取值wcwo采样步长 h快速小惯性50.8K/T 上下浮动 20%8300.001慢大惯性25.0K/T 上下浮动 20%2100.001带积分环节3036250.001第三个例子是 G(s)3/s也就是对象本身带积分这在电机转速控制里很常见。ESO 的 z2 会估计掉残余扰动控制律同样能压住静差。验证时看两个点第一2 秒加阶跃扰动后输出能否在约 4 倍观测器带宽时间内恢复第二b0 改为真实值的 60% 和 150% 分别仿真曲线不应该发散。4.2 二阶位置控制实例让系统按期望动力学走二阶对象是机械位置控制的常见模型比如 dot x1 x2dot x2 a x1 b x2 b0 u f。典型参数 a -25b -2b0 10仿真里给定的阶跃目标从 0 到 12 秒时加一个幅值 1 的推力扰动。这组实例必须用三阶 ESObeta1 3 wobeta2 3 wo^2beta3 wo^3。控制器用两组反馈系数k1 wc^2k2 2 wc。控制律写成u (k1 (r - z1) k2 (0 - z2) - z3) / b0其中 z2 是速度估计给定速度通常是 0所以直接写成 k2 * (0 - z2)。如果直接忽略掉速度反馈系统会变成欠阻尼阶跃爬升慢而且容易超调。验证时加一个尖峰扰动观察 z3 的估计波形应该能在输出还没明显变化时就出现一个反向补偿脉冲这就是 ESO 的前馈效果。参数锚点我通常给 wc 6wo 3 * wc也就是 wo 取 18。如果对象本身阻尼很弱比如 b 0wc 要降到 4 左右如果阻尼强wc 可以放到 10。位置控制里最忌讳一上来把 wc 拉到 10 以上二质量系统在 10 赫兹以上会出现结构谐振ESO 会把谐振也当成扰动硬补效果反而更抖。4.3 带纯时滞的对象实例能控但有边界时滞是 ADRC 最容易让人误判的场景。模型写成 G(s) e^{-tau s} * K / (T s 1)比如 tau 0.5K 5T 0.8。用同一组一阶 LADRC 参数仿真的话wc 8 会直接振荡。原因不是 ESO 失效而是 ESO 根据当前输出估计扰动但扰动经过时滞才反映到输出上ESO 看到的“当前扰动”其实是 0.5 秒之前的补偿时机晚了。时滞 tauwc 上限参考wo 参考现象0.1830接近无时滞效果0.52.515有小超调能稳定1.01.28响应慢但优于同带宽 PID我的处理习惯是tau 不超过对象时间常数的 20% 时ADRC 直接用tau 大到和 T 同量级时必须降低 wc并把仿真中的阶跃给定改成斜坡否则控制量一开始就会大幅摆动。更激进的做法是搭配 Smith 预估器但那是另一个方案不是 ADRC 默认配置。仿真实例里我一般先对比“低带宽 ADRC”和“低带宽 PID”结论通常是 ADRC 恢复扰动更快但在大时滞下优势明显缩水。4.4 非线性与模型失配实例ESO 的补偿上限在哪里非线性实例最能体现 ADRC 的价值。常见的是二阶系统加上库仑摩擦dot x2 a x1 b x2 b0 u - 2 * sign(x2) d。其中 sign(x2) 产生的摩擦力矩是状态相关的非线性传统线性 PID 在低速跟踪时会出现极限环振荡。用同一个三阶 LADRC参数维持 wc 4wo 16不需要针对摩擦专门建模。观察 z3 的波形它会稳定在一个接近负 2 的均值附近这就是 ESO 把摩擦辨识成常值扰动并完成补偿。输出曲线的表现是最终没有静差低速时不再爬行。这里可以明显看到“模型给不准也能控”的实际意义。另一个更苛刻的边界是 b0 本身变化。比如真实增益在 8 和 12 之间跳变而控制器固定 b0 10这种情况 ESO 能补偿缓慢变化但如果增益每 0.1 秒跳变一次ESO 带宽跟不上输出就会明显波动。遇到这场景我没有捷径要么提高 wo 到极限要么改成在线辨识 b0单纯靠 ESO 硬扛是不行的。仿真里可以这样设计把 b0 的跳变周期设成 0.5 秒观察 z3 和输出的变化幅度你就摸到 ADRC 的补偿上限了。5. 仿真实战避坑清单5 条让结果变形的隐藏问题5.1 现象一上仿真就发散波形直接炸到 1e6 量级原因基本是采样步长 h 与 ESO 带宽 wo 的乘积超过了数值稳定性边界。欧拉法离散 ESO 时稳定性要求 wo * h 小于大约 0.3。wo 取 30 时 h 必须小于 0.01很多人图省事直接把 Simulink 默认步长记在 0.01 以上配上 wo 50一跑就发散。解决办法是先定 h再反推 wo 上限我一般要求 wo * h 0.1留三倍裕量这样 z3 也不会因为离散误差抖动。5.2 现象ESO 估计的 z3 明显滞后实际扰动补偿总慢半拍滞后通常来自 wo 太低或者量测输出经过了一阶滤波。如果你在反馈通道加了低通滤波滤波时间常数为 0.02 秒而 wo 是 20滤波器的相位延迟已经超过 ESO 的响应速度z3 自然跟不上。解决方法是把滤波器的截止频率设到 5 倍 wo 以上或者把滤波器模型也引入 ESO 的参考对象让它知道自己观测的是滤波后的输出。真实工程里没有“无滞后测量”做仿真时加滤波器再调参比直接不加滤波更接近实际。5.3 现象控制量高频振荡但输出波形看着还行常见原因是 g 或者是非线性反馈里的指数幂放大了噪声。线性 LADRC 场景下通常是 wo 取太高ESO 把量测噪声当成了扰动在补偿。比如 wo 100 配上 h 0.001理论上稳定但加入白噪声后 z3 的方差会放大到上百控制量就像锯齿一样。解决办法是先画 z3 波形如果 z3 抖成随机噪声形状就降低 wo直到 z3 只能看到阶跃扰动、看不到噪声为止。记住观测器不是越快的越好够用就行。5.4 现象阶跃响应超调很大但改小 wc 又变慢这是典型的没有配 TD 或者过渡过程没有限制控制量变化率。ADRC 在线性范围内能直接把误差拉回来但对象有执行机构饱和时控制量一旦顶到上限闭环就变成开环超调随之而来。解决办法是在仿真里加入饱和模块并且把 ESO 输入 u 取成饱和后的实际控制量而不是控制器输出的原始控制量。如果加了饱和仍超调就把给定信号从阶跃换成斜坡或者安排过渡过程这是 TD 存在的意义不是 ADRC 的缺陷。5.5 现象同一组参数Simulink 跑的和手写脚本跑的结果对不上原因基本是求解器差异。手写脚本是固定步长欧拉法Simulink 默认变步长可能是 ode45两者的局部误差和离散误差不一样特别是 ESO 这种强耦合系统波形形状可能一样但超调量差 2% 到 3%。解决方法是把 Simulink 求解器强制改成固定步长离散求解器并设置与手写脚本相同的 h对比前先统一离散化方式和步长。这个坑看起来小实际上一卡就是半天我见过有人因此误判参数鲁棒性白白浪费了一周的时间。6. 参数整定的进阶技巧用带宽法快速锚定一组可用参数1.1 从期望响应时间反推 wc再用倍数关系套 wo 和 b0带宽法的核心是三个参数不孤立地调。先确定闭环想要的调节时间 Ts按经验取 wc 4 / Ts比如希望 0.8 秒进稳态wc 就是 5然后 wo 直接取 3 到 5 倍的 wc先别管最优先用 3 倍跑出第一个曲线。b0 则是被你控对象物理模型给出的名义增益一般取辨识值或者铭牌值偏差 50% 以内都允许。注意这里有个反直觉的约束wo 越大补偿越快但采样步长、量测噪声、对象未建模动态都会限制它所以 wo 的上限不是由性能决定而是由系统里最薄弱的环节决定。实际仿真里我习惯把 wo 逐步翻倍直到控制量出现抖动然后退回一半作为最终值这比理论计算更快。参数整定的顺序是定 b0标 wc再拉 wo最后回头调 b0 的 20% 微调。不要反着来反着调会陷入毫无边界的搜索循环。1.2 一套仿真验证套路阶跃加扰动联合实验测三个指标不要只跑一个阶跃响应就宣布参数可用。我的习惯是每调一组参数就跑三个实验第一是 0 到 1 的阶跃记录超调量、峰值时间和调节时间第二是在 2 秒时加入一个已知幅值的阶跃扰动记录输出最大偏差和恢复到 5% 误差带的时间第三是把 b0 改成原始值的 0.7 倍和 1.4 倍分别再跑前两个实验对比曲线差异。三组实验都通过才敢说这组参数有工程意义。我最后一次在模拟项目X里调位置环把 wc 从 8 拉到 10 时阶跃曲线很好但扰动恢复时间翻倍原因就是 wo 跟不上新的 wc后来把 wo 从 25 提到了 35 才两难全解。这件事让我养成了习惯任何参数改动都至少跑一次扰动实验不要只看阶跃波形。仿真阶段代价为零这部分花的时间最后都会在联调阶段省回来。希望帮到你。本文还有配套的精品资源点击获取