コード例 #1
0
ファイル: GlideComputerTask.cpp プロジェクト: damianob/xcsoar
void
GlideComputerTask::ProcessBasicTask(const MoreData &basic,
                                    const MoreData &last_basic,
                                    DerivedInfo &calculated,
                                    const DerivedInfo &last_calculated,
                                    const ComputerSettings &settings_computer)
{
    if (basic.HasTimeAdvancedSince(last_basic) && basic.location_available)
        trace.Update(settings_computer, ToAircraftState(basic, calculated));

    ProtectedTaskManager::ExclusiveLease _task(task);

    _task->SetTaskBehaviour(settings_computer.task);

    if (basic.HasTimeAdvancedSince(last_basic) && basic.location_available) {
        const AircraftState current_as = ToAircraftState(basic, calculated);
        const AircraftState last_as = ToAircraftState(last_basic, last_calculated);

        _task->Update(current_as, last_as);

        const fixed fallback_mc = calculated.last_thermal.IsDefined() &&
                                  positive(calculated.last_thermal_average_smooth)
                                  ? calculated.last_thermal_average_smooth
                                  : fixed_zero;
        if (_task->UpdateAutoMC(current_as, fallback_mc))
            calculated.ProvideAutoMacCready(basic.clock,
                                            _task->GetGlidePolar().GetMC());
    }

    calculated.task_stats = _task->GetStats();
    calculated.common_stats = _task->GetCommonStats();
    calculated.glide_polar_safety = _task->GetSafetyPolar();
}
コード例 #2
0
ファイル: BasicComputer.cpp プロジェクト: rjsikarwar/XCSoar
void
BasicComputer::Compute(MoreData &data,
                       const MoreData &last, const MoreData &last_gps,
                       const DerivedInfo &calculated)
{
  ComputeTrack(data, last_gps);

  if (data.HasTimeAdvancedSince(last_gps)) {
    ComputeGroundSpeed(data, last_gps);
    ComputeAirspeed(data, calculated);
  }
#ifndef NDEBUG
  // For testing without gps.
  // When CPU load is low enough it can be done for every sample.
  else if (data.dyn_pressure_available)
    ComputeAirspeed(data, calculated);
#endif

  ComputeHeading(data.attitude, data, calculated);

  ComputeEnergyHeight(data);
  ComputeGPSVario(data, last, last_gps);
  ComputeBruttoVario(data);
  ComputeNettoVario(data, calculated);
  ComputeDynamics(data, calculated);
}
コード例 #3
0
void
GlideComputerAirData::Average30s(const MoreData &basic,
                                 const NMEAInfo &last_basic,
                                 DerivedInfo &calculated,
                                 const DerivedInfo &last_calculated)
{
  const bool time_advanced = basic.HasTimeAdvancedSince(last_basic);
  if (!time_advanced || calculated.circling != last_calculated.circling) {
    vario_30s_filter.reset();
    netto_30s_filter.reset();
    calculated.average = basic.brutto_vario;
    calculated.netto_average = basic.netto_vario;
  }

  if (!time_advanced)
    return;

  const unsigned Elapsed(basic.time - last_basic.time);
  if (Elapsed == 0)
    return;

  for (unsigned i = 0; i < Elapsed; ++i) {
    vario_30s_filter.update(basic.brutto_vario);
    netto_30s_filter.update(basic.netto_vario);
  }
  calculated.average = vario_30s_filter.average();
  calculated.netto_average = netto_30s_filter.average();
}
コード例 #4
0
void
WarningComputer::Update(const ComputerSettings &settings_computer,
                        const MoreData &basic, const MoreData &last_basic,
                        const DerivedInfo &calculated,
                        AirspaceWarningsInfo &result)
{
  if (!basic.HasTimeAdvancedSince(last_basic) ||
      !clock.check_advance(basic.time))
    return;

  airspaces.set_flight_levels(settings_computer.pressure);

  AirspaceActivity day(calculated.date_time_local.day_of_week);
  airspaces.set_activity(day);

  if (!settings_computer.airspace.enable_warnings ||
      !basic.location_available || !basic.NavAltitudeAvailable()) {
    if (initialised) {
      initialised = false;
      protected_manager.clear();
    }

    return;
  }

  const AircraftState as = ToAircraftState(basic, calculated);
  ProtectedAirspaceWarningManager::ExclusiveLease lease(protected_manager);

  if (!initialised) {
    initialised = true;
    lease->Reset(as);
  }

  if (lease->Update(as, settings_computer.glide_polar_task,
                    calculated.task_stats,
                    calculated.circling,
                    uround(basic.time - last_basic.time)))
    result.latest.Update(basic.clock);
}
コード例 #5
0
void
GlideComputerAirData::GR(const MoreData &basic, const MoreData &last_basic,
                         const DerivedInfo &calculated, VarioInfo &vario_info)
{
  if (!basic.NavAltitudeAvailable() || !last_basic.NavAltitudeAvailable()) {
    vario_info.ld_vario = INVALID_GR;
    vario_info.gr = INVALID_GR;
    return;
  }

  if (basic.HasTimeRetreatedSince(last_basic)) {
    vario_info.ld_vario = INVALID_GR;
    vario_info.gr = INVALID_GR;
  }

  const bool time_advanced = basic.HasTimeAdvancedSince(last_basic);
  if (time_advanced) {
    fixed DistanceFlown = basic.location.Distance(last_basic.location);

    // Glide ratio over ground
    vario_info.gr =
      UpdateGR(vario_info.gr, DistanceFlown,
               last_basic.nav_altitude - basic.nav_altitude, fixed(0.1));

    if (calculated.flight.flying && !calculated.circling)
      gr_calculator.Add((int)DistanceFlown, (int)basic.nav_altitude);
  }

  // Lift / drag instantaneous from vario, updated every reading..
  if (basic.total_energy_vario_available && basic.airspeed_available &&
      calculated.flight.flying) {
    vario_info.ld_vario =
      UpdateGR(vario_info.ld_vario, basic.indicated_airspeed,
               -basic.total_energy_vario, fixed(0.3));
  } else {
    vario_info.ld_vario = INVALID_GR;
  }
}
コード例 #6
0
void
CirclingComputer::Turning(CirclingInfo &circling_info,
                          const MoreData &basic, const MoreData &last_basic,
                          const DerivedInfo &calculated,
                          const DerivedInfo &last_calculated,
                          const ComputerSettings &settings_computer)
{
    // You can't be circling unless you're flying
    if (!calculated.flight.flying || !basic.HasTimeAdvancedSince(last_basic))
        return;

    // JMW limit rate to 50 deg per second otherwise a big spike
    // will cause spurious lock on circling for a long time
    fixed turn_rate = max(fixed(-50), min(fixed(50), calculated.turn_rate));

    // Make the turn rate more smooth using the LowPassFilter
    turn_rate = LowPassFilter(last_calculated.turn_rate_smoothed,
                              turn_rate, fixed(0.3));
    circling_info.turn_rate_smoothed = turn_rate;
    circling_info.turning = fabs(turn_rate) >= min_turn_rate;

    // Force cruise or climb mode if external device says so
    bool force_cruise = false;
    bool force_circling = false;
    if (settings_computer.external_trigger_cruise_enabled && !basic.gps.replay) {
        switch (basic.switch_state.flight_mode) {
        case SwitchInfo::FlightMode::UNKNOWN:
            force_circling = false;
            force_cruise = false;
            break;

        case SwitchInfo::FlightMode::CIRCLING:
            force_circling = true;
            force_cruise = false;
            break;

        case SwitchInfo::FlightMode::CRUISE:
            force_circling = false;
            force_cruise = true;
            break;
        }
    }

    switch (calculated.turn_mode) {
    case CirclingMode::CRUISE:
        // If (in cruise mode and beginning of circling detected)
        if (circling_info.turning || force_circling) {
            // Remember the start values of the turn
            circling_info.turn_start_time = basic.time;
            circling_info.turn_start_location = basic.location;
            circling_info.turn_start_altitude = basic.nav_altitude;
            circling_info.turn_start_energy_height = basic.energy_height;
            circling_info.turn_mode = CirclingMode::POSSIBLE_CLIMB;
        }
        if (!force_circling)
            break;

    case CirclingMode::POSSIBLE_CLIMB:
        if (force_cruise) {
            circling_info.turn_mode = CirclingMode::CRUISE;
            break;
        }
        if (circling_info.turning || force_circling) {
            if (((basic.time - calculated.turn_start_time) > cruise_climb_switch)
                    || force_circling) {
                // yes, we are certain now that we are circling
                circling_info.circling = true;

                // JMW Transition to climb
                circling_info.turn_mode = CirclingMode::CLIMB;

                // Remember the start values of the climbing period
                circling_info.climb_start_location = circling_info.turn_start_location;
                circling_info.climb_start_altitude = circling_info.turn_start_altitude
                                                     + circling_info.turn_start_energy_height;
                circling_info.climb_start_time = circling_info.turn_start_time;
            }
        } else {
            // nope, not turning, so go back to cruise
            circling_info.turn_mode = CirclingMode::CRUISE;
        }
        break;

    case CirclingMode::CLIMB:
        if (!circling_info.turning || force_cruise) {
            // Remember the end values of the turn
            circling_info.turn_start_time = basic.time;
            circling_info.turn_start_location = basic.location;
            circling_info.turn_start_altitude = basic.nav_altitude;
            circling_info.turn_start_energy_height = basic.energy_height;

            // JMW Transition to cruise, due to not properly turning
            circling_info.turn_mode = CirclingMode::POSSIBLE_CRUISE;
        }
        if (!force_cruise)
            break;

    case CirclingMode::POSSIBLE_CRUISE:
        if (force_circling) {
            circling_info.turn_mode = CirclingMode::CLIMB;
            break;
        }

        if (!circling_info.turning || force_cruise) {
            if (((basic.time - circling_info.turn_start_time) > climb_cruise_switch)
                    || force_cruise) {
                // yes, we are certain now that we are cruising again
                circling_info.circling = false;

                // Transition to cruise
                circling_info.turn_mode = CirclingMode::CRUISE;
                circling_info.cruise_start_location = circling_info.turn_start_location;
                circling_info.cruise_start_altitude = circling_info.turn_start_altitude;
                circling_info.cruise_start_time = circling_info.turn_start_time;
            }
        } else {
            // nope, we are circling again
            // JMW Transition back to climb, because we are turning again
            circling_info.turn_mode = CirclingMode::CLIMB;
        }
        break;
    }
}