你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

分享一个做平衡车是学卡尔曼滤波的资料

[复制链接]
laotui 发布时间:2015-5-23 10:33
使用MPU6050卡尔曼滤波处理效果还好
6050.jpg

卡尔曼滤波算法C语言实现.pdf

下载

1.19 MB, 下载次数: 216

赞 收藏 1 评论10 发布时间:2015-5-23 10:33

举报

10个回答
真心英雄 回答时间:2015-5-23 13:28:28
谢谢了呃
爱的简单 回答时间:2015-5-23 16:37:35
真心英雄 发表于 2015-5-23 13:28
- B7 Z4 \& @2 N3 T, x; n9 M: `谢谢了呃

" X& a' @( Y. n, B" f4 C9 F+ o2 {' T新手,学习来了
lkl0305 回答时间:2015-5-23 16:59:27
多谢分享,学习学习
夏明smile 回答时间:2015-5-23 17:35:22
高大上的滤波,我也只能汗颜了
你好我好大家好! 回答时间:2015-5-24 00:22:07
谢谢分享
带你看世界 回答时间:2015-5-24 01:08:12
不错,不错
wwwhlw 回答时间:2015-5-24 11:11:57
多谢分享。。。
jj_feng 回答时间:2016-8-9 15:13:51
谢谢分享!
zhangxu56726 回答时间:2016-8-9 15:32:40
有实现代码吗?
孤独的文艺青年 回答时间:2016-8-9 18:35:18
我用printf("%0.2f    %0.2f    %0.2f\r\n",Angle,Angle_ax,Gyro_y);函数分别读取的加速度,角速度和倾角,我发现当我快速的改变板子的倾角的时候,比如快速变化10度,Angle(卡尔曼滤波后的倾角)瞬时变化非常快,可能会瞬间变化几十度然后回到正常角度,而当我缓慢变化10度的时候,Angle变化是正常线性变化到10度,在这两种变化中,Angle_ax(从MPU6050读取的值经过处理后的陀螺仪的Y轴数据)的变化一直都是线性正常的,并且Angle的值特别接近Angle_ax的值
$ Z& R; ]: N2 x9 z" }问题:1,我快速改变板子倾角时Angle的变化正常吗?7 s3 I3 n# f! b' T: }
      2,Angle正常变化的时候是应该与Angle_ax的值相近吗?7 e3 P/ Y: o4 n0 a6 B

$ d+ _# M2 H7 `' A  a% [8 E* j现在情况就是,就算我是在减小倾角,只要我快速地改变,它显示的倾角都会先增大再减小,而如果我慢速改变的话,倾角就会缓慢减小而不会出现中间的角度增大5 z4 C0 Y$ t. P: R6 @$ I" w: y
/ X0 d- c- q: B, \+ K
$ s8 K8 o3 n7 V. p$ |( {
*************读取数据********************4 D/ G+ {  n  ?: N8 J/ k1 y
//定义MPU6050内部地址
# A$ d5 v) z2 ?#define        SMPLRT_DIV                0x19        //陀螺仪采样率 典型值 0X07 125Hz* r# F& C6 [9 ~- C0 v
#define        CONFIG                          0x1A        //低通滤波频率 典型值 0x00
# j9 \8 {1 g! v$ I+ Z$ b' x  N9 \. D#define        GYRO_CONFIG                0x1B        //陀螺仪自检及测量范围                 典型值 0x18 不自检 2000deg/s$ c! |( s7 O5 D+ K! i+ |9 O6 n* R
#define        ACCEL_CONFIG        0x1C        //加速度计自检及测量范围及高通滤波频率 典型值 0x01 不自检 2G 5Hz
/ T8 M4 ?; b% Q( M0 Z9 a#define INT_PIN_CFG     0x37" Y3 g) ~* h9 ~
#define INT_ENABLE      0x38
, D0 B" X' p6 X3 U#define INT_STATUS      0x3A    //只读
9 r2 j+ {7 Q! u#define        ACCEL_XOUT_H        0x3B
1 t: O  [' t( d/ j% A6 Y* A#define        ACCEL_XOUT_L        0x3C% q6 O( w' ~3 I: T
#define        ACCEL_YOUT_H        0x3D# T/ ~" C# ?5 P+ c. C
#define        ACCEL_YOUT_L        0x3E' l/ R& e; V! W$ Z- h' r) ~
#define        ACCEL_ZOUT_H        0x3F( }3 ^% B- t5 c" c" ^# A( l
#define        ACCEL_ZOUT_L        0x40& M6 f# h7 ?" u1 ^' X
#define        TEMP_OUT_H                0x41
6 ?$ F; n1 D, r7 P) L+ V#define        TEMP_OUT_L                0x42/ J( a/ {8 l/ K
#define        GYRO_XOUT_H    0x43
7 n8 B* A0 i+ G! o1 C#define        GYRO_XOUT_L                0x44        ! E( R6 l$ X3 D4 D0 Q
#define        GYRO_YOUT_H        0x45
# m8 q9 D$ Z( N$ w7 q& i#define        GYRO_YOUT_L                0x46
# N' m! ?! I  W! q$ f# |+ J+ o#define        GYRO_ZOUT_H        0x47% Q1 q1 K. N" b/ I5 ~& q' R
#define        GYRO_ZOUT_L                0x48: T5 x0 F, B; t% b! z

/ U/ X5 D2 m- o4 b' c//读取寄存器原生数据  X/ i" V; t2 Z, y" @  e
           , D; B& S. x; W, @
        MPU6050_Raw_Data.Accel_X = (buf[0]<<8 | buf[1]);. H/ p! Z. f0 z1 c4 r
        MPU6050_Raw_Data.Accel_Y = (buf[2]<<8 | buf[3]);
! M+ ?/ Z7 C9 X; o        MPU6050_Raw_Data.Accel_Z = (buf[4]<<8 | buf[5]); $ s) ~6 e; h- }2 I- u) a3 \7 a
        MPU6050_Raw_Data.Temp =    (buf[6]<<8 | buf[7]);  ( z& g- ?- V! `3 {
        MPU6050_Raw_Data.Gyro_X = (buf[8]<<8 | buf[9]);
/ A7 W! n) }" u4 }: _0 g        MPU6050_Raw_Data.Gyro_Y = (buf[10]<<8 | buf[11]);
+ l) A' D2 S; |$ Y        MPU6050_Raw_Data.Gyro_Z = (buf[12]<<8 | buf[13]);% {. I  j! e( a3 ]2 V4 J  l
       + g' i/ o! U2 a) d* Q) y1 d$ }) R
       , B  r/ l4 T8 K, {* ^8 u# f% n
        //将原生数据转换为实际值,计算公式跟寄存器的配置有关% `5 G! G5 @; Q! b, C/ ^/ n
        MPU6050_Real_Data.Accel_X = -(float)(MPU6050_Raw_Data.Accel_X)/8192.0; 0 Q/ e9 ]8 P+ Z% t5 [
        MPU6050_Real_Data.Accel_Y = -(float)(MPU6050_Raw_Data.Accel_Y)/8192.0;
- i7 s" d: O2 A$ }7 X( O) x' V4 I/ F        MPU6050_Real_Data.Accel_Z = (float)(MPU6050_Raw_Data.Accel_Z)/8192.0; 7 [; R# X$ H+ z; ]! E9 ?
              MPU6050_Real_Data.Gyro_X=-(float)(MPU6050_Raw_Data.Gyro_X - gyroADC_X_offset)/65.5;   
* ~, z( ~" L/ E7 u* t7 k        MPU6050_Real_Data.Gyro_Y=-(float)(MPU6050_Raw_Data.Gyro_Y - gyroADC_Y_offset)/65.5;   
$ ?9 S" G( b, J        MPU6050_Real_Data.Gyro_Z=(float)(MPU6050_Raw_Data.Gyro_Z - gyroADC_Z_offset)/65.5;   
% r' x( [, v% g$ W( }% G1 }+ v    }
" k$ S9 w/ M; x6 L% |    * Z! z" Y' v4 N; d; U, C& U

' Y' x4 c2 w6 h" R$ L3 P0 m* o& ^3 j+ S. [
//******卡尔曼参数************, j# N( r7 e1 O4 y& `
               
2 S# `2 |4 }6 `# v9 R! [const float Q_angle=0.001;  
- B! q( @% Z  Dconst float Q_gyro=0.003;) g2 I. c; I6 `
const float R_angle=0.5;
, U+ q% u4 F- u) |: j3 Gconst float dt=0.01;                          //dt为kalman滤波器采样时间;2 v1 w  K7 j* ~/ w. r4 M
const char  C_0 = 1;  U) G# R& k3 T: b/ L; ]
float Q_bias, Angle_err;% f/ |1 l; ]1 w" F4 K, g" f. C
float PCt_0, PCt_1, E;
" A4 c/ [! S9 i/ f/ ~float K_0, K_1, t_0, t_1;: _$ P+ ?# M, f% Q, v; m
float Pdot[4] ={0,0,0,0};6 u/ R/ \& X: {
float PP[2][2] = { { 1, 0 },{ 0, 1 } };
/ c) U9 J" s. m: H% \" S3 }3 y, c, ^$ ]! D" v) P4 u) b4 O- `& V: B; v
/*****************卡尔曼滤波**************************************************/! G' T2 `* D' g* O( i4 N0 x
void Kalman_Filter(float Accel,float Gyro)               
4 \) h% A3 W% Y9 l* s: o3 }; j0 `{
2 g+ i( s2 a0 E4 _8 V        Angle+=(Gyro - Q_bias) * dt; //先验估计
( S( W6 O  {" v2 j, o* P/ a% P+ U: E        / x( x, \* ~  E! ~$ k3 K6 h
        Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分
7 D6 E4 l7 s& J; I, z+ I% n
9 @# J: g9 j) L* p- Q        Pdot[1]= -PP[1][1];  h; A9 B0 E1 W: D: {
        Pdot[2]= -PP[1][1];
3 J) D* ~, P! c: q        Pdot[3]=Q_gyro;
. j5 w' M/ N& f7 v       
' A8 T" G7 e, w        PP[0][0] += Pdot[0] * dt;   // Pk-先验估计误差协方差微分的积分$ d3 y) x" v2 `7 N1 E
        PP[0][1] += Pdot[1] * dt;   // =先验估计误差协方差0 ~, R4 }: N, o
        PP[1][0] += Pdot[2] * dt;
7 `9 B' [8 l) s5 y        PP[1][1] += Pdot[3] * dt;
* U0 e# \6 I: o2 ^               
+ K1 @6 S) A8 m        Angle_err = Accel - Angle;        //zk-先验估计
! P) X$ N- F! x6 x3 @. ~       
+ s1 @. y1 @8 s9 o( q        PCt_0 = C_0 * PP[0][0];
' Z3 f- R1 }# W9 H6 ^  R        PCt_1 = C_0 * PP[1][0];
8 ^+ Q5 V- u# I& O) w        - {8 @+ Q/ D* v  o! {3 u- a  O: N
        E = R_angle + C_0 * PCt_0;  D* Y  I4 A# j# B3 U
       
+ b- Y! n6 s5 Q        K_0 = PCt_0 / E;
2 X1 X9 h4 g6 Y        K_1 = PCt_1 / E;* S# H$ H7 m+ x7 v+ h  C8 X
       
% m5 _+ v1 z" B        t_0 = PCt_0;
6 J+ C3 E* U0 c# o, l        t_1 = C_0 * PP[0][1];
; s+ v3 a" x2 f3 t# S
$ M" ?" E/ f. w0 A) G  q        PP[0][0] -= K_0 * t_0;                 //后验估计误差协方差
! w! _0 y; w5 y5 d        PP[0][1] -= K_0 * t_1;
5 a3 Y( G6 }" _8 \( z" Y        PP[1][0] -= K_1 * t_0;8 d1 T& }/ i$ W3 {* Q9 f
        PP[1][1] -= K_1 * t_1;
/ X, E: C* X6 P               
4 n' K+ s0 T! e        Angle        += K_0 * Angle_err;         //后验估计4 }4 j+ Z; @' l: E8 V
        Q_bias        += K_1 * Angle_err;         //后验估计+ J# u: s" }5 G' L
        Gyro_y   = Gyro - Q_bias;         //输出值(后验估计)的微分=角速度
" x) d1 s. H+ [7 m. {6 r
( D+ t* l' v6 C}
. b; x- J7 s1 @4 I0 _% E. b& _# |3 _) [4 b2 a0 Q2 s
******************倾角计算*****************' m: `* X6 X' D
void Angle_Calculate(void)# b' @1 h" J2 P% e- x. I
{
7 d. s* L+ ^; N+ s0 f. w$ y. ^5 {9 f0 L
/****************************加速度****************************************/
3 `/ K; ~: T5 Z  h2 j' \       
1 \) X$ Q3 g' y: @, w        Accel_x  =  MPU6050_Real_Data.Accel_X;          //读取X轴加速度
7 R$ c; h6 U  ?        Angle_ax = Accel_x*1.2*180/3.14;     //弧度转换为度
. S0 r7 ^2 c$ r8 m7 N3 X# I* L* H) X6 r& ~
/****************************角速度****************************************/
. e( q, H$ u; g% U- n3 `8 W       
- L- o( ?5 u  E. v         Gyro_y = MPU6050_Real_Data.Gyro_Y;             , B- `( o) k: r3 T" O5 T# w  T
时间dt,所以此处不用积分9 O( Q7 X: p6 I/ Q
/***************************卡尔曼融合*************************************/4 K' G* Z  z2 W3 Y% Q
        Kalman_Filter(Angle_ax,Gyro_y);       //卡尔曼滤波计算倾角0 s, o& W- h1 m2 u3 U
       
1 S! ?2 |2 v# z0 V1 |* y5 z# s7 h% x3 s& z- u4 A
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版