132 lines
4.6 KiB
C
132 lines
4.6 KiB
C
|
//
|
|||
|
// 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];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|