示例#1
0
bool 
AbstractTask::UpdateAutoMC(GlidePolar &glide_polar,
                           const AircraftState& state, fixed fallback_mc)
{
  if (!task_behaviour.auto_mc) {
    /* AutoMC disabled in configuration */
    ResetAutoMC();
    return false;
  }

  fixed mc_found;
  if (task_behaviour.IsAutoMCFinalGlideEnabled() &&
      TaskStarted(true) && stats.flight_mode_final_glide) {
    /* calculate final glide MacCready */

    if (CalcBestMC(state, glide_polar, mc_found)) {
      /* final glide MacCready found */
      if (mc_lpf_valid)
        stats.mc_best = std::max(mc_lpf.Update(mc_found), fixed(0));
      else {
        stats.mc_best = std::max(mc_lpf.Reset(mc_found), fixed(0));
        mc_lpf_valid = true;
      }
    } else
      /* below final glide, but above margin */
      stats.mc_best = fixed(0);

    glide_polar.SetMC(stats.mc_best);
    return true;
  } else if (task_behaviour.IsAutoMCCruiseEnabled()) {
    /* cruise: set MacCready to recent climb average */

    if (!positive(fallback_mc)) {
      /* no climb average calculated yet */
      ResetAutoMC();
      return false;
    }

    stats.mc_best = fallback_mc;
    glide_polar.SetMC(stats.mc_best);
    return true;
  } else if (TaskStarted(true)) {
    /* no solution, but forced final glide AutoMacCready - converge to
       zero */

    mc_found = fixed(0);
    if (mc_lpf_valid)
      stats.mc_best = std::max(mc_lpf.Update(mc_found), fixed(0));
    else {
      stats.mc_best = std::max(mc_lpf.Reset(mc_found), fixed(0));
      mc_lpf_valid = true;
    }

    glide_polar.SetMC(stats.mc_best);
    return true;
  } else {
    ResetAutoMC();
    return false;
  }
}
示例#2
0
void
GlidePolarTest::TestMC()
{
  polar.SetMC(fixed(1));
  ok1(equals(polar.GetVBestLD(), 33.482780452));

  polar.SetMC(fixed(0));
  ok1(equals(polar.GetVBestLD(), 25.830434162));
}
示例#3
0
void
RenderMacCready(Canvas &canvas, const PixelRect rc,
                 const ChartLook &chart_look,
                 const GlidePolar &glide_polar)
{
  ChartRenderer chart(chart_look, canvas, rc);

  if (!glide_polar.IsValid()) {
    chart.DrawNoData();
    return;
  }

  chart.ScaleXFromValue(0);
  chart.ScaleXFromValue(MAX_MACCREADY);
  chart.ScaleYFromValue(0);
  chart.ScaleYFromValue(glide_polar.GetVMax());

  chart.DrawXGrid(Units::ToSysVSpeed(1), 1, ChartRenderer::UnitFormat::NUMERIC);
  chart.DrawYGrid(Units::ToSysSpeed(10), 10, ChartRenderer::UnitFormat::NUMERIC);

  GlidePolar gp = glide_polar;
  double m = 0;
  double m_last;
  gp.SetMC(m);
  double v_last = gp.GetVBestLD();
  double vav_last = 0;
  do {
    m_last = m;
    m+= MAX_MACCREADY/STEPS_MACCREADY;
    gp.SetMC(m);
    const double v = gp.GetVBestLD();
    const double vav = gp.GetAverageSpeed();
    chart.DrawLine(m_last, v_last, m, v, ChartLook::STYLE_BLACK);
    chart.DrawLine(m_last, vav_last, m, vav, ChartLook::STYLE_BLUETHINDASH);
    v_last = v;
    vav_last = vav;
  } while (m<MAX_MACCREADY);

  // draw current MC setting
  chart.DrawLine(glide_polar.GetMC(), 0, glide_polar.GetMC(), glide_polar.GetVMax(),
                 ChartLook::STYLE_REDTHICKDASH);

  // draw labels and other overlays

  gp.SetMC(0.9*MAX_MACCREADY);
  chart.DrawLabel(_T("Vopt"), 0.9*MAX_MACCREADY, gp.GetVBestLD());
  gp.SetMC(0.9*MAX_MACCREADY);
  chart.DrawLabel(_T("Vave"), 0.9*MAX_MACCREADY, gp.GetAverageSpeed());

  chart.DrawYLabel(_T("V"), Units::GetSpeedName());
  chart.DrawXLabel(_T("MC"), Units::GetVerticalSpeedName());

  RenderGlidePolarInfo(canvas, rc, chart_look, glide_polar);
}
示例#4
0
GlidePolar
AbortTask::GetSafetyPolar() const
{
  const fixed mc_safety = task_behaviour.safety_mc;
  GlidePolar polar = glide_polar;
  polar.SetMC(mc_safety);
  return polar;
}
示例#5
0
int main(int argc, char **argv)
{
  plan_tests(728);

  task_behaviour.SetDefaults();

  TestAll();

  glide_polar.SetMC(fixed(1));
  TestAll();

  glide_polar.SetMC(fixed(2));
  TestAll();

  glide_polar.SetMC(fixed(4));
  TestAll();

  return exit_status();
}
示例#6
0
int main(int argc, char **argv)
{
    plan_tests(2095);

    glide_settings.SetDefaults();

    TestAll();

    glide_polar.SetMC(fixed(0.1));
    TestAll();

    glide_polar.SetMC(fixed(1));
    TestAll();

    glide_polar.SetMC(fixed(4));
    TestAll();

    glide_polar.SetMC(fixed(10));
    TestAll();

    return exit_status();
}
示例#7
0
bool 
AbstractTask::UpdateAutoMC(GlidePolar &glide_polar,
                           const AircraftState& state, fixed fallback_mc)
{
  if (!positive(fallback_mc))
    fallback_mc = glide_polar.GetMC();

  if (!TaskStarted(true) || !task_behaviour.auto_mc) {
    ResetAutoMC();
    return false;
  }

  if (task_behaviour.auto_mc_mode == TaskBehaviour::AutoMCMode::CLIMBAVERAGE) {
    stats.mc_best = mc_lpf.reset(fallback_mc);
    mc_lpf_valid = true;
    trigger_auto = false;
    return false;
  }

  fixed mc_found;
  if (CalcBestMC(state, glide_polar, mc_found)) {
    // improved solution found, activate auto fg mode
    if (mc_found > stats.mc_best)
      trigger_auto = true;
  } else {
    // no solution even at mc=0, deactivate auto fg mode
    trigger_auto = false;
  }

  if (!trigger_auto &&
      task_behaviour.auto_mc_mode == TaskBehaviour::AutoMCMode::FINALGLIDE &&
      stats.mc_best >= fixed(0.05)) {
    /* no solution, but forced final glide AutoMacCready - converge to
       zero */
    mc_found = fixed_zero;
    trigger_auto = true;
  }

  if (trigger_auto && mc_lpf_valid) {
    // smooth out updates
    stats.mc_best = std::max(mc_lpf.update(mc_found), fixed_zero);
    glide_polar.SetMC(stats.mc_best);
  } else {
    // reset lpf so will be smooth next time it becomes active
    stats.mc_best = mc_lpf.reset(fallback_mc);
    mc_lpf_valid = true;
  }

  return trigger_auto;
}
示例#8
0
void 
InputEvents::eventNearestAirspaceDetails(gcc_unused const TCHAR *misc)
{
  const MoreData &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();
  const ComputerSettings &settings_computer =
    CommonInterface::GetComputerSettings();

  ProtectedAirspaceWarningManager *airspace_warnings = GetAirspaceWarnings();
  if (airspace_warnings != NULL && !airspace_warnings->warning_empty()) {
    // Prevent the dialog from closing itself without active warning
    // This is relevant if there are only acknowledged airspaces in the list
    // AutoClose will be reset when the dialog is closed again by hand
    dlgAirspaceWarningsShowModal(*XCSoarInterface::main_window,
                                 *airspace_warnings);
    return;
  }

  const AircraftState aircraft_state =
    ToAircraftState(basic, calculated);
  AirspaceVisiblePredicate visible(settings_computer.airspace,
                          CommonInterface::GetMapSettings().airspace,
                          aircraft_state);
  GlidePolar polar = settings_computer.polar.glide_polar_task;
  polar.SetMC(max(polar.GetMC(),fixed_one));
  AirspaceAircraftPerformanceGlide perf(polar);
  AirspaceSoonestSort ans(aircraft_state, perf, fixed(1800), visible);

  const AbstractAirspace* as = ans.find_nearest(airspace_database);
  if (!as) {
    return;
  } 

  dlgAirspaceDetails(*as, airspace_warnings);

  // clear previous warning if any
  XCSoarInterface::main_window->popup.Acknowledge(PopupMessage::MSG_AIRSPACE);

  // TODO code: No control via status data (ala DoStatusMEssage)
  // - can we change this?
//  Message::AddMessage(5000, Message::MSG_AIRSPACE, text);
}
示例#9
0
 /**
  * Adjust MacCready value of internal glide polar
  *
  * @param mc MacCready value (m/s)
  */
 void set_mc(fixed mc) {
     m_glide_polar.SetMC(mc);
 };