ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

自抗扰控制ADRC实战:从PID调参困境到一阶LADRC工程落地

2026/10/7 15:44:22 拓冰建站 浏览量
自抗扰控制ADRC实战:从PID调参困境到一阶LADRC工程落地 1. 从一个让人头疼的温控场景说起去年帮一个做小型热处理炉的朋友调温控炉子不大加热功率3kW热电偶反馈原本用的是经典PID。问题出在升温段设定值从室温直接跳到600℃PID输出瞬间饱和超调能冲到80℃以上等它慢慢回落再稳定下来一批工件的时间窗口已经错过了。更麻烦的是炉门偶尔要开一下放料一开一关温度掉个几十度PID重新追上去又是一次振荡。这个场景其实很典型被控对象有惯性、有延迟、有外部扰动而且设定值还会大范围跳变。经典PID在这种工况下不是不能用而是需要反复折中——调大比例带响应慢调小比例带超调大积分时间短了振荡长了消除静差又慢。工程师大部分时间花在“拆东墙补西墙”上。自抗扰控制ADRCActive Disturbance Rejection Control就是冲着这类问题来的。它的核心思路跟PID完全不同不去精确建模被控对象而是把对象内部所有说不清、道不明的动态加上外部扰动统统打包成一个“总扰动”然后用扩张状态观测器ESO实时估计它再在控制量里把它抵消掉。剩下的部分就变成一个近似积分串联型的简单系统用最简单的比例控制就能搞定。我第一次接触ADRC是看韩京清先生的那篇《从PID技术到“自抗扰控制”技术》当时觉得这套东西有点“反直觉”——不建模反而能控好后来在几个电机调速和温控项目里实际用下来发现它在抗扰、解耦、设定值跟踪这三个维度上的表现确实比调好的PID更省心。当然它也不是银弹参数多了、整定有门槛、工程化落地需要一些技巧。这篇内容就围绕ADRC这套算法从设计思路、核心模块拆解、参数整定、实操实现到常见坑完整讲一遍。适合已经用过PID、想找一个更抗扰方案的控制工程师也适合刚学ADRC、被那一堆公式绕晕的学生。我会尽量用生活化的类比把原理说清楚同时给出可以直接抄的代码和参数整定流程。2. ADRC整体设计思路与方案选型2.1 为什么放弃“精确建模”这条路传统控制里如果你要控好一个对象第一步通常是建模机理建模或者系统辨识拿到传递函数或者状态空间。然后基于模型设计控制器比如极点配置、LQR、内模控制。这套流程在对象清楚、扰动可控的场合非常有效。但工程现场往往不是这样。我做过一个伺服平台负载会换、摩擦会变、传动间隙随磨损增大你花两周辨识出来的模型过一个月就不准了。这时候基于模型设计的控制器性能会明显下降甚至不稳定。ADRC的哲学是与其花大力气去追一个永远追不准的模型不如承认“我不知道的部分”存在然后实时估计并补偿它。这个“不知道的部分”就是总扰动包括对象内部未建模动态比如高阶模态、非线性摩擦参数摄动质量变化、电阻随温度变化外部扰动负载突变、风扰、电网波动通道间耦合多变量系统里其他回路对本回路的影响把这些全部归入一个扩张状态用观测器估计出来控制量里减掉它系统就“净化”了。这个思路的好处是控制器设计不再依赖精确模型鲁棒性天然就强。2.2 ADRC与PID的本质区别很多人第一次看ADRC会觉得它就是“PID加了个观测器”。这个说法对了一半。区别在于维度PIDADRC误差处理直接对误差做比例、积分、微分用跟踪微分器安排过渡过程误差反馈用非线性或线性组合扰动处理积分项被动消除静差响应慢ESO主动估计并前馈补偿响应快微分信号直接差分噪声放大严重用TD或ESO提取噪声抑制好模型依赖不依赖模型但调参靠试不依赖精确模型但需要知道系统阶数和大致增益超调抑制靠调参折中TD安排过渡过程从源头减少超调最关键的一点PID的积分项是在误差出现之后才起作用属于“事后补救”ADRC的ESO是在扰动影响输出之前就估计出来属于“事前补偿”。这个时间差在快速性要求高的场合就是性能差距的来源。2.3 ADRC的典型结构选型标准ADRC由三部分组成跟踪微分器TD为设定值安排过渡过程提取微分信号扩张状态观测器ESO估计系统状态和总扰动非线性状态误差反馈NLSEF根据误差和扰动估计生成控制量工程上常见的几种变体线性ADRCLADRC把TD和NLSEF都线性化只保留ESO的扩张状态思想。参数少、整定有解析公式、频域分析方便是目前工业落地最多的形式。非线性ADRC保留fal函数等非线性环节性能潜力更大但参数多、整定靠经验。降阶ADRC针对一阶对象省掉TD直接用一阶ESO加比例控制结构极简。模型辅助ADRC如果知道对象的大致增益b0把它放进控制量里ESO只需要估计“剩余扰动”估计压力小性能更好。我个人的建议新手从一阶LADRC入手把ESO和b0这两个概念吃透再往上加TD和非线性环节。一阶LADRC能解决大部分温控、流量、压力这类一阶惯性对象的问题代码不到50行参数只有三个观测器带宽wo、控制器带宽wc、增益b0整定有公式可循。3. 核心模块拆解与实操要点3.1 跟踪微分器给设定值“踩刹车”设定值跳变是超调的主要来源之一。你让一个惯性系统瞬间追上一个大阶跃它必然冲过头。TD的作用就是把阶跃信号变成一条平滑的过渡曲线同时给出这条曲线的微分。生活类比你开车要停到车位如果一脚刹车踩死车会点头、乘客不舒服老司机是提前松油门、轻踩刹车让车平缓滑进去。TD就是那个“老司机”。最常用的TD形式是韩京清提出的非线性跟踪微分器x1(k1) x1(k) h*x2(k) x2(k1) x2(k) h*fhan(x1(k)-v(k), x2(k), r, h0)其中v是设定值x1跟踪vx2是v的微分估计r是速度因子越大跟踪越快h0是滤波因子越大滤波越强。实操要点r的选取r越大过渡过程越快但太大就失去“安排过渡”的意义。一般取r 4~10倍的控制带宽对应的值。我通常先取r100试看过渡时间是否合适再调。h0的选取h0一般取采样周期的5~20倍。太小滤波不够微分噪声大太大过渡过程变慢。离散实现fhan函数里有符号函数和饱和判断离散实现时要注意避免除零和数值抖动。如果你用LADRCTD可以简化成线性形式甚至直接用一个一阶惯性环节代替x1(k1) x1(k) h*(v - x1(k))/TT是过渡时间常数。这个形式更简单参数物理意义明确我实际用下来在温控场合完全够用。注意TD不是必须的。如果你的设定值本身就是缓变的或者你对超调不敏感可以省掉TD直接把设定值送进误差反馈。省掉TD后ADRC就退化成“ESO比例控制”结构更简单。3.2 扩张状态观测器ADRC的心脏ESO是整个ADRC最核心、也最值得花时间理解的部分。它的任务是根据控制量u和输出y估计出系统的状态x1、x2以及扩张状态x3总扰动。以二阶对象为例原系统可以写成x1 x2 x2 f(x1,x2,w) b0*u y x1其中f是总扰动b0是控制增益的估计值。把f扩张成状态x3得到x1 x2 x2 x3 b0*u x3 h y x1然后设计线性ESOe z1 - y z1 z2 - beta1*e z2 z3 - beta2*e b0*u z3 -beta3*ez1、z2、z3分别是x1、x2、x3的估计。beta1、beta2、beta3是观测器增益。参数整定有解析公式把ESO的特征方程配置成(swo)^3得到beta1 3*wo beta2 3*wo^2 beta3 wo^3wo是观测器带宽物理意义是“ESO跟踪扰动的速度”。wo越大估计越快但对噪声越敏感。工程上一般取wo 3~10倍的控制带宽wc。实操要点b0的选取b0是控制增益的估计值不需要精确但数量级要对。比如你的对象是G(s)K/(Ts1)b0大约取K/T。如果b0取大了控制量偏小响应慢取小了控制量偏大容易振荡。我一般先估算一个值然后在这个值上下调2~3倍看效果。离散实现用欧拉法离散时采样周期h要足够小一般h*wo 0.1否则离散化误差会导致ESO性能下降甚至发散。噪声处理如果输出噪声大可以在ESO前面加一个低通滤波器或者降低wo。我做过一个流量控制传感器噪声很大wo从50降到15才稳定下来。提示ESO的估计能力是有限的。如果总扰动变化太快超过wo的带宽ESO就跟不上。这时候要么提高wo但受噪声限制要么用模型辅助ADRC把已知部分前馈掉减轻ESO负担。3.3 状态误差反馈把估计的扰动“抵消掉”有了ESO的估计控制量就很好设计了。以二阶LADRC为例u0 kp*(v - z1) - kd*z2 u (u0 - z3)/b0其中v是设定值或TD的输出kp、kd是控制器增益。把u代入系统方程如果z3估计准确那么x2 f b0*u f u0 - z3 ≈ u0系统就变成了一个双积分串联型x1x2, x2u0。对这个简单系统用PD控制就能任意配置极点。参数整定把闭环特征方程配置成(swc)^2得到kp wc^2 kd 2*wcwc是控制器带宽决定响应速度。wc越大响应越快但控制量越大对执行器要求越高。实操要点wc和wo的关系一般wo 3~10倍wc。wo太小扰动估计跟不上补偿效果差wo太大噪声放大。我通常先定wc根据响应时间要求然后wo取5倍wc试。控制量限幅ADRC的输出u一定要限幅否则在设定值跳变或大扰动时u可能超出执行器范围导致积分饱和或执行器损坏。限幅值根据实际执行器能力定。抗积分饱和LADRC本身没有积分项但ESO的z3估计在限幅期间会累积误差。可以在限幅时暂停ESO更新或者用条件积分法处理。3.4 一阶LADRC最简可落地形式很多对象温控、流量、压力可以近似成一阶惯性y f b0*u这时候ADRC可以简化成e z1 - y z1 z2 - beta1*e b0*u z2 -beta2*e u (kp*(v - z1) - z2)/b0参数只有三个wo、wc、b0。整定公式beta1 2*wo beta2 wo^2 kp wc这个形式代码极短我下面给一个C语言实现可以直接移植到单片机或PLC里。typedef struct { float wo; // 观测器带宽 float wc; // 控制器带宽 float b0; // 控制增益估计 float z1; // 状态估计 float z2; // 扰动估计 float h; // 采样周期 float u_max; // 输出限幅 float u_min; } LADRC1; float ladrc1_update(LADRC1 *adrc, float v, float y) { float e adrc-z1 - y; float beta1 2 * adrc-wo; float beta2 adrc-wo * adrc-wo; // ESO更新 adrc-z1 adrc-h * (adrc-z2 - beta1 * e adrc-b0 * adrc-u_last); adrc-z2 adrc-h * (-beta2 * e); // 控制量计算 float u0 adrc-wc * (v - adrc-z1); float u (u0 - adrc-z2) / adrc-b0; // 限幅 if (u adrc-u_max) u adrc-u_max; if (u adrc-u_min) u adrc-u_min; adrc-u_last u; return u; }这段代码里有个细节ESO更新用的是上一拍的u_last而不是当前拍算出来的u。这是离散实现的标准做法保证因果性。如果你用当前拍的u会引入代数环可能导致数值问题。4. 完整实操流程与参数整定实录4.1 对象分析与阶数确定拿到一个对象第一步不是写代码而是确定用几阶ADRC。方法很简单给对象一个阶跃输入看输出响应。如果输出单调上升、没有明显过冲和振荡近似一阶用一阶ADRC。如果输出有S形、或者有振荡近似二阶用二阶ADRC。如果对象有纯延迟把延迟时间折算成等效惯性时间或者用Smith预估器补偿后再上ADRC。我那个热处理炉的例子阶跃响应是单调上升的时间常数大约300秒纯延迟约20秒。延迟相对时间常数很小直接按一阶处理b0取加热功率除以时间常数对应的增益。4.2 b0的估算方法b0是ADRC里唯一需要“知道一点对象信息”的参数。估算方法有三种机理法如果知道对象物理模型直接算。比如温控炉b0 P/(C*T)P是加热功率C是热容T是时间常数。阶跃法给一个已知阶跃u_step测输出稳态变化y_stepb0 ≈ y_step/(u_step*T)。T是时间常数。试凑法先取一个数量级差不多的值然后看控制效果。b0偏大响应慢、控制量小b0偏小响应快、控制量大、容易振荡。我一般用阶跃法简单可靠。实测下来b0允许有2~3倍的误差ADRC都能稳住这也是它鲁棒性的体现。4.3 带宽整定流程参数整定我总结了一个“三步法”第一步定wc。根据你对响应时间的要求。如果希望闭环响应时间约等于对象时间常数的1/5那么wc ≈ 5/T。比如T300秒wc ≈ 0.017 rad/s。实际调试时先取一个保守值然后逐步加大直到响应速度满意但控制量不超限。第二步定wo。wo 5~10倍wc。先取5倍看扰动抑制效果。如果负载突变后恢复慢加大wo如果控制量抖动明显减小wo。第三步微调b0。b0主要影响控制量的幅值。如果控制量长期饱和说明b0偏小适当加大如果控制量很小但响应慢说明b0偏大适当减小。下面是我在热处理炉上的一组实际参数参数数值说明采样周期h1s温控慢1秒足够wc0.02 rad/s响应时间约50swo0.1 rad/s5倍wcb00.8 ℃/(s·%)阶跃法估算u限幅0~100%加热器全开全关实测效果设定值从室温跳到600℃超调小于5℃稳定时间约120秒。开炉门扰动后温度掉30℃约40秒恢复。对比之前PID的超调80℃、恢复2分钟提升明显。4.4 离散实现与代码移植ADRC的离散实现有几个坑采样周期选择h要满足h*wo 0.1否则ESO离散化误差大。如果wo0.1h1秒我取1秒刚好。如果wo更大h要相应减小。数据类型单片机上用floatPLC上用REAL。注意z3可能累积到较大值要防止溢出。初始化z1初始化为当前输出yz2初始化为0u_last初始化为0。这样启动时不会有大跳变。抗饱和限幅时ESO的更新可以暂停或者把限幅前后的差值反馈回ESO。我用的是简单暂停法效果可以。移植到PLC的ST语言结构类似只是语法不同。关键是把ESO的差分方程写对注意运算顺序。4.5 与PID的对比测试为了验证ADRC的效果我在同一个炉子上做了对比测试指标PID调好的一阶LADRC超调量15%4%稳定时间180s120s开炉门恢复时间120s40s参数个数33调参时间2天半天PID的参数是花了2天反复折中调出来的ADRC半天就整定好了。这个对比不是说PID不好而是说在抗扰和设定值跟踪兼顾这个需求下ADRC的调参负担更小。5. 常见问题与排查技巧实录5.1 ESO估计发散怎么办这是新手最常遇到的问题。现象是z1、z2、z3越来越大控制量饱和系统失控。原因通常有三个h*wo太大离散化不稳定。解决减小h或减小wo。b0符号搞反如果b0应该是正你写成负ESO会往错误方向估计。解决检查b0符号确保u增大时y增大。输出反馈极性错误y的符号或量纲不对。解决检查传感器标定和接线。排查顺序先查b0符号再查h*wo最后查传感器。5.2 控制量抖动严重怎么处理抖动通常来自噪声。ESO的z3对噪声最敏感因为它是通过两次积分得到的。处理方法降低wo牺牲一点扰动估计速度换平稳。在y进入ESO之前加一阶低通滤波截止频率取wo的2~5倍。用非线性ESOfal函数对小误差有线性区能抑制噪声。我一般先加低通滤波简单有效。滤波会引入相位滞后但温控这种慢过程影响不大。5.3 设定值跟踪有静差LADRC理论上没有积分项但ESO的z3估计包含了稳态扰动补偿后静差应该为零。如果有静差检查z3是否收敛到了正确的扰动值。如果z3一直在变说明wo太小估计不准。b0是否准确。b0偏差会导致控制量标定错误产生静差。限幅是否长期生效。如果u长期饱和系统处于开环静差无法消除。5.4 多变量耦合怎么处理ADRC天然有解耦能力因为每个回路的ESO会把其他回路的影响当成扰动估计并补偿。但前提是每个回路的wo足够大能跟上耦合扰动的变化。如果耦合很强wo需要取很大可能受噪声限制。这时候可以考虑用模型辅助ADRC把已知的耦合项前馈掉。用分散ADRC加解耦补偿器。如果耦合特别强考虑多变量ADRC但参数整定复杂很多。5.5 常见问题速查表现象可能原因排查方法解决措施ESO发散h*wo太大检查h和wo乘积减小h或woESO发散b0符号错误检查b0正负修正符号控制量抖动噪声大观察y的噪声加低通滤波或降wo响应慢wc太小计算响应时间加大wc超调大无TD或wc太大观察设定值跳变响应加TD或减小wc静差z3未收敛观察z3波形加大wo或修正b0控制量饱和b0偏小观察u幅值加大b0恢复慢wo太小加扰动测试加大wo5.6 几个独家避坑技巧技巧一先开环测b0再闭环调参。不要一上来就闭环先用开环阶跃测出对象增益和时间常数算出b0这样闭环调试起点就准了。技巧二wo从大到小调。先取一个较大的wo看ESO估计是否快速跟上然后逐步减小到噪声可接受的程度。反过来调容易一开始就被噪声干扰。技巧三用z3的波形诊断。z3是总扰动的估计正常情况下应该平稳。如果z3大幅波动说明wo太大或噪声太大如果z3长期偏离零说明有稳态扰动未补偿。技巧四限幅值留余量。u限幅不要设到执行器极限留10%~20%余量给扰动补偿留空间。技巧五采样周期不要随意改。ADRC的参数和h是绑定的改了hwo和wc都要重新调。如果必须改h按比例调整wo和wc。6. 从一阶到高阶的扩展思路一阶LADRC能解决大部分慢过程的问题但如果你遇到的是伺服、无人机、机器人这类快速对象一阶就不够了。这时候需要二阶甚至高阶ADRC。二阶ADRC的结构在前面已经讲过参数整定公式是beta1 3*wo beta2 3*wo^2 beta3 wo^3 kp wc^2 kd 2*wc参数多了一个kd但整定逻辑和一阶一样先定wc再定wo最后微调b0。高阶ADRC三阶以上一般不建议用因为参数多、整定难、对噪声敏感。如果对象确实是高阶更好的做法是用降阶ADRC加一个前置滤波器或者用模型辅助ADRC把已知的高阶动态前馈掉。我在一个伺服转台项目上用过二阶LADRC对象是电机加负载有弹性连接近似二阶。wc取50 rad/swo取300 rad/sb0取电机转矩常数除以转动惯量。效果比PID好尤其是在负载变化时PID需要重新调参ADRC不用。7. 工程落地的一些个人体会ADRC这套东西理论文章很多但工程落地的细节往往没人讲。我踩过的坑里最大的一个是把b0当成“必须精确”的参数。早期我花大量时间辨识b0后来发现b0差2~3倍根本不影响稳定性只是控制量幅值有变化。ADRC的鲁棒性就体现在这里它不靠精确模型靠的是ESO的实时估计。第二个坑是wo取得太大。理论上wo越大估计越快但实际系统里噪声是无处不在的。wo大到一定程度z3就被噪声淹没控制量抖得没法用。我现在的习惯是先取一个理论值然后砍一半看效果再慢慢加。第三个坑是忽略执行器动态。ADRC算出来的u是理想控制量但执行器阀门、加热器、电机驱动器本身有延迟和饱和。如果执行器响应比ADRC带宽还慢整个闭环性能就被执行器限制了。这时候要么降低wc要么换更快的执行器。最后分享一个小技巧用Simulink先仿真再上实物。ADRC的代码不长但在实物上调试风险高。我一般先在Simulink里搭一个对象模型把ADRC代码用MATLAB Function块实现调好参数再移植到嵌入式。这样能省很多现场调试时间。这个内容后续还可以往几个方向扩展一是自适应ADRC让wo和wc根据工况自动调整二是ADRC和MPC的结合用ADRC做底层抗扰MPC做上层优化三是多变量ADRC的解耦设计。这些我还在摸索有新的心得再分享。