【电赛/毕设终极杀器】超越 PID 与 LQR!控制界的黑魔法:自抗扰控制 (ADRC) 原理与 STM32 硬核部署指南
前言
凌晨 5 点,你的无人机终于能悬停了。但当你给无人机挂上一个待投放的小沙包时,原本完美的 PID 参数瞬间失效,无人机疯狂摇摆直至炸机。
为什么?
PID 的痛点:它只能“看到误差才去补救”,反应永远慢半拍;而且参数完全绑定了当前的重量和重心,重量一变,参数全废!
LQR 的痛点:它需要你写出绝对精确的“物理数学模型”。但现实中,地毯的摩擦力、电机的磨损、风的阻力,你怎么可能精确建模?!有没有一种算法,既不需要精确的物理模型,又能瞬间把所有未知干扰(不管你是挂了重物,还是被大风吹)强行抵消掉?
有!它就是中国学者的骄傲、被誉为“面向 21 世纪的控制理论”——ADRC(自抗扰控制)。
本文将带你跨越理论的鸿沟,用最直白的人话和短短几十行 C 代码,在 STM32 里装上这个工业界最顶级的“抗扰引擎”!
@TOC
一、 认知颠覆:ADRC 到底在干一件什么“神仙事”?
不管是系统内部的老化(电机没力气了),还是外部的干扰(大风吹、撞到石头),在 ADRC 的眼里,统统被打包成一个词——“总扰动(Total Disturbance)”。
ADRC 的核心哲学:我不需要知道干扰是怎么来的,我只需要把它“看”出来,然后在它破坏系统之前,反向干掉它!
🏆 核心灵魂:扩张状态观测器(ESO)
这是 ADRC 最牛逼的地方。
假设你给电机发了 50 的 PWM,按照经验,电机应该转 100 圈/秒。
但是,传感器传回来的数据是 80 圈/秒。
PID 是怎么做的?“哦,差了 20 圈,我加大一点 PWM 试试。”
ESO(观测器)是怎么做的?“我发了 50 的力,你应该转 100 圈,但你只转了 80 圈。说明现实世界中,有一个等效于 -20圈 的‘未知妖孽(总扰动)’在阻碍你!”
ESO 极其敏锐,它能在微秒级的时间内,实时计算出这个“总扰动”的大小!
既然知道了扰动有多大,接下来就太简单了:在原本的控制输出上,直接加上一个反向的力,把扰动“同等抵消”掉!这就是“自抗扰”。
二、 化繁为简:为什么我们要用 LADRC(线性自抗扰)?
如果你去查文献,标准的 ADRC 包含 TD(跟踪微分器)、NLSEF(非线性状态误差反馈)和 ESO。它足足有10 多个参数要调!在电赛四天三夜里,调这 10 个参数会让你精神分裂。
降维打击:高志强教授提出的 LADRC(线性自抗扰)!
高教授用极其巧妙的频域理论,把这 10 个玄学参数,强行缩减成了3 个具有明确物理意义的参数:
(控制增益):代表你的系统“给多大推力,就有多大加速度”。这是唯一需要大概估算的物理量。b0b0
(观测器带宽):代表 ESO “看”扰动的速度有多快。越大,抗干扰越敏锐(但太大容易引入传感器噪声)。ωoωo
(控制器带宽):代表系统追踪目标的速度有多快。越大,响应越快。ωcωc
震撼事实:用了 LADRC,你调参就像调收音机频道一样简单,只需要拧
和ωoωo这两个旋钮,系统就能稳如磐石!ωcωc
三、 STM32 纯 C 语言实战:二阶 LADRC 极速部署代码
别看论文里的矩阵微分方程吓人。在单片机的离散时间(
dtdt)里,二阶 LADRC 仅仅是几个极简的迭代公式!
下面这段代码,完美适用于电机位置控制、倒立摆角度控制、无人机姿态控制(这些都是典型的二阶系统:输出受加速度控制)。
1. 参数与结构体定义
codeC
typedef struct { // 【需要你调的 3 个核心参数】 float wc; // 控制器带宽 (决定响应速度) float wo; // 观测器带宽 (决定抗干扰速度,通常设为 wc 的 3~5 倍) float b0; // 系统增益 (PWM -> 加速度的转换比例) // ESO 观测器增益 (根据 wo 自动计算,无需手调!) float beta1; float beta2; float beta3; // ESO 内部状态估计变量 float z1; // 估计的位置 (或角度) float z2; // 估计的速度 (或角速度) float z3; // !!!估计的总扰动!!! (ADRC的灵魂) float dt; // 运行周期 (如 0.005s) float u; // 最终的输出控制量 (PWM) } LADRC_TypeDef; /** * @brief LADRC 参数初始化 (自动计算观测器增益) */ void LADRC_Init(LADRC_TypeDef *adrc, float wc, float wo, float b0, float dt) { adrc->wc = wc; adrc->wo = wo; adrc->b0 = b0; adrc->dt = dt; // 核心黑魔法:基于带宽极点配置自动计算 beta 参数! adrc->beta1 = 3.0f * wo; adrc->beta2 = 3.0f * wo * wo; adrc->beta3 = wo * wo * wo; adrc->z1 = 0; adrc->z2 = 0; adrc->z3 = 0; adrc->u = 0; }2. 核心控制执行函数(放进 5ms 定时器中断)
这段代码分两步:第一步让 ESO 观测出总扰动
z3z3,第二步利用
z3z3抵消扰动并输出控制量!
codeC
/** * @brief 执行一次 LADRC 计算 * @param target: 目标值 (期望角度/位置) * @param measure: 传感器真实测量值 * @retval 最终输出的控制量 (PWM) */ float LADRC_Calculate(LADRC_TypeDef *adrc, float target, float measure) { // ======================================================== // 第一步:线性扩张状态观测器 (LESO) - “火眼金睛”看透一切干扰 // ======================================================== float e = adrc->z1 - measure; // 观测值与真实值的误差 // 更新状态估计 (离散化欧拉积分) adrc->z1 += adrc->dt * (adrc->z2 - adrc->beta1 * e); adrc->z2 += adrc->dt * (adrc->z3 + adrc->b0 * adrc->u - adrc->beta2 * e); // 这里算出来的 z3,就是包含了摩擦力、风阻、负载变化的所有“总扰动”! adrc->z3 += adrc->dt * (-adrc->beta3 * e); // ======================================================== // 第二步:线性误差反馈控制 (LSEF) - 抵消扰动,精准打击 // ======================================================== // 1. 计算 PD 控制规律 (这里也利用了自动配置参数的黑魔法) float Kp = adrc->wc * adrc->wc; float Kd = 2.0f * adrc->wc; // 基础控制量 u0 (基于估计状态,因为经过ESO过滤,自带极强平滑效果) float u0 = Kp * (target - adrc->z1) - Kd * adrc->z2; // 2. 终极杀招:扰动补偿!!! // 无论外界怎么干扰,我直接减去观测到的总扰动 z3! adrc->u = (u0 - adrc->z3) / adrc->b0; // (可选) 加上输出限幅保护代码 // if(adrc->u > MAX_PWM) adrc->u = MAX_PWM; ... return adrc->u; }看到没?!没有积分器(I),也就永远没有积分饱和、撞墙疯跑的危险!而且你连微分噪声都不用怕,因为 z2 是 ESO 自己推算出的丝滑微分信号,根本不是传感器原始数据求导来的!
四、 玄学破局:LADRC 怎么调参?(工业级套路)
PID 调参是门玄学,但 LADRC 调参是纯粹的工程学!
第一步:估算
b0b0(唯一需要试错的物理量)
先随便给一个数(比如 1.0 或 10.0)。
如果系统震荡得很厉害,
给大一点(欺骗系统说它自己很强,它输出的力就会变柔和)。b0b0如果系统反应迟钝像没吃饭一样,
给小一点。b0b0只要
调到了一个刚好不震荡的范围,剩下的事情就交给b0b0
了!ωω
第二步:调节观测器
ωoωo和控制器
ωcωc原则:
通常是ωoωo
的3 到 5 倍。因为观测器必须比控制器“看”得快,系统才稳。ωcωc操作:逐渐增大
(比如从 5 慢慢加到 30),并保持ωcωc
。ωo=4×ωcωo=4×ωc什么时候停?当你的电机开始发出“滋滋”的高频噪声时(说明
太高,把传感器的底噪当成扰动放大了),立刻停止,并把带宽回调 20%。ωoωo
大功告成!整个调参过程可能只需要 3 分钟,你的系统鲁棒性就能直接碾压调了 3 天的 PID!
五、 赛场实战:ADRC 降维打击的表现是什么样的?
如果你在电赛中选了两轮平衡自行车或者风力摆,在答辩现场:
评委要求:“在你的车上放一块 500g 的配重铁块。”
PID 队伍:重心大变,I 环积分缓慢累加,小车剧烈摇晃好几秒才勉强站住,甚至直接倒地。
ADRC 队伍:加上铁块的瞬间,ESO 在 5 毫秒内计算出 z3 扰动发生了突变,控制量
瞬间补偿。肉眼看过去,小车几乎纹丝不动,仿佛铁块根本不存在!uu
评委要求:“用手拨一下无人机的机臂。”
ADRC 队伍:你的手会感觉到一种极度强烈的“肌肉抵抗感”,外力撤除瞬间,无人机毫无超调地死死钉回原点。
在你的《系统设计报告》上写下:
“本系统摒弃了传统 PID 对精确模型的依赖与积分饱和缺陷,采用二阶自抗扰控制器(LADRC)。利用扩张状态观测器(ESO)对系统内部耦合及外部气流扰动进行实时在线估计与前馈补偿,实现了变负载工况下的极高鲁棒性控制。”
评委看完,不仅国一稳了,甚至可能问你有没有兴趣读他的研究生!
结语
如果说 PID 是古典物理,LQR 是精英物理,那么 ADRC 就是现代工程控制领域的“黑客帝国”。
它打破了西方控制理论中“必须精确建立数学模型”的教条,用极具东方哲学意味的“见招拆招”思想,把所有未知的混沌与无序,全部打包成一个
z3z3,然后一剑封喉。
不要再让你的电机在微积分的误差中悲鸣了,用扩张状态观测器,去洞悉物理世界的真实吧!
预祝各位挑战控制巅峰的开发者:扰动秒抵消,悬停如定海神针,负载千变万化,系统稳如泰山!🏆