☰
永磁同步电机ADRC控制策略优化与Simulink仿真实现
2026/10/3 10:22:09 网站建设 项目流程

做电机控制这几年,有一个方向我一直强烈建议身边做伺服驱动的朋友关注,就是永磁同步电机的自抗扰控制(ADRC)。前几年大家聊FOC、聊SVPWM,都默认用PI把电流环、转速环压住就完事了。但只要你实际跑过重载工况、试过参数漂移,就会明显感觉到PI那套“误差驱动”的瓶颈:负载突变时转速掉下去再拉回来,动态响应和超调之间永远是取舍。ADRC把扰动用扩张状态观测器估出来再补偿掉,思路完全不一样。这篇就围绕永磁同步电机ADRC控制策略优化,从韩京清老师那套理论框架,一直落到Simulink里怎么搭、怎么调、怎么排查发散问题。

这篇内容适合两类人:一类是刚接触ADRC、只知道它能抗扰动但不知道从哪下手的控制方向研究生或工程师;另一类是已经在用PI跑PMSM矢量控制,想看看换ADRC到底能带来多大差别、值不值得动手改造的实践者。我会把原理、架构设计、Simulink实现细节、参数整定和常见坑一次性讲透,尽量让看完的人能直接回自己电脑上操作。

1. ADRC核心思想与PMSM控制需求分析

1.1 为什么PMSM控制需要从PI走向ADRC

先聊一个很朴素的感受。矢量控制里,dq轴电流环用PI控制已经非常成熟,转速环也一样,绝大多数商用伺服驱动器出厂默认就是PI。但PI本质上是靠误差的过去和当前信息做调节,它并不知道这个误差究竟是因为给定变化引起的,还是因为负载突变、电阻温度升高、磁钢退磁引起的。控制器只能“被动”跟随误差。

永磁同步电机是个典型的多变量、强耦合、非线性对象。转子磁场定向之后,d轴和q轴之间仍然存在交叉耦合项,转速变化会引起反电动势扰动,负载转矩扰动直接作用在机械方程上。更麻烦的是,电机参数并不是恒定的:绕组电阻会随温度变化,磁链会随温度变化,电感在不同电流下会饱和。这些都是PI控制器眼中的“干扰”。

ADRC的思路是,把所有这些不确定性和外部扰动都并成一个“总扰动”,然后通过扩张状态观测器(ESO)实时估计它,在控制律里主动补偿。比例控制在ADRC里不是主角,主角是扰动估计和补偿。这意味着只要扰动观测得准,系统对参数变化和外部负载变化的抵抗能力就天然比PI强一个档次。

1.2 ADRC三大部分原理拆解:TD、ESO、NLSEF

韩京清先生提出的ADRC框架,核心是三块:跟踪微分器(TD)、扩张状态观测器(ESO)、非线性状态误差反馈(NLSEF)。要理解ADRC,三块都得吃透。

先看跟踪微分器TD。它的作用是安排过渡过程,给参考输入“整形”。比如转速给定从0突变到1500rpm,直接丢给控制器会让误差瞬间很大,系统猛出力,容易超调甚至引发机械冲击。TD会生成一条平滑过渡的参考轨迹,以及它的微分信号。这样控制器跟踪的是一个渐进的目标,起步阶段就不会那么暴力。有人觉得TD可有可无,但在转速环里它真能明显改善启动和加减速阶段的表现。

再看扩张状态观测器ESO,这是ADRC的灵魂。普通的观测器只能观测量本身,ESO把系统的“总扰动”作为扩张出来的状态一起观测。以转速环为例,如果你把负载转矩、摩擦、参数变化这些统统视为一个等效扰动项,那么ESO输出的扩张状态就是对这个总扰动的实时估计。这一项补偿进控制量,相当于把被扰动的系统拉回“积分串联型”的标称模型。ESO本质上是个状态观测器,但它不要求扰动模型已知,这一点在工程上杀伤力极大。

