Example #1
0
// $PDVDS,nx,nz,flap,stallratio,netto
static bool
PDVDS(NMEAInputLine &line, NMEAInfo &info)
{
  fixed AccelX = line.read(fixed_zero);
  fixed AccelZ = line.read(fixed_zero);

  int mag = (int)hypot(AccelX, AccelZ);
  info.acceleration.ProvideGLoad(fixed(mag) / 100, true);

  /*
  double flap = line.read(0.0);
  */
  line.skip();

  info.stall_ratio = line.read(fixed_zero);
  info.stall_ratio_available.Update(info.clock);

  fixed value;
  if (line.read_checked(value))
    info.ProvideNettoVario(value / 10);

  //hasVega = true;

  return true;
}
Example #2
0
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.read_checked(direction) || !line.read_checked(speed))
    return false;

  char okay = line.read_first_char();
  if (okay == 'V') {
    okay = line.read_first_char();
    if (okay == 'V')
      return true;

    if (okay != 'A') {
      line.skip();
      okay = line.read_first_char();
    }
  }

  if (okay == 'A') {
    SpeedVector wind(Angle::Degrees(fixed(direction)),
                     Units::ToSysUnit(fixed(speed), unKiloMeterPerHour));
    info.ProvideExternalWind(wind);
  }

  return true;
}
Example #3
0
void
CirclingComputer::TurnRate(CirclingInfo &circling_info,
                           const NMEAInfo &basic, const NMEAInfo &last_basic,
                           const DerivedInfo &calculated,
                           const DerivedInfo &last_calculated)
{
    if (!basic.time_available || !last_basic.time_available ||
            !calculated.flight.flying) {
        circling_info.turn_rate = fixed_zero;
        circling_info.turn_rate_heading = fixed_zero;
        return;
    }

    if (!basic.HasTimeAdvancedSince(last_basic))
        return;

    // Calculate time passed since last calculation
    const fixed dt = basic.time - last_basic.time;
    assert(positive(dt));

    circling_info.turn_rate =
        (basic.track - last_basic.track).AsDelta().Degrees() / dt;
    circling_info.turn_rate_heading =
        (calculated.heading - last_calculated.heading).AsDelta().Degrees() / dt;
}
Example #4
0
bool
EWMicroRecorderDevice::ParseNMEA(const char *String, NMEAInfo &info)
{
    if (!VerifyNMEAChecksum(String))
        return false;

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

    if (StringIsEqual(type, "$PGRMZ")) {
        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;
}
bool
GlideComputerAirData::FlightTimes(const NMEAInfo &basic,
                                  const NMEAInfo &last_basic,
                                  DerivedInfo &calculated,
                                  const ComputerSettings &settings)
{
  if (basic.gps.replay != last_basic.gps.replay)
    // reset flight before/after replay logger
    ResetFlight(calculated, settings, basic.gps.replay);

  if (basic.time_available && basic.HasTimeRetreatedSince(last_basic)) {
    // 20060519:sgi added (basic.Time != 0) due to always return here
    // if no GPS time available
    if (basic.location_available)
      // Reset statistics.. (probably due to being in IGC replay mode)
      ResetFlight(calculated, settings, false);

    return false;
  }

  FlightState(basic, last_basic, calculated, calculated.flight,
              settings.polar.glide_polar_task);

  return true;
}
Example #6
0
void
FlyingComputer::Compute(fixed takeoff_speed,
                        const NMEAInfo &basic, const NMEAInfo &last_basic,
                        const DerivedInfo &calculated,
                        FlyingState &flying)
{
  if (basic.HasTimeRetreatedSince(last_basic)) {
    Reset();
    flying.Reset();
  }

  // GPS not lost
  if (!basic.location_available)
    return;

  // Speed too high for being on the ground
  const fixed speed = basic.airspeed_available
    ? std::max(basic.true_airspeed, basic.ground_speed)
    : basic.ground_speed;

  if (speed > takeoff_speed ||
      (calculated.altitude_agl_valid && calculated.altitude_agl > fixed(300)))
    Moving(flying, basic.time, basic.location);
  else
    Stationary(flying, basic.time, basic.location);
}
Example #7
0
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;
}
Example #8
0
static bool
ParsePITV3(NMEAInputLine &line, NMEAInfo &info)
{
  fixed value;

  // bank angle [degrees, positive right]
  if (line.ReadChecked(value)) {
    info.attitude.bank_angle_available.Update(info.clock);
    info.attitude.bank_angle = Angle::Degrees(value);
  }

  // pitch angle [degrees, positive up]
  if (line.ReadChecked(value)) {
    info.attitude.pitch_angle_available.Update(info.clock);
    info.attitude.pitch_angle = Angle::Degrees(value);
  }

  // heading [degrees]
  if (line.ReadChecked(value)) {
    info.attitude.heading_available.Update(info.clock);
    info.attitude.heading = Angle::Degrees(value);
  }

  // IAS [m/s]
  if (line.ReadChecked(value)) {
    info.ProvideIndicatedAirspeed(value);
  }

  // Load factor [g]
  if (line.ReadChecked(value)) {
    info.acceleration.ProvideGLoad(value, true);
  }

  return true;
}
Example #9
0
// RMN: Volkslogger
// Source data:
// $PGCS,1,0EC0,FFF9,0C6E,02*61
// $PGCS,1,0EC0,FFFA,0C6E,03*18
static bool
vl_PGCS1(NMEAInputLine &line, NMEAInfo &info)
{
  if (line.Read(1) != 1)
    return false;

  /* pressure sensor */
  line.Skip();

  // four characers, hex, barometric altitude
  unsigned u_altitude;
  if (line.ReadHexChecked(u_altitude)) {
    int altitude(u_altitude);
    if (altitude > 60000)
      /* Assuming that altitude has wrapped around.  60 000 m occurs
         at QNH ~2000 hPa */
      altitude -= 65535;

    info.ProvidePressureAltitude(fixed(altitude));
  }

  // ExtractParameter(String,ctemp,3);
  // four characters, hex, constant.  Value 1371 (dec)

  // nSatellites = (int)(min(12,HexStrToDouble(ctemp, NULL)));

  return false;
}
Example #10
0
static bool
LXWP0(NMEAInputLine &line, NMEAInfo &info)
{
  /*
  $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1

   0 loger_stored (Y/N)
   1 IAS (kph) ----> Condor uses TAS!
   2 baroaltitude (m)
   3-8 vario (m/s) (last 6 measurements in last second)
   9 heading of plane
  10 windcourse (deg)
  11 windspeed (kph)
  */

  line.Skip();

  fixed airspeed;
  bool tas_available = line.ReadChecked(airspeed);
  if (tas_available && (airspeed < fixed(-50) || airspeed > fixed(250)))
    /* implausible */
    return false;

  fixed value;
  if (line.ReadChecked(value))
    /* a dump on a LX7007 has confirmed that the LX sends uncorrected
       altitude above 1013.25hPa here */
    info.ProvidePressureAltitude(value);

  if (tas_available)
    /*
     * Call ProvideTrueAirspeed() after ProvidePressureAltitude() to use
     * the provided altitude (if available)
     */
    info.ProvideTrueAirspeed(Units::ToSysUnit(airspeed, Unit::KILOMETER_PER_HOUR));

  if (line.ReadChecked(value))
    info.ProvideTotalEnergyVario(value);

  line.Skip(6);

  SpeedVector wind;
  if (ReadSpeedVector(line, wind))
    info.ProvideExternalWind(wind);

  return true;
}
Example #11
0
/**
 * Parse a "$D" sentence.
 *
 * Example: "$D,+0,100554,+25,18,+31,,0,-356,+25,+11,115,96*6A"
 */
