wheel_legged/application/balance/observer.c

132 lines
4.6 KiB
C
Raw Normal View History

//
// Created by SJQ on 2024/1/13.
//
#include "observer.h"
#include "bsp_dwt.h"
#include "arm_math.h"
2024-02-28 17:33:48 +08:00
static const float dt = 1e-3;
2024-03-17 17:51:24 +08:00
static const float p_A[6][3] = {
2024-03-17 17:51:24 +08:00
{-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] = {
2024-03-17 17:51:24 +08:00
{-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为常量
2024-03-17 17:51:24 +08:00
//后验估计协方差初始值
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);
2024-03-17 17:51:24 +08:00
for (uint8_t i = 0; i < 36; i += 7)
{
// 初始化过程噪声与量测噪声
Q[i] = 1.0f;//process_noise;
R[i] = 0.01f;//measure_noise;
}
//暂时只使用状态预测一个步骤
2024-03-17 17:51:24 +08:00
//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));
2024-03-17 17:51:24 +08:00
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];
//测量值更新
2024-03-17 17:51:24 +08:00
// 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);
2024-03-17 17:51:24 +08:00
// 提取估计值
for (uint8_t i = 0; i < 2; i++)
{
observer->Estimate_X[i] = kf->FilteredValue[i];
}
}