扩展卡尔曼滤波(ekf)辩识永磁同步电机电机转动惯量,s函数编写,附参考资料

玩过电机控制的都知道,转动惯量辨识是个头疼的活儿。传统方法要么需要离线测试,要么抗干扰能力差。今天咱们搞点有意思的——用扩展卡尔曼滤波(EKF)在线辨识永磁同步电机的转动惯量,直接在Simulink里撸S函数实现。

先看核心状态方程。假设系统状态向量是[转速ω; 转动惯量J],非线性模型长这样:

function [dx,y] = PMSM_EKF_States(x, u)
    % 状态方程
    omega = x(1);
    J = x(2);
    Te = u(1);
    Tl = u(2);  % 负载转矩
    
    domega = (Te - Tl - B*omega) / J;
    dJ = 0;  % 惯量视为缓变量
    
    dx = [domega; dJ];
    y = omega;
end

注意这里把转动惯量J当作状态量来处理,而不是固定参数。B是已知的摩擦系数,Te是电磁转矩,Tl作为已知干扰输入。

重点来了,雅可比矩阵的计算直接决定了EKF的收敛性。咱们用符号计算求导省事:

syms omega_J J_sym Te_sym Tl_sym B_sym
f = [(Te_sym - Tl_sym - B_sym*omega_J)/J_sym; 0];
F = jacobian(f, [omega_J, J_sym]);
H = jacobian(omega_J, [omega_J, J_sym]);

% 生成代码直接粘贴进S函数
matlabFunction(F,'File','EKF_JacobianF');
matlabFunction(H,'File','EKF_JacobianH');

这样生成的雅可比矩阵避免了手推公式出错,特别是当模型复杂时优势明显。

S函数的关键在于处理离散化。看这段核心迭代:

function sys=mdlUpdate(t,x,u)
    % 获取当前状态
    omega = x(1);
    J = x(2);
    
    % 状态预测
    [dx,~] = PMSM_EKF_States(x, u(1:2));
    x_pred = x + dx*T_sample;
    
    % 协方差预测
    F = EKF_JacobianF(omega,J,u(1),u(2),B);
    P_pred = F*P_prev*F' + Q;
    
    % 卡尔曼增益
    H = EKF_JacobianH();
    K = P_pred*H'/(H*P_pred*H' + R);
    
    % 状态修正
    z = u(3);  % 实际转速测量值
    x_new = x_pred + K*(z - H*x_pred);
    
    % 协方差更新
    P_new = (eye(2) - K*H)*P_pred;
    
    sys = [x_new; P_new(:)];
end

这里有个坑:Q和R矩阵的选取需要反复调试。建议初始值取Q=diag([1e-4,1e-6]), R=0.01,然后根据实际响应调整。Q(2,2)过大会导致J估计值抖动,过小则收敛慢。

实测时发现个有趣现象:突加负载时J的估计值会有个跳变,之后快速收敛。这说明动态过程中的激励信号对参数辨识至关重要。建议在调试时主动注入转矩脉动,能显著提高辨识精度。

最后推荐三本参考书:

1.《非线性系统》H.K. Khalil(理论推导)

2.《电机控制仿真实践》薛定宇(Matlab实战)

3.《卡尔曼滤波与组合导航》秦永元(参数整定技巧)

搞完这些,电机参数辨识终于不用停机测试了。实测某750W永磁电机,转动惯量估计误差稳定在±3%以内,满足多数工业场景需求。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