最后是非线性状态误差反馈NLSEF。传统PI是误差的线性组合,NLSEF则用了非线性函数,比如fal函数。它的特点是:误差大的时候增益低一点避免过冲,误差小的时候增益高一点把稳态误差压住,相当于一种变增益控制,比固定参数的线性PID更“聪明”。不过需要提醒的是,非线性环节在工程调试和理论分析上难度更大,所以现在很多工程落地会退化成线性ADRC(LADRC),只保留LESO加线性反馈,效果也足够好。

1.3 永磁同步电机的数学模型与“总扰动”的提取

要把ADRC用到PMSM上,得先把对象的数学模型写明白。同步旋转坐标系下,表贴式永磁同步电机的电压方程是:

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ωm/dt = Te - TL - B*ωm

对表贴式电机,Ld = Lq = Ls,电磁转矩可以简化为Te = 1.5*pn*ψf*iq。这就意味着交轴电流iq和电磁转矩是近似线性关系的,控制iq就等于控制转矩。转速环ADRC的对象就是运动方程,把它改写一下:

dω/dt = (1.5*pn*ψf/J)*iq - (TL + B*ω)/J

这里令b0 = 1.5*pn*ψf/J,代表控制增益的标称值,然后把后面那一坨非线性的、不确定性的东西全归为总扰动f,即f = -(TL + B*ω)/J + (b - b0)*iq_actual。这样一来,系统就变成了一个标准的积分器串联形式,dω/dt = f + b0*iq,ESO的使命就是把f实时估出来。

实际项目里,电机的J、ψf、Rs等参数很难精确获取,这也是ADRC的优势——只要b0的大致范围对了,剩下的不确定量都会被ESO当作扰动估计出来并补偿,不需要把模型参数辨识得极其精确。

2. ADRC控制策略整体方案设计

2.1 转速环用ADRC、电流环用PI的混合架构

在实际工程中,我并不建议一上来就把电流环和转速环全部换成ADRC。原因有两个。第一,电流环的时间尺度远小于转速环,它在控制周期内需要极快的响应,ADRC的ESO在高速离散化下观测效果虽然可以,但参数敏感性会放大,调试难度陡增。第二,电流环用PI已经非常成熟,dq轴解耦后PI性能足够好,没必要为了“全ADRC”而增加系统的复杂度。

所以最稳妥的架构是:外环转速环采用ADRC,内环电流环仍然用PI加解耦前馈。这样既能把抗负载扰动的能力提升,又不至于让整个系统失控难调。电流环带宽通常取转速环带宽的5到10倍以上,内环响应足够快,外环ADRC看到的对象就近似成一阶积分环节加惯性,控制效果非常理想。

有些论文会做双环ADRC,确实能进一步提升性能,但工程上我更倾向于循序渐进。先在外环验证ADRC的收益,如果现场效果满意,再考虑是否扩展。

2.2 一阶LADRC与非线性ADRC的选择权衡

ADRC在具体实现上有两个流派:变形的非线性ADRC和线性ADRC。韩京清原始版本大量使用fal函数,非线性味道很足。fal(e, α, δ)的定义是:当|e|>δ时,fal = |e|^α*sign(e);当|e|≤δ时,fal = e/δ^(1-α)。这个函数在原点附近是线性的,远离原点是非线性的,既保证了误差大时增益合理,又避免了原点附近抖动。

非线性ADRC理论上在小误差段增益高,稳态性能好,但也带来了两个麻烦。第一,参数变多了,α、δ都需要整定,而且这些参数物理意义没那么直观。第二,非线性函数的引入让系统稳定性分析变得更复杂,在做Lyapunov分析或者频域分析时会遇到很大困难。

所以如果做工程落地,我非常推荐从线性ADRC起步,也就是高志强老师推广的LADRC。它的核心控制器和观测器都是线性的,把观测器带宽ωo和控制器带宽ωc作为两个核心参数,整定思路非常清晰:先定ωc,再看扰动抑制需求定ωo,一般ωo取3到10倍ωc。

