/**
 * 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;
}
Beispiel #2
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, bool enable_baro)
{
  fixed value;

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

  // 2,3 = baro altitude, unit
  bool available = line.read_checked_compare(value, "M");
  if (enable_baro) {
    if (available)
      info.BaroAltitude = value;
    info.BaroAltitudeAvailable = available;
  }

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

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

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

  return true;
}
Beispiel #3
0
static bool
ParseAPENV1(NMEAInputLine &line, NMEAInfo &info)
{
  // $APENV1,IAS,Altitude,0,0,0,VerticalSpeed,

  int ias;
  if (!line.ReadChecked(ias)) return false;

  int altitude;
  if (!line.ReadChecked(altitude)) return false;

  line.Skip();
  line.Skip();
  line.Skip();

  // In ft/min, quality of this is limited, do not use for the time being
  int vs;
  if (!line.ReadChecked(vs)) return false;

  auto sys_alt = Units::ToSysUnit(fixed(altitude), Unit::FEET);
  info.ProvidePressureAltitude(sys_alt);
  info.ProvideIndicatedAirspeedWithAltitude(Units::ToSysUnit(fixed(ias), Unit::KNOTS), sys_alt);

  return true;
}
Beispiel #4
0
static bool
LXWP2(NMEAInputLine &line, NMEA_INFO *GPS_INFO)
{
  /*
   * $LXWP2,
   * maccready value, (m/s)
   * ballast, (1.0 - 1.5)
   * bugs, (0 - 100%)
   * polar_a,
   * polar_b,
   * polar_c,
   * audio volume
   */

  fixed value;
  // MacCready value
  if (line.read_checked(value))
    GPS_INFO->settings.ProvideMacCready(value, GPS_INFO->Time);

  // Ballast
  line.skip();
  /*
  if (line.read_checked(value))
    GPS_INFO->ProvideBallast(value, GPS_INFO->Time);
  */

  // Bugs
  if (line.read_checked(value))
    GPS_INFO->settings.ProvideBugs((fixed(100) - value) / 100, GPS_INFO->Time);

  return true;
}
Beispiel #5
0
static bool
LXWP2(NMEAInputLine &line, NMEA_INFO *GPS_INFO)
{
  /*
   * $LXWP2,
   * maccready value, (m/s)
   * ballast, (1.0 - 1.5)
   * bugs, (0 - 100%)
   * polar_a,
   * polar_b,
   * polar_c,
   * audio volume
   */

  fixed value;
  // MacCready value
  if (line.read_checked(value))
    GPS_INFO->MacCready = value;

  // Ballast
  line.skip();
  /*
  if (line.read_checked(value))
    GPS_INFO->Ballast = value;
  */

  // Bugs
  if (line.read_checked(value))
    GPS_INFO->Bugs = fixed(100) - value;

  return true;
}
Beispiel #6
0
bool
NMEAParser::GSA(NMEAInputLine &line, NMEAInfo &info)
{
    /*
     * $--GSA,a,a,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x.x,x.x,x.x*hh
     *
     * Field Number:
     *  1) Selection mode
     *         M=Manual, forced to operate in 2D or 3D
     *         A=Automatic, 3D/2D
     *  2) Mode (1 = no fix, 2 = 2D fix, 3 = 3D fix)
     *  3) ID of 1st satellite used for fix
     *  4) ID of 2nd satellite used for fix
     *  ...
     *  14) ID of 12th satellite used for fix
     *  15) PDOP
     *  16) HDOP
     *  17) VDOP
     *  18) checksum
     */

    line.Skip();

    if (line.Read(0) == 1)
        info.location_available.Clear();

    // satellites are in items 4-15 of GSA string (4-15 is 1-indexed)
    for (unsigned i = 0; i < GPSState::MAXSATELLITES; i++)
        info.gps.satellite_ids[i] = line.Read(0);

    info.gps.satellite_ids_available.Update(info.clock);

    return true;
}
Beispiel #7
0
/**
 * Parse the $PLXVS sentence (LXNav V7).
 *
 * $PLXVS,OAT,mode,voltage *CS<CR><LF>
 *
 * Example: $PLXVS,23.1,0,12.3,*CS<CR><LF>
 *
 * @see http://www.xcsoar.org/trac/raw-attachment/ticket/1666/V7%20dataport%20specification%201.97.pdf
 */
