Crude navigation
Dependencies: GPS L3GD20 LSM303DLHC mbed PID
main.cpp
- Committer:
- Spilly
- Date:
- 2015-03-09
- Revision:
- 3:ffa0e1429a72
- Parent:
- 2:503a5ac6c3b6
- Child:
- 4:a397b44a0fe8
File content as of revision 3:ffa0e1429a72:
#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 0.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 0.5f //Period in seconds of PID loop #define RATE 0.1f #define PIDCYCLES 100 //GPS GPS gps(D9, D7); //X-Bee Serial xBee(PTC15, PTC14); //PID //Kc, Ti, Td, interval PID controller(.1, .005, .01, RATE); //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); float whichWay(float magHead, float calcHead); void testYaw(void); int main() { 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); //set mode to auto controller.setMode(1); //We want the difference to be zero controller.setSetPoint(0); xBee.baud(9600); xBee.printf("\nI'm Alive...\n"); //Setup the GPS gps.Init(); xBee.printf("gps initialized\n"); while(!xBee.readable()) { xBee.printf("Press any key to begin\n"); wait(1); } //Test PID heading while(1) { if(updateAngles()) { makeVector(); //set heading to a fixed number for testing float magDiff = whichWay(yaw, 0); controller.setProcessValue(magDiff); motorSpeed = controller.compute(); goForward(0.5f + motorSpeed,0.5f - motorSpeed); xBee.printf("heading = %f\tdiff = %f\tspeed = %f\n", yaw, magDiff, motorSpeed); wait(RATE); } } xBee.printf("attempting to get a fix\n"); //wait until we have a gps fix while(gps.fixtype == 0) { xBee.printf("fix %d\n", gps.fixtype); gps.parseData(); wait(.2); } //set starting position curPos[0] = gps.latitude; curPos[1] = gps.longitude; //Convert starting position and goal position to a vector makeVector(); //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) { //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(); //xBee.printf("Main 3\n"); //get data from IMU and do calculations to determine heading //updateAngles(); //updateAngles(); float latDif = sqrt((goalPos[0] - curPos[0]) * (goalPos[0] - curPos[0])); float longDif = sqrt((goalPos[1] - curPos[1]) * (goalPos[1] - curPos[1])); //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]); } } //create polar vector based on two sets of latitude and longitude void makeVector(void) { float arcLength[2]; //arc length = radius * angle //Y arcLength[1] = EARTHRADIUS * (goalPos[0] - curPos[0]); //X arcLength[0] = EARTHRADIUS * (curPos[1] - goalPos[1]); //calculate magnitude of vector polarVector[0] = sqrt((arcLength[0] * arcLength[0]) + (arcLength[1] * arcLength[1])); //Use arcTan(-x/y) b/c we want our heading to be in respect to North (North = 0 degrees, East = 90 deg, etc.) polarVector[1] = (RADTODEGREE * (atan2(-arcLength[0], arcLength[1]))); //make negative angles positive if(polarVector[1] < 0) polarVector[1] = polarVector[1] + 360; } //Outputs difference in compass heading(magHead) and heading required(calcHead) //negative is left and positive is right 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 - HEADDIFF))) //if(1) { //quadrant I if(calcHead < 90) { 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; } } } //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; } } else { if(magHead < (180 + calcHead)) { //turn left need negative magDiff = calcHead - magHead; } else { //turn right need positive magDiff = calcHead - magHead + 360; } } } //quadrant III else if(calcHead < 270) { 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; } } } //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 0; }