Crude navigation

Dependencies:   GPS L3GD20 LSM303DLHC mbed PID

Revision:
2:503a5ac6c3b6
Parent:
0:e79311aae7ed
Child:
3:ffa0e1429a72
--- a/main.cpp	Sat Feb 21 01:22:52 2015 +0000
+++ b/main.cpp	Wed Mar 04 17:48:08 2015 +0000
@@ -1,41 +1,62 @@
 #include "mbed.h"
 #include "GPS.h"
 #include "modSensData.h"
+#include "move.h"
+#include "PID.h"
 
 //Radius of the earth in meters
 #define EARTHRADIUS 6378100.0f
 //Tolerance for heading actual and heading needed
-#define HEADDIFF 5.0f
+#define HEADDIFF 2.0f
+//Tolerance for whether or not vehicle has arrived at goal position
+#define ARRIVED 100.0f
 //Period in seconds of the the main loop
-#define PERIOD 1
-
+#define PERIOD 0.5f
+//Period in seconds of PID loop
+#define RATE .001
+#define PIDCYCLES 100
 //GPS
 GPS gps(D9, D7);
 
 //X-Bee
 Serial xBee(PTC15, PTC14);
 
+//PID
+//Kc, Ti, Td, interval
+PID controller(.01, .01, 20, RATE);
 
-float startPos[2], curPos[2], goalPos[2] = {35.478593, -81.981878}, polarVector[2];
+//Enter new position here
+float goalPos[2] = {35.336020, -81.912420};
+
+float startPos[2], curPos[2], polarVector[2];
+
+int sCheck, pCheck = 1;
 
 void setGoalPos(float lat, float lon);
 void makeVector(void);
-char whichWay(float magHead, float calcHead);
+float whichWay(float magHead, float calcHead);
 void testYaw(void);
 
 int main()
 {
-    xBee.baud(9600);
+    float motorSpeed = 0.5f;
+    //PID control of left and right motors based on input from gyro
+    //Goal is to have the vehicle go straight
+    controller.setInputLimits(-180, 180);
+    controller.setOutputLimits(-.5, .5);
+    controller.setMode(0);
+    //We want the difference to be zero
+    controller.setSetPoint(0);
     
-    //uncomment to check math for calculating needed heading
-    //testYaw();
+    xBee.baud(9600);
     
     xBee.printf("\nI'm Alive...\n");
     
     //Setup the GPS
     gps.Init();
+    xBee.printf("gps initialized\n");
     
-    gps.parseData();
+    xBee.printf("attempting to get a fix\n");
     
     //wait until we have a gps fix
     while(gps.fixtype == 0)
@@ -55,25 +76,59 @@
     //printf("lat %f\tlon %f\thead %f\talt %f\tspd %f\tfix %d\tsat %d\n", gps.latitude, gps.longitude, gps.heading, gps.altitude, gps.speed, gps.fixtype, gps.satellites);
     //printf("magn %f\tangle %f\tlat %f\tlon %f\tgoalLat %f\tgoalLon %f\n", polarVector[0], polarVector[1], gps.latitude, gps.longitude, goalPos[0], goalPos[1]);
     
+    
+    xBee.printf("starting main loop\n");
     while (1) 
     {
-        // Process / check GPS data
+        //Emergency stop
+        if(xBee.readable())
+        {
+            char tempChar = xBee.getc();
+            if(tempChar == 'n')
+            {
+                xBee.printf("emergency stop\n");
+                goStop(1,1);
+                while(1);
+            }
+        }
+        //check GPS data
+        //xBee.printf("GPS parse data attemp = %d\n", gps.parseData());
         gps.parseData();
         //printf("lat %f\tlon %f\thead %f\talt %f\tspd %f\tfix %d\tsat %d\n", gps.latitude, gps.longitude, gps.heading, gps.altitude, gps.speed, gps.fixtype, gps.satellites);
-        
         //update current position
         curPos[0] = gps.latitude;
         curPos[1] = gps.longitude;
         
-        makeVector();
+        //makeVector();
+        //xBee.printf("Main 3\n");
+        //get data from IMU and do calculations to determine heading
+        //updateAngles();
+        //updateAngles();
         
-        //get data from IMU and do calculations to determine heading
-        updateAngles();
+        float latDif = sqrt((goalPos[0] - curPos[0]) * (goalPos[0] - curPos[0]));
+        float longDif = sqrt((goalPos[1] - curPos[1]) * (goalPos[1] - curPos[1]));
         
-        //decide which way to go
-        char direction = whichWay(yaw, polarVector[1]);
-        xBee.printf("dist %f\tneed %f\tcurrent %f\tdir %c\tlat %f\tlon %f\tgoalLat %f\tgoalLon %f\n", polarVector[0], polarVector[1], yaw, direction, gps.latitude, gps.longitude, goalPos[0], goalPos[1]);
-        wait(PERIOD);
+        //Get absolute value of how far off goal latitude and longitude are from current latitude and longitude
+        //If it is less than tolerance for arriving, stop 
+        if(polarVector[0] <= ARRIVED)
+        {
+            xBee.printf("We Have Arrived\n");
+            goStop(1,1);
+            sCheck = 0;
+            while(1);
+        }
+        
+        if(updateAngles())
+        {
+            makeVector();
+            float magDiff = whichWay(yaw, polarVector[1]);
+            controller.setProcessValue(magDiff);
+            
+            motorSpeed = controller.compute();
+            goForward(0.5f + motorSpeed,0.5f - motorSpeed);
+            wait(RATE);
+        }
+        //xBee.printf("dist %f\tneed %f\tcurrent %f\tdir %c\tlat %f\tlon %f\tgoalLat %f\tgoalLon %f\n", polarVector[0], polarVector[1], yaw, direction, gps.latitude, gps.longitude, goalPos[0], goalPos[1]);
     }
 }
 
