1. 基于SMO的永磁同步电机无位置传感器控制基础模型
任务目标
搭建永磁同步电机(PMSM)矢量控制仿真模型,实现基于滑模观测器(SMO)的转子位置与速度估计,并验证无位置传感器控制的基本功能。本案例聚焦于SMO核心算法及其与矢量控制的闭环集成,不涉及弱磁、MTPA等扩展策略。
系统架构与原理
采用id=0的矢量控制策略,电流环PI调节器输出d-q轴电压,经Park逆变换得到α-β轴电压,驱动PMSM模型。SMO基于α-β轴电流误差构造滑模面,通过开关函数提取反电动势信息,再经低通滤波与反正切计算得到转子位置估计值,速度由位置差分获得。系统框图如下:
环境依赖
MATLAB R2020a及以上版本(或GNU Octave 7.x),无需额外工具箱。仿真步长固定为1e-5秒,求解器选择ode4(四阶龙格-库塔)。
关键完整代码
以下为完整的PMSM无位置传感器矢量控制仿真核心代码,包含电机模型、SMO观测器、PI控制器及主循环:
% PMSM_SMO_Basic.m - 基于滑模观测器的PMSM无位置传感器控制基础模型
clear; clc; close all;
%% 1. PMSM参数
pmsm.Rs = 2.875; % 定子电阻(Ω)
pmsm.Ld = 0.0085; % d轴电感(H)
pmsm.Lq = 0.0085; % q轴电感(H)
pmsm.flux = 0.175; % 永磁体磁链(Wb)
pmsm.J = 0.001; % 转动惯量(kg·m²)
pmsm.B = 0.0001; % 阻尼系数(N·m·s)
pmsm.p = 4; % 极对数
%% 2. 控制参数
ctrl.Ts = 1e-5; % 仿真步长(s)
ctrl.Tsim = 0.5; % 仿真时间(s)
ctrl.w_ref = 150; % 给定电角速度(rad/s)
ctrl.id_ref = 0; % id=0控制
% PI参数(电流环)
ctrl.Kp_i = 20; ctrl.Ki_i = 200;
% PI参数(速度环)
ctrl.Kp_w = 0.5; ctrl.Ki_w = 5;
% SMO参数
smo.k = 100; % 滑模增益
smo.lpf_cutoff = 500; % 低通滤波器截止频率(rad/s)
%% 3. 状态初始化
x = [0; 0; 0; 0]; % [id; iq; w; theta]
x_hat = [0; 0; 0; 0]; % 观测器状态 [i_alpha_hat; i_beta_hat; w_hat; theta_hat]
i_alpha_hat = 0; i_beta_hat = 0;
e_alpha_f = 0; e_beta_f = 0; % 滤波后反电动势
w_hat = 0; theta_hat = 0;
int_w = 0; int_d = 0; int_q = 0; % PI积分器状态
% 存储
N = round(ctrl.Tsim / ctrl.Ts);
time = zeros(1, N); theta = zeros(1, N); theta_hat_log = zeros(1, N);
w_log = zeros(1, N); w_hat_log = zeros(1, N); iq_log = zeros(1, N);
%% 4. 主仿真循环
for k = 1:N
t = (k-1) * ctrl.Ts;
time(k) = t;
% --- 速度PI: 生成iq_ref ---
w_err = ctrl.w_ref - w_hat;
int_w = int_w + w_err * ctrl.Ts;
iq_ref = ctrl.Kp_w * w_err + ctrl.Ki_w * int_w;
iq_ref = max(min(iq_ref, 10), -10); % 限幅
% --- 电流PI: 生成vd, vq ---
err_d = ctrl.id_ref - x(1);
err_q = iq_ref - x(2);
int_d = int_d + err_d * ctrl.Ts;
int_q = int_q + err_q * ctrl.Ts;
vd = ctrl.Kp_i * err_d + ctrl.Ki_i * int_d;
vq = ctrl.Kp_i * err_q + ctrl.Ki_i * int_q;
% --- Park逆变换: dq→αβ ---
va = cos(theta_hat) * vd - sin(theta_hat) * vq;
vb = sin(theta_hat) * vd + cos(theta_hat) * vq;
% --- PMSM模型(在αβ坐标系) ---
% 电机电气方程: v = Ri + L di/dt + e
% 反电动势: e_alpha = -flux*w*sin(theta), e_beta = flux*w*cos(theta)
e_alpha = -pmsm.flux * x(3) * sin(x(4));
e_beta = pmsm.flux * x(3) * cos(x(4));
% 电流微分
di_alpha = (va - pmsm.Rs*x(1) - e_alpha) / pmsm.Ld;
di_beta = (vb - pmsm.Rs*x(2) - e_beta) / pmsm.Lq;
% 机械方程
Te = 1.5 * pmsm.p * pmsm.flux * x(2); % 电磁转矩
dw = (Te - pmsm.B*x(3)) / pmsm.J;
dtheta = x(3);
% 更新电机状态(欧拉积分)
x(1) = x(1) + di_alpha * ctrl.Ts;
x(2) = x(2) + di_beta * ctrl.Ts;
x(3) = x(3) + dw * ctrl.Ts;
x(4) = x(4) + dtheta * ctrl.Ts;
% --- SMO滑模观测器 ---
% 电流观测误差
err_alpha = x(1) - i_alpha_hat;
err_beta = x(2) - i_beta_hat;
% 滑模控制律(开关函数)
z_alpha = smo.k * sign(err_alpha);
z_beta = smo.k * sign(err_beta);
% 电流观测器动态
di_alpha_hat = (va - pmsm.Rs*i_alpha_hat - z_alpha) / pmsm.Ld;
di_beta_hat = (vb - pmsm.Rs*i_beta_hat - z_beta) / pmsm.Lq;
i_alpha_hat = i_alpha_hat + di_alpha_hat * ctrl.Ts;
i_beta_hat = i_beta_hat + di_beta_hat * ctrl.Ts;
% 等效反电动势(经低通滤波)
alpha_lpf = smo.lpf_cutoff * ctrl.Ts / (1 + smo.lpf_cutoff * ctrl.Ts);
e_alpha_f = e_alpha_f + alpha_lpf * (z_alpha - e_alpha_f);
e_beta_f = e_beta_f + alpha_lpf * (z_beta - e_beta_f);
% 位置估计(反正切)
theta_hat = atan2(-e_alpha_f, e_beta_f);
% 角度归一化到[0, 2π)
if theta_hat < 0
theta_hat = theta_hat + 2*pi;
end
% 速度估计(位置差分+低通)
if k > 1
w_hat_raw = (theta_hat - theta_hat_prev) / ctrl.Ts;
% 处理角度跳变
if w_hat_raw > pi/ctrl.Ts
w_hat_raw = w_hat_raw - 2*pi/ctrl.Ts;
elseif w_hat_raw < -pi/ctrl.Ts
w_hat_raw = w_hat_raw + 2*pi/ctrl.Ts;
end
w_hat = 0.95*w_hat + 0.05*w_hat_raw; % 一阶低通
end
theta_hat_prev = theta_hat;
% 存储
theta(k) = x(4);
theta_hat_log(k) = theta_hat;
w_log(k) = x(3);
w_hat_log(k) = w_hat;
iq_log(k) = x(2);
end
%% 5. 结果可视化
figure('Position', [100 100 900 600]);
subplot(2,2,1);
plot(time, w_log, 'b-', 'LineWidth', 1.5); hold on;
plot(time, w_hat_log, 'r--', 'LineWidth', 1.5);
legend('实际速度', '估计速度');
xlabel('时间(s)'); ylabel('电角速度(rad/s)');
title('速度估计结果'); grid on;
subplot(2,2,2);
theta_err = theta - theta_hat_log;
% 角度误差归一化到[-pi, pi]
theta_err = mod(theta_err + pi, 2*pi) - pi;
plot(time, theta_err*180/pi, 'g-', 'LineWidth', 1.5);
xlabel('时间(s)'); ylabel('位置误差(°)');
title('转子位置估计误差'); grid on;
subplot(2,2,3);
plot(time, iq_log, 'm-', 'LineWidth', 1.5);
xlabel('时间(s)'); ylabel('iq(A)');
title('q轴电流响应'); grid on;
subplot(2,2,4);
plot(time, theta*180/pi, 'b-', 'LineWidth', 1.5); hold on;
plot(time, theta_hat_log*180/pi, 'r--', 'LineWidth', 1.5);
legend('实际位置', '估计位置');
xlabel('时间(s)'); ylabel('转子位置(°)');
title('位置跟踪对比'); grid on;
%% 6. 稳态误差统计(取最后20%数据)
steady_start = round(0.8*N);
w_err_steady = mean(abs(w_log(steady_start:end) - w_hat_log(steady_start:end)));
theta_err_steady = mean(abs(theta_err(steady_start:end)));
fprintf('稳态速度估计误差: %.3f rad/s\n', w_err_steady);
fprintf('稳态位置估计误差: %.3f rad (%.2f°)\n', theta_err_steady, theta_err_steady*180/pi);
运行方式
- 将上述代码保存为
PMSM_SMO_Basic.m; - 在MATLAB中切换到该文件目录,直接运行脚本;
- 程序自动执行仿真并输出4幅波形图及稳态误差统计。
验证方法与通过条件
运行后观察以下结果并判定是否通过:
- 速度跟踪:速度估计值(红色虚线)在0.1s内收敛至给定值150 rad/s附近,稳态误差小于5 rad/s;
- 位置估计:位置误差曲线(绿色)在暂态后收敛至±10°以内,且不随时间发散;
- 位置跟踪对比:实际位置与估计位置曲线基本重合,无累积漂移;
- q轴电流:启动阶段存在合理超调,稳态后保持平稳。
若以上条件满足,则说明SMO观测器与矢量控制闭环正确,案例验证通过。若位置误差持续增大或速度无法收敛,请检查滑模增益smo.k是否足够大(可尝试增大至150~200),以及低通截止频率是否合适。