ImageVerifierCode 换一换
格式:DOCX , 页数:14 ,大小:493.48KB ,
资源ID:26278842      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/26278842.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(MPU6050数据轻松分析.docx)为本站会员(b****9)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

MPU6050数据轻松分析.docx

1、MPU6050数据轻松分析MPU6050数据轻松分析MPU6050数据轻松分析这个文章是根据自己学习,查资料的汇总,同时把一些自己的心得加进去。如果有什么不对的,欢迎请大家指正、交流。邮箱:zhb_account最近看到加速度计和陀螺仪比较火,而且也有很多人都在研究。于是也在网上淘了一个mpu6050模块,想用来做自平衡小车。可是使用起来就发愁了。网上关于mpu6050的资料的确不少,但是大家都是互相抄袭,然后贴出一段程序,看完之后还是不知道所以然。经过翻阅各个方面的资料,以及自己的研究在处理mpu6050数据方面有一些心得,在这里和大家分享一下。在处理加速度计和陀螺仪用到的方法都是比较简单的

2、,这里的简单并不是不需要任何基础知识,只是这些基本知识都是最基本的,比如简单的三角函数,数学计算,物理知识,c语言以及基本的arduino知识(如果不会arduino会其它单片机也是一样的,本文实践是使用arduino),加速度在x,y,z轴的分量,然后利用各个方向的分量与重力加速度的比值来计算出小车大致的倾角。其实在自平衡小车上非静止的时候,加速度计测出的结果并不是非常精确。因为大家在高中物理的时候都学过,物体时刻都会受到地球的万有引力作用产生一个向下的重力加速度,而小车在动态时,受电机的作用肯定有一个前进或者后退方向的作用力,而加速度计测出的结果是,重力加速度与小车运动加速度合成得到一个总

3、的加速度在三个方向上的分量。不过我们暂时不考虑电机作用产生的运动加速度对测量结果的影响。因为我们要先把复杂的事情分解成一个个简单的事情来分析,这样才能看到成果,才会有信心继续。下边我们就开始分析从加速度得到角度的方法。如下图,把加速度计平放,分别画出xyz轴的方向。这三个轴就是我们后边分析所要用到的坐标系。把mpu6050安装在自平衡车上时也是这样的水平安装在小车底盘上的,假设两个车轮安装时车轴和y轴在一条直线上。那么小车摆动时,参考水平面就是桌面,并且车轴(y轴)与桌面始终是平行的,小车摆动和移动过程中y轴与桌面的夹角是不会发生变化的,一直是0度。发生变化的是x轴与桌面的夹角以及z轴与桌面的

4、夹角,而且桌面与x轴z轴夹角变化度数是一样的。所以我们只需要计算出x轴和z轴中任意一个轴的夹角就可以反映出小车的倾斜的情况了。为了方便分析,由于y轴与桌面夹角始终不变,我们从y轴的方向俯看下去,那么这个问题就会简化成只有x轴和z轴的二维关系。假设某一时刻小车上加速度计(mpu6050)处于如下状态,下图是我们看到简化后的模型。在这个图中,y轴已经简化和坐标系的原点o重合在了一起。我们来看看如何计算出小车的倾斜角,也就是与桌面的夹角a。上图g是重力加速度,gx、gz分别是g在x轴和z轴的分量。由于重力加速度是垂直于水平面的,得到:角a+角b=90度X轴与y轴是垂直关系,得到:角c+角b=90度于

5、是轻松的就可以得出:角a=角c根据力的分解,g、gx、gz三者构成一个长方形,根据平行四边形的原理可以得出:角c=角d所以计算出角度d就等效于计算出了x轴与桌面的夹角a。前边已经说过gx是g在x轴的分量,那么根据正弦定理就可以得出:Sind=gx/g得到这个公式可是还是得不到想要的角度,因为需要计算反正弦,而反正弦在单片机里不是很好计算。为了得到角度,于是又查了相关资料,原来在角度较小的情况下,角度的正弦与角度对应的弧度成线性关系。先看看下边的图:这个图x轴是角度,取值范围是090度,有三个函数曲线,分别是:Y=sinx 正弦曲线Y=x*3.14/180 弧度Y=0.92*x*3.14/180

