1. 自抗扰控制(ADRC)实战:从Simulink建模到参数调优
自抗扰控制器(Active Disturbance Rejection Control, ADRC)作为现代控制理论中的一匹黑马,正在工业控制领域掀起一场静悄悄的革命。与传统PID控制相比,ADRC最大的优势在于它能实时估计并补偿系统内外部的各种扰动,这使得它在电机控制、飞行器姿态调节、精密仪器等场景中表现尤为出色。
我在工业自动化领域摸爬滚打多年,从最早的PID整定到后来的模糊控制、自适应控制都尝试过,直到五年前接触到ADRC,才算真正找到了应对复杂非线性系统的"银弹"。今天要分享的这套Simulink模型,是我经过数十个实际项目迭代后的精华版本,特别适合以下两类朋友:
- 控制工程师:想快速验证ADRC在自家设备上的效果,但又被数学公式劝退
- 在校研究生:需要搭建ADRC仿真平台完成课题,但苦于没有现成参考模型
这个模型最大的特点就是"即插即用"——所有核心模块都已封装好,参数调节通过直观的滑块完成,你甚至不需要完全理解那些艰深的状态观测器理论,就能体验到ADRC的强大抗扰能力。
2. 模型架构设计解析
2.1 三阶与四阶模型的选择策略
在我的Simulink模型中,三阶ADRC和四阶ADRC可以通过一个简单的开关模块进行切换。这两种结构各有千秋:
三阶ADRC(标准型)
matlab复制状态变量:z1(输出估计), z2(一阶导数), z3(总扰动)
适用场景:大多数二阶工业对象(如电机、温度系统)
优势:结构简单,计算量小,实时性好
四阶ADRC(增强型)
matlab复制状态变量:z1-z3同上, z4(扰动导数)
适用场景:超调敏感或扰动变化剧烈的系统(如精密定位平台)
优势:对高频扰动抑制更好,但需要更强的计算能力
实际选择建议:初次尝试建议从三阶开始,当发现系统存在高频抖动或周期性扰动时,再考虑切换到四阶结构。我的经验法则是——采样周期超过1ms的硬件优先用三阶。
2.2 核心模块实现细节
模型包含五个关键子系统,其数据流关系如下图所示(模拟框图):
code复制[参考输入] → [跟踪微分器TD] → [状态反馈]
↓
[被控对象] ← [控制量生成] ← [扩张状态观测器ESO]
1. 跟踪微分器(TD)
matlab复制function [v1, v2] = TD(v0, h, r)
% v0: 目标值
% h: 步长
% r: 速度因子
persistent x1 x2
if isempty(x1)
x1 = 0; x2 = 0;
end
fh = -r^2*(x1-v0) - 2*r*x2;
x1 = x1 + h*x2;
x2 = x2 + h*fh;
v1 = x1;
v2 = x2;
end
这个非线性TD模块的精妙之处在于参数r——它决定了参考信号的跟踪速度。在实际调试中,我通常先设r=10*wc(wc为期望闭环带宽),再根据响应微调。
2. 扩张状态观测器(ESO)
文首给出的三阶ESO代码已经展示了核心结构,这里补充一个工程实践中的改进技巧——在误差项e上加入死区补偿:
matlab复制e = y - z1_prev;
if abs(e) < 0.001 % 死区阈值
e = 0;
end
这个小改动能有效抑制测量噪声引起的观测器抖动,特别适合编码器分辨率不高的场合。
3. 参数整定实战指南
3.1 调参三件套的使用哲学
模型中的三个调节控件不是随意设计的,它们对应着ADRC的三个核心自由度:
| 控件名称 | 对应参数 | 物理意义 | 调节策略 |
|---|---|---|---|
| 跟踪速度滑杆 | wc | 闭环带宽 | 根据对象惯性决定,大惯性系统取小值 |
| 抗扰强度旋钮 | β系列 | 观测器增益 | 从低往高调,直到扰动抑制满意 |
| 平滑系数拨盘 | h | 滤波系数 | 噪声大时增大,但会引入相位滞后 |
经典调参流程:
- 将抗扰强度调到最小,此时ADRC退化为PD控制
- 调节跟踪速度,使系统响应达到理想速度(无超调)
- 逐步增大抗扰强度,观察对阶跃扰动的抑制效果
- 最后微调平滑系数,平衡噪声抑制与动态性能
3.2 参数间的耦合关系
在实际调试中,我发现这三个参数存在有趣的相互作用:
- wc与β的黄金比例:β01 ≈ 5wc, β02 ≈ 15wc², β03 ≈ 30*wc³ 这个经验公式能快速找到参数合理区间
- h的副作用:过大的平滑系数会导致ESO估计滞后,表现为控制量出现"追赶"现象
- b0的敏感性:系统增益估计误差超过50%时,控制量会出现明显振荡
这里分享一个快速估算b0的实验室方法:
matlab复制1. 给系统施加阶跃输入u_step
2. 测量稳态输出变化量y_inf
3. b0 ≈ y_inf / u_step * 0.8 (0.8为安全系数)
4. 工程应用中的避坑指南
4.1 数字实现的常见陷阱
采样周期选择:
- 经验公式:T_sample ≤ 1/(50*wc)
- 我的惨痛教训:曾在一个电机控制项目中用了10ms采样周期,结果wc调到20rad/s时就出现震荡,后来降到1ms才稳定
数值积分方法:
matlab复制% 避免使用欧拉积分(特别是四阶模型)
% 推荐采用梯形法或龙格库塔法
function [z1, z2, z3] = ESO_3rd_improved(y, u)
...
% 改用梯形积分
k1 = z2_prev + beta01*e;
k2 = z3_prev + beta02*e + u;
z1 = z1_prev + h/2*(k1 + (z2_prev + beta01*e));
...
end
4.2 实际项目中的适应性改造
非线性对象的处理:
当控制对象存在显著非线性(如机械系统的死区、饱和),需要在ESO前加入逆非线性补偿:
matlab复制u_actual = deadzone_compensate(u_desired); % 死区补偿示例
多回路协同控制:
在无人机姿态控制这类多变量系统中,我的做法是:
- 每个自由度独立设计ADRC
- 在ESO的z3项中加入耦合项估计
- 最后通过加权分配控制量
5. 模型使用进阶技巧
5.1 性能评估指标设计
为了量化ADRC的优越性,我在模型中内置了三个评价指标:
matlab复制IAE = sum(abs(e)); % 绝对误差积分
ITAE = sum(t.*abs(e)); % 时间加权误差
控制量波动 = std(u);
使用时建议对比PID控制下的这些指标,典型情况下ADRC的ITAE能降低30%-50%。
5.2 面向硬件的代码生成
模型已做好HDL Coder兼容性配置,生成嵌入式代码只需三步:
- 右键ADRC_Controller子系统
- 选择"HDL Code" → "Generate HDL for Subsystem"
- 在弹出窗口中设置目标器件类型
特别提醒:生成代码前务必检查所有数据类型的位宽,我遇到过因为默认int16导致定点运算溢出的坑。
6. 典型应用场景实测
6.1 伺服电机位置控制
测试条件:
- 对象:750W交流伺服电机
- 扰动:0.5Nm的周期性负载变化
- 对比:相同带宽下的PID控制
结果:
| 指标 | PID | ADRC | 改善率 |
|---|---|---|---|
| 定位超调量 | 4.2% | 0.8% | 81% |
| 扰动恢复时间 | 120ms | 35ms | 71% |
| 控制量波动 | 0.32 | 0.18 | 44% |
6.2 温度控制系统
某烘箱温度控制数据:
matlab复制% PID控制
Rise_time = 280s; Overshoot = 3.5℃;
% ADRC控制
Rise_time = 210s; Overshoot = 0.8℃;
关键技巧:在温度这类大滞后系统中,需要适当降低wc并在ESO中加入滞后补偿项。
这套模型虽然已经过大量实战检验,但控制领域没有放之四海皆准的解决方案。建议读者先在我的模型框架上熟悉ADRC的"脾气",再根据具体应用场景进行针对性优化。遇到任何使用问题,欢迎在GitHub仓库的issue区讨论——你踩的坑可能我已经填过,而你的创新也可能启发他人。
