1. 项目概述:为什么选ADRC做永磁同步电机仿真
搞电机控制的人,谁没被PID支配过几年?从大学实验室到产线调试,PID确实是万金油,结构简单、参数直观、工程经验丰富。可一旦碰到永磁同步电机这种强耦合、非线性、参数时变的被控对象,PID那三板斧就开始露怯了——负载突变时转速波动大,参数摄动时动态性能明显退化,更别提Simulink里仿真跑得欢、上了台架就翻车的经典尴尬。这也是我当初决定把ADRC(自抗扰控制)引入PMSM仿真模型的核心动机。
这个模型解决的是这样一个问题:在不改变电机本体数学模型的前提下,用ADRC替代传统的PID速度环,通过扩张状态观测器(ESO)实时估计系统内部扰动和外部负载扰动,并在控制律中进行主动补偿,从而提升系统的抗扰能力和鲁棒性。说人话就是——负载突然加上去,转速掉得少、回得快;电机参数因为温度变化漂移了,系统还跟没事人一样。
项目本身非常值得做。一方面,ADRC是当前工业控制领域最有希望大规模替代PID的候选方案之一,其理论体系完整、工程实现路径清晰;另一方面,Simulink仿真平台给了我们一个低成本、零风险验证算法效果的绝佳环境。无论你是学生做毕业设计,还是工程师搞技术预研,这套仿真模型都能让你在半天之内建立起对ADRC从理论到实践的全链路认知。我在实际搭建过程中踩了不少坑,这篇文章把每一步的来龙去脉都写清楚,看完你也能从零搭出一套能跑的ADRC+PMSM仿真模型。
1.1 标题拆解:ADRC和PMSM各自是什么
永磁同步电机,简称PMSM,是当前工业伺服、电动汽车、机器人领域最主流的电机类型。它的转子装有永磁体,不需要励磁电流,所以效率高、功率密度大。但它的数学模型是一个典型的非线性强耦合系统——d轴和q轴之间存在交叉耦合项,反电动势与转速成正比,转矩与电流之间存在非线性的乘积关系。这些特性决定了它不像直流电机那样"一个PI环就能怡然自得"。
自抗扰控制ADRC的核心思想,最早由韩京清研究员在上世纪90年代提出。它把系统的未建模动态和外部扰动统一看成"总扰动",然后通过扩张状态观测器把这个总扰动实时估计出来,再在控制输入中减去这个估计值,实现对扰动的主动补偿。这套思想的精妙之处在于:它不依赖被控对象的精确数学模型——你是几阶系统、非线性有多强,ESO都能给你兜住。
这两个东西放到一起,碰撞出的火花非常有意思。PMSM数学模型越复杂、扰动越不确定,ADRC发挥的空间就越大。如果被控对象本身是理想线性的,那ADRC相对PID的优势并不明显,甚至PID已经足够了。但PMSM恰恰不是,它内部有交叉耦合、外部有负载突变,还有参数漂移,天然就是ADRC的试验田。
1.2 为什么不用PID改用ADRC:一场控制理念的对比
既然PID用了这么多年,为什么还要折腾ADRC?我个人的体会是:PID是"基于误差消除误差",但它有一个天然短板——没有办法区分"误差是因为外部扰动造成的"还是"因为控制器本身没干好造成的"。整个反馈系统就像一个被动挨打的拳手,被打了一拳才做出反应,反应完了可能又被补了一拳。
ADRC的逻辑完全不同。ESO的数学本质是一个扩张了状态维度的观测器。在原系统状态的基础上,把那个说不清道不明的"总扰动"也当成一个状态来估计。也就是说,它不仅能测到"转速掉了",还能同时估计出"是负载转矩增加了,还是磁链衰减了,还是逆变器非线性导致的等效扰动"。然后控制器不再等转速掉下去再慢慢调——而是在扰动刚出现的瞬间,就把补偿量叠加到控制输入上,提前把坑填平。
这个差异在仿真里体现得很直观。给系统加一个阶跃负载,PID控制的转速会先掉下去再慢慢爬回来,回落的深度和恢复时间与PID参数直接相关;ADRC控制的转速几乎只有一点点瞬态凹坑,然后迅速恢复到给定值——那个凹坑的大小直接取决于ESO的跟踪速度。这个仿真模型跑通了之后,你会实实在在地感受到什么叫"主动抗扰"。
2. ADRC控制器的结构拆解
ADRC不是一个单一的控制算法,而是一个控制框架。我在模型里实现的是最经典的二阶ADRC——二阶系统模型,速度环作为被控对象。它由三个核心部件组成:跟踪微分器(TD)、扩张状态观测器(ESO)和非线性状态误差反馈(NLSEF)。这三个部件各司其职,但缺一个整体性能都会打折。
2.1 跟踪微分器(TD):给速度信号安排一条平滑路径
TD解决的是"快速性与超调"的矛盾。传统的PID一阶低通滤波也能滤掉转速测量中的噪声,但滤波会带来相位滞后,滞后的信号反馈回来会让系统觉得"我还没到目标呢",继续使劲输出,结果就是超调。TD的思路是安排一个过渡过程:给一个阶跃速度给定,TD输出一条平滑的、有最大加速度限制的轨迹,让实际转速沿着这条轨迹平滑到达目标。
TD的离散形式我在Simulink里是这样实现的:
function [x1, x2] = td_update(x1, x2, v, r, h0) % x1: 过渡信号, x2: 过渡信号导数 % v: 给定值, r: 跟踪速度因子, h0: 滤波因子 f = fhan(x1 - v, x2, r, h0); x1 = x1 + h0 * x2; x2 = x2 + h0 * f; end function f = fhan(x1, x2, r, h) % 最速控制综合函数,ADRC中TD的核心 d = r * h; d0 = d * h; y = x1 + h * x2; a0 = sqrt(d^2 + 8 * r * abs(y)); if abs(y) <= d0 a = x2 + y / h; else a = x2 + 0.5 * (a0 - d) * sign(y); end if abs(a) <= d f = -r * a / d; else f = -r * sign(a); end end这段代码里的fhan函数是韩京清提出的最速控制综合函数。我最初在搭模型的时候一度很困惑:为什么不直接用一阶惯性环节代替TD?后来仿真对比发现,TD的过渡过程能让系统在阶跃给定下几乎无超调地达到目标转速,而一阶惯性环节则会因为相位滞后产生可观的超调量。TD的跟踪速度因子r直接决定过渡过程快慢——r越大,过渡过程越短,但对噪声越敏感;r太小,转速响应会变得拖沓。这个参数和PID里的比例增益有点像,需要根据实际系统特性权衡。
2.2 扩张状态观测器(ESO):整个ADRC的灵魂
如果说TD是"前馈整形",那ESO就是整个ADRC最核心的部分。它解决的是"状态感知"问题——在只知道被控对象输入输出信息的前提下,同时估计出系统状态和总扰动。
二阶系统的扩张状态观测器可以写成这样的形式:
对于系统:x1_dot = x2, x2_dot = f(x1, x2, w, t) + b0 * u
其中f就是那个总扰动,包含内部未建模动态和外部扰动w。扩张状态x3 = f,则ESO可以设计为:
- e = z1 - y
- z1_dot = z2 - beta1 * e
- z2_dot = z3 - beta2 * fal(e, 0.5, delta) + b0 * u
- z3_dot = -beta3 * fal(e, 0.25, delta)
这里的fal函数是一个非线性函数,表达式为:
function f = fal(e, alpha, delta) if abs(e) <= delta f = e / delta^(1 - alpha); else f = sign(e) * abs(e)^alpha; end end直观理解就是:小误差时放大(线性段),大误差时饱和(非线性段),从而保证观测器在小误差时快速收敛,在大误差时不过度超调。
我在搭建这个模块时用了一个小技巧:把beta参数从"带宽法"出发设定。ESO的观测带宽w0决定了ESO的收敛速度,三个增益的初值可以取为beta1 = 3w0, beta2 = 3w0^2, beta3 = w0^3。这样整定参数时只需要关注w0一个数就行。当然实际仿真中这些增益还要微调,因为非线性函数的存在使得带宽法估算值只是一个好的出发点。
2.3 非线性状态误差反馈(NLSEF)与扰动补偿
NLSEF的作用是把TD给出的过渡信号与系统实际状态之间的误差,结合ESO的扰动估计,组合成最终的控制律。传统PID是对误差做"比例、积分、微分"的线性组合,而NLSEF用非线性组合误差——小误差用高增益,大误差用低增益,从数学形式上更符合"小偏差精细调节、大偏差快速逼近"的工程直觉。
控制律的形式一般是:
u0 = kp * fal(e1, alpha1, delta) + kd * fal(e2, alpha2, delta)
然后最终控制输入:
u = (u0 - z3) / b0
其中z3是ESO估计的总扰动,b0是控制增益估计值。这个b0的分母项正是扰动补偿的关键——ESO估计出多大扰动,控制输入就反向减去多大分量。如果b0的估计不准确,补偿就会产生偏差:b0偏大,补偿过冲;b0偏小,补偿不足。
这里有一个非常关键的Simulink实现细节:控制律的输出是转速环的给定转矩电流iq_ref,由于PMSM的电磁转矩与q轴电流近似成正比(在id=0控制策略下),所以ADRC速度环的输出直接串联到电流环的输入端。这个等效链路的增益是1.5p磁链(与电机参数相关),在整定b0时需要把这个增益折算进去,否则ESO的扰动估计会失真。我一开始偷懒直接取b0=1,结果ESO的观测效果看着还行,但整体系统的抗扰性能明显不如预期,排查了半天才发现是这个增益折算的问题。
3. Simulink模型整体架构设计
搭建ADRC+PMSM仿真模型,架构设计决定成败。如果一上来就闷头拖模块,后面改起来会非常痛苦。我的建议是先在纸上把信号流图画清楚——从速度给定到转速反馈,中间经过哪些环节,每个环节的输入输出是什么,然后再说Simulink里怎么搭。
3.1 模型整体拓扑:双闭环还是三环
伺服系统最常见的拓扑是位置环、速度环、电流环三环结构。这个仿真模型我做的是速度电流双闭环,位置环留了接口但没闭环——因为ADRC的速度环是核心,位置环如果要加,也只是在速度环外面串一个比例控制器,思路完全一致。
双闭环结构如下:
- 外环(速度环):ADRC控制器,输入是给定转速与反馈转速的误差关系(经过TD和ESO状态),输出是q轴电流给定iq_ref
- 内环(电流环):两个PI控制器,分别控制d轴电流和q轴电流。d轴电流给定为0(id=0控制),q轴电流给定来自速度环输出
我遇到不少人在仿真时把速度环和电流环都用ADRC,认为"用ADRC越多越高级"。其实没必要。电流环的动态比速度环快得多,电流环的被控对象(定子绕组)相对而言更接近线性模型,PI控制完全够用,还省了ADRC参数整定的麻烦。速度环是真正面临负载扰动和参数摄动的环节,把ADRC放在这里性价比最高。
3.2 坐标变换与PMSM数学模型的Simulink实现
PMSM在Simulink里有两种建模方式:直接用Simscape Electrical里的永磁同步电机模型,或者用数学公式自己搭dq坐标系下的电机模型。我做模型时用的是数学公式方式——好处是每一个物理量都看得见摸得着,方便调试和排查问题。
dq坐标系下的电压方程为:
- ud = Rsid + Lddid/dt - omega_eLqiq
- uq = Rsiq + Lqdiq/dt + omega_e*(Ld*id + psi_f)
电磁转矩方程:Te = 1.5p(psi_f*iq + (Ld - Lq)idiq)
对于表贴式PMSM,Ld = Lq,转矩方程退化为Te = 1.5ppsi_f*iq,非常清爽。我用的电机参数如下:
| 参数 | 数值 | 单位 |
|---|---|---|
| 极对数 p | 4 | - |
| 定子电阻 Rs | 2.875 | Ω |
| d轴电感 Ld | 8.5 | mH |
| q轴电感 Lq | 8.5 | mH |
| 永磁体磁链 psi_f | 0.175 | Wb |
| 转动惯量 J | 0.001 | kg·m² |
| 阻尼系数 B | 0.0001 | N·m·s/rad |
坐标变换模块实现Park变换和Clark变换。Clark把三相abc坐标系变到静止两相αβ,Park把αβ变到旋转dq。这两个变换在Simulink里可以用Fcn模块直接写表达式,也可以用封装好的子系统。我个人的习惯是单独建一个"坐标变换"子模块,里面用Fcn写公式,这样改动电机参数时不用动变换模块。
3.3 离散化与采样时间设置的工程考量
仿真模型的采样时间设置是很多人忽略但影响很大的细节。ADRC本身是一个连续算法,但实际工程中一定是在DSP或MCU里离散化运行的,所以我在模型里做了离散化处理——速度环ADRC的采样时间设为0.1ms(对应10kHz控制频率),电流环的采样时间设为0.01ms(100kHz)。
为什么速度环要慢一拍?因为电流环需要更快的带宽来保证电流跟随,速度环的带宽相对较低。如果两个环都用0.01ms采样,仿真速度会变慢,而且对ADRC来说没必要——ESO的带宽不需要做那么高。我在实际跑仿真时发现,ESO的观测带宽w0设定在300rad/s左右就足够应对大多数工况了,对应的采样时间0.1ms完全够用。
离散化方式上,ESO和TD我用的是前向欧拉法(一阶),实现简单、计算量小,在采样时间足够短的时候精度完全够用。如果你追求更高精度,可以用RK4,但仿真步长固定为0.01ms时,欧拉法和RK4的差别肉眼几乎看不出来——完全没必要为了这种"自以为是的精度"拖慢仿真速度。
4. 建模实操:从零搭建仿真模型
下面进入重头戏——具体怎么搭。我会按从底层到顶层的顺序一步步讲解,每一步要建什么模块、参数怎么填、有哪些坑,都写清楚。整个模型我建议分成三个大子系统:PMSM本体子系统、坐标变换与逆变器子系统、ADRC控制器子系统。
4.1 第一步:搭建PMSM本体与逆变器模块
PMSM本体用电压方程和转矩方程搭。输入是ud和uq,输出是电流id、iq和机械转速。在Simulink里,我的做法是:
- 建一个子系统,内部用积分模块(Integrator)表示电流动态。dq轴电流的微分方程写成ud = Rs*id + Ld*did/dt - omega_e*Lq*iq的形式,那么did/dt = (ud - Rs*id + omega_e*Lq*iq)/Ld,从这个公式直接连积分器。
- 机械方程同理,转速的积分基于运动方程:J*dω/dt = Te - B*ω - TL,所以转速积分器的输入是(Te - B*ω - TL)/J。
- 电角速度omega_e = ω * p,直接乘一个增益模块。
逆变器的建模我做了简化——没有用IGBT导通损耗那种细节模型,而是用一个饱和限幅模块模拟逆变器输出电压极限。直流母线电压假设为300V,那么三相线电压有效值要经过SVPWM限制,简化后就是ud和uq的幅值限幅在±150V左右。
提示:初次跑仿真时如果发现id和iq发散到几千甚至几万,基本可以确定是限幅没加或者电机参数填错了。我踩过这个坑——忘记加限幅,仿真结果直接变成一条直线,根本看不出控制效果。
4.2 第二步:ADRC控制器C-MEX S-Function实现
ADRC控制器我用的是S-Function方式实现,而不是一堆Simulink基本模块堆砌。原因很简单:S-Function的代码逻辑清晰,参数调整只需要改一个变量数组,而且方便后续移植到嵌入式代码里。另一个方案是Matlab Function模块,也可以,但代码组织不如S-Function规整。
S-Function的框架如下:
function adrc_sfun(block) % 输入: 速度给定ref, 速度反馈w % 输出: 电流给定iq_ref setup(block); end function setup(block) block.NumInputPorts = 2; block.NumOutputPorts = 1; block.SetPreCompPortInfoToDynamic; block.InputPort(1).Dimensions = 1; block.InputPort(2).Dimensions = 1; block.OutputPort(1).Dimensions = 1; block.SampleTimes = [0.0001 0]; % 0.1ms离散采样 block.RegDialogs = ... {'b0', 'Parameters for ADRC', 'b0'}; % 参数: [b0, r, h0, w0, kp, kd] block.SetAccelRunOn = true; block.SimStateCompliance = 'DefaultSimState'; block.NumContStates = 0; block.NumDworks = 4; block.Dwork(1).Name = 'z1'; block.Dwork(1).Dimensions = 1; % ... 其他dwork定义省略 end更简洁的方式是用Level-2 MATLAB S-Function,把状态更新打包。我在实际的模型里是这样实现核心更新逻辑的:
function OutputUpdate(block) % 读取输入 ref = block.InputPort(1).Data; w = block.InputPort(2).Data; % 读取状态 z1 = block.Dwork(1).Data; z2 = block.Dwork(2).Data; z3 = block.Dwork(3).Data; x1 = block.Dwork(4).Data; % TD状态 x2 = block.Dwork(5).Data; % TD [x1, x2] = td_update(x1, x2, ref, r, h0); % ESO e = z1 - w; z1 = z1 + h * (z2 - beta1 * e); z2 = z2 + h * (z3 - beta2 * fal(e, 0.5, delta) + b0 * u_prev); z3 = z3 + h * (-beta3 * fal(e, 0.25, delta)); % NLSEF e1 = x1 - z1; e2 = x2 - z2; u0 = kp * fal(e1, 0.5, delta) + kd * fal(e2, 0.5, delta); u = (u0 - z3) / b0; % 输出并保存上一次u block.OutputPort(1).Data = u; block.Dwork(6).Data = u; % u_prev end这个代码框架基本就是ADRC的全貌。你可能注意到ESO的更新方程里用了上一次的控制输入u_prev,这是离散化的自然结果——当前时刻的ESO输出用上一时刻的控制输入来计算,因为当前时刻的控制输入还没算出来呢。在连续域里没有这个问题,但离散仿真里必须这样处理,否则会出现代数环报警。
4.3 第三步:电流环PI控制器搭建与限幅设置
电流环两个PI控制器结构一样,只是参数不同。d轴PI控制id到0,q轴PI控制iq到给定。PI参数我用的是零极点对消法整定:PI的零点对消电机电时间常数的极点,即Ti = Lq/Rs(或Ld/Rs),比例增益Kp取电流环带宽wc乘以电感Lq。
举个例子:
- q轴:Lq = 8.5mH, Rs = 2.875Ω, 电时间常数Tq = Lq/Rs ≈ 2.96ms
- 取电流环带宽wc = 3000rad/s
- Ki = Kp / Ti,Kp = wc * Lq = 3000 * 0.0085 = 25.5
- Ti = 0.00296,所以Ki = 25.5 / 0.00296 ≈ 8615
这样算出来的参数可以直接用,但跑仿真时要注意:如果出现电流震荡,多半是带宽取太高了,把wc降到2000rad/s试试。电流环的输出限幅也要注意,我设的限幅是±20A——超过这个值,在仿真里会看到iq_ref被削顶。
这个仿真模型最复杂的地方其实是ADRC参数的协调。单独调ESO和NLSEF都没问题,但两者放在一起需要多次迭代。下面是我调试时用的参数表(只针对上文电机参数):
| ADRC参数 | 数值 | 说明 |
|---|---|---|
| b0 | 23.5 | 控制增益,折算转矩常数1.5*p*psi_f |
| r | 1000 | TD的跟踪速度因子,越大过渡越快 |
| h0 | 0.001 | 滤波因子,抑制噪声 |
| w0 | 300 | ESO观测带宽,rad/s |
| kp | 8 | NLSEF比例增益 |
| kd | 1.2 | NLSEF微分增益 |
这套参数能让系统在额定转速下启动无超调,并且在2Nm负载突变时转速跌落小于20rpm、恢复时间约0.05s。如果你想抄作业,直接用这套参数跑,保准能出基本正确的波形。
5. 仿真验证与结果分析
模型搭出来只是第一步,最关键的环节是验证ADRC到底比PID强在哪里。我的建议是设计三组对照实验:启动响应测试、负载突变测试、参数摄动鲁棒性测试。这三组实验做完,ADRC和PID的差异就一目了然了。
5.1 启动响应测试:阶跃给定对比
给定1000rpm阶跃转速指令。PID组的响应曲线大概是这样:转速快速上升,到达额定值附近后有一个约15%~20%的超调,然后经过约0.1s的振荡收敛。ADRC组的曲线则不同——转速沿着TD规划的平滑路径上升,几乎无超调地到达给定转速,但上升时间会比PID慢一点(大约0.15s左右)。
这个对比结果很典型。PID的"快"是牺牲了超调换来的,ADRC的"稳"是通过主动规划过渡过程实现的。如果你把PID参数往小调压低超调,它的响应会变得很慢,反而比ADRC更慢。也就是说,ADRC在"同超调量下响应更快"这个维度上通常能赢。
5.2 负载突变测试:抗扰能力直观对比
在t=0.5s的时刻突加2Nm负载,观察转速动态。PID组的转速跌落大约60~80rpm,恢复时间约0.3s;ADRC组的转速跌落大约20rpm左右,恢复时间约0.05s。差距非常直观。
原理上也不难理解:PID要等转速出现偏差后才通过积分环节慢慢把偏差拉回,属于"事后补偿";ADRC的ESO在负载突加的瞬间就感知到了转矩的变化,立即在控制量中叠加补偿,属于"事前抵消"。我为了验证ESO确实观测到了扰动,在Scope里特意把z3(总扰动估计值)的波形调出来看——负载加上后,z3的数值在极短时间内跳变到大约2Nm(换算成转矩)附近,而PID控制器里根本没有这个环节。
5.3 参数摄动鲁棒性测试:真实工程价值
仿真做完了,很多人会想:"参数实物模型和仿真不一样怎么办?" 这正好是ADRC的优势所在——让电机参数在仿真中途突变,看看谁扛得住。我把Lq从8.5mH突变为13mH(模拟磁路饱和),转动惯量J从0.001增大到0.002。PID组在参数突变后转速波形出现了明显振荡,甚至需要重新整定参数才能恢复性能;ADRC组的波形变化几乎看不出来,ESO自动把参数摄动当成"内部扰动"给补偿掉了。
这就是ADRC在工程中最值钱的地方——你不知道的、测不了的、算不准的那些因素,ESO都会替你打包处理。如果把同样的算法移植到实物台架上,意味着你可以少花很多时间在"为不同工况分别整定参数"上。
6. 常见问题与调试心得
这一节是血泪经验总结。我在搭建和调试这套模型的过程中遇到的各种问题,梳理成速查表,大概率你也会碰到。
6.1 仿真直接发散:先排除最蠢的错误
最典型的发散原因是ESO参数beta值设置过大或b0设置错误。可以按下面的排查顺序来:
- 先把b0设成0(控制器就没有扰动补偿了),看系统是否能稳定。如果此时还不稳定,问题不在ADRC,而在电流环或电机模型本身。
- 然后把b0恢复,逐步增加ESO带宽w0。如果从w0=50开始不收敛、到300时发散,检查是否离散化步长太大——把仿真步长从0.01ms改到0.001ms对比一下。
- 还有一种情况是限幅缺失。逆变器饱和限幅没有加,控制器输出几百A的电流给电机模型,电机转速直接飞了。
6.2 ESO观测结果抖动严重:fal函数delta参数的问题
ESO的z3波形抖动,最常见的原因是fal函数里的delta参数设得太小。delta决定了线性区间的大小,delta越小,非线性段越强,但对噪声越敏感。在Simulink的数值仿真环境中,计算误差不可避免,如果delta=0.0001,观测器会一直在极小的误差区域来回震荡,导致z3抖动。
解决办法很简单——把delta改为0.01甚至0.05,z3的波形会平滑很多。不要担心delta改大后ESO性能下降,仿真里的噪声水平通常远低于实物,在仿真中追求极致精度但牺牲稳定性的做法没有意义。
6.3 b0到底该取多少:控制增益的物理折算
这是ADRC入门最容易卡住的地方。ESO的原理要求我们知道b0的精确值,但很多资料直接告诉你"b0是个大概值"就完事了,实际操作起来很困惑。
我的经验是这样:
- 针对PMSM速度环,速度环的输入是iq_ref(A),输出是转速(rad/s)。一阶近似的传递关系是:dω/dt = (1.5*p*ψ_f / J) * iq_ref。所以b0 ≈ 1.5*p*ψ_f / J。
- 代入参数:1.5 * 4 * 0.175 / 0.001 = 1050。
- 但实际模型还有电流环动态在环路里,电流环的延迟会降低等效增益,所以仿真中我发现b0取800~1200之间都能跑,但取值偏离太多时ESO的估计会偏。
注意:b0的物理意义就是"控制输入到状态微分的增益"。你可以通过开环仿真精确测定——给一个阶跃iq_ref,测量转速的加速度,两者一比就是b0。这个方法比纯理论计算靠谱得多。
6.4 电流环与ADRC速度环的耦合问题
跑仿真时另一个常见现象是:速度环输出iq_ref已经很大了,但电流环就是跟踪不上。原因在于电流环的带宽不够或者限幅太小。电流环PI带宽至少要达到速度环ESO带宽的3~5倍,否则内环的动态响应会成为整个系统的瓶颈。
如果电流环带宽上不去,可以检查电流环PI参数是不是按零极点对消法设置的。很多教程里直接给"Kp=10, Ki=100"之类的经验值,但对不同参数电机来说完全不适用。按前面提到的公式算出来的参数虽然可能不是最优,但至少方向正确。
7. 扩展方向与后续演进
这个模型跑通之后,可以沿着几个方向继续深入。
第一,位置环ADRC。在当前双闭环基础上,把位置环设为外环,一样可以用TD安排位置过渡过程。位置环的ADRC设计思路完全一致,只是被控对象变成了一阶积分环节,状态维度减少到一阶,对应的ESO也降为二阶。
第二,无传感器控制。把速度环的反馈从"直接测量"改为"基于反电动势的滑模观测器估计",ADRC的ESO会自动把估计误差当成扰动的一部分处理掉——这也是ADRC的一个隐藏加成,它对上游传感器的不精确有一定的容忍度。
第三,参数自适应。固定参数的ADRC已经能扛参数摄动了,但如果磁链或电感变化范围极大,可以对b0做在线辨识修正,让ESO的估计精度进一步改善。
我个人最推荐第一和第三个方向。位置环ADRC在工业伺服里有直接应用价值,参数自适应则是把ADRC推向工程化的重要一步。如果你打算做毕业设计或者技术储备,往这三个方向任何一个延伸都比停留在仿真层面更有说服力。
最后再分享一个小技巧:调试ADRC时一定要把ESO的z1、z2、z3三个信号引出到Scope,和实际转速、电流波形对照着看。z1应该实时跟住转速反馈,z2是转速的导数,z3平滑不抖动就说明观测器工作正常。很多人调试时只关注最终的转速波形,ESO内部出问题都不知道,走了不少弯路。先确认ESO观测准确,再去调NLSEF,这条调试路径是最省时间的。