// // Created by SJQ on 2024/1/13. // #include "observer.h" #include "bsp_dwt.h" #include "arm_math.h" static const float dt = 1e-3; static const float p_A[6][3] = { {-2089.29388440040,913.777119858069,161.725026756580}, {-48.4503739138708,21.1903377794882,3.75037618024515}, {349.621231737198,-308.272343710195,14.5058784104114}, {8.10765758344078,-7.14878382193259,1.73804857662225}, {-126.242793963670,111.312353023678,-5.23784728498450}, {-2.92754916727612,2.58131475207839,21.1973941504635} }; static const float p_B[6][3] = { {-5.36398695946053,59.5647709213161,-40.3119963098152}, {127.834870314177,-113.128844359679,30.8319480335393}, {-33.9678204232552,24.3044065007359,0.798747072246912}, {13.4736135478509,-6.23400169559697,-0.818937686872829}, {12.2652521237935,-8.77594351760660,1.29067140754752}, {-4.86511248363210,2.25100114119497,2.36237087051996}, }; float gEstimateKF_F[36] = {1, dt, 0, 0, 0,0, 0, 1, 0, 0, 0,0, 0, 0, 1, dt, 0,0, 0, 0, 0, 1, 0,0, 0, 0, 0, 0, 1,dt, 0, 0, 0, 0, 0,1}; // 状态转移矩阵其余项在滤波器更新时更新 float gEstimateKF_B[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 控制矩阵其余项在滤波器更新时更新 const float gEstimateKF_H[36] = {1, 0, 0, 0, 0,0, 0, 1, 0, 0, 0,0, 0, 0, 1, 0, 0,0, 0, 0, 0, 1, 0,0, 0, 0, 0, 0, 1,0, 0, 0, 0, 0, 0,1}; // 由于不需要异步量测自适应,这里直接设置矩阵H为常量 //后验估计协方差初始值 static float P[36] = {1, 0, 0, 0, 0,0, 0, 1, 0, 0, 0,0, 0, 0, 1, 0, 0,0, 0, 0, 0, 1, 0,0, 0, 0, 0, 0, 1,0, 0, 0, 0, 0, 0,1}; // R Q矩阵初始值(其实这里设置多少都无所谓) static float Q[36] = {1, 0, 0, 0, 0,0, 0, 1, 0, 0, 0,0, 0, 0, 1, 0, 0,0, 0, 0, 0, 1, 0,0, 0, 0, 0, 0, 1,0, 0, 0, 0, 0, 0,1}; static float R[36] = {1, 0, 0, 0, 0,0, 0, 1, 0, 0, 0,0, 0, 0, 1, 0, 0,0, 0, 0, 0, 1, 0,0, 0, 0, 0, 0, 1,0, 0, 0, 0, 0, 0,1}; void Observer_Init(BalanceObserver* observer) { KalmanFilter_t *kf = &observer->stateEstimateKF; Kalman_Filter_Init(kf,6,2,6); for (uint8_t i = 0; i < 36; i += 7) { // 初始化过程噪声与量测噪声 Q[i] = 1.0f;//process_noise; R[i] = 0.01f;//measure_noise; } //暂时只使用状态预测一个步骤 //kf->UseAutoAdjustment = 1; //kf->SkipEq2 = 1; kf->SkipEq3 = 1; kf->SkipEq4 = 1; kf->SkipEq5 = 1; memcpy(kf->F_data , gEstimateKF_F , sizeof(gEstimateKF_F)); memcpy(kf->B_data , gEstimateKF_B , sizeof(gEstimateKF_B)); memcpy(kf->H_data , gEstimateKF_H , sizeof(gEstimateKF_H)); memcpy(kf->Q_data , Q,sizeof(Q)); memcpy(kf->R_data , R,sizeof(R)); // set rest of memory to 0 DWT_GetDeltaT(&observer->DWT_CNT); } //由当前时刻的状态量预测dt时刻后的 void Observer_Estimate(BalanceObserver* observer,float* zk,float* uk,float L0) { float L2;//腿长的平方 arm_power_f32(&L0,1,&L2); KalmanFilter_t *kf = &observer->stateEstimateKF; float A[6],B[6]; for(int i = 0 ;i<6;i++) { A[i] = p_A[i][0] * L2 + p_A[i][1] * L0 + p_A[i][2]; B[i] = p_B[i][0] * L2 + p_B[i][1] * L0 + p_B[i][2]; } //F矩阵更新 kf->F_data[6] = A[0] * dt; kf->F_data[10] = A[1] * dt; kf->F_data[18] = A[2] * dt; kf->F_data[22] = A[3] * dt; kf->F_data[30] = A[4] * dt; kf->F_data[34] = A[5] * dt; //B矩阵更新 kf->B_data[2] = B[0]; kf->B_data[3] = B[1]; kf->B_data[6] = B[2]; kf->B_data[7] = B[3]; kf->B_data[10] = B[4]; kf->B_data[11] = B[5]; //测量值更新 // memcpy(kf->MeasuredVector,zk,6*4); // //测量值更新 // memcpy(kf->ControlVector,uk,2*4); for(uint8_t i = 0; i < 6; i++) kf->MeasuredVector[i] = zk[i]; for(uint8_t i = 0; i < 2; i++) kf->ControlVector[i] = uk[i]; Kalman_Filter_Update(kf); // 提取估计值 for (uint8_t i = 0; i < 2; i++) { observer->Estimate_X[i] = kf->FilteredValue[i]; } }