Exemple #1
0
/**
 * Is called by the CalculationThread and processes the received GPS data in Basic()
 */
bool
GlideComputer::ProcessGPS(bool force)
{
  const MoreData &basic = Basic();
  DerivedInfo &calculated = SetCalculated();
  const ComputerSettings &settings = GetComputerSettings();

  const bool last_flying = calculated.flight.flying;

  calculated.date_time_local = basic.date_time_utc + settings.utc_offset;

  calculated.Expire(basic.clock);

  // Process basic information
  air_data_computer.ProcessBasic(Basic(), SetCalculated(),
                                 GetComputerSettings());

  // Process basic task information
  task_computer.ProcessBasicTask(basic, LastBasic(),
                                 calculated,
                                 GetComputerSettings(),
                                 force);
  task_computer.ProcessMoreTask(basic, calculated, GetComputerSettings());

  // Check if everything is okay with the gps time and process it
  if (!air_data_computer.FlightTimes(Basic(), LastBasic(), SetCalculated(),
                                     GetComputerSettings()))
    return false;

  TakeoffLanding(last_flying);

  if (!time_retreated())
    task_computer.ProcessAutoTask(basic, calculated);

  // Process extended information
  air_data_computer.ProcessVertical(Basic(), LastBasic(),
                                    SetCalculated(),
                                    GetComputerSettings());

  if (!time_retreated())
    stats_computer.ProcessClimbEvents(calculated);

  // Calculate the team code
  CalculateOwnTeamCode();

  // Calculate the bearing and range of the teammate
  CalculateTeammateBearingRange();

  vegavoice.Update(basic, Calculated(), GetComputerSettings().voice);

  // update basic trace history
  if (time_advanced())
    calculated.trace_history.append(basic);

  // Update the ConditionMonitors
  ConditionMonitorsUpdate(Basic(), Calculated(), settings);

  return idle_clock.CheckUpdate(500);
}
Exemple #2
0
void
DeviceBlackboard::tick()
{
  SetBasic().expire();

  // calculate fast data to complete aircraft state

  computer.Compute(SetBasic(), LastBasic(),
                   Calculated(), SettingsComputer());

  if (Basic().Time!= LastBasic().Time) {
    state_last = Basic();
  }
}
Exemple #3
0
/**
 * Process slow calculations. Called by the CalculationThread.
 */
void
GlideComputer::ProcessIdle(bool exhaustive)
{
  // Log GPS fixes for internal usage
  // (snail trail, stats, olc, ...)
  stats_computer.DoLogging(Basic(), LastBasic(), Calculated(),
                           GetComputerSettings().logger);

  task_computer.ProcessIdle(Basic(), SetCalculated(), GetComputerSettings(),
                            exhaustive);

  if (time_advanced())
    warning_computer.Update(GetComputerSettings(), Basic(), LastBasic(),
                            Calculated(), SetCalculated().airspace_warnings);
}
Exemple #4
0
/**
 * Logs GPS fixes for stats
 * @return True if valid fix (fix distance <= 200m), False otherwise
 */
bool
GlideComputerStats::DoLogging()
{
  /// @todo consider putting this sanity check inside Parser
  if (Distance(Basic().location, LastBasic().location) > fixed(200))
    // prevent bad fixes from being logged or added to OLC store
    return false;

  // log points more often in circling mode
  if (Calculated().circling)
    log_clock.set_dt(fixed(SettingsComputer().LoggerTimeStepCircling));
  else
    log_clock.set_dt(fixed(SettingsComputer().LoggerTimeStepCruise));

  if (FastLogNum) {
    log_clock.set_dt(fixed_one);
    FastLogNum--;
  }

  if (log_clock.check_advance(Basic().time) && logger != NULL)
      logger->LogPoint(Basic());

  if (Calculated().flight.flying &&
      stats_clock.check_advance(Basic().time)) {
    flightstats.AddAltitudeTerrain(Calculated().flight.flight_time,
                                   Calculated().terrain_altitude);
    flightstats.AddAltitude(Calculated().flight.flight_time,
                            Basic().NavAltitude);
    flightstats.AddTaskSpeed(Calculated().flight.flight_time,
                             Calculated().task_stats.get_pirker_speed());
  }

  return true;
}
Exemple #5
0
/**
 * Calculates location, altitude, average climb speed and
 * looks up the callsign of each target
 */