static bool
LeonardoParseD(NMEAInputLine &line, NMEAInfo &info)
{
  double value;

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

  if (line.Rest().empty())
    /* short "$D" sentence ends after vario */
    return true;

  // 1 = air pressure [Pa]
  if (line.ReadChecked(value))
    info.ProvideStaticPressure(AtmosphericPressure::Pascal(value));

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

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

  // 4 = temperature [deg C]
  double oat;
  info.temperature_available = line.ReadChecked(oat);
  if (info.temperature_available)
    info.temperature = CelsiusToKelvin(oat);

  // 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;
}
Example #12
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 #13
0
bool
NMEAParser::PTAS1(NMEAInputLine &line, NMEAInfo &info)
{
    /*
     * $PTAS1,xxx,yyy,zzzzz,aaa*CS<CR><LF>
     *
     * xxx
     * CV or current vario. =vario*10+200 range 0-400(display +/-20.0 knots)
     *
     * yyy
     * AV or average vario. =vario*10+200 range 0-400(display +/-20.0 knots)
     *
     * zzzzz
     * Barometric altitude in feet +2000
     *
     * aaa
     * TAS knots 0-200
     */

    // Parse current vario data
    fixed vario;
    if (line.ReadChecked(vario)) {
        // Properly convert to m/s
        vario = Units::ToSysUnit((vario - fixed(200)) / 10, Unit::KNOTS);
        info.ProvideTotalEnergyVario(vario);
    }

    // Skip average vario data
    line.Skip();

    // Parse barometric altitude
    fixed baro_altitude;
    if (line.ReadChecked(baro_altitude)) {
        // Properly convert to meter
        baro_altitude = Units::ToSysUnit(baro_altitude - fixed(2000), Unit::FEET);
        info.ProvidePressureAltitude(baro_altitude);
    }

    // Parse true airspeed
    fixed vtas;
    if (line.ReadChecked(vtas))
        info.ProvideTrueAirspeed(Units::ToSysUnit(vtas, Unit::KNOTS));

    return true;
}
Example #14
0
/**
 * Attempt to compute airspeed when it is not yet available from:
 * 1) dynamic pressure and air density derived from some altitude.
 * 2) pitot pressure and static pressure.
 * 3) ground speed and wind.
 */
