1. 基于SMO的永磁同步电机无位置传感器控制基础模型

任务目标

搭建永磁同步电机(PMSM)矢量控制仿真模型,实现基于滑模观测器(SMO)的转子位置与速度估计,并验证无位置传感器控制的基本功能。本案例聚焦于SMO核心算法及其与矢量控制的闭环集成,不涉及弱磁、MTPA等扩展策略。

系统架构与原理

采用id=0的矢量控制策略,电流环PI调节器输出d-q轴电压,经Park逆变换得到α-β轴电压,驱动PMSM模型。SMO基于α-β轴电流误差构造滑模面,通过开关函数提取反电动势信息,再经低通滤波与反正切计算得到转子位置估计值,速度由位置差分获得。系统框图如下:

速度PI ω*→iq* 电流PI id,iq→vd,vq IPark dq→αβ PMSM 模型 Clarke abc→αβ SMO 滑模观测器 位置 计算 ia,ib,ic ω_est θ_est ω* (给定)

环境依赖

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);

运行方式

  1. 将上述代码保存为PMSM_SMO_Basic.m;
  2. 在MATLAB中切换到该文件目录,直接运行脚本;
  3. 程序自动执行仿真并输出4幅波形图及稳态误差统计。

验证方法与通过条件

运行后观察以下结果并判定是否通过:

  • 速度跟踪:速度估计值(红色虚线)在0.1s内收敛至给定值150 rad/s附近,稳态误差小于5 rad/s;
  • 位置估计:位置误差曲线(绿色)在暂态后收敛至±10°以内,且不随时间发散;
  • 位置跟踪对比:实际位置与估计位置曲线基本重合,无累积漂移;
  • q轴电流:启动阶段存在合理超调,稳态后保持平稳。

若以上条件满足,则说明SMO观测器与矢量控制闭环正确,案例验证通过。若位置误差持续增大或速度无法收敛,请检查滑模增益smo.k是否足够大(可尝试增大至150~200),以及低通截止频率是否合适。