Пример #1
0
const AircraftState
ToAircraftState(const MoreData &info, const DerivedInfo &calculated)
{
  AircraftState aircraft;

  /* SPEED_STATE */
  aircraft.ground_speed = info.ground_speed;
  aircraft.true_airspeed = info.true_airspeed;
  aircraft.indicated_airspeed = info.indicated_airspeed;

  /* ALTITUDE_STATE */
  aircraft.altitude = info.nav_altitude;
  aircraft.working_band_fraction = calculated.thermal_band.working_band_fraction;
  aircraft.altitude_agl = calculated.altitude_agl;

  /* VARIO_INFO */
  aircraft.vario = info.brutto_vario;
  aircraft.netto_vario = info.netto_vario;

  /* FLYING_STATE */
  (FlyingState &)aircraft = calculated.flight;

  /* AIRCRAFT_STATE */
  aircraft.time = info.time;
  aircraft.location = info.location;
  aircraft.track = info.track;
  aircraft.g_load = info.acceleration.available
    ? info.acceleration.g_load
    : fixed_one;
  aircraft.wind = calculated.GetWindOrZero();

  return aircraft;
}
Пример #2
0
void
GlideComputerAirData::ProcessVertical(const MoreData &basic,
                                      const MoreData &last_basic,
                                      DerivedInfo &calculated,
                                      const ComputerSettings &settings)
{
  /* the "circling" flag may be modified by
     CirclingComputer::Turning(); remember the old state so this
     method can check for modifications */
  const bool last_circling = calculated.circling;

  auto_qnh.Process(basic, calculated, settings, waypoints);

  circling_computer.TurnRate(calculated, basic,
                             calculated.flight);
  Turning(basic, calculated, settings);

  wind_computer.Compute(settings.wind, settings.polar.glide_polar_task,
                        basic, calculated);
  wind_computer.Select(settings.wind, basic, calculated);
  wind_computer.ComputeHeadWind(basic, calculated);

  thermallocator.Process(calculated.circling,
                         basic.time, basic.location,
                         basic.netto_vario,
                         calculated.GetWindOrZero(),
                         calculated.thermal_locator);

  LastThermalStats(basic, calculated, last_circling);

  gr_computer.Compute(basic, last_basic, calculated,
                      calculated,
                      settings);

  GR(basic, calculated.flight, calculated);
  CruiseGR(basic, calculated);

  average_vario.Compute(basic, calculated.circling, last_circling,
                        calculated);
  AverageClimbRate(basic, calculated);

  if (calculated.circling)
    CurrentThermal(basic, calculated, calculated.current_thermal);

  lift_database_computer.Compute(calculated.lift_database,
                                 calculated.trace_history.CirclingAverage,
                                 basic, calculated);
  circling_computer.MaxHeightGain(basic, calculated.flight, calculated);
  NextLegEqThermal(basic, calculated, settings);
}
Пример #3
0
void
RouteComputer::ProcessRoute(const MoreData &basic, DerivedInfo &calculated,
                            const GlideSettings &settings,
                            const RoutePlannerConfig &config,
                            const GlidePolar &glide_polar,
                            const GlidePolar &safety_polar)
{
  if (!basic.location_available || !basic.NavAltitudeAvailable())
    return;

  protected_route_planner.SetPolars(settings, glide_polar, safety_polar,
                                    calculated.GetWindOrZero());

  Reach(basic, calculated, config);
  TerrainWarning(basic, calculated, config);
}
Пример #4
0
  void CalculateDirect(const PolarSettings &polar_settings,
                       const TaskBehaviour &task_behaviour,
                       const DerivedInfo &calculated) {
    if (!basic.location_available || !basic.NavAltitudeAvailable())
      return;

    const GlidePolar &glide_polar =
      task_behaviour.route_planner.reach_polar_mode == RoutePlannerConfig::Polar::TASK
      ? polar_settings.glide_polar_task
      : calculated.glide_polar_safety;
    const MacCready mac_cready(task_behaviour.glide, glide_polar);

    for (VisibleWaypoint &vwp : waypoints) {
      const Waypoint &way_point = *vwp.waypoint;

      if (way_point.IsLandable() || way_point.flags.watched)
        vwp.CalculateReachabilityDirect(basic, calculated.GetWindOrZero(),
                                        mac_cready, task_behaviour);
    }
  }
