25 out_minimum_rx_buf_to_decide = 3;
27 if (m_rx_buffer.size() < 3)
return true;
29 const size_t nBytesAval = m_rx_buffer.size();
33 m_rx_buffer.peek_many(&peek_buffer[0], 3);
34 if (peek_buffer[0] !=
'$' || peek_buffer[1] !=
'G' || peek_buffer[2] !=
'P')
43 bool line_is_ended =
false;
46 const char val =
static_cast<char>(m_rx_buffer.peek(i));
47 if (
val ==
'\r' ||
val ==
'\n')
57 for (
size_t i = 0; i < line.size(); i++) m_rx_buffer.pop();
60 const bool did_have_gga = m_just_parsed_messages.has_GGA_datum;
62 line, m_just_parsed_messages,
false ))
65 m_just_parsed_messages.sensorLabel =
"NMEA";
68 const bool now_has_gga = m_just_parsed_messages.has_GGA_datum;
69 if (now_has_gga && !did_have_gga)
77 std::cerr <<
"[CGPSInterface::implement_parser_NMEA] Line " 78 "of unknown format ignored: `" 86 out_minimum_rx_buf_to_decide = nBytesAval + 1;
104 if (verbose) cout <<
"[CGPSInterface] GPS raw string: " <<
s << endl;
107 if (
s.size() < 7)
return false;
108 if (
s[0] !=
'$' ||
s[1] !=
'G')
return false;
110 std::vector<std::string> lstTokens;
112 s,
"*,\t\r\n", lstTokens,
false );
113 if (lstTokens.size() < 3)
return false;
115 for (
size_t i = 0; i < lstTokens.size(); i++)
118 bool parsed_ok =
false;
120 if (lstTokens[0] ==
"$GPGGA" && lstTokens.size() >= 13)
125 bool all_fields_ok =
true;
132 token = lstTokens[1];
133 if (token.size() >= 6)
140 all_fields_ok =
false;
143 token = lstTokens[2];
144 if (token.size() >= 4)
146 double lat = 10 * (token[0] -
'0') + token[1] -
'0';
147 lat += atof(&(token.c_str()[2])) / 60.0;
151 all_fields_ok =
false;
154 token = lstTokens[3];
156 all_fields_ok =
false;
157 else if (token[0] ==
'S')
161 token = lstTokens[4];
162 if (token.size() >= 5)
165 100 * (token[0] -
'0') + 10 * (token[1] -
'0') + token[2] -
'0';
166 lat += atof(&(token.c_str()[3])) / 60.0;
170 all_fields_ok =
false;
173 token = lstTokens[5];
175 all_fields_ok =
false;
176 else if (token[0] ==
'W')
180 token = lstTokens[6];
185 token = lstTokens[7];
190 token = lstTokens[8];
198 token = lstTokens[9];
200 all_fields_ok =
false;
209 token = lstTokens[11];
230 parsed_ok = all_fields_ok;
232 else if (lstTokens[0] ==
"$GPRMC" && lstTokens.size() >= 13)
237 bool all_fields_ok =
true;
244 token = lstTokens[1];
245 if (token.size() >= 6)
252 all_fields_ok =
false;
255 token = lstTokens[2];
257 all_fields_ok =
false;
262 token = lstTokens[3];
263 if (token.size() >= 4)
265 double lat = 10 * (token[0] -
'0') + token[1] -
'0';
266 lat += atof(&(token.c_str()[2])) / 60.0;
270 all_fields_ok =
false;
273 token = lstTokens[4];
275 all_fields_ok =
false;
276 else if (token[0] ==
'S')
280 token = lstTokens[5];
281 if (token.size() >= 5)
284 100 * (token[0] -
'0') + 10 * (token[1] -
'0') + token[2] -
'0';
285 lat += atof(&(token.c_str()[3])) / 60.0;
289 all_fields_ok =
false;
292 token = lstTokens[6];
294 all_fields_ok =
false;
295 else if (token[0] ==
'W')
299 token = lstTokens[7];
303 token = lstTokens[8];
307 token = lstTokens[9];
308 if (token.size() >= 6)
315 all_fields_ok =
false;
318 token = lstTokens[10];
319 if (token.size() >= 2)
323 token = lstTokens[11];
325 all_fields_ok =
false;
326 else if (token[0] ==
'W')
331 if (lstTokens.size() >= 14)
334 token = lstTokens[12];
336 all_fields_ok =
false;
353 parsed_ok = all_fields_ok;
355 else if (lstTokens[0] ==
"$GPGLL" && lstTokens.size() >= 5)
360 bool all_fields_ok =
true;
366 token = lstTokens[1];
367 if (token.size() >= 4)
369 double lat = 10 * (token[0] -
'0') + token[1] -
'0';
370 lat += atof(&(token.c_str()[2])) / 60.0;
374 all_fields_ok =
false;
377 token = lstTokens[2];
379 all_fields_ok =
false;
380 else if (token[0] ==
'S')
384 token = lstTokens[3];
385 if (token.size() >= 5)
388 100 * (token[0] -
'0') + 10 * (token[1] -
'0') + token[2] -
'0';
389 lat += atof(&(token.c_str()[3])) / 60.0;
393 all_fields_ok =
false;
396 token = lstTokens[4];
398 all_fields_ok =
false;
399 else if (token[0] ==
'W')
402 if (lstTokens.size() >= 7)
405 token = lstTokens[5];
406 if (token.size() >= 6)
409 10 * (token[0] -
'0') + token[1] -
'0';
411 10 * (token[2] -
'0') + token[3] -
'0';
415 all_fields_ok =
false;
418 token = lstTokens[6];
420 all_fields_ok =
false;
434 parsed_ok = all_fields_ok;
436 else if (lstTokens[0] ==
"$GPVTG" && lstTokens.size() >= 9)
441 bool all_fields_ok =
true;
452 if (lstTokens[2] !=
"T" || lstTokens[4] !=
"M" || lstTokens[6] !=
"N" ||
454 all_fields_ok =
false;
463 parsed_ok = all_fields_ok;
465 else if (lstTokens[0] ==
"$GPZDA" && lstTokens.size() >= 5)
470 bool all_fields_ok =
true;
484 token = lstTokens[1];
485 if (token.size() >= 6)
492 all_fields_ok =
false;
495 token = lstTokens[2];
498 token = lstTokens[3];
501 token = lstTokens[4];
521 parsed_ok = all_fields_ok;
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
uint8_t fix_quality
NMEA standard values: 0 = invalid, 1 = GPS fix (SPS), 2 = DGPS fix, 3 = PPS fix, 4 = Real Time Kinema...
content_t fields
Message content, accesible by individual fields.
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
mrpt::system::TTimeStamp getAsTimestamp(const mrpt::system::TTimeStamp &date) const
Build an MRPT timestamp with the hour/minute/sec of this structure and the date from the given timest...
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
mrpt::system::TTimeStamp originalReceivedTimestamp
The local computer-based timestamp based on the reception of the message in the computer.
content_t fields
Message content, accesible by individual fields.
uint32_t satellitesUsed
The number of satelites used to compute this estimation.
const size_t MAX_NMEA_LINE_LENGTH
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
content_t fields
Message content, accesible by individual fields.
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)
int8_t validity_char
This will be: 'A'=OK or 'V'=void.
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)
double orthometric_altitude
The measured orthometric altitude, in meters (A)+(B).
double altitude_meters
The measured altitude, in meters (A).
bool thereis_HDOP
This states whether to take into account the value in the HDOP field.
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)
double corrected_orthometric_altitude
The corrected (only for TopCon mmGPS) orthometric altitude, in meters mmGPS(A+B). ...
mrpt::system::TTimeStamp getDateAsTimestamp() const
Build an MRPT timestamp with the year/month/day of this observation.
bool implement_parser_NMEA(size_t &out_minimum_rx_buf_to_decide)
uint8_t date_day
Date: day (1-31), month (1-12), two-digits year (00-99)
content_t fields
Message content, accesible by individual fields.
float HDOP
The HDOP (Horizontal Dilution of Precision) as returned by the sensor.
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
This namespace contains representation of robot actions and observations.
double lat
[deg], [deg], hgt over sea level[m]
bool has_satellite_timestamp
If true, CObservation::timestamp has been generated from accurate satellite clock.
GLsizei const GLchar ** string
static bool parse_NMEA(const std::string &cmd_line, mrpt::obs::CObservationGPS &out_obs, const bool verbose=false)
Parses one line of NMEA data from a GPS receiver, and writes the recognized fields (if any) into an o...
void tokenize(const std::string &inString, const std::string &inDelimiters, std::deque< std::string > &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters.
double geoidal_distance
Undulation: Difference between the measured altitude and the geoid, in meters (B).
double magnetic_dir
Magnetic variation direction (East:+, West:-)
mrpt::system::TTimeStamp getDateAsTimestamp() const
Build an MRPT timestamp with the year/month/day of this observation.
mrpt::system::TTimeStamp getDateTimeAsTimestamp() const
Build an MRPT UTC timestamp with the year/month/day + hour/minute/sec of this observation.
void setMsg(const MSG_CLASS &msg)
Stores a message in the list messages, making a copy of the passed object.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
double speed_knots
Measured speed (in knots)
double direction_degrees
Measured speed direction (in degrees)
char positioning_mode
'A': Autonomous, 'D': Differential, 'N': Not valid, 'E': Estimated, 'M': Manual
content_t fields
Message content, accesible by individual fields.
std::string trim(const std::string &str)
Removes leading and trailing spaces.
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
int8_t validity_char
This will be: 'A'=OK or 'V'=void.
double ground_speed_knots
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
uint16_t date_year
2000-...
double true_track
Degrees.
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)