// 协方差矩阵 Pfloat P[4][4] = { {10,0,0,0}, {0,10,0,0}, {0,0,100,0}, {0,0,0,100}};// 过程噪声 Qfloat Q[4][4] = { {0.1f,0,0,0}, {0,0.1f,0,0}, {0,0,10.0f,0}, {0,0,0,0.5f}};// 观测噪声 R(电流采样噪声)float R[2][2] = { {0.5f,0}, {0,0.5f}};// 单位矩阵float I[4][4] = { {1,0,0,0}, {0,1,0,0}, {0,0,1,0}, {0,0,0,1}};//========================= 矩阵工具函数(简化版) =========================//void Matrix_Mul4x4(float A[4][4], float B[4][4], float out[4][4]);void Matrix_Mul4x4T(float A[4][4], float B[4][4], float out[4][4]); // A*B^Tvoid Matrix_Add4x4(float A[4][4], float B[4][4], float out[4][4]);float Matrix_Det2x2(float m[2][2]);void Matrix_Inv2x2(float m[2][2], float out[2][2]);//========================= EKF 主函数(5大步骤完整实现) =========================//// 输入:uα, uβ 电机电压// 输入:iα_sam, iβ_sam 电流采样void EKF_Step(float uα, float uβ, float iα_sam, float iβ_sam){ // 保存上一时刻状态 float iα_prev = x[0]; float iβ_prev = x[1]; float ωe_prev = x[2]; float θe_prev = x[3]; //===================================================================== // 【第一步:状态预测(先验估计)】 // 公式:x_pred = f(x_prev, u) // 完全使用电机 αβ 方程计算 //===================================================================== float x_pred[4]; x_pred[0] = iα_prev + Ts*(-Rs/Ls*iα_prev + ωe_prev*PSIf/Ls*sinf(θe_prev) + uα/Ls); x_pred[1] = iβ_prev + Ts*(-Rs/Ls*iβ_prev - ωe_prev*PSIf/Ls*cosf(θe_prev) + uβ/Ls); x_pred[2] = ωe_prev; // 短时间转速不变 x_pred[3] = θe_prev + Ts*ωe_prev; // 角度 = 角度 + 转速*时间 // 角度限幅 -π ~ π if(x_pred[3] > M_PI) x_pred[3] -= 2*M_PI; if(x_pred[3] < -M_PI) x_pred[3] += 2*M_PI; //===================================================================== // 【第二步:计算雅可比矩阵 F】 // 作用:非线性模型线性化,描述状态间误差耦合 //===================================================================== float F[4][4] = {0}; float F11 = 1 - Rs*Ts/Ls; float F13 = PSIf*Ts/Ls*sinf(θe_prev); float F14 = PSIf*Ts/Ls*ωe_prev*cosf(θe_prev); float F22 = 1 - Rs*Ts/Ls; float F23 = -PSIf*Ts/Ls*cosf(θe_prev); float F24 = PSIf*Ts/Ls*ωe_prev*sinf(θe_prev); F[0][0] = F11; F[0][1] = 0; F[0][2] = F13; F[0][3] = F14; F[1][0] = 0; F[1][1] = F22; F[1][2] = F23; F[1][3] = F24; F[2][0] = 0; F[2][1] = 0; F[2][2] = 1; F[2][3] = 0; F[3][0] = 0; F[3][1] = 0; F[3][2] = Ts; F[3][3] = 1; //===================================================================== // 【第三步:协方差预测】 // 公式:P_pred = F*P*F.T + Q // 作用:把上一轮误差按电机模型传播放大 //===================================================================== float P_temp1[4][4], P_temp2[4][4], P_pred[4][4]; Matrix_Mul4x4(F, P, P_temp1); // F * P Matrix_Mul4x4T(P_temp1, F, P_temp2); // F*P * F^T Matrix_Add4x4(P_temp2, Q, P_pred); // + Q //===================================================================== // 【第四步:计算卡尔曼增益 K】 // 公式:K = P_pred*H.T / (H*P_pred*H.T + R) // 作用:自动决定信任模型还是信任传感器 // H = [[1,0,0,0],[0,1,0,0]] //===================================================================== float S[2][2], S_inv[2][2]; S[0][0] = P_pred[0][0] + R[0][0]; S[0][1] = P_pred[0][1] + R[0][1]; S[1][0] = P_pred[1][0] + R[1][0]; S[1][1] = P_pred[1][1] + R[1][1]; Matrix_Inv2x2(S, S_inv); // 求逆 // K = P_pred * H.T * S_inv float K[4][2]; K[0][0] = P_pred[0][0] * S_inv[0][0] + P_pred[0][1] * S_inv[1][0]; K[0][1] = P_pred[0][0] * S_inv[0][1] + P_pred[0][1] * S_inv[1][1]; K[1][0] = P_pred[1][0] * S_inv[0][0] + P_pred[1][1] * S_inv[1][0]; K[1][1] = P_pred[1][0] * S_inv[0][1] + P_pred[1][1] * S_inv[1][1]; K[2][0] = P_pred[2][0] * S_inv[0][0] + P_pred[2][1] * S_inv[1][0]; K[2][1] = P_pred[2][0] * S_inv[0][1] + P_pred[2][1] * S_inv[1][1]; K[3][0] = P_pred[3][0] * S_inv[0][0] + P_pred[3][1] * S_inv[1][0]; K[3][1] = P_pred[3][0] * S_inv[0][1] + P_pred[3][1] * S_inv[1][1]; //===================================================================== // 【第五步:状态更新】 // 公式:x_new = x_pred + K*(z - H*x_pred) // 作用:用电流误差修正 iα、iβ、ωe、θe //===================================================================== float res[2]; res[0] = iα_sam - x_pred[0]; // iα 残差 res[1] = iβ_sam - x_pred[1]; // iβ 残差 x[0] = x_pred[0] + K[0][0]*res[0] + K[0][1]*res[1]; x[1] = x_pred[1] + K[1][0]*res[0] + K[1][1]*res[1]; x[2] = x_pred[2] + K[2][0]*res[0] + K[2][1]*res[1]; // 修正转速 x[3] = x_pred[3] + K[3][0]*res[0] + K[3][1]*res[1]; // 修正角度 // 角度限幅 if(x[3] > M_PI) x[3] -= 2*M_PI; if(x[3] < -M_PI) x[3] += 2*M_PI; //===================================================================== // 【第六步:协方差更新】 // 公式:P_new = (I - K*H)*P_pred // 作用:压缩误差,给下一轮使用 //===================================================================== float KH[4][4] = {0}; KH[0][0] = K[0][0]; KH[0][1] = K[0][1]; KH[1][0] = K[1][0]; KH[1][1] = K[1][1]; KH[2][0] = K[2][0]; KH[2][1] = K[2][1]; KH[3][0] = K[3][0]; KH[3][1] = K[3][1]; // I - K*H float I_KH[4][4]; for(int i=0; i<4; i++) for(int j=0; j<4; j++) I_KH[i][j] = I[i][j] - KH[i][j]; // P = (I-KH)*P_pred Matrix_Mul4x4(I_KH, P_pred, P);}