2d drive position tracking (final draft)

Dependencies:   MotorV2 QEI mbed

Fork of TerraBot_Drive_2D by Milo Pan

Files at this revision

API Documentation at this revision

Comitter:
simplyellow
Date:
Tue Nov 29 21:16:58 2016 +0000
Parent:
0:d4bb648b7f2c
Commit message:
final 2d tracking

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r d4bb648b7f2c -r 17db90f61f6c main.cpp
--- a/main.cpp	Mon Nov 14 21:46:17 2016 +0000
+++ b/main.cpp	Tue Nov 29 21:16:58 2016 +0000
@@ -2,209 +2,206 @@
 #include "mbed.h"
 #include "Motor.h"
 
-/*
-    Written by Milo Pan with the help of Jacob Callahan
-*/
-
-/*
-Use X4 encoding.
-QEI wheel(p29, p30, NC, 624, QEI::X4_ENCODING);
-QEI constructor(CHANNEL A, CHANNEL B,PinName index (NC), int pulsesPerRev, Encoding encoding=X2_ENCODING) 
-Use X2 encoding by default.
-Encoding x4 = x4_ENCODING;
-*/
-
-/*
-Measurement Instructions
-in order to convert the numerical value (outputted by this program) to Inches traveled,
-measurements need to be taken (i.e. have the truck travel 40" for 10 trials, average the values, and find the factor
-*/
-
 Serial pc(USBTX, USBRX);
 
-QEI wheel (p29, p30, NC, 128, QEI::X4_ENCODING);    //orange, yellow wires, VU 5 VOLTS, BOTTOM 2x2 pins on WW02
-float pulseCount;                                   //number of pulses detected by encoder
-float encoding = 2;                                 //X2
-float circumference = 13.25;                        //inches of circumference
+QEI wheel (p29, p30, NC, 128, QEI::X4_ENCODING);
+//orange, yellow wires, VU 5 VOLTS, BOTTOM 2x2 pins on WW02
+
+float pulseCount;
+float encoding = 2;
+float circumference = 13.25;
+float constant = 1360;              // constant = 20*68
+
 float distance;
 
+float x;
+float y;
+
 AnalogIn pot(p15);
 float value;
-float angle;
-float zero;
+float turnAngle;
+float zeroAngle;
+
+float PI = 3.14159265;
+
+#define STRAIGHT 0
+#define CCW 1
+#define CW 2
+
+int dir = 3;
+
+float df = 4.50;                    // distance from pivot to front wheel
+float db = 4.25;                    // distance from pivot to back wheel
+float W;
+float R;
+float dispAngle;
+
+#define Q1 1
+#define Q2 2
+#define Q3 3
+#define Q4 4
+
+int quadrant = 0;
 
-float PI = 3.14159;
+void clear() {
+    distance = 0;
+    x = 0;
+    y = 0;
+}
+
+void potSetup() {
+    zeroAngle = (float) pot;
+    for(int i = 5; i > 0; i--) {
+        pc.printf("%d seconds to set turning angle.\n\r", i);
+        wait(1);
+    }
+    turnAngle = ((float) pot - zeroAngle) * 300;
+    pc.printf("---------------------------------\n\r");
+    //debug
+    /*
+    for(int i = 5; i > 0; i--) {
+        pc.printf("%f is the turning Angle.\n\r", turnAngle);
+        pc.printf("%f is the zero value.\n\r", zeroAngle);
+        pc.printf("%f is the pot value.\n\r", (float) pot);
+        wait(1);
+    }*/
+}
 
