
原创代码,包运行成功。有中文注释
文章目录
程序简介
本程序基于MATLAB搭建永磁同步电机(Permanent Magnet Synchronous Motor,PMSM)电气仿真模型,采用无迹卡尔曼滤波(Unscented Kalman Filter,UKF),实现定子电阻参数的在线辨识,并通过更新电气模型中的电阻参数,分析参数辨识对电流预测精度的影响。
在永磁同步电机运行过程中,定子电阻可能受到绕组温度变化等因素影响而发生改变。如果电机模型始终采用固定的标称电阻,可能产生模型参数失配,影响电流预测与状态估计的准确性。
针对这一问题,程序将定子电阻作为增广状态引入UKF,利用电压、电流及已知转速信息进行参数递推估计,并通过标称模型与参数更新模型的对比,验证电阻辨识在改善电气模型预测精度方面的作用。
算法与仿真设置
程序采用三维增广状态模型,包含d轴电流、q轴电流和定子电阻参数。其中,电阻采用对数参数化形式进行估计,以保证恢复后的电阻值始终为正。
UKF通过Sigma点无迹变换完成非线性状态预测和电流量测更新,无需计算状态方程的雅可比矩阵。
程序主要包括以下环节:
- 定子电阻在线辨识: 利用已知机械转速、dq轴电压和带噪电流测量,递推估计定子电阻。
- 参数变化跟踪: 模拟电阻逐渐增大的工况,分析UKF对参数变化的估计能力。
- 电气模型更新: 将辨识得到的电阻参数用于后续电流预测,并与标称电阻模型进行对比。
- 数值稳定性检查: 检查无迹变换、协方差正定性以及辨识参数的有效性。
仿真总时长为1.2秒,采样周期为0.1 ms,电流测量噪声标准差为0.04 A。
定子电阻标称值为0.45 Ω,程序设置电阻在0.45秒附近开始逐渐增大,最终达到标称值的1.25倍,以模拟参数发生变化的情况。
结果分析
程序主要输出以下结果:
- 定子电阻辨识: 对比定子电阻真实值、UKF估计值及参数估计不确定度,分析电阻变化跟踪效果。
- 电阻相对误差: 展示辨识误差随时间的变化,并计算指定区间内的参数相对均方根误差(RMSE)。
- dq轴电流滤波: 对比真实电流、带噪测量电流及UKF滤波估计结果。
- 电压与转速变化: 展示电机运行过程中的dq轴电压及已知机械转速,为参数辨识结果提供工况参考。
- 模型预测对比: 在0.95秒时固定已辨识的电阻参数,使用相同初始测量和电压输入,分别计算标称电阻模型与更新电阻模型的电流预测结果。
- 性能评价: 对比两种模型的电流预测RMSE,并计算参数更新后的预测误差改善率,同时输出归一化新息平方(NIS)等评价指标。
程序特点与适用方向
本程序基于基础MATLAB函数实现,包含完整的PMSM电气模型、dq轴电流控制、UKF参数辨识、电阻参数更新、模型预测验证及结果可视化过程。
与传统EKF参数辨识方法不同,UKF利用Sigma点传播状态分布,无需对非线性状态方程进行显式线性化。程序还采用对数参数化处理,使估计电阻保持正值。
电机电阻、电感、永磁磁链、测量噪声、滤波协方差、采样时间及参数变化工况等均可自行调整。
本例适用于永磁同步电机定子电阻在线辨识、无迹卡尔曼滤波、模型参数失配分析及电气模型更新等方向的学习与仿真研究,也可以作为进一步研究电机在线参数补偿和多参数辨识算法的基础例程。
运行结果
dq电流滤波:

参数辨识结果:

新息与参数不确定度:

电压激励与编码器转速:

电阻更新模型验证:

命令行输出:

MATLAB源代码
部分代码:
matlab
% 电阻辨识与模型补偿:独立MATLAB例程
% 2026-10-19/Ver1,作者:matlabfilter,V同号,可获取代码定制、讲解等
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;
ut_error=0; state_is_finite=1;
%% 理想有编码器电气台架:机械转速已知,只研究电气参数
speed_known=90+12*sin(2*pi*2*time);
angle_known=cumtrapz(time,pole_pairs*speed_known);
id_reference=1.2*sin(2*pi*19*time)+0.7*sin(2*pi*43*time);
iq_reference=2.5+1.1*sin(2*pi*17*time)+0.7*sin(2*pi*31*time);
resistance_true=Rs*ones(1,sample_count);
flux_true=psi_f*ones(1,sample_count);
Ld_true=Ld*ones(1,sample_count); Lq_true=Lq*ones(1,sample_count);
resistance_true=Rs*(1+0.25*(1+tanh((time-0.45)/0.07))/2);
current_true=zeros(2,sample_count); current_true(:,1)=[0;2.5];
voltage_dq=zeros(2,sample_count); current_integrals=zeros(2,1);
for k=2:sample_count
[udq,current_integrals]=dq_current_controller(current_true(:,k-1), ...
[id_reference(k-1);iq_reference(k-1)],speed_known(k-1),current_integrals,Ts, ...
Rs,Ld,Lq,psi_f,pole_pairs,Kp_d,Ki_d,Kp_q,Ki_q,voltage_limit);
voltage_dq(:,k-1)=udq;
current_true(:,k)=electrical_truth_step(current_true(:,k-1),udq,speed_known(k-1), ...
Ts,resistance_true(k-1),Ld_true(k-1),Lq_true(k-1),flux_true(k-1),pole_pairs);
end
voltage_dq(:,end)=voltage_dq(:,end-1);
current_dq_meas=current_true+0.04*randn(2,sample_count);
%% 对数参数增广UKF:不输入待辨识参数真值
x=[current_dq_meas(:,1);log(0.75)]; P=diag([0.2^2,0.2^2,0.3^2]);
Q=diag([2e-6,2e-6,2e-7]); R=0.04^2*eye(2); H=[eye(2),zeros(2,1)];
state_est=zeros(3,sample_count); state_est(:,1)=x;
innovation=nan(2,sample_count); nis_values=nan(1,sample_count);
parameter_sigma=zeros(1,sample_count);
Ld_known=Ld; Lq_known=Lq;
parameter_nominal=Rs; resistance_est=zeros(1,sample_count); resistance_est(1)=Rs*exp(x(3));
validation_start=find(time>=0.95,1);
ut_error=check_sigma_transform_ukf();
for k=2:sample_count
if k==validation_start
frozen_resistance=resistance_est(k-1);
Q(3,3)=0; P(3,1:2)=0; P(1:2,3)=0;
end
[xp,Pp]=electrical_predict_ukf(x,P,Q,voltage_dq(:,k-1),speed_known(k-1),Ts, ...
Rs,Ld_known,Lq_known,psi_f,pole_pairs);
[predicted,Czz,Pxz]=linear_moments_ukf(xp,Pp,H);
residual=current_dq_meas(:,k)-predicted;
S=Czz+R; K=Pxz/S;
if k>=validation_start, K(3,:)=0; end
x=xp+K*residual;
P=Pp-K*Pxz'-Pxz*K'+K*S*K'; P=(P+P')/2;
state_est(:,k)=x; innovation(:,k)=residual; nis_values(k)=residual'*(S\residual);
parameter_value=parameter_nominal*exp(x(3));
parameter_sigma(k)=parameter_value*sqrt(P(3,3));
resistance_est(k)=parameter_value;
[~,chol_flag]=chol(P); covariance_chol_failures=covariance_chol_failures+(chol_flag~=0);
covariance_min=min(covariance_min,min(eig(P)));
assert(chol_flag==0 && all(isfinite(x)) && parameter_value>0,'参数或协方差异常');
end
current_est=state_est(1:2,:);
current_error=current_est-current_true;
current_rmse=sqrt(mean(current_error(:,time>=0.24).^2,'all'));
control_current_peak=max(abs(current_true),[],'all');
evaluation=time>=0.75 & time<0.95;
parameter_relative_rmse_pct=100*sqrt(mean(((resistance_est(evaluation)-resistance_true(evaluation))./resistance_true(evaluation)).^2));
final_parameter=resistance_est(end);
% 验证段不再更新电阻;两种开环模型由同一带噪测量初始化,使用同一实际电压。
validation_nominal=nan(2,sample_count); validation_updated=nan(2,sample_count);
validation_nominal(:,validation_start)=current_dq_meas(:,validation_start);
validation_updated(:,validation_start)=current_dq_meas(:,validation_start);
for k=validation_start+1:sample_count
validation_nominal(:,k)=electrical_truth_step(validation_nominal(:,k-1),voltage_dq(:,k-1), ...
speed_known(k-1),Ts,Rs,Ld,Lq,psi_f,pole_pairs);
validation_updated(:,k)=electrical_truth_step(validation_updated(:,k-1),voltage_dq(:,k-1), ...
speed_known(k-1),Ts,frozen_resistance,Ld,Lq,psi_f,pole_pairs);
end
validation_region=time>=1.00;
nominal_model_rmse=sqrt(mean((validation_nominal(:,validation_region)-current_true(:,validation_region)).^2,'all'));
updated_model_rmse=sqrt(mean((validation_updated(:,validation_region)-current_true(:,validation_region)).^2,'all'));
improvement_pct=100*(nominal_model_rmse-updated_model_rmse)/max(nominal_model_rmse,eps);
完整代码:
https://download.csdn.net/download/callmeup/93721675
如需帮助,或有滤波相关的MATLAB代码定制需求,可从个人主页左侧联系我