A
ADRC 从零到系统理解
控制理论 · 从直觉到实现

从零开始
系统理解 ADRC

这不是一份只堆公式的笔记。我们从“为什么传统控制会被模型误差和扰动难住”讲起, 一步一步建立总扰动、扩张状态、ESO、控制律、LADRC 带宽整定以及数字实现。

1. ADRC 到底想解决什么?

控制器最怕的不是“系统有动态”,而是:我们不知道真实动态到底是什么,而且它还会变化。

模型误差

算出来的模型不等于真实对象

摩擦、死区、柔性、温漂、负载变化,往往没有被准确写进模型。

外部扰动

环境会突然改变系统

负载突变、风扰、冲击、供电波动,都可能让原本稳定的控制效果变差。

参数变化

今天的参数未必等于明天

质量、转动惯量、电阻、增益等,会随工作状态和时间变化。

传统思路 尽可能准确建模,然后按模型设计控制器。
ADRC 思路 不强求知道所有细节,而是在线估计“这些未知因素合起来造成了多大影响”,然后实时补偿。

2. ADRC 的一句话核心思想

\[ \boxed{\text{把未知动态与外部扰动统一看成总扰动,在线估计,再主动抵消}} \]

这个思路可以拆成三个动作:

看目标参考输入 \(r\)
看系统测量输出 \(y\)
估计未知影响ESO 得到 \(\hat F\)
主动补偿控制量中减去 \(\hat F\)
关键认识 ADRC 不是“完全不要模型”。它通常仍需知道系统大致阶次、控制方向,以及输入增益的估计值 \(b_0\)。 更准确地说,它是弱模型依赖

3. ADRC 的完整结构

先不要急着背公式。你可以先把 ADRC 看成一条非常清晰的“信息流”: 目标信号进入 → 形成期望轨迹 → 和估计状态比较 → 得到基础控制量 → 用扰动估计补偿 → 驱动对象 → 再用输出修正估计。

经典 ADRC 通常包含三个部分:

TD

跟踪微分器

把参考输入 \(r\) 变成更平滑、更可跟踪的信号 \(v_1\),并给出其导数 \(v_2\)。

ESO

扩张状态观测器

根据输出 \(y\) 和输入 \(u\),估计系统状态 \(z_1,z_2,\dots\) 以及总扰动 \(z_{n+1}\)。

SEF / NLSEF

状态误差反馈

根据误差 \(e_1=v_1-z_1,\ e_2=v_2-z_2\) 生成基础控制量 \(u_0\),再进行扰动补偿。

3.1 大框架:ADRC 在回路里做什么

先只记一件事:ADRC 站在参考输入和被控对象之间,比传统控制器多做了一步—— 先估计出对象受到的总扰动,再把它从控制量里减掉

参考 r ADRC 控制器 ① 在线估计总扰动 ② 在控制量中主动抵消 u 被控对象 ÿ = F + b₀·u 真实动态未知 总扰动 F = 未建模动态 + 外扰 + 参数变化 y 测量输出 y 反馈给控制器 前向控制通道 测量反馈通道 扰动与不确定性

图中字母的含义

符号名称说明
\(r\)参考输入你希望输出达到的目标值,由外部给定。
\(u\)控制量控制器最终施加到对象上的输入,也是执行器实际执行的量。
\(y\)测量输出传感器测到的对象输出,含噪声,是回路里唯一能直接拿到的真实信息。
\(\ddot y\)输出的二阶导数二阶对象的最高阶导数。图中 \(\ddot y=F+b_0u\) 就是 ADRC 的标准形式。
\(F\)总扰动真实存在但不可测。把未建模动态、外部扰动、参数变化、增益误差全部打包成的一项。
\(b_0\)输入增益估计控制器唯一需要人为给定的模型参数,是真实增益 \(b\) 的粗略估计。
大框架只有三种线 蓝色是前向控制通道 \(r\to u\to y\);绿色是测量反馈通道,把真实输出送回控制器; 红色是所有不确定性汇总成的总扰动 \(F\)。传统控制器只有蓝、绿两条,ADRC 多了“对红色这一项做估计并抵消”的能力。

3.2 详细框架:把控制器方块打开

把上图中的“ADRC 控制器”展开,就得到下面的完整结构:TD 负责整理目标,SEF 负责生成基础控制量, ESO 负责估计状态与总扰动,补偿节点负责把扰动估计减掉。

参考 r TD 跟踪微分器 输出 v₁, v₂ v₁, v₂ SEF / NLSEF e₁ = v₁ − z₁ e₂ = v₂ − z₂ u₀ = kp·e₁ + kd·e₂ u₀ Σ 1 / b₀ + 输出限幅 u 被控对象 ÿ = f + b·u 输出 y 外扰 w、参数变化、未建模动态 测量输出 y 实际控制量 u ESO 扩张状态观测器 e₀ = y − z₁ ż₁ = z₂ + β₁·e₀ ż₂ = z₃ + b₀·u + β₂·e₀ ż₃ = β₃·e₀ z₁ ≈ y,z₂ ≈ ẏ,z₃ ≈ F(总扰动) 比对象阶次多一阶,多出来的状态就是总扰动 估计状态 z₁, z₂ 送去构成误差 扰动估计 z₃ 在此被减掉 前向控制通道 测量信号送给 ESO 状态与扰动估计 扰动与不确定性
先记住三个字母前缀,这张图就不会看错 \(v\) 是“想要的”——TD 给出的期望轨迹; \(z\) 是“估计的”——ESO 算出来的估计值,不是真实值,也不是测量值\(e\) 是“差出来的”——期望与估计之差,或测量与估计之差。 带下标 0 的 \(b_0,u_0\) 表示“标称的、补偿之前的”量。

