MPU9250
Fork of MPU9250_SPI by
Revision 12:a70c193d8195, committed 2016-05-09
- Comitter:
- kikoaac
- Date:
- Mon May 09 05:45:18 2016 +0000
- Parent:
- 11:084e8ba240c1
- Commit message:
- MPU9250;
Changed in this revision
MPU9250.cpp | Show annotated file Show diff for this revision Revisions of this file |
MPU9250.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 084e8ba240c1 -r a70c193d8195 MPU9250.cpp --- a/MPU9250.cpp Tue Jul 01 13:59:45 2014 +0000 +++ b/MPU9250.cpp Mon May 09 05:45:18 2016 +0000 @@ -5,7 +5,18 @@ #include <mbed.h> #include "MPU9250.h" -mpu9250_spi::mpu9250_spi(SPI& _spi, PinName _cs) : spi(_spi), cs(_cs) {} +mpu9250_spi::mpu9250_spi(SPI& _spi, PinName _cs) : spi(_spi), cs(_cs) +{ + /* uint8_t offset[3][2] = + {-21 , MPUREG_XG_OFFS_TC}; + for(i=0; i<offset; i++) { + WriteReg(offset[i][1], offset[i][0]); + wait(0.001); //I2C must slow down the write speed, otherwise it won't work + }*/ + Magnetometer_offset[0]=0; + Magnetometer_offset[1]=0; + Magnetometer_offset[2]=0; +} unsigned int mpu9250_spi::WriteReg( uint8_t WriteAddr, uint8_t WriteData ) { @@ -42,14 +53,15 @@ BITS_DLPF_CFG_98HZ BITS_DLPF_CFG_42HZ BITS_DLPF_CFG_20HZ -BITS_DLPF_CFG_10HZ -BITS_DLPF_CFG_5HZ +BITS_DLPF_CFG_10HZ +BITS_DLPF_CFG_5HZ BITS_DLPF_CFG_2100HZ_NOLPF returns 1 if an error occurred -----------------------------------------------------------------------------------------------*/ #define MPU_InitRegNum 17 -bool mpu9250_spi::init(int sample_rate_div,int low_pass_filter){ +bool mpu9250_spi::init(int sample_rate_div,int low_pass_filter) +{ uint8_t i = 0; uint8_t MPU_Init_Data[MPU_InitRegNum][2] = { {0x80, MPUREG_PWR_MGMT_1}, // Reset Device @@ -64,7 +76,7 @@ //{0x20, MPUREG_USER_CTRL}, // Enable AUX {0x20, MPUREG_USER_CTRL}, // I2C Master mode {0x0D, MPUREG_I2C_MST_CTRL}, // I2C configuration multi-master IIC 400KHz - + {AK8963_I2C_ADDR, MPUREG_I2C_SLV0_ADDR}, //Set the I2C slave addres of AK8963 and set for write. //{0x09, MPUREG_I2C_SLV4_CTRL}, //{0x81, MPUREG_I2C_MST_DELAY_CTRL}, //Enable I2C delay @@ -76,7 +88,7 @@ {AK8963_CNTL1, MPUREG_I2C_SLV0_REG}, //I2C slave 0 register address from where to begin data transfer {0x12, MPUREG_I2C_SLV0_DO}, // Register value to continuous measurement in 16bit {0x81, MPUREG_I2C_SLV0_CTRL} //Enable I2C and set 1 byte - + }; spi.format(8,0); spi.frequency(1000000); @@ -88,7 +100,7 @@ set_acc_scale(2); set_gyro_scale(250); - + //AK8963_calib_Magnetometer(); //Can't load this function here , strange problem? return 0; } @@ -102,39 +114,40 @@ BITS_FS_16G returns the range set (2,4,8 or 16) -----------------------------------------------------------------------------------------------*/ -unsigned int mpu9250_spi::set_acc_scale(int scale){ +unsigned int mpu9250_spi::set_acc_scale(int scale) +{ unsigned int temp_scale; WriteReg(MPUREG_ACCEL_CONFIG, scale); - - switch (scale){ + + switch (scale) { case BITS_FS_2G: acc_divider=16384; - break; + break; case BITS_FS_4G: acc_divider=8192; - break; + break; case BITS_FS_8G: acc_divider=4096; - break; + break; case BITS_FS_16G: acc_divider=2048; - break; + break; } temp_scale=WriteReg(MPUREG_ACCEL_CONFIG|READ_FLAG, 0x00); - - switch (temp_scale){ + + switch (temp_scale) { case BITS_FS_2G: temp_scale=2; - break; + break; case BITS_FS_4G: temp_scale=4; - break; + break; case BITS_FS_8G: temp_scale=8; - break; + break; case BITS_FS_16G: temp_scale=16; - break; + break; } return temp_scale; } @@ -150,37 +163,38 @@ BITS_FS_2000DPS returns the range set (250,500,1000 or 2000) -----------------------------------------------------------------------------------------------*/ -unsigned int mpu9250_spi::set_gyro_scale(int scale){ +unsigned int mpu9250_spi::set_gyro_scale(int scale) +{ unsigned int temp_scale; WriteReg(MPUREG_GYRO_CONFIG, scale); - switch (scale){ + switch (scale) { case BITS_FS_250DPS: gyro_divider=131; - break; + break; case BITS_FS_500DPS: gyro_divider=65.5; - break; + break; case BITS_FS_1000DPS: gyro_divider=32.8; - break; + break; case BITS_FS_2000DPS: gyro_divider=16.4; - break; + break; } temp_scale=WriteReg(MPUREG_GYRO_CONFIG|READ_FLAG, 0x00); - switch (temp_scale){ + switch (temp_scale) { case BITS_FS_250DPS: temp_scale=250; - break; + break; case BITS_FS_500DPS: temp_scale=500; - break; + break; case BITS_FS_1000DPS: temp_scale=1000; - break; + break; case BITS_FS_2000DPS: temp_scale=2000; - break; + break; } return temp_scale; } @@ -192,7 +206,8 @@ mpu9250 which should be 104 when in SPI mode. returns the I2C address (104) -----------------------------------------------------------------------------------------------*/ -unsigned int mpu9250_spi::whoami(){ +unsigned int mpu9250_spi::whoami() +{ unsigned int response; response=WriteReg(MPUREG_WHOAMI|READ_FLAG, 0x00); return response; @@ -217,8 +232,10 @@ bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; data=(float)bit_data; accelerometer_data[i]=data/acc_divider; + accelerometer_data[i]=0.1*accelerometer_data[i]+0.9*accelerometer_data_prev[i]; + accelerometer_data_prev[i]=accelerometer_data[i]; } - + } /*----------------------------------------------------------------------------------------------- @@ -245,10 +262,11 @@ /*----------------------------------------------------------------------------------------------- READ TEMPERATURE -usage: call this function to read temperature data. +usage: call this function to read temperature data. returns the value in °C -----------------------------------------------------------------------------------------------*/ -void mpu9250_spi::read_temp(){ +void mpu9250_spi::read_temp() +{ uint8_t response[2]; int16_t bit_data; float data; @@ -285,7 +303,8 @@ set_acc_scale(temp_scale); } -uint8_t mpu9250_spi::AK8963_whoami(){ +uint8_t mpu9250_spi::AK8963_whoami() +{ uint8_t response; WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read. WriteReg(MPUREG_I2C_SLV0_REG, AK8963_WIA); //I2C slave 0 register address from where to begin data transfer @@ -293,13 +312,76 @@ //WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81); //Enable I2C and set bytes wait(0.001); - response=WriteReg(MPUREG_EXT_SENS_DATA_00|READ_FLAG, 0x00); //Read I2C + response=WriteReg(MPUREG_EXT_SENS_DATA_00|READ_FLAG, 0x00); //Read I2C //ReadRegs(MPUREG_EXT_SENS_DATA_00,response,1); - //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00); //Read I2C + //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00); //Read I2C return response; } -void mpu9250_spi::AK8963_calib_Magnetometer(){ +double* mpu9250_spi::AK8936_read_Orientation(double *getdata) +{ + + double gx = accelerometer_data[0]; + double gy = accelerometer_data[1]; + double gz = accelerometer_data[2]; + double mx = Magnetometer[0];//-centorx; + double my = Magnetometer[1];//-centory; + double mz = Magnetometer[2];//-centorz; + double g0x=0.01,g0y=0.001,g0z=0.99; + double Gproduct = gx*g0x+gy*g0y+gz*g0z; + double Glengh = sqrt(gx*gx+gy*gy+gz*gz); + double G0lengh =sqrt(g0x*g0x+g0y*g0y+g0z*g0z); + double nx = (gy * g0z - gz * g0y); + double ny = (gz * g0x - gx * g0z); + double nz = (gx * g0y - gy * g0x); + double GPlengh = sqrt(nx*nx+ny*ny+nz*nz); + nx/=GPlengh; + ny/=GPlengh; + nz/=GPlengh; + double accang = acos((Gproduct)/(fabs(Glengh)*fabs(G0lengh)));/* + double hx=(nx*nx*(1-cos(accang))+cos(accang))*mx + (nx*ny*(1-cos(accang))+nz*sin(accang))*my + (nz*nx*(1-cos(accang))+ny*sin(accang))*mz; + double hy=(nx*ny*(1-cos(accang))+nz*sin(accang))*mx + (ny*ny*(1-cos(accang))+cos(accang))*my + (ny*nz*(1-cos(accang))+nx*sin(accang))*mz;*/ + double Mrot[3][3] = { + {nx*nx*(1-cos(accang))+cos(accang) , nx*ny*(1-cos(accang))+nz*sin(accang) ,nz*nx*(1-cos(accang))+ny*sin(accang)}, + {nx*ny*(1-cos(accang))+nz*sin(accang) , ny*ny*(1-cos(accang))+cos(accang) ,ny*nz*(1-cos(accang))+nx*sin(accang)}, + {nz*nx*(1-cos(accang))+ny*sin(accang) , ny*nz*(1-cos(accang))+nx*sin(accang) ,nz*nz*(1-cos(accang))+cos(accang)} + }; + double MrotD[3][3]; + double temp[3][3]; + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) { + temp[j][i]=Mrot[i][j]; + MrotD[j][i]=temp[j][i]; + } + double hx = MrotD[0][0]*mx+MrotD[0][1]*my+MrotD[0][2]*mz; + double hy = MrotD[1][0]*mx+MrotD[1][1]*my+MrotD[1][2]*mz; + double hz = MrotD[2][0]*mx+MrotD[2][1]*my+MrotD[2][2]*mz; + double heading = atan2(hy,hx)*180/3.14; + if (heading > 0) + heading = 360 - heading; + else + heading = -heading; + float pitch = atan(-hx/sqrt(hy*hy+hz*hz))*180/3.14; //invert gx because +pitch is up. range is +/-90 degrees + float roll = atan(hy/sqrt(hx*hx+hz*hz))*180/3.14; // right side down is +roll + if (gz > 0) + { + if ( roll > 0) + roll = 180 - roll; + else + roll = -180 - roll; + } + getdata[0]=heading; + getdata[1]=pitch; + getdata[2]=roll; + return getdata; +} +void mpu9250_spi::AK8963_setoffset(int x,double offset) +{ + if((x<0)||(x>3))return; + Magnetometer_offset[x]+=offset; +} +void mpu9250_spi::AK8963_calib_Magnetometer() +{ uint8_t response[3]; float data; int i; @@ -310,16 +392,17 @@ //WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81); //Enable I2C and set bytes wait(0.001); - //response[0]=WriteReg(MPUREG_EXT_SENS_DATA_01|READ_FLAG, 0x00); //Read I2C + //response[0]=WriteReg(MPUREG_EXT_SENS_DATA_01|READ_FLAG, 0x00); //Read I2C ReadRegs(MPUREG_EXT_SENS_DATA_00,response,3); - - //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00); //Read I2C + + //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00); //Read I2C for(i=0; i<3; i++) { data=response[i]; Magnetometer_ASA[i]=((data-128)/256+1)*Magnetometer_Sensitivity_Scale_Factor; } } -void mpu9250_spi::AK8963_read_Magnetometer(){ +void mpu9250_spi::AK8963_read_Magnetometer() +{ uint8_t response[7]; int16_t bit_data; float data; @@ -335,10 +418,11 @@ for(i=0; i<3; i++) { bit_data=((int16_t)response[i*2+1]<<8)|response[i*2]; data=(float)bit_data; - Magnetometer[i]=data*Magnetometer_ASA[i]; + Magnetometer[i]=data*Magnetometer_ASA[i]-Magnetometer_offset[i]; } } -void mpu9250_spi::read_all(){ +void mpu9250_spi::read_all() +{ uint8_t response[21]; int16_t bit_data; float data; @@ -357,6 +441,8 @@ bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; data=(float)bit_data; accelerometer_data[i]=data/acc_divider; + //accelerometer_data[i]=0.1*accelerometer_data[i]+0.9*accelerometer_data_prev[i]; + //accelerometer_data_prev[i]=accelerometer_data[i]; } //Get temperature bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; @@ -372,19 +458,314 @@ for(i=7; i<10; i++) { bit_data=((int16_t)response[i*2+1]<<8)|response[i*2]; data=(float)bit_data; - Magnetometer[i-7]=data*Magnetometer_ASA[i-7]; + Magnetometer[i-7]=data*Magnetometer_ASA[i-7]-Magnetometer_offset[i-7]; + } +} + + + +void mpu9250_spi::SpeedSet() +{ + get_speedrate(); + read_acc(); + /*for(int i=0;i<3;i++) + ratespeed[i]=acc[i];*/ + double S[3]; + speedT.stop(); + for(int i=0; i<3; i++) { + + S[i] =((double)(ratespeed[i]+prev_ratespeed[i])*speedT.read()/2); + speed[i]+=(double)S[i]; + speed[i]=floor(speed[i]*100.0)/100.0; + Synthesis_speed[i]+=(double)S[i]; + Synthesis_speed[i]=0.9*(double)(Synthesis_speed[i]+(double)ratespeed[i]/100.5)+0.1*ratespeed[i]; + kalman_speed[i]=kalmaspeed[i].getAngle((double)kalman_speed[i], (double)ratespeed[i], (double)angleT.read()*1000); + comp_speed[i]=kalman_speed[i]*0.01+Synthesis_speed[i]*0.01+comp_speed[i]*0.98; + prev_ratespeed[i]=ratespeed[i]; + } + speedT.reset(); + speedT.start(); +} +void mpu9250_spi::MeterSet() +{ + double S[3]; + for(int i = 0 ; i<3 ; i++) + ratemeter[i]=comp_speed[i]*1000; + meterT.stop(); + for(int i=0; i<3; i++) { + + S[i] =((double)(ratemeter[i]+prev_ratemeter[i])*meterT.read()/2); + meter[i]+=(double)S[i]; + Synthesis_meter[i]+=(double)S[i]; + Synthesis_meter[i]=0.9*(double)(Synthesis_meter[i]+(double)ratemeter[i]/100.5)+0.1*meter[i]; + kalman_meter[i]=kalmameter[i].getAngle((double)kalman_meter[i], (double)ratemeter[i], (double)angleT.read()*1000); + comp_meter[i]=kalman_meter[i]*0.01+Synthesis_meter[i]*0.01+comp_meter[i]*0.98; + prev_ratemeter[i]=ratemeter[i]; + } + meterT.reset(); + meterT.start(); +} + + + +void mpu9250_spi::MPU_setup() +{ + z_offset=2; + x_offset=0; + y_offset=0; + uint8_t buffer[6]; + + for(int i=0; i<sampleNum; i++) { + ReadRegs(MPUREG_ACCEL_XOUT_H,buffer,6); + int Xacc = (int)buffer[1] << 8 | (int)buffer[0]; + int Yacc = (int)buffer[3] << 8 | (int)buffer[2]; + int Zacc = (int)buffer[5] << 8 | (int)buffer[4]-255; + if((int)Xacc-x_offset>xnoise) + xnoise=(int)Xacc-x_offset; + else if((int)Xacc-x_offset<-xnoise) + xnoise=-(int)Xacc-x_offset; + + if((int)Yacc-y_offset>ynoise) + ynoise=(int)Yacc-y_offset; + else if((int)Yacc-y_offset<-ynoise) + ynoise=-(int)Yacc-y_offset; + + if((int)Zacc-z_offset>znoise) + znoise=(int)Zacc-z_offset; + else if((int)Zacc-z_offset<-znoise) + znoise=-(int)Zacc-z_offset; + } + + +} +void mpu9250_spi::MPU_setnum(int Num,float time,double rate) +{ + sampleNum=Num; + sampleTime=time; + Rate=rate; +} + + +void mpu9250_spi::get_angle_acc() +{ + //short data[3]; + //get_axis_acc(data); + float R = sqrt(pow((float)accelerometer_data[0],2) + pow((float)accelerometer_data[1],2) + pow((float)accelerometer_data[2],2)); + angle_acc[0]=atan2(accelerometer_data[0],accelerometer_data[2])*(180 / 3.1415); + angle_acc[1]=atan2(accelerometer_data[1],accelerometer_data[2])*(180 / 3.1415); + //angle_acc[2]= + /*angle_acc[1] = -((180 / 3.1415) * acos((float)accelerometer_data[1] / R)-90); // roll - angle of magnetic field vector in x direction + angle_acc[0] = (180 / 3.1415) * acos((float)accelerometer_data[0] / R)-90; // pitch - angle of magnetic field vector in y direction + angle_acc[2] = (180 / 3.1415) * acos((float)accelerometer_data[2] / R); //*/ + /*angle_acc[0] = atan2(accelerometer_data[0],sqrt(pow((float)accelerometer_data[1],2)+pow((float)accelerometer_data[2],2)))*180/3.1415; + angle_acc[1] = atan2(accelerometer_data[1],sqrt(pow((float)accelerometer_data[0],2)+pow((float)accelerometer_data[2],2)))*180/3.1415; + angle_acc[2] = atan2(sqrt(pow((float)accelerometer_data[1],2)+pow((float)accelerometer_data[2],2)),accelerometer_data[2])*180/3.1415;*/ + +} +void mpu9250_spi::get_rate() +{ + uint8_t response[6]; + short offset_t[3]= {0,0,0}; + ReadRegs(MPUREG_GYRO_XOUT_H,response,6); + for(int i=0; i<3; i++) { + short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; + rate[i]=(double)(bit_data*0.01)-offset_t[i]; + //printf("%d",rate[i]); + } +} + +void mpu9250_spi::get_speedrate() +{ + uint8_t response[6]; + short offset_t[3]= {0,0,0}; + ReadRegs(MPUREG_ACCEL_XOUT_H,response,6); + for(int i=0; i<3; i++) { + short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; + ratespeed[i]=(short)(bit_data*0.01)-offset_t[i]; } } +void mpu9250_spi::get_angle(double *x,double *y,double *z) +{ + *x=(floor(angle[0]*100.0)/100.0); + *y=(floor(angle[1]*100.0)/100.0); + *z=(floor(angle[2]*100.0)/100.0); +} +void mpu9250_spi::set_angle() +{ + get_rate(); + read_acc(); + get_angle_acc(); + double S[3]; + angleT.stop(); + for(int i=0; i<3; i++) { + //rate[i]=gyroscope_data[i]*0.01; + double angA=angle_acc[i]; + S[i] =((double)(rate[i]+prev_rate[i])*angleT.read()/2); + // S[i]=(floor(S[i]*100.0)/100.0);//-offset_angle[i]; + angle[i]+=(floor(S[i]*10000.0)/10000.0);//-offset_angle[i]; + //angle[i]+=(double)S[i]; + Synthesis_angle[i]+=(double)angle[i]; + Synthesis_angle[i]=0.92*(double)(Synthesis_angle[i]+(double)rate[i])+0.08*angA; + kalman_angle[i]=kalma[i].getAngle((double)angA, (double)rate[i], (double)angleT.read_ms()); + comp_angle[i]=kalman_angle[i];//Synthesis_angle[i]*0.5+kalman_angle[i]*0+angle[i]*0.3+angle_acc[i]*0.2; + comp_angle[i]=kalman_angle[i]*0.4+Synthesis_angle[i]*0.4+comp_angle[i]*0.2; + prev_rate[i]=rate[i]; + } + angleT.reset(); + angleT.start(); +} +void mpu9250_spi::set_angleoffset() +{ + double axis[3],offseta[3]; + offseta[0]=offseta[1]=offseta[2]=0; + offset_angle[0]=0; + offset_angle[1]=0; + offset_angle[2]=0; + for(int i=0; i<sampleNum; i++) { + offseta[0]+=rate[0]; + offseta[1]+=rate[1]; + offseta[2]+=rate[2]; + } + offset_angle[0]=offseta[0]/sampleNum; + offset_angle[1]=offseta[1]/sampleNum; + offset_angle[2]=offseta[2]/sampleNum; + offset_angle[0]=(floor(offset_angle[0]*100.0)/100.0); + offset_angle[1]=(floor(offset_angle[1]*100.0)/100.0); + offset_angle[2]=(floor(offset_angle[2]*100.0)/100.0); + angle[0]=0; + angle[1]=0; + angle[2]=0; +} +void mpu9250_spi::set_noise() +{ + short gyro[3]; + noise[0]=noise[1]=noise[2]=0; + uint8_t response[6]; + for(int i=0; i<sampleNum; i++) { + + for(int t=0; t<3; t++) { + for(int i=0; i<3; i++) { + short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; + gyro[i]=(short)bit_data; + } + if((int)gyro[t]>noise[t]) + noise[t]=(int)gyro[t]; + else if((int)gyro[t]<-noise[t]) + noise[t]=-(int)gyro[t]; + } + } + noise[0]*=sampleTime; + noise[1]*=sampleTime; + noise[2]*=sampleTime; +} +void mpu9250_spi::set_offset() +{ + short axis[3],offseta[3]; + uint8_t response[6]; + offseta[0]=0; + offseta[1]=0; + offseta[2]=0; + for(int i=0; i<sampleNum; i++) { + for(int i=0; i<3; i++) { + short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; + axis[i]=(short)bit_data; + } + offseta[0]+=axis[0]; + offseta[1]+=axis[1]; + offseta[2]+=axis[2]; + } + offset[0]=offseta[0]/sampleNum; + offset[1]=offseta[1]/sampleNum; + offset[2]=offseta[2]/sampleNum; +} +mpu9250_spi::kalman::kalman(void) +{ + P[0][0] = 0; + P[0][1] = 0; + P[1][0] = 0; + P[1][1] = 0; + + angle = 0; + bias = 0; + + Q_angle = 0.001; + Q_gyroBias = 0.003; + R_angle = 0.03; +} + +double mpu9250_spi::kalman::getAngle(double newAngle, double newRate, double dt) +{ + //predict the angle according to the gyroscope + rate = newRate - bias; + angle = dt * rate; + //update the error covariance + P[0][0] += dt * (dt * P[1][1] * P[0][1] - P[1][0] + Q_angle); + P[0][1] -= dt * P[1][1]; + P[1][0] -= dt * P[1][1]; + P[1][1] += dt * Q_gyroBias; + //difference between the predicted angle and the accelerometer angle + y = newAngle - angle; + //estimation error + S = P[0][0] + R_angle; + //determine the kalman gain according to the error covariance and the distrust + K[0] = P[0][0]/S; + K[1] = P[1][0]/S; + //adjust the angle according to the kalman gain and the difference with the measurement + angle += K[0] * y; + bias += K[1] * y; + //update the error covariance + P[0][0] -= K[0] * P[0][0]; + P[0][1] -= K[0] * P[0][1]; + P[1][0] -= K[1] * P[0][0]; + P[1][1] -= K[1] * P[0][1]; + + return angle; +} +void mpu9250_spi::kalman::setAngle(double newAngle) +{ + angle = newAngle; +}; +void mpu9250_spi::kalman::setQangle(double newQ_angle) +{ + Q_angle = newQ_angle; +}; +void mpu9250_spi::kalman::setQgyroBias(double newQ_gyroBias) +{ + Q_gyroBias = newQ_gyroBias; +}; +void mpu9250_spi::kalman::setRangle(double newR_angle) +{ + R_angle = newR_angle; +}; + +double mpu9250_spi::kalman::getRate(void) +{ + return rate; +}; +double mpu9250_spi::kalman::getQangle(void) +{ + return Q_angle; +}; +double mpu9250_spi::kalman::getQbias(void) +{ + return Q_gyroBias; +}; +double mpu9250_spi::kalman::getRangle(void) +{ + return R_angle; +}; /*----------------------------------------------------------------------------------------------- SPI SELECT AND DESELECT usage: enable and disable mpu9250 communication bus -----------------------------------------------------------------------------------------------*/ -void mpu9250_spi::select() { +void mpu9250_spi::select() +{ //Set CS low to start transmission (interrupts conversion) cs = 0; } -void mpu9250_spi::deselect() { +void mpu9250_spi::deselect() +{ //Set CS high to stop transmission (restarts conversion) cs = 1; } \ No newline at end of file
diff -r 084e8ba240c1 -r a70c193d8195 MPU9250.h --- a/MPU9250.h Tue Jul 01 13:59:45 2014 +0000 +++ b/MPU9250.h Mon May 09 05:45:18 2016 +0000 @@ -18,7 +18,7 @@ unsigned int WriteReg( uint8_t WriteAddr, uint8_t WriteData ); unsigned int ReadReg( uint8_t WriteAddr, uint8_t WriteData ); void ReadRegs( uint8_t ReadAddr, uint8_t *ReadBuf, unsigned int Bytes ); - + void get_speedrate(); bool init(int sample_rate_div,int low_pass_filter); void read_temp(); void read_acc(); @@ -32,6 +32,9 @@ unsigned int whoami(); uint8_t AK8963_whoami(); void AK8963_read_Magnetometer(); + void AK8963_setoffset(int x,double offset); + double *AK8936_read_Orientation(double *getdata); + void read_all(); @@ -42,16 +45,111 @@ int calib_data[3]; float Magnetometer_ASA[3]; - float accelerometer_data[3]; + double accelerometer_data[3]; + double accelerometer_data_prev[3]; float Temperature; float gyroscope_data[3]; float Magnetometer[3]; - + float Magnetometer_offset[3]; + double speed[3]; + double meter[3]; + float angle_acc[3]; + short offset_gyro[3]; + short rate[3]; + + void set(float time=0.0001 , float time2=0.001){sampleTimeSpeed=time;sampleTimeMeter=time2;} + double freefallSpeedSet(); double freefallSpeedGet(); + double freefallMeterSet(); double freefallMeterGet(); + + void SpeedSet(); + void MeterSet(); + + void Filter(); + double VectolGet();double VectolSet(); + + void MPU_setup(); + void MPU_setnum(int Num=500,float time=0.0001,double rate=0.00390635);//set data member + + void get_angle_acc(); + void get_rate(); + void set_angle();//set always [time] + void newset_angle(double ANG_x,double ANG_y,double ANG_z); + void get_angle(double *x,double *y,double *z); + + void set_noise(); + void set_offset(); + void set_angleoffset(); + short ratespeed[3]; + short ratemeter[3]; + double Synthesis_speed[3],kalman_speed[3],comp_speed[3]; + double Synthesis_meter[3],kalman_meter[3],comp_meter[3]; + double angle[3],Synthesis_angle[3],kalman_angle[3],comp_angle[3]; private: PinName _CS_pin; PinName _SO_pin; PinName _SCK_pin; float _error; + Timer angleT; + Timer speedT; + Timer meterT; + + //ACC ADXL345 + int x_acc,y_acc,z_acc,sampleNum; + double x_offset,y_offset,z_offset; + float gx,gy,gz,xnoise,ynoise,znoise; + //GYALO L3GD20 + double Rate; + double sampleTime; + float noise[3]; + short offset[3];short prev_rate[3]; + + double t[3]; + short tempDATA_ACC[3],tempDATA_ANGLE[3]; + double offset_angle[3]; + + short prev_ratespeed[3],prev_speed[3]; + short prev_ratemeter[3],prev_meter[3]; + double real_acc[3]; + short acc[3]; + double filter_acc[3]; + + int sampleTimeSpeed,sampleTimeMeter; + + class kalman + { + public: + kalman(void); + double getAngle(double newAngle, double newRate, double dt); + + void setAngle(double newAngle); + void setQangle(double newQ_angle); + void setQgyroBias(double newQ_gyroBias); + void setRangle(double newR_angle); + + double getRate(void); + double getQangle(void); + double getQbias(void); + double getRangle(void); + + + private: + double P[2][2]; //error covariance matrix + double K[2]; //kalman gain + double y; //angle difference + double S; //estimation error + + double rate; //rate in deg/s + double angle; //kalman angle + double bias; //kalman gyro bias + + double Q_angle; //process noise variance for the angle of the accelerometer + double Q_gyroBias; //process noise variance for the gyroscope bias + double R_angle; //measurement noise variance + }; + kalman kalmaspeed[3]; + kalman kalmameter[3]; + //KALMAN + kalman kalma[3]; }; #endif