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