nmea gps library - without any serial
Dependents: HARP2 HARP3 20180621_FT813
Fork of GPS_parser by
nmea_parser.cpp
00001 /* 00002 * @file nmea_parser.cpp 00003 * @author Tyler Weaver 00004 * 00005 * @section LICENSE 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00008 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00009 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00010 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00011 * furnished to do so, subject to the following conditions: 00012 * 00013 * The above copyright notice and this permission notice shall be included in all copies or 00014 * substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00017 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00018 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00019 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * @section DESCRIPTION 00023 * 00024 * NMEA GPS Serial Output parser. 00025 * Routine taken from NMEA Software Standard (NMEA 0183) 00026 * http://www.winsystems.com/software/nmea.pdf 00027 * 00028 * Only handles GGA and RMC Messages 00029 */ 00030 00031 #include "nmea_parser.h" 00032 00033 NmeaParser::NmeaParser() 00034 { 00035 longitude_ = 0.0; 00036 latitude_ = 0.0; 00037 utc_time_ = 0; 00038 lat_reference_ = '\0'; 00039 long_reference_ = '\0'; 00040 quality_ = 0; 00041 satellite_count_ = 0; 00042 hdop_ = 0.0; 00043 msl_altitude_ = 0.0; 00044 msl_altitude_unit_ = '\0'; 00045 00046 rmc_status_ = '\0'; 00047 speed_ = 0.0; 00048 track_ = 0.0; 00049 date_ = 0; 00050 00051 dec_longitude_ = 0.0; 00052 dec_latitude_ = 0.0; 00053 00054 current_ = NULL; 00055 } 00056 00057 float NmeaParser::nmea_to_dec(float deg_coord, char nsew) 00058 { 00059 int degree = static_cast<int>(deg_coord/100); 00060 float minutes = deg_coord - degree*100; 00061 float dec_deg = minutes / 60; 00062 float decimal = degree + dec_deg; 00063 if (nsew == 'S' || nsew == 'W') { // return negative 00064 decimal *= -1; 00065 } 00066 return decimal; 00067 } 00068 00069 // GET FUNCTIONS ///////////////////////////////////////////////////////////////// 00070 00071 float NmeaParser::msl_altitude () 00072 { 00073 if (!quality_) 00074 return 0.0; 00075 else 00076 return msl_altitude_; 00077 } 00078 00079 int NmeaParser::satellite_count () 00080 { 00081 if (!quality_) 00082 return 0; 00083 else 00084 return satellite_count_; 00085 } 00086 00087 float NmeaParser::longitude () 00088 { 00089 if (!quality_) 00090 return 0.0; 00091 else 00092 return longitude_; 00093 } 00094 00095 float NmeaParser::calc_dec_longitude () 00096 { 00097 dec_longitude_ = nmea_to_dec(longitude_, long_reference_); 00098 if (!quality_) 00099 return 0.0; 00100 else 00101 return dec_longitude_; 00102 } 00103 00104 float NmeaParser::latitude () 00105 { 00106 if (!quality_) 00107 return 0.0; 00108 else 00109 return latitude_; 00110 } 00111 00112 float NmeaParser::calc_dec_latitude () 00113 { 00114 dec_latitude_ = nmea_to_dec(latitude_, lat_reference_); 00115 if (!quality_) 00116 return 0.0; 00117 else 00118 return dec_latitude_; 00119 } 00120 00121 float NmeaParser::track () 00122 { 00123 if (!quality_) 00124 return 0.0; 00125 else 00126 return track_; 00127 } 00128 00129 float NmeaParser::speed () 00130 { 00131 if (!quality_) 00132 return 0.0; 00133 else 00134 return speed_; 00135 } 00136 00137 float NmeaParser::calc_altitude_ft () 00138 { 00139 if (!quality_) 00140 return 0.0; 00141 else 00142 return 3.280839895*msl_altitude_; 00143 } 00144 00145 int NmeaParser::quality () 00146 { 00147 return quality_; 00148 } 00149 00150 int NmeaParser::date() 00151 { 00152 return date_; 00153 } 00154 00155 float NmeaParser::utc_time () 00156 { 00157 return utc_time_; 00158 } 00159 00160 // NAVIGATION FUNCTIONS //////////////////////////////////////////////////////////// 00161 float NmeaParser::calc_initial_bearing(float pointLat, float pontLong) 00162 { 00163 const double d2r = PI / 180.0; 00164 const double r2d = 180.0 / PI; 00165 double calc_latitude = calc_dec_latitude (); 00166 double calc_longitude = calc_dec_longitude (); 00167 00168 double dlat = abs(pointLat - calc_latitude) * d2r; 00169 double dlong = abs(pontLong - calc_longitude) * d2r; 00170 double y = sin(dlong) * cos(pointLat * d2r); 00171 double x = cos(calc_latitude*d2r)*sin(pointLat*d2r) - sin(calc_latitude*d2r)*cos(pointLat*d2r)*cos(dlong); 00172 return 360.0-(atan2(y,x)*r2d); 00173 00174 // (atan2(y,x*r2d) + 360.0) % 360.0 ??? http://www.movable-type.co.uk/scripts/latlong.html 00175 } 00176 00177 double NmeaParser::calc_dist_to_mi(float pointLat, float pontLong) 00178 { 00179 const double d2r = PI / 180.0; 00180 double dlat = pointLat - calc_dec_latitude (); 00181 double dlong = pontLong - calc_dec_longitude (); 00182 double a = pow(sin(dlat/2.0),2.0) + cos(calc_dec_latitude ()*d2r) * cos(pointLat*d2r) * pow(sin(dlong/2.0),2.0); 00183 double c = 2.0 * asin(sqrt(abs(a))); 00184 double d = 63.765 * c; 00185 00186 return d; 00187 } 00188 00189 double NmeaParser::calc_dist_to_km(float pointLat, float pontLong) 00190 { 00191 return calc_dist_to_mi(pointLat, pontLong)*1.609344; 00192 } 00193 00194 char *NmeaParser::my_token(char *source,char token) 00195 { 00196 char *start; 00197 /* The source string is real only for the first call. Subsequent calls 00198 are made with the source string pointer as NULL 00199 */ 00200 if(source != NULL) { 00201 /* If the string is empty return NULL */ 00202 if(strlen(source) == 0) 00203 return NULL; 00204 strcpy(stat_string_,source); 00205 /* Current is our 'current' position within the string */ 00206 current_ = stat_string_; 00207 } 00208 start = current_; 00209 00210 while (true) { 00211 /* If we're at the end of the string, return NULL */ 00212 if((*current_ == '\0') && (current_ == start)) 00213 return NULL; 00214 /* If we're at the end now, but weren't when we started, we need 00215 to return the pointer for the last field before the end of string 00216 */ 00217 if(*current_ == '\0') 00218 return start; 00219 /* If we've located our specified token (comma) in the string 00220 load its location in the copy with an end of string marker 00221 so that it can be handled correctly by the calling program. 00222 */ 00223 if(*current_ == token) { 00224 *current_ = '\0'; 00225 current_++; 00226 return start; 00227 } else { 00228 current_++; 00229 } 00230 } 00231 } 00232 00233 int NmeaParser::parse(char *string) 00234 { 00235 int field_count; 00236 field_count = 0; 00237 /* NMEA 0183 fields are delimited by commas. The my_token function returns 00238 pointers to the fields. 00239 */ 00240 /* Get the first field pointer */ 00241 field_[0] = my_token(string,','); 00242 field_count++; 00243 00244 while (true) { 00245 /* Contiue retrieving fields until there are no more (NULL) */ 00246 field_[field_count] = my_token(NULL,','); 00247 if(field_[field_count] == NULL) 00248 break; 00249 field_count++; 00250 } 00251 /* If we got at least ONE field */ 00252 if(field_count) { 00253 /* Check the first field for the valid NMEA 0183 headers */ 00254 if(strcmp(field_[0],"$GPGGA") == 0) { 00255 /* Retrieve the values from the remaining fields */ 00256 utc_time_ = atof(field_[1]); 00257 latitude_ = atof(field_[2]); 00258 lat_reference_ = *(field_[3]); 00259 longitude_ = atof(field_[4]); 00260 long_reference_ = *(field_[5]); 00261 quality_ = atoi(field_[6]); 00262 satellite_count_ = atoi(field_[7]); 00263 hdop_ = atof(field_[8]); 00264 msl_altitude_ = atof(field_[9]); 00265 msl_altitude_unit_ = *(field_[10]); 00266 return GGA; 00267 } 00268 if(strcmp(field_[0],"$GPRMC") == 0) { 00269 /* Retrieve the data from the remaining fields */ 00270 utc_time_ = atof(field_[1]); 00271 latitude_ = atof(field_[3]); 00272 lat_reference_ = *(field_[4]); 00273 longitude_ = atof(field_[5]); 00274 long_reference_ = *(field_[6]); 00275 speed_ = atof(field_[7]); 00276 track_ = atof(field_[8]); 00277 date_ = atol(field_[9]); 00278 return RMC; 00279 } 00280 } 00281 return NOT_PARSED; 00282 }
Generated on Tue Jul 12 2022 21:37:51 by 1.7.2