static void
ComputeAirspeed(NMEAInfo &basic, const DerivedInfo &calculated)
{
  if (basic.airspeed_available && basic.airspeed_real)
    /* got it already */
    return;

  const auto any_altitude = basic.GetAnyAltitude();

  if (!basic.airspeed_available && any_altitude.first) {
    fixed dyn; bool available = false;
    if (basic.dyn_pressure_available) {
      dyn = basic.dyn_pressure.GetHectoPascal();
      available = true;
    } else if (basic.pitot_pressure_available && basic.static_pressure_available) {
      dyn = basic.pitot_pressure.GetHectoPascal() - basic.static_pressure.GetHectoPascal();
      available = true;
    }
    if (available) {
      basic.indicated_airspeed = sqrt(fixed(163.2653061) * dyn);
      basic.true_airspeed = basic.indicated_airspeed *
                            AirDensityRatio(any_altitude.second);

      basic.airspeed_available.Update(basic.clock);
      basic.airspeed_real = true; // Anyway not less real then any other method.
      return;
    }
  }

  if (!basic.ground_speed_available || !calculated.wind_available ||
      !calculated.flight.flying) {
    /* impossible to calculate */
    basic.airspeed_available.Clear();
    return;
  }

  fixed TrueAirspeedEstimated = fixed(0);

  const SpeedVector wind = calculated.wind;
  if (positive(basic.ground_speed) || wind.IsNonZero()) {
    fixed x0 = basic.track.fastsine() * basic.ground_speed;
    fixed y0 = basic.track.fastcosine() * basic.ground_speed;
    x0 += wind.bearing.fastsine() * wind.norm;
    y0 += wind.bearing.fastcosine() * wind.norm;

    TrueAirspeedEstimated = SmallHypot(x0, y0);
  }

  basic.true_airspeed = TrueAirspeedEstimated;

  basic.indicated_airspeed = TrueAirspeedEstimated;
  if (any_altitude.first)
    basic.indicated_airspeed /= AirDensityRatio(any_altitude.second);

  basic.airspeed_available.Update(basic.clock);
  basic.airspeed_real = false;
}
Example #15
0
/**
 * $PWES0,DD,VVVV,MMMM,NNNN,BBBB,SSSS,AAAAA,QQQQQ,IIII,TTTT,UUU,CCC*CS<CR><LF>
 */
