quadcopter cufe
/
2006_Theta_Control_yaw
Quadcopter Attitude Control(Yaw-Pitch-Roll)
AngularDataAcquizition.h@0:e63996fd7d3e, 2015-07-03 (annotated)
- Committer:
- khaledelmadawi
- Date:
- Fri Jul 03 11:16:02 2015 +0000
- Revision:
- 0:e63996fd7d3e
Quadcopter Attitude Control(Yaw-Pitch-Roll)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
khaledelmadawi | 0:e63996fd7d3e | 1 | #ifndef MBED_AngularDataAcquizition_H |
khaledelmadawi | 0:e63996fd7d3e | 2 | #define MBED_AngularDataAcquizition_H |
khaledelmadawi | 0:e63996fd7d3e | 3 | |
khaledelmadawi | 0:e63996fd7d3e | 4 | #include "I2Cdev.h" |
khaledelmadawi | 0:e63996fd7d3e | 5 | #include "mbed.h" |
khaledelmadawi | 0:e63996fd7d3e | 6 | #include "MPU6050_6Axis_MotionApps20.h" // works |
khaledelmadawi | 0:e63996fd7d3e | 7 | #include <math.h> |
khaledelmadawi | 0:e63996fd7d3e | 8 | |
khaledelmadawi | 0:e63996fd7d3e | 9 | #ifndef M_PI |
khaledelmadawi | 0:e63996fd7d3e | 10 | #define M_PI 3.1415 |
khaledelmadawi | 0:e63996fd7d3e | 11 | #endif |
khaledelmadawi | 0:e63996fd7d3e | 12 | #define D_BAUDRATE 115200 |
khaledelmadawi | 0:e63996fd7d3e | 13 | |
khaledelmadawi | 0:e63996fd7d3e | 14 | class AngularDataAcquizition{ |
khaledelmadawi | 0:e63996fd7d3e | 15 | public: |
khaledelmadawi | 0:e63996fd7d3e | 16 | AngularDataAcquizition(PinName D_SDA, PinName D_SCL); |
khaledelmadawi | 0:e63996fd7d3e | 17 | void BeginInterrupt(float InterruptDuration); |
khaledelmadawi | 0:e63996fd7d3e | 18 | void StopInterrupt(); |
khaledelmadawi | 0:e63996fd7d3e | 19 | void UpdateTheta(); |
khaledelmadawi | 0:e63996fd7d3e | 20 | void MeanValue(float *FilteredVal, int num); |
khaledelmadawi | 0:e63996fd7d3e | 21 | void FilterVariablesAquizition(float *variable,int number); |
khaledelmadawi | 0:e63996fd7d3e | 22 | void callMeanFilteredReadings(); |
khaledelmadawi | 0:e63996fd7d3e | 23 | |
khaledelmadawi | 0:e63996fd7d3e | 24 | float Meanypr[3]; |
khaledelmadawi | 0:e63996fd7d3e | 25 | bool dmpReady; // set true if DMP init was successful |
khaledelmadawi | 0:e63996fd7d3e | 26 | |
khaledelmadawi | 0:e63996fd7d3e | 27 | private: |
khaledelmadawi | 0:e63996fd7d3e | 28 | I2C _i2c; |
khaledelmadawi | 0:e63996fd7d3e | 29 | MPU6050 mpuLocal; |
khaledelmadawi | 0:e63996fd7d3e | 30 | Ticker timer; |
khaledelmadawi | 0:e63996fd7d3e | 31 | uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU |
khaledelmadawi | 0:e63996fd7d3e | 32 | uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) |
khaledelmadawi | 0:e63996fd7d3e | 33 | uint16_t packetSize; // expected DMP packet size (default is 42 bytes) |
khaledelmadawi | 0:e63996fd7d3e | 34 | uint16_t fifoCount; // count of all bytes currently in FIFO |
khaledelmadawi | 0:e63996fd7d3e | 35 | uint8_t fifoBuffer[64]; // FIFO storage buffer |
khaledelmadawi | 0:e63996fd7d3e | 36 | // orientation/motion vars |
khaledelmadawi | 0:e63996fd7d3e | 37 | Quaternion q; // [w, x, y, z] quaternion container |
khaledelmadawi | 0:e63996fd7d3e | 38 | VectorInt16 aa; // [x, y, z] accel sensor measurements |
khaledelmadawi | 0:e63996fd7d3e | 39 | VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements |
khaledelmadawi | 0:e63996fd7d3e | 40 | VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements |
khaledelmadawi | 0:e63996fd7d3e | 41 | VectorFloat gravity; // [x, y, z] gravity vector |
khaledelmadawi | 0:e63996fd7d3e | 42 | float euler[3]; // [psi, theta, phi] Euler angle container |
khaledelmadawi | 0:e63996fd7d3e | 43 | float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector |
khaledelmadawi | 0:e63996fd7d3e | 44 | Serial pc; |
khaledelmadawi | 0:e63996fd7d3e | 45 | // packet structure for InvenSense teapot demo |
khaledelmadawi | 0:e63996fd7d3e | 46 | uint8_t teapotPacket[15]; |
khaledelmadawi | 0:e63996fd7d3e | 47 | |
khaledelmadawi | 0:e63996fd7d3e | 48 | }; |
khaledelmadawi | 0:e63996fd7d3e | 49 | |
khaledelmadawi | 0:e63996fd7d3e | 50 | |
khaledelmadawi | 0:e63996fd7d3e | 51 | |
khaledelmadawi | 0:e63996fd7d3e | 52 | |
khaledelmadawi | 0:e63996fd7d3e | 53 | |
khaledelmadawi | 0:e63996fd7d3e | 54 | |
khaledelmadawi | 0:e63996fd7d3e | 55 | |
khaledelmadawi | 0:e63996fd7d3e | 56 | AngularDataAcquizition::AngularDataAcquizition(PinName D_SDA, PinName D_SCL): _i2c(D_SDA, D_SCL),pc(USBTX, USBRX) { |
khaledelmadawi | 0:e63996fd7d3e | 57 | dmpReady = false; |
khaledelmadawi | 0:e63996fd7d3e | 58 | teapotPacket[0] = '$',teapotPacket[1] = 0x02,teapotPacket[2] = 0,teapotPacket[3] = 0,teapotPacket[4] = 0,teapotPacket[5] = 0,teapotPacket[6] = 0, |
khaledelmadawi | 0:e63996fd7d3e | 59 | teapotPacket[7] = 0,teapotPacket[8] = 0,teapotPacket[9] = 0,teapotPacket[10] = 0x00,teapotPacket[11] = 0x00,teapotPacket[12] = '\r',teapotPacket[13] = '\n',teapotPacket[14] = 0 ; |
khaledelmadawi | 0:e63996fd7d3e | 60 | //Serial pc(USBTX, USBRX); // tx, rx |
khaledelmadawi | 0:e63996fd7d3e | 61 | |
khaledelmadawi | 0:e63996fd7d3e | 62 | pc.baud(D_BAUDRATE); |
khaledelmadawi | 0:e63996fd7d3e | 63 | // initialize device |
khaledelmadawi | 0:e63996fd7d3e | 64 | pc.printf("Initializing I2C devices...\n"); |
khaledelmadawi | 0:e63996fd7d3e | 65 | mpuLocal.initialize(); |
khaledelmadawi | 0:e63996fd7d3e | 66 | // verify connection |
khaledelmadawi | 0:e63996fd7d3e | 67 | pc.printf("Testing device connections...\n"); |
khaledelmadawi | 0:e63996fd7d3e | 68 | |
khaledelmadawi | 0:e63996fd7d3e | 69 | bool mpu6050TestResult = mpuLocal.testConnection(); |
khaledelmadawi | 0:e63996fd7d3e | 70 | if(mpu6050TestResult){ |
khaledelmadawi | 0:e63996fd7d3e | 71 | pc.printf("mpuLocalLocalLocal6050 test passed \n"); |
khaledelmadawi | 0:e63996fd7d3e | 72 | } else{ |
khaledelmadawi | 0:e63996fd7d3e | 73 | pc.printf("mpuLocalLocalLocal6050 test failed \n"); |
khaledelmadawi | 0:e63996fd7d3e | 74 | } |
khaledelmadawi | 0:e63996fd7d3e | 75 | |
khaledelmadawi | 0:e63996fd7d3e | 76 | // wait for ready |
khaledelmadawi | 0:e63996fd7d3e | 77 | pc.printf("\nSend any character to begin DMP programming and demo: "); |
khaledelmadawi | 0:e63996fd7d3e | 78 | |
khaledelmadawi | 0:e63996fd7d3e | 79 | //while(!pc.readable()); |
khaledelmadawi | 0:e63996fd7d3e | 80 | // pc.getc(); |
khaledelmadawi | 0:e63996fd7d3e | 81 | pc.printf("\n"); |
khaledelmadawi | 0:e63996fd7d3e | 82 | |
khaledelmadawi | 0:e63996fd7d3e | 83 | // load and configure the DMP |
khaledelmadawi | 0:e63996fd7d3e | 84 | pc.printf("Initializing DMP...\n"); |
khaledelmadawi | 0:e63996fd7d3e | 85 | devStatus = mpuLocal.dmpInitialize(); |
khaledelmadawi | 0:e63996fd7d3e | 86 | |
khaledelmadawi | 0:e63996fd7d3e | 87 | // supply your own gyro offsets here, scaled for min sensitivity |
khaledelmadawi | 0:e63996fd7d3e | 88 | mpuLocal.setXGyroOffset(-61); |
khaledelmadawi | 0:e63996fd7d3e | 89 | mpuLocal.setYGyroOffset(-127); |
khaledelmadawi | 0:e63996fd7d3e | 90 | mpuLocal.setZGyroOffset(19); |
khaledelmadawi | 0:e63996fd7d3e | 91 | mpuLocal.setZAccelOffset(16282); // 1688 factory default for my test chip |
khaledelmadawi | 0:e63996fd7d3e | 92 | |
khaledelmadawi | 0:e63996fd7d3e | 93 | // make sure it worked (returns 0 if so) |
khaledelmadawi | 0:e63996fd7d3e | 94 | if (devStatus == 0) { |
khaledelmadawi | 0:e63996fd7d3e | 95 | // turn on the DMP, now that it's ready |
khaledelmadawi | 0:e63996fd7d3e | 96 | pc.printf("Enabling DMP...\n"); |
khaledelmadawi | 0:e63996fd7d3e | 97 | mpuLocal.setDMPEnabled(true); |
khaledelmadawi | 0:e63996fd7d3e | 98 | |
khaledelmadawi | 0:e63996fd7d3e | 99 | // enable Arduino interrupt detection |
khaledelmadawi | 0:e63996fd7d3e | 100 | pc.printf("Enabling interrupt detection (Arduino external interrupt 0)...\n"); |
khaledelmadawi | 0:e63996fd7d3e | 101 | // attachInterrupt(0, dmpDataReady, RISING); |
khaledelmadawi | 0:e63996fd7d3e | 102 | mpuIntStatus = mpuLocal.getIntStatus(); |
khaledelmadawi | 0:e63996fd7d3e | 103 | |
khaledelmadawi | 0:e63996fd7d3e | 104 | // set our DMP Ready flag so the main loop() function knows it's okay to use it |
khaledelmadawi | 0:e63996fd7d3e | 105 | pc.printf("DMP ready! Waiting for first interrupt...\n"); |
khaledelmadawi | 0:e63996fd7d3e | 106 | dmpReady = true; |
khaledelmadawi | 0:e63996fd7d3e | 107 | |
khaledelmadawi | 0:e63996fd7d3e | 108 | // get expected DMP packet size for later comparison |
khaledelmadawi | 0:e63996fd7d3e | 109 | packetSize = mpuLocal.dmpGetFIFOPacketSize(); |
khaledelmadawi | 0:e63996fd7d3e | 110 | } else { |
khaledelmadawi | 0:e63996fd7d3e | 111 | // ERROR! |
khaledelmadawi | 0:e63996fd7d3e | 112 | // 1 = initial memory load failed |
khaledelmadawi | 0:e63996fd7d3e | 113 | // 2 = DMP configuration updates failed |
khaledelmadawi | 0:e63996fd7d3e | 114 | // (if it's going to break, usually the code will be 1) |
khaledelmadawi | 0:e63996fd7d3e | 115 | pc.printf("DMP Initialization failed (code "); |
khaledelmadawi | 0:e63996fd7d3e | 116 | pc.printf("%u",devStatus); |
khaledelmadawi | 0:e63996fd7d3e | 117 | pc.printf(")\n"); |
khaledelmadawi | 0:e63996fd7d3e | 118 | } |
khaledelmadawi | 0:e63996fd7d3e | 119 | |
khaledelmadawi | 0:e63996fd7d3e | 120 | |
khaledelmadawi | 0:e63996fd7d3e | 121 | } |
khaledelmadawi | 0:e63996fd7d3e | 122 | |
khaledelmadawi | 0:e63996fd7d3e | 123 | void AngularDataAcquizition::UpdateTheta(){ |
khaledelmadawi | 0:e63996fd7d3e | 124 | // reset interrupt flag and get INT_STATUS byte |
khaledelmadawi | 0:e63996fd7d3e | 125 | mpuIntStatus = mpuLocal.getIntStatus(); |
khaledelmadawi | 0:e63996fd7d3e | 126 | |
khaledelmadawi | 0:e63996fd7d3e | 127 | // get current FIFO count |
khaledelmadawi | 0:e63996fd7d3e | 128 | fifoCount = mpuLocal.getFIFOCount(); |
khaledelmadawi | 0:e63996fd7d3e | 129 | |
khaledelmadawi | 0:e63996fd7d3e | 130 | // check for overflow (this should never happen unless our code is too inefficient) |
khaledelmadawi | 0:e63996fd7d3e | 131 | if ((mpuIntStatus & 0x10) || fifoCount == 1024) { |
khaledelmadawi | 0:e63996fd7d3e | 132 | // reset so we can continue cleanly |
khaledelmadawi | 0:e63996fd7d3e | 133 | mpuLocal.resetFIFO(); |
khaledelmadawi | 0:e63996fd7d3e | 134 | pc.printf("FIFO overflow!"); |
khaledelmadawi | 0:e63996fd7d3e | 135 | |
khaledelmadawi | 0:e63996fd7d3e | 136 | // otherwise, check for DMP data ready interrupt (this should happen frequently) |
khaledelmadawi | 0:e63996fd7d3e | 137 | } else if (mpuIntStatus & 0x02) { |
khaledelmadawi | 0:e63996fd7d3e | 138 | // wait for correct available data length, should be a VERY short wait |
khaledelmadawi | 0:e63996fd7d3e | 139 | while (fifoCount < packetSize) fifoCount = mpuLocal.getFIFOCount(); |
khaledelmadawi | 0:e63996fd7d3e | 140 | |
khaledelmadawi | 0:e63996fd7d3e | 141 | // read a packet from FIFO |
khaledelmadawi | 0:e63996fd7d3e | 142 | mpuLocal.getFIFOBytes(fifoBuffer, packetSize); |
khaledelmadawi | 0:e63996fd7d3e | 143 | |
khaledelmadawi | 0:e63996fd7d3e | 144 | // track FIFO count here in case there is > 1 packet available |
khaledelmadawi | 0:e63996fd7d3e | 145 | // (this lets us immediately read more without waiting for an interrupt) |
khaledelmadawi | 0:e63996fd7d3e | 146 | fifoCount -= packetSize; |
khaledelmadawi | 0:e63996fd7d3e | 147 | // display Euler angles in degrees |
khaledelmadawi | 0:e63996fd7d3e | 148 | mpuLocal.dmpGetQuaternion(&q, fifoBuffer); |
khaledelmadawi | 0:e63996fd7d3e | 149 | mpuLocal.dmpGetGravity(&gravity, &q); |
khaledelmadawi | 0:e63996fd7d3e | 150 | mpuLocal.dmpGetYawPitchRoll(ypr, &q, &gravity); |
khaledelmadawi | 0:e63996fd7d3e | 151 | } |
khaledelmadawi | 0:e63996fd7d3e | 152 | } |
khaledelmadawi | 0:e63996fd7d3e | 153 | void AngularDataAcquizition::MeanValue(float *FilteredVal, int num){ |
khaledelmadawi | 0:e63996fd7d3e | 154 | int i,j; |
khaledelmadawi | 0:e63996fd7d3e | 155 | for(j=0;j<3;j++) |
khaledelmadawi | 0:e63996fd7d3e | 156 | FilteredVal[j]=0; |
khaledelmadawi | 0:e63996fd7d3e | 157 | for (i=0;i<num;i++){ |
khaledelmadawi | 0:e63996fd7d3e | 158 | UpdateTheta(); |
khaledelmadawi | 0:e63996fd7d3e | 159 | for(j=0;j<3;j++) |
khaledelmadawi | 0:e63996fd7d3e | 160 | FilteredVal[j]=FilteredVal[j]+ypr[j]; |
khaledelmadawi | 0:e63996fd7d3e | 161 | } |
khaledelmadawi | 0:e63996fd7d3e | 162 | for(j=0;j<3;j++) |
khaledelmadawi | 0:e63996fd7d3e | 163 | FilteredVal[j]=FilteredVal[j]/num; |
khaledelmadawi | 0:e63996fd7d3e | 164 | } |
khaledelmadawi | 0:e63996fd7d3e | 165 | void AngularDataAcquizition::callMeanFilteredReadings(){ |
khaledelmadawi | 0:e63996fd7d3e | 166 | MeanValue(Meanypr,20); |
khaledelmadawi | 0:e63996fd7d3e | 167 | Meanypr[1]=Meanypr[1]-(1.19284-0.00716-0.7679)*3.14/180; |
khaledelmadawi | 0:e63996fd7d3e | 168 | Meanypr[2]=Meanypr[2]-(-0.96533+0.021043+0.107681)*3.14/180; |
khaledelmadawi | 0:e63996fd7d3e | 169 | |
khaledelmadawi | 0:e63996fd7d3e | 170 | } |
khaledelmadawi | 0:e63996fd7d3e | 171 | void AngularDataAcquizition::BeginInterrupt(float InterruptDuration){ |
khaledelmadawi | 0:e63996fd7d3e | 172 | if(dmpReady) |
khaledelmadawi | 0:e63996fd7d3e | 173 | timer.attach(this,&AngularDataAcquizition::callMeanFilteredReadings, InterruptDuration); |
khaledelmadawi | 0:e63996fd7d3e | 174 | } |
khaledelmadawi | 0:e63996fd7d3e | 175 | void AngularDataAcquizition::StopInterrupt(){ |
khaledelmadawi | 0:e63996fd7d3e | 176 | if(dmpReady) |
khaledelmadawi | 0:e63996fd7d3e | 177 | timer.detach(); |
khaledelmadawi | 0:e63996fd7d3e | 178 | } |
khaledelmadawi | 0:e63996fd7d3e | 179 | |
khaledelmadawi | 0:e63996fd7d3e | 180 | #endif |
khaledelmadawi | 0:e63996fd7d3e | 181 |