Eurobot2012_Primary

Dependencies:   mbed Eurobot_2012_Primary

Revision:
1:bbabbd997d21
Parent:
0:f3bf6c7e2283
Child:
2:cffa347bb943
--- a/main.cpp	Fri Apr 20 20:39:35 2012 +0000
+++ b/main.cpp	Fri Apr 20 21:56:15 2012 +0000
@@ -6,6 +6,7 @@
 #include "motors.h"
 #include "math.h"
 #include "system.h"
+#include "geometryfuncs.h"
 
 //#include <iostream>
 
@@ -13,63 +14,77 @@
 //I2C i2c(p28, p27);        // sda, scl
 TSI2C i2c(p28, p27);
 Serial pc(USBTX, USBRX); // tx, rx
-Serial  IRturret(p13, p14);
+Serial  IRturret(p9, p10);
 
 DigitalOut     OLED1(LED1);
 DigitalOut     OLED2(LED2);
 DigitalOut     OLED3(LED3);
 DigitalOut     OLED4(LED4);
 
-int16_t face;
-
-
 Motors motors;
 Kalman kalman(motors);
 
 float targetX = 1000, targetY = 1000, targetTheta = 0;
 
-// bytes packing for IR turret serial comm
+// bytes packing/unpacking for IR turret serial comm
 union IRValue_t {
-    float IR_floats[6];
-    int   IR_ints[6];
-    unsigned char IR_chars[24];
+    float IR_floats[3];
+    int IR_ints[3];
+    unsigned char IR_chars[12];
 } IRValues;
 
+char Alignment_char[4] = {0xFF,0xFE,0xFD,0xFC};
+int Alignment_ptr = 0;
+bool data_flag = false;
+int buff_pointer = 0;
+bool angleInit = false;
+float angleOffset = 0;
+
+void vIRValueISR (void);
+void vKalmanInit(void);
+
 //TODO mutex on kalman state, and on motor commands (i.e. on the i2c bus)
 //NOTE! Recieving data with RF12B now DISABLED due to interferance with rtos!
 
+
 void vMotorThread(void const *argument);
 void vPrintState(void const *argument);
 void ai_thread (void const *argument);
 void motion_thread(void const *argument);
-void vIRValueISR (void);
-void motorSpeedThread(void const *argument);
+
 
 float getAngle (float x, float y);
 void getIRValue(void const *argument);
 
-
-//Thread thr_AI(ai_thread);
-//Thread thr_motion(motion_thread);
-//Thread thr_getIRValue(getIRValue);
+// Thread pointers
+Thread *AI_Thread_Ptr;
+Thread *Motion_Thread_Ptr;
 
 Mutex targetlock;
 bool flag_terminate = false;
 
-
 float temp = 0;
 
 //Main loop
 int main() {
-motors.stop();
     pc.baud(115200);
-    IRturret.baud(9600);
+    IRturret.baud(115200);
     IRturret.format(8,Serial::Odd,1);
-    //Thread thread(motorSpeedThread, NULL, osPriorityAboveNormal); //PID controller task. run at 50ms
-    //IRturret.attach(&vIRValueISR);
-    //Thread tMotorThread(vMotorThread,NULL,osPriorityNormal,256);
+    //IRturret.attach(&vIRValueISR,Serial::RxIrq);
+    //vKalmanInit();
+
+    Thread tMotorThread(vMotorThread,NULL,osPriorityNormal,256);
     Thread tUpdateState(vPrintState,NULL,osPriorityNormal,1024);
 
+    //Thread thr_AI(ai_thread,NULL,osPriorityNormal,1024);
+    //Thread thr_motion(motion_thread,NULL,osPriorityNormal,1024);
+    //AI_Thread_Ptr = &thr_AI;
+    //Motion_Thread_Ptr = &thr_motion;
+
+    //measure cpu usage. output updated once per second to symbol cpupercent
+    //Thread mCPUthread(measureCPUidle, NULL, osPriorityIdle, 1024); //check if stack overflow with such a small staack
+
+
     pc.printf("We got to main! ;D\r\n");
 
     //REMEMBERT TO PUT PULL UP RESISTORS ON I2C!!!!!!!!!!!!!!
@@ -79,18 +94,15 @@
     }
 }
 
