Example #1
0
/**
 * Parses a RMC sentence
 *
 * $--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
 * @param String Input string
 * @param params Parameter array
 * @param nparams Number of parameters
 * @param info NMEA_INFO struct to parse into
 * @return Parsing success
 */
bool
NMEAParser::RMC(NMEAInputLine &line, NMEAInfo &info)
{
  fixed ThisTime = line.read(fixed_zero);

  bool gpsValid = !NAVWarn(line.read_first_char());

  GeoPoint location;
  bool valid_location = ReadGeoPoint(line, location);

  GPSState &gps = info.gps;

  fixed speed;
  bool GroundSpeedAvailable = line.read_checked(speed);

  fixed track;
  bool track_available = line.read_checked(track);

  // JMW get date info first so TimeModify is accurate
  if (ReadDate(line, info.date_time_utc))
    info.date_available = true;

  ThisTime = TimeModify(ThisTime, info.date_time_utc, info.date_available);
  ThisTime = TimeAdvanceTolerance(ThisTime);

  if (!TimeHasAdvanced(ThisTime, info))
    return true;

  if (!gpsValid)
    info.location_available.Clear();
  else if (valid_location)
    info.location_available.Update(info.clock);

  if (valid_location)
    info.location = location;

  if (GroundSpeedAvailable) {
    info.ground_speed = Units::ToSysUnit(speed, unKnots);
    info.ground_speed_available.Update(info.clock);
  }

  if (track_available && info.MovementDetected()) {
    // JMW don't update bearing unless we're moving
    info.track = Angle::degrees(track).as_bearing();
    info.track_available.Update(info.clock);
  }

  if (!GGAAvailable) {
    // update SatInUse, some GPS receiver don't emit GGA sentence
    gps.satellites_used = -1;
  }

  info.gps.real = real;
#ifdef ANDROID
  info.gps.android_internal_gps = false;
#endif

  return true;
}
Example #2
0
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;
}