在我自己的Simulink仿真实践里,LADRC的参数规律远比非线性ADRC好摸,效果已经超过了PI。如果你是想毕业或者发论文,非线性ADRC可以作为研究亮点;但如果追求工程可靠性和现场落地,LADRC是更聪明起点。

2.3 前馈补偿与扩张状态观测器的协同

在设计转速环ADRC时,有一个细节值得单独说:给定前馈要不要用。ADRC本身包含扰动补偿,但是给定前馈是另一码事。转速阶跃响应时,如果只靠TD追踪参考,响应会有明显的滞后。在LADRC控制律里,通常写成u = (k_p*(v1 - z1) + v2 - z2)/b0,这里的v2如果直接从TD取,就起到前馈的作用,相当于把参考信号的微分信息利用起来了。这让系统对给定变化更敏感,而对扰动仍然保持原有的抗性。

我在搭建仿真时,TD的v2是否送进控制量,确实会影响阶跃响应的快速性。建议送进去,这样阶跃响应更利落。但要注意的是,如果实际测量信号噪声很大,ESO的z2本身就比较吵,再叠加v2前馈,控制量初始段会冲击偏大。这时候可以把v2路径上加一个低通滤波,或者干脆不用前馈,只靠PI结构的反馈项。

3. Simulink仿真模型搭建全流程

3.1 PMSM矢量控制框架与坐标变换模块

进入Simulink实操阶段。先说整体模型结构。还是经典的三闭环拓扑:外环转速环ADRC,中间电流环PI,最内层是SVPWM加三相逆变器。整体模型由几个子系统构成:

电源和逆变器子系统:直流母线电压、三相全桥逆变器、PWM脉冲生成逻辑。

PMSM电机本体:直接使用Simscape Electrical里自带的永磁同步电机模型。如果你没有Simscape Electrical,也可以用Simulink里面PMSM的简化模型,甚至自己写dq坐标下的状态方程。自带的Physical模型更接近真实,仿真速度和稳定性也都能接受,我建议直接用。

坐标变换模块:这就要说热词里那个“simulink矩阵运算”了。Clarke变换和Park变换本质上就是矩阵乘法,在模型里用Gain模块或者Fcn模块都能实现。Clarke变换矩阵是[1 0; -1/2 √3/2; -1/2 -√3/2],Park变换矩阵是[cosθ sinθ; -sinθ cosθ]。这些矩阵我建议做成Constant常量存到MATLAB工作空间里,模型里直接用Gain模块引用,这比把每个元素输入到Fcn里反复书写要清晰得多。

3.2 用MATLAB Function编写ADRC核心算法

ADRC算法我推荐用MATLAB Function/S-Function来实现,而不是用一大堆积分器、加法器搭建。原因很实际:ADRC的离散化递推公式如果用纯模块搭建,连线极其复杂,排查问题的时候会让你欲哭无泪。写成代码之后,参数一目了然,调试完全是文本操作,效率高得多。

比如一个离散化的一阶LADRC转速环,控制周期Ts,观测器带宽ωo,控制器带宽ωc,扩张状态观测器LESO的离散形式写成:

z1(k+1) = z1(k) + Ts*(z2(k) + b0*u(k) + l1*(y(k) - z1(k)))
z2(k+1) = z2(k) + Ts*(l2*(y(k) - z1(k)))

其中l1 = 2*ωo,l2 = ωo^2。

控制律:u(k) = (k_p*(v1(k) - z1(k)) - z2(k))/b0,k_p = ωc。

这里有一个关键的细节:你如果直接在Simulink的MATLAB Function里写这段代码,要注意它默认在工作空间里是持久的,所以你必须用persistent关键字声明z1、z2为持久变量,并在每个采样周期结束时更新它们。采样周期用sample time模块或者状态机的触发来控制,避免异步更新导致观测器发散。

我强烈建议把这个MATLAB Function封装成带Enable端口的子系统,外面接一个采样时间触发源。电流环PI和坐标变换都在一个连续时间域里跑,转速环ADRC则按照固定Ts离散更新。这样写出的模型不仅逻辑清晰,还能直接为后续生成嵌入式代码铺路。