信号:图中每个字母是什么

符号含义性质补充说明
\(r\)原始参考输入外部给定可以是阶跃、斜坡或任意指令。
\(v_1\)平滑后的期望轨迹TD 输出,期望值把突变的 \(r\) 变成对象追得上的轨迹。
\(v_2\)期望轨迹的导数TD 输出,期望值\(v_2\approx\dot v_1\),供速度误差使用,避免直接对 \(r\) 求导。
\(y\)对象实际输出真值 + 噪声,可测回路中唯一直接测到的量。
\(\dot y\)输出的真实导数真值,通常不可测正因为测不到,才要用 ESO 估出 \(z_2\)。
\(F\)总扰动真值,不可测\(F=f+(b-b_0)u\),见第 4 章。
\(w\)外部扰动真值,不可测只是 \(F\) 的一部分,不等于 \(F\)。
\(z_1\)对 \(y\) 的估计ESO 输出,估计值\(z_1\approx y\),相当于滤波后的输出。
\(z_2\)对 \(\dot y\) 的估计ESO 输出,估计值\(z_2\approx\dot y\),代替差分求导。
\(z_3\)对 \(F\) 的估计ESO 输出,估计值整个 ADRC 的核心,就是它被减到控制量里。
\(e_0\)观测误差ESO 内部信号\(e_0=y-z_1\),观测器靠它自我校正。
\(e_1\)位置误差SEF 内部信号\(e_1=v_1-z_1\)。注意用的是 \(z_1\) 而不是 \(y\)。
\(e_2\)速度误差SEF 内部信号\(e_2=v_2-z_2\)。
\(u_0\)基础控制量SEF 输出补偿之前的控制量,只管“跟踪”,不管“抗扰”。
\(u\)实际控制量施加到对象\(u=(u_0-z_3)/b_0\),再经限幅后输出。

参数:需要你来定的量

符号含义怎么来的
\(b\)对象真实输入增益真值,未知。它和 \(b_0\) 的差值会自动进入 \(F\)。
\(b_0\)输入增益估计人为设定,只要符号正确、数量级合理即可。
\(k_p,\ k_d\)状态误差反馈增益由控制器带宽决定:\(k_p=\omega_c^2,\ k_d=2\omega_c\)。
\(\beta_1,\beta_2,\beta_3\)观测器增益由观测器带宽决定:\(3\omega_o,\ 3\omega_o^2,\ \omega_o^3\)。
\(\omega_c\)控制器带宽决定系统“跑多快”,见第 11 章。
\(\omega_o\)观测器带宽决定观测器“看多快”,一般取 \((3\sim5)\omega_c\)。
按这个顺序读第二张图 ① 参考 \(r\) 经 TD 变成平滑轨迹 \(v_1,v_2\); ② SEF 把 \(v_1,v_2\) 与估计状态 \(z_1,z_2\) 作差,得到基础控制量 \(u_0\); ③ 补偿节点减去扰动估计 \(z_3\),再乘 \(1/b_0\)、限幅后得到真正施加的 \(u\); ④ ESO 同时拿到实际输入 \(u\) 和测量输出 \(y\),反过来修正 \(z_1,z_2,z_3\)。 若 \(z_3\approx F\),则 \(\ddot y\approx u_0\),复杂对象被“整理”成双积分器。
两张图的关系 第一张图里的“ADRC 控制器”方块,等于第二张图里 TD + SEF + Σ + \(1/b_0\) + ESO 的全部内容。 第一张图用来记住思想,第二张图用来对照写代码。

3.3 详细框图里每条线代表什么

下面六张卡片用通用阶次记号:\(n\) 阶对象配 \(n+1\) 阶 ESO,多出来的那个状态记作 \(z_{n+1}\)。 二阶时 \(z_{n+1}\) 就是上图里的 \(z_3\)。

1)\(r \rightarrow TD\)

原始参考输入 \(r\) 进入 TD。TD 输出更平滑的参考轨迹 \(v_1\) 和它的导数 \(v_2\)。

2)TD \(\rightarrow\) Feedback

反馈器并不一定直接拿 \(r\) 做控制,而是拿 TD 给出的 \(v_1,v_2\) 做“想要达到的状态”。

3)ESO \(\rightarrow\) Feedback

ESO 提供 \(z_1,z_2,\dots,z_n\),它们是对象状态的估计值。反馈器根据这些量形成误差 \(e_1,e_2,\dots\)。

4)Feedback \(\rightarrow u_0\)

反馈器先产生“基础控制量” \(u_0\)。这个时候还没有补偿未知扰动。

5)ESO \(\rightarrow\) 补偿节点

ESO 给出总扰动估计 \(z_{n+1}\approx F\)。控制器在求实际输入 \(u\) 时把这部分减掉,从而主动抗扰。

6)Plant \(\rightarrow y\rightarrow ESO\)

对象输出 \(y\) 回送给 ESO,ESO 再结合实际控制输入 \(u\) 修正状态与扰动估计。

\[ \boxed{ \text{ADRC 的主逻辑:} \quad r \xrightarrow{\text{TD}} (v_1,v_2) \xrightarrow{\text{Feedback}} u_0 \xrightarrow{\text{扰动补偿}} u \xrightarrow{\text{Plant}} y \xrightarrow{\text{ESO}} (z_1,z_2,\dots,z_{n+1}) } \]