static bool
PWES0(NMEAInputLine &line, NMEAInfo &info)
{
    int i, k;

    line.skip(); /* device */

    if (line.read_checked(i))
        info.ProvideTotalEnergyVario(fixed(i) / 10);

    line.skip(); /* average vario */

    if (line.read_checked(i))
        info.ProvideNettoVario(fixed(i) / 10);

    line.skip(); /* average netto vario */
    line.skip(); /* speed to fly */

    if (line.read_checked(i))
        info.ProvidePressureAltitude(fixed(i));

    if (line.read_checked(i))
        info.ProvideBaroAltitudeTrue(fixed(i));

    bool have_ias = line.read_checked(i);
    bool have_tas = line.read_checked(k);
    if (have_ias && have_tas)
        info.ProvideBothAirspeeds(Units::ToSysUnit(fixed(i) / 10,
                                  unKiloMeterPerHour),
                                  Units::ToSysUnit(fixed(k) / 10,
                                          unKiloMeterPerHour));

    if (line.read_checked(i)) {
        info.voltage = fixed(i) / 10;
        info.voltage_available.Update(info.clock);
    }

    if (line.read_checked(i)) {
        info.temperature = Units::ToSysUnit(fixed(i) / 10, unGradCelcius);
        info.temperature_available = true;
    }

    return true;
}
Example #16
0
static bool
cLXWP0(NMEAInputLine &line, NMEAInfo &info)
{
  /*
  $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1

   0 logger_stored (Y/N)
   1 IAS (kph) ----> Condor uses TAS!
   2 baroaltitude (m)
   3 vario (m/s)
   4-8 unknown
   9 heading of plane
  10 windcourse (deg)
  11 windspeed (kph)
  */

  fixed value;

  line.Skip();

  fixed airspeed;
  bool tas_available = line.ReadChecked(airspeed);

  fixed alt = line.Read(fixed_zero);

  if (tas_available)
    info.ProvideTrueAirspeedWithAltitude(Units::ToSysUnit(airspeed,
                                                               Unit::KILOMETER_PER_HOUR),
                                              alt);

  // ToDo check if QNH correction is needed!
  info.ProvideBaroAltitudeTrue(alt);

  if (line.ReadChecked(value))
    info.ProvideTotalEnergyVario(value);

  line.Skip(6);

  SpeedVector wind;
  if (ReadSpeedVector(line, wind))
    info.ProvideExternalWind(wind);

  return true;
}
Example #17
0
bool
BlueFlyDevice::ParsePRS(const char *content, NMEAInfo &info)
{
  // e.g. PRS 17CBA

  char *endptr;
  long value = strtol(content, &endptr, 16);
  if (endptr != content) {
    AtmosphericPressure pressure = AtmosphericPressure::Pascal(fixed(value));

    kalman_filter.Update(pressure.GetHectoPascal(), fixed(0.25), fixed(0.02));

    info.ProvideNoncompVario(ComputeNoncompVario(kalman_filter.GetXAbs(),
                                                 kalman_filter.GetXVel()));
    info.ProvideStaticPressure(AtmosphericPressure::HectoPascal(kalman_filter.GetXAbs()));
  }

  return true;
}
Example #18
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, NMEAInfo &info)
{
  double value;

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

  // 1 = vario [cm/s]
  if (line.ReadChecked(value))
    info.ProvideTotalEnergyVario(value / 100);

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

  if (line.Rest().empty())
    /* short "$C" sentence ends after airspeed */
    return true;

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

  // 4 = temperature [deg C]
  double oat;
  info.temperature_available = line.ReadChecked(oat);
  if (info.temperature_available)
    info.temperature = CelsiusToKelvin(oat);

  line.Skip(5);

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

  return true;
}
Example #19
0
static bool
PDVDV(NMEAInputLine &line, NMEAInfo &info)
{
  fixed value;

  if (line.read_checked(value))
    info.ProvideTotalEnergyVario(value / 10);

  bool ias_available = line.read_checked(value);
  fixed tas_ratio = line.read(fixed(1024)) / 1024;
  if (ias_available)
    info.ProvideBothAirspeeds(value / 10, value / 10 * tas_ratio);

  //hasVega = true;

  if (line.read_checked(value))
    info.ProvidePressureAltitude(value);

  return true;
}
Example #20
0
static bool
ParsePITV4(NMEAInputLine &line, NMEAInfo &info)
{
  fixed value;

  // TE vario [m/s]
  if (line.ReadChecked(value))
    info.ProvideTotalEnergyVario(value);

  return true;
}
Example #21
0
static bool
GPWIN(NMEAInputLine &line, NMEAInfo &info)
{
  line.skip(2);

  fixed value;
  if (line.read_checked(value))
    info.ProvidePressureAltitude(value / 10);

  return false;
}
Example #22
0
/**
 * Parses a PGRMZ sentence (Garmin proprietary).
 *
 * @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::RMZ(NMEAInputLine &line, NMEAInfo &info)
{
  //JMW?  RMZAltitude = info.pressure.PressureAltitudeToQNHAltitude(RMZAltitude);

  fixed value;
  if (ReadAltitude(line, value)) {
    // JMW no in-built baro sources, so use this generic one
    if (info.flarm.IsDetected())
      /* FLARM emulates the Garmin $PGRMZ sentence, but emits the
         altitude above 1013.25 hPa - since the don't have a "FLARM"
         device driver, we use the auto-detected "isFlarm" flag
         here */
      info.ProvideWeakPressureAltitude(value);
    else
      info.ProvideBaroAltitudeTrue(value);
  }

  return true;
}
Example #23
0
/**
 * Parse a "$PDGFTL1" sentence.
 *
 * Example: "$PDGFTL1,2025,2000,250,-14,45,134,28,65,382,153*3D"
 */