-void motorSpeedThread(void const *argument) {
-    while (1) {
-        motors.speedRegulatorTask();
-        Thread::wait(10);
-    }
-}
-
 
 void vMotorThread(void const *argument) {
     motors.resetEncoders();
     while (1) {
-        motors.setSpeed(20,-20);
+        motors.setSpeed(20,20);
+        Thread::wait(2000);
+        motors.stop();
+        Thread::wait(5000);
+        motors.setSpeed(-20,-20);
         Thread::wait(2000);
         motors.stop();
         Thread::wait(5000);
@@ -98,6 +110,10 @@
         Thread::wait(2000);
         motors.stop();
         Thread::wait(5000);
+        motors.setSpeed(20,-20);
+        Thread::wait(2000);
+        motors.stop();
+        Thread::wait(5000);
     }
 }
 
@@ -105,41 +121,28 @@
 
 void vPrintState(void const *argument) {
     float state[3];
-    float sonardist[3];
-    //float x,y;
-    //float d = beaconpos[2].y - beaconpos[1].y;
-    //float i = beaconpos[0].y;
-    //float j = beaconpos[0].x;
+    float SonarMeasures[3];
+    float IRMeasures[3];
+
 
     while (1) {
         kalman.statelock.lock();
         state[0] = kalman.X(0);
         state[1] = kalman.X(1);
         state[2] = kalman.X(2);
-        sonardist[0] = kalman.SonarMeasures[0]*1000.0f;
-        sonardist[1] = kalman.SonarMeasures[1]*1000.0f;
-        sonardist[2] = kalman.SonarMeasures[2]*1000.0f;
+        SonarMeasures[0] = kalman.SonarMeasures[0];
+        SonarMeasures[1] = kalman.SonarMeasures[1];
+        SonarMeasures[2] = kalman.SonarMeasures[2];
+        IRMeasures[0] = kalman.IRMeasures[0];
+        IRMeasures[1] = kalman.IRMeasures[1];
+        IRMeasures[2] = kalman.IRMeasures[2];
         kalman.statelock.unlock();
-
-        // trilateration algorithm
-        //y = ((sonardist[1]*sonardist[1]) - (sonardist[2]*sonardist[2]) + d*d) / (2*d);
-        //x = ((sonardist[1]*sonardist[1]) - (sonardist[0]*sonardist[0]) + i*i + j*j) / (2*j) - (i/j)*y;
-
-
-        //kalman.statelock.lock();
         pc.printf("\r\n");
-        //printf("Position X: %0.1f Y: %0.1f \r\n", x,y);
         pc.printf("current: %0.4f %0.4f %0.4f \r\n", state[0], state[1],state[2]);
-        //targetlock.lock();
-        //pc.printf("target : %0.4f %0.4f %0.4f \r\n", targetX/1000, targetY/1000,targetTheta);
-        //targetlock.unlock();
-        printf("Sonar Dist: %0.4f, %0.4f, %0.4f \r\n", sonardist[0],sonardist[1],sonardist[2]);
-
-        //printf("Distance is %0.1f, %0.1f \r\n", motors.encoderToDistance(motors.getEncoder1()), motors.encoderToDistance(motors.getEncoder2()));
-
-        //pc.printf("IR ang : %f \n",temp * 180/3.14);
-        //kalman.statelock.unlock();
-        Thread::wait(200);
+        pc.printf("Sonar: %0.4f %0.4f %0.4f \r\n",SonarMeasures[0],SonarMeasures[1],SonarMeasures[2]);
+        pc.printf("IR   : %0.4f %0.4f %0.4f \r\n",IRMeasures[0]*180/PI,IRMeasures[1]*180/PI,IRMeasures[2]*180/PI);
+        pc.printf("Angle_Offset: %0.4f \r\n",angleOffset*180/PI);
+        Thread::wait(100);
     }
 }
 
