static bool PZAN3(NMEAInputLine &line, NMEAInfo &info) { // old: $PZAN3,+,026,V,321,035,A,321,035,V*cc // new: $PZAN3,+,026,A,321,035,V[,A]*cc line.Skip(3); int direction, speed; if (!line.ReadChecked(direction) || !line.ReadChecked(speed)) return false; char okay = line.ReadFirstChar(); if (okay == 'V') { okay = line.ReadFirstChar(); if (okay == 'V') return true; if (okay != 'A') { line.Skip(); okay = line.ReadFirstChar(); } } if (okay == 'A') { SpeedVector wind(Angle::Degrees(direction), Units::ToSysUnit(fixed(speed), Unit::KILOMETER_PER_HOUR)); info.ProvideExternalWind(wind); } return true; }
static bool ReadFixedAndChar(NMEAInputLine &line, fixed &d, char &ch) { bool success = line.ReadChecked(d); ch = line.ReadFirstChar(); return success; }
static bool ReadAltitude(NMEAInputLine &line, fixed &value_r) { fixed value; bool available = line.ReadChecked(value); char unit = line.ReadFirstChar(); if (!available) return false; if (unit == _T('f') || unit == _T('F')) value = Units::ToSysUnit(value, Unit::FEET); value_r = value; return true; }
bool NMEAParser::GLL(NMEAInputLine &line, NMEAInfo &info) { /* * $--GLL,llll.ll,a,yyyyy.yy,a,hhmmss.ss,a,m,*hh * * Field Number: * 1) Latitude * 2) N or S (North or South) * 3) Longitude * 4) E or W (East or West) * 5) Universal Time Coordinated (UTC) * 6) Status A - Data Valid, V - Data Invalid * 7) FAA mode indicator (NMEA 2.3 and later) * 8) Checksum */ GeoPoint location; bool valid_location = ReadGeoPoint(line, location); fixed this_time; if (!ReadTime(line, info.date_time_utc, this_time)) return true; bool gps_valid = !NAVWarn(line.ReadFirstChar()); if (!TimeHasAdvanced(this_time, info)) return true; if (!gps_valid) info.location_available.Clear(); else if (valid_location) info.location_available.Update(info.clock); if (valid_location) info.location = location; info.gps.real = real; #if defined(ANDROID) || defined(__APPLE__) info.gps.nonexpiring_internal_gps = false; #endif return true; }
bool NMEAParser::RMC(NMEAInputLine &line, NMEAInfo &info) { /* * $--RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxx,x.x,a,m,*hh * * Field Number: * 1) UTC Time * 2) Status, V=Navigation receiver warning A=Valid * 3) Latitude * 4) N or S * 5) Longitude * 6) E or W * 7) Speed over ground, knots * 8) Track made good, degrees true * 9) Date, ddmmyy * 10) Magnetic Variation, degrees * 11) E or W * 12) FAA mode indicator (NMEA 2.3 and later) * 13) Checksum */ fixed this_time; if (!ReadTime(line, info.date_time_utc, this_time)) return true; bool gps_valid = !NAVWarn(line.ReadFirstChar()); GeoPoint location; bool valid_location = ReadGeoPoint(line, location); fixed speed; bool ground_speed_available = line.ReadChecked(speed); Angle track; bool track_available = ReadBearing(line, track); // JMW get date info first so TimeModify is accurate ReadDate(line, info.date_time_utc); Angle variation; bool variation_available = ReadVariation(line, variation); if (!TimeHasAdvanced(this_time, info)) return true; if (!gps_valid) info.location_available.Clear(); else if (valid_location) info.location_available.Update(info.clock); if (valid_location) info.location = location; if (ground_speed_available) { info.ground_speed = Units::ToSysUnit(speed, Unit::KNOTS); info.ground_speed_available.Update(info.clock); } if (track_available && info.MovementDetected()) { // JMW don't update bearing unless we're moving info.track = track; info.track_available.Update(info.clock); } if (!variation_available) info.variation_available.Clear(); else if (variation_available) { info.variation = variation; info.variation_available.Update(info.clock); } info.gps.real = real; #if defined(ANDROID) || defined(__APPLE__) info.gps.nonexpiring_internal_gps = false; #endif return true; }