本帖最后由 cyq456 于 2013-8-24 21:02 编辑
看了这贴http://www.geek-workshop.com/thread-1695-1-1.html都有几天了,有所领悟,所以根据http://starlino.com/imu_kalman_arduino.html这贴写了一个mpu6050可以用的程序。
————————————————分割线—————————————————————————————————
其中RwEst[0] 为处理后x轴的加速度, RwEst[1] 为处理后y轴的加速度 , RwEst[z] 为处理后z轴的加速度。
处理后的加速度可以直接用于求角度。
想求角度可以参考这贴http://www.geek-workshop.com/for ... 328&page=1#pid27876[/url]
代码:
- #include "Wire.h"
- #include "I2Cdev.h"
- #include "MPU6050.h"
- MPU6050 accelgyro;
- #define PI 3.14159265358979f
- #define INPUT_COUNT 5
- #define Gz_offset 0.30
- #define Gy_offset 1.09
- #define Gx_offset -1.94
- int16_t ax, ay, az;
- int16_t gx, gy, gz;
- int an[INPUT_COUNT];
- char firstSample;
- float wGyro;
- float RwEst[3];
- unsigned long lastMicros;
- unsigned long interval;
- float RwAcc[3];
- float RwGyro[3];
- float Awz[2];
- bool blinkState = false;
- void setup()
- {
- Serial.begin(38400);
- Wire.begin();
- accelgyro.initialize();
- wGyro=10;
- firstSample=1;
- }
- void loop()
- {
- getEstimatedInclination();
- Serial.print(interval);
- Serial.print(",");
- Serial.print(RwAcc[0]); //Inclination X axis (as measured by accelerometer)
- Serial.print(",");
- Serial.print(RwEst[0]); //Inclination X axis (estimated / filtered)
- Serial.print(",");
- Serial.print(RwAcc[1]); //Inclination Y axis (as measured by accelerometer)
- Serial.print(",");
- Serial.print(RwEst[1]); //Inclination Y axis (estimated / filtered)
- Serial.print(",");
- Serial.print(RwAcc[2]); //Inclination Z axis (as measured by accelerometer)
- Serial.print(",");
- Serial.print(RwEst[2]); //Inclination Z axis (estimated / filtered)
- Serial.println("");
- blinkState = !blinkState;
- }
- void getEstimatedInclination()
- {
- static int i,w;
- static float tmpf,tmpf2;
- static unsigned long newMicros;
- static char signRzGyro;
- newMicros=millis();
- Get_an();
- interval=newMicros-lastMicros;
- lastMicros = newMicros;
- for(w=0;w<=2;w++) RwAcc[w]=getInput(w);
- normalize3DVector(RwAcc);
- if (firstSample)
- {
- for(w=0;w<=2;w++) RwEst[w]=RwAcc[w]; //initialize with accelerometer readings
- }
- else
- {
- if(abs(RwEst[2])<0.1)
- {
- for(w=0;w<=2;w++) RwGyro[w]=RwEst[w];
- }
- else
- {
- for(w=0;w<=1;w++)
- {
- tmpf=getInput(3+w);
- tmpf *= interval / 1,000.0f;
- Awz[w] = atan2(RwEst[w],RwEst[2]) * 180 /PI;
- Awz[w] += tmpf;
- }
- signRzGyro=(cos(Awz[0]*PI/180)>=0)?1:-1;
- for(w=0;w<=1;w++)
- {
- RwGyro[w] = sin(Awz[w]*PI/180);
- RwGyro[w]/=sqrt(1+squared(cos(Awz[w]*PI/180))*squared(tan(Awz[1-w]*PI/180)) );
- }
- RwGyro[2]=signRzGyro*sqrt(1-squared(RwGyro[0])-squared(RwGyro[1]));
- }
- for(w=0;w<=2;w++) RwEst[w] = (RwAcc[w] + wGyro* RwGyro[w])/(1 + wGyro);
- normalize3DVector(RwEst);
- }
- firstSample = 0;
- }
- float squared(float x)
- {
- return x*x;
- }
- float getInput(char i)
- {
- static float tmpf;
- if(i<=2) tmpf=an[i]/16384.0;
- else if(i==3) tmpf=an[i]/131.0-Gx_offset;
- else if(i==4) tmpf=an[i]/131.0-Gy_offset;
- else tmpf=an[i]/131.0-Gz_offset;
- return tmpf;
- }
- void normalize3DVector(float* vector)
- {
- static float R;
- R = sqrt(vector[0]*vector[0]+vector[1]*vector[1]+vector[2]*vector[2]);
- vector[0] /= R;
- vector[1] /= R;
- vector[2] /= R;
- }
- void Get_an()
- {
- accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
- an[0]=ax;
- an[1]=ay;
- an[2]=az;
- an[3]=gx;
- an[4]=gy;
- an[5]=gz;
- }
复制代码
|