26 out_minimum_rx_buf_to_decide = 3;
28 if (m_rx_buffer.size() < 3)
return true;
30 const size_t nBytesAval = m_rx_buffer.size();
34 m_rx_buffer.peek_many(&peek_buffer[0], 3);
35 if (peek_buffer[0] !=
'$' || peek_buffer[1] !=
'G' || peek_buffer[2] !=
'P')
44 bool line_is_ended =
false;
47 const char val =
static_cast<char>(m_rx_buffer.peek(i));
48 if (
val ==
'\r' ||
val ==
'\n')
58 for (
size_t i = 0; i < line.size(); i++) m_rx_buffer.pop();
61 const bool did_have_gga = m_just_parsed_messages.has_GGA_datum;
63 line, m_just_parsed_messages,
false ))
66 m_just_parsed_messages.sensorLabel =
"NMEA";
69 const bool now_has_gga = m_just_parsed_messages.has_GGA_datum;
70 if (now_has_gga && !did_have_gga)
78 std::cerr <<
"[CGPSInterface::implement_parser_NMEA] Line " 79 "of unknown format ignored: `" 87 out_minimum_rx_buf_to_decide = nBytesAval + 1;
105 if (verbose) cout <<
"[CGPSInterface] GPS raw string: " <<
s << endl;
108 if (
s.size() < 7)
return false;
109 if (
s[0] !=
'$' ||
s[1] !=
'G')
return false;
111 std::vector<std::string> lstTokens;
113 s,
"*,\t\r\n", lstTokens,
false );
114 if (lstTokens.size() < 3)
return false;
116 for (
size_t i = 0; i < lstTokens.size(); i++)
119 bool parsed_ok =
false;
121 if (lstTokens[0] ==
"$GPGGA" && lstTokens.size() >= 13)
126 bool all_fields_ok =
true;
133 token = lstTokens[1];
134 if (token.size() >= 6)
141 all_fields_ok =
false;
144 token = lstTokens[2];
145 if (token.size() >= 4)
147 double lat = 10 * (token[0] -
'0') + token[1] -
'0';
148 lat += atof(&(token.c_str()[2])) / 60.0;
152 all_fields_ok =
false;
155 token = lstTokens[3];
157 all_fields_ok =
false;
158 else if (token[0] ==
'S')
162 token = lstTokens[4];
163 if (token.size() >= 5)
166 100 * (token[0] -
'0') + 10 * (token[1] -
'0') + token[2] -
'0';
167 lat += atof(&(token.c_str()[3])) / 60.0;
171 all_fields_ok =
false;
174 token = lstTokens[5];
176 all_fields_ok =
false;
177 else if (token[0] ==
'W')
181 token = lstTokens[6];
186 token = lstTokens[7];
191 token = lstTokens[8];
199 token = lstTokens[9];
201 all_fields_ok =
false;
210 token = lstTokens[11];
231 parsed_ok = all_fields_ok;
233 else if (lstTokens[0] ==
"$GPRMC" && lstTokens.size() >= 13)
238 bool all_fields_ok =
true;
245 token = lstTokens[1];
246 if (token.size() >= 6)
253 all_fields_ok =
false;
256 token = lstTokens[2];
258 all_fields_ok =
false;
263 token = lstTokens[3];
264 if (token.size() >= 4)
266 double lat = 10 * (token[0] -
'0') + token[1] -
'0';
267 lat += atof(&(token.c_str()[2])) / 60.0;
271 all_fields_ok =
false;
274 token = lstTokens[4];
276 all_fields_ok =
false;
277 else if (token[0] ==
'S')
281 token = lstTokens[5];
282 if (token.size() >= 5)
285 100 * (token[0] -
'0') + 10 * (token[1] -
'0') + token[2] -
'0';
286 lat += atof(&(token.c_str()[3])) / 60.0;
290 all_fields_ok =
false;
293 token = lstTokens[6];
295 all_fields_ok =
false;
296 else if (token[0] ==
'W')
300 token = lstTokens[7];
304 token = lstTokens[8];
308 token = lstTokens[9];
309 if (token.size() >= 6)
316 all_fields_ok =
false;
319 token = lstTokens[10];
320 if (token.size() >= 2)
324 token = lstTokens[11];
326 all_fields_ok =
false;
327 else if (token[0] ==
'W')
332 if (lstTokens.size() >= 14)
335 token = lstTokens[12];
337 all_fields_ok =
false;
354 parsed_ok = all_fields_ok;
356 else if (lstTokens[0] ==
"$GPGLL" && lstTokens.size() >= 5)
361 bool all_fields_ok =
true;
367 token = lstTokens[1];
368 if (token.size() >= 4)
370 double lat = 10 * (token[0] -
'0') + token[1] -
'0';
371 lat += atof(&(token.c_str()[2])) / 60.0;
375 all_fields_ok =
false;
378 token = lstTokens[2];
380 all_fields_ok =
false;
381 else if (token[0] ==
'S')
385 token = lstTokens[3];
386 if (token.size() >= 5)
389 100 * (token[0] -
'0') + 10 * (token[1] -
'0') + token[2] -
'0';
390 lat += atof(&(token.c_str()[3])) / 60.0;
394 all_fields_ok =
false;
397 token = lstTokens[4];
399 all_fields_ok =
false;
400 else if (token[0] ==
'W')
403 if (lstTokens.size() >= 7)
406 token = lstTokens[5];
407 if (token.size() >= 6)
410 10 * (token[0] -
'0') + token[1] -
'0';
412 10 * (token[2] -
'0') + token[3] -
'0';
416 all_fields_ok =
false;
419 token = lstTokens[6];
421 all_fields_ok =
false;
435 parsed_ok = all_fields_ok;
437 else if (lstTokens[0] ==
"$GPVTG" && lstTokens.size() >= 9)
442 bool all_fields_ok =
true;
453 if (lstTokens[2] !=
"T" || lstTokens[4] !=
"M" || lstTokens[6] !=
"N" ||
455 all_fields_ok =
false;
464 parsed_ok = all_fields_ok;
466 else if (lstTokens[0] ==
"$GPZDA" && lstTokens.size() >= 5)
471 bool all_fields_ok =
true;
485 token = lstTokens[1];
486 if (token.size() >= 6)
493 all_fields_ok =
false;
496 token = lstTokens[2];
499 token = lstTokens[3];
502 token = lstTokens[4];
522 parsed_ok = all_fields_ok;
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:-)
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)
void tokenize(const std::string &inString, const std::string &inDelimiters, OUT_CONTAINER &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters.
double orthometric_altitude
The measured orthometric altitude, in meters (A)+(B).
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
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...
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)