Sensor library for quadcopter

Dependencies:   MotionDriverv512

Committer:
oprospero
Date:
Fri Jun 13 18:27:35 2014 +0000
Revision:
2:dae13ba06097
Parent:
1:fe68e0f86ecf
Child:
3:e658293d4b83
Refit for quadCommand; Add lower boundary for fifo reset

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oprospero 0:5c097bb1300f 1
oprospero 0:5c097bb1300f 2 #include "Sensor.h"
oprospero 0:5c097bb1300f 3 #ifdef DEBUG_S
oprospero 0:5c097bb1300f 4 #include "mbed.h"
oprospero 0:5c097bb1300f 5 Serial p(USBTX, USBRX);
oprospero 0:5c097bb1300f 6 Timer td;
oprospero 0:5c097bb1300f 7 int printCounter = 0;
oprospero 0:5c097bb1300f 8 int tIntStatus = 0;
oprospero 0:5c097bb1300f 9 int tgetFIFOCount = 0;
oprospero 0:5c097bb1300f 10 int tgetFIFOCheck = 0;
oprospero 0:5c097bb1300f 11 int tgetFIFOreset = 0;
oprospero 0:5c097bb1300f 12 int tgetFIFOBytes = 0;
oprospero 0:5c097bb1300f 13 int teulars = 0;
oprospero 0:5c097bb1300f 14 #define NL "\n\r"
oprospero 0:5c097bb1300f 15 #define PRINT(x) p.printf(x) //Serial.print(x)
oprospero 0:5c097bb1300f 16 #define PRINTF p.printf //Serial.print(x, y)
oprospero 0:5c097bb1300f 17 #define PRINTLN(x) PRINT(x);PRINT(NL)
oprospero 0:5c097bb1300f 18 #define START td.start();
oprospero 0:5c097bb1300f 19 #define STOP td.stop()
oprospero 0:5c097bb1300f 20 #define RESET td.reset()
oprospero 0:5c097bb1300f 21 #define READ td.read_us()
oprospero 0:5c097bb1300f 22 #define GET(x) x = READ
oprospero 0:5c097bb1300f 23 #else
oprospero 0:5c097bb1300f 24 #define PRINT(x)
oprospero 0:5c097bb1300f 25 #define PRINTF(x, y)
oprospero 0:5c097bb1300f 26 #define PRINTLN(x)
oprospero 0:5c097bb1300f 27 #define START
oprospero 0:5c097bb1300f 28 #define STOP
oprospero 0:5c097bb1300f 29 #define RESET
oprospero 0:5c097bb1300f 30 #define READ
oprospero 0:5c097bb1300f 31 #define GET(x)
oprospero 0:5c097bb1300f 32 #endif
oprospero 0:5c097bb1300f 33
oprospero 0:5c097bb1300f 34
oprospero 0:5c097bb1300f 35 Sensor::Sensor() : dmp()
oprospero 0:5c097bb1300f 36 {
oprospero 2:dae13ba06097 37 gyro_orientation[0] = 1;
oprospero 0:5c097bb1300f 38 gyro_orientation[1] = 0;
oprospero 0:5c097bb1300f 39 gyro_orientation[2] = 0;
oprospero 0:5c097bb1300f 40 gyro_orientation[3] = 0;
oprospero 2:dae13ba06097 41 gyro_orientation[4] = 1;
oprospero 0:5c097bb1300f 42 gyro_orientation[5] = 0;
oprospero 0:5c097bb1300f 43 gyro_orientation[6] = 0;
oprospero 0:5c097bb1300f 44 gyro_orientation[7] = 0;
oprospero 0:5c097bb1300f 45 gyro_orientation[8] = 1;
oprospero 0:5c097bb1300f 46 //InvMpu mpu;
oprospero 0:5c097bb1300f 47 }
oprospero 0:5c097bb1300f 48
oprospero 0:5c097bb1300f 49 int Sensor::initialize()
oprospero 0:5c097bb1300f 50 {
oprospero 0:5c097bb1300f 51 int result = 0;
oprospero 1:fe68e0f86ecf 52 result = mpu_initialize();
oprospero 1:fe68e0f86ecf 53 if (result) return result;
oprospero 2:dae13ba06097 54 result = dmp_initialize();
oprospero 2:dae13ba06097 55 run_self_test();
oprospero 1:fe68e0f86ecf 56 return 0;
oprospero 0:5c097bb1300f 57 }
oprospero 0:5c097bb1300f 58
oprospero 0:5c097bb1300f 59 int Sensor::mpu_initialize()
oprospero 0:5c097bb1300f 60 {
oprospero 0:5c097bb1300f 61 unsigned char accel_fsr;
oprospero 0:5c097bb1300f 62 unsigned short gyro_rate, gyro_fsr;
oprospero 0:5c097bb1300f 63 long accel_bias[3], gyro_bias[3];
oprospero 1:fe68e0f86ecf 64 if( !dmp.testConnection() )
oprospero 1:fe68e0f86ecf 65 return -1;
oprospero 1:fe68e0f86ecf 66 if( dmp.mpu_init() )
oprospero 1:fe68e0f86ecf 67 return -2;
oprospero 0:5c097bb1300f 68 /* Get/set hardware configuration. Start gyro. */
oprospero 0:5c097bb1300f 69 /* Wake up all sensors. */
oprospero 1:fe68e0f86ecf 70 if( dmp.mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL) )
oprospero 1:fe68e0f86ecf 71 return -3;
oprospero 0:5c097bb1300f 72 /* Push both gyro and accel data into the FIFO. */
oprospero 1:fe68e0f86ecf 73 if( dmp.mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL) )
oprospero 1:fe68e0f86ecf 74 return -4;
oprospero 1:fe68e0f86ecf 75 if( dmp.mpu_set_sample_rate(SAMPLE_RATE) )
oprospero 1:fe68e0f86ecf 76 return -5;
oprospero 0:5c097bb1300f 77 /* Read back configuration in case it was set improperly. */
oprospero 0:5c097bb1300f 78 dmp.mpu_get_sample_rate(&gyro_rate);
oprospero 0:5c097bb1300f 79 dmp.mpu_get_gyro_fsr(&gyro_fsr);
oprospero 0:5c097bb1300f 80 dmp.mpu_get_accel_fsr(&accel_fsr);
oprospero 0:5c097bb1300f 81
oprospero 0:5c097bb1300f 82 if( !(gyro_rate == SAMPLE_RATE && gyro_fsr == 2000 && accel_fsr == 2) )
oprospero 1:fe68e0f86ecf 83 return -6;
oprospero 2:dae13ba06097 84
oprospero 1:fe68e0f86ecf 85 return 0;
oprospero 0:5c097bb1300f 86 }
oprospero 0:5c097bb1300f 87
oprospero 0:5c097bb1300f 88 int Sensor::dmp_initialize()
oprospero 0:5c097bb1300f 89 {
oprospero 0:5c097bb1300f 90 // Instruction via MotionDriver_Tutorial
oprospero 1:fe68e0f86ecf 91 if( dmp.dmp_load_motion_driver_firmware() )
oprospero 1:fe68e0f86ecf 92 return -8;
oprospero 0:5c097bb1300f 93 unsigned short temp = dmp.inv_orientation_matrix_to_scalar(gyro_orientation);
oprospero 1:fe68e0f86ecf 94 if( dmp.dmp_set_orientation(temp) )
oprospero 1:fe68e0f86ecf 95 return -9;
oprospero 0:5c097bb1300f 96 // unsigned short mask = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL | DMP_FEATURE_SEND_RAW_ACCEL ;
oprospero 0:5c097bb1300f 97 unsigned short mask = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL ;
oprospero 1:fe68e0f86ecf 98 // unsigned short mask = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_SEND_CAL_GYRO;
oprospero 1:fe68e0f86ecf 99 if( dmp.dmp_enable_feature(mask) )
oprospero 1:fe68e0f86ecf 100 return -10;
oprospero 1:fe68e0f86ecf 101 if( dmp.mpu_set_sample_rate(200) )
oprospero 1:fe68e0f86ecf 102 return -11;
oprospero 1:fe68e0f86ecf 103 if( dmp.dmp_set_fifo_rate(100) )
oprospero 1:fe68e0f86ecf 104 return -12;
oprospero 1:fe68e0f86ecf 105 if( dmp.mpu_set_dmp_state(1) )
oprospero 1:fe68e0f86ecf 106 return -13;
oprospero 2:dae13ba06097 107 // if( dmp.mpu_set_lpf(188) )
oprospero 2:dae13ba06097 108 // return -14;
oprospero 1:fe68e0f86ecf 109 return 0;
oprospero 0:5c097bb1300f 110 }
oprospero 0:5c097bb1300f 111
oprospero 0:5c097bb1300f 112
oprospero 0:5c097bb1300f 113 void Sensor::run_self_test()
oprospero 0:5c097bb1300f 114 {
oprospero 0:5c097bb1300f 115 int result;
oprospero 0:5c097bb1300f 116 long gyro_cal[3], accel_cal[3];
oprospero 0:5c097bb1300f 117 unsigned char i = 0;
oprospero 0:5c097bb1300f 118
oprospero 0:5c097bb1300f 119 result = dmp.mpu_run_self_test(gyro_cal, accel_cal);
oprospero 0:5c097bb1300f 120 if (result == 0x7) {
oprospero 0:5c097bb1300f 121 /* Test passed. We can trust the gyro data here, so let's push it down
oprospero 0:5c097bb1300f 122 * to the DMP.
oprospero 0:5c097bb1300f 123 */
oprospero 0:5c097bb1300f 124 for(i = 0; i<3; i++) {
oprospero 0:5c097bb1300f 125 gyro_cal[i] = (long)(gyro_cal[i] * 32.8f); //convert to +-1000dps
oprospero 0:5c097bb1300f 126 accel_cal[i] *= 4096.f; //convert to +-8G
oprospero 0:5c097bb1300f 127 accel_cal[i] = accel[i] >> 16;
oprospero 0:5c097bb1300f 128 gyro_cal[i] = (long)(gyro_cal[i] >> 16);
oprospero 0:5c097bb1300f 129 }
oprospero 0:5c097bb1300f 130 dmp.mpu_set_gyro_bias_reg(gyro_cal);
oprospero 0:5c097bb1300f 131 dmp.mpu_set_accel_bias_6050_reg(accel_cal);
oprospero 0:5c097bb1300f 132 }
oprospero 0:5c097bb1300f 133 }
oprospero 0:5c097bb1300f 134
oprospero 0:5c097bb1300f 135 int Sensor::updateAngles()
oprospero 0:5c097bb1300f 136 {
oprospero 2:dae13ba06097 137 int result = false;
oprospero 0:5c097bb1300f 138 long quat[4];
oprospero 0:5c097bb1300f 139 unsigned char more;
oprospero 0:5c097bb1300f 140 short sensors;
oprospero 0:5c097bb1300f 141 result = dmp.dmp_read_fifo(gyro, accel, quat, NULL, &sensors, &more);
oprospero 2:dae13ba06097 142 while (result == -2)
oprospero 2:dae13ba06097 143 {
oprospero 2:dae13ba06097 144 result = dmp.dmp_read_fifo(gyro, accel, quat, NULL, &sensors, &more);
oprospero 2:dae13ba06097 145 }
oprospero 0:5c097bb1300f 146 if (result == 0)
oprospero 0:5c097bb1300f 147 {
oprospero 0:5c097bb1300f 148 q.set(quat);
oprospero 0:5c097bb1300f 149 dmp.dmpGetGravity(&gravity,&q);
oprospero 0:5c097bb1300f 150 dmp.dmpGetYawPitchRoll(ypr,&q,&gravity);
oprospero 0:5c097bb1300f 151 }
oprospero 0:5c097bb1300f 152 // PRINTF("More: %d\n\r",more);
oprospero 2:dae13ba06097 153 if (more > 4) dmp.mpu_reset_fifo();
oprospero 0:5c097bb1300f 154 return more;
oprospero 0:5c097bb1300f 155 }
oprospero 0:5c097bb1300f 156
oprospero 0:5c097bb1300f 157 float Sensor::getPitch()
oprospero 0:5c097bb1300f 158 {
oprospero 0:5c097bb1300f 159 return ypr[1] * RAD2DEG;
oprospero 0:5c097bb1300f 160 }
oprospero 0:5c097bb1300f 161 float Sensor::getRoll()
oprospero 0:5c097bb1300f 162 {
oprospero 0:5c097bb1300f 163 return ypr[2] * RAD2DEG;
oprospero 0:5c097bb1300f 164 }
oprospero 0:5c097bb1300f 165 float Sensor::getYaw()
oprospero 0:5c097bb1300f 166 {
oprospero 0:5c097bb1300f 167 return ypr[0] * RAD2DEG;
oprospero 0:5c097bb1300f 168 }
oprospero 0:5c097bb1300f 169
oprospero 0:5c097bb1300f 170 float Sensor::getGyroPitch()
oprospero 0:5c097bb1300f 171 {
oprospero 2:dae13ba06097 172 return gyro[0] * GYRO_GAIN;
oprospero 0:5c097bb1300f 173 }
oprospero 0:5c097bb1300f 174 float Sensor::getGyroRoll()
oprospero 0:5c097bb1300f 175 {
oprospero 2:dae13ba06097 176 return gyro[1] * GYRO_GAIN;
oprospero 0:5c097bb1300f 177 }
oprospero 0:5c097bb1300f 178 float Sensor::getGyroYaw()
oprospero 0:5c097bb1300f 179 {
oprospero 2:dae13ba06097 180 return gyro[2] * GYRO_GAIN;
oprospero 0:5c097bb1300f 181 }