@@ -183,7 +186,7 @@
     targetlock.lock();
     targetX     = 1500;
     targetY     = 1000;
-    targetTheta = -PI;
+    targetTheta = -PI/2;
     targetlock.unlock();
 
     // home
@@ -206,10 +209,10 @@
 // motion control thread ------------------------
 void motion_thread(void const *argument) {
     motors.resetEncoders();
-    motors.setSpeed(20,20);
-    Thread::wait(2000);
+    motors.setSpeed(MOVE_SPEED/2,MOVE_SPEED/2);
+    Thread::wait(1000);
     motors.stop();
-    //thr_AI.signal_set(0x01);
+    (*AI_Thread_Ptr).signal_set(0x01);
 
 
 
@@ -231,17 +234,6 @@
         kalman.statelock.unlock();
 
 
-
-        // get IR turret angle --------------------------------------
-        /*        float angEst = getAngle(currX, currY);          // check this
-                if (angEst != 1000){
-                    // here the value should be a valid estimate
-                    // so update kalman state
-
-                }
-        */
-        //!!! add code here to update kalman angle state !!!
-
         // check if target reached ----------------------------------
         if (  ( abs(currX - targetX) < POSITION_TOR )
                 &&( abs(currY - targetY) < POSITION_TOR )
@@ -250,7 +242,6 @@
             diffDir = rectifyAng(currTheta - targetTheta);
             diffSpeed = diffDir / PI;
 
-            //pc.printf("%f \n",diffDir);
             if (abs(diffDir) > ANGLE_TOR) {
                 if (abs(diffSpeed) < 0.5) {
                     diffSpeed = 0.5*diffSpeed/abs(diffSpeed);
@@ -261,7 +252,7 @@
             } else {
                 motors.stop();
                 Thread::wait(4000);
-                //thr_AI.signal_set(0x01);
+                (*AI_Thread_Ptr).signal_set(0x01);
             }
         }
 
@@ -311,64 +302,78 @@
     }
 }
 
