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

【MCU实战经验】+基于stm32两轮平衡车制作  

[复制链接]
思考的大兵 发布时间:2014-4-12 20:54
阅读主题, 点击返回1楼
赞 3 收藏 24 评论180 发布时间:2014-4-12 20:54
180个回答
hxl520521 回答时间:2016-8-6 05:52:43
一下载谢谢了
hxl520521 回答时间:2016-8-6 05:54:15
以下载谢谢了
hxl520521 回答时间:2016-8-7 08:28:48
好厉害,有图纸吗
jj_feng 回答时间:2016-8-9 15:16:58
厉害,谢谢分享
孤独的文艺青年 回答时间:2016-8-9 18:34:51
我用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的值/ \2 k, L5 ]( E0 G! |
问题:1,我快速改变板子倾角时Angle的变化正常吗?
1 n' ^- L& j* E2 q      2,Angle正常变化的时候是应该与Angle_ax的值相近吗?. I: C7 v/ a% F# }1 S* u
! X; X) E  j6 h1 V0 E5 ~
现在情况就是,就算我是在减小倾角,只要我快速地改变,它显示的倾角都会先增大再减小,而如果我慢速改变的话,倾角就会缓慢减小而不会出现中间的角度增大
( ~2 l  n2 U' {3 g) _
: `+ E4 Q- U# J0 A& T- @! w( R0 }* N3 d4 f3 P
*************读取数据********************
8 ?+ q; _5 a  G//定义MPU6050内部地址
& v$ _: V0 l: l2 [/ r0 h6 n#define        SMPLRT_DIV                0x19        //陀螺仪采样率 典型值 0X07 125Hz
1 k( `- Z, L! a" ^$ U+ }5 G& u#define        CONFIG                          0x1A        //低通滤波频率 典型值 0x00
- Z+ I! Y1 t6 ?+ J5 j#define        GYRO_CONFIG                0x1B        //陀螺仪自检及测量范围                 典型值 0x18 不自检 2000deg/s
7 V& y/ z* p" c2 r#define        ACCEL_CONFIG        0x1C        //加速度计自检及测量范围及高通滤波频率 典型值 0x01 不自检 2G 5Hz
* s; b6 j# A, I' W; m0 n#define INT_PIN_CFG     0x37% a, e4 G  Q. }/ M. I
#define INT_ENABLE      0x38
% l) J" `1 d0 U6 l! m. M5 c#define INT_STATUS      0x3A    //只读
: ]! M( e) [- Q6 w, _" J#define        ACCEL_XOUT_H        0x3B
- ~/ {" p' a- \  S#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
0 F( B5 Y9 f! I5 q#define        ACCEL_ZOUT_L        0x40
0 o: Q4 `& m, e#define        TEMP_OUT_H                0x41
7 P# h- |: ?/ I0 ?; Q) I#define        TEMP_OUT_L                0x427 H% z0 t) h% G/ W' b7 ?/ N
#define        GYRO_XOUT_H    0x43
+ w4 ]! Q. Q+ S. F( a#define        GYRO_XOUT_L                0x44       
% U8 p/ c7 W" [) l# u4 G#define        GYRO_YOUT_H        0x45
6 T5 A7 A  _% G, p' ?2 m% X#define        GYRO_YOUT_L                0x46! p6 h3 x; a$ ^$ E! z7 [) l
#define        GYRO_ZOUT_H        0x47
* g" j) X& x" f: }) n& ^* U#define        GYRO_ZOUT_L                0x48) C! K+ h$ u  O+ i
7 l  ^; a  p3 y& Q) I0 w
//读取寄存器原生数据
2 v  ~, G4 B( v& i6 A           3 M9 E- o5 X9 {3 g# w. g( k
        MPU6050_Raw_Data.Accel_X = (buf[0]<<8 | buf[1]);
7 ~' K0 E( B4 {4 C4 [        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]);  
& v  o- h, M6 n: s/ Q/ q        MPU6050_Raw_Data.Gyro_X = (buf[8]<<8 | buf[9]);
5 S; e8 V' u' b. K, ^& [5 n        MPU6050_Raw_Data.Gyro_Y = (buf[10]<<8 | buf[11]);
; }' l) {3 u2 V8 V( i% i/ }& B* ?        MPU6050_Raw_Data.Gyro_Z = (buf[12]<<8 | buf[13]);% n  A' t0 o1 }
       ) p* T4 x# D+ K
       ( w4 P" ~* Z  S2 @, Y/ ?
        //将原生数据转换为实际值,计算公式跟寄存器的配置有关
: Q! w9 S( v" v% I! E! k! _: Y* K        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;   
5 H" x) |/ u3 u$ M        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
   
+ C; ]0 S! z. M) f; K
" Y% X/ I. i. d. m, M* i8 p
, H7 i: {9 n% P7 R) S//******卡尔曼参数************
( ^6 Y! i0 |& a5 J               
" J0 U% i8 n. z; E! xconst float Q_angle=0.001;  
& F  Q( H0 v; d; r7 qconst float Q_gyro=0.003;
5 b( ?& P8 ?4 {9 Wconst float R_angle=0.5;
0 Z4 M, ?- @! T( h. Oconst float dt=0.01;                          //dt为kalman滤波器采样时间;5 I0 U" N; P2 b5 [9 Y' s8 f
const char  C_0 = 1;
7 ^: N1 b8 q0 v9 J! ffloat 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 } };
& X( b0 D7 t1 H2 `+ v! ]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
{
' n9 l; @; z2 ^/ `. {        Angle+=(Gyro - Q_bias) * dt; //先验估计
1 H- T, p: L) U       
; _; l1 Z  H' T- l( o        Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分* o7 v: R$ V6 f1 [

0 U0 P! p6 y' l6 b( g        Pdot[1]= -PP[1][1];
1 Q/ A1 V8 R- N3 f' |        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
       
3 d8 j  u8 \3 u2 W# F        PP[0][0] += Pdot[0] * dt;   // Pk-先验估计误差协方差微分的积分
. O* L5 E9 Z3 A7 m- U        PP[0][1] += Pdot[1] * dt;   // =先验估计误差协方差
7 O; l6 Z8 ~6 q, ]- j6 f  q2 x! J        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
       
3 C. F  C- y1 I  t2 f1 _5 i" g        PCt_0 = C_0 * PP[0][0];
4 A& x. L) P; s  l9 T# ~        PCt_1 = C_0 * PP[1][0];
& U! K  ]. C3 e( R) V       
9 D# i& g4 n/ U9 m9 E3 Y* Q* p        E = R_angle + C_0 * PCt_0;1 l( }8 f9 h. u+ _9 x; K  U! K
       
