做电机控制仿真这些年,被问得最多的一个问题不是“PID怎么调”,而是“负载突变一下,转速到底能不能抗住”。传统PID在标称工况下确实稳,可一旦转动惯量变了、或者负载突然加上来,控制器表现就有点狼狈。这也是我最后把目光放在自抗扰控制ADRC上的原因。这篇文章就以一台永磁同步电机(PMSM)为对象,在Simulink里完整搭建一套ADRC调速系统的仿真模型,从原理推导到参数整定、从模块搭建到抗扰验证,全程把关键细节摊开来讲,希望能帮你少走几周弯路。
如果你正在做电机驱动、伺服系统或者电力电子相关的仿真,甚至准备把ADRC移植到硬件上,这篇文章都适合你。内容偏工程实践,不搞纯理论堆砌,所有数字和调试经验都来自我实际跑过的模型。
1. 为什么PMSM调速要引入ADRC:从PID的痛点说起
1.1 PMSM控制难在哪:非线性、耦合和参数摄动
永磁同步电机的数学模型,如果写在dq旋转坐标系下,其实是这样的:
定子电压方程:
- ud = Rs·id + Ld·(did/dt) - ωe·Lq·iq
- uq = Rs·iq + Lq·(diq/dt) + ωe·(Ld·id + ψf)
电磁转矩方程:
- Te = 1.5·pn·(ψf·iq + (Ld - Lq)·id·iq)
运动方程:
- J·(dω/dt) = Te - Tl - B·ω
这里有个关键点,很多初学者容易忽略:PMSM是一个强耦合、非线性、多变量的对象。id轴和iq轴之间有交叉耦合,转速又反过来影响电压方程里的反电动势项。更麻烦的是,参数不是固定的——Ld、Lq会随电流饱和程度变化,永磁磁链ψf会随温度漂移,负载转矩Tl更是完全未知的时变量。
我们通常用矢量控制(FOC)把问题简化,在id = 0的控制策略下,转矩变成Te = 1.5·pn·ψf·iq,相当于把电机“伪装”成一个线性对象。但注意,这只是把电气耦合解耦了,机械侧的扰动、参数摄动一点都没有消失,它们仍然会通过运动方程直接影响转速。
1.2 传统PID在负载扰动和参数失配下的挣扎
PID的原理本质上是“看到误差再动手”。负载转矩一突加,转速先跌下去,误差变大,积分项才开始慢慢把转速拉回来。这个过程中的动态跌落幅值和恢复时间,就成了PID的硬伤。
具体来说有三个问题我特别有体会:
- 扰动辨识滞后:PID只能通过误差感知外界变化,误差没出现之前,控制器什么都做不了。所以负载突变必然伴随明显动态转速跌落。
- 积分饱和:转速大偏差时积分项拼命累积,等转速回来了,积分还在“泄洪”,超调随之而来。
- 参数失配:PID参数是按标称工况整定的。转动惯量J一旦变了,原本的阻尼比和带宽全变,轻则动态变差,重则系统振荡。
很多人用PI速度环时,把Kp、Ki调到某一组负载下很好看,换个负载工况就拉了。这不是PI不行,而是它天生缺乏“主动感知扰动”的能力。
1.3 ADRC的思路:把“不确定的东西”统一看成扰动
自抗扰控制的核心思想,说出来其实很朴素:与其费尽心思精确建模,不如把“所有没建模的东西”统一打包成一项总扰动,然后用观测器把它实时估计出来,在控制量里直接补偿掉。
ADRC创始人韩京清先生那句“把未知当成扰动,而不是把扰动当成未知”,我第一次看到的时候觉得像哲学,做完仿真才体会到这话的工程分量。
ADRC处理的对象可以写成这样一行方程:
- dω/dt = b0·u + f
其中u是控制量,b0是控制增益的粗略估计值,f就是“总扰动”——负载转矩、摩擦、磁链漂移、未建模动态、交叉耦合,全都在f里面。控制器要做的事情就两件:
- 通过扩张状态观测器(ESO)把f估计出来;
- 在控制律里把f抵消掉。
打个比方,PID像是一个“撞见偏差再反应”的司机,ADRC则是一个“提前感知路面颠簸、实时修正方向盘”的司机。差别不在脚法,而在有没有对未知干扰的感知通道。
2. ADRC三个核心组件在PMSM转速环里的作用
2.1 扩张状态观测器:电机模型里最关键的“黑盒猜测”
扩张状态观测器(ESO)是ADRC的核心,也是我觉得最值得多花时间理解的部分。
对于转速环的一阶模型dω/dt = b0·u + f,我们把总扰动f当成一个额外的状态变量x2,于是系统变成:
- x1_dot = x2 + b0·u
- x2_dot = h(h是扰动变化率,未知但有限)
然后构建观测器:
- z1_dot = z2 + β1·(ω - z1) + b0·u
- z2_dot = β2·(ω - z1)
这里的z1用来跟踪实际转速ω,z2用来跟踪总扰动f。β1、β2是观测器增益,通常用带宽法取:
- β1 = 2·ωo
- β2 = ωo²
其中ωo叫做观测器带宽。这个参数一上去,整个ESO的收敛速度就定下来了。
我在调试过程中最直观的感受是:z2曲线就像电机的“扰动心电图”。负载突变时,z2立刻跳变,比转速误差信号来得更早更直接。控制器正是靠这个信号才做到“扰动刚出现、补偿就到位”。
2.2 跟踪微分器:让给定信号平滑过渡
跟踪微分器(TD)负责给参考转速安排一个过渡过程。它接收阶跃形式的转速给定,输出一条平滑的跟踪轨迹v1和它的近似微分v2:
- v1_dot = v2
- v2_dot = -r·sat(v1 - ωref, v2, r)
如果不要TD,直接把阶跃给定丢给控制器,转速追一个阶跃,超调几乎难免。ADRC里的TD相当于给阶跃信号“提前化妆”,让它变成一个平滑加速曲线,转速自然无超调。
不过这里我要说一句实际经验:很多工程化LADRC方案里TD是可以省略的。只要ESO带宽足够、观测器收敛快,转速环本身对给定阶跃的响应也比较平滑。TD的作用更多体现在“大给定变化+极短加速时间”的场景,比如伺服点位控制。做PMSM仿真时,我建议先不加TD,跑通了再看需求决定是否补上。
2.3 状态误差反馈:线性和非线性两种路线
ADRC的最后一块拼图是状态误差反馈控制律。它把给定信号的状态和观测器估计的状态做差,然后进行反馈控制。
线性风格(LSEF)非常简单:
- u0 = kp·(v1 - z1) + kd·(v2 - z2)
非线性风格(NLSEF)则引入fal函数:
- u0 = k1·fal(e1, a1, δ) + k2·fal(e2, a2, δ)
其中fal(e, a, δ)的定义是:当|e| > δ时取|e|^a·sign(e),否则取e / δ^(1-a)。
非线性的好处是小误差时高增益、大误差时增益自动受限,鲁棒性更强;代价是参数多、线性度差、整定难度上升。而线性ADRC(LADRC)可以用带宽法直接给出全部参数,工程上极其方便。
我在仿真里先跑通LADRC,再对比NLADRC,两者的性能差距在PMSM这个对象上其实没有理论文章里说的那么神秘——线性结构调好了,抗扰效果已经很能打。这点值得提醒:不要一上来就迷信非线性版本,线性版本能让你更快理解ADRC的工程本质。
2.4 转速环ADRC的数学模型推导
现在把ADRC落到PMSM转速环上。从运动方程出发:
- J·(dω/dt) = 1.5·pn·ψf·iq - Tl - B·ω
整理成标准形式:
- dω/dt = (1.5·pn·ψf/J)·iq + (-Tl/J - B·ω/J)
如果我们把控制量u定义为iq的参考值,并取b0 = 1.5·pn·ψf/J,那么:
- dω/dt = b0·u + f
- f = -Tl/J - B·ω/J + (b0真实值 - b0估计值)·u
最后这一项很重要,它意味着即使你J、ψf猜得不准,这部分误差也会被折进f里,交由ESO去估计并补偿。这就是ADRC对参数失配宽容的数学根源。
注意一个细节:ADRC转速环的输出是iq的参考值,不是直接给电压。电流环仍然用PI(或者内模控制)去快速跟踪这个电流指令。ADRC负责机械动态,电流环负责电气动态,两者带宽拉开,系统才有稳定的大前提。
3. Simulink仿真模型搭建实操
3.1 模型整体架构与模块划分
Simulink里搭这个系统,我推荐按功能把模型拆成几个子系统,方便排查问题:
- 给定与测量子系统:转速给定、转速反馈、电流测量;
- ADRC速度环子系统:输入为转速给定和实测转速,输出为iq参考值;
- 电流环PI子系统:内环,输出uq参考值;
- 坐标变换子系统:Clark、Park变换,把三相电流变到dq轴;
- PMSM本体子系统:dq方程积分得到id、iq、转矩、转速;
- 逆变器与调制子系统:SVPWM或简化的PWM调制,把dq电压指令变成三相电压。
我实际建模时用数学方程直接搭PMSM本体,不用大库里的封装模块。这样做的最大好处是每一个中间变量都能拉出来看波形,对理解电机内部动态非常有帮助。等模型验证成熟,再切换到Simscape的电机模块也不迟。
3.2 PMSM数学本体与坐标变换搭建
PMSM本体的核心是dq坐标系电压方程加运动方程。用Simulink标准模块就能搭:
- 电压方程右侧的反电动势项ωe·Lq·iq、ωe·(Ld·id + ψf)要单独计算;
- 积分出id、iq后,再算出Te;
- 运动方程J·(dω/dt) = Te - Tl - B·ω积分出机械角速度ωm,再乘极对数pn得到电角速度ωe;
- 电角度θ = ωe的积分,作为Park变换的夹角。
坐标变换我给一个常用写法,等幅值变换:
Clark变换:
- iα = ia - 0.5·ib - 0.5·ic
- iβ = (√3/2)·(ib - ic)
Park变换:
- id = iα·cosθ + iβ·sinθ
- iq = -iα·sinθ + iβ·cosθ
在Simulink里用Fcn模块写这些公式,再配合Gain模块和Sum模块,几分钟就能搭完。实测一个容易踩的坑是:Park变换和反Park变换用的角度必须是电角度,机械角度要乘以极对数pn,否则电流波形完全对不上。我最初就错在这里,id、iq全是振荡的交流量,一度以为换向角算错了。
3.3 逆变器和PWM调制的基本处理方式
逆变器部分我有两种做法,取决于当前仿真阶段:
- 理想受控电压源模式:直接把ud、uq经过反Park变换得到uα、uβ,再用“电压源+电机模型”喂给定子相电压。省掉PWM开关过程,模型跑起来非常快,适合先验证ADRC控制逻辑。
- 真实PWM调制模式:用Universal Bridge加PWM Generator,加入直流母线电压和开关频率,模拟真实开关过程。这时候电磁转矩会带高频纹波,转速环的观测器设计需要留出滤波余量。
我的建议很明确:第一次做ADRC仿真,先用理想模式把算法逻辑跑通,别让PWM的开关毛刺干扰你观察ESO的特性。等控制参数整定得差不多了,再切换PWM模式验证实际效果,这样排查问题会快很多。
3.4 ADRC子系统的Simulink实现细节
ADRC速度环子系统的输入输出定义我这样安排:
- 输入1:转速参考值ωref
- 输入2:实测转速ω
- 输出:iq参考值
子系统内部的ESO部分,用两个积分器串联:
- z1积分器前:z2 + β1·(ω - z1) + b0·u
- z2积分器前:β2·(ω - z1)
积分器初值设置有个细节:z1的初值应设为电机的初始转速,否则启动瞬间ESO会有一个收敛过程;z2初值设为0即可。控制律部分:
- u0 = kp·(ωref - z1) + kd·(0 - z2) (如果不加TD,直接把ωref当作给定)
- u = (u0 - z2) / b0
注意kp、kd和带宽的关系,后面参数整定章节再说。
搭建时还要小心一个高频问题:如果子系统内部ESO输出和控制量u之间存在直接代数回路,Simulink会报代数环。解决办法是在iq参考值输出之后加一个Memory或Unit Delay模块,打破这个回路;或者干脆把ADRC做离散化,用离散积分器实现。
4. 参数整定:带宽法与实操调参流程
4.1 基于带宽的LADRC参数化方法
LADRC能流行,一个关键原因是参数少且好整定。对转速环这种一阶对象,ADRC需要定的参数只有三个:
- 控制增益估计b0
- 控制器带宽ωc
- 观测器带宽ωo
带宽法给的标准取法:
- 观测器增益:β1 = 2·ωo,β2 = ωo²
- 控制器增益:kp = ωc,kd = 2·ωc(如果控制律用P+扰动补偿,一个ωc就够)
刹车逻辑记住一条原则:观测器带宽要比控制器带宽快3到10倍。控制器带宽决定了期望的闭环响应速度,观测器带宽决定了扰动估计的收敛速度。观测器太慢,补偿总是慢半拍;观测器太快,噪声被放大,电流指令全是毛刺。
电流环PI可以先用标称参数跑通,作为速度环的“内部执行器”。常见做法是让电流环带宽比转速环带宽高5到10倍,保证内环不拖外环后腿。
4.2 一组可直接跑的初始参数示例
我用一台典型的小功率PMSM做过验证,参数如下,大家可以先用这组数把模型跑起来再调。
电机参数:
| 参数 | 符号 | 取值 | 单位 |
|---|---|---|---|
| 极对数 | pn | 4 | - |
| 定子电阻 | Rs | 2.875 | Ω |
| d轴电感 | Ld | 8.5 | mH |
| q轴电感 | Lq | 8.5 | mH |
| 永磁磁链 | ψf | 0.175 | Wb |
| 转动惯量 | J | 0.001 | kg·m² |
| 阻尼系数 | B | 0 | N·m·s |
ADRC初始参数:
| 参数 | 取值 | 说明 |
|---|---|---|
| b0 | 1050 | 由1.5·pn·ψf/J估算 |
| ωc | 30 rad/s | 转速环期望带宽 |
| ωo | 150 rad/s | 观测器带宽,5倍ωc |
| β1 | 300 | 2·ωo |
| β2 | 22500 | ωo² |
对应MATLAB初始化脚本可以这样写:
% PMSM参数 pn = 4; Rs = 2.875; Ld = 8.5e-3; Lq = 8.5e-3; psi_f = 0.175; J = 0.001; B = 0; % ADRC速度环参数(LADRC) b0 = 1.5 * pn * psi_f / J; % 实际=1050 omega_c = 30; % 控制器带宽 omega_o = 5 * omega_c; % 观测器带宽 beta1 = 2 * omega_o; beta2 = omega_o^2; kp = omega_c^2; % 若用二阶误差反馈 kd = 2 * omega_c; % 电流环PI参数(标称工况下先给一组可用值) Kp_i = 15; Ki_i = 2500;注意b0的计算公式里,如果按标准一阶LADRC模型,控制量是iq,那么b0 ≈ 1.5·pn·ψf/J,单位是rad/(s²·A)。算出来确实在1000量级,这个数量级在仿真和硬件调试里都很典型。
4.3 从PID参数“迁移”到ADRC的经验
很多从PID转过来的同学,第一反应是把ωc设得和PI的穿越频率差不多大。这个直观感觉是对的,但我吃过亏:把ωc一把拧到100以上,转速环立刻开始抖动,iq波形高频振荡,ESO的z2也跟着抖。
原因在于ωc只是“理想控制带宽”,实际能跑多大,还要看电流环响应和转速反馈噪声。我更推荐的整定流程是:
- 先把电流环PI调稳,确保iq对指令的跟踪带宽足够;
- 速度环ωc从20开始,给一个1000rpm阶跃,看转速上升时间;
- 逐步增大ωc,每次加20%,观察转速响应和iq纹波;
- 一旦出现高频抖动,退回到上一个稳定值,然后保持ωc不变;
- 再增大ωo,观察抗扰能力的边际收益,直到噪声开始变得刺眼为止。
这套流程本质上是在“响应速度”和“噪声容忍度”之间找平衡点。实测下来,把ωo取到3~8倍ωc通常比较均衡,5倍是最常用的起步值。
5. 仿真验证与抗扰测试结果分析
5.1 空载阶跃响应测试
第一个验证场景是空载阶跃。给定转速从0直接跳到1000rpm,观察ADRC和传统PI控制下的转速响应差异。
我模型里设置的仿真条件:定步长,步长取1e-6s,算法用ode4(四阶龙格库塔),保证数值精度足够。在这个条件下:
- PI控制:转速超调约8%,调节时间约0.2s,iq电流启动时有明显大电流冲击;
- LADRC:转速基本无超调,上升时间约0.1s,调节时间约0.15s,启动电流峰值更低。
更让我注意的是ESO的z2输出。启动瞬间,z2从0开始迅速偏转到一个正值然后回落,它实际上是在“观察”启动阶段那些未建模的转矩项。把这个曲线拉出来和实际扰动对比,你会直观感受到什么叫“观测器把看不见的东西看见了”。
5.2 负载突变与扰动补偿效果
第二个场景是抗扰能力的核心测试:在0.5s时突加50%额定负载转矩,0.8s时突卸。我把PI和LADRC的转速动态放在一起对比:
| 指标 | PI控制 | LADRC |
|---|---|---|
| 突加负载时转速跌落 | 约30rpm | 约5rpm |
| 恢复时间 | >0.3s | 约0.08s |
| 突卸负载时转速抬升 | 约25rpm | 约4rpm |
LADRC之所以抗扰强,靠的就是ESO的z2。负载突加瞬间,z2立刻跳变捕捉到扰动变化,控制律马上在iq参考里增加补偿分量,相当于“扰动刚有苗头就被压下去”,这已经超出了传统PID“先偏差后补偿”的时序逻辑。
这个测试是ADRC价值的试金石,建议大家一定不要跳过。我会把z2曲线和实际负载波形放在同一个Scope里看,那种“z2几乎同步跟随负载趋势”的画面,比任何理论分析都有说服力。
5.3 参数失配鲁棒性对比
第三个场景我要重点说,因为它最能体现ADRC的工程价值。把转动惯量J从0.001直接放大5倍到0.005,控制器结构参数不动:
- PI控制:转速响应变得迟钝,突加负载时跌落更大,恢复时间翻倍,甚至可能出现轻微振铃;
- LADRC:转速响应几乎不变,抗扰性能下降幅度很小。
原因就在于ADRC把未建模动态全部视为总扰动f。J变化后,真实控制增益偏离b0的差异会被计入f,ESO主动补偿掉。仿真里我还试过把磁链ψf在运行中人为改变20%,LADRC照样能维持稳定。这种对参数漂移的“钝感力”,在电机发热、磁钢退磁、机械连接松动等实际场景里非常实用。
6. 调试过程中的三个坑与解决方案
6.1 代数环问题:为什么仿真跑不动
第一次搭ADRC模型时我遇到了一个典型问题:变步长仿真起始就报“代数环”错误,或者仿真运行极慢、步长自动缩小到几微秒。
原因在于ESO的输出间接参与了控制量u的计算,而u又作为ESO输入,形成了一个围绕ADRC子系统的代数回路。Simulink检测到这种没有延迟的闭环,就只能靠数值迭代硬解。
解决办法有两个:
- 在ADRC子系统输出iq_ref后串一个Memory或Unit Delay模块,打破代数回路;
- 把ESO和控制律做离散化,用离散积分器实现,从根本上避免代数环。
我的建议是后者,因为离散化ADRC更贴近后续嵌入式移植的写法,跑仿真也更稳。
一个容易忽略的细节:如果加了Unit Delay,相当于控制量滞后了一个仿真步长,这会降低相位裕度。离散化时建议把控制律里的计算顺序重排一下,让补偿量先算、再更新观测器状态,这样滞后影响最小。
6.2 ESO带宽过大引起的高频噪声
市面上的ADRC资料都会提醒“ωo不能太大”,但实际踩坑的体验不太一样:刚开始总嫌扰动估计不够快,一鼓作气把ωo调到300、500,结果转速波形没问题,iq指令上却出现密密麻麻的高频毛刺。
这是因为转速反馈信号里本来就包含测量噪声、数值噪声和PWM开关纹波,ESO带宽越高,对这些高频分量的放大越严重。z2本来应该平滑跟踪扰动,结果变成了噪声放大器。
我的处理经验:
- 先把ωo降回3~5倍ωc的水平,确认噪声消失;
- 如果确实需要更高观测带宽,在转速测量通道加一阶低通滤波器,截止频率放在电流环带宽附近;
- 更彻底的办法是在iq_ref输出端加一个限速或一阶滤波,抑制控制量的高频分量。
要记住一个工程原则:观测器带宽不是越高越好,而是“够用就行”。扰动的主要成分频率通常远低于噪声频率,留出足够裕量即可。
6.3 b0与J取不对时的表现
b0是ADRC里唯一跟模型有关的参数,它的准确性会直接影响控制品质。仿真里故意试错会发现两种典型表现:
- b0取大(比如取实际值的1.5倍):等效控制器增益偏高,系统会趋向振荡,iq波形出现明显振铃;
- b0取小(比如取实际值的0.5倍):扰动补偿强度不足,抗扰响应变慢,转速跌落变大。
怎么判断需不需要改b0?我的经验是看z2的“工作状态”。理想情况下z2应该主要反映负载等外部扰动,如果z2波形与iq指令高度相关、控制量一变化z2立刻大幅波动,很可能b0偏差过大。
实际工程中很难拿到精确的J和ψf,我的做法是把b0按标称参数的70%~100%之间取值,故意留出一点补偿余量。因为b0略小时系统还能靠ESO补,b0过大则容易出现不稳定振荡。这个“保守取b0”的经验在仿真和硬件里都帮我省了不少事。
最后再说一点个人的调试体会:ADRC最大的魅力不在于参数有多神奇,而在于它让你从“拼命建精确模型”转向“认真看待未知扰动”。我在把转速环从PI切到LADRC之后,最大的改变是养成了一个习惯——每次调完参数,都会盯着ESO的z2曲线看一会儿。那根曲线几乎能把电机的“真实处境”都讲出来:负载变化、参数漂移、非线性摩擦,全写在上面。对做电机控制的人来说,这种“看得见扰动”的能力,比任何漂亮的理论都让人踏实。