+void vIRValueISR (void) {
 
-void getIRValue(void const *argument) {
-    Thread::signal_wait(0x01);
-    if (IRturret.readable() >= 24) {
-        for (int i=0; i < 24; i++) {
-            IRValues.IR_chars[i] = IRturret.getc();
+    OLED3 = !OLED3;
+    // A workaround for mbed UART ISR bug
+    // Clear the RBR flag to make sure the interrupt doesn't loop
+    // UART3 for the port on pins 9/10, UART2 for pins 28/27, and UART1 for pins 13/14.
+    // UART0 for USB UART
+    unsigned char RBR = LPC_UART1->RBR;
+
+
+    if (!data_flag) { // look for alignment bytes
+        if (RBR == Alignment_char[Alignment_ptr]) {
+            Alignment_ptr ++;
         }
+        if (Alignment_ptr >= 4) {
+            Alignment_ptr = 0;
+            data_flag = true; // set the dataflag
+        }
+    } else { // fetch data bytes
+        IRValues.IR_chars[buff_pointer] = RBR;
+        buff_pointer ++;
+        if (buff_pointer >= 12) {
+            buff_pointer = 0;
+            data_flag = false; // dessert the dataflag
+            if (angleInit) {
+                kalman.runupdate(Kalman::measurement_t(IRValues.IR_ints[0]+3),rectifyAng(IRValues.IR_floats[1]+angleOffset),IRValues.IR_floats[2]);
+            } else {
+                kalman.runupdate(Kalman::measurement_t(IRValues.IR_ints[0]+3),IRValues.IR_floats[1],IRValues.IR_floats[2]);
+            }
+        }
+
     }
 }
 
-void vIRValueISR (void) {
-    //thr_getIRValue.signal_set(0x01);
-}
-
-
-float getAngle (float x, float y) {
-    /*  function that returns current robot orientation
-        input:  x, y coords in mm
-        output: orientation in rad
-        note: the angle readings from IR is read in here
-            must be called faster than IR turret frequency (few Hz - currently 3Hz)
-    */
-
-    // variables
-    float   ang0 = 0, ang1 = 0, ang2 = 0;
-    int     sc0 = 0, sc1 = 0, sc2 = 0;
-
-
-
-    // read serial port
-    if (IRturret.readable()) {
-        IRturret.scanf("%f;%f;%f;%d;%d;%d;",&ang0,&ang1,&ang2,&sc0,&sc1,sc2);
+void vKalmanInit(void) {
+    float SonarMeasures[3];
+    float IRMeasures[3];
+    int beacon_cnt = 0;
+    wait(1);
+    IRturret.attach(NULL,Serial::RxIrq);
+    kalman.statelock.lock();
+    SonarMeasures[0] = kalman.SonarMeasures[0]*1000.0f;
+    SonarMeasures[1] = kalman.SonarMeasures[1]*1000.0f;
+    SonarMeasures[2] = kalman.SonarMeasures[2]*1000.0f;
+    IRMeasures[0] = kalman.IRMeasures[0];
+    IRMeasures[1] = kalman.IRMeasures[1];
+    IRMeasures[2] = kalman.IRMeasures[2];
+    kalman.statelock.unlock();
+    //printf("0: %0.4f, 1: %0.4f, 2: %0.4f \n\r", IRMeasures[0]*180/PI, IRMeasures[1]*180/PI, IRMeasures[2]*180/PI);
+    float d = beaconpos[2].y - beaconpos[1].y;
+    float i = beaconpos[0].y - beaconpos[1].y;
+    float j = beaconpos[0].x - beaconpos[1].x;
+    float y_coor = (SonarMeasures[1]*SonarMeasures[1]- SonarMeasures[2]*SonarMeasures[2] + d*d) / (2*d);
+    float x_coor = (SonarMeasures[1]*SonarMeasures[1] - SonarMeasures[0]*SonarMeasures[0] + i*i + j*j)/(2*j) - i*y_coor/j;
+    angleOffset = 0;
+    for (int i = 0; i < 3; i++) {
+        float angle_est = atan2(beaconpos[i].y - y_coor,beaconpos[i].x - x_coor);
+        if (IRMeasures[i] != 0){
+           beacon_cnt ++;
+           float angle_temp = angle_est - IRMeasures[i];
+           angle_temp -= (floor(angle_temp/(2*PI)))*2*PI; 
+           angleOffset += angle_temp;
+        }
     }
-
-    // if none sampled
-    if (!sc0 && !sc1 && ! sc2) {
-        return 1000;
-    }
-
-    //
-    else {
-        float est0 = 0, est1 = 0, est2 = 0;
-
-        // calc
-        if ((sc0 > RELI_BOUND_LOW)||(sc0 < RELI_BOUND_HIGH)) {
-            est0 = atan2(1000 - y, 3000-x) - ang0;
-        }
-        if ((sc1 > RELI_BOUND_LOW)||(sc1 < RELI_BOUND_HIGH)) {
-            est1 = atan2( -y, -x) - ang1;
-        }
-        if ((sc2 > RELI_BOUND_LOW)||(sc2 < RELI_BOUND_HIGH)) {
-            est2 = atan2(2000 - y, -x) - ang2;
-        }
-
-        // weighted avg
-        return rectifyAng( ((est0 * RELI_BOUND_HIGH-sc0) + (est1 * RELI_BOUND_HIGH-sc1) + (est2 * RELI_BOUND_HIGH-sc2)) / (3*RELI_BOUND_HIGH - sc0 - sc1 - sc2) );
-    }
-
-}
-
-
+    angleOffset = angleOffset/float(beacon_cnt);
+    //printf("\n\r");
+    angleInit = true;
+    kalman.statelock.lock();
+    kalman.X(0) = x_coor/1000.0f;
+    kalman.X(1) = y_coor/1000.0f;
+    kalman.X(2) = 0;
+    kalman.statelock.unlock();
+    //printf("x: %0.4f, y: %0.4f, offset: %0.4f \n\r", x_coor, y_coor, angleOffset*180/PI);
+    IRturret.attach(&vIRValueISR,Serial::RxIrq);
+}
\ No newline at end of file