你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。关注该话题即可发布文章!
问题:1,我快速改变板子倾角时Angle的变化正常吗?
2,Angle正常变化的时候是应该与Angle_ax的值相近吗?. I: C7 v/ a% F# }1 S* u
! X; X) E j6 h1 V0 E5 ~
现在情况就是,就算我是在减小倾角,只要我快速地改变,它显示的倾角都会先增大再减小,而如果我慢速改变的话,倾角就会缓慢减小而不会出现中间的角度增大
& T- @! w( R0 }* N3 d4 f3 P
*************读取数据********************
//定义MPU6050内部地址
#define SMPLRT_DIV 0x19 //陀螺仪采样率 典型值 0X07 125Hz
#define CONFIG 0x1A //低通滤波频率 典型值 0x00
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围 典型值 0x18 不自检 2000deg/s
#define ACCEL_CONFIG 0x1C //加速度计自检及测量范围及高通滤波频率 典型值 0x01 不自检 2G 5Hz
#define INT_PIN_CFG 0x37% a, e4 G Q. }/ M. I
#define INT_ENABLE 0x38
#define INT_STATUS 0x3A //只读
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C+ |% N7 x: i0 u- p, G' B; {
#define ACCEL_YOUT_H 0x3D" O% K Q( Z+ w
#define ACCEL_YOUT_L 0x3E+ o5 X- V$ ~: G ]
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x427 H% z0 t) h% G/ W' b7 ?/ N
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46! p6 h3 x; a$ ^$ E! z7 [) l
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48) C! K+ h$ u O+ i
7 l ^; a p3 y& Q) I0 w
//读取寄存器原生数据
3 M9 E- o5 X9 {3 g# w. g( k
MPU6050_Raw_Data.Accel_X = (buf[0]<<8 | buf[1]);
MPU6050_Raw_Data.Accel_Y = (buf[2]<<8 | buf[3]);9 ~) H1 K8 d+ Y- j J; N: }
MPU6050_Raw_Data.Accel_Z = (buf[4]<<8 | buf[5]); & l& n/ }( B0 r! r6 @
MPU6050_Raw_Data.Temp = (buf[6]<<8 | buf[7]);
MPU6050_Raw_Data.Gyro_X = (buf[8]<<8 | buf[9]);
MPU6050_Raw_Data.Gyro_Y = (buf[10]<<8 | buf[11]);
MPU6050_Raw_Data.Gyro_Z = (buf[12]<<8 | buf[13]);% n A' t0 o1 }
) p* T4 x# D+ K
( w4 P" ~* Z S2 @, Y/ ?
//将原生数据转换为实际值,计算公式跟寄存器的配置有关
MPU6050_Real_Data.Accel_X = -(float)(MPU6050_Raw_Data.Accel_X)/8192.0; . K4 [. @- i/ Y" l% D7 U- `9 F
MPU6050_Real_Data.Accel_Y = -(float)(MPU6050_Raw_Data.Accel_Y)/8192.0; ( e( K. _) c( |: I
MPU6050_Real_Data.Accel_Z = (float)(MPU6050_Raw_Data.Accel_Z)/8192.0; ( \1 _) [7 J0 y& d. X8 L
MPU6050_Real_Data.Gyro_X=-(float)(MPU6050_Raw_Data.Gyro_X - gyroADC_X_offset)/65.5; # C1 a$ X: @( q5 ? v1 b+ z
MPU6050_Real_Data.Gyro_Y=-(float)(MPU6050_Raw_Data.Gyro_Y - gyroADC_Y_offset)/65.5;
MPU6050_Real_Data.Gyro_Z=(float)(MPU6050_Raw_Data.Gyro_Z - gyroADC_Z_offset)/65.5; 8 m" b/ K6 P7 y. ^5 v3 x
} % z/ D4 Y+ d/ O" E/ P2 n
//******卡尔曼参数************
const float Q_angle=0.001;
const float Q_gyro=0.003;
const float R_angle=0.5;
const float dt=0.01; //dt为kalman滤波器采样时间;5 I0 U" N; P2 b5 [9 Y' s8 f
const char C_0 = 1;
float Q_bias, Angle_err;; g; i& H+ t2 o+ ^, Y5 `
float PCt_0, PCt_1, E;5 X1 R+ E3 K1 k3 _7 `$ u% J1 A
float K_0, K_1, t_0, t_1;! _9 c, Q4 Z) L" J& T
float Pdot[4] ={0,0,0,0};, P/ Z0 Y, \& |/ B/ r9 j3 e% k
float PP[2][2] = { { 1, 0 },{ 0, 1 } };
! ]4 d' M! i/ M4 o
/*****************卡尔曼滤波**************************************************/' I) m8 u; }% W3 @) i% d6 |
void Kalman_Filter(float Accel,float Gyro) / i1 P3 A! t% i: F- O3 o
{
Angle+=(Gyro - Q_bias) * dt; //先验估计
Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分* o7 v: R$ V6 f1 [
Pdot[1]= -PP[1][1];
Pdot[2]= -PP[1][1];: L7 i) A. i/ t6 _' W, d* [5 M8 u
Pdot[3]=Q_gyro;& X4 ~. c" d+ l$ ^8 j" ?9 \0 O, _- R( O
PP[0][0] += Pdot[0] * dt; // Pk-先验估计误差协方差微分的积分
PP[0][1] += Pdot[1] * dt; // =先验估计误差协方差
PP[1][0] += Pdot[2] * dt;; Q" |: G1 S6 y+ J, E. U2 z( Q
PP[1][1] += Pdot[3] * dt;. C$ @3 I* L' ^" P! G9 R3 A* m* X
9 P! H5 Q6 C" H' q8 S
Angle_err = Accel - Angle; //zk-先验估计' l. x [; P1 m0 v" E. @7 X
PCt_0 = C_0 * PP[0][0];
PCt_1 = C_0 * PP[1][0];
E = R_angle + C_0 * PCt_0;1 l( }8 f9 h. u+ _9 x; K U! K
K_0 = PCt_0 / E;8 v7 j" U c- {/ o. } _" f
K_1 = PCt_1 / E;
* b/ V4 \. g7 ^' x/ R7 s; e8 }0 [
t_0 = PCt_0;* Y* N2 R( B9 w1 r: z) \: K! S0 T
t_1 = C_0 * PP[0][1];$ s0 v, ~0 ?4 c) @
* O* k5 F7 @9 E/ T! f T
PP[0][0] -= K_0 * t_0; //后验估计误差协方差9 f' V% G" i) c; ?1 H q( ]
PP[0][1] -= K_0 * t_1;
PP[1][0] -= K_1 * t_0;
PP[1][1] -= K_1 * t_1;
Angle += K_0 * Angle_err; //后验估计
Q_bias += K_1 * Angle_err; //后验估计7 ]2 `) e! ^4 u
Gyro_y = Gyro - Q_bias; //输出值(后验估计)的微分=角速度
0 i& ] W2 ^5 j: Z1 v
}
******************倾角计算*****************- n8 a7 R% B. }+ d9 [* s2 m
void Angle_Calculate(void)" C6 A$ n5 Q k
{
/****************************加速度****************************************/
# }! I+ u3 }. f0 T) E6 n
Accel_x = MPU6050_Real_Data.Accel_X; //读取X轴加速度
Angle_ax = Accel_x*1.2*180/3.14; //弧度转换为度
/****************************角速度****************************************/. X4 o7 |% n- P- g1 W: r
' W( E& }- w1 r6 [% m
Gyro_y = MPU6050_Real_Data.Gyro_Y; 5 n7 C$ w# {+ i4 B
时间dt,所以此处不用积分
/***************************卡尔曼融合*************************************/. ^2 h) i2 k, k4 ~
Kalman_Filter(Angle_ax,Gyro_y); //卡尔曼滤波计算倾角1 M( @8 s/ l4 @& s
" Z8 D9 X- x* w) o, s Y( s
楼主这么强,学习一下