Guides the user to their classes

Dependencies:   4DGL-uLCD-SE Course SDFileSystem mbed PinDetect LSM9DS1_Library_cal MBed_Adafruit-GPS-Library

Committer:
nkela6
Date:
Fri Dec 09 00:24:58 2016 +0000
Revision:
16:4b4e6cf66e7c
Parent:
15:75a121b14e5d
Child:
17:1de531cd3d4a
added global snooze button attached to center of joystick. Turns of red screen for 2 minutes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kkizirian 0:ce60014510e5 1 // Class Scheduler
kkizirian 0:ce60014510e5 2 #include "mbed.h"
kkizirian 0:ce60014510e5 3 #include "uLCD_4DGL.h"
kkizirian 0:ce60014510e5 4 #include <string>
kkizirian 0:ce60014510e5 5 #include <vector>
kkizirian 0:ce60014510e5 6 #include "Course.h"
kkizirian 0:ce60014510e5 7 #include "SDFileSystem.h"
kkizirian 5:430f44669f94 8 #include "MBed_Adafruit_GPS.h"
kkizirian 3:0ca91f8afec5 9 #include "LSM9DS1.h"
kkizirian 2:c708e2027970 10 #include "PinDetect.h"
kkizirian 3:0ca91f8afec5 11 #define PI 3.14159
kkizirian 3:0ca91f8afec5 12 #define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.
kkizirian 0:ce60014510e5 13
kkizirian 0:ce60014510e5 14 SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
kkizirian 0:ce60014510e5 15 Serial pc(USBTX, USBRX);
kkizirian 3:0ca91f8afec5 16 uLCD_4DGL uLCD(p13,p14,p15); // serial tx, serial rx, reset pin;
kkizirian 3:0ca91f8afec5 17 PinDetect left(p20);
kkizirian 3:0ca91f8afec5 18 PinDetect right(p18);
nkela6 16:4b4e6cf66e7c 19 PinDetect center(p19);
kkizirian 5:430f44669f94 20 Serial * gps_Serial;
kkizirian 0:ce60014510e5 21
kkizirian 0:ce60014510e5 22 int update;
kkizirian 0:ce60014510e5 23 vector<Course> courseVec;
kkizirian 4:93a4b415fe6c 24 void readClassFile(vector<Course>& cVec);
kkizirian 5:430f44669f94 25 int getNextClass(vector<Course>& cVec);
kkizirian 2:c708e2027970 26 void displayCourseVec();
kkizirian 3:0ca91f8afec5 27 float calculateHeading(float mx, float my), computeAngleToDestination(float diffLat, float diffLong);
kkizirian 9:5b871fb9f554 28 float longToDecimal(float longitudeInDDMM, char eastOrWest), latToDecimal(float latitudeInDDMM, char northOrSouth);
kkizirian 4:93a4b415fe6c 29 int xEnd, yEnd = 0.0;
kkizirian 5:430f44669f94 30 int currHour, currMinute, currSecond = 0;
kkizirian 5:430f44669f94 31 int hoursToNextClass, minutesToNextClass, secondsToNextClass = 0;
kkizirian 5:430f44669f94 32 int nextClass = 0;
kkizirian 5:430f44669f94 33 int currClass = -1;
kkizirian 5:430f44669f94 34 const int refresh_Time = 1000; //refresh time in ms
kkizirian 3:0ca91f8afec5 35 bool screen_refreshed = false;
kkizirian 2:c708e2027970 36 int volatile current_screen = 0;
kkizirian 2:c708e2027970 37 bool volatile screen_change = false;
kkizirian 5:430f44669f94 38 void timeToNextClass();
nkela6 13:0eb9fbd63fb2 39 float displacement(float diffLat,float diffLong);
nkela6 13:0eb9fbd63fb2 40 float calc_eta(float displacement, float speed);
nkela6 13:0eb9fbd63fb2 41 bool late(float eta);
nkela6 16:4b4e6cf66e7c 42 timer t2;
nkela6 16:4b4e6cf66e7c 43
nkela6 16:4b4e6cf66e7c 44 bool snooze = 0;
kkizirian 0:ce60014510e5 45
kkizirian 2:c708e2027970 46 void left_callback(void)
kkizirian 2:c708e2027970 47 {
kkizirian 3:0ca91f8afec5 48 if (courseVec.size() != 0) {
kkizirian 3:0ca91f8afec5 49 current_screen = (3 + current_screen - 1)%3;
kkizirian 3:0ca91f8afec5 50 screen_change = true;
kkizirian 3:0ca91f8afec5 51 } else
kkizirian 3:0ca91f8afec5 52 current_screen = 0;
kkizirian 5:430f44669f94 53 currClass = -1;
kkizirian 5:430f44669f94 54 uLCD.cls();
kkizirian 2:c708e2027970 55 }
kkizirian 2:c708e2027970 56
kkizirian 2:c708e2027970 57 void right_callback(void)
kkizirian 2:c708e2027970 58 {
kkizirian 3:0ca91f8afec5 59 if (courseVec.size() != 0) {
kkizirian 3:0ca91f8afec5 60 current_screen = (3 + current_screen + 1)%3;
kkizirian 3:0ca91f8afec5 61 screen_change = true;
kkizirian 3:0ca91f8afec5 62 } else
kkizirian 3:0ca91f8afec5 63 current_screen = 0;
kkizirian 5:430f44669f94 64 currClass = -1;
kkizirian 5:430f44669f94 65 uLCD.cls();
kkizirian 2:c708e2027970 66 }
kkizirian 2:c708e2027970 67
kkizirian 0:ce60014510e5 68 int main()
kkizirian 0:ce60014510e5 69 {
kkizirian 3:0ca91f8afec5 70 LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);
kkizirian 3:0ca91f8afec5 71 float h = 0.0;
kkizirian 3:0ca91f8afec5 72 float angleToDest = 0.0;
kkizirian 3:0ca91f8afec5 73 IMU.begin();
kkizirian 3:0ca91f8afec5 74 if (!IMU.begin()) {
kkizirian 3:0ca91f8afec5 75 pc.printf("Failed to communicate with LSM9DS1.\n");
kkizirian 3:0ca91f8afec5 76 }
kkizirian 3:0ca91f8afec5 77 uLCD.cls();
kkizirian 3:0ca91f8afec5 78 uLCD.printf("Place IMU flat");
kkizirian 3:0ca91f8afec5 79 IMU.calibrate(1);
kkizirian 3:0ca91f8afec5 80 uLCD.cls();
kkizirian 3:0ca91f8afec5 81 uLCD.printf("Rotate IMU 360\ndegrees in \nhorizontal plane");
kkizirian 3:0ca91f8afec5 82 IMU.calibrateMag(0);
kkizirian 3:0ca91f8afec5 83
kkizirian 2:c708e2027970 84 left.mode(PullUp);
kkizirian 2:c708e2027970 85 right.mode(PullUp);
kkizirian 2:c708e2027970 86 left.attach_deasserted(&left_callback);
kkizirian 2:c708e2027970 87 right.attach_deasserted(&right_callback);
kkizirian 2:c708e2027970 88 left.setSampleFrequency();
kkizirian 2:c708e2027970 89 right.setSampleFrequency();
kkizirian 2:c708e2027970 90
kkizirian 0:ce60014510e5 91 readClassFile(courseVec);
kkizirian 5:430f44669f94 92
kkizirian 5:430f44669f94 93 gps_Serial = new Serial(p28,p27); //serial object for use w/ GPS
kkizirian 5:430f44669f94 94 Adafruit_GPS myGPS(gps_Serial); //object of Adafruit's GPS class
kkizirian 5:430f44669f94 95 char c; //when read via Adafruit_GPS::read(), the class returns single character stored here
kkizirian 5:430f44669f94 96 Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info?
kkizirian 5:430f44669f94 97 const int refresh_Time = 2000; //refresh time in ms
kkizirian 5:430f44669f94 98
kkizirian 5:430f44669f94 99 myGPS.begin(9600); //sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *)
kkizirian 5:430f44669f94 100 //a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf
kkizirian 5:430f44669f94 101
kkizirian 5:430f44669f94 102 myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation
kkizirian 5:430f44669f94 103 myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
kkizirian 5:430f44669f94 104 myGPS.sendCommand(PGCMD_ANTENNA);
kkizirian 5:430f44669f94 105
kkizirian 4:93a4b415fe6c 106 float myLat = 33.775991;
kkizirian 4:93a4b415fe6c 107 float myLong = -84.397128;
kkizirian 2:c708e2027970 108
kkizirian 5:430f44669f94 109 float destinationLat = courseVec[1].getLat();
kkizirian 5:430f44669f94 110 float destinationLong = courseVec[1].getLong();
kkizirian 5:430f44669f94 111
kkizirian 4:93a4b415fe6c 112 screen_change = true;
kkizirian 0:ce60014510e5 113 pc.baud(9600);
kkizirian 5:430f44669f94 114 c = myGPS.read(); //queries the GPS
kkizirian 5:430f44669f94 115 currHour = myGPS.hour - 5; //for eastern time zone
kkizirian 5:430f44669f94 116 if (currHour < 0)
kkizirian 5:430f44669f94 117 currHour += 24;
kkizirian 5:430f44669f94 118 currMinute = myGPS.minute;
kkizirian 5:430f44669f94 119 currSecond = myGPS.seconds;
kkizirian 5:430f44669f94 120 nextClass = getNextClass(courseVec);
kkizirian 2:c708e2027970 121
kkizirian 5:430f44669f94 122 refresh_Timer.start(); //starts the clock on the timer
kkizirian 0:ce60014510e5 123 while(1) {
kkizirian 5:430f44669f94 124 c = myGPS.read(); //queries the GPS
kkizirian 5:430f44669f94 125
kkizirian 5:430f44669f94 126 //if (c) { pc.printf("%c", c); } //this line will echo the GPS data if not paused
kkizirian 5:430f44669f94 127
kkizirian 5:430f44669f94 128 //check if we recieved a new message from GPS, if so, attempt to parse it,
kkizirian 5:430f44669f94 129 if ( myGPS.newNMEAreceived() ) {
kkizirian 5:430f44669f94 130 if ( !myGPS.parse(myGPS.lastNMEA()) ) {
kkizirian 5:430f44669f94 131 continue;
kkizirian 5:430f44669f94 132 }
kkizirian 5:430f44669f94 133 }
kkizirian 5:430f44669f94 134
kkizirian 5:430f44669f94 135 if (refresh_Timer.read_ms() >= refresh_Time) {
kkizirian 5:430f44669f94 136 refresh_Timer.reset();
kkizirian 6:ceb6a5426add 137 if (myGPS.fix) {
kkizirian 9:5b871fb9f554 138 myLat = latToDecimal(myGPS.latitude, myGPS.lat);
kkizirian 9:5b871fb9f554 139 myLong = longToDecimal(myGPS.longitude, myGPS.lon);
kkizirian 6:ceb6a5426add 140 }
kkizirian 9:5b871fb9f554 141
kkizirian 5:430f44669f94 142 currHour = myGPS.hour - 5; //for eastern time zone
kkizirian 5:430f44669f94 143 if (currHour < 0)
kkizirian 5:430f44669f94 144 currHour += 24;
kkizirian 5:430f44669f94 145 currMinute = myGPS.minute;
kkizirian 5:430f44669f94 146 currSecond = myGPS.seconds;
kkizirian 5:430f44669f94 147 nextClass = getNextClass(courseVec);
kkizirian 5:430f44669f94 148 timeToNextClass();
nkela6 13:0eb9fbd63fb2 149 destinationLat = courseVec[nextClass].getLat();
nkela6 13:0eb9fbd63fb2 150 destinationLong = courseVec[nextClass].getLong();
nkela6 13:0eb9fbd63fb2 151 float diffLat = destinationLat - myLat;
nkela6 13:0eb9fbd63fb2 152 float diffLong = destinationLong - myLong;
nkela6 13:0eb9fbd63fb2 153 float dis = displacement(diffLat,diffLong);
nkela6 13:0eb9fbd63fb2 154 float speed = 3.1; //mph. Source:https://lmgtfy.com/?q=average+human+walking+speed
nkela6 13:0eb9fbd63fb2 155 float eta = calc_eta(dis,speed)*60;//(miles, mph)*60
nkela6 16:4b4e6cf66e7c 156 if((late(eta)==1)&&(snooze==0)) {
nkela6 14:d8a6134cafa3 157 uLCD.background_color(RED);
nkela6 16:4b4e6cf66e7c 158 uLCD.textbackground_color(RED);
nkela6 16:4b4e6cf66e7c 159 } elseif((late(eta)==1)&&(snooze==1)){
nkela6 16:4b4e6cf66e7c 160 t2.start();
nkela6 16:4b4e6cf66e7c 161 if(t2.read>120)//2 minute snooze
nkela6 16:4b4e6cf66e7c 162 {
nkela6 16:4b4e6cf66e7c 163 uLCD.background_color(BLACK);
nkela6 16:4b4e6cf66e7c 164 uLCD.textbackground_color(BLACK);
nkela6 16:4b4e6cf66e7c 165 }
nkela6 16:4b4e6cf66e7c 166 t2.stop();
nkela6 16:4b4e6cf66e7c 167 }
nkela6 16:4b4e6cf66e7c 168 else {
nkela6 14:d8a6134cafa3 169 uLCD.background_color(BLACK);
nkela6 16:4b4e6cf66e7c 170 uLCD.textbackground_color(BLACK);
nkela6 13:0eb9fbd63fb2 171 }
kkizirian 5:430f44669f94 172
kkizirian 5:430f44669f94 173 switch(current_screen) {
kkizirian 5:430f44669f94 174 case 0:
kkizirian 5:430f44669f94 175 wait(.2);
kkizirian 5:430f44669f94 176 if (screen_change) {
kkizirian 5:430f44669f94 177 displayCourseVec();
kkizirian 5:430f44669f94 178 screen_change = false;
kkizirian 5:430f44669f94 179 }
kkizirian 5:430f44669f94 180 break;
kkizirian 5:430f44669f94 181 case 1:
kkizirian 5:430f44669f94 182 IMU.readMag();
kkizirian 5:430f44669f94 183 h = calculateHeading(IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my));
kkizirian 5:430f44669f94 184 pc.printf("Heading: %f\n", h);
kkizirian 5:430f44669f94 185 angleToDest = computeAngleToDestination(diffLat, diffLong);
kkizirian 5:430f44669f94 186 h = angleToDest - h;
kkizirian 3:0ca91f8afec5 187 h = h - 90;
kkizirian 5:430f44669f94 188 if (h < 0)
kkizirian 5:430f44669f94 189 h = h + 360;
kkizirian 5:430f44669f94 190 if (h > 360)
kkizirian 5:430f44669f94 191 h = h - 360;
kkizirian 5:430f44669f94 192 xEnd = 0;
kkizirian 5:430f44669f94 193 yEnd = 0;
kkizirian 5:430f44669f94 194 float rads = 0.0;
kkizirian 5:430f44669f94 195 //uLCD.cls();
kkizirian 5:430f44669f94 196 if (h < 90) {
kkizirian 5:430f44669f94 197 rads = h * PI / 180;
kkizirian 5:430f44669f94 198 xEnd = floor(63 * sin(rads) + .5);
kkizirian 5:430f44669f94 199 yEnd = floor(63 * cos(rads) + .5);
kkizirian 5:430f44669f94 200 xEnd = 63 + xEnd;
kkizirian 5:430f44669f94 201 yEnd = 63 + yEnd;
kkizirian 5:430f44669f94 202 } else if (90 < h < 180) {
kkizirian 5:430f44669f94 203 h = h - 90;
kkizirian 5:430f44669f94 204 rads = h * PI / 180;
kkizirian 5:430f44669f94 205 xEnd = floor(63 * cos(rads) + .5);
kkizirian 5:430f44669f94 206 yEnd = floor(63 * sin(rads) + .5);
kkizirian 5:430f44669f94 207 xEnd = 63 + xEnd;
kkizirian 5:430f44669f94 208 yEnd = 63 - yEnd;
kkizirian 5:430f44669f94 209 } else if (180 < h < 270) {
kkizirian 5:430f44669f94 210 h = h - 180;
kkizirian 5:430f44669f94 211 rads = h * PI / 180;
kkizirian 5:430f44669f94 212 xEnd = floor(63 * sin(rads) + .5);
kkizirian 5:430f44669f94 213 yEnd = floor(63 * cos(rads) + .5);
kkizirian 5:430f44669f94 214 xEnd = 63 - xEnd;
kkizirian 5:430f44669f94 215 yEnd = 63 - yEnd;
kkizirian 5:430f44669f94 216 } else if (270 < h) {
kkizirian 5:430f44669f94 217 h = h - 270;
kkizirian 5:430f44669f94 218 rads = h * PI / 180;
kkizirian 5:430f44669f94 219 xEnd = floor(63 * cos(rads) + .5);
kkizirian 5:430f44669f94 220 yEnd = floor(63 * sin(rads) + .5);
kkizirian 5:430f44669f94 221 xEnd = 63 - xEnd;
kkizirian 5:430f44669f94 222 yEnd = 63 + yEnd;
kkizirian 5:430f44669f94 223 }
kkizirian 2:c708e2027970 224 uLCD.cls();
kkizirian 5:430f44669f94 225 uLCD.line(63, 63, xEnd, yEnd, WHITE);
kkizirian 5:430f44669f94 226 break;
kkizirian 5:430f44669f94 227 case 2:
kkizirian 5:430f44669f94 228 //uLCD.cls();
nkela6 16:4b4e6cf66e7c 229 //uLCD.text_mode(TRANSPARENT);
kkizirian 7:e4d667beaf33 230 uLCD.locate(0,2);
kkizirian 8:3266cc9eda81 231 uLCD.printf(" ");
kkizirian 6:ceb6a5426add 232 uLCD.locate(0,3);
kkizirian 5:430f44669f94 233 uLCD.printf("Time to next class");
kkizirian 6:ceb6a5426add 234 uLCD.locate(0, 4);
kkizirian 5:430f44669f94 235 uLCD.printf("%02dhrs %02dminutes", hoursToNextClass, minutesToNextClass);
kkizirian 6:ceb6a5426add 236 uLCD.locate(0, 5);
kkizirian 5:430f44669f94 237 uLCD.printf("%02dseconds", secondsToNextClass);
nkela6 15:75a121b14e5d 238 uLCD.locate(0,7);
nkela6 15:75a121b14e5d 239 uLCD.printf("ETA: (min)");
nkela6 15:75a121b14e5d 240 uLCD.locate(0,8);
nkela6 15:75a121b14e5d 241 uLCD.printf("%f",eta);
nkela6 15:75a121b14e5d 242 uLCD.locate(0,10);
nkela6 15:75a121b14e5d 243 uLCD.printf("Displacement:");
nkela6 15:75a121b14e5d 244 uLCD.locate(0,11);
nkela6 15:75a121b14e5d 245 uLCD.printf("%f",dis);
kkizirian 6:ceb6a5426add 246 uLCD.locate(0, 0);
kkizirian 7:e4d667beaf33 247 uLCD.printf("Next class ");
kkizirian 5:430f44669f94 248 if (nextClass != currClass) {
kkizirian 6:ceb6a5426add 249 uLCD.locate(0, 1);
kkizirian 5:430f44669f94 250 uLCD.printf(" ");
kkizirian 6:ceb6a5426add 251 uLCD.locate(0, 1);
kkizirian 5:430f44669f94 252 uLCD.printf("%s", courseVec[nextClass].getDisplayString());
kkizirian 5:430f44669f94 253 }
kkizirian 5:430f44669f94 254 currClass = nextClass;
kkizirian 5:430f44669f94 255 break;
kkizirian 5:430f44669f94 256 }
kkizirian 0:ce60014510e5 257 }
kkizirian 0:ce60014510e5 258 }
kkizirian 0:ce60014510e5 259 }
kkizirian 0:ce60014510e5 260
kkizirian 2:c708e2027970 261 void readClassFile(vector<Course>& cVec)
kkizirian 2:c708e2027970 262 {
kkizirian 0:ce60014510e5 263 cVec.clear();
kkizirian 0:ce60014510e5 264
kkizirian 0:ce60014510e5 265 FILE *readFp = fopen("/sd/classdir/classes.txt", "r");
kkizirian 0:ce60014510e5 266 char line[15];
kkizirian 0:ce60014510e5 267 char buildingBuf[4];
kkizirian 0:ce60014510e5 268 char hourBuf[3];
kkizirian 0:ce60014510e5 269 int hour;
kkizirian 0:ce60014510e5 270 char minuteBuf[3];
kkizirian 0:ce60014510e5 271 int minute;
kkizirian 0:ce60014510e5 272 char ampmBuf[3];
kkizirian 0:ce60014510e5 273 uLCD.cls();
kkizirian 0:ce60014510e5 274 uLCD.locate(0, 1);
kkizirian 0:ce60014510e5 275 uLCD.printf("Reading class file...");
kkizirian 2:c708e2027970 276
kkizirian 0:ce60014510e5 277 memset(buildingBuf, 0, sizeof(buildingBuf));
kkizirian 0:ce60014510e5 278 memset(hourBuf, 0, sizeof(hourBuf));
kkizirian 0:ce60014510e5 279 memset(minuteBuf, 0, sizeof(minuteBuf));
kkizirian 0:ce60014510e5 280 memset(ampmBuf, 0, sizeof(ampmBuf));
kkizirian 0:ce60014510e5 281 memset(line, 0, sizeof(line));
kkizirian 0:ce60014510e5 282
kkizirian 0:ce60014510e5 283 if (readFp == NULL)
kkizirian 0:ce60014510e5 284 return;
kkizirian 0:ce60014510e5 285 else {
kkizirian 0:ce60014510e5 286 while (!feof(readFp)) {
kkizirian 0:ce60014510e5 287 fgets(line, 15, readFp);
kkizirian 0:ce60014510e5 288 if(line[8] == NULL)
kkizirian 0:ce60014510e5 289 continue;
kkizirian 0:ce60014510e5 290 memcpy(buildingBuf, line, 3);
kkizirian 0:ce60014510e5 291 memcpy(hourBuf, &line[4], 2);
kkizirian 0:ce60014510e5 292 memcpy(minuteBuf, &line[7], 2);
kkizirian 0:ce60014510e5 293 memcpy(ampmBuf, &line[10], 2);
kkizirian 0:ce60014510e5 294
kkizirian 0:ce60014510e5 295 string building = buildingBuf;
kkizirian 0:ce60014510e5 296 hour = atoi(hourBuf);
kkizirian 0:ce60014510e5 297 minute = atoi(minuteBuf);
kkizirian 0:ce60014510e5 298 string ampm = ampmBuf;
kkizirian 0:ce60014510e5 299
kkizirian 0:ce60014510e5 300 Course temp(building, hour, minute, ampm);
kkizirian 0:ce60014510e5 301 cVec.push_back(temp);
kkizirian 0:ce60014510e5 302 }
kkizirian 0:ce60014510e5 303 }
kkizirian 0:ce60014510e5 304 fclose(readFp);
kkizirian 0:ce60014510e5 305 return;
kkizirian 2:c708e2027970 306 }
kkizirian 2:c708e2027970 307
kkizirian 2:c708e2027970 308 void displayCourseVec()
kkizirian 2:c708e2027970 309 {
nkela6 16:4b4e6cf66e7c 310 //uLCD.text_mode(TRANSPARENT);
kkizirian 2:c708e2027970 311 if (courseVec.size() == 0) {
kkizirian 2:c708e2027970 312 uLCD.cls();
kkizirian 2:c708e2027970 313 uLCD.locate(0,0);
kkizirian 2:c708e2027970 314 uLCD.printf("No classes input!");
kkizirian 2:c708e2027970 315 uLCD.locate(0,1);
kkizirian 2:c708e2027970 316 } else {
kkizirian 2:c708e2027970 317 uLCD.cls();
kkizirian 2:c708e2027970 318 uLCD.locate(0,1);
kkizirian 2:c708e2027970 319 for (int i = 0; i < courseVec.size(); i++) {
kkizirian 2:c708e2027970 320 uLCD.locate(0, i);
kkizirian 2:c708e2027970 321 uLCD.printf("%s", courseVec[i].getDisplayString());
kkizirian 2:c708e2027970 322 }
kkizirian 2:c708e2027970 323 }
kkizirian 3:0ca91f8afec5 324 }
kkizirian 3:0ca91f8afec5 325
kkizirian 3:0ca91f8afec5 326 float calculateHeading(float mx, float my)
kkizirian 3:0ca91f8afec5 327 {
kkizirian 3:0ca91f8afec5 328 float heading = 0.0;
kkizirian 3:0ca91f8afec5 329 if (my == 0.0)
kkizirian 3:0ca91f8afec5 330 heading = (mx < 0.0) ? 180.0 : 0.0;
kkizirian 3:0ca91f8afec5 331 else
kkizirian 3:0ca91f8afec5 332 heading = atan2(mx, my)*360.0/(2.0*PI);
kkizirian 3:0ca91f8afec5 333 //pc.printf("heading atan=%f \n\r",heading);
kkizirian 3:0ca91f8afec5 334 heading -= DECLINATION; //correct for geo location
kkizirian 3:0ca91f8afec5 335 if(heading>180.0) heading = heading - 360.0;
kkizirian 3:0ca91f8afec5 336 else if(heading<-180.0) heading = 360.0 + heading;
kkizirian 3:0ca91f8afec5 337 else if(heading<0.0) heading = 360.0 + heading;
kkizirian 3:0ca91f8afec5 338
kkizirian 3:0ca91f8afec5 339 // Convert everything from radians to degrees:
kkizirian 3:0ca91f8afec5 340 //heading *= 180.0 / PI;
kkizirian 3:0ca91f8afec5 341
kkizirian 3:0ca91f8afec5 342 //pc.printf("Magnetic Heading: %f degress\n\r",heading);
kkizirian 3:0ca91f8afec5 343 return heading;
kkizirian 3:0ca91f8afec5 344 }
kkizirian 3:0ca91f8afec5 345
kkizirian 3:0ca91f8afec5 346 float computeAngleToDestination(float diffLat, float diffLong)
kkizirian 3:0ca91f8afec5 347 {
kkizirian 3:0ca91f8afec5 348 float angle = 0.0;
kkizirian 3:0ca91f8afec5 349
kkizirian 3:0ca91f8afec5 350 if (diffLat > 0) {
kkizirian 3:0ca91f8afec5 351 if (diffLong > 0) {
kkizirian 3:0ca91f8afec5 352 // in quadrant 1
kkizirian 3:0ca91f8afec5 353 angle = 180*atan2(diffLat,diffLong)/PI;
kkizirian 3:0ca91f8afec5 354 } else {
kkizirian 3:0ca91f8afec5 355 // in quadrant 2
kkizirian 3:0ca91f8afec5 356 angle = 180*atan2(diffLat,-1 * diffLong)/PI;
kkizirian 3:0ca91f8afec5 357 angle = 180 - angle;
kkizirian 3:0ca91f8afec5 358 }
kkizirian 3:0ca91f8afec5 359 } else {
kkizirian 3:0ca91f8afec5 360 if (diffLong > 0) {
kkizirian 3:0ca91f8afec5 361 // in quadrant 4
kkizirian 3:0ca91f8afec5 362 angle = 180*atan2(-1*diffLat, diffLong)/PI;
kkizirian 3:0ca91f8afec5 363 angle = 360 - angle;
kkizirian 3:0ca91f8afec5 364 } else {
kkizirian 3:0ca91f8afec5 365 // in quadrant 3
kkizirian 3:0ca91f8afec5 366 angle = 180*atan2(-1*diffLat, -1*diffLong)/PI;
kkizirian 3:0ca91f8afec5 367 angle = 180 + angle;
kkizirian 3:0ca91f8afec5 368 }
kkizirian 3:0ca91f8afec5 369 }
kkizirian 3:0ca91f8afec5 370
kkizirian 3:0ca91f8afec5 371 //pc.printf("Angle to Destination: %f degress\n\r",angle);
kkizirian 3:0ca91f8afec5 372 return angle;
kkizirian 5:430f44669f94 373 }
kkizirian 5:430f44669f94 374
kkizirian 5:430f44669f94 375 int getNextClass(vector<Course>& cVec)
kkizirian 5:430f44669f94 376 {
kkizirian 5:430f44669f94 377 int numIterations = 0;
kkizirian 5:430f44669f94 378 for (int i = 0; i < cVec.size(); i++) {
kkizirian 5:430f44669f94 379 numIterations++;
kkizirian 5:430f44669f94 380 pc.printf("Iteration : %i\ncurrHour: %i\ncourseHour: %i\n", numIterations, currHour, cVec[i].getHour_inMilitaryTime());
kkizirian 5:430f44669f94 381 if (courseVec[i].getHour_inMilitaryTime() < currHour)
kkizirian 5:430f44669f94 382 continue;
kkizirian 5:430f44669f94 383 else if (courseVec[i].getHour_inMilitaryTime() > currHour)
kkizirian 5:430f44669f94 384 return i;
kkizirian 5:430f44669f94 385 else if (courseVec[i].getHour_inMilitaryTime() == currHour) {
kkizirian 5:430f44669f94 386 if (courseVec[i].getMinute() <= currMinute)
kkizirian 5:430f44669f94 387 continue;
kkizirian 5:430f44669f94 388 else if (courseVec[i].getMinute() > currMinute) {
kkizirian 5:430f44669f94 389 return i;
kkizirian 5:430f44669f94 390 }
kkizirian 5:430f44669f94 391 }
kkizirian 5:430f44669f94 392 if (numIterations == cVec.size())
kkizirian 5:430f44669f94 393 return 0;
kkizirian 5:430f44669f94 394 }
kkizirian 5:430f44669f94 395 return 0;
kkizirian 5:430f44669f94 396 }
kkizirian 5:430f44669f94 397
kkizirian 5:430f44669f94 398 void timeToNextClass()
kkizirian 6:ceb6a5426add 399 {
kkizirian 5:430f44669f94 400 hoursToNextClass = courseVec[nextClass].getHour_inMilitaryTime() - currHour;
kkizirian 5:430f44669f94 401 if (hoursToNextClass < 0)
kkizirian 5:430f44669f94 402 hoursToNextClass += 24;
kkizirian 5:430f44669f94 403
kkizirian 5:430f44669f94 404 minutesToNextClass = courseVec[nextClass].getMinute() - currMinute;
kkizirian 5:430f44669f94 405 if (minutesToNextClass < 0) {
kkizirian 5:430f44669f94 406 hoursToNextClass--;
kkizirian 5:430f44669f94 407 minutesToNextClass += 60;
kkizirian 5:430f44669f94 408 }
kkizirian 6:ceb6a5426add 409
kkizirian 5:430f44669f94 410 secondsToNextClass = 60 - currSecond;
kkizirian 5:430f44669f94 411 minutesToNextClass--;
kkizirian 6:ceb6a5426add 412
kkizirian 5:430f44669f94 413 if (minutesToNextClass < 0) {
kkizirian 5:430f44669f94 414 hoursToNextClass--;
kkizirian 5:430f44669f94 415 minutesToNextClass += 60;
kkizirian 5:430f44669f94 416 }
kkizirian 6:ceb6a5426add 417
kkizirian 5:430f44669f94 418 if (hoursToNextClass < 0)
kkizirian 5:430f44669f94 419 hoursToNextClass += 24;
kkizirian 6:ceb6a5426add 420 }
kkizirian 6:ceb6a5426add 421
kkizirian 6:ceb6a5426add 422 // convert from DDMM.mmmm to decimal
kkizirian 9:5b871fb9f554 423 float latToDecimal(float latitudeInDDMM, char northOrSouth)
kkizirian 6:ceb6a5426add 424 {
kkizirian 6:ceb6a5426add 425 float latInDec = 0.0;
kkizirian 6:ceb6a5426add 426 float temp = 0.0;
kkizirian 6:ceb6a5426add 427 latInDec = latitudeInDDMM / 100;
kkizirian 6:ceb6a5426add 428 temp = latInDec - floor(latInDec);
kkizirian 6:ceb6a5426add 429 temp = temp / .6;
kkizirian 6:ceb6a5426add 430 latInDec = floor(latInDec) + temp;
kkizirian 10:5579618161ef 431 if (northOrSouth == 'S')
kkizirian 9:5b871fb9f554 432 return -1 * latInDec;
kkizirian 6:ceb6a5426add 433 return latInDec;
kkizirian 6:ceb6a5426add 434 }
kkizirian 6:ceb6a5426add 435
nkela6 13:0eb9fbd63fb2 436 float displacement(float diffLat,float diffLong)
nkela6 13:0eb9fbd63fb2 437 {
nkela6 14:d8a6134cafa3 438 float d = sqrt(diffLat*diffLat+diffLong*diffLong);
nkela6 14:d8a6134cafa3 439 return d;
nkela6 13:0eb9fbd63fb2 440 }
nkela6 13:0eb9fbd63fb2 441 float calc_eta(float displacement, float speed)
nkela6 13:0eb9fbd63fb2 442 {
nkela6 15:75a121b14e5d 443 float estTimeArr = displacement/speed; // for displacement. take average speed // convert to minutes later
nkela6 15:75a121b14e5d 444 estTimeArr = estTimeArr+ 0.25*estTimeArr; //adding delay for distance vs displacement and traffic lights
nkela6 15:75a121b14e5d 445 return estTimeArr;
nkela6 14:d8a6134cafa3 446 }
nkela6 13:0eb9fbd63fb2 447
kkizirian 9:5b871fb9f554 448 float longToDecimal(float longitudeInDDMM, char eastOrWest)
kkizirian 6:ceb6a5426add 449 {
kkizirian 6:ceb6a5426add 450 float longInDec = 0.0;
kkizirian 6:ceb6a5426add 451 float temp = 0.0;
kkizirian 6:ceb6a5426add 452 longInDec = longitudeInDDMM / 100;
kkizirian 6:ceb6a5426add 453 temp = longInDec - floor(longInDec);
kkizirian 6:ceb6a5426add 454 temp = temp / .6;
kkizirian 6:ceb6a5426add 455 longInDec = floor(longInDec) + temp;
kkizirian 9:5b871fb9f554 456 if (eastOrWest == 'E')
kkizirian 9:5b871fb9f554 457 return longInDec;
kkizirian 6:ceb6a5426add 458 return -1 * longInDec;
nkela6 13:0eb9fbd63fb2 459 }
nkela6 13:0eb9fbd63fb2 460
nkela6 13:0eb9fbd63fb2 461 bool late(float eta)
nkela6 13:0eb9fbd63fb2 462 {
nkela6 13:0eb9fbd63fb2 463 float totalMinutes = hoursToNextClass*60+ minutesToNextClass+ secondsToNextClass/60;
nkela6 14:d8a6134cafa3 464 if(totalMinutes>eta) {
nkela6 13:0eb9fbd63fb2 465 return 1;
nkela6 14:d8a6134cafa3 466 } else {
nkela6 13:0eb9fbd63fb2 467 return 0;
nkela6 13:0eb9fbd63fb2 468 }
nkela6 14:d8a6134cafa3 469 }
nkela6 16:4b4e6cf66e7c 470 bool snooze()
nkela6 16:4b4e6cf66e7c 471 {
nkela6 16:4b4e6cf66e7c 472 }