如果只讨论 LADRC,第二张图还能进一步简化:TD 可以弱化甚至省略,Feedback 改成线性 P/PD, ESO 改成线性 ESO,最终结构会更简洁。

4. 最关键的一步:定义“总扰动”

以常见二阶对象为例:

\[ \ddot y=f(y,\dot y,t,w)+bu \]

其中 \(f(\cdot)\) 可以包含:

  • 对象内部未知动态;
  • 非线性、摩擦和耦合;
  • 外部扰动 \(w\);
  • 参数变化。

我们只选一个大致的输入增益 \(b_0\),把原式改写为:

\[ \ddot y = \underbrace{f+(b-b_0)u}_{F} + b_0u \]

定义:

\[ \boxed{F=f+(b-b_0)u} \]

于是:

\[ \boxed{\ddot y=F+b_0u} \]
这一步为什么强大? 因为 \(F\) 不只代表外部扰动。模型错误、参数不准、未建模动态,甚至 \(b_0\) 选得不完全准确, 都可以被一起装进 \(F\)。
自测:如果真实输入增益是 \(b\),而控制器使用的是 \(b_0\),两者差异去哪了?
进入总扰动中的 \((b-b_0)u\)。

5. TD:为什么目标信号也要处理?

如果参考输入从 0 突然跳到 1,理想导数在跳变时刻非常大。 直接把这种指令送进高增益控制器,容易引起控制冲击、饱和或机械振动。

TD 的任务通常有两个:

平滑参考轨迹

生成平滑的 \(v_1\),让系统不必瞬间完成不可能的动作。

获得参考导数

同时给出 \(v_2\approx \dot v_1\),供速度误差反馈使用。

一个便于理解的线性二阶 TD 可以写成:

\[ \begin{cases} \dot v_1=v_2\\ \dot v_2=-2\omega_t v_2-\omega_t^2(v_1-r) \end{cases} \]

它本质上是一个临界阻尼二阶跟踪系统:

\[ (s+\omega_t)^2 \]
初学建议 学 LADRC 时可以先把 TD 暂时拿掉,令 \(v_1=r\)、\(v_2=\dot r\),先集中理解 ESO 和扰动补偿。 等主干理解清楚,再回来学习 TD。

6. ESO:把扰动当成一个“看得见的状态”

对二阶系统:

\[ \ddot y=F+b_0u \]

定义扩张状态:

\[ x_1=y,\qquad x_2=\dot y,\qquad x_3=F \]

则系统变为:

\[ \begin{cases} \dot x_1=x_2\\ \dot x_2=x_3+b_0u\\ \dot x_3=h\\ y=x_1 \end{cases} \]

这里 \(h=\dot F\) 未知。ESO 的目标不是知道 \(h\),而是通过测量误差不断校正, 让 \(z_1,z_2,z_3\) 分别逼近 \(x_1,x_2,x_3\)。

三阶线性 ESO

定义观测误差:

\[ e_o=y-z_1 \]
\[ \begin{cases} \dot z_1=z_2+\beta_1e_o\\ \dot z_2=z_3+b_0u+\beta_2e_o\\ \dot z_3=\beta_3e_o \end{cases} \]

\(z_1\)

输出估计,\(z_1\approx y\)

\(z_2\)

速度估计,\(z_2\approx \dot y\)

\(z_3\)

总扰动估计,\(z_3\approx F\)

ESO 不是魔法 它能估计的前提是:系统可观测、采样足够快、噪声不过分、总扰动变化速度在观测器能力范围内。

7. 控制律:先控制,再把扰动抵消

先设计一个“理想情况下”的基础控制量:

\[ u_0=k_p(r-z_1)+k_d(\dot r-z_2) \]

然后使用 ESO 给出的扰动估计 \(z_3\) 进行补偿:

\[ \boxed{u=\frac{u_0-z_3}{b_0}} \]

代入对象:

\[ \ddot y=F+b_0u =F+b_0\frac{u_0-z_3}{b_0} =u_0+(F-z_3) \]

当 ESO 估计准确,即 \(z_3\approx F\) 时:

\[ \boxed{\ddot y\approx u_0} \]
最核心的理解 一个复杂、非线性、受扰动的对象,在补偿后被“整理”为近似二重积分器。 接下来只需要用简单 PD 配置想要的闭环动态。

为什么经典 LADRC 常常不用积分 I?

因为恒定或缓慢变化的扰动由 \(z_3\) 直接估计并补偿,不必再依赖误差积分慢慢累积补偿量。 同时,PD 可以保持干净的二阶闭环:

\[ s^2+k_ds+k_p \]

加入积分后会变成三阶:

\[ s^3+k_ds^2+k_ps+k_i \]

因此极点配置、参数解释和抗饱和处理都会更复杂。

8. LADRC:把 ADRC 变得更容易调

原始 ADRC 常使用非线性 ESO、非线性反馈和非线性 TD。 LADRC 则把关键环节线性化,并用带宽统一参数化。

项目经典 ADRCLADRC
观测器可用 fal 等非线性函数线性 ESO
反馈非线性状态误差反馈P 或 PD 线性反馈
整定参数较多以 \(\omega_c,\omega_o\) 为主
理解难度较高更适合工程入门
核心思想完全相同:估计总扰动并主动补偿
推荐学习顺序 先掌握 LADRC,再理解非线性 ADRC。因为两者的主干完全相同,而 LADRC 的数学结构更清楚。

9. 一阶 LADRC

