Allows for a GPS module to be connected to a serial port and exposes an easy to use API to get the GPS data. New feature, added Mbed/LPC17xx RTC synchronisation
Dependents: SatGPS AntiTheftGPS FLIGHT_CONTROL_AND_COMMUNICATIONS_SYSTEM GPS-Lora ... more
GPS_Time.cpp
00001 /* 00002 Copyright (c) 2010 Andy Kirkham 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 00023 #include "GPS_Time.h" 00024 00025 GPS_Time::GPS_Time() 00026 { 00027 year = 2000; 00028 month = 1; 00029 day = 1; 00030 hour = 0; 00031 minute = 0; 00032 second = 0; 00033 tenths = 0; 00034 hundreths = 0; 00035 status = 'V'; 00036 velocity = 0; 00037 track = 0; 00038 magvar_dir = 'W'; 00039 magvar = 0; 00040 } 00041 00042 time_t 00043 GPS_Time::to_C_tm(bool set) 00044 { 00045 GPS_Time t; 00046 tm ct; 00047 time_t q; 00048 00049 timeNow(&t); 00050 ct.tm_sec = t.second; 00051 ct.tm_min = t.minute; 00052 ct.tm_hour = t.hour; 00053 ct.tm_mday = t.day; 00054 ct.tm_mon = t.month - 1; 00055 ct.tm_year = t.year - 1900; 00056 ct.tm_isdst = 0; // GPS has no understanding of DST. 00057 00058 q = mktime(&ct); 00059 if (set) { 00060 set_time(q); 00061 } 00062 return q; 00063 } 00064 00065 GPS_Time * 00066 GPS_Time::timeNow(GPS_Time *n) 00067 { 00068 if (n == NULL) n = new GPS_Time; 00069 00070 do { 00071 memcpy(n, this, sizeof(GPS_Time)); 00072 } 00073 while (memcmp(n, this, sizeof(GPS_Time))); 00074 return n; 00075 } 00076 00077 void 00078 GPS_Time::operator++() 00079 { 00080 hundreths++; 00081 if (hundreths == 10) { 00082 hundreths = 0; 00083 tenths++; 00084 if (tenths == 10) { 00085 tenths = hundreths = 0; 00086 } 00087 } 00088 } 00089 00090 void 00091 GPS_Time::operator++(int) 00092 { 00093 const int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 00094 bool dateInc = false; 00095 00096 tenths = hundreths = 0; 00097 second++; 00098 00099 if (second == 60) { 00100 second = 0; 00101 minute++; 00102 if (minute == 60) { 00103 minute = 0; 00104 hour++; 00105 if (hour == 24) { 00106 hour = 0; 00107 dateInc = true; 00108 } 00109 } 00110 } 00111 00112 if (dateInc) { 00113 /* Handle February leap year. */ 00114 int leap_year = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 1 : 0; 00115 int days_this_month = days[month - 1]; 00116 if (month == 2 && leap_year) days_this_month++; 00117 day++; 00118 if (day > days_this_month) { 00119 day = 1; 00120 month++; 00121 if (month == 13) { 00122 year++; 00123 } 00124 } 00125 } 00126 } 00127 00128 // $GPRMC,112709.735,A,5611.5340,N,00302.0306,W,000.0,307.0,150411,,,A*70 00129 void 00130 GPS_Time::nmea_rmc(char *s) 00131 { 00132 char *token; 00133 int token_counter = 0; 00134 char *time = (char *)NULL; 00135 char *date = (char *)NULL; 00136 char *stat = (char *)NULL; 00137 char *vel = (char *)NULL; 00138 char *trk = (char *)NULL; 00139 char *magv = (char *)NULL; 00140 char *magd = (char *)NULL; 00141 00142 token = strtok(s, ","); 00143 while (token) { 00144 switch (token_counter) { 00145 case 9: date = token; break; 00146 case 1: time = token; break; 00147 case 2: stat = token; break; 00148 case 7: vel = token; break; 00149 case 8: trk = token; break; 00150 case 10: magv = token; break; 00151 case 11: magd = token; break; 00152 } 00153 token = strtok((char *)NULL, ","); 00154 token_counter++; 00155 } 00156 00157 if (stat && date && time) { 00158 hour = (char)((time[0] - '0') * 10) + (time[1] - '0'); 00159 minute = (char)((time[2] - '0') * 10) + (time[3] - '0'); 00160 second = (char)((time[4] - '0') * 10) + (time[5] - '0'); 00161 day = (char)((date[0] - '0') * 10) + (date[1] - '0'); 00162 month = (char)((date[2] - '0') * 10) + (date[3] - '0'); 00163 year = (int)((date[4] - '0') * 10) + (date[5] - '0') + 2000; 00164 status = stat[0]; 00165 velocity = atof(vel); 00166 track = atof(trk); 00167 magvar = atof(magv); 00168 magvar_dir = magd[0]; 00169 } 00170 } 00171 00172 double 00173 GPS_Time::julian_day_number(GPS_Time *t) { 00174 double wikipedia_jdn = (double)(1461 * ((int)t->year + 4800 + ((int)t->month - 14) / 12)) / 4 + (367 * ((int)t->month - 2 - 12 * (((int)t->month - 14) / 12))) / 12 - (3 * (((int)t->year + 4900 + ((int)t->month - 14) / 12 ) / 100)) / 4 + (int)t->day - 32075; 00175 return wikipedia_jdn; 00176 } 00177 00178 double 00179 GPS_Time::julian_date(GPS_Time *t) { 00180 double hour, minute, second, jd; 00181 hour = (double)t->hour; 00182 minute = (double)t->minute; 00183 second = (double)t->second + ((double)t->tenths / 10.) + ((double)t->hundreths / 100.); 00184 00185 jd = julian_day_number(t) - 0.5 + 00186 ((hour - 12.) / 24.) + 00187 (minute / 1440.) + 00188 (second / 86400.); 00189 00190 return jd; 00191 } 00192 00193 double 00194 GPS_Time::siderealDegrees(double jd, double longitude) { 00195 double sidereal, gmst, lmst; 00196 double T = jd - 2451545.0; 00197 double T1 = T / 36525.0; 00198 double T2 = T1 * T1; 00199 double T3 = T2 * T1; 00200 00201 /* Calculate gmst angle. */ 00202 sidereal = 280.46061837 + (360.98564736629 * T) + (0.000387933 * T2) - (T3 / 38710000.0); 00203 00204 /* Convert to degrees. */ 00205 sidereal = fmod(sidereal, 360.0); 00206 if (sidereal < 0.0) sidereal += 360.0; 00207 00208 gmst = sidereal; 00209 lmst = gmst + longitude; 00210 return lmst; 00211 } 00212 00213 double 00214 GPS_Time::siderealDegrees(GPS_Time *t, double longitude) { 00215 if (t == NULL) t = new GPS_Time; 00216 return siderealDegrees(julian_date(t), longitude); 00217 } 00218 00219 double 00220 GPS_Time::siderealHA(double jd, double longitude) { 00221 double lmst = siderealDegrees(jd, longitude); 00222 return lmst / 360.0 * 24.0; 00223 } 00224 00225 double 00226 GPS_Time::siderealHA(GPS_Time *t, double longitude) { 00227 double lmst = siderealDegrees(t, longitude); 00228 return lmst / 360.0 * 24.0; 00229 } 00230
Generated on Tue Jul 12 2022 18:11:53 by 1.7.2