示例#1
0
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;
}
示例#2
0
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);
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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();
}
示例#6
0
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;
}