简介:面向永磁同步电机无位置传感器控制的学习与研究人员,这份MATLAB/Simulink仿真材料围绕模型参考自适应算法(MRAS)搭建了可运行的电机控制验证环境,重点解决缺少位置传感器时转速与位置估计,以及电阻、电感、磁链等参数在线辨识的问题。压缩包共2个文件,由1个Simulink模型文件和1个MATLAB绘图脚本组成,整体约33KB,前者承载电机数学模型、状态观测器、参数辨识单元与控制器,后者用于整理并绘制仿真结果曲线。已有502人学习,说明该主题在课程设计与工程预研中关注度较高。读者可据此复现从电机建模、MRAS自适应律设计到参数估计的完整流程,并通过转速、电流与位置波形评估控制策略的稳态与动态表现,适合作为电机控制算法入门到进阶的对照案例。
1. 只有相电流、没有编码器,MRAS 能顶到什么转速
手上只有三路相电流采样和一个母线电压,电机要从静止拉到 3000 rpm——这是无位置传感器控制最常见的开局。MRAS(模型参考自适应系统)是这类场景里性价比最高的方案之一:不注入高频信号、不加额外硬件,靠电机本体方程和一条自适应律,把转子位置和转速从电压电流里反推出来。这套 MATLAB/Simulink 完整仿真模型把参考模型、可调模型、PI 自适应律、参数辨识脚本和低速切换逻辑拆成可单独打开的子模块,配上一次性加载的参数文件,改几个数字就能换成自己手上的电机。它适合正在做电机控制算法验证、想先把观测器跑通再上硬件的一线工程师,也适合刚接触参数辨识、需要一个能对拍的基准模型的人。下面按“数学骨架—模型搭建—参数辨识—避坑—验证”一层层拆。
2. MRAS 的数学骨架:参考模型、可调模型和自适应律怎么落地
MRAS 的直觉很简单:让两个模型算同一个物理量,一个用真实信号驱动、不含待估参数,另一个含待估参数,两者输出做差,差值经自适应律反过来修正待估参数,直到差值收敛到零。难点从来不是这句话,而是三个问题:选哪两个量做差、差值怎么构造才不会在过零附近丢方向、增益按什么量纲给。这一章把这三件事讲透,后面搭模型才有依据。
2.1 参考模型与可调模型的选型:PMSM 和异步机不是一套
表贴式 PMSM 在 αβ 静止坐标系下的电压方程是:
uα = Rs·iα + L·diα/dt + eα, eα = -ωe·ψf·sinθ uβ = Rs·iβ + L·diβ/dt + eβ, eβ = ωe·ψf·cosθ注意反电动势里已经含了 ωe 和 θ,这就是天然的“可调”入口。所以 PMSM 的 MRAS 通常这样分工:参考模型就是电机本体(真实采到的 iα、iβ),可调模型是一个电流观测器,用估计转速 ω̂ 重建反电动势,再把重建的反电动势代回同一个电压方程算估计电流 îα、îβ。两边电流误差趋零,说明 ω̂ 逼近真值。
异步机反过来:转子磁链的电压模型不含转速,电流模型含转速,所以参考模型取电压模型磁链、可调模型取电流模型磁链,误差用两个磁链矢量的叉积。这套模型如果直接把异步机的结构套到 PMSM 上,仿真会跑出“能收敛但稳态有固定偏差”的波形,很多人到这里以为是增益没调好,其实是模型选错了。
选 PMSM 反电动势型还有两个工程理由。第一,它不需要对反电动势做纯积分,避免了直流偏置累积,这一点在第 4 章会展开。第二,它的可调模型里 Rs 和 L 是显式出现的,方便单独把参数辨识模块挂进去做在线修正。代价是低速时反电动势幅值正比于转速,转速越低信噪比越差,这也是 PMSM 无位置传感器控制的固有短板。
提示:模型里把 L 当成常数处理,只对表贴式(Ld≈Lq)成立。凸极率高的内嵌式电机要改成 dq 轴分离形式,否则估计角度会带一个与负载电流相关的二次谐波误差。
2.2 从 Popov 超稳定性到 PI 自适应律:增益的量纲比数值更重要
误差方程可以整理成 de/dt = A·e + B·w 的线性前向环节加一个非线性反馈环节,A 的特征值在左半平面,前向环节严格正实;反馈环节只要满足 Popov 积分不等式 ∫ε·(ω̂−ω)dt ≥ −γ²,整个系统就渐进收敛。满足这个不等式的自适应律取 PI 形式:
ε = êα·eβ − êβ·eα % ê 为估计反电动势,e 为电流误差 ω̂ = Kp·ε + Ki·∫ε dt θ̂ = ∫ω̂ dt叉积这个构造是关键:当估计角度超前真实角度 Δθ 时,两个矢量的叉积正比于 sin(Δθ),Δθ 小的时候近似线性,过零时符号自然翻转,不需要额外判方向。用点积就不行,点积在 Δθ=0 附近是 cos 型,导数为零,误差一大就推不动。
真正让人翻车的是增益量纲。ê 的单位是 V,e 的单位是 A,所以 ε 的单位是 W。Kp 的量纲是 rpm/W,Ki 是 rpm/(W·s)。很多开源例程里直接写 Kp=1000、Ki=50000,那是针对另一套标幺化后的变量,照抄到有名值系统里必发散。我一般这样反推:先把 Kp、Ki 置零跑一次,用 Scope 录下启动瞬间 ε 的峰值 εmax,再令
Kp ≈ 0.05 × 额定转速 / εmax Ki ≈ Kp × 电流环带宽 / 20这套经验公式不保证最优,但能保证第一次跑不发散,剩下的在这个量级附近微调。收敛速度和抗噪是一对矛盾:Kp 拉大收敛快但估计转速毛刺大,反过来 Ki 拉大稳态误差消得干净但动态拖尾。
2.3 先写一个纯 m 脚本,把估计器逻辑验证干净
直接进 Simulink 搭闭环,出错时你分不清是观测器的问题还是电流环的问题。我的习惯是先写一个不含机械方程的最小脚本,把真实转速钉死,只验证估计器能不能跟上。这段代码可以独立运行,几十行,跑完就知道符号对不对、增益大概在什么量级。
%% mras_pmsm_core.m —— MRAS 估计器最小可运行验证(不含机械方程) clear; clc; Ts = 1e-5; % 数值积分步长,10 us Tend = 0.6; % 仿真时长 N = round(Tend/Ts); Rs = 0.35; % 定子电阻 Ohm(示例值,按铭牌替换) L = 8.5e-3; % 相电感 H psi = 0.175; % 永磁磁链 Wb p = 4; % 极对数 Uamp = 120; % 相电压幅值 V w_m = 1200; % 真实机械转速 rpm w_e = w_m*pi/30*p; % 真实电角速度 rad/s Kp_ad = 2.5; % 自适应律比例,单位 rpm/W Ki_ad = 80; % 自适应律积分,单位 rpm/(W*s) w_max = 6000; % 估计转速限幅 rpm ia = 0; ib = 0; % 真实电流 alpha/beta iha = 0; ihb = 0; % 估计电流 th = 0; thh = 0; % 真实/估计电角度 wmh = 200; % 估计转速初值,非零,避免上电死锁 Ieps = 0; rec = zeros(N,4); for k = 1:N % 1) 真实电机:反电动势 + 电压方程 ea = -w_e*psi*sin(th); eb = w_e*psi*cos(th); ua = Uamp*cos(th + 0.3); % 电压矢量滞后 0.3 rad,制造有功分量 ub = Uamp*sin(th + 0.3); dia = (ua - Rs*ia - ea)/L; dib = (ub - Rs*ib - eb)/L; % 2) 可调模型:用估计转速重建反电动势 w_eh = wmh*pi/30*p; eha = -w_eh*psi*sin(thh); ehb = w_eh*psi*cos(thh); diha = (ua - Rs*iha - eha)/L; dihb = (ub - Rs*ihb - ehb)/L; % 3) 叉积误差 -> PI 自适应律 -> 限幅 ea_err = ia - iha; eb_err = ib - ihb; eps = eha*eb_err - ehb*ea_err; Ieps = Ieps + eps*Ts; wmh = Kp_ad*eps + Ki_ad*Ieps; wmh = min(max(wmh, -w_max), w_max); % 4) 状态推进(前向欧拉) ia = ia + dia*Ts; ib = ib + dib*Ts; iha = iha + diha*Ts; ihb = ihb + dihb*Ts; th = th + w_e*Ts; thh = thh + w_eh*Ts; rec(k,:) = [w_m, wmh, th, thh]; end t = (1:N)'*Ts; subplot(2,1,1); plot(t, rec(:,1), t, rec(:,2), '--'); ylabel('机械转速 / rpm'); legend('真实','估计'); grid on; subplot(2,1,2); plot(t, rec(:,3), t, rec(:,4), '--'); ylabel('电角度 / rad'); legend('真实','估计'); grid on; fprintf('末段转速估计误差 %.1f rpm\n', mean(rec(end-200:end,2)) - w_m);逻辑上分四步:先用真实方程推进电流、再用电估计推进观测器电流、然后算叉积误差修正估计转速、最后积分出估计角度。参数上有三处必须注意:wmh初值给 0 会导致 ê 恒为零、ε 恒为零、估计器永远启动不了,这是这套结构最隐蔽的死锁;w_max限幅一定要加,否则启动第一拍 ε 是个大数,积分器一拍就能把估计值顶到几万转;Ts取 1e-5 是数值积分精度要求,和控制周期是两回事。
判断脚本跑通的标准不是曲线好看,而是末段转速误差小于 1%、角度误差小于 0.05 rad。达不到就先别往 Simulink 里搬。
2.4 各环节采样率分配
多速率是 Simulink 仿真跑得动的前提,全部用 1 μs 跑 10 秒的模型,一台普通工作站要跑半小时以上。
| 环节 | 建议步长 | 依据 |
|---|---|---|
| 功率级与电机本体 | 1e-6 ~ 5e-6 s | 开关频率 10 kHz 时每个开关周期至少 20 个点 |
| 电流环与坐标变换 | 1e-4 s | 与 PWM 载波同步,10 kHz |
| MRAS 估计器 | 1e-4 s | 与电流环同频,省掉一次插值 |
| 速度环 | 1e-3 s | 比电流环慢一个数量级 |
| 参数辨识注入 | 1e-3 ~ 1e-2 s | 激励信号本身频率低 |
估计器和电流环同频有个好处:电压指令和电流采样在同一个时刻对齐,不会因为插值引入相位差,低速时这点相位差会被放大成角度误差。代价是估计器的计算量必须在一个控制周期内跑完,实际控制器上要注意别超时。
3. 在 Simulink 里搭出完整回路:从空模型到能出转速波形
有了脚本验证过的自适应律,Simulink 里要补的是外围:逆变器、坐标变换、电流环、速度环,以及把它们和估计器接成一个闭环。这一章按建模顺序给参数、给脚本、给接线步骤,照着搭一遍大概两三个小时,再调参半天能出第一版波形。
3.1 主电路与电机本体的参数配置
模型默认用理想开关加三相桥,电机用 Simscape 里的 PMSM 模块或自己写的离散状态方程都行。参数按下面这张表填,示例值是一台 1 kW 级伺服电机的量级,换成自己手上的电机时逐项对应铭牌和实测值。
| 参数 | 符号 | 示例值 | 来源 |
|---|---|---|---|
| 定子相电阻 | Rs | 0.35 Ω | 万用表测两相线电阻后除以 2 |
| d 轴电感 | Ld | 8.5 mH | LCR 表或阶跃响应辨识 |
| q 轴电感 | Lq | 8.5 mH | 表贴式取与 Ld 相同 |
| 永磁磁链 | ψf | 0.175 Wb | 空载反电动势法反算 |
| 极对数 | p | 4 | 铭牌 |
| 转动惯量 | J | 3e-3 kg·m² | 加速实验或厂家数据 |
| 母线电压 | Udc | 311 V | 220 V 交流整流 |
| 开关频率 | fsw | 10 kHz | 控制器能力与损耗折中 |
| 额定转速 | n | 3000 rpm | 铭牌 |
电感这一项最容易被忽略:LCR 表在 1 kHz 下测出来的值和实际运行工况下的增量电感能差 30% 以上,因为磁路饱和。做 MRAS 仿真时用增量电感更接近真实,可以用不同电流点反复测几组,取工作点附近的值。
3.2 初始化脚本:所有参数只在一个地方改
模型里散落几十个 Constant 块,改一次参数要翻半天,这是仿真模型最常见的可维护性问题。做法是写一个初始化脚本,把所有参数塞进结构体,再用load或直接在工作区里引用。
%% init_pmsm_mras.m —— 仿真前必须跑一次的初始化脚本 clear; clc; % ---------- 电机本体 ---------- mot.Rs = 0.35; % 定子相电阻 Ohm mot.Ld = 8.5e-3; % d 轴电感 H mot.Lq = 8.5e-3; % q 轴电感 H mot.psi = 0.175; % 永磁磁链 Wb mot.p = 4; % 极对数 mot.J = 3e-3; % 转动惯量 kg*m^2 mot.Bm = 1e-4; % 粘性阻尼 N*m*s % ---------- 逆变器 ---------- inv.Udc = 311; % 母线电压 V inv.fsw = 10e3; % 开关频率 Hz inv.Ts = 1e-4; % 控制周期 s inv.Ts_p = 1e-6; % 功率级步长 s inv.dead = 2e-6; % 死区时间 s % ---------- 控制器 ---------- ctl.n_ref = 1500; % 给定机械转速 rpm ctl.kp_i = 6.0; % 电流环 Kp ctl.ki_i = 1200; % 电流环 Ki ctl.kp_w = 0.08; % 速度环 Kp ctl.ki_w = 1.2; % 速度环 Ki ctl.iq_max = 12; % q 轴电流限幅 A % ---------- MRAS 估计器 ---------- mras.Kp = 2.5; % 自适应律比例 rpm/W mras.Ki = 80; % 自适应律积分 rpm/(W*s) mras.w0 = 200; % 估计转速初值 rpm,防上电死锁 mras.wmax = 6000; % 估计转速限幅 rpm mras.wc = 30; % 反电动势低通截止频率 rad/s % ---------- 低速段策略 ---------- low.n_switch = 150; % 低于该转速走 I-F 强拖 low.if_ratio = 1.2; % 强拖电流与负载电流之比 save('pmsm_mras_params.mat');电流环 Kp 的整定依据是带宽:想让电流环带宽 1 kHz,Kp ≈ L × 2π × 1000 ≈ 6.0,Ki ≈ Rs × 2π × 1000/10 ≈ 1200,这里的 /10 是把零点放在带宽的十分之一处。速度环 Kp 用惯量反推,0.08 对应 100 rad/s 左右的带宽。这些值都不是唯一解,但按公式推出来的至少不会发散。
提示:脚本末尾存 mat 文件是为了让模型可以在不打开脚本的情况下单独分发。运行模型前在 MATLAB 命令窗跑一次
init_pmsm_mras,或者把脚本挂到模型的 InitFcn 回调里。
3.3 MRAS 子系统的接线与代码
新建一个 Subsystem,命名 MRAS_Estimator,输入四路:uα、uβ、iα、iβ;输出三路:估计转速(rpm)、估计电角度(rad)、叉积误差 ε(调试用)。内部放一个 MATLAB Function 块,代码用离散形式写,状态量用 persistent 保存,这样不需要额外加单位延迟块。
function [w_hat, th_hat, eps_out] = mras_pmsm(u_alpha, u_beta, i_alpha, i_beta) %#codegen % 离散 MRAS 估计器,控制周期 Ts = 100 us persistent iha ihb th_hat w_hat Ieps if isempty(iha) iha = 0; ihb = 0; th_hat = 0; w_hat = 200; % rpm,非零初值,打破上电死锁 Ieps = 0; end Ts = 100e-6; Rs = 0.35; L = 8.5e-3; psi = 0.175; p = 4; Kp = 2.5; Ki = 80; WMAX = 6000; % 1) 用上一拍估计角度重建反电动势 w_e_hat = w_hat*pi/30*p; eha = -w_e_hat*psi*sin(th_hat); ehb = w_e_hat*psi*cos(th_hat); % 2) 可调模型:电流观测器,前向欧拉 diha = (u_alpha - Rs*iha - eha)/L; dihb = (u_beta - Rs*ihb - ehb)/L; iha = iha + diha*Ts; ihb = ihb + dihb*Ts; % 3) 叉积误差 -> PI 自适应律 -> 限幅 ea = i_alpha - iha; eb = i_beta - ihb; eps = eha*eb - ehb*ea; Ieps = Ieps + eps*Ts; w_new = Kp*eps + Ki*Ieps; w_new = min(max(w_new, -WMAX), WMAX); % 4) 角度积分与归一化 th_hat = th_hat + w_new*pi/30*p*Ts; if th_hat > 2*pi th_hat = th_hat - 2*pi; elseif th_hat < 0 th_hat = th_hat + 2*pi; end w_hat = w_new; eps_out = eps; end三处细节决定这个块能不能用。第一,反电动势用的是上一拍的th_hat,电流更新完之后才更新角度,这个顺序等价于人为引入一拍延迟,正好打断代数环,不要为了“更精确”把角度更新挪到前面。第二,persistent变量的初始化块只在第一次调用时执行,仿真中途改参数不会重置状态,需要重启仿真或加复位端口。第三,eps_out一定要引出来接 Scope,调参时全靠它判断符号和量级,藏起来等于把黑匣子盖上。
接线顺序:Park 变换和 Park 逆变换的角度输入全部接th_hat,不要接真实角度。调试期混用真实角度做反馈,转速曲线会漂亮得不像话,但那是假的——估计器的误差被闭环自己吃掉了,你永远看不到角度偏差。真实角度只用来接 Scope 做对比。
3.4 求解器与仿真配置
| 配置项 | 取值 | 理由 |
|---|---|---|
| Solver | ode4(Runge-Kutta)或 FixedStepDiscrete | 开关模型用定步长更可控 |
| 固定步长 | 1e-6 s | 对应 10 kHz 开关频率 |
| 多速率 | 电流环 1e-4 s、速度环 1e-3 s | 用 Rate Transition 块隔离 |
| 仿真时长 | 2 s | 覆盖启动、稳态、加载三个过程 |
| 代数环 | 全部用单位延迟或 persistent 打断 | 有代数环时仿真会报错或极慢 |
第一次跑建议把速度环断开,直接给 q 轴电流阶跃,只看电流环和估计器能不能跟上。等估计转速和真实转速的误差稳定在 2% 以内,再把速度环接回去。这个分步习惯能省掉大量“到底是哪个环在振”的排查时间。
4. 参数辨识与低速段:为什么转速一低就翻车
高速段这套 MRAS 表现很好,1500 rpm 以上估计误差通常能压到 1% 以内。真正的问题都集中在 200 rpm 以下:波形开始周期性抖动、加载后估计值突然塌陷、正反转切换时角度直接跑偏。这些现象背后其实是同一件事——反电动势的幅值随转速线性下降,而模型误差不随转速下降。
4.1 定子电阻温漂如何吃掉低速精度
先算一笔账。示例电机 ψf = 0.175 Wb,p = 4。转速 60 rpm 时电角速度 ωe = 60×π/30×4 ≈ 25.1 rad/s,反电动势幅值 = 0.175×25.1 ≈ 4.4 V。此时相电流 5 A,Rs 压降 = 0.35×5 = 1.75 V,和反电动势是同一个量级。
铜的电阻温度系数约 0.00393/℃,电机从冷态 25℃ 跑到 100℃ 绕组温升 75℃,Rs 增加约 29%,变成 0.45 Ω。同样的 5 A 电流下压降变成 2.26 V,比冷态多出 0.51 V。这 0.51 V 在观测器里被当成反电动势的一部分,占 4.4 V 的 11.6%,换算成角度误差约 arcsin(0.116) ≈ 6.7°。
同一台电机跑到 1500 rpm,反电动势 110 V,同样的 0.51 V 误差只占 0.46%,角度误差不到 0.3°,完全可以忽略。这就是低速翻车的定量解释:不是算法不行,是模型参数误差被转速放大了。所以低速段能不能用,取决于 Rs 辨识得准不准,而不是自适应律调得多好。
4.2 纯积分漂移与低通滤波替代
反电动势积分得到磁链的做法在理论上很干净,实际不能用:采样零漂、ADC 偏置、死区造成的电压误差,任何一个直流量经过纯积分都会线性累积,几十秒后积分器就顶到饱和。常见做法是用一阶低通代替纯积分,牺牲一点相位换取直流抑制。
function y = lpf_integrator(u, Ts, wc) % 带直流抑制的积分器:等价于 wc/(s+wc) 的低通 persistent yk if isempty(yk), yk = 0; end yk = yk + Ts*(u - wc*yk); y = yk; endwc取 3~30 rad/s,对应 0.5~5 Hz。取值越小直流抑制越弱但相位滞后越小,低速时反电动势频率本来就低,wc必须比 ωe 小一个数量级以上,否则滤掉的是有用信号。
相位滞后要补回来。低通环节在频率 ωe 处的相位滞后是 arctan(ωe/wc) 的补角,简单做法是在估计角度上直接加补偿量dth = atan(wc/w_e_hat),转速越低补偿量越大。这个补偿不做,低速时估计角度会系统性超前十几度,转矩输出打折,带载能力明显下降。
4.3 分步参数辨识:三个参数不要一起辨识
Rs、ψf、Ld/Lq 同时在线辨识,在稳态工况下是不可观的——多组参数组合能给出同样的电流响应。工程上的做法是分步、分工况。
| 参数 | 方法 | 激励条件 | 合格判据 |
|---|---|---|---|
| Rs | 直流伏安法,或闭环给定 id 阶跃后测稳态电压电流比 | 堵转,注入 20%~100% 额定电流的直流量,取 5 个点 | 各点线性度偏差 < 2% |
| ψf | 空载反电动势法,外力拖动测线电压 | 500 rpm 匀速,断开逆变器 | 与铭牌偏差 < 5% |
| Ld / Lq | 堵转下 d 轴小信号阶跃,或高频注入后测阻抗 | 电流工作点覆盖 25%~100% 额定 | 与设计值偏差 < 10%,饱和趋势合理 |
| Rs 在线修正 | 低速轻载时用 q 轴电压方程残差做慢速积分修正 | 转速 < 300 rpm | 修正量收敛且不振荡 |
Rs 在线修正的环路带宽要压得很低,通常 1~5 Hz,比速度环还慢一个量级。带宽一高就会和 MRAS 的自适应律抢着修正同一个误差,两个环互相激励,波形上表现为低频大幅度摆动,很容易被误判成机械共振。
4.4 低速段的工程兜底:I-F 强拖与切换判据
再准的辨识也救不了 30 rpm 以下的反电动势,那个转速下信号已经被噪声和死区误差淹没。工程上的标准做法是低速段切到 I-F 强拖:给定电流矢量的幅值和频率,靠电流矢量拖着转子走,不开位置闭环;等转速升到能可靠观测的区间再切回 MRAS 闭环。
切换判据不能只看转速,要看三个条件同时满足:估计转速与强拖给定转速的偏差小于 5%、估计角度与强拖给定的角度差小于 0.2 rad、连续满足 50 个控制周期。三个条件缺一个都会在负载突变时切错,切错的表现是转矩瞬间塌陷、电流冲击到限幅。
切换过程本身要平滑:切换瞬间把 MRAS 的积分器预置成当前强拖的转速值,角度直接对齐,不要让它从零开始追。这一步不做,切换瞬间会有一个明显的转速跌落,负载越大跌得越深。
5. 避坑与排查:五条血泪记录
这套模型我拆过不止一遍,下面五条是复现率最高的问题,每条按“现象—原因—解决”写,对着查能省掉大半时间。
本文还有配套的精品资源,点击获取