matlab的FOC仿真

工具: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

运行结果:

相关推荐
默默学前端1 小时前
JavaScript 中 call、apply、bind 的区别
开发语言·前端·javascript
星辰_mya2 小时前
Fork/Join 框架与并行流:CPU 密集型的“分身术”
java·开发语言·面试
郝学胜-神的一滴2 小时前
循环队列深度剖析:从算法原理到C++实现全解析
开发语言·数据结构·c++·算法·leetcode
Via_Neo2 小时前
接雨水问题 + 输入优化
java·开发语言·算法
所谓伊人,在水一方3332 小时前
【Python数据可视化精通】第9讲 | 实时数据流可视化
开发语言·python·信息可视化·数据分析·pandas
吃鱼不吐刺.2 小时前
阻塞队列。
java·开发语言
不光头强2 小时前
ArrayList知识点
java·开发语言·windows
码云数智-大飞2 小时前
解锁数据库极速引擎:索引底层机制、聚簇与非聚簇之争及性能避坑指南
开发语言
花间相见2 小时前
【JAVA基础03】—— JDK、JRE、JVM详解及原理
java·开发语言·jvm