假设对象可以近似写成:

\[ \dot y=F+b_0u \]

二阶 LESO

\[ \begin{cases} e_o=y-z_1\\ \dot z_1=z_2+b_0u+\beta_1e_o\\ \dot z_2=\beta_2e_o \end{cases} \]

控制律

\[ u_0=k_p(r-z_1),\qquad u=\frac{u_0-z_2}{b_0} \]

带宽参数化

\[ k_p=\omega_c,\qquad \beta_1=2\omega_o,\qquad \beta_2=\omega_o^2 \]

一阶对象配二阶 ESO;ESO 比对象阶次多一阶,多出来的状态就是总扰动。

10. 二阶 LADRC

对象:

\[ \ddot y=F+b_0u \]

三阶 LESO

\[ \begin{cases} e_o=y-z_1\\ \dot z_1=z_2+\beta_1e_o\\ \dot z_2=z_3+b_0u+\beta_2e_o\\ \dot z_3=\beta_3e_o \end{cases} \]

控制律

\[ u_0=k_p(r-z_1)+k_d(\dot r-z_2) \] \[ u=\frac{u_0-z_3}{b_0} \]

带宽参数化

\[ k_p=\omega_c^2,\qquad k_d=2\omega_c \] \[ \beta_1=3\omega_o,\qquad \beta_2=3\omega_o^2,\qquad \beta_3=\omega_o^3 \]

11. \(\omega_c\) 与 \(\omega_o\):一个管“跑”,一个管“看”

Controller bandwidth

\(\omega_c\):控制器带宽

决定闭环响应速度,进而决定 \(k_p,k_d\)。

\[ k_p=\omega_c^2,\qquad k_d=2\omega_c \]
Observer bandwidth

\(\omega_o\):观测器带宽

决定 ESO 状态和扰动估计速度,进而决定 \(\beta_1,\beta_2,\beta_3\)。

\[ \beta_1=3\omega_o,\quad \beta_2=3\omega_o^2,\quad \beta_3=\omega_o^3 \]

为什么 \(k_p,k_d\) 是这样来的?

希望二阶闭环为临界阻尼:

\[ s^2+k_ds+k_p=(s+\omega_c)^2 \]

展开并对比系数:

\[ (s+\omega_c)^2=s^2+2\omega_cs+\omega_c^2 \]

所以:

\[ k_p=\omega_c^2,\qquad k_d=2\omega_c \]

为什么 \(\beta_1,\beta_2,\beta_3\) 是这样来的?

把三个 ESO 极点都配置在 \(-\omega_o\):

\[ s^3+\beta_1s^2+\beta_2s+\beta_3=(s+\omega_o)^3 \]
\[ (s+\omega_o)^3 =s^3+3\omega_os^2+3\omega_o^2s+\omega_o^3 \]

两者通常怎么选?

\[ \omega_o=k_o\omega_c,\qquad k_o\approx 3\sim 10 \]

工程上常从 \(3\sim5\) 倍开始。观测器通常要比控制器快,但过快会放大测量噪声和离散误差。

不是越大越好 提高 \(\omega_c\) 会加快响应,但增加控制量和未建模高频风险; 提高 \(\omega_o\) 会加快估计,但会放大噪声,尤其 \(\beta_3=\omega_o^3\) 增长很快。

从调节时间反推 \(\omega_c\)

临界阻尼、2% 误差带下,可用:

\[ T_s\approx \frac{6}{\omega_c} \qquad\Longleftrightarrow\qquad \omega_c\approx\frac{6}{T_s} \]

12. LADRC 参数计算器

先给出期望调节时间,再选择观测器相对速度,自动得到二阶 LADRC 参数。

计算假设 二阶 LADRC、临界阻尼、2% 调节时间近似。
\(\omega_c\)20.000
\(\omega_o\)100.000
\(b_0\)1.000
\(k_p\)400.000
\(k_d\)40.000
\(\beta_1\)300.000
\(\beta_2\)30000.000
\(\beta_3\)1000000.000
建议初始步长≤ 0.00050 s
实际步长 \(T_s\)
离散裕度 \(\omega_oT_s\)
该采样率下 \(\omega_o\) 上限
注意 参数计算只是起点。实际还要结合采样率、噪声、执行器限幅、对象共振和时延进行修正。

13. 交互仿真:观察跟踪、抗扰与噪声

仿真对象为:

\[ \ddot y=-a_1\dot y-a_0y+bu+d(t) \]

LADRC 不直接使用 \(a_0,a_1\),只使用 \(b_0\)。对象内部动态与扰动统一进入总扰动。

Reference r Output y
True total disturbance F Estimated disturbance z₃
Control effort u Actuator limit ±80
第三张图才是最该看的 输出曲线好看不代表参数能用。ADRC 在实机上翻车,八成栽在控制量上:撞满限幅、高频抖振、 \(\omega_o\) 一大 \(u\) 就长毛刺。把 \(\omega_o/\omega_c\) 推到 8、再把噪声拉到 0.03, 看看 \(u\) 会变成什么样——这时候输出曲线可能还是挺漂亮的。
建议你这样观察 先固定 \(b=b_0\),增加扰动,看输出能否快速恢复;再故意让 \(b\neq b_0\),观察增益误差如何被 ESO 并入总扰动; 最后增加噪声,观察高 \(\omega_o\) 的代价。

14. 数字控制器如何实现?

连续公式最终要在单片机、DSP、PLC 或实时程序中离散执行。

二阶 LADRC 的最小实现流程