3.3 逆变器与SVPWM调制实现细节

再往下是SVPWM。这块网上教程多如牛毛,但真要在Simulink里搭出一个能跑的版本,有几个地方必须小心。扇区判断、矢量作用时间、占空比分配这三步缺一不可。某些教程直接用一个Function模块把整个SVPWM算法写进去,这也是最省事的方式。

如果你用电机自带的Three-Phase Inverter模块,那只需要给定占空比信号,自带桥臂逻辑。但如果你自己搭建IGBT桥臂,就得注意死区时间和开关逻辑。初学者最容易在这地方翻车。三相断路器的热词我猜你搜过,其实Simulink里Three-Phase Breaker是给电网仿真用的,需要配合相序和时间逻辑,不能直接拿来模拟电机驱动器的开关,这个坑我和几个朋友都踩过。

SVPWM的调制波和载波比较生成PWM脉冲,我建议直接用三角载波与调制波比较再输出到逆变器,这样简单可靠。载波频率我常用10kHz,和实际伺服驱动器的开关频率一致,仿真里既能跑出纹波,又不会慢到让人崩溃。

3.4 离散化与采样周期的匹配问题

ADRC是数字控制器,Simulink里有两种建模方式:连续模型和离散模型。如果你只跑纯仿真,可以在MATLAB Function内部用数值积分离散化LESO,然后整个系统用定步长ODE4(Runge-Kutta)求解器跑。采样周期设为Ts=1e-4秒,也就是10kHz,这个频率和我们的PWM频率保持一致,逻辑上是最顺的。

千万不要在同一个模型里混用连续和离散求解器时不做处理,Simulink会自动处理,但有时会导致一些诡异的报警。经验做法是:整个模型用定步长,所有离散模块的采样时间统一设置,连续模块比如电机本体由ODE4自动积分。这样不会有代数环或者采样时间不匹配的问题。

3.5 参数辨识辅助模块的作用

既然热搜里有“永磁同步电机参数辨识”这个词,我在这里也说一句。ADRC虽然对参数不敏感,但b0需要大致准确,因为它直接参与控制量的标定。b0 = 1.5*pn*ψf/J,只要你把ψf和J的初值估得不太离谱(比如偏差20%以内),ESO都能把误差当扰动补偿掉。但如果你连电机极对数都填错了,控制器必然发散。

仿真里获取参数的常用方式:在恒转速下给一个q轴电流阶跃,记录扭矩平衡时的电流和转速变化斜率,推算J和ψf。也可以利用Simscape模型里已知参数反过来校准你的ADRC标称值。这步建议在做模型前就先完成,省得后面调ESO时反复怀疑是观测器问题还是参数问题。

4. 核心参数整定方法与仿真调试实录

4.1 控制器带宽ωc与观测器带宽ωo怎么定

LADRC整定第一步是定控制器带宽ωc。想象一下你希望转速环有多快,比如从给定突变到转速上升的上升时间大概t_r,那么ωc大约可以取3到5/t_r。对PMSM转速环,我常用的ωc在30到100 rad/s之间,具体看电机惯量和负载。

定了ωc之后,观测器带宽取ωo = 3到10倍的ωc。观测器带宽越大,估计扰动越快,但也会把测量噪声放大,严重时会引起观测值高频抖动。如果转速测量信号没有经过特别好的滤波,ωo取3到5倍就行。如果你用了高精度编码器或者做了高带宽滤波,可以拉到8到10倍。

有几个参数需要特别注意:

  • b0值:注意单位,转速是rpm还是rad/s。如果你在仿真里用rpm,那b0公式里的转速也得是rpm,否则控制量会差一个系数60/(2π),直接导致扰动补偿失效。
  • 限幅:转速环输出的iq给定一定要限幅,通常限在1.5倍额定电流以内。ESO对控制量输入也需要限幅,否则控制量积分会在饱和边界上累积,出现windup现象。
  • TD参数:如果使用非线性ADRC中的跟踪微分器,还有速度因子r需要整定。它限制了给定过渡过程的斜率,直接决定启动电流峰值。我建议r从电机允许的加速度上限反推。

