Exemplo n.º 1
0
void
I2CbaroDevice::onI2CbaroValues(unsigned sensor, AtmosphericPressure pressure)
{
  ScopeLock protect(device_blackboard->mutex);
  NMEAInfo &basic = device_blackboard->SetRealState(index);
  basic.UpdateClock();
  basic.alive.Update(basic.clock);

  if (pressure.IsPlausible()) {
    double param;

    // Set filter properties depending on sensor type
    if (sensor == 85 && press_use == DeviceConfig::PressureUse::STATIC_WITH_VARIO) {
       if (static_p == 0) kalman_filter.SetAccelerationVariance(0.0075);
       param = 0.05;
    } else {
       param = 0.5;
    }

    kalman_filter.Update(pressure.GetHectoPascal(), param);

    switch (press_use) {
      case DeviceConfig::PressureUse::NONE:
        break;

      case DeviceConfig::PressureUse::STATIC_ONLY:
        static_p = kalman_filter.GetXAbs();
        basic.ProvideStaticPressure(AtmosphericPressure::HectoPascal(static_p));
        break;

      case DeviceConfig::PressureUse::STATIC_WITH_VARIO:
        static_p = pressure.GetHectoPascal();
        basic.ProvideNoncompVario(ComputeNoncompVario(kalman_filter.GetXAbs(), kalman_filter.GetXVel()));
        basic.ProvideStaticPressure(AtmosphericPressure::HectoPascal(static_p));
        break;

      case DeviceConfig::PressureUse::TEK_PRESSURE:
        basic.ProvideTotalEnergyVario(ComputeNoncompVario(kalman_filter.GetXAbs(),
                                                    kalman_filter.GetXVel()));
        break;

      case DeviceConfig::PressureUse::PITOT:
        if (static_p != 0) {
          auto dyn = pressure.GetHectoPascal() - static_p - pitot_offset;
          if (dyn < 0.31)
            // suppress speeds below ~25 km/h
            dyn = 0;
          basic.ProvideDynamicPressure(AtmosphericPressure::HectoPascal(dyn));
        }
        break;

      case DeviceConfig::PressureUse::PITOT_ZERO:
        pitot_offset = kalman_filter.GetXAbs() - static_p;
        basic.ProvideSensorCalibration(1, pitot_offset);
        break;
    }
  }

  device_blackboard->ScheduleMerge();
}
Exemplo n.º 2
0
bool
BlueFlyDevice::ParsePRS(const char *content, NMEAInfo &info)
{
  // e.g. PRS 17CBA

  char *endptr;
  long value = strtol(content, &endptr, 16);
  if (endptr != content) {
    AtmosphericPressure pressure = AtmosphericPressure::Pascal(fixed(value));

    kalman_filter.Update(pressure.GetHectoPascal(), fixed(0.25), fixed(0.02));

    info.ProvideNoncompVario(ComputeNoncompVario(kalman_filter.GetXAbs(),
                                                 kalman_filter.GetXVel()));
    info.ProvideStaticPressure(AtmosphericPressure::HectoPascal(kalman_filter.GetXAbs()));
  }

  return true;
}
Exemplo n.º 3
0
void
BMP085Device::onBMP085Values(fixed temperature,
                             AtmosphericPressure pressure)
{
  ScopeLock protect(device_blackboard->mutex);
  NMEAInfo &basic = device_blackboard->SetRealState(index);
  basic.UpdateClock();
  basic.alive.Update(basic.clock);

#ifdef USE_TEMPERATURE
  basic.temperature = temperature;
  basic.temperature_available = true;
#endif

  kalman_filter.Update(pressure.GetHectoPascal(), fixed(0.05));

  basic.ProvideNoncompVario(ComputeNoncompVario(kalman_filter.GetXAbs(),
                                                kalman_filter.GetXVel()));
  basic.ProvideStaticPressure(AtmosphericPressure::HectoPascal(kalman_filter.GetXAbs()));

  device_blackboard->ScheduleMerge();
}
Exemplo n.º 4
0
gcc_visibility_default
JNIEXPORT void JNICALL
Java_org_xcsoar_NonGPSSensors_setBarometricPressure(
    JNIEnv* env, jobject obj, jfloat pressure, jfloat sensor_noise_variance) {
  /* We use a Kalman filter to smooth Android device pressure sensor
     noise.  The filter requires two parameters: the first is the
     variance of the distribution of second derivatives of pressure
     values that we expect to see in flight, and the second is the
     maximum time between pressure sensor updates in seconds before
     the filter gives up on smoothing and uses the raw value.

     The pressure acceleration variance used here is actually wider
     than the maximum likelihood variance observed in the data: it
     turns out that the distribution is more heavy-tailed than a
     normal distribution, probably because glider pilots usually
     experience fairly constant pressure change most of the time. */
  static constexpr fixed KF_VAR_ACCEL(0.0075);
  static constexpr fixed KF_MAX_DT(60);

  // XXX this shouldn't be a global variable
  static SelfTimingKalmanFilter1d kalman_filter(KF_MAX_DT, KF_VAR_ACCEL);

  const unsigned int index = getDeviceIndex(env, obj);
  ScopeLock protect(device_blackboard->mutex);

  /* Kalman filter updates are also protected by the blackboard
     mutex. These should not take long; we won't hog the mutex
     unduly. */
  kalman_filter.Update(fixed(pressure), fixed(sensor_noise_variance));

  NMEAInfo &basic = device_blackboard->SetRealState(index);
  basic.ProvideNoncompVario(ComputeNoncompVario(kalman_filter.GetXAbs(),
                                                kalman_filter.GetXVel()));
  basic.ProvideStaticPressure(
      AtmosphericPressure::HectoPascal(kalman_filter.GetXAbs()));
  device_blackboard->ScheduleMerge();
}
Exemplo n.º 5
0
void
I2CbaroDevice::onI2CbaroValues(unsigned sensor, AtmosphericPressure pressure)
{
  ScopeLock protect(device_blackboard->mutex);
  NMEAInfo &basic = device_blackboard->SetRealState(index);
  basic.UpdateClock();
  basic.alive.Update(basic.clock);

  if (pressure.IsPlausible()) {
    fixed param;

    // Set filter properties depending on sensor type
    if (sensor == 85 && press_use == DeviceConfig::PressureUse::STATIC_WITH_VARIO) {
       if (static_p == fixed(0)) kalman_filter.SetAccelerationVariance(fixed(0.0075));
       param = fixed(0.05);
    } else {
       param = fixed(0.5);
    }

    fixed p = pressure.GetHectoPascal();

#if 0
static FILE* fp;
static int c;
if (c == 0) {
  char path[MAX_PATH];
  LocalPath(path, _T("bmp085.trace"));
  fp = fopen(path, "w");
}
if (fp) {
  fprintf(fp, "%f,\n", p);
  if (c == 3000) {
    fclose(fp);
    fp = NULL;
  }
  c++;
}
#endif

    kalman_filter.Update(p, param);

    switch (press_use) {
      case DeviceConfig::PressureUse::NONE:
        break;

      case DeviceConfig::PressureUse::STATIC_ONLY:
        static_p = kalman_filter.GetXAbs();
        basic.ProvideStaticPressure(AtmosphericPressure::HectoPascal(static_p));
        break;

      case DeviceConfig::PressureUse::STATIC_WITH_VARIO:
        static_p = pressure.GetHectoPascal();
        basic.ProvideNoncompVario(ComputeNoncompVario(kalman_filter.GetXAbs(), kalman_filter.GetXVel()));
        basic.ProvideStaticPressure(AtmosphericPressure::HectoPascal(static_p));
        break;

      case DeviceConfig::PressureUse::TEK_PRESSURE:
        basic.ProvideTotalEnergyVario(ComputeNoncompVario(kalman_filter.GetXAbs(),
                                                    kalman_filter.GetXVel()));
        break;

      case DeviceConfig::PressureUse::PITOT:
        if (static_p != fixed(0))
        {
          fixed dyn = pressure.GetHectoPascal() - static_p - pitot_offset;
          if (dyn < fixed(0.31)) dyn = fixed(0);      // suppress speeds below ~25 km/h
          basic.ProvideDynamicPressure(AtmosphericPressure::HectoPascal(dyn));
        }
        break;

      case DeviceConfig::PressureUse::PITOT_ZERO:
        pitot_offset = kalman_filter.GetXAbs() - static_p;
        basic.ProvideSensorCalibration(fixed (1), pitot_offset);
        break;
    }
  }

  device_blackboard->ScheduleMerge();
}