Пример #1
0
/**
 * Parse a "$VMVABD" sentence.
 *
 * Example: "$VMVABD,0000.0,M,0547.0,M,-0.0,,,MS,0.0,KH,22.4,C*65"
 */
static bool
FlytecParseVMVABD(NMEAInputLine &line, NMEA_INFO &info)
{
  fixed value;

  // 0,1 = GPS altitude, unit
  if (line.read_checked_compare(info.GPSAltitude, "M"))
    info.GPSAltitudeAvailable.Update(info.clock);

  // 2,3 = baro altitude, unit
  if (line.read_checked_compare(value, "M"))
    info.ProvideBaroAltitudeTrue(value);

  // 4-7 = integrated vario, unit
  line.skip(4);

  // 8,9 = indicated or true airspeed, unit
  if (line.read_checked_compare(value, "KH"))
    // XXX is that TAS or IAS?  Documentation isn't clear.
    info.ProvideBothAirspeeds(Units::ToSysUnit(value, unKiloMeterPerHour));

  // 10,11 = temperature, unit
  info.TemperatureAvailable =
    line.read_checked_compare(value, "C");
  if (info.TemperatureAvailable)
    info.OutsideAirTemperature = Units::ToSysUnit(value, unGradCelcius);

  return true;
}
Пример #2
0
/**
 * Update the measurements if new level reached
 * @param basic NMEA_INFO for temperature and humidity
 */
void
CuSonde::updateMeasurements(const NMEA_INFO &basic)
{
  // if (not flying) nothing to update...
  if (!basic.flight.Flying)
    return;

  // if (no temperature or humidity available) nothing to update...
  if (!basic.TemperatureAvailable || !basic.HumidityAvailable)
    return;

  // find appropriate level
  unsigned short level = (unsigned short)((int)max(basic.GetAltitudeBaroPreferred(),
                                                   fixed(0.0))
                                          / CUSONDE_HEIGHTSTEP);

  // if (level out of range) cancel update
  if (level >= CUSONDE_NUMLEVELS)
    return;

  // if (level skipped) cancel update
  if (abs(level - last_level) > 1) {
    last_level = level;
    return;
  }

  // if (no level transition yet) wait for transition
  if (abs(level - last_level) == 0)
    return;

  // calculate ground height
  hGround = basic.AltitudeAGL;

  // if (going up)
  if (level > last_level) {
    // we round down (level) because of potential lag of temp sensor
    cslevels[level].updateTemps(basic.RelativeHumidity,
        Units::ToUserUnit(basic.OutsideAirTemperature, unGradCelcius));
    cslevels[level].updateThermalIndex(level);

    if (level > 0) {
      findThermalHeight((unsigned short)(level - 1));
      findCloudBase((unsigned short)(level - 1));
    }

  // if (going down)
  } else {
    // we round up (level+1) because of potential lag of temp sensor
    cslevels[level + 1].updateTemps(basic.RelativeHumidity,
        Units::ToUserUnit(basic.OutsideAirTemperature, unGradCelcius));
    cslevels[level + 1].updateThermalIndex((unsigned short)(level + 1));

    if (level < CUSONDE_NUMLEVELS - 1) {
      findThermalHeight(level);
      findCloudBase(level);
    }
  }

  last_level = level;
}
bool
EWMicroRecorderDevice::ParseNMEA(const char *String, NMEA_INFO &info)
{
  if (!VerifyNMEAChecksum(String))
    return false;

  NMEAInputLine line(String);
  char type[16];
  line.read(type, 16);

  if (strcmp(type, "$PGRMZ") == 0) {
    fixed value;

    /* The normal Garmin $PGRMZ line contains the "true" barometric
       altitude above MSL (corrected with QNH), but EWMicroRecorder
       differs here slightly: it emits the uncorrected barometric
       altitude.  That is the only reason why we catch this sentence
       in the driver instead of letting the generic class NMEAParser
       do it. */
    if (ReadAltitude(line, value))
      info.ProvidePressureAltitude(value);

    return true;
  } else
    return false;
}
Пример #4
0
/**
 * Parse a "$D" sentence.
 *
 * Example: "$D,+0,100554,+25,18,+31,,0,-356,+25,+11,115,96*6A"
 */
static bool
LeonardoParseD(NMEAInputLine &line, NMEA_INFO &info)
{
    fixed value;

    // 0 = vario [dm/s]
    if (line.read_checked(value))
        info.ProvideTotalEnergyVario(value / 10);

    // 1 = air pressure [Pa]
    if (line.skip() == 0)
        /* short "$C" sentence ends after airspeed */
        return true;

    // 2 = netto vario [dm/s]
    if (line.read_checked(value))
        info.ProvideNettoVario(value / 10);

    // 3 = airspeed [km/h]
    /* XXX is that TAS or IAS? */
    if (line.read_checked(value))
        info.ProvideTrueAirspeed(Units::ToSysUnit(value, unKiloMeterPerHour));

    // 4 = temperature [deg C]
    fixed oat;
    info.TemperatureAvailable = line.read_checked(oat);
    if (info.TemperatureAvailable)
        info.OutsideAirTemperature = Units::ToSysUnit(oat, unGradCelcius);

    // 5 = compass [degrees]
    /* XXX unsupported by XCSoar */

    // 6 = optimal speed [km/h]
    /* XXX unsupported by XCSoar */

    // 7 = equivalent MacCready [cm/s]
    /* XXX unsupported by XCSoar */

    // 8 = wind speed [km/h]
    /* not used here, the "$C" record repeats it together with the
       direction */

    return true;
}
Пример #5
0
/**
 * Parse a "$C" sentence.
 *
 * Example: "$C,+2025,-7,+18,+25,+29,122,314,314,0,-356,+25,45,T*3D"
 */