static bool
PLXVS(NMEAInputLine &line, NMEAInfo &info)
{
  fixed temperature;
  if (line.ReadChecked(temperature)) {
    info.temperature = CelsiusToKelvin(temperature);
    info.temperature_available = true;
  }

  int mode;
  info.switch_state.flight_mode = SwitchState::FlightMode::UNKNOWN;
  if (line.ReadChecked(mode)) {
    if (mode == 0)
      info.switch_state.flight_mode = SwitchState::FlightMode::CIRCLING;
    else if (mode == 1)
      info.switch_state.flight_mode = SwitchState::FlightMode::CRUISE;
  }

  fixed voltage;
  if (line.ReadChecked(voltage)) {
    info.voltage = voltage;
    info.voltage_available.Update(info.clock);
  }

  return true;
}
Beispiel #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;
}
Beispiel #9
0
static bool
ReadFixedAndChar(NMEAInputLine &line, fixed &d, char &ch)
{
    bool success = line.ReadChecked(d);
    ch = line.ReadFirstChar();
    return success;
}
Beispiel #10
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;
}
Beispiel #11
0
static bool
PTFRS(NMEAInputLine &line, NMEAInfo &info)
{
    // $PTFRS,1,0,0,0,0,0,0,0,5,1,10,0,3,1338313437,0,0,0,,,2*4E
    //
    // $PTFRS,<sealed>,<downloadmode>,<event>,<neartp>,<sealing>,<baromode>,
    //        <decllock>,<newrecavail>,<enl>,<rpm>,<interval>,<error>,<timbase>,
    //        <time>,<secpower>,<secpowerint>,<usup>,<ulit>,
    //        <chargerstate>,<antstate>*CS<CR><LF>

    line.Skip(8);

    unsigned enl;
    if (line.ReadChecked(enl)) {
        info.engine_noise_level = enl;
        info.engine_noise_level_available.Update(info.clock);
    }

    line.Skip(7);

    unsigned supply_voltage;
    if (line.ReadChecked(supply_voltage) && supply_voltage != 0) {
        info.voltage = fixed(supply_voltage) / 1000;
        info.voltage_available.Update(info.clock);
    }

    return true;
}
Beispiel #12
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, NMEAInfo &info)
{
  fixed value;

  // 0,1 = GPS altitude, unit
  if (line.ReadCheckedCompare(info.gps_altitude, "M"))
    info.gps_altitude_available.Update(info.clock);

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

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

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

  // 10,11 = temperature, unit
  info.temperature_available =
    line.ReadCheckedCompare(value, "C");
  if (info.temperature_available)
    info.temperature = CelsiusToKelvin(value);

  return true;
}
Beispiel #13
0
static bool
LXWP2(NMEAInputLine &line, NMEAInfo &info)
{
  /*
   * $LXWP2,
   * maccready value, (m/s)
   * ballast, (1.0 - 1.5)
   * bugs, (0 - 100%)
   * polar_a,
   * polar_b,
   * polar_c,
   * audio volume
   */

  fixed value;
  // MacCready value
  if (line.ReadChecked(value))
    info.settings.ProvideMacCready(value, info.clock);

  // Ballast
  if (line.ReadChecked(value))
    info.settings.ProvideBallastOverload(value, info.clock);

  // Bugs
  if (line.ReadChecked(value))
    info.settings.ProvideBugs((fixed(100) - value) / 100, info.clock);

  return true;
}
Beispiel #14
0
/**
 * Parses a GLL sentence
 *
 * $--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
 * @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::GLL(NMEAInputLine &line, NMEAInfo &info)
{
  GeoPoint location;
  bool valid_location = ReadGeoPoint(line, location);

  fixed ThisTime = TimeModify(line.read(fixed_zero), info.date_time_utc,
                              info.date_available);
  ThisTime = TimeAdvanceTolerance(ThisTime);

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

  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;

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

  return true;
}
Beispiel #15
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;
}
Beispiel #16
0
/**
 * Parses a PFLAU sentence
 * (Operating status and priority intruder and obstacle data)
 * @param String Input string
 * @param params Parameter array
 * @param nparams Number of parameters
 * @param GPS_INFO GPS_INFO struct to parse into
 * @return Parsing success
 * @see http://flarm.com/support/manual/FLARM_DataportManual_v4.06E.pdf
 */
