【PMSM例程3】负载前馈与补偿估计,基于EKF,附MATLAB程序的下载链接

本博客基于永磁同步电机(PMSM)数学模型,采用扩展卡尔曼滤波(EKF)实现未知负载转矩观测,并结合磁场定向控制(FOC)设计负载前馈补偿策略。通过阶跃负载工况仿真,对比分析转速响应、负载估计误差及抗扰性能,支持参数可调,适用于电机负载观测与前馈控制算法研究。

在这里插入图片描述

附完整代码的下载链接

总体介绍

本程序基于永磁同步电机(Permanent Magnet Synchronous Motor, PMSM)数学模型,采用扩展卡尔曼滤波(Extended Kalman Filter, EKF)实现未知负载转矩观测,并结合磁场定向控制(FOC)设计负载转矩前馈补偿方法。通过模拟不同负载阶跃变化工况,对比开启和关闭前馈补偿时的转速响应、负载估计误差及抗扰性能,并输出相关曲线和评价指标。电机参数、控制器参数、负载变化及测量噪声等均可自行调整,便于开展电机负载观测、前馈补偿与抗扰控制仿真研究。

运行结果

前馈试验电流与转矩

在这里插入图片描述

负载估计误差

在这里插入图片描述

负载前馈速度补偿

在这里插入图片描述

负载观测与前馈电流

在这里插入图片描述

命令行输出

在这里插入图片描述

MATLAB源代码

部分代码如下:

% 负载观测与前馈补偿:独立MATLAB例程
% 2026-10-12/Ver1,作者:matlabfilter,V同号,可获取代码定制、讲解等
% 只使用基础MATLAB。参数为普通标量,信号为数值数组,不使用结构体。
% 点击运行即可;末尾含全部局部函数。Figure无水印,配套PNG由维护工具导出。
clear; clc; close all;
rng(0);

%% 共用教学参数与单位:不将本例解释为Word中15 kW电机的实机验证
Rs=0.45; Ld=3e-3; Lq=3.6e-3; psi_f=0.075;
pole_pairs=4; J=2e-3; B=5e-4;
Ts=1e-4; simulation_time=1.2;
dc_voltage=120; voltage_limit=dc_voltage/sqrt(3); current_limit=10;
Kp_speed=0.25; Ki_speed=4.0;
current_bandwidth=1200;
Kp_d=Ld*current_bandwidth; Kp_q=Lq*current_bandwidth;
Ki_d=Rs*current_bandwidth; Ki_q=Rs*current_bandwidth;
time=0:Ts:simulation_time; sample_count=numel(time);
Kt=1.5*pole_pairs*psi_f; Kr=1.5*pole_pairs*(Ld-Lq);
% 维护用汇总也是数值向量;各指标仍以独立、有意义的变量保留。
speed_rmse=NaN; angle_rmse_deg=NaN; load_rmse=NaN;
parameter_relative_rmse_pct=NaN; secondary_parameter_rmse_pct=NaN;
improvement_pct=NaN; current_rmse=NaN; peak_speed_error=NaN;
gap_speed_rmse=NaN; recovery_speed_rmse=NaN;
final_parameter=NaN; final_secondary_parameter=NaN;
disturbance_speed_peak=NaN; control_current_peak=NaN; takeover_speed_peak=NaN;
recovery_time=NaN; covariance_min=Inf; covariance_chol_failures=0;
jacobian_error=0; state_is_finite=1;

