Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 *t = gps.timeNow(); 00026 //pc.printf("%02d:%02d:%02d.%i %02d/%02d/%04d\r\n\n", t->hour, t->minute, t->second, t->hundreths, t->day, t->month, t->year); 00027 //delete(t); 00028 00029 GPS_Time::GPS_Time() 00030 { 00031 year = 2000; 00032 month = 1; 00033 day = 1; 00034 hour = 0; 00035 minute = 0; 00036 second = 0; 00037 tenths = 0; 00038 hundreths = 0; 00039 status = 'V'; 00040 velocity = 0; 00041 track = 0; 00042 magvar_dir = 'W'; 00043 magvar = 0; 00044 } 00045 00046 time_t 00047 GPS_Time::to_C_tm(bool set) 00048 { 00049 GPS_Time t; 00050 tm ct; 00051 time_t q; 00052 00053 timeNow(&t); 00054 ct.tm_sec = t.second; 00055 ct.tm_min = t.minute; 00056 ct.tm_hour = t.hour; 00057 ct.tm_mday = t.day; 00058 ct.tm_mon = t.month - 1; 00059 ct.tm_year = t.year - 1900; 00060 ct.tm_isdst = 0; // GPS has no understanding of DST. 00061 00062 q = mktime(&ct); 00063 if (set) { 00064 set_time(q); 00065 } 00066 return q; 00067 } 00068 00069 GPS_Time * 00070 GPS_Time::timeNow(GPS_Time *n) 00071 { 00072 if (n == NULL) n = new GPS_Time; 00073 00074 do { 00075 memcpy(n, this, sizeof(GPS_Time)); 00076 } 00077 while (memcmp(n, this, sizeof(GPS_Time))); 00078 return n; 00079 } 00080 00081 void 00082 GPS_Time::operator++() 00083 { 00084 hundreths++; 00085 if (hundreths == 10) { 00086 hundreths = 0; 00087 tenths++; 00088 if (tenths == 10) { 00089 tenths = hundreths = 0; 00090 } 00091 } 00092 } 00093 00094 void 00095 GPS_Time::operator++(int) 00096 { 00097 const int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 00098 bool dateInc = false; 00099 00100 tenths = hundreths = 0; 00101 second++; 00102 00103 if (second == 60) { 00104 second = 0; 00105 minute++; 00106 if (minute == 60) { 00107 minute = 0; 00108 hour++; 00109 if (hour == 24) { 00110 hour = 0; 00111 dateInc = true; 00112 } 00113 } 00114 } 00115 00116 if (dateInc) { 00117 /* Handle February leap year. */ 00118 int leap_year = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 1 : 0; 00119 int days_this_month = days[month - 1]; 00120 if (month == 2 && leap_year) days_this_month++; 00121 day++; 00122 if (day > days_this_month) { 00123 day = 1; 00124 month++; 00125 if (month == 13) { 00126 year++; 00127 } 00128 } 00129 } 00130 } 00131 00132 // $GPRMC,112709.735,A,5611.5340,N,00302.0306,W,000.0,307.0,150411,,,A*70 00133 void 00134 GPS_Time::nmea_rmc(char *s) 00135 { 00136 char *token; 00137 int token_counter = 0; 00138 char *time = (char *)NULL; 00139 char *date = (char *)NULL; 00140 char *stat = (char *)NULL; 00141 char *vel = (char *)NULL; 00142 char *trk = (char *)NULL; 00143 char *magv = (char *)NULL; 00144 char *magd = (char *)NULL; 00145 00146 token = strtok(s, ","); 00147 while (token) { 00148 switch (token_counter) { 00149 case 9: date = token; break; 00150 case 1: time = token; break; 00151 case 2: stat = token; break; 00152 case 7: vel = token; break; 00153 case 8: trk = token; break; 00154 case 10: magv = token; break; 00155 case 11: magd = token; break; 00156 } 00157 token = strtok((char *)NULL, ","); 00158 token_counter++; 00159 } 00160 00161 if (stat && date && time) { 00162 hour = (char)((time[0] - '0') * 10) + (time[1] - '0'); 00163 minute = (char)((time[2] - '0') * 10) + (time[3] - '0'); 00164 second = (char)((time[4] - '0') * 10) + (time[5] - '0'); 00165 day = (char)((date[0] - '0') * 10) + (date[1] - '0'); 00166 month = (char)((date[2] - '0') * 10) + (date[3] - '0'); 00167 year = (int)((date[4] - '0') * 10) + (date[5] - '0') + 2000; 00168 status = stat[0]; 00169 velocity = atof(vel); 00170 track = atof(trk); 00171 magvar = atof(magv); 00172 magvar_dir = magd[0]; 00173 } 00174 } 00175 00176 double 00177 GPS_Time::julian_day_number(GPS_Time *t) { 00178 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; 00179 return wikipedia_jdn; 00180 } 00181 00182 double 00183 GPS_Time::julian_date(GPS_Time *t) { 00184 double hour, minute, second, jd; 00185 hour = (double)t->hour; 00186 minute = (double)t->minute; 00187 second = (double)t->second + ((double)t->tenths / 10.) + ((double)t->hundreths / 100.); 00188 00189 jd = julian_day_number(t) - 0.5 + 00190 ((hour - 12.) / 24.) + 00191 (minute / 1440.) + 00192 (second / 86400.); 00193 00194 return jd; 00195 } 00196 00197 double 00198 GPS_Time::siderealDegrees(double jd, double longitude) { 00199 double sidereal, gmst, lmst; 00200 double T = jd - 2451545.0; 00201 double T1 = T / 36525.0; 00202 double T2 = T1 * T1; 00203 double T3 = T2 * T1; 00204 00205 /* Calculate gmst angle. */ 00206 sidereal = 280.46061837 + (360.98564736629 * T) + (0.000387933 * T2) - (T3 / 38710000.0); 00207 00208 /* Convert to degrees. */ 00209 sidereal = fmod(sidereal, 360.0); 00210 if (sidereal < 0.0) sidereal += 360.0; 00211 00212 gmst = sidereal; 00213 lmst = gmst + longitude; 00214 return lmst; 00215 } 00216 00217 double 00218 GPS_Time::siderealDegrees(GPS_Time *t, double longitude) { 00219 if (t == NULL) t = new GPS_Time; 00220 return siderealDegrees(julian_date(t), longitude); 00221 } 00222 00223 double 00224 GPS_Time::siderealHA(double jd, double longitude) { 00225 double lmst = siderealDegrees(jd, longitude); 00226 return lmst / 360.0 * 24.0; 00227 } 00228 00229 double 00230 GPS_Time::siderealHA(GPS_Time *t, double longitude) { 00231 double lmst = siderealDegrees(t, longitude); 00232 return lmst / 360.0 * 24.0; 00233 } 00234
Generated on Tue Jul 12 2022 23:57:33 by
1.7.2