static bool
LeonardoParseC(NMEAInputLine &line, NMEA_INFO &info)
{
    fixed value;

    // 0 = altitude [m]
    if (line.read_checked(value))
        info.ProvideBaroAltitudeTrue(value);

    // 1 = vario [dm/s]
    if (line.read_checked(value))
        info.ProvideTotalEnergyVario(value / 10);

    // 2 = airspeed [km/h]
    /* XXX is that TAS or IAS? */
    if (line.read_checked(value))
        info.ProvideTrueAirspeed(Units::ToSysUnit(value, unKiloMeterPerHour));

    // 3 = netto vario [dm/s]
    if (line.read_checked(value))
        info.ProvideNettoVario(value / 10);
    else
        /* short "$C" sentence ends after airspeed */
        return true;

    // 4 = temperature [deg C]
    fixed oat;
    info.TemperatureAvailable = line.read_checked(oat);
    if (info.TemperatureAvailable)
        info.OutsideAirTemperature = Units::ToSysUnit(oat, unGradCelcius);

    // 10 = wind speed [km/h]
    // 11 = wind direction [degrees]
    SpeedVector wind;
    if (ReadSpeedVector(line, wind))
        info.ProvideExternalWind(wind);

    return true;
}
Пример #6
0
/**
 * Parse a "$BRSF" sentence.
 *
 * Example: "$BRSF,063,-013,-0035,1,193,00351,535,485*38"
 */
static bool
FlytecParseBRSF(NMEAInputLine &line, NMEA_INFO &info)
{
  fixed value;

  // 0 = indicated or true airspeed [km/h]
  if (line.read_checked(value))
    // XXX is that TAS or IAS?  Documentation isn't clear.
    info.ProvideBothAirspeeds(Units::ToSysUnit(value, unKiloMeterPerHour));

  // 1 = integrated vario [dm/s]
  // 2 = altitude A2 [m] (XXX what's this?)
  // 3 = waypoint
  // 4 = bearing to waypoint [degrees]
  // 5 = distance to waypoint [100m]
  // 6 = MacCready speed to fly [100m/h]
  // 7 = speed to fly, best glide [100m/h]

  return true;
}
Пример #7
0
/**
 * Parse a "$FLYSEN" sentence.
 *
 * @see http://www.flytec.ch/public/Special%20NMEA%20sentence.pdf
 */
static bool
FlytecParseFLYSEN(NMEAInputLine &line, NMEA_INFO &info)
{
  fixed value;

  //  Time(hhmmss),   6 Digits
  line.skip();

  //  Latitude(ddmm.mmm),   8 Digits incl. decimal
  //  N (or S),   1 Digit
  line.skip(2);

  //  Longitude(dddmm.mmm),   9 Digits inc. decimal
  //  E (or W),   1 Digit
  line.skip(2);

  //  Track (xxx Deg),   3 Digits
  //  Speed over Ground (xxxxx cm/s)        5 Digits
  //  GPS altitude (xxxxx meter),           5 Digits
  line.skip(3);

  //  Validity of 3 D fix A or V,           1 Digit
  char validity = line.read_first_char();
  if (validity != 'A' && validity != 'V') {
    validity = line.read_first_char();
    if (validity != 'A' && validity != 'V')
      return false;
  }

  //  Satellites in Use (0 to 12),          2 Digits
  line.skip();

  //  Raw pressure (xxxxxx Pa),  6 Digits
  if (line.read_checked(value))
    info.ProvideStaticPressure(value / 100);

  //  Baro Altitude (xxxxx meter),          5 Digits (-xxxx to xxxxx) (Based on 1013.25hPa)
  if (line.read_checked(value))
    info.ProvidePressureAltitude(value);

  //  Variometer (xxxx cm/s),   4 or 5 Digits (-9999 to 9999)
  if (line.read_checked(value))
    info.ProvideTotalEnergyVario(value / 100);

  //  true airspeed (xxxxx cm/s),           5 Digits (0 to 99999cm/s = 3600km/h)
  if (line.read_checked(value))
    info.ProvideTrueAirspeed(value / 100);

  //  Airspeed source P or V,   1 Digit P= pitot, V = Vane wheel
  //  Temp. PCB (xxx °C),   3 Digits
  //  Temp. Balloon Envelope (xxx °C),      3 Digits
  //  Battery Capacity Bank 1 (0 to 100%)   3 Digits
  //  Battery Capacity Bank 2 (0 to 100%)   3 Digits
  //  Dist. to WP (xxxxxx m),   6 Digits (Max 200000m)
  //  Bearing (xxx Deg),   3 Digits
  //  Speed to fly1 (MC0 xxxxx cm/s),       5 Digits
  //  Speed to fly2 (McC. xxxxx cm/s)       5 Digits
  //  Keypress Code (Experimental empty to 99)     2 Digits

  return true;
}