%% 同一负载事件、同一传感器噪声:分别关闭和开启前馈
speed_reference=80*ones(1,sample_count);
load_true=0.35*ones(1,sample_count);
load_true(time>=0.45)=0.90; load_true(time>=0.85)=0.45;
current_noise=0.04*randn(2,sample_count); encoder_noise=0.04*randn(1,sample_count);
state_history=zeros(4,sample_count,2); load_history=zeros(2,sample_count);
feedforward_history=zeros(2,sample_count); voltage_history=zeros(2,sample_count,2);
current_reference_history=zeros(2,sample_count);
observer_covariance=diag([0.08^2,0.25^2]);
A_load=[-B/J,-1/J;0,0]; F_load=eye(2)+Ts*A_load+Ts^2*A_load*A_load/2;
Q_load=diag([1e-4,4e-5]); R_speed=0.04^2; H_speed=[1,0];
jacobian_error=check_motor_jacobian(Rs,Ld,Lq,psi_f,pole_pairs,J,B,Ts,false);
% 负载模型的离散导数另作中心差分核对。
load_check=[90;0.45]; torque_check=0.7; numerical=zeros(2);
for column=1:2
    h=1e-5; offset=zeros(2,1); offset(column)=h;
    numerical(:,column)=(load_predict(load_check+offset,torque_check,Ts,J,B) ...
                       -load_predict(load_check-offset,torque_check,Ts,J,B))/(2*h);
end
jacobian_error=max(jacobian_error,norm(numerical-F_load,'fro')/norm(F_load,'fro'));
assert(jacobian_error<1e-6,'负载观测模型导数核对失败');
for run_index=1:2
    plant=[0;(0.35+B*80)/Kt;80;0.30];
    state_history(:,1,run_index)=plant; integrals=zeros(3,1);
    x_load=[80+encoder_noise(1);0.20]; P_load=observer_covariance;
    load_history(run_index,1)=x_load(2); feedforward_filtered=0;
    for k=2:sample_count
        % 编码器辅助本例;未知负载真值不传入控制器或负载观测器。
        measured_speed=plant(3)+encoder_noise(k-1);
        measured_dq=plant(1:2)+current_noise(:,k-1);
        c=cos(plant(4)); s=sin(plant(4)); measured_ab=[c,-s;s,c]*measured_dq;
        iq_feedforward=(0.35+B*80)/Kt;
        if run_index==2
            target=max(-2,min(2,(x_load(2)-0.35)/Kt));
            feedforward_filtered=feedforward_filtered+Ts/(0.008+Ts)*(target-feedforward_filtered);
            iq_feedforward=iq_feedforward+feedforward_filtered;
        end
        feedforward_history(run_index,k-1)=feedforward_filtered;
        [uab,integrals,current_reference_history(run_index,k-1)]=foc_controller( ...
            measured_ab,plant(4),measured_speed,speed_reference(k-1),integrals,Ts, ...
            Rs,Ld,Lq,psi_f,pole_pairs,voltage_limit,current_limit, ...
            Kp_speed,Ki_speed,Kp_d,Ki_d,Kp_q,Ki_q,iq_feedforward);
        voltage_history(:,k-1,run_index)=uab;
        measured_torque=Kt*measured_dq(2)+Kr*measured_dq(1)*measured_dq(2);
        xp_load=load_predict(x_load,measured_torque,Ts,J,B);
        Pp_load=F_load*P_load*F_load'+Q_load;
        plant=motor_truth_step(plant,uab,Ts,Rs,Ld,Lq,psi_f,pole_pairs,J,B,load_true(k-1));
        residual=plant(3)+encoder_noise(k)-H_speed*xp_load;
        S=H_speed*Pp_load*H_speed'+R_speed; K=Pp_load*H_speed'/S;
        x_load=xp_load+K*residual; IKH=eye(2)-K*H_speed;
        P_load=IKH*Pp_load*IKH'+K*R_speed*K'; P_load=(P_load+P_load')/2;
        [~,chol_flag]=chol(P_load);
        covariance_chol_failures=covariance_chol_failures+(chol_flag~=0);
        covariance_min=min(covariance_min,min(eig(P_load)));
        assert(chol_flag==0 && all(isfinite(x_load)),'负载观测数值异常');
        state_history(:,k,run_index)=plant;
        load_history(run_index,k)=x_load(2);
    end
end

完整代码:
https://download.youkuaiyun.com/download/callmeup/93685239

如需帮助,或有滤波相关的MATLAB代码定制需求,可从个人主页左侧联系我

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MATLAB卡尔曼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值