Source code for Active Aerodynamics and Drag Reduction System
Dependencies: mbed Servo mbed-rtos LSM9DS1_Library_cal MPL3115A2
main.cpp
- Committer:
- skiley6
- Date:
- 2020-04-22
- Revision:
- 3:4b9d098dcb04
- Parent:
- 2:426f26e9801d
- Child:
- 4:8442a7d55f23
File content as of revision 3:4b9d098dcb04:
#include "mbed.h" #include "rtos.h" #include "Servo.h" #include "LSM9DS1.h" #define PI 3.14159 // Used in IMU code #define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA (Used in IMU code) // SETUP Servo servoFR(p21); Servo servoFL(p22); Servo servoRR(p23); Servo servoRL(p24); LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); RawSerial blue(p13,p14); // bluetooth Serial pc(USBTX, USBRX); // tx, rx //BusOut myled(LED1,LED2,LED3,LED4); //bluetooth debugging DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); //THREADS Thread blueRXThread; Thread blueTXThread; Thread IMUThread; Thread servoThread; // VARIABLE DECLARATIONS volatile float YawRate; enum statetype {Off = 0, Testing, DRS_Active, Active_Yaw, Active_Roll}; volatile statetype servoState = Off; // FUNCTION DECLARATIONS void blueRX() { char bnum=0; char bhit=0; while(1) { if (blue.readable()) { //if not ready with a character yield time slice! if (blue.getc()=='!') { //getc is one character only! //since GUI button sends all characters in string fast don't need to do //readable each time, but can if you wanted to if (blue.getc()=='B') { //button data bnum = blue.getc(); //button number bhit = blue.getc(); //save to check for '1' for hit only - ignored release is '0' switch (bnum) { case '1': //number button 1 - DRS Enabled if (bhit=='1') { if(servoState == DRS_Active) { servoState = Off; } else { servoState = DRS_Active; } } else { } break; case '2': //number button 2 - Active Aero Yaw Based if (bhit=='1') { if(servoState == Active_Yaw) { servoState = Off; } else { servoState = Active_Yaw; } } else { } break; case '3': //number button 3 - Active Aero Roll Based if (bhit=='1') { if(servoState == Active_Roll) { servoState = Off; } else { servoState = Active_Roll; } } else { } break; case '4': //number button 4 - Testing Flaps if (bhit=='1') { servoState = Testing; } else { } break; default: } } } } else Thread::yield();// give up rest of time slice when no characters to read } } void blueTX() { //float value; while(1) { //Send data blue.printf("%f\n", YawRate); //value+=1.0; led1 = !led1; Thread::wait(200); } } // IMU - caluclate pitch and roll void printAttitude(float ax, float ay, float az, float mx, float my, float mz) { float roll = atan2(ay, az); float pitch = atan2(-ax, sqrt(ay * ay + az * az)); // touchy trig stuff to use arctan to get compass heading (scale is 0..360) mx = -mx; float heading; if (my == 0.0) heading = (mx < 0.0) ? 180.0 : 0.0; else heading = atan2(mx, my)*360.0/(2.0*PI); //pc.printf("heading atan=%f \n\r",heading); heading -= DECLINATION; //correct for geo location if(heading>180.0) heading = heading - 360.0; else if(heading<-180.0) heading = 360.0 + heading; else if(heading<0.0) heading = 360.0 + heading; // Convert everything from radians to degrees: //heading *= 180.0 / PI; pitch *= 180.0 / PI; roll *= 180.0 / PI; pc.printf("Pitch: %f, Roll: %f degress\n\r",pitch,roll); pc.printf("Magnetic Heading: %f degress\n\r",heading); } // IMU - read and display magnetometer, gyroscope, acceleration values void getIMUData() { while(1) { while(!IMU.gyroAvailable()); IMU.readGyro(); YawRate = IMU.calcGyro(IMU.gz); Thread::wait(50); } /* while(!IMU.magAvailable(X_AXIS)); IMU.readMag(); while(!IMU.accelAvailable()); IMU.readAccel(); while(!IMU.gyroAvailable()); IMU.readGyro(); pc.printf(" X axis Y axis Z axis\n\r"); pc.printf("gyro: %9f %9f %9f in deg/s\n\r", IMU.calcGyro(IMU.gx), IMU.calcGyro(IMU.gy), IMU.calcGyro(IMU.gz)); pc.printf("accel: %9f %9f %9f in Gs\n\r", IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az)); pc.printf("mag: %9f %9f %9f in gauss\n\r", IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz)); printAttitude(IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az), IMU.calcMag(IMU.mx),IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz)); zAccel = IMU.calcAccel(IMU.az);//setting global variable for storage of z-Axis acceleration yAccel = IMU.calcAccel(IMU.ay); xAccel = IMU.calcAccel(IMU.ax); */ } void setServos() { uint32_t testSpeed = 20; float testPrec = 0.05; while(1) { switch(servoState) { case Off: //close all flaps servoFR = 0.5; servoFL = 0.5; servoRR = 0.5; servoRL = 0.5; Thread::wait(250); //longer wait because of Off state break; case Testing: servoFR = 0; servoFL = 1; servoRR = 0; servoRL = 1; Thread::wait(500); for(float i=0; i<0.5; i+= testPrec) { servoFR = i; servoRR = i; Thread::wait(testSpeed); } for(float i=0.5; i>0; i-= testPrec) { servoFR = i; servoRR = i; Thread::wait(testSpeed); } for(float i=0; i<0.5; i+= testPrec) { servoFL = 1 - i; servoRL = 1 - i; Thread::wait(testSpeed); } for(float i=0.5; i>0; i-= testPrec) { servoFL = 1 - i; servoRL = 1 - i; Thread::wait(testSpeed); } for(float i=0; i<0.5; i+= testPrec) { servoFR = i; servoRR = i; servoFL = 1 - i; servoRL = 1 - i; Thread::wait(testSpeed); } for(float i=.5; i>0; i-= testPrec) { servoFR = i; servoRR = i; servoFL = 1 - i; servoRL = 1 - i; Thread::wait(testSpeed); } servoState = Off; break; case DRS_Active: servoFR = 0.25; servoFL = 1 - 0.25; servoRR = 0; servoRL = 1 - 0;; Thread::wait(250); break; case Active_Yaw: float tempFront = 0.0; float tempRear = 0.0; float newFront = 0.0; float newRear = 0.0; tempFront = YawRate/200; //divide to get into 0 -> 0.5 range for front wings tempRear = YawRate/400; //divide to get into 0 -> 0.25 range for rear wings if(YawRate >= 10) //if turning Left { newFront = 0.5 - tempFront; //open up right flaps newRear = 0.25 - tempRear; if(newFront < 0) { servoFR = 0; servoRR = 0.25; } else { servoFR = newFront; servoRR = newRear; } servoFL = 0.5; //keep left side closed servoRL = 0.5; } else if(YawRate <= -10) // if turning Right { newFront = 1 - (0.5 + tempFront); // open up left flaps newRear = 1 - (0.5 + tempRear); if(newFront < 0) { servoFL = 1 - 0; servoRL = 1 - 0.25; } else { servoFL = newFront; servoRL = newRear; } servoFR = 0.5; // keep right side closed servoRR = 0.5; } else { servoFR = 0.5; //set all to closed servoFL = 0.5; servoRR = 0.5; servoRL = 0.5; } Thread::wait(25); break; case Active_Roll: break; default: } } } int main() { // initialise IMU IMU.begin(); if (!IMU.begin()) { pc.printf("Failed to communicate with LSM9DS1.\n"); } //IMU.calibrate(1); //IMU.calibrateMag(0); blue.baud(9600); //set baud rate for UART window blueRXThread.start(blueRX); blueTXThread.start(blueTX); IMUThread.start(getIMUData); servoThread.start(setServos); while(1) { } }