, X' F% D" D; f  j        K_0 = PCt_0 / E;8 v7 j" U  c- {/ o. }  _" f
        K_1 = PCt_1 / E;
9 z" n$ k% @0 a0 T        * 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;
/ N8 c1 D; q, d7 r- w4 r3 s4 _        PP[1][0] -= K_1 * t_0;
0 X. n0 o- F$ I5 p6 v% W        PP[1][1] -= K_1 * t_1;
; q( U7 m! d/ A" E               
, Q! ~) s& N1 @: G- R- k% a        Angle        += K_0 * Angle_err;         //后验估计
* @# g4 L9 K( h" c9 x7 ~9 e        Q_bias        += K_1 * Angle_err;         //后验估计7 ]2 `) e! ^4 u
        Gyro_y   = Gyro - Q_bias;         //输出值(后验估计)的微分=角速度
, |% i$ ]' n6 G  X8 Y6 D0 i& ]  W2 ^5 j: Z1 v
}
# O" e0 q/ M! f7 `6 C- v" H
2 D! l6 G8 M* e1 W7 w8 L5 L5 C******************倾角计算*****************- n8 a7 R% B. }+ d9 [* s2 m
void Angle_Calculate(void)" C6 A$ n5 Q  k
{
. M- K. ^3 n4 O
  L$ }) C' S% H% X/ ]/****************************加速度****************************************/
9 ]  L' D" ?$ v0 Y        # }! I+ u3 }. f0 T) E6 n
        Accel_x  =  MPU6050_Real_Data.Accel_X;          //读取X轴加速度
% x% h1 O$ m5 k6 I3 Z        Angle_ax = Accel_x*1.2*180/3.14;     //弧度转换为度
/ B2 T: o; Y' h" Z; d
. F- K& a, n7 b5 X8 z. y+ [, [/****************************角速度****************************************/. 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,所以此处不用积分
' X8 Q0 g% R0 t) K/***************************卡尔曼融合*************************************/. ^2 h) i2 k, k4 ~
        Kalman_Filter(Angle_ax,Gyro_y);       //卡尔曼滤波计算倾角1 M( @8 s/ l4 @& s
       
' j, A* }2 M2 k2 ]" Z8 D9 X- x* w) o, s  Y( s
jj_feng 回答时间:2016-8-10 14:14:07
谢谢分享
$ d; q$ a( l: l$ j
大哥的诱惑 回答时间:2016-8-10 14:43:19
谢谢您的分享,不错的帖子哦!
nashchen17 回答时间:2016-8-11 12:58:14
太感謝了,好一篇分享文章
zbmxu 回答时间:2016-8-11 16:11:33
滤波学习下,谢谢
kernel_sa 回答时间:2016-9-20 01:03:14
3 y2 m2 Z: q2 D* f1 B# Y: G, {
楼主这么强,学习一下
airuoshahen 回答时间:2016-10-28 11:48:26
好佩服楼主,厉害了我的哥!
悬崖上的废墟 回答时间:2016-11-20 11:45:58
谢谢楼主分享
andypanfan 回答时间:2016-12-9 08:53:35
正需要呢,顶一个!!!
5265325 回答时间:2016-12-9 10:49:51
maiunjour 回答时间:2016-12-9 17:12:03
特来学习~!

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版