6、 乘以一个0.92系数的弧度从图上可以看出,当角度范围是029度时:sinx=x*3.14/180对于自平衡车来说,小车的摆动范围在-2929度之内,如果超过这个范围,小车姿态也无法调整,所以对于自平衡小车sinx=x*3.14/180基本上是成立的。当然有时候也会担心-2929度的摇摆范围还是无法满足需求。那可以给上边的公式乘一个系数。得到如下公式:Sinx=k*x*3.14/180从上边的函数对比图可以看出,当系数取0.92时,角度范围可以扩大到-4545度。 经过这一系列的分析,终于得到角度换算方法: 由Sind=gx/gSind=k*d*3.14/180得到:gx/g=k*d*3.14

7、/180那么角度就可以通过如下公式计算出:d=180*gx/(k*g*3.14)而gx可以从加速度计里读出来,所以这下角度就可以轻松得到了。而之前也说过这个角度不是很精确,但是至少可以反映出角度变化的趋势。不过可以通过卡尔曼滤波等算法把加速度计读出的角度和陀螺仪读出的角度结合起来,使小车的角度更加准确。1、陀螺仪通过陀螺仪来测量角度就很简单了,因为陀螺仪读出的是角速度,大家都知道,角速度乘以时间,就是转过的角度。把每次计算出的角度做累加就会等到当前所在位置的角度。先看下图:假设最初陀螺仪是与桌面平行,单片机每tms读一次陀螺仪的角速度,当读了三次角速度以后 z轴转到上图的位置,则在这段时间中转

8、过的角度为x:角x=角1+角2+角3假设从陀螺仪读出的角速度为w,那总角度为:X=(w1*t1+w2*t2+w3*t3)/1000假设经过n次,那么总的角度如下:X=(w1*t1+w2*t2+w3*t3+wn*tn)/1000实际上这就是一个积分过程。其实这种计算出来的角度也存在一定的误差,而且总的角度是经过多次相加得到的,这样误差就会越积累越大,最终导致计算出的角度与实际角度相差很大。于是也可以使用卡尔曼滤波把加速度计读出的角度结合在一起,使计算出的角度更准确。2、mpu6050与arduino连接为了方便大家学习和复制,同时也应大家的要求,详细列出从哪里可以找到,对比了很多觉得这个是最划算

9、和实用的,供大家参考名称来源Mpu6050模块Arduino模块其它Mpu6050可以直接买现成的模块,模块使用i2c接口和arduino通信,连接方式如下:Mpu6050ArduinoVCCVCCGNDGNDSCLAD5SDAAD43、Arduino代码在开始之前先介绍一下用到的组件和算法。Mpu6050是通过i2c接口和arduino连接,所以需要i2c库,另外mpu6050也有现成的库。由于陀螺仪本身就有偏差,多次积累之后偏差会越来越大越来越不准确,所以需要用一些滤波算法来校正,这里用的是卡尔曼滤波算法。卡尔曼滤波在网上讲的很多,这里就不多说了。网上有一个测量温度的通俗版,另外维基百科里

10、的介绍比较简单。有兴趣的可以去研究一下。另外也可以用其它算法来滤波,这里也只是做演示所以不多介绍。/ Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation/ is used in I2Cdev.h#include Wire.h/ I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files/ for both classes must be in the include path of your pro

11、ject#include I2Cdev.h#include MPU6050.h/ class default I2C address is 0x68/ specific I2C addresses may be passed as a parameter here/ AD0 low = 0x68 (default for InvenSense evaluation board)/ AD0 high = 0x69MPU6050 accelgyro;int16_t ax, ay, az;int16_t gx, gy, gz;double total_angle=0;#define LED_PIN

12、13/* 把mpu6050放在水平桌面上,分别读取读取2000次,然后求平均值 */#define AX_ZERO (-1476) /* 加速度计的0偏修正值 */#define GX_ZERO (-30.5) /* 陀螺仪的0偏修正值 */void setup() / join I2C bus (I2Cdev library doesnt do this automatically) Wire.begin(); / initialize serial communication / (38400 chosen because it works as well at 8MHz as it do