// 每个采样周期执行一次
// 输入:reference r, reference derivative r_dot, measured output y
// 状态:z1, z2, z3
// 参数:b0, wc, wo, dt

kp = wc * wc
kd = 2 * wc

beta1 = 3 * wo
beta2 = 3 * wo * wo
beta3 = wo * wo * wo

// 1) 计算观测误差
eo = y - z1

// 2) 更新 LESO
z1_dot = z2 + beta1 * eo
z2_dot = z3 + b0 * u_prev + beta2 * eo
z3_dot = beta3 * eo

z1 += dt * z1_dot
z2 += dt * z2_dot
z3 += dt * z3_dot

// 3) 状态误差反馈
u0 = kp * (r - z1) + kd * (r_dot - z2)

// 4) 扰动补偿
u = (u0 - z3) / b0

// 5) 输出限幅
u = clamp(u, u_min, u_max)

u_prev = u
细节一:用哪个时刻的 \(u\) ESO 方程中使用哪个时刻的 \(u\),必须在程序里定义清楚。常见做法是使用上一采样周期实际施加的 \(u_{k-1}\), 保持计算因果性。上面伪代码中 \(z_2\) 的更新用的就是 u_prev
细节二:回送给 ESO 的必须是限幅之后的 \(u\) 注意伪代码里 u_prev = u 写在 clamp() 之后,这不是随手写的顺序,是必须的。 ESO 的全部逻辑是“拿我施加的输入和实测输出做对比”。执行器一旦饱和,实际施加的就不是算出来的那个大值; 如果仍把限幅前的 \(u\) 记账,ESO 就会认为“我使了这么大劲,输出却没动”, 于是把没施加上去的那部分全部误判成扰动,\(z_3\) 单向越积越大,控制量继续要求更大的补偿—— 正反馈,观测器直接跑飞。
这比 PID 的积分饱和更隐蔽:PID 的 I 顶到上限后至少还是有界的,而这里是错误的模型输入, 错的是 ESO 对世界的认知。除了顺序写对,工程上通常还要给 \(z_3\) 本身加限幅, 并在检测到持续饱和时冻结 \(z_3\) 的积分。

实际工程还需要加入

  • 控制输出限幅与变化率限制;
  • 启动阶段的状态初始化;
  • 传感器异常值处理;
  • 必要的测量滤波,但避免引入过大相位滞后;
  • 无扰切换与手自动切换;
  • 对 \(z_3\) 或补偿量进行合理限幅;
  • 更稳定的离散化方法,例如双线性变换或精确离散模型。

15. 推荐调参流程

步骤 1:确定对象阶次

主要动态像一阶,就先用一阶 LADRC;主要动态像位置—速度关系,就先用二阶 LADRC。

步骤 2:估计 \(b_0\)

先保证符号正确,再保证数量级合理。它表示控制输入对最高阶输出导数的直接增益。 具体估法(阶跃初始斜率法)和“宁大勿小”的原因见 第 19 章记忆点 9

步骤 3:选 \(\omega_c\)

可由期望调节时间初估:\(\omega_c\approx6/T_s\)。从保守值开始。

步骤 4:选 \(\omega_o\)

先取 \(\omega_o=(3\sim5)\omega_c\),再根据抗扰速度和噪声折中。

步骤 5:加入限幅

不带限幅的仿真参数,不能直接照搬到真实执行器。

步骤 6:逐项排查

先看估计,再看控制;先解决符号和尺度,再追求速度。

现象—原因—处理

现象可能原因处理方向
整体响应太慢\(\omega_c\) 太小逐步提高 \(\omega_c\)
扰动后恢复太慢\(\omega_o\) 太小适当提高 \(\omega_o\)
控制量抖动明显\(\omega_o\) 太大或噪声高降低 \(\omega_o\),检查采样与滤波
一开始就向错误方向跑\(b_0\) 符号错误立即检查控制方向
仿真稳定,实机振荡时延、饱和、共振未建模降低带宽,加入真实限制
\(z_3\) 很大不一定异常,可能是量纲或 \(b_0\) 偏差结合实际控制量与单位判断

16. 初学者最容易踩的坑

坑 1:把总扰动理解成“只有外部扰动”

总扰动还包括内部未知动态、非线性、参数误差以及 \((b-b_0)u\)。

坑 2:认为 ADRC 完全不需要模型

至少需要大致阶次、输入方向和合理的 \(b_0\)。对象若有明显时延、非最小相位零点或柔性共振,也必须考虑。

坑 3:盲目增大 \(\omega_o\)

观测器越快,噪声和离散误差通常越严重。尤其 \(\beta_3=\omega_o^3\),参数会快速增长。

坑 4:忽略控制饱和

ESO 估计到大扰动后,控制器可能要求超过执行器能力的补偿量。真实系统必须限制幅值与变化率。

坑 5:把 \(z_3\) 当成某一个物理扰动

\(z_3\) 估计的是“合成后的等效影响”,它未必等于某个单独可测的力、转矩或负载。

坑 6:只看输出,不看 ESO 状态

调试时要同时观察 \(z_1,z_2,z_3\)、控制量和限幅状态,否则很难判断问题来自观测器还是控制器。

17. ADRC 与 PID:不是谁“绝对更好”