bool
NMEAParser::PFLAU(NMEAInputLine &line, FLARM_STATE &flarm)
{
  static int old_flarm_rx = 0;

  flarm.FLARM_Available = true;
  isFlarm = true;

  // PFLAU,<RX>,<TX>,<GPS>,<Power>,<AlarmLevel>,<RelativeBearing>,<AlarmType>,
  //   <RelativeVertical>,<RelativeDistance>(,<ID>)
  flarm.FLARM_RX = line.read(0);
  flarm.FLARM_TX = line.read(0);
  flarm.FLARM_GPS = line.read(0);
  line.skip();
  flarm.FLARM_AlarmLevel = line.read(0);

  // process flarm updates

  if (flarm.FLARM_RX && old_flarm_rx == 0)
    // traffic has appeared..
    InputEvents::processGlideComputer(GCE_FLARM_TRAFFIC);

  if (flarm.FLARM_RX == 0 && old_flarm_rx)
    // traffic has disappeared..
    InputEvents::processGlideComputer(GCE_FLARM_NOTRAFFIC);

  // TODO feature: add another event for new traffic.

  old_flarm_rx = flarm.FLARM_RX;

  return false;
}
Beispiel #17
0
bool
VegaDevice::PDVSC(NMEAInputLine &line, gcc_unused NMEAInfo &info)
{
  char responsetype[10];
  line.Read(responsetype, 10);

  char name[80];
  line.Read(name, 80);

  if (StringIsEqual(name, "ERROR"))
    // ignore error responses...
    return true;

  int value = line.Read(0);

  if (StringIsEqual(name, "ToneDeadbandCruiseLow"))
    value = std::max(value, -value);
  if (StringIsEqual(name, "ToneDeadbandCirclingLow"))
    value = std::max(value, -value);

  settings.Lock();
  settings.Set(name, value);
  settings.Unlock();

  return true;
}
Beispiel #18
0
/**
 * Parses a GLL sentence
 *
 * $--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
 * @param String Input string
 * @param params Parameter array
 * @param nparams Number of parameters
 * @param GPS_INFO GPS_INFO struct to parse into
 * @return Parsing success
 */
bool
NMEAParser::GLL(NMEAInputLine &line, NMEA_INFO *GPS_INFO)
{
  GeoPoint location;
  bool valid_location = ReadGeoPoint(line, location);

  fixed ThisTime = TimeModify(line.read(fixed_zero), GPS_INFO->DateTime);

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

  if (!activeGPS)
    return true;

  if (GPS_INFO->gps.Replay)
    // block actual GPS signal
    return true;

  GPS_INFO->gps.NAVWarning = !gpsValid;

  if (!TimeHasAdvanced(ThisTime, GPS_INFO))
    return false;

  if (valid_location)
    GPS_INFO->Location = location;
  else
    GPS_INFO->gps.NAVWarning = true;

  return true;
}
Beispiel #19
0
bool
VegaDevice::PDVSC(NMEAInputLine &line, gcc_unused NMEAInfo &info)
{
  char responsetype[10];
  line.read(responsetype, 10);

  char name[80];
  line.read(name, 80);

  if (strcmp(name, "ERROR") == 0)
    // ignore error responses...
    return true;

  int value = line.read(0);

  if (strcmp(name, "ToneDeadbandCruiseLow") == 0)
    value = std::max(value, -value);
  if (strcmp(name, "ToneDeadbandCirclingLow") == 0)
    value = std::max(value, -value);

  settings_mutex.Lock();
  settings[name] = value;
  settings_mutex.Unlock();

  return true;
}
Beispiel #20
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;
}
Beispiel #21
0
bool
OpenVarioDevice::POV(NMEAInputLine &line, NMEAInfo &info)
{
  /*
   * Type definitions:
   *
   * E: TE vario in m/s
   * P: static pressure in hPa
   * Q: dynamic pressure in Pa
   * R: total pressure in hPa
   * S: true airspeed in km/h
   * T: temperature in deg C
   */

  while (!line.IsEmpty()) {
    char type = line.ReadOneChar();
    if (type == '\0')
      break;

    fixed value;
    if (!line.ReadChecked(value))
      break;

    switch (type) {
      case 'E': {
        info.ProvideTotalEnergyVario(value);
        break;
      }
      case 'P': {
        AtmosphericPressure pressure = AtmosphericPressure::HectoPascal(value);
        info.ProvideStaticPressure(pressure);
        break;
      }
      case 'Q': {
        AtmosphericPressure pressure = AtmosphericPressure::Pascal(value);
        info.ProvideDynamicPressure(pressure);
        break;
      }
      case 'R': {
        AtmosphericPressure pressure = AtmosphericPressure::HectoPascal(value);
        info.ProvidePitotPressure(pressure);
        break;
      }
      case 'S': {
        value = Units::ToSysUnit(value, Unit::KILOMETER_PER_HOUR);
        info.ProvideTrueAirspeed(value);
        break;
      }
      case 'T': {
        info.temperature = CelsiusToKelvin(value);
        info.temperature_available = true;
        break;
      }
    }
  }

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

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

  return false;
}
Beispiel #23
0
static bool
GPWIN(NMEAInputLine &line, NMEA_INFO *GPS_INFO)
{
  line.skip(2);

  fixed value;
  if (line.read_checked(value))
    GPS_INFO->ProvidePressureAltitude(value / 10);

  return false;
}
Beispiel #24
0
static bool
PDAAV(NMEAInputLine &line, gcc_unused NMEAInfo &info)
{
  gcc_unused unsigned short beepfrequency = line.Read(0);
  gcc_unused unsigned short soundfrequency = line.Read(0);
  gcc_unused unsigned char soundtype = line.Read(0);

  // Temporarily commented out - function as yet undefined
  //  audio_setconfig(beepfrequency, soundfrequency, soundtype);

  return true;
}
Beispiel #25
0
static bool
PDVVT(NMEAInputLine &line, NMEAInfo &info)
{
  int value;
  info.temperature_available = line.ReadChecked(value);
  if (info.temperature_available)
    info.temperature = fixed(value) / 10;

  info.humidity_available = line.ReadChecked(info.humidity);

  return true;
}
Beispiel #26
0
static bool
GPWIN(NMEAInputLine &line, NMEA_INFO *GPS_INFO, bool enable_baro)
{
  line.skip(2);

  fixed value;
  if (enable_baro && line.read_checked(value)) {
    GPS_INFO->BaroAltitude = GPS_INFO->pressure.AltitudeToQNHAltitude(value / 10);
    GPS_INFO->BaroAltitudeAvailable = true;
  }

  return false;
}
Beispiel #27
0
  void PDVSC_S(NMEAInputLine &line) {
    char name[64], value[256];
    line.read(name, ARRAY_SIZE(name));
    line.read(value, ARRAY_SIZE(value));

    settings[name] = value;

    ConsoleOperationEnvironment env;

    char buffer[512];
    snprintf(buffer, ARRAY_SIZE(buffer), "PDVSC,A,%s,%s", name, value);
    PortWriteNMEA(*port, buffer, env);
  }
