예제 #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
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;
}