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); }
void GlidePolarTest::TestBasic() { polar.Update(); ok1(equals(polar.polar.a, polar.ideal_polar.a)); ok1(equals(polar.polar.b, polar.ideal_polar.b)); ok1(equals(polar.polar.c, polar.ideal_polar.c)); ok1(equals(polar.SinkRate(Units::ToSysUnit(fixed(80), Unit::KILOMETER_PER_HOUR)), 0.606)); ok1(equals(polar.SinkRate(Units::ToSysUnit(fixed(120), Unit::KILOMETER_PER_HOUR)), 0.99)); ok1(equals(polar.SinkRate(Units::ToSysUnit(fixed(160), Unit::KILOMETER_PER_HOUR)), 1.918)); ok1(equals(polar.GetSMax(), polar.SinkRate(polar.GetVMax()))); ok1(equals(polar.GetVMin(), 19.934640523)); ok1(equals(polar.GetSMin(), polar.SinkRate(polar.GetVMin()))); ok1(equals(polar.GetVTakeoff(), polar.GetVMin() / 2)); ok1(equals(polar.GetVBestLD(), 25.830434162)); ok1(equals(polar.GetSBestLD(), polar.SinkRate(polar.GetVBestLD()))); ok1(equals(polar.GetBestLD(), polar.GetVBestLD() / polar.GetSBestLD())); ok1(equals(polar.GetTotalMass(), 318)); ok1(equals(polar.GetWingLoading(), 32.448979592)); ok1(equals(polar.GetBallast(), 0)); ok1(equals(polar.GetBallastLitres(), 0)); ok1(polar.IsBallastable()); ok1(!polar.HasBallast()); }
bool AirspaceWarningManager::UpdateTask(const AircraftState &state, const GlidePolar &glide_polar, const TaskStats &task_stats) { if (!glide_polar.IsValid()) return false; const ElementStat ¤t_leg = task_stats.current_leg; if (!task_stats.task_valid || !current_leg.location_remaining.IsValid()) return false; const GlideResult &solution = current_leg.solution_remaining; if (!solution.IsOk() || !solution.IsAchievable()) /* glide solver failed, cannot continue */ return false; const AirspaceAircraftPerformance perf_task(glide_polar, current_leg.solution_remaining); GeoPoint location_tp = current_leg.location_remaining; const fixed time_remaining = solution.time_elapsed; const GeoVector vector(state.location, location_tp); fixed max_distance = config.warning_time * glide_polar.GetVMax(); if (vector.distance > max_distance) /* limit the distance to what our glider can actually fly within the configured warning time */ location_tp = state.location.IntermediatePoint(location_tp, max_distance); return UpdatePredicted(state, location_tp, perf_task, AirspaceWarning::WARNING_TASK, time_remaining); }
/** * Specialisation based on simplified theoretical MC cross-country * speeds. Assumes cruise at best LD (ignoring wind) for current MC * setting, climb rate at MC setting, with direct descent possible * at sink rate of cruise. */ explicit AirspaceAircraftPerformance(const GlidePolar &polar) :vertical_tolerance(0), cruise_speed(polar.GetVBestLD()), cruise_descent(polar.GetSBestLD()), descent_rate(polar.GetSMax()), climb_rate(polar.GetMC()), max_speed(polar.GetVMax()) { assert(polar.IsValid()); }