// $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; }
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; }
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; }
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; }
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); }
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; }
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; }
// 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; }
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; }
/** * 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; }
/** * 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; }
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; }
/** * 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; }
/** * $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; }
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; }
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; }
/** * 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; }
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; }
static bool ParsePITV4(NMEAInputLine &line, NMEAInfo &info) { fixed value; // TE vario [m/s] if (line.ReadChecked(value)) info.ProvideTotalEnergyVario(value); return true; }
static bool GPWIN(NMEAInputLine &line, NMEAInfo &info) { line.skip(2); fixed value; if (line.read_checked(value)) info.ProvidePressureAltitude(value / 10); return false; }
/** * 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; }
/** * 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; }
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; }
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; }
/** * 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; }
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; }
/** * 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; }
/* !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; }
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; }