static bool
PDGFTL1(NMEAInputLine &line, NMEAInfo &info)
{
  fixed value;

  //  Baro Altitude QNE(1013.25)     2025     meter        2025 mt
  if (line.ReadChecked(value))
    info.ProvidePressureAltitude(value);

  //  Baro Altitude QNH  2000     meter        2000 mt
  if (line.ReadChecked(value))
    info.ProvideBaroAltitudeTrue(value);

  //  Vario  250      cm/sec       +2,50 m/s
  if (line.ReadChecked(value))
    info.ProvideTotalEnergyVario(value / 100);

  //  Netto Vario  -14      dm/sec       -1,40 m/s
  if (line.ReadChecked(value))
    info.ProvideNettoVario(value / 10);

  //  Indicated Air Speed  45       km/h         45 km/h
  //  Ground Efficiency  134      ratio        13,4 : 1
  line.Skip(2);

  //  Wind Speed  28       km/h         28 km/h
  //  Wind Direction  65       degree       65 degree
  SpeedVector wind;
  if (ReadSpeedVector(line, wind))
    info.ProvideExternalWind(wind);

  //  Main Lithium Battery Voltage   382      0.01 volts   3,82 volts
  if (line.ReadChecked(value)) {
    info.voltage = value / 100;
    info.voltage_available.Update(info.clock);
  }

  //  Backup AA Battery Voltage      153      0.01 volts   1,53 volts

  return true;
}
Example #24
0
static bool
PZAN1(NMEAInputLine &line, NMEAInfo &info)
{
  fixed baro_altitude;
  if (line.ReadChecked(baro_altitude))
    /* the ZS1 documentation does not specify wheter the altitude is
       STD or QNH, but Franz Poeschl confirmed via email that it is
       the QNH altitude */
    info.ProvideBaroAltitudeTrue(baro_altitude);

  return true;
}
Example #25
0
bool
DemoReplayGlue::Update(NMEAInfo &data, fixed time_scale)
{
  if (!UpdateTime())
    return true;

  fixed floor_alt = fixed_300;
  if (device_blackboard->Calculated().terrain_valid) {
    floor_alt += device_blackboard->Calculated().terrain_altitude;
  }

  bool retval;

  {
    ProtectedTaskManager::ExclusiveLease protected_task_manager(*task_manager);
    TaskAccessor ta(protected_task_manager, floor_alt);
    retval = DemoReplay::Update(time_scale, ta);
  }

  const AircraftState &s = aircraft.GetState();

  data.clock = s.time;
  data.alive.Update(data.clock);
  data.ProvideTime(s.time);
  data.location = s.location;
  data.location_available.Update(data.clock);
  data.ground_speed = s.ground_speed;
  data.ground_speed_available.Update(data.clock);
  data.track = s.track;
  data.track_available.Update(data.clock);
  data.gps_altitude = s.altitude;
  data.gps_altitude_available.Update(data.clock);
  data.ProvidePressureAltitude(s.altitude);
  data.ProvideBaroAltitudeTrue(s.altitude);
  data.gps.real = false;
  data.gps.replay = true;
  data.gps.simulator = false;

  return retval;
}
Example #26
0
/**
 * Parse the $PLXVF sentence (LXNav V7).
 *
 * $PLXVF,time ,AccX,AccY,AccZ,Vario,IAS,PressAlt*CS<CR><LF>
 *
 * Example: $PLXVF,1.00,0.87,-0.12,-0.25,90.2,244.3,*CS<CR><LF>
 *
 * @see http://www.xcsoar.org/trac/raw-attachment/ticket/1666/V7%20dataport%20specification%201.97.pdf
 */