-/* VERSION 1
-float x = 0;
-float dx;
-float y = 0;
-float dy;
-float dispAngle;        // theta d
-float r;                // r
-float c;                // c, chord length
+void setDirection() {
+    if (turnAngle > 0.5) {          // +/- 0.5 leeway
+        pc.printf("DIRECTION SET TO CCW with turnAngle %f\n\r", turnAngle);
+        dir = CCW;
+        pc.printf("%d is direction\n\r", dir);
+    } else if (turnAngle < -0.5) {
+        pc.printf("DIRECTION SET TO CW with turnAngle %f\n\r", turnAngle);
+        dir = CW;
+    } else {
+        pc.printf("DIRECTION SET TO STRAIGHT with turnAngle %f\n\r", turnAngle);
+        dir = STRAIGHT;
+    }
+    turnAngle = abs(turnAngle);
+}
 
-float segment;          // intermediary variable for ease of calculation
+void setQuadrant() {
+    if ((turnAngle > 0) && (turnAngle < 90)) {
+        quadrant = Q1;
+    } else if ((turnAngle > 90) && (turnAngle < 180)) {
+        quadrant = Q2;
+    } else if ((turnAngle > 180) && (turnAngle < 270)) {
+        quadrant = Q3;
+    } else if ((turnAngle > 270) && (turnAngle < 360)) {
+        quadrant = Q4;
+    } else if (turnAngle == 0) {
+        //don't worry
+    } else {
+        pc.printf("turnAngle not valid. TERMINATED. \n\r");
+        while(true) {}
+    }
+}
 
-float heading;          // heading of front
+void checkToStart() {               // start tracking when distance > 0
+    while(true) {
+        pulseCount = (float) wheel.getPulses();
+        distance = pulseCount*circumference/encoding/constant;
+        if (distance > 0) {
+            return;
+        } else {
+            wait(0.0001);
+        }
+    }
+}
+/*
+AXES
+when robot is facing forward
+forward is +x
+left is +y
 */
 
 
