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; } }
void AbstractTask::Reset() { ResetAutoMC(); active_task_point_last = 0 - 1; ce_lpf.reset(fixed_one); stats.reset(); }
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; }