比较维度PIDADRC / LADRC
核心信息主要使用跟踪误差使用误差、状态估计和扰动估计
抗恒定扰动常依靠积分累积由 ESO 估计并直接补偿
模型需求通常较低大致阶次与 \(b_0\)
参数解释\(K_p,K_i,K_d\)\(\omega_c,\omega_o,b_0\)
实现复杂度中等
噪声敏感D 项敏感高带宽 ESO 敏感
适用场景对象稳定、需求常规、工程成熟扰动明显、参数变化、模型不确定
实用判断 PID 能稳定可靠地完成任务时,没有必要为了“高级”而更换。 ADRC 的价值在于:当扰动和不确定性成为主要矛盾时,它提供了更直接的处理框架。

18. 用一张逻辑链把 ADRC 记住

对象复杂模型不准、有扰动
统一打包定义总扰动 \(F\)
扩张状态把 \(F\) 当成新状态
估计并补偿ESO + \(u=(u_0-\hat F)/b_0\)
\[ \boxed{ \begin{aligned} \ddot y&=F+b_0u\\ z_3&\approx F\\ u_0&=k_p(r-z_1)+k_d(\dot r-z_2)\\ u&=\frac{u_0-z_3}{b_0} \end{aligned}} \]
\[ \boxed{ \begin{aligned} k_p&=\omega_c^2,\qquad k_d=2\omega_c\\ \beta_1&=3\omega_o,\qquad \beta_2=3\omega_o^2,\qquad \beta_3=\omega_o^3 \end{aligned}} \]
最终记忆句 \(\omega_c\) 决定系统“跑多快”,\(\omega_o\) 决定观测器“看多快”, \(b_0\) 决定控制输入按什么尺度进入系统。

19. 记忆卡:把 ADRC 压成十句话

前面十八章是“为什么这样做”。这一章只留“考试前五分钟要看的东西”—— 每个记忆点都是一句可以背下来的结论,加上它成立的理由。

记忆点 1:所有机关只为一件事——把对象变成积分串联型

一句话 ESO 负责把对象“洗”成标准件(\(\ddot y\approx u_0\)),PD 负责给标准件配速度。

补偿之后 \(\ddot y\approx u_0\),对象在控制器眼里就是一个纯双积分器 \(1/s^2\)—— 没有摩擦、没有耦合、没有参数变化、没有负载。这种“\(\dot x_1=x_2,\ \dot x_2=u\)”的结构叫 积分串联型(cascade / chain of integrators)。

一旦成了积分串联型,控制就没有难度了:\(u_0=k_p e_1+k_d e_2\),闭环 \((s+\omega_c)^2\), \(k_p=\omega_c^2,\ k_d=2\omega_c\)。PD 之所以够用,是因为难的部分已经被 ESO 干掉了, 而不是因为对象本来就简单。

反过来推论 如果实机上 PD 段怎么调都不对,问题几乎一定不在 \(k_p,k_d\),而在“对象没被洗干净”—— 即 \(z_3\) 没跟上 \(F\)。先看估计,再看控制。

记忆点 2:观测器带宽必须比控制器带宽大

一句话 眼睛要比腿快:\(\omega_o=(3\sim10)\,\omega_c\),工程起点 \(3\sim5\) 倍。

原因在于控制律用的全是估计值:\(u_0=k_p(v_1-z_1)+k_d(v_2-z_2)\),补偿量也是估计值 \(z_3\)。 如果 ESO 比控制器慢,控制器就是在拿过期的状态做高增益反馈——等价于回路里插了一段相位滞后, 结果就是振荡甚至失稳。所以“先看得清,才能跑得快”,顺序不能反。

但也不是越大越好,代价有三条,都随 \(\omega_o\) 迅速变坏:

噪声

按 \(\omega_o^3\) 放大

\(\beta_3=\omega_o^3\),测量噪声经 \(e_0\) 直接乘进扰动估计,最后全跑到控制量上。

离散

受 \(\omega_o T_s\) 限制

采样率跟不上时,观测器自己就会发散,与对象无关。见第 12 章的离散裕度判定。

未建模

会“看见”高频动态

\(\omega_o\) 一旦跨过柔性共振或时延对应的频率,ESO 会把它当成扰动去补偿,越补越振。

记忆点 3:推箱子——ADRC 比 PID 多用了两条信息

场景:你要把一个箱子沿桌面推到某个位置。同一个任务,PID 和 ADRC 手里握着的信息量完全不同。

PID 手里的信息 ADRC 手里的信息 误差 e = r − y PID u 只知道“现在差多少” 比例、积分、微分三条腿 全都长在同一条信息 e 上 ① 误差 v − z ② 我施加的 u ③ 模型预期 b₀·u ADRC 内含 ESO u = (u₀ − z₃)/b₀ ③ 与实测一比,差出来的就是“意外” z₃ = 桌面变涩了 + 箱子里有铁块 + 有人在拽 当场从控制量里减掉,不必等误差积累起来

把这个故事讲全,就是四步:

  1. 我知道自己使了多大劲。这就是把 \(u\) 送进 ESO 的那条线。PID 从头到尾不使用 \(u\)—— 它只看结果,不看自己的动作。
  2. 我心里有个“本该如何”的模型。以我这个力气推这么个箱子,本该产生这么大的加速度, 这就是 \(b_0u\):一个粗糙但够用的标称模型。
  3. 我把“本该走多快”和“眼睛看到的实际走多快”一对比。差出来的部分就是我没料到的东西—— 桌面涩了、箱子里装了铁块、有人在另一边拽。这个持续对比并修正的过程就是 ESO, 它的依据正是 \(e_0=y-z_1\),它的结论正是 \(z_3\)。
  4. 于是我立刻多加这么多劲把它抵掉(\(u=(u_0-z_3)/b_0\)), 而不是像积分项那样,等误差攒够了再慢慢加力。
