Eurobot2012_Primary

Dependencies:   mbed Eurobot_2012_Primary

Revision:
25:143b19c1fb05
Parent:
24:7a3906c2f5d5
Child:
26:0995f61cb7b8
--- a/Eurobot_shared/Kalman/Kalman.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-//***************************************************************************************
-//Kalman Filter implementation
-//***************************************************************************************
-#include "Kalman.h"
-#include "rtos.h"
-#include "RFSRF05.h"
-#include "math.h"
-#include "globals.h"
-#include "motors.h"
-#include "system.h"
-#include "geometryfuncs.h"
-
-#include <tvmet/Matrix.h>
-#include <tvmet/Vector.h>
-using namespace tvmet;
-
-Kalman::Kalman(Motors &motorsin,
-               UI &uiin,
-               PinName Sonar_Trig,
-               PinName Sonar_Echo0,
-               PinName Sonar_Echo1,
-               PinName Sonar_Echo2,
-               PinName Sonar_Echo3,
-               PinName Sonar_Echo4,
-               PinName Sonar_Echo5,
-               PinName Sonar_SDI,
-               PinName Sonar_SDO,
-               PinName Sonar_SCK,
-               PinName Sonar_NCS,
-               PinName Sonar_NIRQ) :
-        ir(*this),
-        sonararray(Sonar_Trig,
-                   Sonar_Echo0,
-                   Sonar_Echo1,
-                   Sonar_Echo2,
-                   Sonar_Echo3,
-                   Sonar_Echo4,
-                   Sonar_Echo5,
-                   Sonar_SDI,
-                   Sonar_SDO,
-                   Sonar_SCK,
-                   Sonar_NCS,
-                   Sonar_NIRQ),
-        motors(motorsin),
-        ui(uiin),
-        predictthread(predictloopwrapper, this, osPriorityNormal, 512),
-        predictticker( SIGTICKARGS(predictthread, 0x1) ),
-//        sonarthread(sonarloopwrapper, this, osPriorityNormal, 256),
-//        sonarticker( SIGTICKARGS(sonarthread, 0x1) ),
-        updatethread(updateloopwrapper, this, osPriorityNormal, 512) {
-
-    //Initilising offsets
-    InitLock.lock();
-    IR_Offset = 0;
-    Sonar_Offset = 0;
-    InitLock.unlock();
-
-
-    //Initilising matrices
-
-    // X = x, y, theta;
-    if (Colour)
-        X = 0.5, 0, 0;
-    else
-        X = 2.5, 0, PI;
-
-    P = 1, 0, 0,
-        0, 1, 0,
-        0, 0, 0.04;
-
-    //measurment variance R is provided by each sensor when calling runupdate
-
-    //attach callback
-    sonararray.callbackobj = (DummyCT*)this;
-    sonararray.mcallbackfunc = (void (DummyCT::*)(int beaconnum, float distance, float variance)) &Kalman::runupdate;
-
-
-    predictticker.start(20);
-//    sonarticker.start(50);
-
-}
-
-
-//Note: this init function assumes that the robot faces east, theta=0, in the +x direction
-void Kalman::KalmanInit() {
-    motors.stop();
-    float SonarMeasuresx1000[3];
-    float IRMeasuresloc[3];
-    int beacon_cnt = 0;
-
-
-// doesn't work since they break the ISR
-    /*
-    #ifdef ROBOT_PRIMARY
-        LPC_UART3->FCR = LPC_UART3->FCR | 0x06;       // Flush the serial FIFO buffer / OR with FCR
-    #else
-        LPC_UART1->FCR = LPC_UART1->FCR | 0x06;       // Flush the serial FIFO buffer / OR with FCR
-    #endif
-    */
-    // zeros the measurements
-    for (int i = 0; i < 3; i++) {
-        SonarMeasures[i] = 0;
-        IRMeasures[i] = 0;
-    }
-
-    InitLock.lock();
-    //zeros offsets
-    IR_Offset = 0;
-    Sonar_Offset = 0;
-    InitLock.unlock();
-
-    // attaches ir interrup
-    ir.attachisr();
-
-    //wating untill the IR has reved up and picked up some valid data
-    //Thread::wait(1000);
-    wait(2);
-
-    //temporaraly disable IR updates
-    ir.detachisr();
-
-    //lock the state throughout the computation, as we will override the state at the end
-    InitLock.lock();
-    statelock.lock();
-
-
-
-    SonarMeasuresx1000[0] = SonarMeasures[0]*1000.0f;
-    SonarMeasuresx1000[1] = SonarMeasures[1]*1000.0f;
-    SonarMeasuresx1000[2] = SonarMeasures[2]*1000.0f;
-    IRMeasuresloc[0] = IRMeasures[0];
-    IRMeasuresloc[1] = IRMeasures[1];
-    IRMeasuresloc[2] = IRMeasures[2];
-    //printf("0: %0.4f, 1: %0.4f, 2: %0.4f \n\r", IRMeasuresloc[0]*180/PI, IRMeasuresloc[1]*180/PI, IRMeasuresloc[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 origin_x = beaconpos[1].x;
-    float y_coor = (SonarMeasuresx1000[1]*SonarMeasuresx1000[1]- SonarMeasuresx1000[2]*SonarMeasuresx1000[2] + d*d) / (2*d);
-    float x_coor = origin_x + (SonarMeasuresx1000[1]*SonarMeasuresx1000[1] - SonarMeasuresx1000[0]*SonarMeasuresx1000[0] + i*i + j*j)/(2*j) - i*y_coor/j;
-
-    //debug for trilateration
-    printf("Cal at x: %0.4f, y: %0.4f \r\n",x_coor,y_coor );
-
-    float Dist_Exp[3];
-    for (int i = 0; i < 3; i++) {
-        //Compute sonar offset
-        Dist_Exp[i] = hypot(beaconpos[i].y - y_coor,beaconpos[i].x - x_coor);
-        Sonar_Offset += (SonarMeasuresx1000[i]-Dist_Exp[i])/3000.0f;
-
-        //Compute IR offset
-        float angle_est = atan2(beaconpos[i].y - y_coor,beaconpos[i].x - x_coor);
-        if (!Colour)
-        angle_est -= PI;
-        //printf("Angle %d : %f \n\r",i,angle_est*180/PI );
-        // take average offset angle from valid readings
-        if (IRMeasuresloc[i] != 0) {
-            beacon_cnt ++;
-            // changed to current angle - estimated angle
-            float angle_temp = IRMeasuresloc[i] - angle_est;
-            angle_temp -= (floor(angle_temp/(2*PI)))*2*PI;
-            IR_Offset += angle_temp;
-        }
-    }
-    IR_Offset /= float(beacon_cnt);
-
-    //debug
-    printf("Offsets IR: %0.4f, Sonar: %0.4f \r\n",IR_Offset*180/PI,Sonar_Offset*1000 );
-
-    //statelock already locked
-    X(0) = x_coor/1000.0f;
-    X(1) = y_coor/1000.0f;
-    
-    if (Colour)
-        X(2) = 0;
-    else
-        X(2) = PI;
-
-    // unlocks mutexes
-    InitLock.unlock();
-    statelock.unlock();
-
-
-    //reattach the IR processing
-    ir.attachisr();
-}
-
-
-void Kalman::predictloop() {
-
-    OLED4 = !ui.regid(0, 3);
-    OLED4 = !ui.regid(1, 4);
-
-    float lastleft = 0;
-    float lastright = 0;
-
-    while (1) {
-        Thread::signal_wait(0x1);
-        OLED1 = !OLED1;
-
-        int leftenc = motors.getEncoder1();
-        int rightenc = motors.getEncoder2();
-
-        float dleft = motors.encoderToDistance(leftenc-lastleft)/1000.0f;
-        float dright = motors.encoderToDistance(rightenc-lastright)/1000.0f;
-
-        lastleft = leftenc;
-        lastright = rightenc;
-
-
-        //The below calculation are in body frame (where +x is forward)
-        float dxp, dyp,d,r;
-        float thetap = (dright - dleft)*PI / (float(robotCircumference)/1000.0f);
-        if (abs(thetap) < 0.02) { //if the rotation through the integration step is small, approximate with a straight line to avoid numerical error
-            d = (dright + dleft)/2.0f;
-            dxp = d*cos(thetap/2.0f);
-            dyp = d*sin(thetap/2.0f);
-
-        } else { //calculate circle arc
-            //float r = (right + left) / (4.0f * PI * thetap);
-            r = (dright + dleft) / (2.0f*thetap);
-            dxp = abs(r)*sin(thetap);
-            dyp = r - r*cos(thetap);
-        }
-
-        statelock.lock();
-
-        float tempX2 = X(2);
-        //rotating to cartesian frame and updating state
-        X(0) += dxp * cos(X(2)) - dyp * sin(X(2));
-        X(1) += dxp * sin(X(2)) + dyp * cos(X(2));
-        X(2) = rectifyAng(X(2) + thetap);
-
-        //Linearising F around X
-        float avgX2 = (X(2) + tempX2)/2.0f;
-        Matrix<float, 3, 3> F;
-        F = 1, 0, (dxp * -sin(avgX2) - dyp * cos(avgX2)),
-            0, 1, (dxp * cos(avgX2) - dyp * sin(avgX2)),
-            0, 0, 1;
-
-        //Generating forward and rotational variance
-        float varfwd = fwdvarperunit * abs(dright + dleft) / 2.0f;
-        float varang = varperang * abs(thetap);
-        float varxydt = xyvarpertime * PREDICTPERIOD/1000.0f;
-        float varangdt = angvarpertime * PREDICTPERIOD/1000.0f;
-
-        //Rotating into cartesian frame
-        Matrix<float, 2, 2> Qsub,Qsubrot,Qrot;
-        Qsub = varfwd + varxydt, 0,
-               0, varxydt;
-
-        Qrot = Rotmatrix(X(2));
-
-        Qsubrot = Qrot * Qsub * trans(Qrot);
-
-        //Generate Q
-        Matrix<float, 3, 3> Q;//(Qsubrot);
-        Q = Qsubrot(0,0), Qsubrot(0,1), 0,
-            Qsubrot(1,0), Qsubrot(1,1), 0,
-            0, 0, varang + varangdt;
-
-        P = F * P * trans(F) + Q;
-
-        //Update UI
-        float statecpy[] = {X(0), X(1), X(2)};
-        ui.updateval(0, statecpy, 3);
-
-        float Pcpy[] = {P(0,0), P(0,1), P(1,0), P(1,1)};
-        ui.updateval(1, Pcpy, 4);
-
-        statelock.unlock();
-    }
-}
-
-//void Kalman::sonarloop() {
-//    while (1) {
-//        Thread::signal_wait(0x1);
-//        sonararray.startRange();
-//    }
-//}
-
-
-void Kalman::runupdate(measurement_t type, float value, float variance) {
-    //printf("beacon %d dist %f\r\n", sonarid, dist);
-    //led2 = !led2;
-
-    measurmentdata* measured = (measurmentdata*)measureMQ.alloc();
-    if (measured) {
-        measured->mtype = type;
-        measured->value = value;
-        measured->variance = variance;
-
-        osStatus putret = measureMQ.put(measured);
-        if (putret)
-            OLED4 = 1;
-        //    printf("putting in MQ error code %#x\r\n", putret);
-    } else {
-        OLED4 = 1;
-        //printf("MQalloc returned NULL ptr\r\n");
-    }
-
-}
-
-void Kalman::updateloop() {
-
-    //sonar Y chanels
-    ui.regid(2, 1);
-    ui.regid(3, 1);
-    ui.regid(4, 1);
-
-    //IR Y chanels
-    ui.regid(5, 1);
-    ui.regid(6, 1);
-    ui.regid(7, 1);
-
-    measurement_t type;
-    float value,variance,rbx,rby,expecdist,Y;
-    float dhdx,dhdy;
-    bool aborton2stddev = false;
-
-    Matrix<float, 1, 3> H;
-
-    float S;
-    Matrix<float, 3, 3> I3( identity< Matrix<float, 3, 3> >() );
-
-
-    while (1) {
-        OLED2 = !OLED2;
-
-        osEvent evt = measureMQ.get();
-
-        if (evt.status == osEventMail) {
-
-            measurmentdata &measured = *(measurmentdata*)evt.value.p;
-            type = measured.mtype; //Note, may support more measurment types than sonar in the future!
-            value = measured.value;
-            variance = measured.variance;
-
-            // don't forget to free the memory
-            measureMQ.free(&measured);
-
-            if (type <= maxmeasure) {
-
-                if (type <= SONAR3) {
-
-                    InitLock.lock();
-                    float dist = value / 1000.0f - Sonar_Offset; //converting to m from mm,subtract the offset
-                    InitLock.unlock();
-
-                    int sonarid = type;
-                    aborton2stddev = true;
-
-                    statelock.lock();
-                    //update the current sonar readings
-                    SonarMeasures[sonarid] = dist;
-
-                    rbx = X(0) - beaconpos[sonarid].x/1000.0f;
-                    rby = X(1) - beaconpos[sonarid].y/1000.0f;
-
-                    expecdist = hypot(rbx, rby);//sqrt(rbx*rbx + rby*rby);
-                    Y = dist - expecdist;
-
-                    //send to ui
-                    ui.updateval(sonarid+2, Y);
-
-                    dhdx = rbx / expecdist;
-                    dhdy = rby / expecdist;
-
-                    H = dhdx, dhdy, 0;
-
-                } else if (type <= IR3) {
-
-                    aborton2stddev = false;
-                    int IRidx = type-3;
-
-                    // subtract the IR offset
-                    InitLock.lock();
-                    value -= IR_Offset;
-                    InitLock.unlock();
-
-                    statelock.lock();
-                    IRMeasures[IRidx] = value;
-
-                    rbx = X(0) - beaconpos[IRidx].x/1000.0f;
-                    rby = X(1) - beaconpos[IRidx].y/1000.0f;
-
-                    float expecang = atan2(-rby, -rbx) - X(2);
-                    Y = rectifyAng(value - expecang);
-
-                    //send to ui
-                    ui.updateval(IRidx + 5, Y);
-
-                    float dstsq = rbx*rbx + rby*rby;
-                    H = -rby/dstsq, rbx/dstsq, -1;
-                }
-
-                Matrix<float, 3, 1> PH (P * trans(H));
-                S = (H * PH)(0,0) + variance;
-
-                if (aborton2stddev && Y*Y > 4 * S) {
-                    statelock.unlock();
-                    continue;
-                }
-
-                Matrix<float, 3, 1> K (PH * (1/S));
-
-                //Updating state
-                X += col(K, 0) * Y;
-                X(2) = rectifyAng(X(2));
-
-                P = (I3 - K * H) * P;
-
-                statelock.unlock();
-
-            }
-
-        } else {
-            OLED4 = 1;
-            //printf("ERROR: in updateloop, code %#x", evt);
-        }
-
-    }
-
-}
-
-// reset kalman states
-void Kalman::KalmanReset() {
-    float SonarMeasuresx1000[3];
-    statelock.lock();
-    SonarMeasuresx1000[0] = SonarMeasures[0]*1000.0f;
-    SonarMeasuresx1000[1] = SonarMeasures[1]*1000.0f;
-    SonarMeasuresx1000[2] = SonarMeasures[2]*1000.0f;
-    //printf("0: %0.4f, 1: %0.4f, 2: %0.4f \n\r", IRMeasuresloc[0]*180/PI, IRMeasuresloc[1]*180/PI, IRMeasuresloc[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 origin_x = beaconpos[1].x;
-    float y_coor = (SonarMeasuresx1000[1]*SonarMeasuresx1000[1]- SonarMeasuresx1000[2]*SonarMeasuresx1000[2] + d*d) / (2*d);
-    float x_coor = origin_x +(SonarMeasuresx1000[1]*SonarMeasuresx1000[1] - SonarMeasuresx1000[0]*SonarMeasuresx1000[0] + i*i + j*j)/(2*j) - i*y_coor/j;
-
-    //statelock already locked
-    X(0) = x_coor/1000.0f;
-    X(1) = y_coor/1000.0f;
-   
-    
-
-/*    if (Colour){
-        X(0) = 0.2;
-        X(1) = 0.2;
-        //X(2) = 0;
-        }
-    else {
-        X(0) = 2.8;
-        X(1) = 0.2;
-        //X(2) = PI;
-    }
-    */
-    P = 0.05, 0, 0,
-        0, 0.05, 0,
-        0, 0, 0.04;
-
-    // unlocks mutexes
-    statelock.unlock();
-
-}
\ No newline at end of file