工具:Matlab2021a
电脑信息:Intel® Xeon® CPU E5-2603 v3 @ 1.60GHz
系统类 型:64位操作系统,基于X64的处理器 windows10 专业版
一、SMO:
代码:
cpp
%% 滑模观测器 (SMO) 无位置传感器控制仿真
% 适用:PMSM 中高速运行区域
clear; clc; close all;
%% 1. 系统参数设置
fs = 20e3; % 控制频率 (Hz)
Ts = 1/fs; % 采样时间
T_sim = 0.8; % 仿真时间 (s)
t = 0:Ts:T_sim-Ts; % 时间向量
N = length(t);
% 电机参数 (4对极,表贴式 PMSM)
Pn = 4; % 极对数
Rs = 0.5; % 定子电阻 (Ohm)
Ls = 0.006; % 定子电感 (H) (Ld=Lq=Ls)
Psi_f = 0.08; % 永磁体磁链 (Wb)
J = 0.001; % 转动惯量
B = 0.0001; % 阻尼系数
% 运行工况
Target_Speed_RPM = 1000; % 目标转速
w_ref = Target_Speed_RPM * 2*pi/60; % rad/s
% SMO 参数
K_sliding = 20; % 滑模增益 (需大于反电动势最大幅值)
% 注意:K 必须足够大以克服扰动,但过大会增加抖振
lambda = 1000; % Sigmoid 函数的陡峭度 (1/delta)
% Sigmoid 函数: K * tanh(x / delta) 近似 sign(x)
% PLL 参数 (用于从 Back-EMF 提取角度)
Kp_pll = 200;
Ki_pll = 10000;
%% 2. 初始化变量
% 电机状态
i_alpha = zeros(1, N);
i_beta = zeros(1, N);
v_alpha = zeros(1, N);
v_beta = zeros(1, N);
theta_real = zeros(1, N);
w_real = zeros(1, N);
speed_rpm = zeros(1, N);
% 观测器状态
i_alpha_hat = zeros(1, N);
i_beta_hat = zeros(1, N);
e_alpha_hat = zeros(1, N); % 观测反电动势
e_beta_hat = zeros(1, N);
theta_est = zeros(1, N);
w_est = zeros(1, N);
speed_est_rpm = zeros(1, N);
% 初始条件
% 假设电机从静止启动,给定一个简单的开环V/F启动或直接给初值
% 这里为了演示SMO效果,我们让电机先加速到一定速度再切入SMO逻辑
% 或者假设初始位置已知误差较小
i_alpha(1) = 0; i_beta(1) = 0;
i_alpha_hat(1) = 0; i_beta_hat(1) = 0;
theta_real(1) = 0;
theta_est(1) = 0;
w_real(1) = 0;
w_est(1) = 0;
% 积分器状态
pll_integrator = 0;
fprintf('开始 SMO 仿真...\n');
%% 3. 主循环
for k = 1:N-1
next = k+1;
% --- 3.1 生成参考电压 (简化为开环矢量控制或理想电流环输出) ---
% 为了专注于SMO,这里假设电流环完美跟踪,直接计算所需的端电压
% 简单的 V/f 控制逻辑用于产生激励,或者使用 FOC 的电压输出
% 这里构造一个旋转电压矢量来驱动电机
th_cmd = w_ref * t(k); % 指令角度
% 简单的电压源逆变桥输出模拟 (FOC 电压指令)
% 假设 Id_ref=0, Iq_ref 由速度环决定 (此处简化为恒定转矩加速)
% 实际上应该有一个速度闭环,这里简化处理:
if t(k) < 0.2
% 加速阶段
w_target = w_ref * (t(k)/0.2);
else
w_target = w_ref;
end
% 简化的 FOC 电压计算 (忽略电流环动态,直接算出平衡电压 + 加速电压)
% v_d = Rs*id - w*Lq*iq
% v_q = Rs*iq + w*Ld*id + w*Psi_f
% 假设 id=0, iq 由负载和加速度决定
Te_load = 0.5; % 负载转矩
Te_acc = J * (w_ref/0.2); % 加速所需转矩 (前0.2秒)
if t(k) >= 0.2, Te_acc = 0; end
Te_total = Te_load + Te_acc;
iq_ref = Te_total / (1.5 * Pn * Psi_f);
id_ref = 0;
% 真实电角度
% 简单机械模型更新
alpha_mech = (Te_total - B*w_real(k) - Te_load) / J; % 角加速度
w_real(next) = w_real(k) + alpha_mech * Ts;
theta_real(next) = theta_real(k) + w_real(k) * Ts;
% 限制速度不超过目标 (简单模拟)
if w_real(next) > w_target, w_real(next) = w_target; end
% 坐标变换 (dq -> alpha-beta) 获取当前时刻的真实电压
% 注意:这里用当前步的 theta 和 w 计算电压施加到电机
vd = Rs*id_ref - w_real(k)*Ls*iq_ref;
vq = Rs*iq_ref + w_real(k)*Ls*id_ref + w_real(k)*Psi_f;
v_alpha(k) = vd * cos(theta_real(k)) - vq * sin(theta_real(k));
v_beta(k) = vd * sin(theta_real(k)) + vq * cos(theta_real(k));
% --- 3.2 电机模型 (真实植物) ---
% di/dt = (v - R*i - e) / L
% e_alpha = -Psi_f * w * sin(theta)
% e_beta = Psi_f * w * cos(theta)
e_alpha_real = -Psi_f * w_real(k) * sin(theta_real(k));
e_beta_real = Psi_f * w_real(k) * cos(theta_real(k));
di_alpha_dt = (v_alpha(k) - Rs*i_alpha(k) - e_alpha_real) / Ls;
di_beta_dt = (v_beta(k) - Rs*i_beta(k) - e_beta_real) / Ls;
i_alpha(next) = i_alpha(k) + di_alpha_dt * Ts;
i_beta(next) = i_beta(k) + di_beta_dt * Ts;
% --- 3.3 滑模观测器 (SMO) ---
% 1. 计算电流误差
err_ia = i_alpha_hat(k) - i_alpha(k);
err_ib = i_beta_hat(k) - i_beta(k);
% 2. 滑模控制律 (使用 Sigmoid 平滑化以减少抖振)
% Z_alpha = K * tanh(err_ia / delta)
% 这里用 lambda 代表 1/delta
Z_alpha = K_sliding * tanh(err_ia * lambda);
Z_beta = K_sliding * tanh(err_ib * lambda);
% 3. 观测器状态方程
% d(i_hat)/dt = (v - R*i_hat - Z) / L
di_alpha_hat_dt = (v_alpha(k) - Rs*i_alpha_hat(k) - Z_alpha) / Ls;
di_beta_hat_dt = (v_beta(k) - Rs*i_beta_hat(k) - Z_beta) / Ls;
i_alpha_hat(next) = i_alpha_hat(k) + di_alpha_hat_dt * Ts;
i_beta_hat(next) = i_beta_hat(k) + di_beta_hat_dt * Ts;
% 4. 提取反电动势 (Z 即为等效的反电动势加上高频噪声)
% 需要通过低通滤波器 (LPF) 滤除高频开关分量
% 这里使用一阶 LPF 模拟
fc_lpf = 200; % 截止频率,需根据转速调整,转速越高截止频率越高
alpha_lpf = 2*pi*fc_lpf*Ts / (1 + 2*pi*fc_lpf*Ts);
e_alpha_hat(k) = (1-alpha_lpf)*e_alpha_hat(max(1,k-1)) + alpha_lpf * Z_alpha;
e_beta_hat(k) = (1-alpha_lpf)*e_beta_hat(max(1,k-1)) + alpha_lpf * Z_beta;
% --- 3.4 锁相环 (PLL) 估算位置和速度 ---
% 误差信号:e_err = -e_alpha_hat * cos(theta_est) - e_beta_hat * sin(theta_est)
% 理论上 Back-EMF 矢量角度即为转子位置 (对于表贴机)
% 但直接用 atan2 噪声大,故用 PLL
% 归一化反电动势矢量 (可选,提高稳定性)
emf_mag = sqrt(e_alpha_hat(k)^2 + e_beta_hat(k)^2);
if emf_mag < 0.1
% 低速时反电动势太小,SMO 不可靠,保持上一时刻或开环
% 实际工程中会有切换逻辑
pll_error = 0;
else
% PLL 输入误差:sin(theta_err) ≈ -e_alpha*cos(th_est) - e_beta*sin(th_est)
% 注意符号定义,取决于 Back-EMF 公式定义
pll_error = (-e_alpha_hat(k) * cos(theta_est(k)) - e_beta_hat(k) * sin(theta_est(k))) / emf_mag;
end
% PI 调节器
prop_term = Kp_pll * pll_error;
pll_integrator = pll_integrator + Ki_pll * pll_error * Ts;
w_est(next) = prop_term + pll_integrator;
theta_est(next) = theta_est(k) + w_est(next) * Ts;
% 角度归一化 [-pi, pi]
theta_est(next) = mod(theta_est(next) + pi, 2*pi) - pi;
% 记录数据
speed_rpm(k) = w_real(k) * 30 / pi;
speed_est_rpm(k) = w_est(k) * 30 / pi;
end
fprintf('仿真结束。\n');
%% 4. 绘图分析
figure('Name', 'SMO 无位置传感器仿真', 'Color', 'w', 'Position', [100, 100, 1000, 800]);
subplot(3,1,1);
plot(t, theta_real, 'b', 'LineWidth', 1.5); hold on;
plot(t, theta_est, 'r--', 'LineWidth', 1.5);
legend('真实位置', 'SMO估计位置');
title('转子位置对比');
ylabel('角度 (rad)');
grid on;
xlim([0, T_sim]);
subplot(3,1,2);
plot(t, speed_rpm, 'b', 'LineWidth', 1.5); hold on;
plot(t, speed_est_rpm, 'r--', 'LineWidth', 1.5);
legend('真实转速', 'SMO估计转速');
title('转速对比');
ylabel('RPM');
grid on;
xlim([0, T_sim]);
subplot(3,1,3);
plot(t, theta_real - theta_est, 'k', 'LineWidth', 1);
title('位置估算误差 (真实 - 估计)');
ylabel('误差 (rad)');
xlabel('时间 (s)');
grid on;
xlim([0, T_sim]);
% 计算稳态误差
steady_state_idx = find(t > 0.4); % 取0.4秒后的数据
if ~isempty(steady_state_idx)
err_std = std(theta_real(steady_state_idx) - theta_est(steady_state_idx));
err_mean = mean(theta_real(steady_state_idx) - theta_est(steady_state_idx));
fprintf('稳态位置误差均值: %.4f rad (%.2f 度)\n', err_mean, rad2deg(err_mean));
fprintf('稳态位置误差标准差: %.4f rad\n', err_std);
end
运行结果:

二、隆伯格:
代码:
cpp
%% 龙伯格观测器 (Luenberger Observer) 无位置传感器控制仿真
% 原理:基于反电动势 (Back-EMF) 的增广状态观测器
% 特点:线性反馈,无极点跳变,波形平滑
clear; clc; close all;
%% 1. 参数设置
fs = 20e3; % 控制频率 (Hz)
Ts = 1/fs; % 采样时间
T_sim = 0.8; % 仿真时间 (s)
t = 0:Ts:T_sim-Ts; % 时间向量
N = length(t);
% 电机参数 (PMSM)
Pn = 4; % 极对数
Rs = 0.5; % 定子电阻 (Ohm)
Ld = 0.006; % d轴电感 (H)
Lq = 0.006; % q轴电感 (H) (表贴式 Ld=Lq)
Psi_f = 0.08; % 永磁体磁链 (Wb)
J = 0.001; % 转动惯量
B = 0.0001; % 阻尼系数
% 运行工况
Target_Speed_RPM = 1200;
w_ref = Target_Speed_RPM * 2*pi/60;
% 龙伯格观测器设计参数
% 观测器带宽通常是电机电气时间常数的 3~5 倍
% 电机电气极点 p_motor = -Rs/Ls
p_motor = -Rs/Ld;
observer_bandwidth_factor = 5;
p_obs = p_motor * observer_bandwidth_factor; % 期望的观测器极点
% 计算增益矩阵 L (针对 alpha-beta 轴解耦设计)
% 状态方程: x = [ia, ib, ea, eb]'
% 对于表贴机,alpha/beta轴解耦,可以分别设计两个二阶观测器或一个四阶
% 这里采用简化的对角增益设计 (假设 Ld=Lq)
% 理论推导表明,为了将极点配置在 p_obs (重根),增益如下:
% L1 (电流增益) = -(2*p_obs + Rs/L) <-- 注意符号定义,取决于误差反馈方向
% L2 (EMF增益) = -p_obs^2 * L
% 在本代码结构中: x_hat_dot = A*x_hat + B*u + L*(y - y_hat)
% 我们直接计算标量增益用于 alpha 和 beta 轴
L_ia = -2 * p_obs - Rs/Ld; % 电流误差反馈增益
L_ea = - (p_obs^2) * Ld; % 用于修正 EMF 变化率的增益 (间接)
% 注意:上面的公式是基于特定状态空间形式的。
% 为了通用性和稳定性,我们采用更直观的"电流误差反馈修正EMF"结构:
% d(i_hat)/dt = (v - R*i_hat - e_hat)/L + G1 * (i - i_hat)
% d(e_hat)/dt = 0 (假设低速下EMF变化慢) + G2 * (i - i_hat)
% 这种结构下,特征方程 s^2 + (R/L + G1)s + G2/L = 0
% 我们希望极点为 (s - p_obs)^2 = s^2 - 2*p_obs*s + p_obs^2
% 对比系数:
% R/L + G1 = -2*p_obs => G1 = -2*p_obs - R/L
% G2/L = p_obs^2 => G2 = p_obs^2 * L
G1 = -2 * p_obs - Rs/Ld;
G2 = (p_obs^2) * Ld;
% PLL 参数
Kp_pll = 300;
Ki_pll = 20000;
%% 2. 初始化变量
% 真实系统
i_alpha = zeros(1, N);
i_beta = zeros(1, N);
theta_real = zeros(1, N);
w_real = zeros(1, N);
v_alpha = zeros(1, N);
v_beta = zeros(1, N);
% 观测器系统
i_alpha_hat = zeros(1, N);
i_beta_hat = zeros(1, N);
e_alpha_hat = zeros(1, N); % 观测到的反电动势
e_beta_hat = zeros(1, N);
theta_est = zeros(1, N);
w_est = zeros(1, N);
% 初始值
i_alpha(1) = 0; i_beta(1) = 0;
i_alpha_hat(1) = 0; i_beta_hat(1) = 0;
e_alpha_hat(1) = 0; e_beta_hat(1) = 0;
theta_real(1) = 0; w_real(1) = 0;
theta_est(1) = 0; w_est(1) = 0;
pll_integrator = 0;
fprintf('开始龙伯格观测器仿真...\n');
%% 3. 主循环
for k = 1:N-1
next = k+1;
% --- 3.1 生成参考电压 (简化 FOC 驱动) ---
% 速度规划
if t(k) < 0.2
w_target = w_ref * (t(k)/0.2);
else
w_target = w_ref;
end
% 机械模型更新 (真实电机)
Te_load = 0.5;
Te_acc = J * (w_ref/0.2);
if t(k) >= 0.2, Te_acc = 0; end
Te_total = Te_load + Te_acc;
iq_ref = Te_total / (1.5 * Pn * Psi_f);
id_ref = 0;
% 真实转子动力学
alpha_mech = (Te_total - B*w_real(k) - Te_load) / J;
w_real(next) = w_real(k) + alpha_mech * Ts;
if w_real(next) > w_target, w_real(next) = w_target; end
theta_real(next) = theta_real(k) + w_real(k) * Ts;
% 计算真实端电压 (用于驱动模型)
vd = Rs*id_ref - w_real(k)*Lq*iq_ref;
vq = Rs*iq_ref + w_real(k)*Ld*id_ref + w_real(k)*Psi_f;
v_alpha(k) = vd * cos(theta_real(k)) - vq * sin(theta_real(k));
v_beta(k) = vd * sin(theta_real(k)) + vq * cos(theta_real(k));
% --- 3.2 真实电机电流模型 (Plant) ---
% 反电动势
e_alpha_real = -Psi_f * w_real(k) * sin(theta_real(k));
e_beta_real = Psi_f * w_real(k) * cos(theta_real(k));
di_alpha_dt = (v_alpha(k) - Rs*i_alpha(k) - e_alpha_real) / Ld;
di_beta_dt = (v_beta(k) - Rs*i_beta(k) - e_beta_real) / Lq;
i_alpha(next) = i_alpha(k) + di_alpha_dt * Ts;
i_beta(next) = i_beta(k) + di_beta_dt * Ts;
% --- 3.3 龙伯格观测器 (Luenberger Observer) ---
% 1. 计算电流观测误差
err_ia = i_alpha(k) - i_alpha_hat(k);
err_ib = i_beta(k) - i_beta_hat(k);
% 2. 观测器状态方程
% d(i_hat)/dt = (v - R*i_hat - e_hat)/L + G1 * err
% d(e_hat)/dt = 0 + G2 * err (假设反电动势在短时间内恒定/缓变)
di_alpha_hat_dt = (v_alpha(k) - Rs*i_alpha_hat(k) - e_alpha_hat(k)) / Ld + G1 * err_ia;
di_beta_hat_dt = (v_beta(k) - Rs*i_beta_hat(k) - e_beta_hat(k)) / Lq + G1 * err_ib;
de_alpha_hat_dt = G2 * err_ia;
de_beta_hat_dt = G2 * err_ib;
% 3. 欧拉积分更新
i_alpha_hat(next) = i_alpha_hat(k) + di_alpha_hat_dt * Ts;
i_beta_hat(next) = i_beta_hat(k) + di_beta_hat_dt * Ts;
e_alpha_hat(next) = e_alpha_hat(k) + de_alpha_hat_dt * Ts;
e_beta_hat(next) = e_beta_hat(k) + de_beta_hat_dt * Ts;
% --- 3.4 锁相环 (PLL) 提取位置和速度 ---
% 使用当前步的观测值 (next) 或上一步,这里用 next 以获得最新信息
% 归一化
emf_mag = sqrt(e_alpha_hat(next)^2 + e_beta_hat(next)^2);
pll_error = 0;
if emf_mag > 0.5 % 低速阈值,防止除零和噪声干扰
% 误差定义:使得观测 EMF 矢量与估计角度对齐
% e_alpha = -E*sin(theta), e_beta = E*cos(theta)
% 误差 = -e_alpha*cos(th_est) - e_beta*sin(th_est) = E*sin(theta - th_est)
pll_error = (-e_alpha_hat(next) * cos(theta_est(k)) - e_beta_hat(next) * sin(theta_est(k))) / emf_mag;
end
% PI 控制器
prop_term = Kp_pll * pll_error;
pll_integrator = pll_integrator + Ki_pll * pll_error * Ts;
w_est(next) = prop_term + pll_integrator;
theta_est(next) = theta_est(k) + w_est(next) * Ts;
% 角度归一化
theta_est(next) = mod(theta_est(next) + pi, 2*pi) - pi;
end
fprintf('仿真结束。\n');
%% 4. 绘图与分析
figure('Name', '龙伯格观测器仿真', 'Color', 'w', 'Position', [100, 100, 1000, 800]);
subplot(3,1,1);
plot(t, theta_real, 'b', 'LineWidth', 1.5); hold on;
plot(t, theta_est, 'r--', 'LineWidth', 1.5);
legend('真实位置', '龙伯格估计');
title(['转子位置 (观测器带宽因子 = ' num2str(observer_bandwidth_factor) ')']);
ylabel('角度 (rad)');
grid on; xlim([0, T_sim]);
subplot(3,1,2);
plot(t, w_real*30/pi, 'b', 'LineWidth', 1.5); hold on;
plot(t, w_est*30/pi, 'r--', 'LineWidth', 1.5);
legend('真实转速', '估计转速');
title('转速对比');
ylabel('RPM');
grid on; xlim([0, T_sim]);
subplot(3,1,3);
plot(t, e_alpha_real, 'b:', 'DisplayName', '真实 Ea'); hold on;
plot(t, e_alpha_hat, 'r', 'DisplayName', '观测 Ea');
legend('Location', 'best');
title('A相反电动势观测效果');
ylabel('Voltage (V)');
grid on; xlim([0, T_sim]);
% 误差统计
steady_idx = find(t > 0.4);
if ~isempty(steady_idx)
pos_err = theta_real(steady_idx) - theta_est(steady_idx);
fprintf('稳态位置误差均值: %.4f rad (%.2f 度)\n', mean(pos_err), rad2deg(mean(pos_err)));
fprintf('稳态位置误差标准差: %.4f rad\n', std(pos_err));
end
运行结果:

三、线性磁链
代码:
cpp
%% 线性磁链观测器 (Linear Flux Observer) 仿真
% 原理:结合电压模型与电流模型,利用线性反馈消除积分漂移
% 特点:无低通滤波器相位滞后,低速性能优于纯电压模型
clear; clc; close all;
%% 1. 参数设置
fs = 20e3; % 控制频率 (Hz)
Ts = 1/fs; % 采样时间
T_sim = 1.0; % 仿真时间 (s)
t = 0:Ts:T_sim-Ts; % 时间向量
N = length(t);
% 电机参数 (PMSM, 表贴式)
Pn = 4; % 极对数
Rs = 0.5; % 定子电阻 (Ohm)
Ld = 0.006; % d轴电感 (H)
Lq = 0.006; % q轴电感 (H)
Psi_f_ref = 0.08; % 额定永磁磁链幅值 (Wb)
J = 0.001; % 转动惯量
B = 0.0001; % 阻尼系数
% 运行工况:包含低速启动过程
Target_Speed_RPM = 600;
w_ref = Target_Speed_RPM * 2*pi/60;
% 观测器参数
% K_flux 是线性反馈增益,决定了观测器带宽和抗漂移能力
% 越大收敛越快,但对噪声越敏感;越小抗噪好,但低速漂移大
K_flux = 50; % 磁链观测器增益 (需整定)
% PLL 参数
Kp_pll = 200;
Ki_pll = 5000;
%% 2. 初始化变量
% 真实系统
i_alpha = zeros(1, N);
i_beta = zeros(1, N);
v_alpha = zeros(1, N);
v_beta = zeros(1, N);
theta_real = zeros(1, N);
w_real = zeros(1, N);
psi_alpha_real = zeros(1, N); % 真实总磁链
psi_beta_real = zeros(1, N);
psi_f_alpha_real = zeros(1, N); % 真实永磁磁链分量
psi_f_beta_real = zeros(1, N);
% 观测器系统
psi_alpha_hat = zeros(1, N); % 观测总磁链 alpha
psi_beta_hat = zeros(1, N); % 观测总磁链 beta
psi_f_alpha_hat = zeros(1, N); % 观测永磁磁链 alpha (用于计算角度)
psi_f_beta_hat = zeros(1, N);
theta_est = zeros(1, N);
w_est = zeros(1, N);
% 初始条件
i_alpha(1) = 0; i_beta(1) = 0;
psi_alpha_hat(1) = 0; psi_beta_hat(1) = 0;
% 注意:实际应用中可能需要预充电初始磁链,这里假设为0开始收敛
theta_real(1) = 0; w_real(1) = 0;
theta_est(1) = 0; w_est(1) = 0;
pll_integrator = 0;
fprintf('开始线性磁链观测器仿真...\n');
%% 3. 主循环
for k = 1:N-1
next = k+1;
% --- 3.1 速度规划与机械模型 (真实电机) ---
% 斜坡启动,测试低速性能
if t(k) < 0.5
w_target = w_ref * (t(k)/0.5);
else
w_target = w_ref;
end
Te_load = 0.2;
Te_acc = J * (w_ref/0.5);
if t(k) >= 0.5, Te_acc = 0; end
Te_total = Te_load + Te_acc;
iq_ref = max(0, Te_total) / (1.5 * Pn * Psi_f_ref); % 简单转矩控制
id_ref = 0;
% 真实转子动力学
alpha_mech = (Te_total - B*w_real(k) - Te_load) / J;
w_real(next) = w_real(k) + alpha_mech * Ts;
if w_real(next) > w_target, w_real(next) = w_target; end
if w_real(next) < 0, w_real(next) = 0; end
theta_real(next) = theta_real(k) + w_real(k) * Ts;
theta_real(next) = mod(theta_real(next) + pi, 2*pi) - pi;
% 计算真实端电压 (FOC 输出)
vd = Rs*id_ref - w_real(k)*Lq*iq_ref;
vq = Rs*iq_ref + w_real(k)*Ld*id_ref + w_real(k)*Psi_f_ref;
v_alpha(k) = vd * cos(theta_real(k)) - vq * sin(theta_real(k));
v_beta(k) = vd * sin(theta_real(k)) + vq * cos(theta_real(k));
% --- 3.2 真实电机电流与磁链 (Plant) ---
% 反电动势
e_alpha = -Psi_f_ref * w_real(k) * sin(theta_real(k));
e_beta = Psi_f_ref * w_real(k) * cos(theta_real(k));
di_alpha_dt = (v_alpha(k) - Rs*i_alpha(k) - e_alpha) / Ld;
di_beta_dt = (v_beta(k) - Rs*i_beta(k) - e_beta) / Lq;
i_alpha(next) = i_alpha(k) + di_alpha_dt * Ts;
i_beta(next) = i_beta(k) + di_beta_dt * Ts;
% 真实总磁链 psi_s = L*i + psi_f
psi_alpha_real(k) = Ld * i_alpha(k) + Psi_f_ref * cos(theta_real(k));
psi_beta_real(k) = Lq * i_beta(k) + Psi_f_ref * sin(theta_real(k));
% 真实永磁磁链分量
psi_f_alpha_real(k) = Psi_f_ref * cos(theta_real(k));
psi_f_beta_real(k) = Psi_f_ref * sin(theta_real(k));
% --- 3.3 线性磁链观测器 (核心算法) ---
% 方法:电压模型积分 + 电流模型反馈校正
% 电压模型:d(psi_hat)/dt = u - R*i
% 电流模型:psi_model = L * i_hat + psi_f_vec (这里用观测到的磁链反推电流误差)
% 更通用的线性观测器结构:
% d(psi_hat)/dt = u - R*i + K * (psi_current_model - psi_voltage_integral)
% 但由于 psi_current_model 依赖 theta,形成代数环。
%
% 替代方案 (常用工程实现):
% 观测总磁链:d(psi_hat)/dt = u - R*i + K * (psi_ref_mag - |psi_hat|) * (psi_hat / |psi_hat|) ?
% 不,这种是非线性的。
%
% 【本代码采用方案】:基于电流误差的磁链修正
% 1. 先计算纯电压模型积分值 (带漂移)
psi_alpha_volt = psi_alpha_hat(k) + (v_alpha(k) - Rs*i_alpha(k)) * Ts;
psi_beta_volt = psi_beta_hat(k) + (v_beta(k) - Rs*i_beta(k)) * Ts;
% 2. 计算基于当前观测磁链推导出的"期望电流"
% 假设 psi_hat = L * i_est + psi_f_est
% 我们无法直接知道 psi_f_est 的角度,所以使用另一种策略:
% 利用磁链幅值约束或 PLL 辅助。
%
% 【更稳健的线性观测器结构】:
% 状态变量:psi_alpha, psi_beta
% 方程:d(psi)/dt = u - R*i + K * ( i_measured - i_estimated_from_flux )
% 其中 i_estimated_from_flux = (psi_hat - psi_f_vector) / L
% 但 psi_f_vector 未知。
%
% 【修正方案:简化版线性磁链观测器 (带幅值约束反馈)】
% 许多文献使用:d(psi_hat)/dt = u - R*i + K * ( Psi_f_ref * unit_vec - (psi_hat - L*i) )
% 这需要单位矢量,即需要角度,构成耦合。
%
% 【最终采用方案:解耦的线性补偿 (类似龙伯格但观测磁链)】
% 我们观测永磁磁链分量 psi_f_alpha, psi_f_beta
% 关系:psi_f = psi_total - L*i
% 微分:d(psi_f)/dt = d(psi_total)/dt - L*di/dt
% = (u - R*i) - L * ( (u - R*i - e)/L )
% = e (理论上)
% 这又回到了反电动势观测。
%
% *** 真正的线性磁链观测器优势在于处理积分初值和漂移 ***
% 算法:
% psi_hat(k+1) = psi_hat(k) + (u(k) - R*i(k))*Ts + K * ( psi_model_based - psi_hat(k) ) * Ts
% 其中 psi_model_based 是利用当前估计角度计算的磁链。
% 为了打破代数环,使用上一拍的角度或 PLL 同步计算。
% 步骤 A: 纯电压积分 (预测步)
psi_alpha_pred = psi_alpha_hat(k) + (v_alpha(k) - Rs*i_alpha(k)) * Ts;
psi_beta_pred = psi_beta_hat(k) + (v_beta(k) - Rs*i_beta(k)) * Ts;
% 步骤 B: 利用上一时刻估计角度构建"电流模型"磁链参考
% psi_ref = L * i(k) + Psi_f_ref * [cos(theta_est), sin(theta_est)]
% 注意:这里用实测电流 i(k) 和 估计角度
psi_alpha_ref = Ld * i_alpha(k) + Psi_f_ref * cos(theta_est(k));
psi_beta_ref = Lq * i_beta(k) + Psi_f_ref * sin(theta_est(k));
% 步骤 C: 线性反馈校正
% 误差 = 参考值 - 预测值
err_psi_a = psi_alpha_ref - psi_alpha_pred;
err_psi_b = psi_beta_ref - psi_beta_pred;
% 更新观测磁链
psi_alpha_hat(next) = psi_alpha_pred + K_flux * err_psi_a * Ts;
psi_beta_hat(next) = psi_beta_pred + K_flux * err_psi_b * Ts;
% 提取永磁磁链分量 (用于PLL)
% psi_f_hat = psi_total_hat - L * i
psi_f_alpha_hat(next) = psi_alpha_hat(next) - Ld * i_alpha(next);
psi_f_beta_hat(next) = psi_beta_hat(next) - Lq * i_beta(next);
% --- 3.4 锁相环 (PLL) ---
% 输入:观测到的永磁磁链矢量
emf_mag = sqrt(psi_f_alpha_hat(next)^2 + psi_f_beta_hat(next)^2);
pll_error = 0;
if emf_mag > 0.01 % 避免除零
% 磁链矢量角度即为转子角度
% 误差信号构造:sin(theta_err) ≈ sin(theta_real - theta_est)
% 使用叉积形式:sin(A-B) = sinAcosB - cosAsinB
% psi_f_alpha = Psi*cos(theta), psi_f_beta = Psi*sin(theta) (定义可能不同,需对齐)
% 前面定义:psi_alpha = L*i + Psi*cos(theta)
% 所以 psi_f_alpha ~ cos(theta), psi_f_beta ~ sin(theta)
% 误差 = psi_f_beta * cos(est) - psi_f_alpha * sin(est) = Psi * sin(theta - est)
pll_error = (psi_f_beta_hat(next) * cos(theta_est(k)) - psi_f_alpha_hat(next) * sin(theta_est(k))) / emf_mag;
end
prop_term = Kp_pll * pll_error;
pll_integrator = pll_integrator + Ki_pll * pll_error * Ts;
w_est(next) = prop_term + pll_integrator;
theta_est(next) = theta_est(k) + w_est(next) * Ts;
theta_est(next) = mod(theta_est(next) + pi, 2*pi) - pi;
end
fprintf('仿真结束。\n');
%% 4. 绘图分析
figure('Name', '线性磁链观测器仿真', 'Color', 'w', 'Position', [100, 100, 1000, 800]);
subplot(3,1,1);
plot(t, theta_real, 'b', 'LineWidth', 1.5); hold on;
plot(t, theta_est, 'r--', 'LineWidth', 1.5);
legend('真实位置', '磁链观测器估计');
title(['线性磁链观测器 (K=' num2str(K_flux) ')']);
ylabel('角度 (rad)');
grid on; xlim([0, T_sim]);
subplot(3,1,2);
plot(t, w_real*30/pi, 'b', 'LineWidth', 1.5); hold on;
plot(t, w_est*30/pi, 'r--', 'LineWidth', 1.5);
legend('真实转速', '估计转速');
title('转速对比 (含低速启动)');
ylabel('RPM');
grid on; xlim([0, T_sim]);
subplot(3,1,3);
plot(t, psi_f_alpha_real, 'b:', 'DisplayName', '真实 Psi_f_a'); hold on;
plot(t, psi_f_alpha_hat, 'r', 'DisplayName', '观测 Psi_f_a');
legend('Location', 'best');
title('永磁磁链分量观测效果');
ylabel('Wb');
grid on; xlim([0, T_sim]);
% 误差统计
steady_idx = find(t > 0.6);
if ~isempty(steady_idx)
pos_err = theta_real(steady_idx) - theta_est(steady_idx);
fprintf('稳态位置误差均值: %.4f rad (%.2f 度)\n', mean(pos_err), rad2deg(mean(pos_err)));
fprintf('稳态位置误差标准差: %.4f rad\n', std(pos_err));
end
运行结果:

四、非线性磁链
cpp
%% 非线性磁链观测器 (Nonlinear Sliding Mode Flux Observer)
% 原理:在电压模型积分基础上,引入基于电流误差的滑模反馈项
% 特点:对电阻变化鲁棒,无积分漂移,动态响应快
clear; clc; close all;
%% 1. 参数设置
fs = 20e3; % 控制频率 (Hz)
Ts = 1/fs; % 采样时间
T_sim = 1.0; % 仿真时间 (s)
t = 0:Ts:T_sim-Ts; % 时间向量
N = length(t);
% 电机参数 (PMSM, 表贴式)
Pn = 4;
Rs_nominal = 0.5; % 标称电阻 (观测器使用的电阻)
Rs_real = 0.75; % 真实电阻 (模拟温度升高,变化 +50%,测试鲁棒性)
Ld = 0.006;
Lq = 0.006;
Psi_f_ref = 0.08;
J = 0.001;
B = 0.0001;
% 运行工况
Target_Speed_RPM = 800;
w_ref = Target_Speed_RPM * 2*pi/60;
% 非线性观测器参数
K_sliding = 150; % 滑模增益 (需足够大以克服电阻误差引起的扰动)
delta_boundary = 0.05; % 边界层厚度 (用于 sat 函数,减少抖振)
% 如果 delta_boundary -> 0,则退化为 sign 函数,抖振最大但鲁棒性最强
% PLL 参数
Kp_pll = 300;
Ki_pll = 8000;
%% 2. 初始化变量
% 真实系统
i_alpha = zeros(1, N);
i_beta = zeros(1, N);
v_alpha = zeros(1, N);
v_beta = zeros(1, N);
theta_real = zeros(1, N);
w_real = zeros(1, N);
% 观测器系统
psi_alpha_hat = zeros(1, N); % 观测总磁链
psi_beta_hat = zeros(1, N);
i_alpha_hat = zeros(1, N); % 观测电流 (用于计算误差)
theta_est = zeros(1, N);
w_est = zeros(1, N);
psi_f_alpha_hat = zeros(1, N);
psi_f_beta_hat = zeros(1, N);
% 初始条件
i_alpha(1) = 0; i_beta(1) = 0;
psi_alpha_hat(1) = 0; psi_beta_hat(1) = 0;
i_alpha_hat(1) = 0; i_beta_hat(1) = 0;
theta_real(1) = 0; w_real(1) = 0;
theta_est(1) = 0; w_est(1) = 0;
pll_integrator = 0;
fprintf('开始非线性磁链观测器仿真 (真实电阻 vs 标称电阻)...\n');
fprintf('真实电阻 Rs = %.2f, 观测器设定 Rs = %.2f\n', Rs_real, Rs_nominal);
%% 3. 主循环
for k = 1:N-1
next = k+1;
% --- 3.1 速度规划与机械模型 (真实电机) ---
if t(k) < 0.5
w_target = w_ref * (t(k)/0.5);
else
w_target = w_ref;
end
Te_load = 0.3;
Te_acc = J * (w_ref/0.5);
if t(k) >= 0.5, Te_acc = 0; end
Te_total = Te_load + Te_acc;
iq_ref = max(0, Te_total) / (1.5 * Pn * Psi_f_ref);
id_ref = 0;
% 真实转子动力学
alpha_mech = (Te_total - B*w_real(k) - Te_load) / J;
w_real(next) = w_real(k) + alpha_mech * Ts;
if w_real(next) > w_target, w_real(next) = w_target; end
if w_real(next) < 0, w_real(next) = 0; end
theta_real(next) = theta_real(k) + w_real(k) * Ts;
theta_real(next) = mod(theta_real(next) + pi, 2*pi) - pi;
% 计算真实端电压 (使用真实电阻 Rs_real)
vd = Rs_real*id_ref - w_real(k)*Lq*iq_ref;
vq = Rs_real*iq_ref + w_real(k)*Ld*id_ref + w_real(k)*Psi_f_ref;
v_alpha(k) = vd * cos(theta_real(k)) - vq * sin(theta_real(k));
v_beta(k) = vd * sin(theta_real(k)) + vq * cos(theta_real(k));
% --- 3.2 真实电机电流 (Plant) ---
e_alpha = -Psi_f_ref * w_real(k) * sin(theta_real(k));
e_beta = Psi_f_ref * w_real(k) * cos(theta_real(k));
di_alpha_dt = (v_alpha(k) - Rs_real*i_alpha(k) - e_alpha) / Ld;
di_beta_dt = (v_beta(k) - Rs_real*i_beta(k) - e_beta) / Lq;
i_alpha(next) = i_alpha(k) + di_alpha_dt * Ts;
i_beta(next) = i_beta(k) + di_beta_dt * Ts;
% --- 3.3 非线性滑模磁链观测器 (核心算法) ---
% 1. 计算电流观测值 (基于当前观测磁链)
% psi_hat = L * i_hat + psi_f_est => i_hat = (psi_hat - psi_f_est) / L
% 但 psi_f_est 未知。
% 另一种思路:直接利用电压方程预测电流,然后比较?
% 标准滑模磁链观测器结构:
% d(psi_hat)/dt = u - R_nom * i_meas + U_sm (滑模校正项)
% 其中 U_sm 是基于 (i_meas - i_model) 的非线性函数
% 为了构造误差信号,我们需要一个"参考电流"
% 参考电流由观测到的磁链和估计的永磁磁链矢量推导:
% i_ref = (psi_hat - Psi_f_ref * [cos(theta_est), sin(theta_est)]) / L
% 注意:这里存在代数环,使用 k 时刻的角度估计 k+1 时刻
psi_f_a_est = Psi_f_ref * cos(theta_est(k));
psi_f_b_est = Psi_f_ref * sin(theta_est(k));
i_alpha_model = (psi_alpha_hat(k) - psi_f_a_est) / Ld;
i_beta_model = (psi_beta_hat(k) - psi_f_b_est) / Lq;
% 2. 电流误差 (滑模面)
% S = i_meas - i_model
err_ia = i_alpha(k) - i_alpha_model;
err_ib = i_beta(k) - i_beta_model;
% 3. 非线性滑模控制律 (使用饱和函数 sat 代替 sign 以减少抖振)
% U_sm = K * sat(S / delta)
if abs(err_ia) > delta_boundary
U_sm_a = K_sliding * sign(err_ia);
else
U_sm_a = K_sliding * (err_ia / delta_boundary);
end
if abs(err_ib) > delta_boundary
U_sm_b = K_sliding * sign(err_ib);
else
U_sm_b = K_sliding * (err_ib / delta_boundary);
end
% 4. 磁链状态更新
% d(psi_hat)/dt = u - R_nom * i_meas + U_sm
% 注意:这里使用的是标称电阻 Rs_nominal,而非真实电阻 Rs_real
% 滑模项 U_sm 将自动补偿 (Rs_real - Rs_nominal)*i 带来的误差
dpsi_alpha_dt = v_alpha(k) - Rs_nominal * i_alpha(k) + U_sm_a;
dpsi_beta_dt = v_beta(k) - Rs_nominal * i_beta(k) + U_sm_b;
psi_alpha_hat(next) = psi_alpha_hat(k) + dpsi_alpha_dt * Ts;
psi_beta_hat(next) = psi_beta_hat(k) + dpsi_beta_dt * Ts;
% 5. 提取永磁磁链分量 (用于 PLL)
% 重新计算基于最新磁链的模型电流,以更新永磁分量估计
% 或者直接:psi_f_hat = psi_total_hat - L * i_meas (这包含电阻误差,不推荐)
% 正确做法:psi_f_hat 应该从 psi_total_hat 中减去 L * i_model (因为 i_model 是与 psi_f 自洽的)
% 但更简单且常用的工程做法是:
% psi_f_alpha_hat = psi_alpha_hat - L * i_alpha(k);
% 等等,如果用实测电流,电阻误差会体现在 psi_f 幅值上,但角度影响较小?
% 滑模观测器的精髓在于:U_sm 补偿了电阻压降误差,使得 psi_hat 趋近于真实总磁链。
% 因此,直接使用实测电流扣除电感压降是可行的:
psi_f_alpha_hat(next) = psi_alpha_hat(next) - Ld * i_alpha(next);
psi_f_beta_hat(next) = psi_beta_hat(next) - Lq * i_beta(next);
% --- 3.4 锁相环 (PLL) ---
emf_mag = sqrt(psi_f_alpha_hat(next)^2 + psi_f_beta_hat(next)^2);
pll_error = 0;
if emf_mag > 0.01
% 误差构造:sin(theta_err) ≈ psi_f_beta*cos(est) - psi_f_alpha*sin(est)
pll_error = (psi_f_beta_hat(next) * cos(theta_est(k)) - psi_f_alpha_hat(next) * sin(theta_est(k))) / emf_mag;
end
prop_term = Kp_pll * pll_error;
pll_integrator = pll_integrator + Ki_pll * pll_error * Ts;
w_est(next) = prop_term + pll_integrator;
theta_est(next) = theta_est(k) + w_est(next) * Ts;
theta_est(next) = mod(theta_est(next) + pi, 2*pi) - pi;
% 记录观测电流用于绘图
i_alpha_hat(next) = i_alpha_model; % 近似
i_beta_hat(next) = i_beta_model;
end
fprintf('仿真结束。\n');
%% 4. 绘图分析
figure('Name', '非线性滑模磁链观测器', 'Color', 'w', 'Position', [100, 100, 1000, 800]);
subplot(3,1,1);
plot(t, theta_real, 'b', 'LineWidth', 1.5); hold on;
plot(t, theta_est, 'r--', 'LineWidth', 1.5);
legend('真实位置', '非线性观测器估计');
title(['非线性磁链观测器 (电阻失配: 真实=' num2str(Rs_real) ' vs 标称=' num2str(Rs_nominal) ')']);
ylabel('角度 (rad)');
grid on; xlim([0, T_sim]);
subplot(3,1,2);
plot(t, w_real*30/pi, 'b', 'LineWidth', 1.5); hold on;
plot(t, w_est*30/pi, 'r--', 'LineWidth', 1.5);
legend('真实转速', '估计转速');
title('转速对比 (鲁棒性测试)');
ylabel('RPM');
grid on; xlim([0, T_sim]);
subplot(3,1,3);
plot(t, i_alpha, 'b', 'DisplayName', '真实 Ia'); hold on;
plot(t, i_alpha_hat, 'r--', 'DisplayName', '模型 Ia');
% 绘制电流误差以展示滑模面
plot(t, i_alpha - i_alpha_hat, 'k:', 'LineWidth', 1, 'DisplayName', '电流误差 (滑模面)');
legend('Location', 'best');
title('电流跟踪与滑模面 (误差应趋近于0)');
ylabel('Current (A)');
grid on; xlim([0, T_sim]);
% 误差统计
steady_idx = find(t > 0.6);
if ~isempty(steady_idx)
pos_err = theta_real(steady_idx) - theta_est(steady_idx);
fprintf('稳态位置误差均值: %.4f rad (%.2f 度)\n', mean(pos_err), rad2deg(mean(pos_err)));
fprintf('稳态位置误差标准差: %.4f rad\n', std(pos_err));
end
运行结果:
