永磁同步电机ADRC调速:Simulink建模与参数整定实战

📅 发布时间:2026/10/21 8:45:29
永磁同步电机ADRC调速:Simulink建模与参数整定实战
做永磁同步电机PMSM调速的工程师十有八九被同一件事烦过PI参数在一组工况下调得顺顺当当换个负载、加点扰动性能立刻垮掉。这几年ADRC自抗扰控制在电机控制圈子的热度越来越高原因很直接——它不依赖精确的电机模型而是把系统里的“总扰动”当作一个状态实时估计、实时补偿天然比PI扛造。我先后在Simulink里把PMSM的ADRC方案完整搭过很多轮从建模、调参到波形诊断踩了一堆坑这篇就来手把手拆解整个流程顺便把几个文档里不会明说的“骚操作”一并摊开。适合刚接触ADRC、想在仿真里快速跑通原理的人也适合那些PI调到怀疑人生、想换条路试试的控制工程师。1. 为什么PMSM调速要上ADRC1.1 传统PI控制的三道坎先说清楚问题在哪。PMSM矢量控制的标配是“电流环PI速度环PI”这套东西成熟到教科书都不愿意多废话但它有几个绕不开的先天弱点。第一PI本质上是线性控制律它默认被控对象是“参数固定、线性、时不变”的。可电机不是这样绕组电阻Rs随温度漂移电感Ld、Lq随电流饱和变化转子磁链ψf受温度影响负载转矩更是随时跳变。对象变了PI参数没变性能自然往下掉。第二PI靠误差驱动。负载突变的那一刻转速误差还没建立起来PI输出来不及反应等到误差变大了再使劲转速已经跌了一大截。这就是“扰动后知后觉”的致命伤。第三快速性和超调这对矛盾靠一组固定PI参数很难两全。把比例增益调大动态响应快但超调、噪声、振荡一起冒出来调保守一点扰动来了半天回不到稳态。这三道坎不是PI不能用而是它的模型假设天花板太低。ADRC的思路完全不同不去精确建模不指望“误差出现后再纠偏”而是把系统内部参数变化、外部负载变化统统打包成“总扰动”在它还没造成严重后果之前就补偿掉。1.2 ADRC的三个核心角色与整体架构ADRC之所以听起来玄是因为它引进了一套新的概念体系。拆开看其实就三个模块各管一件事。跟踪微分器TD管“怎么去”参考转速不能瞬间砸进系统否则必然激起超调和冲击。TD把阶跃的转速指令变成一条平滑的过渡轨迹同时给出它的“速度趋势”相当于给控制系统安排了刹车和油门。扩张状态观测器ESO管“怎么看”这是ADRC的心脏。它不满足于只观测转速而是把系统里乱七八糟的扰动——负载突变、参数摄动、未建模摩擦——统统归并成一个新的状态变量在观测转速的同时把它一起估出来。非线性状态误差反馈NLSEF管“怎么打”把当前状态和参考轨迹的误差用非线性组合算出一个初步控制量再把ESO报上来的总扰动前馈抵消掉。三个模块合在一起控制量既响应误差又提前干掉扰动。这套架构最迷人的地方在于它不需要你知道扰动具体是怎么来的、方程长什么样ESO会在运行中自己把它“看出来”。1.3 为什么选Simulink而不是手写代码有人会问ADRC本身就是一套差分方程直接写C或者Python不香吗仿真阶段真不建议。Simulink的优势在于“半实物”建模PMSM模型、三相逆变器、PWM调制、测量反馈这些环节都有现成模块你不用从电机方程开始敲。算法部分用MATLAB Function把差分方程封装进去既保留了对细节的掌控又不需要搭几十个积分器和增益模块。后期要换参数、加扰动、看波形改一行脚本比手动重建整个模型快得多。更重要的是Simulink的Scope和To Workspace能让你瞬间对比转速指令、实际转速、ESO估计扰动、负载转矩这些信号。做控制最怕“黑箱”ADRC调参时你特别需要透视观测器内部状态这一点Simulink天生合适。2. 模型搭建前的基础准备2.1 PMSM的数学模型与坐标变换关系不管用什么模块库原理都得先落在纸面上。表贴式永磁同步电机在dq同步旋转坐标系下的电压方程是ud Rs·id Ld·(d id/dt) - ωe·Lq·iq uq Rs·iq Lq·(d iq/dt) ωe·(Ld·id ψf)转矩方程Te 1.5·pn·(ψf·iq (Ld - Lq)·id·iq)表贴式电机Ld等于Lq括号里第二项归零转矩完全由iq决定。这就是id0控制的根源——iq直接对应电磁转矩控制iq就控制了转矩简洁得让人放心。坐标变换是从abc三相到αβ静止坐标Clarke变换再从αβ到dq旋转坐标Park变换。Simulink自带的PMSM模块内部会处理这些变换但你自己心里要有一本账电流环的输出是ud和uq要经过逆Park变换和SVPWM才能变成逆变器的开关信号。ADRC算法运行在dq坐标系里反馈回来的转速是机械转速或电气转速这些单位换算一旦错位后面b0参数必炸。2.2 仿真参数与求解器配置我用一组常见的仿真参数给你做参考这套数据属于小功率表贴式PMSM非常适合首轮跑通参数数值说明定子电阻 Rs2.875 Ω绕组相电阻dq轴电感 Ld / Lq0.0085 H表贴式两者相等永磁磁链 ψf0.175 Wb转子磁链幅值极对数 pn4决定电气转速与机械转速关系转动惯量 J0.0008 kg·m²折算到电机轴的惯量阻尼系数 B0.0001 N·m·s摩擦阻尼常被忽略直流母线电压311 V三相220V整流输出开关频率10 kHzPWM载波仿真步长建议设固定步长离散求解器步长取1e-5秒或更小。10kHz开关频率意味着PWM周期100微秒步长1e-5秒让每个开关周期内有10个计算点波形足够细腻。很多人图省事用变步长连续求解器结果模型在高频开关切换处步长疯狂收缩仿真龟速爬行还容易报代数环错误。固定步长在这里反而稳。2.3 双闭环拓扑怎么选速度环ADRC电流环PI第一次做ADRC的人最容易犯的错一上来电流环速度环全都上ADRC参数一大把调到头昏脑涨还不知道是哪个环在捣乱。我的建议非常明确首轮仿真用“速度环ADRC电流环PI”的混合架构。理由不复杂。电流环动态快、模型相对清楚两个PI参数用传统整定法十分钟就能搞定。速度环才是对抗负载扰动、参数变化的主战场ADRC最值钱的能力放在这里才能体现出来。等这套混合方案跑顺了、你对ESO的脾气摸透了再回头试着把电流环也换成ADRC不迟。这样分层还有个额外好处问题隔离。波形不对的时候你只需要怀疑速度环ADRC的参数电流环PI那边稳如老狗不会互相甩锅。3. 手把手拆解ADRC的Simulink实现3.1 总体框架模型里到底有哪些模块一个完整的速度环ADRC仿真模型信号流从前往后大概是参考转速模块 → ADRC控制器内部含TD、ESO、NLSEF→ q轴电流给定 → 电流环PI → 逆Park变换 → SVPWM → 三相逆变器 → PMSM → 电流、转速测量 → 坐标变换反馈回控制器。看着环节多Simulink里其实就是三大块电力电子主电路、坐标变换与PWM调制、ADRC控制算法。电力电子和PWM部分用模块库里的现成组件自己重点写的是ADRC算法和电流环PI。ADRC控制器的输入有三个参考转速v、反馈转速y来自电机的测量输出、电流环反馈iq用于ESO里的控制量u。输出只有一个q轴电流参考值iq_ref。整个控制器封装成一个子系统内部再分TD、ESO、NLSEF三个子模块层次清楚后续改参数也方便。3.2 TD模块让参考输入“软着陆”速度环ADRC里TD的任务是把阶跃转速指令平滑化。对一阶速度对象TD可以简化成一阶惯性跟踪离散递推式x1(k1) x1(k) h · (-r · (x1(k) - v(k)))这里的r就是速度因子越大过渡越快但太大就失去了“安排过渡过程”的意义。x1是对参考轨迹的跟踪值后续NLSEF用的是x1与实测转速的误差而不是直接用原始指令和实测转速的误差。这个细节很关键——用了TD阶跃起步那一下就不会把误差一下子拉满超调自然被压住。Simulink里一个离散传递函数或一个MATLAB Function就能实现上式。我给的是工程简化版好调好用。如果你追求论文级效果可以上完整的二阶最速控制综合函数fhan但在速度环这种一阶主对象上简化的收益比远超复杂度付出。3.3 ESO模块全场最核心的观测器实现ESO是ADRC的灵魂写差一步整个控制就是空中楼阁。针对PMSM速度环的一阶模型dω/dt b0 · iq f(t)其中f(t)就是负载扰动、参数变化、未建模动态的总和。二阶ESO的离散递推式如下e z1(k) - y(k) z1(k1) z1(k) h · (z2(k) - β1 · e b0 · u(k)) z2(k1) z2(k) - h · β2 · fal(e, α, δ)这里z1观测转速z2观测总扰动f。u是控制量这里取q轴电流iq。fal非线性函数fal(e, α, δ) e / δ^(1-α)当|e| ≤ δ fal(e, α, δ) |e|^α · sign(e)当|e| δα断电控制在0.5附近δ可取0.01量级。fal的用意是“小误差时高增益、大误差时低增益”兼顾收敛速度和抗噪声。在Simulink里ESO必须用离散状态更新实现不能拖一堆连续积分器——连续积分器在固定步长仿真里也能跑但数字实现落不到单片机里失去仿真意义。我自己写MATLAB Function实现ESO上面那组递推式直接搬进去非常干净。3.4 “骚操作”一MATLAB Function替代几十个积木模块这是我最想强调的实战技巧。网上教程里常见做法是用积分器、增益、求和器把ESO搭成积木图一个观测器少说十几个模块连线密到眼睛发花改个β参数要去增益模块里翻半天。我的做法整个ADRC算法内核封装进一个MATLAB Function子系统。function [iq_ref, z1, z2, x1] ADRC_Core(v, y, iq, params) % params 包含 r, b0, kp, beta1, beta2, alpha, delta, Ts % TD x1_next x1 Ts * (-params.r * (x1 - v)); % ESO e z1 - y; z1_next z1 Ts * (z2 - params.beta1 * e params.b0 * iq); z2_next z2 - Ts * params.beta2 * fal(e, params.alpha, params.delta); % NLSEF 扰动补偿 u0 params.kp * (x1 - z1); iq_ref (u0 - z2) / params.b0; % 更新状态 x1 x1_next; z1 z1_next; z2 z2_next; end外部只用两个接口接线内部参数全部放在结构体params里在初始化脚本里赋值。改参数就是改一行脚本波形不对立刻重跑效率高出一个数量级。正因为ADRC的差分结构如此清晰摆在MATLAB Function里远远比积木图更好维护、更好理解、更好移植。3.5 控制律与扰动补偿接线NLSEF部分从简对一阶对象比例控制律足够kp就是控制器带宽ωc。加法层面的操作是先用误差算出u0再用u0减去z2最后除以b0得到iq_ref。这个“减z2除以b0”的动作就是扰动补偿——ESO说“我估计干扰是某个值”控制量就反向抵消它。注意接线里的单位。z2估计的扰动单位是“转速变化率”rad/s²除以b0之后才变成电流单位A。很多第一次搭的人忘记除以b0结果扰动补偿幅度差了几十倍ESO再准也白搭。4. 参数整定从能跑跑到跑得好的关键一跃4.1 带宽法把参数从6个降到2个ADRC的堆头不小TD有rESO有β1、β2、α、δ控制律有kp一数六七个参数手动乱试等于大海捞针。好在有高志强提出的带宽参数化方法把ESO参数全部归约到观测器带宽ωo上。对二阶ESO带宽法给出β1 2·ωo β2 ωo²控制器带宽ωc直接取kp。经验上让ωo等于ωc的3到5倍保证观测器收敛速度显著快于控制器响应速度。这样实际要调的参数缩减为两个ωc和ωo外加一个b0。这三个数定下来整个ADRC就基本定形。这个“骚操作”的核心价值把玄学调参变成工程调参。你先按物理直觉给ωc一个值ωo跟上去系统就能稳定之后再迭代优化而不是每个参数盲试。4.2 b0这一步算错全盘皆输b0是控制量增益的估计值在速度环里对应电磁转矩系数与转动惯量的比值。从机械运动方程J·dω/dt Kt·iq - TL - B·ω其中Kt 1.5·pn·ψf于是b0 Kt / J代入前面那组仿真参数Kt 1.5×4×0.175 1.05 N·m/AJ 0.0008 kg·m²所以b0 1.05 / 0.0008 1312.5。这个数一定要算准吗也不完全是。ADRC的ESO会把b0不准造成的模型误差当作扰动的一部分估计出来并补偿掉所以小幅偏差系统扛得住。但如果你b0差出一个数量级或者正负号错了ESO的补偿方向直接反掉仿真当场发散。给个实在提醒仿真里b0错一倍以内还能救错十倍以上建议直接查单位换算。尤其是转速单位——用rad/s计算得到的b0和你用rpm当反馈时的b0不是一个数中间差60/2π倍。4.3 分步整定的具体操作顺序调参切忌一步到位我推荐的顺序是电流环PI先整定完毕iq给定到实际电流的响应带宽调到数百赫兹以上确保电流环不拖后腿。ADRC里的TD先屏蔽掉或者给一个很大的r让它几乎不滤波此时系统退化成“P控制ESO补偿”。从ωc20开始往上加观察转速阶跃响应。响应太慢就翻倍出现振荡就回退到上一个稳定值。ωo保持ωc的3~5倍观察ESO的z2是否跟随实际扰动。如果z2毛刺大、噪声多适当把ωo往回压。系统稳定后再把TD接回来r从100开始调让转速指令变化不产生超调。每一步只改一个参数改完跑一次阶跃响应存好波形再动下一个。这比你同时拧三个旋钮高效得多出了问题也知道赖谁。4.4 “骚操作”二用在线数据辨识快速初估参数有些时候b0算不准比如电机铭牌数据和实际不符。这时别傻乎乎地在Simulink里盲猜直接用仿真数据做离线拟合。方法不复杂模型跑起来后用To Workspace把iq和dω/dt录下来在MATLAB工作区里对J·dω/dt Kt·iq做最小二乘拟合b0的初值一秒估出来。仿真里估的b0虽然不完全代表实机工况但至少帮你把量级锁死。等真到了台架阶段再用阶跃响应或正弦辨识进一步校准。这个招数很适合那些“手里电机参数残缺不齐”的情况比翻手册慢慢凑数效率高很多。5. 仿真现场常见问题与排查实录5.1 一跑就发散先别急着改参数我见过太多人模型一炸就疯狂改参数越改越乱。发散问题先按顺序排查第一看步长和求解器。固定步长1e-5离散求解器PWM和逆变器模型别用连续变步长这是最稳的组合。第二查代数环。MATLAB Function里如果出现“以前一时刻的输出直接参与本时刻输入计算”的环Simulink会报错或发散。解决办法是在递推式里强制用上一拍的状态量来计算本拍输出。第三查符号。b0正负错、反馈极性反、ESO的u符号不对任何一种都会瞬间击穿系统。跑之前拿几个关键数值手算一遍比如给定iq1时估算一下转速增长方向和幅度和Scope里看到的对一对。第四查限幅。iq_ref不加饱和限幅仿真里控制量可以冲到几千安培必然导致数值爆炸。输出一定要接Saturation上下限按电机额定电流的1.5~2倍给。5.2 ESO观测值跟实际转速对不上z1本应紧跟实测转速y如果两者差得老远问题大多出在ESO参数或输入信号上。β1、β2太小观测器收敛太慢z1就像被胶水粘住一样跟不上。解决把ωo往上提β2是平方关系提升效果特别明显。但如果z1依然差的很大且稳态时仍有固定偏差要怀疑模型阶数不匹配——你把二阶对象强行套一阶ESO或者反过来。PMSM速度环在电流环带宽不够高时确实会显现二阶特性此时可以把ESO升到三阶或者先提高电流环带宽再做决定。5.3 稳态转速抖振、电流毛刺多现象是转速在给定值附近抖个不停电流波形上有明显的高频毛刺。多半是这几个原因fal函数的δ设得太小小误差区增益过高控制量在稳态附近不稳定。把δ从0.001调到0.01量级抖振通常会明显缓解。ωo拉得太高观测器把测量噪声放大以后当成了“扰动”控制量跟着噪声狂跳。把ωo从“能压住多大扰动”这个目标降回“观测器不发毛”这个水平。步长太大导致离散误差明显。电流环这种高带宽回路仿真步长压缩到1e-5量级离散化误差带来的相位滞后能被控制在可接受范围内。5.4 “骚操作”三把扰动估计拖到Scope里一起对比这是我每次调试的保留项目把ESO的z2总扰动估计值和实际负载转矩TL画在同一张Scope里双曲线对比。道理很简单ESO估得准不准直接看两条线是否重合。如果负载在0.5秒时从零阶跃到额定值z2应该在同一时刻快速跟进到对应水平的转速变化率数值。如果z2的反应慢半拍说明ωo不够高如果z2到达后大幅振荡说明观测器环路不稳。这个操作让ESO不再“黑箱化”每次调参都有数据依据而不是对着一条转速曲线瞎猜。比单纯看转速响应下结论要科学得多。6. 从仿真到电机的几条实在建议6.1 离散化移植与运算量评估Simulink里的ADRC差分方程直接翻译成C代码毫无障碍一个控制周期内就是几十行乘加运算。以二阶ESO加一阶TD为例一个周期内浮点运算量几百次量级主流MCU跑5kHz到10kHz控制周期绰绰有余。运算量从来不是ADRC上实机的瓶颈真正的门槛在参数标定和抗噪设计。移植时的最大坑是时序实机代码里ADRC必须在电流采样完成之后、PWM占空比更新之前执行完毕所有状态量更新一次不能仿真那样连续刷新。把Simulink模型转为C代码时要特别注意离散模块的采样时间设置和控制周期完全对齐。6.2 实机环境下的噪声与限幅处理仿真里信号干干净净实机里电流传感器有偏置和噪声编码器测速有量化误差。ESO把这些测量噪声当成扰动的一部分估计出来会让z2高频抖动然后通过补偿链路污染控制量。应对策略有三条ωo别按仿真值硬拉实机里通常降到仿真值的二分之一甚至更低速度反馈自己做低通滤波或采用测速机处理别拿原始脉冲直接怼给ESO控制量输出必须限幅并且要加抗积分饱和机制防止ESO内部状态被大误差冲到飞。6.3 我个人踩过的坑与习惯做法最后说几句实在话。ADRC不是魔法它解决的痛点很明确但带来的参数敏感性和调试负担也真实存在。我在实机调试中最深的一个感受是b0这个参数比ωc和ωo都重要。b0一旦严重失准ESO花多大力气都补不回来b0准了剩下两个带宽参数怎么拧都有下限兜底。另一个习惯是每次调参都留数据。Simulink的Scope截图只是辅助把关键信号用To Workspace整段存下来参数每次调整都做一次记录过几天回头翻你才能看清参数和性能变化之间的因果关系。做控制这一行经验是攒出来的不是靠感觉硬调出来的。如果后续想往深了走可以试试把ESO和TD改成自适应参数版本或者加入模型参考自适应做在线b0辨识这些都是ADRC在电机控制里很活跃的扩展方向。先把基础版本完整跑通、调平稳再考虑这些锦上添花的东西路才走得踏实。