一句话 PID 只用了“结果偏差”一条信息;ADRC 额外用了“我施加了多少输入”和“按标称模型本该得到什么结果”两条。 抗扰更快不是玄学,就是多用了两条信息换来的。
这个故事也解释了 ADRC 的软肋 它的判断建立在“我知道自己使了多大劲”之上。一旦这条信息不准——执行器饱和了却仍按算出来的 \(u\) 记账、 有传输延时、\(b_0\) 数量级错——ADRC 会把“没施加上去的那部分”误判成扰动, 于是比 PID 更容易被带偏。参见第 14 章关于“送进 ESO 的必须是限幅后的 \(u\)”那一条。

记忆点 4:“扩张状态”四个字,逐字拆开就懂了

意思在 ADRC 里指什么
状态 凡是“给它一个导数、就能被积分出来”的量 \(\dot y\) 是状态,因为 \(y\) 是它积分来的;反过来,只要一个量有导数,它就有资格当状态。
扩张 在原有 \(n\) 个状态之外,额外挂一个 令 \(x_{n+1}=F\),把本来是“外生输入”的总扰动,强行变成系统内部的一个状态变量
一句话 能被积分出来的就能当状态,能当状态的就能被观测器估出来。这两句连起来,就是 ESO 全部的合法性。

之所以敢这么干,是因为我们只需要假设 \(\dot F=h\) 有界,完全不需要知道 \(h\) 是什么。 有了这个假设,\(F\) 就满足状态的定义,标准观测器理论直接套上来即可—— “扩张”一词的全部含义,就是把不可测的未知量升格成状态,从而合法地去估计它

记忆点 5:ESO 里那个积分,消的是“我的模型”和“实机”之间的稳态误差

看 \(z_3\) 的方程,它是一个纯积分器

\[ \dot z_3=\beta_3\,e_0,\qquad e_0=y-z_1 \]

只要 \(e_0\neq0\)(我的估计和实机对不上),这个积分就一直往上爬,直到 \(e_0\to0\)。 这跟 PI 里的 I 消除稳态误差是同一个机理,区别只在“积的是谁的误差、顶出来的是什么量”:

对比PID 的 IESO 里的积分
积的是什么误差输出与目标之差 \(r-y\)实机与我的估计之差 \(y-z_1\)
顶出来的是什么直接顶出控制量顶出扰动估计值 \(z_3\)
装在哪里串在闭环主通道上装在观测器里,不在主通道上
副作用额外 \(-90^\circ\) 相位、积分饱和不动主回路相位;但 \(z_3\) 仍需限幅
一句话 ADRC 不是“不要积分”,是把积分从误差回路搬到了观测回路

由此可以直接读出两个结论:ESO 稳态时必然 \(e_0=0\),即 \(z_1=y\); 对常值总扰动,\(z_3\) 零稳态误差地收敛到 \(F\)。 但如果 \(F\) 是斜坡(\(\dot F=\)常数),三阶 ESO 会留下一个固定的稳态偏差—— 要消掉它,就得再扩一阶(把 \(\dot F\) 也当成状态)。

记忆点 6:积分串联型 + PD 比 PI 少一阶

PI(D) 控双积分器ADRC 补偿后配 PD
闭环特征方程\(s^3+k_ds^2+k_ps+k_i\)\(s^2+k_ds+k_p=(s+\omega_c)^2\)
阶次三阶二阶
需要配的极点3 个,且要在三者之间折中1 个位置(重根 \(-\omega_c\))
可调旋钮\(k_p,k_i,k_d\) 三个,互相耦合\(\omega_c\) 一个
相位代价原点极点带来固定 \(-90^\circ\)主回路无积分器,无此代价
饱和处理要做抗积分饱和只需对 \(u\) 和 \(z_3\) 限幅
一句话 I 项是“用相位换静差”,\(z_3\) 补偿是“用信息换静差”。少一阶 = 少一份要牺牲的相位裕度 = 同样稳定裕度下能开更高带宽。

记忆点 7:极点配置在这里只干一件事——把 5 个参数绑成 2 个

全篇一共只做了两次极点配置,各管一件事:

控制器侧

\(s^2+k_ds+k_p=(s+\omega_c)^2\)

双重极点配在 \(-\omega_c\),得 \(k_p=\omega_c^2,\ k_d=2\omega_c\)。 取重根就是临界阻尼:对标称的双积分器不超调。

观测器侧

\(s^3+\beta_1s^2+\beta_2s+\beta_3=(s+\omega_o)^3\)

三重极点配在 \(-\omega_o\),得 \(\beta_1=3\omega_o,\ \beta_2=3\omega_o^2,\ \beta_3=\omega_o^3\)。

一句话 带宽参数化的本质,就是用极点配置把 \(k_p,k_d,\beta_1,\beta_2,\beta_3\) 这 5 个参数, 绑成 \(\omega_c\) 和 \(\omega_o\) 这 2 个。

为什么都取重根?不是因为最优,是因为最省参数:重根让整组增益只由一个数决定, 而且没有振荡模态。如果你愿意多花参数,把三个观测器极点分散配(例如把最快那个拉回来一点) 可以换来更低的噪声灵敏度,代价是失去“一个旋钮”的便利。

记忆点 8:观测器矩阵的特征值,就是估计误差的衰减率

令估计误差 \(\varepsilon=x-z\),把对象方程减去 ESO 方程,误差动态是:

\[ \dot{\varepsilon}=(A-LC)\,\varepsilon+\begin{bmatrix}0\\0\\h\end{bmatrix}, \qquad L=\begin{bmatrix}\beta_1\\\beta_2\\\beta_3\end{bmatrix}, \qquad h=\dot F \]

关键在于 \(A-LC\) 的特征多项式恰好就是上一节配置的那个:

\[ \det\!\big(sI-(A-LC)\big)=s^3+\beta_1s^2+\beta_2s+\beta_3=(s+\omega_o)^3 \]
一句话 \(A-LC\) 的特征值全是 \(-\omega_o\),所以估计误差按 \(e^{-\omega_o t}\) 衰减。 这就是“\(\omega_o\) 决定观测器看多快”的严格出处,不是比喻。

从这一个式子能直接读出四件事:

  • 为什么 \(\beta\) 不能乱填。特征值必须全在左半平面,否则观测器自己先发散—— 和对象稳不稳定完全无关。
  • 误差为什么不会归零。驱动项里还剩 \(h=\dot F\)。\(h\) 有界时误差有界, 界随 \(\omega_o\) 增大而缩小。这就是“ESO 估不了变化太快的扰动”的定量含义。
  • 三重根的形状。重根意味着衰减包含 \(t\,e^{-\omega_o t}\)、\(t^2e^{-\omega_o t}\) 这类项, 起步略慢、无振荡,这正是 ESO 上电初期那段“甩头”的来源,可用状态初始化缓解。
  • 离散化的硬约束。前向欧拉后误差矩阵变成 \(I+T_s(A-LC)\),特征值是 \(1-\omega_oT_s\)(三重)。 要求 \(|1-\omega_oT_s|<1\),即 \(\omega_oT_s<2\) 才是数学上的稳定边界; 工程上要留精度余量,取 \(\omega_oT_s\le0.1\)。这条判定已经做进第 12 章的计算器。

记忆点 9:\(b_0\) 是唯一必须由你给的模型信息

\(b_0\) 回答一个问题:我施加一个单位的输入,最高阶导数应该变多少。 它有三条硬性要求,严格程度递减:

  1. 符号必须对。错了就是正反馈,一上电直接往错误方向跑。这是第一个要检查的东西。
  2. 数量级要对。差 2~3 倍通常都能被 \((b-b_0)u\) 吸收进总扰动,由 ESO 兜住。
  3. 宁大勿小。见下面的实测。
更正一个常见说法(也更正我自己之前的说法) “\(b_0\) 估小比较保守”是错的。因为 \(u=(u_0-z_3)/b_0\),\(b_0\) 偏小会让实际控制量放大, 等效回路增益变成 \(b/b_0>1\)——这是更激进,不是更保守。 在本页这种无时延的理想仿真里你看不出代价(ESO 很快,把增益误差都吸收了); 但真实系统一旦有延时,界限立刻收紧:\(\omega_c=10,\ \omega_o=4\omega_c\) 时, 5 ms 延时下 \(b_0\) 低于约 \(0.35b\) 就发散,20 ms 延时下低于约 \(0.65b\) 就发散。 反过来 \(b_0\) 偏大只是把回路增益压到 1 以下,表现为变钝、超调增大,但不容易直接失稳。 所以实机上宁大勿小。这也是“仿真好好的、上机就振”的一个具体成因。

怎么估:阶跃初始斜率法。

  • 开环(或低增益闭环)给一个已知幅值的输入阶跃 \(u^\ast\);
  • 看输出最高阶导数在阶跃瞬间的初值:二阶对象看 \(\ddot y|_{t=0^+}\),一阶对象看 \(\dot y|_{t=0^+}\);
  • 则 \(b_0\approx\ddot y|_{0^+}/u^\ast\)。取初始时刻是因为此时对象内部动态还没起作用, \(f\approx0\),测到的几乎是纯输入增益。

记忆点 10:三个最容易反过来记的点

别记反

误差用 \(z_1\),不用 \(y\)

\(e_1=v_1-z_1\)。用 \(z_1\) 相当于自带滤波,也保证反馈的都是同一套估计状态。

别记反

\(z_3\) 不是某个物理扰动

它是“合成后的等效影响”,含 \((b-b_0)u\) 和未建模动态,未必等于任何一个可测的力或转矩。

别记反

送进 ESO 的是限幅后的 \(u\)

必须是执行器真正执行的那个值,否则 ESO 会把“没施加上去的部分”记成扰动。

\[ \boxed{ \begin{aligned} &\textbf{一条链:}\; \text{打包} \Rightarrow \text{扩张} \Rightarrow \text{观测} \Rightarrow \text{补偿} \Rightarrow \text{积分串联型} \Rightarrow \text{PD}\\ &\textbf{两个旋钮:}\;\omega_c\ \text{管跑多快},\ \omega_o\ \text{管看多快},\ \omega_o=(3\sim5)\omega_c\\ &\textbf{三个约束:}\;b_0\ \text{符号对},\ \omega_oT_s\le0.1,\ \text{限幅后的}\ u\ \text{回送 ESO} \end{aligned}} \]
最后一道自测:为什么说“ADRC 抗常值扰动比 PI 快”,不是因为它增益更高?
因为 PI 必须先让误差出现,再靠积分把补偿量攒出来,攒的速度受 \(k_i\) 和稳定性限制; ADRC 的 \(z_3\) 是从 \(u\) 与 \(y\) 的不一致中直接算出来的,扰动一进来 \(e_0\) 就变, 不需要等误差长大。快的来源是信息,不是增益。