static bool
PLXVF(NMEAInputLine &line, NMEAInfo &info)
{
  line.Skip(4);

  fixed vario;
  if (line.ReadChecked(vario))
    info.ProvideNettoVario(vario);

  fixed ias;
  bool have_ias = line.ReadChecked(ias);

  fixed altitude;
  if (line.ReadChecked(altitude)) {
    info.ProvidePressureAltitude(altitude);

    if (have_ias)
      info.ProvideIndicatedAirspeedWithAltitude(ias, altitude);
  }

  return true;
}
Example #27
0
static bool
LK8EX1(NMEAInputLine &line, NMEAInfo &info)
{
  unsigned pressure;
  bool pressure_available = (line.ReadChecked(pressure) && pressure != 999999);

  if (pressure_available)
    info.ProvideStaticPressure(AtmosphericPressure::Pascal(fixed(pressure)));

  unsigned altitude;
  bool altitude_available = (line.ReadChecked(altitude) && altitude != 99999);

  if (altitude_available && !pressure_available)
    info.ProvidePressureAltitude(fixed(altitude));

  int vario;
  if (line.ReadChecked(vario) && vario != 9999)
    info.ProvideNoncompVario(fixed(vario) / 100);

  int temperature;
  if (line.ReadChecked(temperature) && temperature != 99) {
    info.temperature = fixed(temperature);
    info.temperature_available = true;
  }

  fixed battery_value;
  if (line.ReadChecked(battery_value) &&
      (unsigned)(battery_value + fixed(0.5)) != 999) {
    if (battery_value > fixed(1000)) {
      info.battery_level = battery_value - fixed(1000);
      info.battery_level_available.Update(info.clock);
    } else {
      info.voltage = battery_value;
      info.voltage_available.Update(info.clock);
    }
  }

  return true;
}
Example #28
0
/**
 * Parses a PTAS1 sentence (Tasman Instruments proprietary).
 *
 * @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::PTAS1(NMEAInputLine &line, NMEAInfo &info)
{
  fixed wnet;
  if (line.read_checked(wnet))
    info.ProvideTotalEnergyVario(Units::ToSysUnit((wnet - fixed(200)) / 10,
                                                       unKnots));

  line.skip(); // average vario +200

  fixed baralt;
  if (line.read_checked(baralt)) {
    baralt = max(fixed_zero, Units::ToSysUnit(baralt - fixed(2000), unFeet));
    info.ProvidePressureAltitude(baralt);
  }

  fixed vtas;
  if (line.read_checked(vtas))
    info.ProvideTrueAirspeed(Units::ToSysUnit(vtas, unKnots));

  return true;
}
Example #29
0
/*
!w,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>*hh<CR><LF>
<1>  Vector wind direction in degrees
<2>  Vector wind speed in 10ths of meters per second
<3>  Vector wind age in seconds
<4>  Component wind in 10ths of Meters per second + 500 (500 = 0, 495 = 0.5 m/s tailwind)
<5>  True altitude in Meters + 1000
<6>  Instrument QNH setting
<7>  True airspeed in 100ths of Meters per second
<8>  Variometer reading in 10ths of knots + 200
<9>  Averager reading in 10ths of knots + 200
<10> Relative variometer reading in 10ths of knots + 200
<11> Instrument MacCready setting in 10ths of knots
<12> Instrument Ballast setting in percent of capacity
<13> Instrument Bug setting
*hh  Checksum, XOR of all bytes
*/
static bool
cai_w(NMEAInputLine &line, NMEAInfo &info)
{
  SpeedVector wind;
  if (ReadSpeedVector(line, wind))
    info.ProvideExternalWind(wind.Reciprocal());

  line.skip(2);

  fixed value;
  if (line.read_checked(value))
    info.ProvideBaroAltitudeTrue(value - fixed(1000));

  if (line.read_checked(value))
    info.settings.ProvideQNH(value, info.clock);

  if (line.read_checked(value))
    info.ProvideTrueAirspeed(value / 100);

  if (line.read_checked(value))
    info.ProvideTotalEnergyVario(Units::ToSysUnit((value - fixed(200)) / 10,
                                                  unKnots));

  line.skip(2);

  int i;

  if (line.read_checked(i))
    info.settings.ProvideMacCready(Units::ToSysUnit(fixed(i) / 10, unKnots),
                                   info.clock);

  if (line.read_checked(i))
    info.settings.ProvideBallastFraction(fixed(i) / 100, info.clock);

  if (line.read_checked(i))
    info.settings.ProvideBugs(fixed(i) / 100, info.clock);

  return true;
}
Example #30
0
static bool
PDVDV(NMEAInputLine &line, NMEAInfo &info)
{
  int value;

  if (line.ReadChecked(value))
    info.ProvideTotalEnergyVario(fixed(value) / 10);

  bool ias_available = line.ReadChecked(value);
  int tas_ratio = line.Read(1024);
  if (ias_available) {
    const fixed ias = fixed(value) / 10;
    info.ProvideBothAirspeeds(ias, ias * tas_ratio / 1024);
  }

  //hasVega = true;

  if (line.ReadChecked(value))
    info.ProvidePressureAltitude(fixed(value));

  return true;
}