Beispiel #1
0
void
WesterboerVW921Device::SentenceOne(const void *_data, size_t length,
                                   struct NMEAInfo &info)
{
  const uint8_t *data = (const uint8_t *)_data;

  // Sentence one exists in multiple versions based on firmware version
  if (length == 31) {
    // According to test device

    fixed wing_loading = fixed(ReadFloat(data + 13));
    info.settings.ProvideWingLoading(wing_loading, info.clock);

    uint8_t polar_type = *(data + 30);
    if (polar_type == 0)
      info.settings.ProvideBugs(fixed_one, info.clock);
    else if (polar_type == 1)
      info.settings.ProvideBugs(fixed(0.85), info.clock);
    else if (polar_type == 2)
      info.settings.ProvideBugs(fixed(0.95), info.clock);

  } else if (length == 26) {
    // According to version 3.30 documentation

    int16_t wing_loading =
        ReadUnalignedLE16((const uint16_t *)(const void *)(data + 11));
    info.settings.ProvideWingLoading(fixed(wing_loading) / 10, info.clock);

    uint8_t polar_type = *(data + 13);
    if (polar_type == 0)
      info.settings.ProvideBugs(fixed_one, info.clock);
    else if (polar_type == 1)
      info.settings.ProvideBugs(fixed(0.95), info.clock);
    else if (polar_type == 2)
      info.settings.ProvideBugs(fixed(0.85), info.clock);
  }
}
Beispiel #2
0
 uint16_t GetSequenceNumber() const {
   return ReadUnalignedLE16(&sequence_number);
 }
Beispiel #3
0
void
WesterboerVW921Device::SentenceZero(const void *_data, size_t length,
                                    struct NMEAInfo &info)
{
  const uint8_t *data = (const uint8_t *)_data;

  /*
  Received sentence #0 with length = 45
  24 77 2d 3c 00 10 82 07   c8 6c 28 00 00 bd ff 46
  00 04 02 00 00 46 00 00   00 12 00 01 00 00 00 00
  00 3f 0b 80 62 d5 b1 7d   5a 0d cd a6 ff
  */

  // 0 - 4        Header
  // 24 77 2d 3c 00

  // 5      Byte  Flight status (Bitmask)
  // 6      Byte  Flight status 2 (Bitmask)
  // Bit 7 : External Switch (1=Climbing, 0=Cruise)

  uint8_t flight_status2 = *(data + 6);
  if ((flight_status2 & (1 << 7)) == 0) {
    info.switch_state.flight_mode = SwitchInfo::FlightMode::CRUISE;
    info.switch_state.speed_command = true;
  } else {
    info.switch_state.flight_mode = SwitchInfo::FlightMode::CIRCLING;
    info.switch_state.speed_command = false;
  }

  info.switch_state_available = true;

  // 7      Byte  GPS status (Bitmask)
  // Bit 3: GPS-Status-Flag ("A"-valid position/"V"- NAV receiver warning)
  // 8      Byte  GPS status 2 (Bitmask)

  // 9     Word  Flight time (sec)
  // 11     Word  Distance to next target (0.1 km)
  // 6c 28 00 00

  // 13     Int   STD altitude (m)
  // 15     Int   QFE-Höhe h (m)
  // b8 ff 00 00

  int16_t std_altitude =
      ReadUnalignedLE16((const uint16_t *)(const void *)(data + 13));
  info.ProvidePressureAltitude(fixed(std_altitude));

  // 17     Int   Windempfehlung (km/ h)
  // 19     Int   delta speed (km/ h)
  // 21     Int   Gleitpath deviation (m)
  // 00 00 00 00 00 00

  // 23     Int   avg. Vario (0,1 m/s)
  // 25     Int   Nettovario (0,1 m/s)
  // 27     Int   Vario (0,1 m/s)
  // 00 00 11 00 f7 ff

  int16_t netto_vario =
      ReadUnalignedLE16((const uint16_t *)(const void *)(data + 25));
  info.ProvideNettoVario(fixed(netto_vario) / 10);

  int16_t vario =
      ReadUnalignedLE16((const uint16_t *)(const void *)(data + 27));
  info.ProvideTotalEnergyVario(fixed(vario) / 10);

  // 29     Int   True Air Speed TAS (0,1 m/s)
  // 31     Int   Groundspeed GS (0,1 m/s)
  // 00 00 e6 00

  int16_t tas =
      ReadUnalignedLE16((const uint16_t *)(const void *)(data + 29));
  info.ProvideTrueAirspeed(fixed(tas) / 10);

  int16_t ground_speed =
      ReadUnalignedLE16((const uint16_t *)(const void *)(data + 31));

  info.ground_speed = fixed(ground_speed) / 10;
  info.ground_speed_available.Update(info.clock);

  // Next 12 bytes are zero if GPS connection is bad:
  // 33     Int   Track (0.1 deg)
  // eb 03
  // 35     Float Latitude (arc, -pi/2 .. +pi/2)
  // 80 62 d6 ce = N504606
  // 39     Float Longitude (arc, -pi .. +pi)
  // 7d 59 e4 01 = E 60601
  // 43     Int   DiffAngle (0.1 deg)
  // 62 fd

  uint8_t gps_status = *(data + 7);
  if ((gps_status & (1 << 3)) != 0) {
    // GPS has a valid fix

    int16_t track =
        ReadUnalignedLE16((const uint16_t *)(const void *)(data + 31));

    info.track = Angle::Degrees(fixed(track) / 10);
    info.track_available.Update(info.clock);

    info.location.latitude = Angle::Radians(fixed(ReadFloat(data + 35)));
    info.location.longitude = Angle::Radians(fixed(ReadFloat(data + 39)));

    info.location_available.Update(info.clock);
  }
}