26 out_minimum_rx_buf_to_decide = 3;
28 if (m_rx_buffer.size()<3)
31 const size_t nBytesAval = m_rx_buffer.size();
35 m_rx_buffer.peek_many(&peek_buffer[0],3);
36 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') {
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;
64 m_just_parsed_messages.sensorLabel =
"NMEA";
67 const bool now_has_gga = m_just_parsed_messages.has_GGA_datum;
68 if (now_has_gga && !did_have_gga) {
75 std::cerr <<
"[CGPSInterface::implement_parser_NMEA] Line of unknown format ignored: `"<<line<<
"`\n";
82 out_minimum_rx_buf_to_decide = nBytesAval+1;
97 cout <<
"[CGPSInterface] GPS raw string: " <<
s << endl;
100 if (
s.size()<7)
return false;
101 if (
s[0]!=
'$' ||
s[1]!=
'G' )
return false;
103 std::vector<std::string> lstTokens;
105 if (lstTokens.size()<3)
return false;
107 for (
size_t i=0;i<lstTokens.size();i++) lstTokens[i] =
mrpt::system::trim(lstTokens[i]);
109 bool parsed_ok =
false;
111 if (lstTokens[0]==
"$GPGGA" && lstTokens.size()>=13)
116 bool all_fields_ok=
true;
123 token = lstTokens[1];
130 else all_fields_ok =
false;
133 token = lstTokens[2];
136 double lat = 10 * (token[0]-
'0') + token[1]-
'0';
137 lat += atof( & (token.c_str()[2]) ) / 60.0;
140 else all_fields_ok =
false;
143 token = lstTokens[3];
145 all_fields_ok =
false;
146 else if (token[0]==
'S')
150 token = lstTokens[4];
153 double lat = 100 * (token[0]-
'0') + 10 * (token[1]-
'0')+ token[2]-
'0';
154 lat += atof( & (token.c_str()[3]) ) / 60.0;
157 else all_fields_ok =
false;
160 token = lstTokens[5];
162 all_fields_ok =
false;
168 token = lstTokens[6];
173 token = lstTokens[7];
178 token = lstTokens[8];
181 gga.
fields.
HDOP = (float)atof( token.c_str() );
186 token = lstTokens[9];
187 if (token.empty()) all_fields_ok =
false;
195 token = lstTokens[11];
214 parsed_ok = all_fields_ok;
216 else if ( lstTokens[0]==
"$GPRMC" && lstTokens.size()>=13)
221 bool all_fields_ok =
true;
228 token = lstTokens[1];
235 else all_fields_ok =
false;
238 token = lstTokens[2];
239 if (token.empty()) all_fields_ok =
false;
243 token = lstTokens[3];
246 double lat = 10 * (token[0]-
'0') + token[1]-
'0';
247 lat += atof( & (token.c_str()[2]) ) / 60.0;
250 else all_fields_ok =
false;
253 token = lstTokens[4];
254 if (token.empty()) all_fields_ok =
false;
255 else if (token[0]==
'S')
259 token = lstTokens[5];
262 double lat = 100 * (token[0]-
'0') + 10 * (token[1]-
'0')+ token[2]-
'0';
263 lat += atof( & (token.c_str()[3]) ) / 60.0;
266 else all_fields_ok =
false;
269 token = lstTokens[6];
270 if (token.empty()) all_fields_ok =
false;
271 else if (token[0]==
'W')
275 token = lstTokens[7];
279 token = lstTokens[8];
283 token = lstTokens[9];
284 if (token.size()>=6) {
289 else all_fields_ok =
false;
292 token = lstTokens[10];
297 token = lstTokens[11];
298 if (token.empty()) all_fields_ok =
false;
299 else if (token[0]==
'W')
304 if (lstTokens.size()>=14) {
306 token = lstTokens[12];
307 if (token.empty()) all_fields_ok =
false;
319 parsed_ok = all_fields_ok;
321 else if ( lstTokens[0]==
"$GPGLL" && lstTokens.size()>=5)
326 bool all_fields_ok =
true;
332 token = lstTokens[1];
335 double lat = 10 * (token[0]-
'0') + token[1]-
'0';
336 lat += atof( & (token.c_str()[2]) ) / 60.0;
339 else all_fields_ok =
false;
342 token = lstTokens[2];
343 if (token.empty()) all_fields_ok =
false;
344 else if (token[0]==
'S')
348 token = lstTokens[3];
351 double lat = 100 * (token[0]-
'0') + 10 * (token[1]-
'0')+ token[2]-
'0';
352 lat += atof( & (token.c_str()[3]) ) / 60.0;
355 else all_fields_ok =
false;
358 token = lstTokens[4];
359 if (token.empty()) all_fields_ok =
false;
360 else if (token[0]==
'W')
363 if (lstTokens.size()>=7) {
365 token = lstTokens[5];
372 else all_fields_ok =
false;
375 token = lstTokens[6];
376 if (token.empty()) all_fields_ok =
false;
387 parsed_ok = all_fields_ok;
389 else if ( lstTokens[0]==
"$GPVTG" && lstTokens.size()>=9)
394 bool all_fields_ok =
true;
405 if (lstTokens[2]!=
"T" ||lstTokens[4]!=
"M" ||lstTokens[6]!=
"N" ||lstTokens[8]!=
"K")
414 parsed_ok = all_fields_ok;
417 else if ( lstTokens[0]==
"$GPZDA" && lstTokens.size()>=5)
422 bool all_fields_ok =
true;
436 token = lstTokens[1];
437 if (token.size()>=6) {
442 else all_fields_ok =
false;
445 token = lstTokens[2];
449 token = lstTokens[3];
453 token = lstTokens[4];
471 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)
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.
bool has_satellite_timestamp
If true, CObservation::timestamp has been generated from accurate satellite clock. Otherwise, no GPS data is available and timestamps are based on the local computer clock.
uint8_t date_year
Date: day (1-31), month (1-12), two-digits year (00-99)
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. Where available, this should contain the accurate satellite-based time...
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 BASE_IMPEXP 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 magnetic_track
Degrees.
double ground_speed_knots
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
void BASE_IMPEXP tokenize(const std::string &inString, const std::string &inDelimiters, std::deque< std::string > &outTokens, bool skipBlankTokens=true) MRPT_NO_THROWS
Tokenizes a string according to a set of delimiting characters.
uint16_t date_year
2000-...
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)