-// VERSION 2
-float df;
-float db;
-float circumference2;
-float proportion;
-float scaledDown;
-float W;
-float R;
-int dir; //1 CCW, 2 CW, 0 straight
-float heading = 0.0;
-float dispAngleRad;
-float dispAngleDeg;
-float x;
-float dx;
-float y;
-float dy;
+void calcDisplacement() {
+    pulseCount = (float) wheel.getPulses();
+    distance = pulseCount*circumference/encoding/constant;
+
+    W = sqrt(df*df+db*db-2*df*db*cos(PI-turnAngle*PI/180));
+    R = W/(2*sin(0.5*turnAngle*PI/180));
+    dispAngle = distance/R;
 
-float totalDistance;
-int i;
-
-
+    if (dir == STRAIGHT) {
+        x = 0;
+        y = distance;
+    } else if (dir == CCW) {
+        x = -1*(R*(1-cos(dispAngle)));
+        y = R*sin(dispAngle);
+        /*
+        switch(quadrant) {
+            case Q1:
+                x = R*(cos(dispAngle)-1);
+                y = R*sin(dispAngle);
+                break;
+            case Q2:
+                x = -1*R*sin(dispAngle);
+                y = R*(cos(dispAngle)-1);
+                break;
+            case Q3:
+                x = R*(cos(dispAngle)-1);
+                y = -1*R*sin(dispAngle);
+                break;
+            case Q4:
+                x = R*sin(dispAngle);
+                y = R*(1-cos(dispAngle));
+                break;
+            default:
+                pc.printf("default \n\r");
+        }*/
+    } else if (dir == CW) {
+        x = R*(1-cos(dispAngle));
+        y = R*sin(dispAngle);
+        /*
+        switch(quadrant) {
+            case Q1:
+                x = R*sin(dispAngle);
+                y = R*(cos(dispAngle)-1);
+                break;
+            case Q2:
+                x = R*(cos(dispAngle)-1);
+                y = R*sin(dispAngle);
+                break;
+            case Q3:
+                x = -1*R*sin(dispAngle);
+                y = R*(1-cos(dispAngle));
+                break;
+            case Q4:
+                x = R*(cos(dispAngle)-1);
+                y = -1*R*sin(dispAngle);
+                break;
+            default:
+                pc.printf("default \n\r");
+        }*/
+    } else {
+        pc.printf("Direction not set. TERMINATED. \n\r");
+        while(true) {}
+    }
 
-void measure() {
-    // raw measurements of pot, encoder
-    //(pulse count / X * N) * (1 / PPI)
-    pulseCount = (float) wheel.getPulses();
-    /* conversion to relevant values: distance of arc traveled, angle of turn
-        |   suppose the truck is a two-segment body
-        /  <- angle between bottom leg and the vertical = angle of turn
-    the 20 and 68 were arbitrary and determined from testing, respectively
-    the distance is in inches
-    */
-    distance = pulseCount*circumference/encoding/20/68; 
-    // with half inch correction after testing extensively
-    /*if (distance > 0) {                                 
-        distance-=0.5;
-    } 
-    */
+    wait(.0001);
 }
 
-/* VERSION 1
-void calculateDisplacement() {
-    /
-        Premise:
-        Suppose the arc s (distance), the distance traveled by the 
-        turning truck, is defined by two connected points on 
-        a circle with radius r.
-    /
-    
-    // convert angle to radians
-    angle = angle*PI/180;
-    // r = s/angle, for distance of arc s         
-    r = distance/(angle);
-    // c = 2*r*sin(angle/2) for chord c
-    c = 2*r*sin(angle/2);
-    // intermediate value
-    segment = (r*(1-cos(angle)));
-    // calculation of angle of displacement
-    dispAngle = acos(segment/c);
-    // calculation of displacement
-    dx = c*cos(dispAngle+heading);
-    dy = c*sin(dispAngle+heading);
-    x = x - r + dx;
-    y = y + dy;
-    wait(1.0);                                           
-}
-*/
-
-void calculateDisplacement() {
-    df = 4.5; // distance from pivot to front wheel
-    db = 4.25; // distance from pivot to back wheel
-    // W = 2*R*sin(0.5*angle);
-    // W = shortest distance between wheels
-    angle = angle*PI/180;
-    W = sqrt(df*df+db*db-2*df*db*cos(PI-angle));
-    R = W/(2*sin(0.5*angle));
-    
-    circumference2 = 2*PI*R; // inches
-    proportion = distance/circumference2;
-    scaledDown = proportion - floor(proportion);
-    dispAngleRad = scaledDown*2*PI;
-    dispAngleDeg = scaledDown*360;
-    dx = R*cos(dispAngleRad + heading);
-    dy = R*sin(dispAngleRad + heading);
-
-    if(dir == 1) {               // CCW
-        x = 0 - R + dx;
-        y = dy;
-    } else if (dir == 2) {                // CW
-        y = dy;
-        if((dispAngleDeg < 90) || (dispAngleDeg > 270)) {
-        x = dx;
-        } else {
-            x = R - dx;
-        }
-    } else {
-        x = 0;
-        y = distance;
+int main() {
+    clear();
+    potSetup();
+    setDirection();
+    setQuadrant();
+    checkToStart();
+    while(true) {
+        calcDisplacement();
+        pc.printf("----------------------\n\r");
+        pc.printf("x: %f\n\r", x);
+        pc.printf("y: %f\n\r", y);
+        pc.printf("distance: %f\n\r", distance);
+        pc.printf("turnAngle: %f\n\r", turnAngle);
+        pc.printf("dispAngle: %f\n\r", dispAngle);
+        pc.printf("direction: %d\n\r", dir);
+        pc.printf("quadrant: %d\n\r", quadrant);
+        pc.printf("W: %f\n\r", W);
+        pc.printf("R: %f\n\r", R);
     }
-    heading += dispAngleRad;
-    wait(1.0);
-}
-/*
-dir
-and straight accuracy
-*/
-
-int main() {
-    // required to set truck straight before start up to calibrate to zero
-    zero = (float) pot;
-    while(i<5) {
-        printf("%d set angle \n\r",i);
-        wait(1);
-        i++;
-    }
-    if (totalDistance == 0) { // pot turns constant after the distance turns non zero
-        value = (float) pot;
-        // appropriate conversion from potentiometer float value to angle
-        angle = (value-zero)*300;
-        printf("%f",angle);
-    }
-    distance = 0;
-    totalDistance = 0;
-    heading = 0;
-    while(1){
-        measure(); 
-
-        calculateDisplacement();
-        
-        totalDistance+=distance;
-        if(totalDistance>0) {//@@@@@@@@@@check dir with angle vals@@@@@@@
-            if (angle > 0.5) {
-                dir = 1;//ccw
-            } else if (angle < -0.5) {
-                dir = 2;//cw
-            } else {
-                dir = 0;
-            }
-        }
-        distance = 0;
-        
-        /*
-            Notes:
-            At startup:
-            distance = 0
-            angle =! 0
-        */
-        
-        // for debugging
-        pc.printf("Distance %f, Angle %f\n\r", totalDistance, angle*180/PI);     
-        pc.printf("(X,Y): %f %f\n\r", x, y); 
-        pc.printf("(DX,DY): %f %f\n\r", dx, dy);    
-        pc.printf("heading: %f\n\r", heading);
-        pc.printf("----------------------------\n\r");   
-    }
-}
-
-
+}
\ No newline at end of file