13、es at 16MHz, but / its really up to you depending on your project) Serial.begin(38400); / initialize device Serial.println(Initializing I2C devices.); accelgyro.initialize(); / verify connection Serial.println(Testing device connections.); Serial.println(accelgyro.testConnection() ? MPU6050 connecti

14、on successful : MPU6050 connection failed);/* 通过卡尔曼滤波得到的最终角度 */float Angle=0.0; /*由角速度计算的倾斜角度 */float Angle_gy=0.0; float Q_angle=0.9; float Q_gyro=0.001;float R_angle=0.5;float dt=0.01; /* dt为kalman滤波器采样时间; */char C_0 = 1;float Q_bias, Angle_err;float PCt_0=0.0, PCt_1=0.0, E=0.0;float K_0=0.0, K_1=

15、0.0, t_0=0.0, t_1=0.0;float Pdot4 =0,0,0,0;float PP22 = 1, 0 , 0, 1 ;/* 卡尔曼滤波函数,具体实现可以参考网上资料,也可以使用其它滤波算法 */void Kalman_Filter(float Accel,float Gyro) Angle+=(Gyro - Q_bias) * dt; Pdot0=Q_angle - PP01 - PP10; Pdot1=- PP11; Pdot2=- PP11; Pdot3=Q_gyro; PP00 += Pdot0 * dt; PP01 += Pdot1 * dt; PP10 += Pd

16、ot2 * dt; PP11 += Pdot3 * dt; Angle_err = Accel - Angle; PCt_0 = C_0 * PP00; PCt_1 = C_0 * PP10; E = R_angle + C_0 * PCt_0; if(E!=0) K_0 = PCt_0 / E; K_1 = PCt_1 / E; t_0 = PCt_0; t_1 = C_0 * PP01; PP00 -= K_0 * t_0; PP01 -= K_0 * t_1; PP10 -= K_1 * t_0; PP11 -= K_1 * t_1; Angle += K_0 * Angle_err;

17、Q_bias += K_1 * Angle_err;void loop() / read raw accel/gyro measurements from device double ax_angle=0.0; double gx_angle=0.0; unsigned long time=0; unsigned long mictime=0; static unsigned long pretime=0; float gyro=0.0; if(pretime=0) pretime=millis(); return; mictime=millis(); accelgyro.getMotion6

18、(&ax, &ay, &az, &gx, &gy, &gz);/* 加速度量程范围设置2g 16384 LSB/g* 计算公式:* 前边已经推导过这里再列出来一次* x是小车倾斜的角度,y是加速度计读出的值* sinx = 0.92*3.14*x/180 = y/16384* x=180*y/(0.92*3.14*16384)=*/ ax -= AX_ZERO;ax_angle=ax/262; /* 陀螺仪量程范围设置250 131 LSB/s * 陀螺仪角度计算公式:* 小车倾斜角度是gx_angle,陀螺仪读数是y,时间是dt* gx_angle +=(y/(131*1000)*dt */

19、 gy -= GX_ZERO; time=mictime-pretime; gyro=gy/131.0; gx_angle=gyro*time;gx_angle=gx_angle/1000.0;total_angle-=gx_angle; dt=time/1000.0; Kalman_Filter(ax_angle,gyro); Serial.print(ax_angle); Serial.print(,); Serial.print(total_angle); Serial.print(,); Serial.println(Angle); pretime=mictime;Mpu6050取值范

20、围调整的方法,修改MPU6050库中的mpu6050.cpp,修改initialize函数中标成红色的行。void MPU6050:initialize() setClockSource(MPU6050_CLOCK_PLL_XGYRO); setFullScaleGyroRange(MPU6050_GYRO_FS_250); /* 陀螺仪取值范围 */ setFullScaleAccelRange(MPU6050_ACCEL_FS_2); /* 加速度计取值范围 */ setSleepEnabled(false); / thanks to Jack Elston for pointing this one out!下别贴出分析出的图供大家参考,图是使用SericalChart,通过收到的串口数据绘制的。红色的是陀螺仪读出的角度,绿色的是加速度计读出的角度。红色是陀螺仪读出的角度,绿色是加速度计读出的角度,黄色是卡尔曼滤波融合后的角度,由于参数调整的不是很好,可以看出黄色曲线有滞后的现象。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1