College Project

Dependencies:   mbed MPU9250_SPI_Test MPU9250-XCLIN

Committer:
d15321854
Date:
Wed Feb 27 01:45:21 2019 +0000
Revision:
6:cc0a54642cdb
Parent:
5:5839d1b118bc
Sensor Fusion

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kylongmu 3:ad2ef67e7f72 1 /*CODED by Qiyong Mu on 21/06/2014
kylongmu 3:ad2ef67e7f72 2 kylongmu@msn.com
kylongmu 3:ad2ef67e7f72 3 */
kylongmu 0:58f9d4556df7 4 #include "mbed.h"
d15321854 6:cc0a54642cdb 5 #include "MPU9250.h"
d15321854 6:cc0a54642cdb 6 #define Kp 0.5f // proportional gain governs rate of convergence to accelerometer/magnetometer
d15321854 6:cc0a54642cdb 7 #define Ki 0.0f//0.005f // integral gain governs rate of convergence of gyroscope biases
d15321854 6:cc0a54642cdb 8 Timer LoopTimer;
d15321854 6:cc0a54642cdb 9 Timer SensorTimer;
d15321854 6:cc0a54642cdb 10 float Times[10] = {0,0,0,0,0,0,0,0,0,0};
d15321854 6:cc0a54642cdb 11 float control_frequency = 800;//PPM_FREQU; // frequency for the main loop in Hz
d15321854 6:cc0a54642cdb 12 int counter = 0;
d15321854 6:cc0a54642cdb 13 int divider = 20;
d15321854 6:cc0a54642cdb 14 float dt; // time for entire loop
d15321854 6:cc0a54642cdb 15 float dt_sensors; // time only to read sensors
d15321854 6:cc0a54642cdb 16 float q0 = 1, q1 = 0, q2 = 0, q3 = 0;
d15321854 6:cc0a54642cdb 17 float q0_A = 1, q1_A = 0, q2_A = 0, q3_A = 0;
d15321854 6:cc0a54642cdb 18 float exInt = 0, eyInt = 0, ezInt = 0;
d15321854 6:cc0a54642cdb 19 float OX = 0, OY = 0, OZ = 0;
d15321854 6:cc0a54642cdb 20 float Mag_x_pre,Mag_y_pre,Mag_z_pre;
d15321854 6:cc0a54642cdb 21 float Mag_x_pre_L,Mag_y_pre_L,Mag_z_pre_L;
d15321854 6:cc0a54642cdb 22 float Mag_x_pre_LL,Mag_y_pre_LL,Mag_z_pre_LL;
d15321854 6:cc0a54642cdb 23 float Mag_x_pre_LLL,Mag_y_pre_LLL,Mag_z_pre_LLL;
d15321854 6:cc0a54642cdb 24 float Mag_x_ave,Mag_y_ave,Mag_x_total,Mag_y_total;
d15321854 6:cc0a54642cdb 25 float Cal_Mag_x_pre_LL,Cal_Mag_x_pre_L,Cal_Mag_x_pre,Cal_Mag_x;
d15321854 6:cc0a54642cdb 26 float GYRO_z_pre,GYRO_z_pre_L,GYRO_z_pre_LL,GYRO_z_pre_LLL;
d15321854 6:cc0a54642cdb 27 float GYRO_z_total,GYRO_z_offset,Global_GYRO_z;
d15321854 6:cc0a54642cdb 28 float Global_mag_vector_angle,Yaw_pre;
d15321854 6:cc0a54642cdb 29 float Global_mag_x_vector_angle,Mag_x_vector_angle;
d15321854 6:cc0a54642cdb 30 float Global_mag_y_vector_angle,Mag_y_vector_angle;
d15321854 6:cc0a54642cdb 31 int Count_mag_check=0;
d15321854 6:cc0a54642cdb 32 float angle[3];
d15321854 6:cc0a54642cdb 33 float Roll,Pitch,Yaw;
d15321854 6:cc0a54642cdb 34 float calibrated_values[3],magCalibrationp[3];
d15321854 6:cc0a54642cdb 35 float v_index[3];
d15321854 6:cc0a54642cdb 36 float dest1,dest2;
d15321854 6:cc0a54642cdb 37 int f=0;
d15321854 6:cc0a54642cdb 38 int j=0;
d15321854 6:cc0a54642cdb 39 int k=0;
d15321854 6:cc0a54642cdb 40 int g=0;
d15321854 6:cc0a54642cdb 41 int count1=0,count2=0,count3=0,count4=0,count5=0,count6=0,count7=0,count8=0,count9=0,count11=0,count12=0,count14=0;
d15321854 6:cc0a54642cdb 42 int Rot_index;
d15321854 6:cc0a54642cdb 43 float mRes = 10.*4912./32760.0;
kylongmu 0:58f9d4556df7 44 DigitalOut myled(LED1);
kylongmu 0:58f9d4556df7 45 Serial pc(SERIAL_TX, SERIAL_RX);
kylongmu 0:58f9d4556df7 46 SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK);
kylongmu 0:58f9d4556df7 47 mpu9250_spi imu(spi,SPI_CS); //define the mpu9250 object
d15321854 6:cc0a54642cdb 48
d15321854 6:cc0a54642cdb 49 void Filter_IMUupdate(float halfT, float gx, float gy, float gz, float ax, float ay, float az) {
d15321854 6:cc0a54642cdb 50 float norm;
d15321854 6:cc0a54642cdb 51 float vx, vy, vz;
d15321854 6:cc0a54642cdb 52 float ex, ey, ez;
d15321854 6:cc0a54642cdb 53
d15321854 6:cc0a54642cdb 54 // normalise the measurements
d15321854 6:cc0a54642cdb 55 norm = sqrt(ax*ax + ay*ay + az*az);
d15321854 6:cc0a54642cdb 56 if(norm == 0.0f) return;
d15321854 6:cc0a54642cdb 57 ax /= norm;
d15321854 6:cc0a54642cdb 58 ay /= norm;
d15321854 6:cc0a54642cdb 59 az /= norm;
d15321854 6:cc0a54642cdb 60
d15321854 6:cc0a54642cdb 61 // estimated direction of gravity
d15321854 6:cc0a54642cdb 62 vx = 2*(q1*q3 - q0*q2);
d15321854 6:cc0a54642cdb 63 vy = 2*(q0*q1 + q2*q3);
d15321854 6:cc0a54642cdb 64 vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;
d15321854 6:cc0a54642cdb 65
d15321854 6:cc0a54642cdb 66 // error is sum of cross product between reference direction of field and direction measured by sensor
d15321854 6:cc0a54642cdb 67 ex = (ay*vz - az*vy);
d15321854 6:cc0a54642cdb 68 ey = (az*vx - ax*vz);
d15321854 6:cc0a54642cdb 69 ez = (ax*vy - ay*vx);
d15321854 6:cc0a54642cdb 70
d15321854 6:cc0a54642cdb 71 // integral error scaled integral gain
d15321854 6:cc0a54642cdb 72 exInt += ex*Ki;
d15321854 6:cc0a54642cdb 73 eyInt += ey*Ki;
d15321854 6:cc0a54642cdb 74 ezInt += ez*Ki;
d15321854 6:cc0a54642cdb 75
d15321854 6:cc0a54642cdb 76 // adjusted gyroscope measurements
d15321854 6:cc0a54642cdb 77 gx += Kp*ex + exInt;
d15321854 6:cc0a54642cdb 78 gy += Kp*ey + eyInt;
d15321854 6:cc0a54642cdb 79 gz += Kp*ez + ezInt;
d15321854 6:cc0a54642cdb 80
d15321854 6:cc0a54642cdb 81 // integrate quaternion rate and normalise
d15321854 6:cc0a54642cdb 82 float q0o = q0; // he did the MATLAB to C error by not thinking of the beginning vector elements already being changed for the calculation of the rest!
d15321854 6:cc0a54642cdb 83 float q1o = q1;
d15321854 6:cc0a54642cdb 84 float q2o = q2;
d15321854 6:cc0a54642cdb 85 float q3o = q3;
d15321854 6:cc0a54642cdb 86 q0 += (-q1o*gx - q2o*gy - q3o*gz)*halfT;
d15321854 6:cc0a54642cdb 87 q1 += (q0o*gx + q2o*gz - q3o*gy)*halfT;
d15321854 6:cc0a54642cdb 88 q2 += (q0o*gy - q1o*gz + q3o*gx)*halfT;
d15321854 6:cc0a54642cdb 89 q3 += (q0o*gz + q1o*gy - q2o*gx)*halfT;
d15321854 6:cc0a54642cdb 90
d15321854 6:cc0a54642cdb 91 // normalise quaternion
d15321854 6:cc0a54642cdb 92 norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
d15321854 6:cc0a54642cdb 93 q0 = q0 / norm;
d15321854 6:cc0a54642cdb 94 q1 = q1 / norm;
d15321854 6:cc0a54642cdb 95 q2 = q2 / norm;
d15321854 6:cc0a54642cdb 96 q3 = q3 / norm;
d15321854 6:cc0a54642cdb 97 }
d15321854 6:cc0a54642cdb 98 void IMU_AHRSupdate(float halfT, float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz) {
d15321854 6:cc0a54642cdb 99 float norm;
d15321854 6:cc0a54642cdb 100 float hx, hy, hz, bx, bz;
d15321854 6:cc0a54642cdb 101 float vx, vy, vz, wx, wy, wz;
d15321854 6:cc0a54642cdb 102 float ex, ey, ez;
d15321854 6:cc0a54642cdb 103
d15321854 6:cc0a54642cdb 104 // auxiliary variables to reduce number of repeated operations
d15321854 6:cc0a54642cdb 105 float q0q0 = q0*q0;
d15321854 6:cc0a54642cdb 106 float q0q1 = q0*q1;
d15321854 6:cc0a54642cdb 107 float q0q2 = q0*q2;
d15321854 6:cc0a54642cdb 108 float q0q3 = q0*q3;
d15321854 6:cc0a54642cdb 109 float q1q1 = q1*q1;
d15321854 6:cc0a54642cdb 110 float q1q2 = q1*q2;
d15321854 6:cc0a54642cdb 111 float q1q3 = q1*q3;
d15321854 6:cc0a54642cdb 112 float q2q2 = q2*q2;
d15321854 6:cc0a54642cdb 113 float q2q3 = q2*q3;
d15321854 6:cc0a54642cdb 114 float q3q3 = q3*q3;
d15321854 6:cc0a54642cdb 115
d15321854 6:cc0a54642cdb 116 // normalise the measurements
d15321854 6:cc0a54642cdb 117 norm = sqrt(ax*ax + ay*ay + az*az);
d15321854 6:cc0a54642cdb 118 if(norm == 0.0f) return;
d15321854 6:cc0a54642cdb 119 ax = ax / norm;
d15321854 6:cc0a54642cdb 120 ay = ay / norm;
d15321854 6:cc0a54642cdb 121 az = az / norm;
d15321854 6:cc0a54642cdb 122 norm = sqrt(mx*mx + my*my + mz*mz);
d15321854 6:cc0a54642cdb 123
d15321854 6:cc0a54642cdb 124 if(norm == 0.0f) return;
d15321854 6:cc0a54642cdb 125 mx = mx / norm;
d15321854 6:cc0a54642cdb 126 my = my / norm;
d15321854 6:cc0a54642cdb 127 mz = mz / norm;
d15321854 6:cc0a54642cdb 128 /*OX=mx;
d15321854 6:cc0a54642cdb 129 OY=my;
d15321854 6:cc0a54642cdb 130 OZ=mz;*/
d15321854 6:cc0a54642cdb 131 // compute reference direction of flux
d15321854 6:cc0a54642cdb 132 hx = 2*mx*(0.5 - q2q2 - q3q3) + 2*my*(q1q2 - q0q3) + 2*mz*(q1q3 + q0q2);
d15321854 6:cc0a54642cdb 133 hy = 2*mx*(q1q2 + q0q3) + 2*my*(0.5 - q1q1 - q3q3) + 2*mz*(q2q3 - q0q1);
d15321854 6:cc0a54642cdb 134 hz = 2*mx*(q1q3 - q0q2) + 2*my*(q2q3 + q0q1) + 2*mz*(0.5 - q1q1 - q2q2);
d15321854 6:cc0a54642cdb 135 bx = sqrt((hx*hx) + (hy*hy));
d15321854 6:cc0a54642cdb 136 bz = hz;
d15321854 6:cc0a54642cdb 137 // estimated direction of gravity and flux (v and w)
d15321854 6:cc0a54642cdb 138 vx = 2*(q1q3 - q0q2);
d15321854 6:cc0a54642cdb 139 vy = 2*(q0q1 + q2q3);
d15321854 6:cc0a54642cdb 140 vz = q0q0 - q1q1 - q2q2 + q3q3;
d15321854 6:cc0a54642cdb 141 wx = 2*bx*(0.5 - q2q2 - q3q3) + 2*bz*(q1q3 - q0q2);
d15321854 6:cc0a54642cdb 142 wy = 2*bx*(q1q2 - q0q3) + 2*bz*(q0q1 + q2q3);
d15321854 6:cc0a54642cdb 143 wz = 2*bx*(q0q2 + q1q3) + 2*bz*(0.5 - q1q1 - q2q2);
d15321854 6:cc0a54642cdb 144
d15321854 6:cc0a54642cdb 145 // error is sum of cross product between reference direction of fields and direction measured by sensors
d15321854 6:cc0a54642cdb 146 ex = (ay*vz - az*vy) + (my*wz - mz*wy);
d15321854 6:cc0a54642cdb 147 ey = (az*vx - ax*vz) + (mz*wx - mx*wz);
d15321854 6:cc0a54642cdb 148 ez = (ax*vy - ay*vx) + (mx*wy - my*wx);
d15321854 6:cc0a54642cdb 149
d15321854 6:cc0a54642cdb 150
d15321854 6:cc0a54642cdb 151 // integral error scaled integral gain
d15321854 6:cc0a54642cdb 152 exInt = exInt + ex*Ki;
d15321854 6:cc0a54642cdb 153 eyInt = eyInt + ey*Ki;
d15321854 6:cc0a54642cdb 154 ezInt = ezInt + ez*Ki;
d15321854 6:cc0a54642cdb 155
d15321854 6:cc0a54642cdb 156 // adjusted gyroscope measurements
d15321854 6:cc0a54642cdb 157 gx = gx + Kp*ex + exInt;
d15321854 6:cc0a54642cdb 158 gy = gy + Kp*ey + eyInt;
d15321854 6:cc0a54642cdb 159 gz = gz + Kp*ez + ezInt;
d15321854 6:cc0a54642cdb 160
d15321854 6:cc0a54642cdb 161 // integrate quaternion rate and normalise
d15321854 6:cc0a54642cdb 162 q0_A = q0_A + (-q1*gx - q2*gy - q3*gz)*halfT;
d15321854 6:cc0a54642cdb 163 q1_A = q1_A + (q0*gx + q2*gz - q3*gy)*halfT;
d15321854 6:cc0a54642cdb 164 q2_A = q2_A + (q0*gy - q1*gz + q3*gx)*halfT;
d15321854 6:cc0a54642cdb 165 q3_A = q3_A + (q0*gz + q1*gy - q2*gx)*halfT;
d15321854 6:cc0a54642cdb 166
d15321854 6:cc0a54642cdb 167 // normalise quaternion
d15321854 6:cc0a54642cdb 168 norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
d15321854 6:cc0a54642cdb 169 q0_A = q0_A / norm;
d15321854 6:cc0a54642cdb 170 q1_A = q1_A / norm;
d15321854 6:cc0a54642cdb 171 q2_A = q2_A / norm;
d15321854 6:cc0a54642cdb 172 q3_A = q3_A / norm;
d15321854 6:cc0a54642cdb 173 }
d15321854 6:cc0a54642cdb 174
d15321854 6:cc0a54642cdb 175
d15321854 6:cc0a54642cdb 176
d15321854 6:cc0a54642cdb 177
d15321854 6:cc0a54642cdb 178 void Filter_compute(float dt, const float * Gyro_data, const float * Acc_data, const float * Comp_data)
d15321854 6:cc0a54642cdb 179 {
d15321854 6:cc0a54642cdb 180 // IMU/AHRS
d15321854 6:cc0a54642cdb 181
d15321854 6:cc0a54642cdb 182 float d_Gyro_angle[3];
d15321854 6:cc0a54642cdb 183 void get_Acc_angle(const float * Acc_data);
d15321854 6:cc0a54642cdb 184 // IMU/AHRS (from http://www.x-io.co.uk/open-source-imu-and-ahrs-algorithms/)
d15321854 6:cc0a54642cdb 185 float radGyro[3],Gyro_cal_data; // Gyro in radians per second
d15321854 6:cc0a54642cdb 186
d15321854 6:cc0a54642cdb 187 for(int i=0; i<3; i++)
d15321854 6:cc0a54642cdb 188 radGyro[i] = Gyro_data[i] * 3.14159/ 180;
d15321854 6:cc0a54642cdb 189
d15321854 6:cc0a54642cdb 190 Filter_IMUupdate(dt/2, radGyro[0], radGyro[1], radGyro[2], Acc_data[0], Acc_data[1], Acc_data[2]);
d15321854 6:cc0a54642cdb 191 IMU_AHRSupdate(dt/2, radGyro[0], radGyro[1], radGyro[2], Acc_data[0], Acc_data[1], Acc_data[2], Comp_data[0], Comp_data[1], Comp_data[2]);
d15321854 6:cc0a54642cdb 192
d15321854 6:cc0a54642cdb 193 float rangle[3]; // calculate angles in radians from quternion output, formula from Wiki (http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles)
d15321854 6:cc0a54642cdb 194
d15321854 6:cc0a54642cdb 195 rangle[0] = atan2(2*q0*q1 + 2*q2*q3, 1 - 2*(q1*q1 + q2*q2));
d15321854 6:cc0a54642cdb 196 rangle[1] = asin (2*q0*q2 - 2*q3*q1);
d15321854 6:cc0a54642cdb 197 rangle[2] = atan2(2*q0_A*q3_A + 2*q1_A*q2_A, 1 - 2*(q2_A*q2_A + q3_A*q3_A)); // Z-axis
d15321854 6:cc0a54642cdb 198
d15321854 6:cc0a54642cdb 199
d15321854 6:cc0a54642cdb 200 for(int i=0; i<2; i++){ // angle in degree
d15321854 6:cc0a54642cdb 201 angle[i] = rangle[i] * 180 / 3.14159;
d15321854 6:cc0a54642cdb 202 }
d15321854 6:cc0a54642cdb 203 Roll=angle[0];
d15321854 6:cc0a54642cdb 204 Pitch=angle[1];
d15321854 6:cc0a54642cdb 205 //**************************************************Gyro_data[2] filter start
d15321854 6:cc0a54642cdb 206 float GYRO_z=0;
d15321854 6:cc0a54642cdb 207
d15321854 6:cc0a54642cdb 208 GYRO_z=Gyro_data[2]*0.15 + GYRO_z_pre*0.20 + GYRO_z_pre_L*0.20 + GYRO_z_pre_LL*0.25 + GYRO_z_pre_LLL*0.20;
d15321854 6:cc0a54642cdb 209 if( count4==1 ){
d15321854 6:cc0a54642cdb 210 GYRO_z_pre_L=GYRO_z_pre;
d15321854 6:cc0a54642cdb 211
d15321854 6:cc0a54642cdb 212 count4=0;
d15321854 6:cc0a54642cdb 213 }
d15321854 6:cc0a54642cdb 214 if( count5==2 ){
d15321854 6:cc0a54642cdb 215 GYRO_z_pre_LL=GYRO_z_pre_L;
d15321854 6:cc0a54642cdb 216
d15321854 6:cc0a54642cdb 217 count5=0;
d15321854 6:cc0a54642cdb 218 }
d15321854 6:cc0a54642cdb 219 if( count6==3 ){
d15321854 6:cc0a54642cdb 220 GYRO_z_pre_LLL=GYRO_z_pre_LL;
d15321854 6:cc0a54642cdb 221
d15321854 6:cc0a54642cdb 222 count6=0;
d15321854 6:cc0a54642cdb 223 }
d15321854 6:cc0a54642cdb 224
d15321854 6:cc0a54642cdb 225
d15321854 6:cc0a54642cdb 226
d15321854 6:cc0a54642cdb 227 count4++;
d15321854 6:cc0a54642cdb 228 count5++;
d15321854 6:cc0a54642cdb 229 count6++;
d15321854 6:cc0a54642cdb 230 GYRO_z_pre=Gyro_data[2];
d15321854 6:cc0a54642cdb 231 Global_GYRO_z=GYRO_z;
d15321854 6:cc0a54642cdb 232 /*pc.printf(" GYRO_z:%10.3f ,count8:%10d ",
d15321854 6:cc0a54642cdb 233 GYRO_z,
d15321854 6:cc0a54642cdb 234 count8
d15321854 6:cc0a54642cdb 235 );*/
d15321854 6:cc0a54642cdb 236 if((count8>5)&&(count8<=805)){
d15321854 6:cc0a54642cdb 237 GYRO_z_total+=GYRO_z;
d15321854 6:cc0a54642cdb 238 }
d15321854 6:cc0a54642cdb 239 if( count8==805 ){
d15321854 6:cc0a54642cdb 240 GYRO_z_offset=GYRO_z_total/800;
d15321854 6:cc0a54642cdb 241 /*pc.printf(" GYRO_z_offset:%10.5f ",
d15321854 6:cc0a54642cdb 242 GYRO_z_offset
d15321854 6:cc0a54642cdb 243 );*/
d15321854 6:cc0a54642cdb 244 GYRO_z_total=0;
d15321854 6:cc0a54642cdb 245 count8=0;
d15321854 6:cc0a54642cdb 246 }
d15321854 6:cc0a54642cdb 247
d15321854 6:cc0a54642cdb 248 count8++;
d15321854 6:cc0a54642cdb 249 //**************************************************Gyro_data[2]'s average filter : answer=GYRO_Z is roughly = 1.05447
d15321854 6:cc0a54642cdb 250
d15321854 6:cc0a54642cdb 251 //************************************************** calculate Yaw
d15321854 6:cc0a54642cdb 252 if( (count11==35) ){
d15321854 6:cc0a54642cdb 253 if( abs(Yaw_pre-Yaw)<1 ){
d15321854 6:cc0a54642cdb 254 Yaw_pre=Yaw_pre;
d15321854 6:cc0a54642cdb 255 }else{
d15321854 6:cc0a54642cdb 256 Yaw_pre=Yaw;
d15321854 6:cc0a54642cdb 257 }
d15321854 6:cc0a54642cdb 258 count11=0;
d15321854 6:cc0a54642cdb 259 }
d15321854 6:cc0a54642cdb 260 count11++;
d15321854 6:cc0a54642cdb 261
d15321854 6:cc0a54642cdb 262 if( count12>=20 ){
d15321854 6:cc0a54642cdb 263 Yaw += (Gyro_data[2]-1.05447) *dt;
d15321854 6:cc0a54642cdb 264 }
d15321854 6:cc0a54642cdb 265 count12++;
d15321854 6:cc0a54642cdb 266 pc.printf(" Yaw:%10.5f ",
d15321854 6:cc0a54642cdb 267 Yaw
d15321854 6:cc0a54642cdb 268 );
d15321854 6:cc0a54642cdb 269 }
d15321854 6:cc0a54642cdb 270 void Mag_Complentary_Filter(float dt, const float * Comp_data)
d15321854 6:cc0a54642cdb 271 {
d15321854 6:cc0a54642cdb 272 float Mag_x=0,Mag_y=0,Mag_z=0;
d15321854 6:cc0a54642cdb 273 Mag_x=Comp_data[0]*0.15 + Mag_x_pre*0.20 + Mag_x_pre_L*0.20 + Mag_x_pre_LL*0.25 + Mag_x_pre_LLL*0.20;
d15321854 6:cc0a54642cdb 274 Mag_y=Comp_data[1]*0.15 + Mag_y_pre*0.20 + Mag_y_pre_L*0.20 + Mag_y_pre_LL*0.25 + Mag_y_pre_LLL*0.20;
d15321854 6:cc0a54642cdb 275 Mag_z=Comp_data[2]*0.15 + Mag_z_pre*0.20 + Mag_z_pre_L*0.20 + Mag_z_pre_LL*0.25 + Mag_z_pre_LLL*0.20;
d15321854 6:cc0a54642cdb 276
d15321854 6:cc0a54642cdb 277
d15321854 6:cc0a54642cdb 278 if( count1==1 ){
d15321854 6:cc0a54642cdb 279 Mag_x_pre_L=Mag_x_pre;
d15321854 6:cc0a54642cdb 280 Mag_y_pre_L=Mag_y_pre;
d15321854 6:cc0a54642cdb 281 Mag_z_pre_L=Mag_z_pre;
d15321854 6:cc0a54642cdb 282 Cal_Mag_x_pre=Cal_Mag_x;
d15321854 6:cc0a54642cdb 283
d15321854 6:cc0a54642cdb 284 count1=0;
d15321854 6:cc0a54642cdb 285 }
d15321854 6:cc0a54642cdb 286 if( count2==2 ){
d15321854 6:cc0a54642cdb 287 Mag_x_pre_LL=Mag_x_pre_L;
d15321854 6:cc0a54642cdb 288 Mag_y_pre_LL=Mag_y_pre_L;
d15321854 6:cc0a54642cdb 289 Mag_z_pre_LL=Mag_z_pre_L;
d15321854 6:cc0a54642cdb 290 Cal_Mag_x_pre_L=Cal_Mag_x_pre;
d15321854 6:cc0a54642cdb 291
d15321854 6:cc0a54642cdb 292 count2=0;
d15321854 6:cc0a54642cdb 293 }
d15321854 6:cc0a54642cdb 294 if( count7==3 ){
d15321854 6:cc0a54642cdb 295 Mag_x_pre_LLL=Mag_x_pre_LL;
d15321854 6:cc0a54642cdb 296 Mag_y_pre_LLL=Mag_y_pre_LL;
d15321854 6:cc0a54642cdb 297 Mag_z_pre_LLL=Mag_z_pre_LL;
d15321854 6:cc0a54642cdb 298 Cal_Mag_x_pre_LL=Cal_Mag_x_pre_L;
d15321854 6:cc0a54642cdb 299
d15321854 6:cc0a54642cdb 300 count7=0;
d15321854 6:cc0a54642cdb 301 }
d15321854 6:cc0a54642cdb 302
d15321854 6:cc0a54642cdb 303
d15321854 6:cc0a54642cdb 304 count1++;
d15321854 6:cc0a54642cdb 305 count2++;
d15321854 6:cc0a54642cdb 306 count7++;
d15321854 6:cc0a54642cdb 307 Mag_x_pre=Comp_data[0];
d15321854 6:cc0a54642cdb 308 Mag_y_pre=Comp_data[1];
d15321854 6:cc0a54642cdb 309 Mag_z_pre=Comp_data[2];
d15321854 6:cc0a54642cdb 310 if( count14>4 ){
d15321854 6:cc0a54642cdb 311 Cal_Mag_x=Mag_x;
d15321854 6:cc0a54642cdb 312 }
d15321854 6:cc0a54642cdb 313 count14++;
d15321854 6:cc0a54642cdb 314
d15321854 6:cc0a54642cdb 315
d15321854 6:cc0a54642cdb 316 //*************************************Mag_ave calculate
d15321854 6:cc0a54642cdb 317 if(count3<=20){
d15321854 6:cc0a54642cdb 318 Mag_x_total+=Mag_x;
d15321854 6:cc0a54642cdb 319 Mag_y_total+=Mag_y;
d15321854 6:cc0a54642cdb 320 }
d15321854 6:cc0a54642cdb 321 if( count3==20){
d15321854 6:cc0a54642cdb 322 Mag_x_ave=Mag_x_total/21;
d15321854 6:cc0a54642cdb 323 Mag_y_ave=Mag_y_total/21;
d15321854 6:cc0a54642cdb 324 /*pc.printf(" Mag_x_ave:%10.5f ,Mag_y_ave:%10.5f ",
d15321854 6:cc0a54642cdb 325 Mag_x_ave,
d15321854 6:cc0a54642cdb 326 Mag_y_ave
d15321854 6:cc0a54642cdb 327 );*/
d15321854 6:cc0a54642cdb 328 Mag_x_total=0;
d15321854 6:cc0a54642cdb 329 Mag_y_total=0;
d15321854 6:cc0a54642cdb 330 count3=0;
d15321854 6:cc0a54642cdb 331
d15321854 6:cc0a54642cdb 332
d15321854 6:cc0a54642cdb 333 }
d15321854 6:cc0a54642cdb 334 count3++;
d15321854 6:cc0a54642cdb 335
d15321854 6:cc0a54642cdb 336 //********************************ROT_check start
d15321854 6:cc0a54642cdb 337
d15321854 6:cc0a54642cdb 338 float v_length,v_length_ave,MagVector_angle;
d15321854 6:cc0a54642cdb 339 v_length=sqrt( Mag_x*Mag_x + Mag_y*Mag_y );
d15321854 6:cc0a54642cdb 340 v_length_ave=sqrt( Mag_x_ave*Mag_x_ave + Mag_y_ave*Mag_y_ave );
d15321854 6:cc0a54642cdb 341
d15321854 6:cc0a54642cdb 342 MagVector_angle=acos(( Mag_x*Mag_x_ave + Mag_y*Mag_y_ave )/(v_length*v_length_ave))*57.3;
d15321854 6:cc0a54642cdb 343
d15321854 6:cc0a54642cdb 344 if( count9==3 ){
d15321854 6:cc0a54642cdb 345 Global_mag_vector_angle=MagVector_angle;
d15321854 6:cc0a54642cdb 346 count9=0;
d15321854 6:cc0a54642cdb 347 }
d15321854 6:cc0a54642cdb 348 count9++;
d15321854 6:cc0a54642cdb 349
d15321854 6:cc0a54642cdb 350
d15321854 6:cc0a54642cdb 351 if( (abs(Global_mag_vector_angle-MagVector_angle)<5) && (abs(Global_GYRO_z)<5) ){
d15321854 6:cc0a54642cdb 352 Count_mag_check++;
d15321854 6:cc0a54642cdb 353
d15321854 6:cc0a54642cdb 354 }else{ Count_mag_check=0; }
d15321854 6:cc0a54642cdb 355
d15321854 6:cc0a54642cdb 356 if( Count_mag_check==30 ){
d15321854 6:cc0a54642cdb 357 Yaw=Yaw_pre;
d15321854 6:cc0a54642cdb 358 Count_mag_check=0;
d15321854 6:cc0a54642cdb 359 }
d15321854 6:cc0a54642cdb 360 float ABS_CHECK=abs(Global_mag_vector_angle-MagVector_angle);
d15321854 6:cc0a54642cdb 361 //********************************Theta_check end
d15321854 6:cc0a54642cdb 362 /*pc.printf("ABS_CHECK:%10.3f,Cal_Mag_x_pre_LL:%10.3f,Mag_x:%10.3f,Count_mag_check:%10d ,Yaw_pre:%10.3f,Yaw_filter:%10.3f ",
d15321854 6:cc0a54642cdb 363 ABS_CHECK,
d15321854 6:cc0a54642cdb 364 Cal_Mag_x_pre_LL,
d15321854 6:cc0a54642cdb 365 Mag_x,
d15321854 6:cc0a54642cdb 366 Count_mag_check,
d15321854 6:cc0a54642cdb 367 Yaw_pre,
d15321854 6:cc0a54642cdb 368 Yaw
d15321854 6:cc0a54642cdb 369 );*/
d15321854 6:cc0a54642cdb 370
d15321854 6:cc0a54642cdb 371 }
kylongmu 0:58f9d4556df7 372 int main(){
kylongmu 0:58f9d4556df7 373 pc.baud(115200);
kylongmu 5:5839d1b118bc 374 if(imu.init(1,BITS_DLPF_CFG_188HZ)){ //INIT the mpu9250
d15321854 6:cc0a54642cdb 375 pc.printf("\nCouldn't initialize MPU9250 via SPI!");
kylongmu 0:58f9d4556df7 376 }
d15321854 6:cc0a54642cdb 377 pc.printf("\nWHOAMI=0x%2x\n",imu.whoami()); //output the I2C address to know if SPI is working, it should be 104
kylongmu 1:7497c7952470 378 wait(1);
d15321854 6:cc0a54642cdb 379 pc.printf("Gyro_scale=%u\n",imu.set_gyro_scale(BITS_FS_2000DPS)); //Set full scale range for gyros
kylongmu 0:58f9d4556df7 380 wait(1);
d15321854 6:cc0a54642cdb 381 pc.printf("Acc_scale=%u\n",imu.set_acc_scale(BITS_FS_16G)); //Set full scale range for accs
kylongmu 1:7497c7952470 382 wait(1);
d15321854 6:cc0a54642cdb 383 pc.printf("AK8963 WHIAM=0x%2x\n",imu.AK8963_whoami());
kylongmu 1:7497c7952470 384 wait(0.1);
kylongmu 5:5839d1b118bc 385 imu.AK8963_calib_Magnetometer();
kylongmu 0:58f9d4556df7 386 while(1) {
d15321854 6:cc0a54642cdb 387
d15321854 6:cc0a54642cdb 388 LoopTimer.start();
kylongmu 0:58f9d4556df7 389 wait(0.1);
d15321854 6:cc0a54642cdb 390
d15321854 6:cc0a54642cdb 391 SensorTimer.start();
d15321854 6:cc0a54642cdb 392 Times[1] = LoopTimer.read(); // 197us
d15321854 6:cc0a54642cdb 393 SensorTimer.stop(); // stop time for measuring sensors
d15321854 6:cc0a54642cdb 394 dt_sensors = SensorTimer.read();
d15321854 6:cc0a54642cdb 395 SensorTimer.reset();
d15321854 6:cc0a54642cdb 396 // meassure dt since last measurement for the filter
d15321854 6:cc0a54642cdb 397 dt = LoopTimer.read(); // time in s since last loop
d15321854 6:cc0a54642cdb 398 LoopTimer.reset();
d15321854 6:cc0a54642cdb 399
d15321854 6:cc0a54642cdb 400
kylongmu 4:6bfddd447c27 401 imu.read_all();
d15321854 6:cc0a54642cdb 402
d15321854 6:cc0a54642cdb 403 Mag_Complentary_Filter(dt,imu.Magnetometer);
d15321854 6:cc0a54642cdb 404 Filter_compute(dt, imu.gyroscope_data, imu.accelerometer_data, imu.Magnetometer);
d15321854 6:cc0a54642cdb 405
d15321854 6:cc0a54642cdb 406 pc.printf("Roll:%10.3f,Pitch:%10.3f,Yaw:%10.3f \n",
d15321854 6:cc0a54642cdb 407 Roll,
d15321854 6:cc0a54642cdb 408 Pitch,
d15321854 6:cc0a54642cdb 409 Yaw
kylongmu 1:7497c7952470 410 );
d15321854 6:cc0a54642cdb 411
kylongmu 0:58f9d4556df7 412 }
kylongmu 0:58f9d4556df7 413 }