Example #1
0
bool
DemoReplayGlue::Update(NMEAInfo &data, fixed time_scale)
{
  if (!UpdateTime())
    return true;

  fixed floor_alt = fixed_300;
  if (device_blackboard->Calculated().terrain_valid) {
    floor_alt += device_blackboard->Calculated().terrain_altitude;
  }

  bool retval;

  {
    ProtectedTaskManager::ExclusiveLease protected_task_manager(*task_manager);
    TaskAccessor ta(protected_task_manager, floor_alt);
    retval = DemoReplay::Update(time_scale, ta);
  }

  const AircraftState &s = aircraft.GetState();

  data.clock = s.time;
  data.alive.Update(data.clock);
  data.ProvideTime(s.time);
  data.location = s.location;
  data.location_available.Update(data.clock);
  data.ground_speed = s.ground_speed;
  data.ground_speed_available.Update(data.clock);
  data.track = s.track;
  data.track_available.Update(data.clock);
  data.gps_altitude = s.altitude;
  data.gps_altitude_available.Update(data.clock);
  data.ProvidePressureAltitude(s.altitude);
  data.ProvideBaroAltitudeTrue(s.altitude);
  data.gps.real = false;
  data.gps.replay = true;
  data.gps.simulator = false;

  return retval;
}
Example #2
0
bool
Replay::Update()
{
  if (replay == nullptr)
    return false;

  if (time_scale <= 0) {
    /* replay is paused */
    /* to avoid a big fast-forward with the next
       PeriodClock::ElapsedUpdate() call below after unpausing, update
       the clock each time we're called while paused */
    clock.Update();
    return true;
  }

  const double old_virtual_time = virtual_time;

  if (virtual_time >= 0) {
    /* update the virtual time */
    assert(clock.IsDefined());

    if (fast_forward < 0) {
      virtual_time += clock.ElapsedUpdate() * time_scale / 1000;
    } else {
      clock.Update();

      virtual_time += 1;
      if (virtual_time >= fast_forward)
        fast_forward = -1;
    }
  } else {
    /* if we ever received a valid time from the AbstractReplay, then
       virtual_time must be initialised */
    assert(!next_data.time_available);
  }

  if (cli == nullptr || fast_forward >= 0) {
    if (next_data.time_available && virtual_time < next_data.time)
      /* still not time to use next_data */
      return true;

    {
      std::lock_guard<Mutex> lock(device_blackboard->mutex);
      device_blackboard->SetReplayState() = next_data;
      device_blackboard->ScheduleMerge();
    }

    while (true) {
      if (!replay->Update(next_data)) {
        Stop();
        return false;
      }

      assert(!next_data.gps.real);

      if (next_data.time_available) {
        if (virtual_time < 0) {
          virtual_time = next_data.time;
          if (fast_forward >= 0)
            fast_forward += virtual_time;
          clock.Update();
          break;
        }

        if (next_data.time >= virtual_time)
          break;

        if (next_data.time < old_virtual_time) {
          /* time warp; that can happen on midnight wraparound during
             NMEA replay */
          virtual_time = next_data.time;
          break;
        }
      }
    }
  } else {
    while (cli->NeedData(virtual_time)) {
      if (!replay->Update(next_data)) {
        Stop();
        return false;
      }

      assert(!next_data.gps.real);

      if (next_data.time_available)
        cli->Update(next_data.time, next_data.location,
                    next_data.gps_altitude,
                    next_data.pressure_altitude);
    }

    if (virtual_time < 0) {
      virtual_time = cli->GetMaxTime();
      if (fast_forward >= 0)
        fast_forward += virtual_time;
      clock.Update();
    }

    const CatmullRomInterpolator::Record r = cli->Interpolate(virtual_time);
    const GeoVector v = cli->GetVector(virtual_time);

    NMEAInfo data = next_data;
    data.clock = virtual_time;
    data.alive.Update(data.clock);
    data.ProvideTime(virtual_time);
    data.location = r.location;
    data.location_available.Update(data.clock);
    data.ground_speed = v.distance;
    data.ground_speed_available.Update(data.clock);
    data.track = v.bearing;
    data.track_available.Update(data.clock);
    data.gps_altitude = r.gps_altitude;
    data.gps_altitude_available.Update(data.clock);
    data.ProvidePressureAltitude(r.baro_altitude);
    data.ProvideBaroAltitudeTrue(r.baro_altitude);

    {
      std::lock_guard<Mutex> lock(device_blackboard->mutex);
      device_blackboard->SetReplayState() = data;
      device_blackboard->ScheduleMerge();
    }
  }

  return true;
}
Example #3
0
bool
IgcReplay::Update(NMEAInfo &basic)
{
  IGCFix fix;

  while (true) {
    if (!ReadPoint(fix, basic))
      return false;

    if (fix.time.IsPlausible())
      break;
  }

  basic.clock = fixed(fix.time.GetSecondOfDay());
  basic.alive.Update(basic.clock);
  basic.ProvideTime(basic.clock);
  basic.location = fix.location;
  basic.location_available.Update(basic.clock);

  if (fix.gps_altitude != 0) {
    basic.gps_altitude = fixed(fix.gps_altitude);
    basic.gps_altitude_available.Update(basic.clock);
  } else
    basic.gps_altitude_available.Clear();

  if (fix.pressure_altitude != 0) {
    basic.ProvidePressureAltitude(fixed(fix.pressure_altitude));
    basic.ProvideBaroAltitudeTrue(fixed(fix.pressure_altitude));
  } else {
    basic.pressure_altitude_available.Clear();
    basic.baro_altitude_available.Clear();
  }

  if (fix.enl >= 0) {
    basic.engine_noise_level = fix.enl;
    basic.engine_noise_level_available.Update(basic.clock);
  } else
    basic.engine_noise_level_available.Clear();

  if (fix.trt >= 0) {
    basic.track = Angle::Degrees(fixed(fix.trt));
    basic.track_available.Update(basic.clock);
  } else
    basic.track_available.Clear();

  if (fix.gsp >= 0) {
    basic.ground_speed = Units::ToSysUnit(fixed(fix.gsp),
                                          Unit::KILOMETER_PER_HOUR);
    basic.ground_speed_available.Update(basic.clock);
  } else
    basic.ground_speed_available.Clear();

  if (fix.ias >= 0) {
    fixed ias = Units::ToSysUnit(fixed(fix.ias), Unit::KILOMETER_PER_HOUR);
    if (fix.tas >= 0)
      basic.ProvideBothAirspeeds(ias,
                                 Units::ToSysUnit(fixed(fix.tas),
                                                  Unit::KILOMETER_PER_HOUR));
    else
      basic.ProvideIndicatedAirspeedWithAltitude(ias, basic.pressure_altitude);
  } else if (fix.tas >= 0)
    basic.ProvideTrueAirspeed(Units::ToSysUnit(fixed(fix.tas),
                                               Unit::KILOMETER_PER_HOUR));

  if (fix.siu >= 0) {
    basic.gps.satellites_used = fix.siu;
    basic.gps.satellites_used_available.Update(basic.clock);
  }

  basic.gps.real = false;
  basic.gps.replay = true;
  basic.gps.simulator = false;

  return true;
}