Beispiel #28
0
static bool
PZAN2(NMEAInputLine &line, NMEAInfo &info)
{
  fixed vtas, wnet;

  if (line.ReadChecked(vtas))
    info.ProvideTrueAirspeed(Units::ToSysUnit(vtas, Unit::KILOMETER_PER_HOUR));

  if (line.ReadChecked(wnet))
    info.ProvideTotalEnergyVario((wnet - fixed(10000)) / 100);

  return true;
}
Beispiel #29
0
static bool
PZAN2(NMEAInputLine &line, NMEAInfo &info)
{
  fixed vtas, wnet;

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

  if (line.read_checked(wnet))
    info.ProvideTotalEnergyVario((wnet - fixed(10000)) / 100);

  return true;
}
Beispiel #30
0
static bool
PDSWC(NMEAInputLine &line, NMEAInfo &info, Vega::VolatileData &volatile_data)
{
  unsigned value;
  if (line.ReadChecked(value) &&
      info.settings.ProvideMacCready(fixed(value) / 10, info.clock))
    volatile_data.mc = value;

  auto &switches = info.switch_state;
  auto &vs = switches.vega;
  vs.inputs = line.ReadHex(0);
  vs.outputs = line.ReadHex(0);

  if (vs.GetFlapLanding())
    switches.flap_position = SwitchState::FlapPosition::LANDING;
  else if (vs.GetFlapZero())
    switches.flap_position = SwitchState::FlapPosition::NEUTRAL;
  else if (vs.GetFlapNegative())
    switches.flap_position = SwitchState::FlapPosition::NEGATIVE;
  else if (vs.GetFlapPositive())
    switches.flap_position = SwitchState::FlapPosition::POSITIVE;
  else
    switches.flap_position = SwitchState::FlapPosition::UNKNOWN;

  if (vs.GetUserSwitchMiddle())
    switches.user_switch = SwitchState::UserSwitch::MIDDLE;
  else if (vs.GetUserSwitchUp())
    switches.user_switch = SwitchState::UserSwitch::UP;
  else if (vs.GetUserSwitchDown())
    switches.user_switch = SwitchState::UserSwitch::DOWN;
  else
    switches.user_switch = SwitchState::UserSwitch::UNKNOWN;

  if (vs.GetAirbrakeLocked())
    switches.airbrake_state = SwitchState::AirbrakeState::LOCKED;
  else if (vs.GetAirbrakeNotLocked())
    switches.airbrake_state = SwitchState::AirbrakeState::NOT_LOCKED;
  else
    switches.airbrake_state = SwitchState::AirbrakeState::UNKNOWN;

  switches.flight_mode = vs.GetCircling()
    ? SwitchState::FlightMode::CIRCLING
    : SwitchState::FlightMode::CRUISE;

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

  return true;
}