@@ -88,8 +143,6 @@
     //X
     arcLength[0] = EARTHRADIUS * (curPos[1] - goalPos[1]);
     
-    //arcLength[0] = EARTHRADIUS * (curPos[1] - goalPos[1]);
-    //arcLength[1] = EARTHRADIUS * (curPos[0] - goalPos[0]);
     //calculate magnitude of vector
     polarVector[0] = sqrt((arcLength[0] * arcLength[0]) + (arcLength[1] * arcLength[1]));
     
@@ -100,32 +153,135 @@
     if(polarVector[1] < 0) polarVector[1] = polarVector[1] + 360;
 }
 
-//Decide which direction to turn based on current compass heading and heading required
-char whichWay(float magHead, float calcHead)
+//Decide which direction to turn based on current compass heading(magHead) and heading required(calcHead)
+float whichWay(float magHead, float calcHead)
 {
+    float magDiff;
     
     float absOfDiff = sqrt((calcHead - magHead) * (calcHead - magHead));
     
     //Is the heading off enough to care?
-    if((absOfDiff >= HEADDIFF) && (absOfDiff <= (360.0f - HEADDIFF)))
+    if((absOfDiff >= HEADDIFF) && (absOfDiff <= (360 - HEADDIFF)))
     {
-        if(calcHead > magHead)
+        //quadrant I
+        if(calcHead < 90)
         {
-            if((calcHead - magHead) < 180)
+            if(calcHead < magHead)
+            {
+                if(magHead < (180 + calcHead))
+                {
+                    //turn left need negative
+                    magDiff = calcHead - magHead;
+                }
+                else
+                {
+                    //turn right need positive
+                    magDiff = calcHead - magHead + 360;
+                }
+            }
+            else
             {
-                return 'R';
+                if(magHead < (180 + calcHead))
+                {
+                    //turn left need negative
+                    magDiff = calcHead - magHead;
+                }
+                else
+                {
+                    //turn right need positive
+                    magDiff = calcHead - magHead + 360;
+                }
+            }
+        }
+        //quadrant II
+        else if(calcHead < 180)
+        {
+            if(calcHead < magHead)
+            {
+                if(magHead < (180 + calcHead))
+                {
+                    //turn left need negative
+                    magDiff = calcHead - magHead;
+                }
+                else
+                {
+                    //turn right need positive
+                    magDiff = calcHead - magHead + 360;
+                }
             }
-            return 'L';
+            else
+            {
+                if(magHead < (180 + calcHead))
+                {
+                    //turn left need negative
+                    magDiff = calcHead - magHead;
+                }
+                else
+                {
+                    //turn right need positive
+                    magDiff = calcHead - magHead + 360;
+                }
+            }
         }
-        else if((magHead - calcHead) < 180)
+        //quadrant III
+        else if(calcHead < 270)
         {
-            return 'L';
+            if(calcHead < magHead)
+            {
+                if(magHead < (180 + calcHead))
+                {
+                    //turn left need negative
+                    magDiff = calcHead - magHead;
+                }
+                else
+                {
+                    //turn right need positive
+                    magDiff = calcHead - magHead + 360;
+                }
+            }
+            else
+            {
+                if(magHead < (180 + calcHead))
+                {
+                    //turn left need negative
+                    magDiff = calcHead - magHead;
+                }
+                else
+                {
+                    //turn right need positive
+                    magDiff = calcHead - magHead + 360;
+                }
+            }
         }
-        return 'R';
+        //quadrant IV
+        else
+        {
+            
+            if(calcHead < magHead)
+            {
+                magDiff = calcHead - magHead;
+            }
+            else
+            {
+                if(magHead < (calcHead - 180))
+                {
+                    
+                    magDiff = calcHead - 360 - magHead;
+                }
+                else
+                {
+                    //turn right need positive
+                    magDiff = calcHead - magHead;
+                }
+            }
+        }
+        return magDiff;
     }
-    return 'G';
+    return 0;
 }
 
+
+
 //Test for verifying heading
 void testYaw(void)
 {