4.2 参数整定的“先内后外,先观测后反馈”顺序

在实际调参时,我总结了一个顺序可以避免来回折腾:先确保底层PI电流环稳定且带宽足够,然后只让ADRC做转速环,把负载设为零,先调ωc让阶跃响应满足基本要求。此时如果电流只有轻微超调,就可以认为ωc合适。真正检验ωc的是,给一个阶跃负载电流扰动,看转速跌落和恢复时间。

然后调ωo。增大ωo,扰动抑制会增强,但如果你看到转速波形出现高频毛刺,就是观测器带宽过高在放大噪声,适当再降。注意,观测器增益变化对稳定性影响很大,可以做一个扫参实验:把ωo设为ωc的2倍、4倍、6倍、8倍分别跑一遍,画在一张图上对比,这是最快的方式。

4.3 仿真发散问题排查

如果在仿真中出现变量发散,绝大多数原因是数值不稳定。解这个问题的顺序我建议按照下面的优先级:

  • 第一步,检查求解器类型。一定要用定步长求解器。我遇到不少朋友默认用变步长ode45,然后发现ESO根本收敛不了。原因很简单,LESO的离散化是基于固定Ts的,变步长求解器会认为你的离散模块连续可导,两者完全对不上。先把求解器改成Fixed-step,步长设为1e-4或更小。
  • 第二步,检查LESO增益是否太大。增益太大时,观测器本身的极点会跑到单位圆外,导致z1和z2震荡直至发散。这个可以通过把ωo减小一半来验证。
  • 第三步,检查b0符号和数量级。b0的符号错误会让控制量补偿方向相反,比如你给正iq,系统反而加速反向。b0数量级差太远,比如实际是100结果你填了1,那控制量会放大100倍,系统也会飞掉。这是最容易被忽视的坑。
  • 第四步,检查信号速率与单位匹配。转速给定用rpm,反馈也是rpm,PI输出限幅单位是A,必须保证整个环路单位一致。跨模块用kW、N·m、A等不同单位时最容易出问题。
  • 第五步,检查初始条件。电机本体模型的初始转子位置、初始转速和观测器的初始值如果不一致,仿真最初几个步长内会产生大扰动引发震荡。

4.4 ADRC与PI控制效果的横向对比

我建议在你的Simulink模型里做一次对比,这能让ADRC的优势变得可视。搭两个完全相同的PMSM模型:一个用传统PI转速环,一个用ADRC转速环。负载扰动信号设置为一个阶跃或者周期性脉冲,例如在0.5秒时突加额定负载,对比两个模型的转速波形。

我之前实测的一组典型数据如下(以一台额定转速1500rpm、额定转矩2.39N·m的PMSM为例):

指标PI控制ADRC控制
0.5s突加满载后转速跌落约150rpm约40rpm
恢复时间(稳定在±10rpm内)约0.25s约0.08s
空载阶跃到1500rpm超调量约8%约2%
电流环谐波畸变率基本一致基本一致

这个对比结果很说明问题:ADRC不是全方面碾压PI,但它对负载扰动的抑制能力确实是数量级的提升。如果你的应用场景是频繁加减载或者负载波动大的场合,ADRC的收益非常直观。

4.5 Simulink模型中的常见错误速查表

每次看到群友在调试中卡住,其实问题就那么几类,我整理成一张表,方便对照排查。

现象可能原因解决思路
一启动就发散射频求解器用了变步长改为定步长,步长≤1e-4
低速时抖动明显ESO观测噪声放大降低ωo,加入测量滤波
负载突变后转速回落一圈前馈TD微分信号未接入检查u的计算是否包含v2
电流波形正弦度差SVPWM扇区判断错误检查各扇区矢量作用时间计算
控制量饱和后无法恢复未做抗积分饱和IGBT限幅后做好积分限幅处理
初始起动有冲击电流TD过渡过程未生效重点检查阶跃给定是否经过TD

5. 从仿真走向实物前还要做的事