Пример #5
0
bool
ConditionMonitorWind::CheckCondition(const NMEAInfo &basic,
                                     const DerivedInfo &calculated,
                                     const ComputerSettings &settings)
{
  wind = calculated.GetWindOrZero();

  if (!calculated.flight.flying) {
    last_wind = wind;
    return false;
  }

  fixed mag_change = fabs(wind.norm - last_wind.norm);
  fixed dir_change = (wind.bearing - last_wind.bearing).AsDelta().AbsoluteDegrees();

  if (mag_change > fixed(2.5))
    return true;

  return wind.norm > fixed(5) &&
         dir_change > fixed(45);
}
Пример #6
0
const AircraftState
ToAircraftState(const MoreData &info, const DerivedInfo &calculated)
{
  AircraftState aircraft;

  /* SPEED_STATE */
  aircraft.ground_speed = info.ground_speed;
  aircraft.true_airspeed = info.true_airspeed;

  /* ALTITUDE_STATE */
  aircraft.altitude = info.NavAltitudeAvailable()
    ? info.nav_altitude
    : 0.;

  aircraft.working_band_fraction = calculated.common_stats.height_fraction_working;

  aircraft.altitude_agl =
    info.NavAltitudeAvailable() && calculated.terrain_valid
    ? calculated.altitude_agl
    : 0.;

  /* VARIO_INFO */
  aircraft.vario = info.brutto_vario;
  aircraft.netto_vario = info.netto_vario;

  /* AIRCRAFT_STATE */
  aircraft.time = info.time_available ? info.time : -1.;
  aircraft.location = info.location_available
    ? info.location
    : GeoPoint::Invalid();
  aircraft.track = info.track;
  aircraft.g_load = info.acceleration.available
    ? info.acceleration.g_load
    : 1.;
  aircraft.wind = calculated.GetWindOrZero();
  aircraft.flying = calculated.flight.flying;

  return aircraft;
}
Пример #7
0
void
GlideComputerAirData::ProcessVertical(const MoreData &basic,
                                      const MoreData &last_basic,
                                      DerivedInfo &calculated,
                                      const DerivedInfo &last_calculated,
                                      const ComputerSettings &settings)
{
  auto_qnh.Process(basic, calculated, settings, waypoints);

  Heading(basic, calculated);
  circling_computer.TurnRate(calculated, basic, last_basic,
                             calculated, last_calculated);
  Turning(basic, last_basic, calculated, last_calculated, settings);

  wind_computer.Compute(settings.wind, settings.polar.glide_polar_task,
                        basic, calculated);
  wind_computer.Select(settings.wind, basic, calculated);
  wind_computer.ComputeHeadWind(basic, calculated);

  thermallocator.Process(calculated.circling,
                         basic.time, basic.location,
                         basic.netto_vario,
                         calculated.GetWindOrZero(),
                         calculated.thermal_locator);

  LastThermalStats(basic, calculated, last_calculated);
  GR(basic, last_basic, calculated, calculated);
  CruiseGR(basic, calculated);

  if (calculated.flight.flying && !calculated.circling)
    calculated.average_gr = gr_calculator.Calculate();

  Average30s(basic, last_basic, calculated, last_calculated);
  AverageClimbRate(basic, calculated);
  CurrentThermal(basic, calculated, calculated.current_thermal);
  UpdateLiftDatabase(basic, calculated, last_calculated);
  circling_computer.MaxHeightGain(basic, calculated.flight, calculated);
  NextLegEqThermal(basic, calculated, settings);
}
Пример #8
0
void
GlideComputerAirData::ThermalSources(const MoreData &basic,
                                     const DerivedInfo &calculated,
                                     ThermalLocatorInfo &thermal_locator)
{
  if (!thermal_locator.estimate_valid ||
      !basic.NavAltitudeAvailable() ||
      !calculated.last_thermal.IsDefined() ||
      negative(calculated.last_thermal.lift_rate))
    return;

  if (calculated.wind_available &&
      calculated.wind.norm / calculated.last_thermal.lift_rate > fixed(10.0)) {
    // thermal strength is so weak compared to wind that source estimate
    // is unlikely to be reliable, so don't calculate or remember it
    return;
  }

  GeoPoint ground_location;
  fixed ground_altitude = fixed_minus_one;
  EstimateThermalBase(terrain, thermal_locator.estimate_location,
                      basic.nav_altitude,
                      calculated.last_thermal.lift_rate,
                      calculated.GetWindOrZero(),
                      ground_location,
                      ground_altitude);

  if (positive(ground_altitude)) {
    ThermalSource &source =
      thermal_locator.AllocateSource(basic.time);

    source.lift_rate = calculated.last_thermal.lift_rate;
    source.location = ground_location;
    source.ground_height = ground_altitude;
    source.time = basic.time;
  }
}