David Spillman / Mbed 2 deprecated GPSNavigationNew

Dependencies:   GPS2 L3GD20 LSM303DLHC2 PID mbed SDFileSystem

Fork of GPSNavigation by David Spillman

Committer:
Spilly
Date:
Thu May 07 16:35:00 2015 +0000
Revision:
16:9d1e72ab7ec7
Parent:
15:1087b8887b53
Child:
17:ba45eaae96b3
Disabled indicator lights

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Spilly 8:c77ab7615b21 1 /************************************************************************************************************************************************************************************************/
Spilly 5:40ac894e0fa7 2 // Created by: Ryan Spillman
Spilly 5:40ac894e0fa7 3 //
Spilly 13:17f04a55c6e2 4 // Last updated 4/29/2015
Spilly 5:40ac894e0fa7 5 //
Spilly 5:40ac894e0fa7 6 // This is the software for my teams autonomous boat that is our graduation/final project at Isothermal Community College
Spilly 5:40ac894e0fa7 7 //
Spilly 5:40ac894e0fa7 8 // The user can drive the vehicle by sending chars over the xBee's serial connection
Spilly 8:c77ab7615b21 9 // GPS waypoints are stored on an external micro-SD card
Spilly 8:c77ab7615b21 10 // The user can record new waypoints to the SD card by driving to a location and entering record mode
Spilly 8:c77ab7615b21 11 // The user can also manually adjust the waypoints with a text editor
Spilly 5:40ac894e0fa7 12 //
Spilly 5:40ac894e0fa7 13 // A PID loop is used to control the heading of the vehicle
Spilly 5:40ac894e0fa7 14 //
Spilly 5:40ac894e0fa7 15 // The project uses a FRDM-K64f (Freescale microcontroller), a LSM303DLHC (magnetometer and accelerometer) to create a tilt compensated comapass,
Spilly 10:b6bf86de613f 16 // MTK3339 GPS module, two xBee Pro S1, three TE KRPA-11 relays (relay logic H-bridge for trolling motor), and a L298n (H-Bridge for linear actuator)
Spilly 8:c77ab7615b21 17 //
Spilly 14:fd20b7ac8de8 18 /**************************************************!!!!!!!WARNING!!!!!!**************************************************************************************************************************/
Spilly 14:fd20b7ac8de8 19 // DO NOT update mbed or SDFileSystem folder
Spilly 14:fd20b7ac8de8 20 // Doing so will/may break this program
Spilly 14:fd20b7ac8de8 21 /**************************************************!!!!!!!WARNING!!!!!!**************************************************************************************************************************/
Spilly 14:fd20b7ac8de8 22 //
Spilly 8:c77ab7615b21 23 /***************************************************How To***************************************************************************************************************************************/
Spilly 8:c77ab7615b21 24 //
Spilly 10:b6bf86de613f 25 // Requires a serial to usb adapter to connect an X-Bee to a PC
Spilly 10:b6bf86de613f 26 // Set both X-Bees up for 115200 baud
Spilly 10:b6bf86de613f 27 // Use TeraTerm (or other serial program) to read and send data over X-Bees
Spilly 12:273479524c71 28 // Set TeraTerm new line character from CR (carrage return) to LF (line feed)
Spilly 8:c77ab7615b21 29 // Program starts by prompting user to press any key
Spilly 8:c77ab7615b21 30 // Once user presses a key, the program waits for a DGPS fix (can be set by changing "FIX")
Spilly 8:c77ab7615b21 31 // Once the program sees a DGPS fix, manual mode is enabled
Spilly 8:c77ab7615b21 32 // User can drive the vehicle in manual mode to any position
Spilly 8:c77ab7615b21 33 // User can record current position to a selected goal position in record mode
Spilly 8:c77ab7615b21 34 // In autonomous mode, the vehicle uses GPS data and compass data to navigate to each goal position
Spilly 8:c77ab7615b21 35 //
Spilly 8:c77ab7615b21 36 // Controls in manual mode:
Spilly 8:c77ab7615b21 37 // directional:
Spilly 8:c77ab7615b21 38 // w = forward
Spilly 8:c77ab7615b21 39 // s = backward
Spilly 8:c77ab7615b21 40 // a = left
Spilly 8:c77ab7615b21 41 // d = right
Spilly 8:c77ab7615b21 42 // mode:
Spilly 8:c77ab7615b21 43 // r = change to record mode
Spilly 8:c77ab7615b21 44 // z = change to autonomous mode
Spilly 8:c77ab7615b21 45 //
Spilly 8:c77ab7615b21 46 // Controls in autonomous mode:
Spilly 8:c77ab7615b21 47 // mode:
Spilly 8:c77ab7615b21 48 // y = change to manual mode
Spilly 8:c77ab7615b21 49 // adjustments:
Spilly 8:c77ab7615b21 50 // d = increase angle
Spilly 8:c77ab7615b21 51 // a = decrease angle
Spilly 8:c77ab7615b21 52 // r = enter new waypoint number
Spilly 8:c77ab7615b21 53 // + = increase (depends on adjust mode)
Spilly 8:c77ab7615b21 54 // - = decrease (depends on adjust mode)
Spilly 8:c77ab7615b21 55 // p = change adjust mode
Spilly 8:c77ab7615b21 56 //
Spilly 8:c77ab7615b21 57 // Controls in record mode:
Spilly 8:c77ab7615b21 58 // *follow serial prompts to record positions
Spilly 8:c77ab7615b21 59 // mode:
Spilly 8:c77ab7615b21 60 // y = change to manual mode
Spilly 8:c77ab7615b21 61 //
Spilly 8:c77ab7615b21 62 /*************************************************************************************************************************************************************************************************/
Spilly 0:e79311aae7ed 63
Spilly 12:273479524c71 64 //unmodified
Spilly 14:fd20b7ac8de8 65 #include "mbed.h" //mbed folder
Spilly 14:fd20b7ac8de8 66 #include "SDFileSystem.h" //SDFileSystem folder
Spilly 12:273479524c71 67
Spilly 12:273479524c71 68 //modified
Spilly 14:fd20b7ac8de8 69 #include "GPS.h" //GPS folder
Spilly 14:fd20b7ac8de8 70 #include "PID.h" //PID folder
Spilly 12:273479524c71 71
Spilly 12:273479524c71 72 //from scratch
Spilly 12:273479524c71 73 #include "IMUDataAndFilters.h"
Spilly 5:40ac894e0fa7 74 #include "navigation.h"
Spilly 8:c77ab7615b21 75 #include "Actuator.h"
Spilly 8:c77ab7615b21 76 #include "TrollingMotor.h"
Spilly 0:e79311aae7ed 77
Spilly 16:9d1e72ab7ec7 78 //#define LIGHT_ON_PERIOD 1.0f
Spilly 16:9d1e72ab7ec7 79 //#define LIGHT_OFF_PERIOD 5.0f
Spilly 14:fd20b7ac8de8 80
Spilly 8:c77ab7615b21 81 #define VOLT_MULT (3.3f / (0.810f / (3.3f + 0.810f))) //voltage divider 3.3k and 810 (VREF = 3.3V) keeps 12V measurements below 3.3V
Spilly 11:1b34319671eb 82 #define RATIO_TOLERANCE 0.02f //How close the difference between the set ratio and current ratio before consider
Spilly 8:c77ab7615b21 83 #define MIN_RATIO 0.04f //Actuator hits retract limit swithc at 2.2%
Spilly 8:c77ab7615b21 84 #define MAX_RATIO 0.85f //Actuator hits extend limit switch at 87.6%
Spilly 8:c77ab7615b21 85 #define CENTER_RATIO 0.29f //Ratio where prop is centered
Spilly 8:c77ab7615b21 86
Spilly 8:c77ab7615b21 87 #define FIX 0 // 2 = DGPS (more accurate but slower to initialize) 1 = GPS only (less accurate but faster to initialize)
Spilly 8:c77ab7615b21 88 #define ARRIVED 5.0f //Tolerance, in meters, for when goal location is reached
Spilly 8:c77ab7615b21 89 #define GPS_ACCUR 3.0f //accuracy of GPS unit
Spilly 8:c77ab7615b21 90 #define GPS_PERIOD 1.0f //GPS polling period (1 Hz)
Spilly 8:c77ab7615b21 91 #define GPS_POLL 0.5f
Spilly 7:ebc76b0f21da 92 #define GPS_ALPHA 0.3f //GPS low pass alpha
Spilly 8:c77ab7615b21 93
Spilly 11:1b34319671eb 94 #define RATE 0.3f //period of heading PID loop
Spilly 8:c77ab7615b21 95 #define headKc 1.0f //directly proportional
Spilly 8:c77ab7615b21 96 #define headTi 0.0f //a larger number makes the integral have less affect on the output
Spilly 8:c77ab7615b21 97 #define headTd 0.0f //a smaller number makes the derivative have less affect on the output
Spilly 12:273479524c71 98
Spilly 12:273479524c71 99 //PID/PID.cpp
Spilly 8:c77ab7615b21 100 PID headingPID(headKc, headTi, headTd, MAGN_PERIOD); //Kc, Ti, Td, interval
Spilly 8:c77ab7615b21 101
Spilly 14:fd20b7ac8de8 102 //mbed classes (mbed folder)
Spilly 5:40ac894e0fa7 103 Timer headingTime;
Spilly 5:40ac894e0fa7 104 Timer acc;
Spilly 5:40ac894e0fa7 105 Timer magn;
Spilly 5:40ac894e0fa7 106 Timer inputTimer;
Spilly 8:c77ab7615b21 107 Timer loopTimer;
Spilly 16:9d1e72ab7ec7 108 //Timer lightTimer;
Spilly 12:273479524c71 109 AnalogIn battery(A0); //analog input from +12v side of linear actuator potentiometer (uses voltage divider)
Spilly 12:273479524c71 110 AnalogIn pot(A1); //analog input from the wiper of linear actuator potentionmeter (uses voltage divider)
Spilly 12:273479524c71 111 DigitalOut ldo(PTC10); //Controls 3.3V LDO v-reg powering MTK3339 (GPS) 1 = GPS powered on and 0 = GPS powered down
Spilly 16:9d1e72ab7ec7 112 //DigitalOut green(D3); //Light output
Spilly 16:9d1e72ab7ec7 113 //DigitalOut white(PTB9); //Light output
Spilly 14:fd20b7ac8de8 114 Serial xBee(PTB11, PTB10); //UART 3 xbee serial
Spilly 14:fd20b7ac8de8 115 //end of mbed classes
Spilly 8:c77ab7615b21 116
Spilly 12:273479524c71 117 //GPS/GPS.cpp
Spilly 14:fd20b7ac8de8 118 GPS gps(PTC15, PTC14); //UART 4 GPS serial
Spilly 12:273479524c71 119
Spilly 12:273479524c71 120 //Not sure where "FILE" is defined
Spilly 12:273479524c71 121 FILE *way; //file pointer for waypoints on SD card
Spilly 12:273479524c71 122 FILE *data; //file pointer for datalog
Spilly 12:273479524c71 123
Spilly 12:273479524c71 124 //SDFileSystem/SDFileSystem.h
Spilly 12:273479524c71 125 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd", PTE6, SDFileSystem::SWITCH_POS_NO, 50000000); //On board microSD
Spilly 8:c77ab7615b21 126
Spilly 8:c77ab7615b21 127 /***************************************************Prototype functions****************************************************************************************************************************/
Spilly 8:c77ab7615b21 128 void getDist(double posZero, double posOne, double curPos[2]);
Spilly 8:c77ab7615b21 129 void getAngle(double posZero, double posOne, double curPos[2], int flush);
Spilly 8:c77ab7615b21 130 /***************************************************End of prototype functions*********************************************************************************************************************/
Spilly 8:c77ab7615b21 131
Spilly 8:c77ab7615b21 132 /***************************************************Global Variables*******************************************************************************************************************************/
Spilly 12:273479524c71 133 //TODO: rewrite polar vector functions to allow elimination of global variables
Spilly 2:503a5ac6c3b6 134
Spilly 12:273479524c71 135 double polarVector[2] = {0,0.0000001f}; //poalarVector[0] = magnitude of vector, polarVector[1] = angle in degrees of vector
Spilly 0:e79311aae7ed 136
Spilly 8:c77ab7615b21 137 /*************************************************************************************************************************************************************************************************/
Spilly 7:ebc76b0f21da 138 // MAIN
Spilly 8:c77ab7615b21 139 /*************************************************************************************************************************************************************************************************/
Spilly 0:e79311aae7ed 140
Spilly 0:e79311aae7ed 141 int main()
Spilly 12:273479524c71 142 {
Spilly 16:9d1e72ab7ec7 143 //int wayPtNum = 0, mode = 0, adjustMode = 0, lightCycle = 0;
Spilly 8:c77ab7615b21 144 int wayPtNum = 0, mode = 0, adjustMode = 0;
Spilly 5:40ac894e0fa7 145 float magDiff = 0;
Spilly 8:c77ab7615b21 146 float batVoltage = 0.0f, potVoltage = 0.0f, voltRatio = 0.0f;
Spilly 8:c77ab7615b21 147 float curSet = 0.0f, prevSet = 0.29f;
Spilly 8:c77ab7615b21 148 float filtered = 0.0000001f;
Spilly 12:273479524c71 149 double curPos[2] = {0,0};
Spilly 12:273479524c71 150 double goalPos[10][2]; //positions are initially read from SD card
Spilly 12:273479524c71 151 //when a position is recorded in record mode, the previously stored position on the SD card is overwritten with the new position
Spilly 12:273479524c71 152
Spilly 12:273479524c71 153 //set the initial state of the lights
Spilly 16:9d1e72ab7ec7 154 //green = 1;
Spilly 16:9d1e72ab7ec7 155 //white = 0;
Spilly 0:e79311aae7ed 156
Spilly 12:273479524c71 157 //turn the GPS 3.3V LDO v-reg on
Spilly 12:273479524c71 158 ldo = 1;
Spilly 12:273479524c71 159 //wait for the GPS unit to boot
Spilly 12:273479524c71 160 wait(1);
Spilly 12:273479524c71 161
Spilly 12:273479524c71 162 //set xBee baud rate
Spilly 5:40ac894e0fa7 163 xBee.baud(115200);
Spilly 0:e79311aae7ed 164 xBee.printf("\nI'm Alive...\n");
Spilly 5:40ac894e0fa7 165 xBee.printf("Press any key to begin\n");
Spilly 5:40ac894e0fa7 166
Spilly 8:c77ab7615b21 167 //wait for keypress to begin
Spilly 5:40ac894e0fa7 168 while(!xBee.readable());
Spilly 5:40ac894e0fa7 169
Spilly 12:273479524c71 170 //Get goal positions from SD card
Spilly 8:c77ab7615b21 171 //start of SD card read
Spilly 12:273479524c71 172 way = fopen ("/sd/GPS_CORDS.txt", "r");
Spilly 8:c77ab7615b21 173
Spilly 8:c77ab7615b21 174 xBee.printf("Reading SD Card Please Wait\n");
Spilly 8:c77ab7615b21 175
Spilly 8:c77ab7615b21 176 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 177 {
Spilly 12:273479524c71 178 fscanf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 179 xBee.printf("waypoint %d = %f,%f\n", x, goalPos[x][0], goalPos[x][1]);
Spilly 8:c77ab7615b21 180 }
Spilly 12:273479524c71 181 fclose(way);
Spilly 8:c77ab7615b21 182 //end of SD card read
Spilly 8:c77ab7615b21 183
Spilly 5:40ac894e0fa7 184 //initialize magnetometer, accelerometer
Spilly 5:40ac894e0fa7 185 compass.init();
Spilly 7:ebc76b0f21da 186 wait(1);
Spilly 0:e79311aae7ed 187 //Setup the GPS
Spilly 0:e79311aae7ed 188 gps.Init();
Spilly 5:40ac894e0fa7 189
Spilly 2:503a5ac6c3b6 190 xBee.printf("gps initialized\n");
Spilly 0:e79311aae7ed 191
Spilly 2:503a5ac6c3b6 192 xBee.printf("attempting to get a fix\n");
Spilly 8:c77ab7615b21 193
Spilly 8:c77ab7615b21 194 while(gps.fixtype != FIX)
Spilly 0:e79311aae7ed 195 {
Spilly 8:c77ab7615b21 196 while(!gps.getData());
Spilly 8:c77ab7615b21 197 if(gps.fixtype == 1)
Spilly 5:40ac894e0fa7 198 {
Spilly 8:c77ab7615b21 199 xBee.printf("Waiting for DGPS fix\tcurrent fix = GPS only\n");
Spilly 8:c77ab7615b21 200 xBee.printf("lat %f\tlon %f\thead %f\talt %f\tspd %f\tfix %d\tsat %d\n", gps.degLat, gps.degLon, gps.heading, gps.altitude, gps.speed, gps.fixtype, gps.satellites);
Spilly 5:40ac894e0fa7 201 }
Spilly 8:c77ab7615b21 202 else xBee.printf("Waiting for DGPS fix\tcurrent fix = no fix\n");
Spilly 0:e79311aae7ed 203 }
Spilly 12:273479524c71 204
Spilly 5:40ac894e0fa7 205 //get IMU data and calculate the tilt compensated compass
Spilly 12:273479524c71 206 getAccel(); //IMUDataAndFilters.h
Spilly 12:273479524c71 207 getMagn(); //IMUDataAndFilters.h
Spilly 12:273479524c71 208 updateAngles(); //IMUDataAndFilters.h
Spilly 5:40ac894e0fa7 209
Spilly 7:ebc76b0f21da 210 xBee.printf("lat %f\tlon %f\thead %f\talt %f\tspd %f\tfix %d\tsat %d\n", gps.degLat, gps.degLon, gps.heading, gps.altitude, gps.speed, gps.fixtype, gps.satellites);
Spilly 5:40ac894e0fa7 211 xBee.printf("dist %f\theading %f\n", polarVector[0], polarVector[1]);
Spilly 7:ebc76b0f21da 212 xBee.printf("\n\nstarting main loop\n");
Spilly 5:40ac894e0fa7 213
Spilly 12:273479524c71 214 //set input constraints (heading difference)
Spilly 5:40ac894e0fa7 215 headingPID.setInputLimits(-180, 180);
Spilly 8:c77ab7615b21 216
Spilly 8:c77ab7615b21 217 //set proportional output limits based on physical limits of actuator and mounting error
Spilly 12:273479524c71 218 float distFromCenter = calcEnds(CENTER_RATIO, MAX_RATIO, MIN_RATIO); //navigation.h
Spilly 8:c77ab7615b21 219
Spilly 12:273479524c71 220 //set output constraints (linear actuator max and min)
Spilly 8:c77ab7615b21 221 headingPID.setOutputLimits((CENTER_RATIO - distFromCenter), (CENTER_RATIO + distFromCenter));
Spilly 5:40ac894e0fa7 222 //set mode to auto
Spilly 5:40ac894e0fa7 223 headingPID.setMode(0);
Spilly 12:273479524c71 224 //We want the difference between actual heading and the heading needed to be zero
Spilly 5:40ac894e0fa7 225 headingPID.setSetPoint(0);
Spilly 0:e79311aae7ed 226
Spilly 12:273479524c71 227 //start timers
Spilly 8:c77ab7615b21 228 loopTimer.start();
Spilly 5:40ac894e0fa7 229 headingTime.start();
Spilly 5:40ac894e0fa7 230 acc.start();
Spilly 5:40ac894e0fa7 231 magn.start();
Spilly 16:9d1e72ab7ec7 232 //lightTimer.start();
Spilly 0:e79311aae7ed 233 while (1)
Spilly 0:e79311aae7ed 234 {
Spilly 8:c77ab7615b21 235 /*********************************************************************************************************************************************************************************************/
Spilly 7:ebc76b0f21da 236 // manual mode
Spilly 8:c77ab7615b21 237 /*********************************************************************************************************************************************************************************************/
Spilly 7:ebc76b0f21da 238
Spilly 5:40ac894e0fa7 239 if(mode == 0)
Spilly 2:503a5ac6c3b6 240 {
Spilly 12:273479524c71 241 //checks to see if all three NEMA sentences from the GPS UART has been received
Spilly 12:273479524c71 242 gps.getData();
Spilly 12:273479524c71 243
Spilly 12:273479524c71 244 //check timer
Spilly 8:c77ab7615b21 245 if(loopTimer.read() > RATE)
Spilly 5:40ac894e0fa7 246 {
Spilly 12:273479524c71 247 //TODO: put this in a function
Spilly 12:273479524c71 248
Spilly 12:273479524c71 249 //This moves actuator to the requested position
Spilly 12:273479524c71 250 //This is proportional feedback ONLY
Spilly 12:273479524c71 251
Spilly 12:273479524c71 252 //read analog input from wiper on potentiometer on linear actuator
Spilly 8:c77ab7615b21 253 potVoltage = pot.read();
Spilly 12:273479524c71 254 //read analog input from battery voltage
Spilly 8:c77ab7615b21 255 batVoltage = battery.read();
Spilly 12:273479524c71 256 //calculate ratio of the two (using a ratio prevents battery voltage fluctuation from affecting actual position)
Spilly 8:c77ab7615b21 257 voltRatio = potVoltage / batVoltage;
Spilly 8:c77ab7615b21 258
Spilly 12:273479524c71 259 //calculate the absolute value of how far off from requested actuator position we are (saves a few processor cycles)
Spilly 8:c77ab7615b21 260 float absDiff = sqrt((prevSet - voltRatio) * (prevSet - voltRatio));
Spilly 12:273479524c71 261 //are we off enough to care? if so, stop moving the actuator
Spilly 8:c77ab7615b21 262 if(absDiff <= RATIO_TOLERANCE)
Spilly 8:c77ab7615b21 263 {
Spilly 8:c77ab7615b21 264 turnStop(1.0f, 1.0f);
Spilly 8:c77ab7615b21 265 //xBee.printf("done\n");
Spilly 8:c77ab7615b21 266 }
Spilly 12:273479524c71 267
Spilly 12:273479524c71 268 //do we need to go further right?
Spilly 8:c77ab7615b21 269 else if((prevSet - voltRatio) >= 0)
Spilly 8:c77ab7615b21 270 {
Spilly 8:c77ab7615b21 271 turnRight(1.0f, 1.0f);
Spilly 8:c77ab7615b21 272 //xBee.printf("turning right\n");
Spilly 8:c77ab7615b21 273 }
Spilly 12:273479524c71 274
Spilly 12:273479524c71 275 //do we need to go further left?
Spilly 8:c77ab7615b21 276 else
Spilly 8:c77ab7615b21 277 {
Spilly 8:c77ab7615b21 278 turnLeft(1.0f, 1.0f);
Spilly 8:c77ab7615b21 279 //xBee.printf("turning left\n");
Spilly 8:c77ab7615b21 280 }
Spilly 12:273479524c71 281 xBee.printf("battery = %f\tpot = %f\tratio = %f\tset %f\tHDOP = %f\tfix = %d\n", (batVoltage * VOLT_MULT), (potVoltage* VOLT_MULT), voltRatio, prevSet, gps.HDOP, gps.fixtype);
Spilly 12:273479524c71 282
Spilly 12:273479524c71 283 //reset timer to zero
Spilly 8:c77ab7615b21 284 loopTimer.reset();
Spilly 5:40ac894e0fa7 285 }
Spilly 12:273479524c71 286
Spilly 7:ebc76b0f21da 287 //check to see if data is available on xBee
Spilly 5:40ac894e0fa7 288 if(xBee.readable())
Spilly 2:503a5ac6c3b6 289 {
Spilly 12:273479524c71 290
Spilly 12:273479524c71 291 //TODO: put this in a function
Spilly 12:273479524c71 292
Spilly 5:40ac894e0fa7 293 char recChar = xBee.getc();
Spilly 5:40ac894e0fa7 294
Spilly 5:40ac894e0fa7 295 //change to autonomous mode
Spilly 5:40ac894e0fa7 296 if(recChar == 'z')
Spilly 5:40ac894e0fa7 297 {
Spilly 8:c77ab7615b21 298 xBee.printf("Changing to autonomous mode\n");
Spilly 8:c77ab7615b21 299 goStop();
Spilly 5:40ac894e0fa7 300 mode = 1;
Spilly 5:40ac894e0fa7 301 }
Spilly 5:40ac894e0fa7 302 //change to record mode
Spilly 8:c77ab7615b21 303 else if(recChar == 'r')
Spilly 5:40ac894e0fa7 304 {
Spilly 8:c77ab7615b21 305 xBee.printf("Changing to record mode\n");
Spilly 8:c77ab7615b21 306 goStop();
Spilly 5:40ac894e0fa7 307 mode = 3;
Spilly 5:40ac894e0fa7 308 }
Spilly 12:273479524c71 309 else if(recChar == '<')
Spilly 12:273479524c71 310 {
Spilly 12:273479524c71 311 xBee.printf("Power cycling GPS\nPlease wait\n");
Spilly 12:273479524c71 312 goStop();
Spilly 12:273479524c71 313 ldo = 0;
Spilly 12:273479524c71 314 wait(0.5);
Spilly 12:273479524c71 315 ldo = 1;
Spilly 12:273479524c71 316 wait(0.5);
Spilly 12:273479524c71 317 }
Spilly 8:c77ab7615b21 318 else if(recChar == '1')
Spilly 8:c77ab7615b21 319 {
Spilly 8:c77ab7615b21 320 xBee.printf("stop\n");
Spilly 8:c77ab7615b21 321 goStop();
Spilly 8:c77ab7615b21 322 }
Spilly 8:c77ab7615b21 323 else if(recChar == 'w')
Spilly 5:40ac894e0fa7 324 {
Spilly 8:c77ab7615b21 325 goForward();
Spilly 8:c77ab7615b21 326 prevSet = CENTER_RATIO;
Spilly 8:c77ab7615b21 327 xBee.printf("Forward\n");
Spilly 8:c77ab7615b21 328 }
Spilly 8:c77ab7615b21 329 else if(recChar == 's')
Spilly 8:c77ab7615b21 330 {
Spilly 8:c77ab7615b21 331 goBackward();
Spilly 8:c77ab7615b21 332 prevSet = CENTER_RATIO;
Spilly 8:c77ab7615b21 333 xBee.printf("backward\n");
Spilly 8:c77ab7615b21 334 }
Spilly 8:c77ab7615b21 335 else if(recChar == 'd')
Spilly 8:c77ab7615b21 336 {
Spilly 8:c77ab7615b21 337 xBee.printf("large step right\n");
Spilly 5:40ac894e0fa7 338
Spilly 8:c77ab7615b21 339 //find the best step size since 0.1 step will go over the limit
Spilly 8:c77ab7615b21 340 if(prevSet + 0.1f > MAX_RATIO)
Spilly 8:c77ab7615b21 341 {
Spilly 8:c77ab7615b21 342 prevSet = prevSet + (MAX_RATIO - prevSet);
Spilly 8:c77ab7615b21 343 }
Spilly 8:c77ab7615b21 344 else
Spilly 8:c77ab7615b21 345 {
Spilly 8:c77ab7615b21 346 prevSet = prevSet + 0.1f;
Spilly 8:c77ab7615b21 347 }
Spilly 8:c77ab7615b21 348 xBee.printf("set = %f\n", prevSet);
Spilly 5:40ac894e0fa7 349 }
Spilly 8:c77ab7615b21 350 //large step left
Spilly 8:c77ab7615b21 351 else if(recChar == 'a')
Spilly 5:40ac894e0fa7 352 {
Spilly 8:c77ab7615b21 353 xBee.printf("large step left\n");
Spilly 8:c77ab7615b21 354 //find the best step size since 0.1 step will go over the limit
Spilly 8:c77ab7615b21 355 if(prevSet - 0.1f < MIN_RATIO)
Spilly 8:c77ab7615b21 356 {
Spilly 8:c77ab7615b21 357 prevSet = prevSet - (prevSet - MIN_RATIO);
Spilly 8:c77ab7615b21 358 }
Spilly 8:c77ab7615b21 359 else
Spilly 8:c77ab7615b21 360 {
Spilly 8:c77ab7615b21 361 prevSet = prevSet - 0.1f;
Spilly 8:c77ab7615b21 362 }
Spilly 8:c77ab7615b21 363 xBee.printf("set = %f\n", prevSet);
Spilly 5:40ac894e0fa7 364 }
Spilly 8:c77ab7615b21 365 //small step right
Spilly 8:c77ab7615b21 366 else if(recChar == 'e')
Spilly 5:40ac894e0fa7 367 {
Spilly 8:c77ab7615b21 368 xBee.printf("small step right\n");
Spilly 8:c77ab7615b21 369 if(prevSet + 0.01f > MAX_RATIO)
Spilly 8:c77ab7615b21 370 {
Spilly 8:c77ab7615b21 371 prevSet = prevSet + (MAX_RATIO - prevSet);
Spilly 8:c77ab7615b21 372 }
Spilly 8:c77ab7615b21 373 else
Spilly 8:c77ab7615b21 374 {
Spilly 8:c77ab7615b21 375 prevSet = prevSet + 0.01f;
Spilly 8:c77ab7615b21 376 }
Spilly 8:c77ab7615b21 377 xBee.printf("set = %f\n", prevSet);
Spilly 8:c77ab7615b21 378 }
Spilly 8:c77ab7615b21 379 else if(recChar == 'q')
Spilly 8:c77ab7615b21 380 {
Spilly 8:c77ab7615b21 381 xBee.printf("Small step left\n");
Spilly 8:c77ab7615b21 382 if(prevSet - 0.01f < MIN_RATIO)
Spilly 8:c77ab7615b21 383 {
Spilly 8:c77ab7615b21 384 prevSet = prevSet - (prevSet - MIN_RATIO);
Spilly 8:c77ab7615b21 385 }
Spilly 8:c77ab7615b21 386 else
Spilly 8:c77ab7615b21 387 {
Spilly 8:c77ab7615b21 388 prevSet = prevSet - 0.01f;
Spilly 8:c77ab7615b21 389 }
Spilly 8:c77ab7615b21 390 xBee.printf("set = %f\n", prevSet);
Spilly 5:40ac894e0fa7 391 }
Spilly 2:503a5ac6c3b6 392 }
Spilly 16:9d1e72ab7ec7 393 /*
Spilly 16:9d1e72ab7ec7 394 if(lightCycle == 0)
Spilly 16:9d1e72ab7ec7 395 {
Spilly 16:9d1e72ab7ec7 396 if(lightTimer.read() >= LIGHT_OFF_PERIOD)
Spilly 16:9d1e72ab7ec7 397 {
Spilly 16:9d1e72ab7ec7 398 green = 0;
Spilly 16:9d1e72ab7ec7 399 white = 0;
Spilly 16:9d1e72ab7ec7 400 lightCycle = 1;
Spilly 16:9d1e72ab7ec7 401 lightTimer.reset();
Spilly 16:9d1e72ab7ec7 402 }
Spilly 16:9d1e72ab7ec7 403 }
Spilly 16:9d1e72ab7ec7 404 else if(lightCycle == 1)
Spilly 16:9d1e72ab7ec7 405 {
Spilly 16:9d1e72ab7ec7 406 if(lightTimer.read() >= LIGHT_ON_PERIOD)
Spilly 16:9d1e72ab7ec7 407 {
Spilly 16:9d1e72ab7ec7 408 green = 1;
Spilly 16:9d1e72ab7ec7 409 white = 1;
Spilly 16:9d1e72ab7ec7 410 lightCycle = 0;
Spilly 16:9d1e72ab7ec7 411 lightTimer.reset();
Spilly 16:9d1e72ab7ec7 412 }
Spilly 16:9d1e72ab7ec7 413 }
Spilly 16:9d1e72ab7ec7 414 */
Spilly 2:503a5ac6c3b6 415 }
Spilly 7:ebc76b0f21da 416
Spilly 8:c77ab7615b21 417 /*********************************************************************************************************************************************************************************************/
Spilly 8:c77ab7615b21 418 // autonomous mode
Spilly 8:c77ab7615b21 419 /*********************************************************************************************************************************************************************************************/
Spilly 12:273479524c71 420 //default trolling motor state when entering autonomous mode is off (user must press "w" to go forward)
Spilly 5:40ac894e0fa7 421 if(mode == 1)
Spilly 2:503a5ac6c3b6 422 {
Spilly 7:ebc76b0f21da 423 //check xBee
Spilly 5:40ac894e0fa7 424 if(xBee.readable())
Spilly 2:503a5ac6c3b6 425 {
Spilly 12:273479524c71 426 //TODO: put this in a function
Spilly 12:273479524c71 427
Spilly 5:40ac894e0fa7 428 char recChar = xBee.getc();
Spilly 12:273479524c71 429 //stop
Spilly 8:c77ab7615b21 430 if(recChar == '1')
Spilly 2:503a5ac6c3b6 431 {
Spilly 8:c77ab7615b21 432 xBee.printf("stop\n");
Spilly 8:c77ab7615b21 433 goStop();
Spilly 8:c77ab7615b21 434 }
Spilly 12:273479524c71 435 //go forward
Spilly 8:c77ab7615b21 436 if(recChar == 'w')
Spilly 8:c77ab7615b21 437 {
Spilly 8:c77ab7615b21 438 xBee.printf("forward\n");
Spilly 8:c77ab7615b21 439 goForward();
Spilly 2:503a5ac6c3b6 440 }
Spilly 5:40ac894e0fa7 441 //change to manual mode
Spilly 5:40ac894e0fa7 442 if(recChar == 'y')
Spilly 2:503a5ac6c3b6 443 {
Spilly 8:c77ab7615b21 444 xBee.printf("Changing to manual mode\n");
Spilly 8:c77ab7615b21 445 goStop();
Spilly 5:40ac894e0fa7 446 mode = 0;
Spilly 7:ebc76b0f21da 447 wayPtNum = 0;
Spilly 2:503a5ac6c3b6 448 }
Spilly 8:c77ab7615b21 449 //increase calculated heading (use this to tweak/cheat calculated heading)
Spilly 8:c77ab7615b21 450 else if(recChar == 'd')
Spilly 8:c77ab7615b21 451 {
Spilly 8:c77ab7615b21 452 polarVector[1] = polarVector[1] + 1;
Spilly 8:c77ab7615b21 453 xBee.printf("increased angle %f\n", polarVector[1]);
Spilly 8:c77ab7615b21 454 }
Spilly 8:c77ab7615b21 455 //reduce calculated heading (use this to tweak/cheat calculated heading)
Spilly 8:c77ab7615b21 456 else if(recChar == 'a')
Spilly 8:c77ab7615b21 457 {
Spilly 8:c77ab7615b21 458 polarVector[1] = polarVector[1] - 1;
Spilly 8:c77ab7615b21 459 xBee.printf("reduced angle %f\n", polarVector[1]);
Spilly 8:c77ab7615b21 460 }
Spilly 12:273479524c71 461
Spilly 12:273479524c71 462 //increments settings based on adjust mode
Spilly 8:c77ab7615b21 463 else if(recChar == '+')
Spilly 8:c77ab7615b21 464 {
Spilly 12:273479524c71 465 //adjust waypoint
Spilly 8:c77ab7615b21 466 if(adjustMode == 0)
Spilly 8:c77ab7615b21 467 {
Spilly 8:c77ab7615b21 468 if(wayPtNum != 9)
Spilly 8:c77ab7615b21 469 {
Spilly 8:c77ab7615b21 470 wayPtNum ++;
Spilly 8:c77ab7615b21 471 xBee.printf("waypoint increased to %d\n", wayPtNum);
Spilly 8:c77ab7615b21 472 }
Spilly 8:c77ab7615b21 473 else
Spilly 8:c77ab7615b21 474 {
Spilly 8:c77ab7615b21 475 xBee.printf("maximum waypoint reached\n");
Spilly 8:c77ab7615b21 476 }
Spilly 8:c77ab7615b21 477 }
Spilly 12:273479524c71 478 //increment proportional gain of heading PID
Spilly 8:c77ab7615b21 479 else if(adjustMode == 1)
Spilly 8:c77ab7615b21 480 {
Spilly 8:c77ab7615b21 481 float curKc = headingPID.getPParam();
Spilly 8:c77ab7615b21 482 float curTi = headingPID.getIParam();
Spilly 8:c77ab7615b21 483 float curTd = headingPID.getDParam();
Spilly 8:c77ab7615b21 484 curKc = curKc + 0.1f;
Spilly 8:c77ab7615b21 485 headingPID.setTunings(curKc, curTi, curTd);
Spilly 8:c77ab7615b21 486 xBee.printf("Kc set to %f\n", curKc);
Spilly 8:c77ab7615b21 487 }
Spilly 12:273479524c71 488 //increment integral gain of heading PID
Spilly 8:c77ab7615b21 489 else if(adjustMode == 2)
Spilly 8:c77ab7615b21 490 {
Spilly 8:c77ab7615b21 491 float curKc = headingPID.getPParam();
Spilly 8:c77ab7615b21 492 float curTi = headingPID.getIParam();
Spilly 8:c77ab7615b21 493 float curTd = headingPID.getDParam();
Spilly 8:c77ab7615b21 494 curTi = curTi + 0.1f;
Spilly 8:c77ab7615b21 495 headingPID.setTunings(curKc, curTi, curTd);
Spilly 8:c77ab7615b21 496 xBee.printf("Ti set to %f\n", curTi);
Spilly 8:c77ab7615b21 497 }
Spilly 12:273479524c71 498 //increment derivative gain of heading PID
Spilly 8:c77ab7615b21 499 else if(adjustMode == 3)
Spilly 8:c77ab7615b21 500 {
Spilly 8:c77ab7615b21 501 float curKc = headingPID.getPParam();
Spilly 8:c77ab7615b21 502 float curTi = headingPID.getIParam();
Spilly 8:c77ab7615b21 503 float curTd = headingPID.getDParam();
Spilly 8:c77ab7615b21 504 curTd = curTd + 0.1f;
Spilly 8:c77ab7615b21 505 headingPID.setTunings(curKc, curTi, curTd);
Spilly 8:c77ab7615b21 506 xBee.printf("Td set to %f\n", curTd);
Spilly 8:c77ab7615b21 507 }
Spilly 8:c77ab7615b21 508 }
Spilly 12:273479524c71 509 //decrements setting based on adjust mode
Spilly 8:c77ab7615b21 510 else if(recChar == '-')
Spilly 8:c77ab7615b21 511 {
Spilly 8:c77ab7615b21 512 if(adjustMode == 0)
Spilly 8:c77ab7615b21 513 {
Spilly 8:c77ab7615b21 514 if(wayPtNum != 0)
Spilly 8:c77ab7615b21 515 {
Spilly 8:c77ab7615b21 516 wayPtNum --;
Spilly 8:c77ab7615b21 517 xBee.printf("waypoint increased to %d\n", wayPtNum);
Spilly 8:c77ab7615b21 518 }
Spilly 8:c77ab7615b21 519 else
Spilly 8:c77ab7615b21 520 {
Spilly 8:c77ab7615b21 521 xBee.printf("minimum waypoint reached\n");
Spilly 8:c77ab7615b21 522 }
Spilly 8:c77ab7615b21 523 }
Spilly 12:273479524c71 524 //decrement proportional gain of heading PID
Spilly 8:c77ab7615b21 525 else if(adjustMode == 1)
Spilly 8:c77ab7615b21 526 {
Spilly 8:c77ab7615b21 527 float curKc = headingPID.getPParam();
Spilly 8:c77ab7615b21 528 float curTi = headingPID.getIParam();
Spilly 8:c77ab7615b21 529 float curTd = headingPID.getDParam();
Spilly 8:c77ab7615b21 530 curKc = curKc - 0.1f;
Spilly 8:c77ab7615b21 531 headingPID.setTunings(curKc, curTi, curTd);
Spilly 8:c77ab7615b21 532 xBee.printf("Kc set to %f\n", curKc);
Spilly 8:c77ab7615b21 533 }
Spilly 12:273479524c71 534 //decrement integral gain of heading PID
Spilly 8:c77ab7615b21 535 else if(adjustMode == 2)
Spilly 8:c77ab7615b21 536 {
Spilly 8:c77ab7615b21 537 float curKc = headingPID.getPParam();
Spilly 8:c77ab7615b21 538 float curTi = headingPID.getIParam();
Spilly 8:c77ab7615b21 539 float curTd = headingPID.getDParam();
Spilly 8:c77ab7615b21 540 curTi = curTi - 0.1f;
Spilly 8:c77ab7615b21 541 headingPID.setTunings(curKc, curTi, curTd);
Spilly 8:c77ab7615b21 542 xBee.printf("Ti set to %f\n", curTi);
Spilly 8:c77ab7615b21 543 }
Spilly 12:273479524c71 544 //decrement derivative gain of heading PID
Spilly 8:c77ab7615b21 545 else if(adjustMode == 3)
Spilly 8:c77ab7615b21 546 {
Spilly 8:c77ab7615b21 547 float curKc = headingPID.getPParam();
Spilly 8:c77ab7615b21 548 float curTi = headingPID.getIParam();
Spilly 8:c77ab7615b21 549 float curTd = headingPID.getDParam();
Spilly 8:c77ab7615b21 550 curTd = curTd - 0.1f;
Spilly 8:c77ab7615b21 551 headingPID.setTunings(curKc, curTi, curTd);
Spilly 8:c77ab7615b21 552 xBee.printf("Td set to %f\n", curTd);
Spilly 8:c77ab7615b21 553 }
Spilly 8:c77ab7615b21 554 }
Spilly 12:273479524c71 555 //change or reset current waypoint number
Spilly 8:c77ab7615b21 556 else if(recChar == 'r')
Spilly 8:c77ab7615b21 557 {
Spilly 8:c77ab7615b21 558 goStop();
Spilly 8:c77ab7615b21 559 //wayPtNum = 0;
Spilly 8:c77ab7615b21 560 //xBee.printf("waypoint count reset\n");
Spilly 8:c77ab7615b21 561 xBee.printf("Please enter desired waypoint (0-9)\t or press r to reset to zero\n");
Spilly 8:c77ab7615b21 562 while(!xBee.readable());
Spilly 8:c77ab7615b21 563 char tempWS[2];
Spilly 8:c77ab7615b21 564 tempWS[0] = xBee.getc();
Spilly 12:273479524c71 565
Spilly 12:273479524c71 566 //press "r" again to reset waypoint number to zero
Spilly 8:c77ab7615b21 567 if(tempWS[0] == 'r')
Spilly 8:c77ab7615b21 568 {
Spilly 8:c77ab7615b21 569 wayPtNum = 0;
Spilly 8:c77ab7615b21 570 }
Spilly 12:273479524c71 571
Spilly 12:273479524c71 572 //else enter the number of waypoint desired
Spilly 8:c77ab7615b21 573 else
Spilly 8:c77ab7615b21 574 {
Spilly 8:c77ab7615b21 575 sscanf(tempWS, "%d", &wayPtNum);
Spilly 8:c77ab7615b21 576 xBee.printf("waypoint is now %d\n", wayPtNum);
Spilly 8:c77ab7615b21 577 }
Spilly 8:c77ab7615b21 578 }
Spilly 12:273479524c71 579 //change adjust mode
Spilly 8:c77ab7615b21 580 else if(recChar == 'p')
Spilly 8:c77ab7615b21 581 {
Spilly 8:c77ab7615b21 582 xBee.printf("To set adjust mode:\nEnter w to adjust waypoint number\nEnter c to adjust Kc\nEnter i to adjust Ti\nEnter d to adjust Td\nEnter z to exit\n");
Spilly 8:c77ab7615b21 583 while(!xBee.readable());
Spilly 8:c77ab7615b21 584 char recCharTemp = xBee.getc();
Spilly 12:273479524c71 585
Spilly 12:273479524c71 586 //set adjust to edit waypoints
Spilly 8:c77ab7615b21 587 if(recCharTemp == 'w')
Spilly 8:c77ab7615b21 588 {
Spilly 8:c77ab7615b21 589 adjustMode = 0;
Spilly 8:c77ab7615b21 590 }
Spilly 12:273479524c71 591
Spilly 12:273479524c71 592 //set adjust to edit proportional gain
Spilly 8:c77ab7615b21 593 else if(recCharTemp == 'c')
Spilly 8:c77ab7615b21 594 {
Spilly 8:c77ab7615b21 595 adjustMode = 1;
Spilly 8:c77ab7615b21 596 xBee.printf("Adjust mode set to Kc\tEnter + to increment and - to decrement Kc\n");
Spilly 8:c77ab7615b21 597 }
Spilly 12:273479524c71 598
Spilly 12:273479524c71 599 //set adjust to edit integral gain
Spilly 8:c77ab7615b21 600 else if(recCharTemp == 'i')
Spilly 8:c77ab7615b21 601 {
Spilly 8:c77ab7615b21 602 adjustMode = 2;
Spilly 8:c77ab7615b21 603 xBee.printf("Adjust mode set to Ti\tEnter + to increment and - to decrement Ti\n");
Spilly 8:c77ab7615b21 604 }
Spilly 12:273479524c71 605
Spilly 12:273479524c71 606 //set adjust to edit derivative gain
Spilly 8:c77ab7615b21 607 else if(recCharTemp == 'd')
Spilly 8:c77ab7615b21 608 {
Spilly 8:c77ab7615b21 609 adjustMode = 3;
Spilly 8:c77ab7615b21 610 xBee.printf("Adjust mode set to Td\tEnter + to increment and - to decrement Td\n");
Spilly 8:c77ab7615b21 611 }
Spilly 12:273479524c71 612 //if any other key is pressed no change to adjust mode is made
Spilly 8:c77ab7615b21 613 else
Spilly 8:c77ab7615b21 614 {
Spilly 8:c77ab7615b21 615 xBee.printf("No changes made\n");
Spilly 8:c77ab7615b21 616 }
Spilly 8:c77ab7615b21 617 }
Spilly 2:503a5ac6c3b6 618 }
Spilly 12:273479524c71 619 //if no xBee data is received
Spilly 15:1087b8887b53 620 //else
Spilly 15:1087b8887b53 621 //{
Spilly 12:273479524c71 622
Spilly 12:273479524c71 623 //TODO: put this in a function
Spilly 12:273479524c71 624
Spilly 12:273479524c71 625 //checks to see if all three NEMA sentences from the GPS UART has been received
Spilly 8:c77ab7615b21 626 if(gps.getData())
Spilly 2:503a5ac6c3b6 627 {
Spilly 8:c77ab7615b21 628 double tempPos[2] = {0,0};
Spilly 5:40ac894e0fa7 629
Spilly 12:273479524c71 630 //store most recent gps location in a temporary variable (using temporary variables because GPS data is accumulated in a low pass filter)
Spilly 8:c77ab7615b21 631 tempPos[0] = gps.degLat;
Spilly 8:c77ab7615b21 632 tempPos[1] = gps.degLon;
Spilly 12:273479524c71 633
Spilly 12:273479524c71 634 //calculate the magnitude of the vector
Spilly 8:c77ab7615b21 635 getDist(goalPos[wayPtNum][0],goalPos[wayPtNum][1], tempPos);
Spilly 12:273479524c71 636
Spilly 12:273479524c71 637 //calculate the angle of the vector
Spilly 8:c77ab7615b21 638 getAngle(goalPos[wayPtNum][0],goalPos[wayPtNum][1], tempPos, 0);
Spilly 5:40ac894e0fa7 639
Spilly 12:273479524c71 640 //checks if the magnitude of distance from goal position is less than threshold for "arriving"
Spilly 5:40ac894e0fa7 641 if(polarVector[0] <= ARRIVED)
Spilly 5:40ac894e0fa7 642 {
Spilly 5:40ac894e0fa7 643 xBee.printf("Goal Position %d reached!\n", wayPtNum);
Spilly 5:40ac894e0fa7 644 wait(1);
Spilly 12:273479524c71 645
Spilly 12:273479524c71 646 //increment waypoint number
Spilly 5:40ac894e0fa7 647 wayPtNum ++;
Spilly 12:273479524c71 648
Spilly 12:273479524c71 649 //we only have ten waypoints so we mus stop at ten
Spilly 12:273479524c71 650 if(wayPtNum >= 10)
Spilly 5:40ac894e0fa7 651 {
Spilly 5:40ac894e0fa7 652 xBee.printf("Final Position Reached!\nShutting down\n");
Spilly 8:c77ab7615b21 653 goStop();
Spilly 8:c77ab7615b21 654 mode = 0;
Spilly 8:c77ab7615b21 655 //while(1);
Spilly 8:c77ab7615b21 656 }
Spilly 8:c77ab7615b21 657 else
Spilly 8:c77ab7615b21 658 {
Spilly 8:c77ab7615b21 659 //flush heading PID data since we have a new heading
Spilly 8:c77ab7615b21 660 headingPID.reset();
Spilly 12:273479524c71 661
Spilly 12:273479524c71 662 //calculate the angle of the vector
Spilly 8:c77ab7615b21 663 getAngle(goalPos[wayPtNum ][0],goalPos[wayPtNum][1], goalPos[wayPtNum - 1], 1);
Spilly 12:273479524c71 664
Spilly 8:c77ab7615b21 665 xBee.printf("Moving to Goal Position %d\theading = %f\n", wayPtNum, polarVector[1]);
Spilly 5:40ac894e0fa7 666 }
Spilly 8:c77ab7615b21 667 }
Spilly 8:c77ab7615b21 668 }
Spilly 8:c77ab7615b21 669
Spilly 12:273479524c71 670 //time to read accelerometer?
Spilly 8:c77ab7615b21 671 if(acc.read() >= ACCEL_PERIOD)
Spilly 8:c77ab7615b21 672 {
Spilly 12:273479524c71 673 //get accelerometer data
Spilly 8:c77ab7615b21 674 getAccel();
Spilly 12:273479524c71 675
Spilly 12:273479524c71 676 //reset timer to zero
Spilly 8:c77ab7615b21 677 acc.reset();
Spilly 8:c77ab7615b21 678 }
Spilly 12:273479524c71 679
Spilly 12:273479524c71 680 //time to read magnatometer and calculate heading PID?
Spilly 8:c77ab7615b21 681 if(magn.read() >= MAGN_PERIOD)
Spilly 8:c77ab7615b21 682 {
Spilly 12:273479524c71 683 //get magnatometer data
Spilly 12:273479524c71 684 getMagn(); //IMUDataAndFilters.h
Spilly 12:273479524c71 685 updateAngles(); //IMUDataAndFilters.h
Spilly 12:273479524c71 686 filtered = lowPass(yaw, filtered, 0); //IMUDataAndFilters.h
Spilly 12:273479524c71 687 magDiff = whichWay(filtered, 0); //navigation.h
Spilly 12:273479524c71 688
Spilly 12:273479524c71 689 //give PID input
Spilly 8:c77ab7615b21 690 headingPID.setProcessValue(-magDiff);
Spilly 12:273479524c71 691
Spilly 12:273479524c71 692 //get output from PID
Spilly 8:c77ab7615b21 693 curSet = headingPID.compute();
Spilly 12:273479524c71 694
Spilly 12:273479524c71 695 //reset timer to zero
Spilly 8:c77ab7615b21 696 magn.reset();
Spilly 8:c77ab7615b21 697 }
Spilly 8:c77ab7615b21 698
Spilly 8:c77ab7615b21 699 //This moves actuator to the requested position
Spilly 8:c77ab7615b21 700 //This is proportional feedback only
Spilly 8:c77ab7615b21 701 if(loopTimer.read() > RATE)
Spilly 8:c77ab7615b21 702 {
Spilly 12:273479524c71 703 //TODO: put this in a function
Spilly 12:273479524c71 704
Spilly 12:273479524c71 705 //This moves actuator to the requested position
Spilly 12:273479524c71 706 //This is proportional feedback ONLY
Spilly 12:273479524c71 707
Spilly 12:273479524c71 708 //read analog input from wiper on potentiometer on linear actuator
Spilly 8:c77ab7615b21 709 potVoltage = pot.read();
Spilly 12:273479524c71 710 //read analog input from battery voltage
Spilly 8:c77ab7615b21 711 batVoltage = battery.read();
Spilly 12:273479524c71 712 //calculate ratio of the two (using a ratio prevents battery voltage fluctuation from affecting actual position)
Spilly 8:c77ab7615b21 713 voltRatio = potVoltage / batVoltage;
Spilly 8:c77ab7615b21 714
Spilly 12:273479524c71 715 //calculate the absolute value of how far off from requested actuator position we are (saves a few processor cycles)
Spilly 8:c77ab7615b21 716 float absDiff = sqrt((curSet - voltRatio) * (curSet - voltRatio));
Spilly 12:273479524c71 717
Spilly 12:273479524c71 718 //are we off enough to care? if so, stop moving the actuator
Spilly 8:c77ab7615b21 719 if(absDiff <= RATIO_TOLERANCE)
Spilly 8:c77ab7615b21 720 {
Spilly 8:c77ab7615b21 721 turnStop(1.0f, 1.0f);
Spilly 12:273479524c71 722 //xBee.printf("done\n");
Spilly 8:c77ab7615b21 723 }
Spilly 12:273479524c71 724 //do we need to turn right?
Spilly 8:c77ab7615b21 725 else if((curSet - voltRatio) >= 0)
Spilly 8:c77ab7615b21 726 {
Spilly 8:c77ab7615b21 727 if(voltRatio > MAX_RATIO)
Spilly 8:c77ab7615b21 728 {
Spilly 12:273479524c71 729 //xBee.printf("Max Limit Reached\n");
Spilly 8:c77ab7615b21 730 turnStop(1.0f, 1.0f);
Spilly 8:c77ab7615b21 731 }
Spilly 8:c77ab7615b21 732 else
Spilly 8:c77ab7615b21 733 {
Spilly 8:c77ab7615b21 734 turnRight(1.0f, 1.0f);
Spilly 12:273479524c71 735 //xBee.printf("turning Right\n");
Spilly 8:c77ab7615b21 736 }
Spilly 8:c77ab7615b21 737 }
Spilly 12:273479524c71 738 //do we need to turn left?
Spilly 8:c77ab7615b21 739 else
Spilly 8:c77ab7615b21 740 {
Spilly 8:c77ab7615b21 741 if(voltRatio < MIN_RATIO)
Spilly 8:c77ab7615b21 742 {
Spilly 12:273479524c71 743 //xBee.printf("Min Limit Reached\n");
Spilly 8:c77ab7615b21 744 turnStop(1.0f, 1.0f);
Spilly 8:c77ab7615b21 745 }
Spilly 8:c77ab7615b21 746 else
Spilly 8:c77ab7615b21 747 {
Spilly 8:c77ab7615b21 748 turnLeft(1.0f, 1.0f);
Spilly 12:273479524c71 749 //xBee.printf("turning Left\n");
Spilly 8:c77ab7615b21 750 }
Spilly 8:c77ab7615b21 751 }
Spilly 12:273479524c71 752
Spilly 12:273479524c71 753 xBee.printf("lat %f\tlon %f\thead %f\talt %f\tspd %f\tfix %d\tsat %d\n", gps.degLat, gps.degLon, gps.heading, gps.altitude, gps.speed, gps.fixtype, gps.satellites);
Spilly 12:273479524c71 754
Spilly 12:273479524c71 755 //record data to SD card
Spilly 12:273479524c71 756 data = fopen("/sd/data.txt", "a");
Spilly 12:273479524c71 757 fprintf(data, "%d,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n", wayPtNum, (batVoltage * VOLT_MULT), voltRatio, curSet, filtered, magDiff, polarVector[0], gps.degLat, gps.degLon, gps.heading, gps.altitude, gps.speed, gps.fixtype, gps.satellites);
Spilly 12:273479524c71 758 fclose(data);
Spilly 12:273479524c71 759
Spilly 12:273479524c71 760 //reset timer to zero
Spilly 8:c77ab7615b21 761 loopTimer.reset();
Spilly 2:503a5ac6c3b6 762 }
Spilly 15:1087b8887b53 763 //}
Spilly 0:e79311aae7ed 764 }
Spilly 7:ebc76b0f21da 765
Spilly 8:c77ab7615b21 766 /*********************************************************************************************************************************************************************************************/
Spilly 7:ebc76b0f21da 767 // record position mode
Spilly 8:c77ab7615b21 768 /*********************************************************************************************************************************************************************************************/
Spilly 7:ebc76b0f21da 769
Spilly 5:40ac894e0fa7 770 if(mode == 3)
Spilly 0:e79311aae7ed 771 {
Spilly 12:273479524c71 772 //stop the trolling motor
Spilly 8:c77ab7615b21 773 goStop();
Spilly 12:273479524c71 774
Spilly 7:ebc76b0f21da 775 xBee.printf("\nPlease enter position number (0-9), or press y to return to manual mode\n");
Spilly 5:40ac894e0fa7 776
Spilly 5:40ac894e0fa7 777 while(!xBee.readable());
Spilly 5:40ac894e0fa7 778 char recChar = xBee.getc();
Spilly 5:40ac894e0fa7 779 recChar = xBee.getc();
Spilly 7:ebc76b0f21da 780
Spilly 5:40ac894e0fa7 781 //return to manual mode
Spilly 5:40ac894e0fa7 782 if(recChar == 'y')
Spilly 2:503a5ac6c3b6 783 {
Spilly 5:40ac894e0fa7 784 mode = 0;
Spilly 2:503a5ac6c3b6 785 }
Spilly 5:40ac894e0fa7 786 else
Spilly 2:503a5ac6c3b6 787 {
Spilly 12:273479524c71 788 //TODO: put this in a function
Spilly 12:273479524c71 789
Spilly 7:ebc76b0f21da 790 xBee.printf("\nFinding most accurate GPS position\nThis will take a few seconds\n\n");
Spilly 7:ebc76b0f21da 791
Spilly 7:ebc76b0f21da 792 float lowestHDOP = 100;
Spilly 7:ebc76b0f21da 793
Spilly 8:c77ab7615b21 794 //take 50 GPS readings and keep the position with the lowest horizontal dilution of precision (HDOP)
Spilly 8:c77ab7615b21 795 //lower HDOP = less error
Spilly 7:ebc76b0f21da 796 for(int i = 0; i< 50; i++)
Spilly 7:ebc76b0f21da 797 {
Spilly 8:c77ab7615b21 798 //wait for data to be available
Spilly 8:c77ab7615b21 799 //while(!gps._UltimateGps.readable())
Spilly 7:ebc76b0f21da 800 gps.parseData();
Spilly 7:ebc76b0f21da 801
Spilly 7:ebc76b0f21da 802 if(gps.HDOP <= lowestHDOP)
Spilly 7:ebc76b0f21da 803 {
Spilly 7:ebc76b0f21da 804 lowestHDOP = gps.HDOP;
Spilly 7:ebc76b0f21da 805 curPos[0] = gps.degLat;
Spilly 7:ebc76b0f21da 806 curPos[1] = gps.degLon;
Spilly 7:ebc76b0f21da 807 }
Spilly 8:c77ab7615b21 808 xBee.printf("lat %f\tlon %f\thead %f\talt %f\tspd %f\tfix %d\tsat %d\n", gps.degLat, gps.degLon, gps.heading, gps.altitude, gps.speed, gps.fixtype, gps.satellites);
Spilly 8:c77ab7615b21 809 char tempChar = 'n';
Spilly 12:273479524c71 810
Spilly 12:273479524c71 811 //first lockup was here
Spilly 12:273479524c71 812 //now pressing "1" will break out of while loop
Spilly 8:c77ab7615b21 813 while(!gps.getData() && !(tempChar == '1'))
Spilly 8:c77ab7615b21 814 {
Spilly 8:c77ab7615b21 815 if(xBee.readable())
Spilly 8:c77ab7615b21 816 {
Spilly 8:c77ab7615b21 817 tempChar = xBee.getc();
Spilly 8:c77ab7615b21 818 i = 50;
Spilly 8:c77ab7615b21 819 }
Spilly 8:c77ab7615b21 820 }
Spilly 7:ebc76b0f21da 821 }
Spilly 5:40ac894e0fa7 822 if(recChar == '0')
Spilly 5:40ac894e0fa7 823 {
Spilly 5:40ac894e0fa7 824 goalPos[0][0] = curPos[0];
Spilly 5:40ac894e0fa7 825 goalPos[0][1] = curPos[1];
Spilly 12:273479524c71 826
Spilly 8:c77ab7615b21 827 //write new coords to SD card
Spilly 12:273479524c71 828 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 829 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 830 {
Spilly 12:273479524c71 831 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 832 }
Spilly 12:273479524c71 833 fclose(way);
Spilly 5:40ac894e0fa7 834 }
Spilly 5:40ac894e0fa7 835 else if(recChar == '1')
Spilly 5:40ac894e0fa7 836 {
Spilly 5:40ac894e0fa7 837 goalPos[1][0] = curPos[0];
Spilly 5:40ac894e0fa7 838 goalPos[1][1] = curPos[1];
Spilly 12:273479524c71 839
Spilly 8:c77ab7615b21 840 //write new coords to SD card
Spilly 12:273479524c71 841 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 842 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 843 {
Spilly 12:273479524c71 844 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 845 }
Spilly 12:273479524c71 846 fclose(way);
Spilly 5:40ac894e0fa7 847 }
Spilly 5:40ac894e0fa7 848 else if(recChar == '2')
Spilly 5:40ac894e0fa7 849 {
Spilly 5:40ac894e0fa7 850 goalPos[2][0] = curPos[0];
Spilly 5:40ac894e0fa7 851 goalPos[2][1] = curPos[1];
Spilly 12:273479524c71 852
Spilly 8:c77ab7615b21 853 //write new coords to SD card
Spilly 12:273479524c71 854 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 855 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 856 {
Spilly 12:273479524c71 857 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 858 }
Spilly 12:273479524c71 859 fclose(way);
Spilly 5:40ac894e0fa7 860 }
Spilly 5:40ac894e0fa7 861 else if(recChar == '3')
Spilly 2:503a5ac6c3b6 862 {
Spilly 5:40ac894e0fa7 863 goalPos[3][0] = curPos[0];
Spilly 5:40ac894e0fa7 864 goalPos[3][1] = curPos[1];
Spilly 12:273479524c71 865
Spilly 8:c77ab7615b21 866 //write new coords to SD card
Spilly 12:273479524c71 867 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 868 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 869 {
Spilly 12:273479524c71 870 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 871 }
Spilly 12:273479524c71 872 fclose(way);
Spilly 5:40ac894e0fa7 873 }
Spilly 5:40ac894e0fa7 874 else if(recChar == '4')
Spilly 5:40ac894e0fa7 875 {
Spilly 5:40ac894e0fa7 876 goalPos[4][0] = curPos[0];
Spilly 5:40ac894e0fa7 877 goalPos[4][1] = curPos[1];
Spilly 12:273479524c71 878
Spilly 8:c77ab7615b21 879 //write new coords to SD card
Spilly 12:273479524c71 880 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 881 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 882 {
Spilly 12:273479524c71 883 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 884 }
Spilly 12:273479524c71 885 fclose(way);
Spilly 5:40ac894e0fa7 886 }
Spilly 5:40ac894e0fa7 887 else if(recChar == '5')
Spilly 5:40ac894e0fa7 888 {
Spilly 5:40ac894e0fa7 889 goalPos[5][0] = curPos[0];
Spilly 5:40ac894e0fa7 890 goalPos[5][1] = curPos[1];
Spilly 12:273479524c71 891
Spilly 8:c77ab7615b21 892 //write new coords to SD card
Spilly 12:273479524c71 893 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 894 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 895 {
Spilly 12:273479524c71 896 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 897 }
Spilly 12:273479524c71 898 fclose(way);
Spilly 5:40ac894e0fa7 899 }
Spilly 5:40ac894e0fa7 900 else if(recChar == '6')
Spilly 5:40ac894e0fa7 901 {
Spilly 5:40ac894e0fa7 902 goalPos[6][0] = curPos[0];
Spilly 5:40ac894e0fa7 903 goalPos[6][1] = curPos[1];
Spilly 5:40ac894e0fa7 904 }
Spilly 5:40ac894e0fa7 905 else if(recChar == '7')
Spilly 5:40ac894e0fa7 906 {
Spilly 5:40ac894e0fa7 907 goalPos[7][0] = curPos[0];
Spilly 5:40ac894e0fa7 908 goalPos[7][1] = curPos[1];
Spilly 12:273479524c71 909
Spilly 8:c77ab7615b21 910 //write new coords to SD card
Spilly 12:273479524c71 911 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 912 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 913 {
Spilly 12:273479524c71 914 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 915 }
Spilly 12:273479524c71 916 fclose(way);
Spilly 2:503a5ac6c3b6 917 }
Spilly 5:40ac894e0fa7 918 else if(recChar == '8')
Spilly 5:40ac894e0fa7 919 {
Spilly 5:40ac894e0fa7 920 goalPos[8][0] = curPos[0];
Spilly 5:40ac894e0fa7 921 goalPos[8][1] = curPos[1];
Spilly 12:273479524c71 922
Spilly 8:c77ab7615b21 923 //write new coords to SD card
Spilly 12:273479524c71 924 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 925 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 926 {
Spilly 12:273479524c71 927 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 928 }
Spilly 12:273479524c71 929 fclose(way);
Spilly 5:40ac894e0fa7 930 }
Spilly 5:40ac894e0fa7 931 else if(recChar == '9')
Spilly 2:503a5ac6c3b6 932 {
Spilly 5:40ac894e0fa7 933 goalPos[9][0] = curPos[0];
Spilly 5:40ac894e0fa7 934 goalPos[9][1] = curPos[1];
Spilly 12:273479524c71 935
Spilly 8:c77ab7615b21 936 //write new coords to SD card
Spilly 12:273479524c71 937 way = fopen("/sd/GPS_CORDS.txt", "w+");
Spilly 8:c77ab7615b21 938 for(int x = 0; x<=9; x++)
Spilly 8:c77ab7615b21 939 {
Spilly 12:273479524c71 940 fprintf(way, "%f,%f\n", &goalPos[x][0], &goalPos[x][1]);
Spilly 8:c77ab7615b21 941 }
Spilly 12:273479524c71 942 fclose(way);
Spilly 2:503a5ac6c3b6 943 }
Spilly 7:ebc76b0f21da 944 xBee.printf("position %c updated\t", recChar);
Spilly 2:503a5ac6c3b6 945 }
Spilly 7:ebc76b0f21da 946 xBee.printf("returning to manual mode\n\n");
Spilly 5:40ac894e0fa7 947 mode = 0;
Spilly 5:40ac894e0fa7 948 }
Spilly 5:40ac894e0fa7 949 }
Spilly 5:40ac894e0fa7 950 }
Spilly 5:40ac894e0fa7 951
Spilly 8:c77ab7615b21 952 /*************************************************************************************************************************************************************************************************/
Spilly 8:c77ab7615b21 953 // create polar vector based on two sets of latitude and longitude
Spilly 8:c77ab7615b21 954 /*************************************************************************************************************************************************************************************************/
Spilly 8:c77ab7615b21 955 //TODO:
Spilly 8:c77ab7615b21 956 //getDist and getAngle need to be optimized
Spilly 8:c77ab7615b21 957 //they were one function but had to be hacked apart
Spilly 7:ebc76b0f21da 958
Spilly 8:c77ab7615b21 959 void getDist(double posZero, double posOne, double curPos[2])
Spilly 5:40ac894e0fa7 960 {
Spilly 7:ebc76b0f21da 961 double arcLength[2];
Spilly 7:ebc76b0f21da 962 double goalPos[2];
Spilly 5:40ac894e0fa7 963 goalPos[0] = posZero;
Spilly 5:40ac894e0fa7 964 goalPos[1] = posOne;
Spilly 5:40ac894e0fa7 965
Spilly 7:ebc76b0f21da 966 /*Note: arc length = radius * angle*/
Spilly 5:40ac894e0fa7 967 //Y
Spilly 5:40ac894e0fa7 968 arcLength[1] = EARTHRADIUS * ((goalPos[0] - curPos[0]) * DEGREETORAD);
Spilly 5:40ac894e0fa7 969 //X
Spilly 5:40ac894e0fa7 970 arcLength[0] = EARTHRADIUS * ((goalPos[1] - curPos[1]) * DEGREETORAD);
Spilly 5:40ac894e0fa7 971
Spilly 5:40ac894e0fa7 972 //calculate magnitude of vector
Spilly 5:40ac894e0fa7 973 polarVector[0] = sqrt((arcLength[0] * arcLength[0]) + (arcLength[1] * arcLength[1]));
Spilly 8:c77ab7615b21 974 }
Spilly 8:c77ab7615b21 975
Spilly 8:c77ab7615b21 976 void getAngle(double posZero, double posOne, double curPos[2], int flush)
Spilly 8:c77ab7615b21 977 {
Spilly 8:c77ab7615b21 978 double tempAngle = 0;
Spilly 8:c77ab7615b21 979 double arcLength[2];
Spilly 8:c77ab7615b21 980 double goalPos[2];
Spilly 8:c77ab7615b21 981 goalPos[0] = posZero;
Spilly 8:c77ab7615b21 982 goalPos[1] = posOne;
Spilly 5:40ac894e0fa7 983
Spilly 8:c77ab7615b21 984 /*Note: arc length = radius * angle*/
Spilly 8:c77ab7615b21 985 //Y
Spilly 8:c77ab7615b21 986 arcLength[1] = EARTHRADIUS * ((goalPos[0] - curPos[0]) * DEGREETORAD);
Spilly 8:c77ab7615b21 987 //X
Spilly 8:c77ab7615b21 988 arcLength[0] = EARTHRADIUS * ((goalPos[1] - curPos[1]) * DEGREETORAD);
Spilly 12:273479524c71 989
Spilly 12:273479524c71 990 //get rid of previous low passed angle data
Spilly 8:c77ab7615b21 991 if(flush)
Spilly 8:c77ab7615b21 992 {
Spilly 8:c77ab7615b21 993 //Use arcTan(x/y) b/c we want our heading to be in respect to North (North = 0 degrees, East = 90 deg, etc.)
Spilly 8:c77ab7615b21 994 polarVector[1] = (RADTODEGREE * (atan2(arcLength[0], arcLength[1])));
Spilly 8:c77ab7615b21 995 //make negative angles positive
Spilly 8:c77ab7615b21 996 if(polarVector[1] < 0) polarVector[1] = polarVector[1] + 360;
Spilly 8:c77ab7615b21 997 }
Spilly 12:273479524c71 998
Spilly 12:273479524c71 999 //lowpass filter the angle
Spilly 8:c77ab7615b21 1000 else
Spilly 8:c77ab7615b21 1001 {
Spilly 8:c77ab7615b21 1002
Spilly 8:c77ab7615b21 1003 tempAngle = (RADTODEGREE * (atan2(arcLength[0], arcLength[1])));
Spilly 8:c77ab7615b21 1004
Spilly 8:c77ab7615b21 1005 if(tempAngle < 0) tempAngle = tempAngle + 360;
Spilly 8:c77ab7615b21 1006 polarVector[1] = lowPass(tempAngle, polarVector[1], 3);
Spilly 8:c77ab7615b21 1007 }
Spilly 8:c77ab7615b21 1008 }