Crude navigation
Dependencies: GPS L3GD20 LSM303DLHC mbed PID
modSensData.h
- Committer:
- Spilly
- Date:
- 2015-03-17
- Revision:
- 4:a397b44a0fe8
- Parent:
- 3:ffa0e1429a72
File content as of revision 4:a397b44a0fe8:
#include "mbed.h" #include "math.h" #include "L3GD20.h" #include "LSM303DLHC.h" L3GD20 gyro(PTE25, PTE24); LSM303DLHC compass(PTE25, PTE24); #define M_PI 3.1415926535897932384626433832795f #define TWO_PI 6.283185307179586476925286766559f #define RADTODEGREE 57.295779513082320876798154814105f #define GRAVITY 1.0f #define THRESHOLD 1.1f // "accel x,y,z (min/max) = X_MIN/X_MAX Y_MIN/Y_MAX Z_MIN/Z_MAX" #define ACCEL_X_MIN ((float) -276) #define ACCEL_X_MAX ((float) 236) #define ACCEL_Y_MIN ((float) -261) #define ACCEL_Y_MAX ((float) 245) #define ACCEL_Z_MIN ((float) -284) #define ACCEL_Z_MAX ((float) 220) // "magn x,y,z (min/max) = X_MIN/X_MAX Y_MIN/Y_MAX Z_MIN/Z_MAX" #define MAGN_X_MIN (-0.370909f) #define MAGN_X_MAX (0.569091f) #define MAGN_Y_MIN (-0.516364f) #define MAGN_Y_MAX (0.392727f) #define MAGN_Z_MIN (-0.618367f) #define MAGN_Z_MAX (0.408163f) // Sensor calibration scale and offset values #define ACCEL_X_OFFSET ((ACCEL_X_MIN + ACCEL_X_MAX) / 2.0f) #define ACCEL_Y_OFFSET ((ACCEL_Y_MIN + ACCEL_Y_MAX) / 2.0f) #define ACCEL_Z_OFFSET ((ACCEL_Z_MIN + ACCEL_Z_MAX) / 2.0f) #define ACCEL_X_SCALE (GRAVITY / (ACCEL_X_MAX - ACCEL_X_OFFSET)) #define ACCEL_Y_SCALE (GRAVITY / (ACCEL_Y_MAX - ACCEL_Y_OFFSET)) #define ACCEL_Z_SCALE (GRAVITY / (ACCEL_Z_MAX - ACCEL_Z_OFFSET)) #define MAGN_X_OFFSET ((MAGN_X_MIN + MAGN_X_MAX) / 2.0f) #define MAGN_Y_OFFSET ((MAGN_Y_MIN + MAGN_Y_MAX) / 2.0f) #define MAGN_Z_OFFSET ((MAGN_Z_MIN + MAGN_Z_MAX) / 2.0f) #define MAGN_X_SCALE (100.0f / (MAGN_X_MAX - MAGN_X_OFFSET)) #define MAGN_Y_SCALE (100.0f / (MAGN_Y_MAX - MAGN_Y_OFFSET)) #define MAGN_Z_SCALE (100.0f / (MAGN_Z_MAX - MAGN_Z_OFFSET)) //calibrated reading = (reading - offset) * scale Timer t1; float vC[3], cC[3], magnetom[3], inertialAccel[3]; float aP[3], vP[3], cP[3], deltaT, timeStamp, degGyro[3], angPos[3], prevAngPos[3]; double roll = 0, pitch = 0, yaw = 0; float magCheck; float accel[3], bias[3], magnDiff; int printStamp = 0, stopStamp = 0, dangerAhead = 0, howLong = 0, count[3], pos[5][3]= { {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} }; int flag = 0, signBit = 0; /********************************************************************************************************************************/ // Get Accelerometer and Magnetometer Data /********************************************************************************************************************************/ void readIMU() { compass.read(&accel[0], &accel[1], &accel[2], &magnetom[0], &magnetom[1], &magnetom[2]); //Compensate magnetometer error //magnetom[0] -= MAGN_X_OFFSET; //magnetom[1] -= MAGN_Y_OFFSET; //magnetom[2] -= MAGN_Z_OFFSET; //Compensate accelerometer error //accel[0] = (accel[0] - ACCEL_X_OFFSET) * ACCEL_X_SCALE; //accel[1] = (accel[1] - ACCEL_Y_OFFSET) * ACCEL_Y_SCALE; //accel[2] = (accel[2] - ACCEL_Z_OFFSET) * ACCEL_Z_SCALE; gyro.read(°Gyro[0], °Gyro[1], °Gyro[2]); } /********************************************************************************************************************************/ // Compass Heading /********************************************************************************************************************************/ void Compass_Heading() { float mag_x; float mag_y; float cos_roll; float sin_roll; float cos_pitch; float sin_pitch; //saves a few processor cycles by calculating and storing values cos_roll = cos(roll); sin_roll = sin(roll); cos_pitch = cos(pitch); sin_pitch = sin(pitch); // Tilt compensated magnetic field X mag_x = magnetom[0] * cos_pitch + magnetom[1] * sin_roll * sin_pitch + magnetom[2] * cos_roll * sin_pitch; // Tilt compensated magnetic field Y mag_y = magnetom[1] * cos_roll - magnetom[2] * sin_roll; // Magnetic Heading yaw = atan2(-mag_x, mag_y); //make negative angles positive if(yaw < 0) yaw = yaw + TWO_PI; yaw = yaw * RADTODEGREE; } /********************************************************************************************************************************/ // getAttitude /********************************************************************************************************************************/ void getAttitude() { float temp1[3]; float temp2[3]; float xAxis[3] = {1.0f, 0.0f, 0.0f}; // GET PITCH // Using y-z-plane-component/x-component of gravity vector pitch = -atan2(accel[0], sqrt((accel[1] * accel[1]) + (accel[2] * accel[2]))); //printf("P = %f", pitch); // GET ROLL // Compensate pitch of gravity vector temp1[0] = (accel[1] * xAxis[2]) - (accel[2] * xAxis[1]); temp1[1] = (accel[2] * xAxis[0]) - (accel[0] * xAxis[2]); temp1[2] = (accel[0] * xAxis[1]) - (accel[1] * xAxis[0]); temp2[0] = (xAxis[1] * temp1[2]) - (xAxis[2] * temp1[1]); temp2[1] = (xAxis[2] * temp1[0]) - (xAxis[0] * temp1[2]); temp2[2] = (xAxis[0] * temp1[1]) - (xAxis[1] * temp1[0]); // Since we compensated for pitch, x-z-plane-component equals z-component: roll = atan2(temp2[1], temp2[2]); } /********************************************************************************************************************************/ // rotateBTI /********************************************************************************************************************************/ //rotation from the body frame to the inertial frame void rotateBTI() { float cos_roll, sin_roll, cos_pitch, sin_pitch, cos_yaw, sin_yaw; float gravity[3] = {0, 0, -GRAVITY}; float rIB[3][3]; //saves a few processor cycles by calculating and storing values //Serial.print("Roll"); cos_roll = cos(roll); //Serial.print(cos_roll, 4); //Serial.print(" "); sin_roll = sin(roll); //Serial.print(sin_roll, 4); //Serial.print(" "); //Serial.print("Pitch"); cos_pitch = cos(pitch); //Serial.print(cos_pitch, 4); //Serial.print(" "); sin_pitch = sin(pitch); //Serial.print(sin_pitch, 4); //Serial.print(" "); //Serial.print("YAW"); cos_yaw = cos(yaw); //Serial.print(cos_yaw, 4); //Serial.print(" "); sin_yaw = sin(yaw); //Serial.print(sin_yaw, 4); //Serial.print(" "); rIB[0][0] = cos_yaw * cos_pitch; rIB[0][1] = (cos_yaw * sin_roll * sin_pitch) - (cos_roll * sin_yaw); rIB[0][2] = (sin_roll * sin_yaw) + (cos_roll * cos_yaw * sin_pitch); rIB[1][0] = cos_pitch * sin_yaw; rIB[1][1] = (cos_roll * cos_yaw) + (sin_roll * sin_yaw * sin_pitch); rIB[1][2] = (cos_roll * sin_yaw * sin_pitch) - (cos_yaw * sin_roll); rIB[2][0] = -1 * sin_pitch; rIB[2][1] = cos_pitch * sin_roll; rIB[2][2] = cos_roll * cos_pitch; for(int i = 0; i < 3; i++) { aP[i] = inertialAccel[i]; inertialAccel[i] = rIB[i][0] * accel[0] + rIB[i][1] * accel[1] + rIB[i][2] * accel[2]; inertialAccel[i] = inertialAccel[i] + gravity[i]; } } int updateAngles() { readIMU(); if((sqrt(accel[0] * accel[0]) <= THRESHOLD) && (sqrt(accel[1] * accel[1]) <= THRESHOLD) && (sqrt(accel[2] * accel[2]) <= THRESHOLD)) { //float prevYaw = yaw; getAttitude(); Compass_Heading(); //float absOfYawDiff = sqrt((prevYaw - yaw) * (prevYaw - yaw)); //check for noise //if((absOfYawDiff >= 30) && (absOfYawDiff <= (360.0f - 30))) //{ return 1; //} //return 0; } return 0; //rotateBTI(); } float getGyro() { float gx, gy, gz; gyro.read(&gx,&gy,&gz); return gz; }