int main(int argc, char **argv) { Args args(argc, argv, "DRIVER FILE"); DebugReplay *replay = CreateDebugReplay(args); if (replay == NULL) return EXIT_FAILURE; args.ExpectEnd(); printf("# time wind_bearing (deg) wind_speed (m/s)\n"); GlidePolar glide_polar(fixed(0)); CirclingSettings circling_settings; WindSettings wind_settings; wind_settings.SetDefaults(); CirclingComputer circling_computer; circling_computer.Reset(); WindComputer wind_computer; wind_computer.Reset(); Validity last; last.Clear(); while (replay->Next()) { const MoreData &basic = replay->Basic(); const DerivedInfo &calculated = replay->Calculated(); circling_computer.TurnRate(replay->SetCalculated(), basic, calculated.flight); circling_computer.Turning(replay->SetCalculated(), basic, calculated.flight, circling_settings); wind_computer.Compute(wind_settings, glide_polar, basic, replay->SetCalculated()); if (calculated.estimated_wind_available.Modified(last)) { TCHAR time_buffer[32]; FormatTime(time_buffer, replay->Basic().time); _tprintf(_T("%s %d %g\n"), time_buffer, (int)calculated.estimated_wind.bearing.Degrees(), (double)calculated.estimated_wind.norm); } last = calculated.estimated_wind_available; } delete replay; }
static void ComputeCircling(DebugReplay &replay, const CirclingSettings &circling_settings) { circling_computer.TurnRate(replay.SetCalculated(), replay.Basic(), replay.Calculated().flight); circling_computer.Turning(replay.SetCalculated(), replay.Basic(), replay.Calculated().flight, circling_settings); }
int main(int argc, char **argv) { Args args(argc, argv, "DRIVER FILE"); DebugReplay *replay = CreateDebugReplay(args); if (replay == NULL) return EXIT_FAILURE; args.ExpectEnd(); printf("# time quality wind_bearing (deg) wind_speed (m/s)\n"); CirclingComputer circling_computer; CirclingWind circling_wind; while (replay->Next()) { circling_computer.TurnRate(replay->SetCalculated(), replay->Basic(), replay->LastBasic(), replay->Calculated(), replay->LastCalculated()); circling_computer.Turning(replay->SetCalculated(), replay->Basic(), replay->LastBasic(), replay->Calculated(), replay->LastCalculated(), replay->SettingsComputer()); if ((replay->LastCalculated().turn_mode == WAITCLIMB && replay->Calculated().turn_mode == CLIMB) || (replay->LastCalculated().turn_mode == WAITCRUISE && replay->Calculated().turn_mode == CRUISE)) circling_wind.slot_newFlightMode(replay->Calculated(), negative(replay->Calculated().turn_rate_smoothed), 0); CirclingWind::Result result = circling_wind.NewSample(replay->Basic()); if (result.quality > 0) { fixed mag = hypot(result.wind.x, result.wind.y); Angle bearing; if (result.wind.y == fixed_zero && result.wind.x == fixed_zero) bearing = Angle::zero(); else bearing = Angle::radians(atan2(result.wind.y, result.wind.x)).as_bearing(); printf("%d %d %d %g\n", (int)replay->Basic().time, result.quality, (int)bearing.value_degrees(), (double)mag); } } delete replay; }
int main(int argc, char **argv) { Args args(argc, argv, "DRIVER FILE"); DebugReplay *replay = CreateDebugReplay(args); if (replay == NULL) return EXIT_FAILURE; args.ExpectEnd(); printf("# time wind_bearing (deg) wind_speed (m/s) grndspeed (m/s) tas (m/s) bearing (deg)\n"); CirclingSettings circling_settings; circling_settings.SetDefaults(); CirclingComputer circling_computer; circling_computer.Reset(); WindEKFGlue wind_ekf; wind_ekf.Reset(); while (replay->Next()) { const MoreData &data = replay->Basic(); const DerivedInfo &calculated = replay->Calculated(); circling_computer.TurnRate(replay->SetCalculated(), data, calculated.flight); WindEKFGlue::Result result = wind_ekf.Update(data, replay->Calculated()); if (result.quality > 0) { TCHAR time_buffer[32]; FormatTime(time_buffer, data.time); _tprintf(_T("%s %d %g %g %g %d\n"), time_buffer, (int)result.wind.bearing.Degrees(), (double)result.wind.norm, (double)data.ground_speed, (double)data.true_airspeed, (int)data.track.Degrees()); } } delete replay; }
void Run(DebugReplay &replay, FlightPhaseDetector &flight_phase_detector, WindList &wind_list, const BrokenDateTime &takeoff_time, const BrokenDateTime &scoring_start_time, const BrokenDateTime &scoring_end_time, const BrokenDateTime &landing_time, Trace &full_trace, Trace &triangle_trace, Trace &sprint_trace, ComputerSettings &computer_settings) { GeoPoint last_location = GeoPoint::Invalid(); constexpr Angle max_longitude_change = Angle::Degrees(30); constexpr Angle max_latitude_change = Angle::Degrees(1); CirclingSettings circling_settings; circling_settings.SetDefaults(); CirclingComputer circling_computer; circling_computer.Reset(); GlidePolar glide_polar(0); WindSettings wind_settings; wind_settings.SetDefaults(); WindComputer wind_computer; wind_computer.Reset(); Validity last_wind; last_wind.Clear(); const Waypoints waypoints; AutoQNH auto_qnh(5); auto_qnh.Reset(); const int64_t takeoff_unix = takeoff_time.ToUnixTimeUTC(); const int64_t landing_unix = landing_time.ToUnixTimeUTC(); int64_t scoring_start_unix, scoring_end_unix; if (scoring_start_time.IsPlausible()) scoring_start_unix = scoring_start_time.ToUnixTimeUTC(); else scoring_start_unix = std::numeric_limits<int64_t>::max(); if (scoring_end_time.IsPlausible()) scoring_end_unix = scoring_end_time.ToUnixTimeUTC(); else scoring_end_unix = 0; while (replay.Next()) { const MoreData &basic = replay.Basic(); const int64_t date_time_utc = basic.date_time_utc.ToUnixTimeUTC(); if (date_time_utc < takeoff_unix) continue; if (date_time_utc > landing_unix) break; circling_computer.TurnRate(replay.SetCalculated(), replay.Basic(), replay.Calculated().flight); circling_computer.Turning(replay.SetCalculated(), replay.Basic(), replay.Calculated().flight, circling_settings); flight_phase_detector.Update(replay.Basic(), replay.Calculated()); wind_computer.Compute(wind_settings, glide_polar, basic, replay.SetCalculated()); if (replay.Calculated().estimated_wind_available.Modified(last_wind)) { wind_list.push_back(WindListItem(basic.date_time_utc, basic.gps_altitude, replay.Calculated().estimated_wind)); } last_wind = replay.Calculated().estimated_wind_available; auto_qnh.Process(basic, replay.SetCalculated(), computer_settings, waypoints); if (!computer_settings.pressure_available && replay.Calculated().pressure_available) { computer_settings.pressure = replay.Calculated().pressure; computer_settings.pressure_available = replay.Calculated().pressure_available; } if (!basic.time_available || !basic.location_available || !basic.NavAltitudeAvailable()) continue; if (last_location.IsValid() && ((last_location.latitude - basic.location.latitude).Absolute() > max_latitude_change || (last_location.longitude - basic.location.longitude).Absolute() > max_longitude_change)) /* there was an implausible warp, which is usually triggered by an invalid point declared "valid" by a bugged logger; if that happens, we stop the analysis, because the IGC file is obviously broken */ break; last_location = basic.location; if (date_time_utc >= scoring_start_unix && date_time_utc <= scoring_end_unix) { const TracePoint point(basic); full_trace.push_back(point); triangle_trace.push_back(point); sprint_trace.push_back(point); } } flight_phase_detector.Finish(); }
bool Run(DebugReplay &replay, FlightTimeResult &result) { bool released = false; bool powered = false; GeoPoint last_location = GeoPoint::Invalid(); constexpr Angle max_longitude_change = Angle::Degrees(30); constexpr Angle max_latitude_change = Angle::Degrees(1); replay.SetCalculated().Reset(); replay.SetFlyingComputer().Reset(); while (replay.Next()) { const MoreData &basic = replay.Basic(); Update(basic, replay.Calculated(), result); if (!basic.time_available || !basic.location_available || !basic.NavAltitudeAvailable()) continue; if (last_location.IsValid() && ((last_location.latitude - basic.location.latitude).Absolute() > max_latitude_change || (last_location.longitude - basic.location.longitude).Absolute() > max_longitude_change)) /* there was an implausible warp, which is usually triggered by an invalid point declared "valid" by a bugged logger; if that happens, we stop the analysis, because the IGC file is obviously broken */ break; last_location = basic.location; if (!released && !negative(replay.Calculated().flight.release_time)) { released = true; } if (replay.Calculated().flight.powered != powered) { powered = replay.Calculated().flight.powered; PowerState power_state; if (powered) { power_state.time = basic.GetDateTimeAt(replay.Calculated().flight.power_on_time); power_state.location = replay.Calculated().flight.power_on_location; power_state.state = PowerState::ON; } else { power_state.time = basic.GetDateTimeAt(replay.Calculated().flight.power_off_time); power_state.location = replay.Calculated().flight.power_off_location; power_state.state = PowerState::OFF; } result.power_states.push_back(power_state); } if (released && !replay.Calculated().flight.flying) /* the aircraft has landed, stop here */ /* TODO: at some point, we might want to emit the analysis of all flights in this IGC file */ break; } Update(replay.Basic(), replay.Calculated(), result); Finish(replay.Basic(), replay.Calculated(), result); // landing detected or eof? if (replay.Tell() != replay.Size()) return false; else return true; }