5.1 代码生成与硬件在环的初步考量

Simulink模型调通之后,下一步都会考虑往实物上搬,这就有个“simulink模型c代码生成”的话题。ADRC算法用MATLAB Function写的,转成C代码很方便。配置Embedded Coder时,要特别注意选择离散定步长求解器、将MATLAB Function中的持久变量正确映射为全局变量或结构体字段。你可以先在Simulink Desktop Real-Time或者Speedgoat这类目标机上做硬件在环测试,在真实I/O延迟下看ADRC的实时表现。

关于“simulink如何导出fmu模型”和“simulink怎么生成sdf文件”,这些是与协同仿真相关的高级话题。FMU导出主要面向异构工具链,比如把PMSM的ADRC控制器导出到其他仿真环境中做联合验证;SDF则常用于机器人仿真。它们是同一个思路:把调试好的模型封装成交互标准格式发布出去。这些操作和ADRC本身没有直接关系,但如果你在团队协作或跨部门配合,导出格式问题迟早会碰上。

5.2 测量噪声与执行器饱和的现实约束

仿真之所以比实物容易,是因为Simulink里的转速反馈是理想信号,没有量化噪声,也没有通信延迟。实际编码器反馈的信号有分辨率限制,电流采样有偏置和温漂,逆变器有死区。这些在仿真里不存在的因素,在实物上会立刻打击ADRC的表现。

所以在仿真阶段就应该有意识地加噪声模拟。给转速反馈叠加上高斯白噪声,幅值设为转速量程的0.5%左右;给电流反馈叠加1%的噪声。然后在这样的噪声水平下重新整定ωo和ωc,看看系统还能不能保持稳定。如果仿真里加了噪声就发散,说明你的观测器带宽过于激进,在实物上一定会出问题。

另外执行器饱和是另一个被低估的问题。ADRC控制律计算出来的iq如果超过驱动器电流限制,你需要在代码里做限幅,并且最好把限幅信息反馈到观测器里(就是用限幅后的u去更新z1、z2),否则观测器很快进入“假饱和”状态,实际电流达不到期望值,控制器却以为已经给出去了,这个过程会不断累积误差导致系统振荡。这一点是工程上最常见的ADRC失效场景。

5.3 关于“外部模式”调试与在线调参

如果你用的是Speedgoat或者Desktop Real-Time跑PMSM控制,那你可以使用Simulink的“外部模式”进行在线调参。外部模式允许你在Simulink界面里直接修改ADRC的实时参数(比如ωc、ωo、b0),不需要重新编译。对于ADRC这类参数整定需求很高的算法来说,在线调参体验极为关键。我的建议是,把ADRC的仿真初版就设计成参数可调:在MATLAB Function里不要硬编码数字,而是通过输入端口把b0、ωc、ωo、Ts作为外部信号传入。这样后期不管是做扫描实验还是硬件在线调参,都不用改一处代码。

我这里再强调一下:很多人会把参数写死在MATLAB Function里,然后反复点击“编辑”重新编译模型,效率极低。如果你一开始就设计成参数外输,整个调试体验会完全不同。

6. 我的一点心得与后续扩展方向

说回ADRC本身。从韩京清老师的原始论文到今天Simulink里的工程实现,这套理论的魅力就在于它把“扰动不确定性”从负担变成了可观测的量。对于PMSM这样参数容易漂移的对象,ADRC在转速环上的收益确实立竿见影。仿真做得再多,也不如在实际电机台架上看一次突加负载的波形,那种“转速几乎不动”的体验会立刻让你信服。

我还建议把ADRC的思想延伸到其他领域,比如位置环、张力控制、风力发电机的转速控制,甚至是PMSM无位置传感器控制中的反电动势观测。ESO本质上就是一个广义扰动观测器,只要你能把对象写成积分串联形式,它就能起作用。后续有时间,我打算再写一篇关于ADRC与滑模观测器结合的文章,把PMSM无感控制中的扰动估计也纳入到同一个框架里。到时候再跟大家继续分享。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询