void
DeviceBlackboard::ProcessFLARM()
{
  const NMEA_INFO &basic = Basic();
  FLARM_STATE &flarm = SetBasic().flarm;
  const FLARM_STATE &last_flarm = LastBasic().flarm;

  // if (FLARM data is available)
  if (!flarm.available || flarm.traffic.empty())
    return;

  fixed FLARM_NorthingToLatitude(0);
  fixed FLARM_EastingToLongitude(0);

  if (basic.LocationAvailable) {
    // Precalculate relative east and north projection to lat/lon
    // for Location calculations of each target
    Angle delta_lat = Angle::degrees(fixed(0.01));
    Angle delta_lon = Angle::degrees(fixed(0.01));

    GeoPoint plat = basic.Location;
    plat.Latitude += delta_lat;
    GeoPoint plon = basic.Location;
    plon.Longitude += delta_lon;

    fixed dlat = Distance(basic.Location, plat);
    fixed dlon = Distance(basic.Location, plon);

    if (positive(fabs(dlat)) && positive(fabs(dlon))) {
      FLARM_NorthingToLatitude = delta_lat.value_degrees() / dlat;
      FLARM_EastingToLongitude = delta_lon.value_degrees() / dlon;
    }
  }

  // for each item in traffic
  for (unsigned i = 0; i < flarm.traffic.size(); i++) {
    FLARM_TRAFFIC &traffic = flarm.traffic[i];

    // if we don't know the target's name yet
    if (!traffic.HasName()) {
      // lookup the name of this target's id
      const TCHAR *fname = FlarmDetails::LookupCallsign(traffic.id);
      if (fname != NULL)
        traffic.name = fname;
    }

    // Calculate distance
    traffic.distance = hypot(traffic.relative_north, traffic.relative_east);

    // Calculate Location
    traffic.location_available = basic.LocationAvailable;
    if (traffic.location_available) {
      traffic.location.Latitude =
          Angle::degrees(traffic.relative_north * FLARM_NorthingToLatitude) +
          basic.Location.Latitude;

      traffic.location.Longitude =
          Angle::degrees(traffic.relative_east * FLARM_EastingToLongitude) +
          basic.Location.Longitude;
    }

    // Calculate absolute altitude
    traffic.altitude_available = basic.GPSAltitudeAvailable;
    if (traffic.altitude_available)
      traffic.altitude = traffic.relative_altitude + basic.GPSAltitude;

    // Calculate average climb rate
    traffic.climb_rate_avg30s_available = traffic.altitude_available;
    if (traffic.climb_rate_avg30s_available)
      traffic.climb_rate_avg30s =
        flarmCalculations.Average30s(traffic.id, basic.Time, traffic.altitude);

    // The following calculations are only relevant for targets
    // where information is missing
    if (traffic.track_received || traffic.turn_rate_received ||
        traffic.speed_received || traffic.climb_rate_received)
      continue;

    // Check if the target has been seen before in the last seconds
    const FLARM_TRAFFIC *last_traffic = last_flarm.FindTraffic(traffic.id);
    if (last_traffic == NULL || !last_traffic->valid)
      continue;

    // Calculate the time difference between now and the last contact
    fixed dt = traffic.valid.GetTimeDifference(last_traffic->valid);
    if (positive(dt)) {
      // Calculate the immediate climb rate
      if (!traffic.climb_rate_received)
        traffic.climb_rate =
          (traffic.relative_altitude - last_traffic->relative_altitude) / dt;
    } else {
      // Since the time difference is zero (or negative)
      // we can just copy the old values
      if (!traffic.climb_rate_received)
        traffic.climb_rate = last_traffic->climb_rate;
    }

    if (positive(dt) &&
        traffic.location_available &&
        last_traffic->location_available) {
      // Calculate the GeoVector between now and the last contact
      GeoVector vec = last_traffic->location.distance_bearing(traffic.location);

      if (!traffic.track_received)
        traffic.track = vec.Bearing;

      // Calculate the turn rate
      if (!traffic.turn_rate_received)
        traffic.turn_rate =
          (traffic.track - last_traffic->track).as_delta().value_degrees() / dt;

      // Calculate the speed [m/s]
      if (!traffic.speed_received)
        traffic.speed = vec.Distance / dt;
    } else {
      // Since the time difference is zero (or negative)
      // we can just copy the old values
      if (!traffic.track_received)
        traffic.track = last_traffic->track;

      if (!traffic.turn_rate_received)
        traffic.turn_rate = last_traffic->turn_rate;

      if (!traffic.speed_received)
        traffic.speed = last_traffic->speed;
    }
  }
}
 bool time_advanced() {
   return Basic().Time - LastBasic().Time > fixed_zero;
 }
 fixed time_delta() const {
   return Basic().time - LastBasic().time;
 }
 bool time_advanced() const {
   return Basic().HasTimeAdvancedSince(LastBasic());
 }
 bool time_advanced() {
   return (Basic().Time-LastBasic().Time>0);
 }