content: //
  // Source code recreated from a .class file by IntelliJ IDEA
  // (powered by Fernflower decompiler)
  //
  
  package com.google.vrtoolkit.cardboard.sensors.internal;
  
  public class GyroscopeBiasEstimator {
      private static final float ACCEL_LOWPASS_FREQ = 1.0F;
      private static final float GYRO_LOWPASS_FREQ = 10.0F;
      private static final float GYRO_BIAS_LOWPASS_FREQ = 0.15F;
      private static final int NUM_GYRO_BIAS_SAMPLES_THRESHOLD = 30;
      private static final int NUM_GYRO_BIAS_SAMPLES_INITIAL_SMOOTHING = 100;
      private LowPassFilter accelLowPass;
      private LowPassFilter gyroLowPass;
      private LowPassFilter gyroBiasLowPass;
      private static final float ACCEL_DIFF_STATIC_THRESHOLD = 0.5F;
      private static final float GYRO_DIFF_STATIC_THRESHOLD = 0.008F;
      private Vector3d smoothedGyroDiff;
      private Vector3d smoothedAccelDiff;
      private static final float GYRO_FOR_BIAS_THRESHOLD = 0.35F;
      private static final int IS_STATIC_NUM_FRAMES_THRESHOLD = 10;
      private GyroscopeBiasEstimator.IsStaticCounter isAccelStatic;
      private GyroscopeBiasEstimator.IsStaticCounter isGyroStatic;
  
      public GyroscopeBiasEstimator() {
          this.reset();
      }
  
      public void reset() {
          this.smoothedGyroDiff = new Vector3d();
          this.smoothedAccelDiff = new Vector3d();
          this.accelLowPass = new LowPassFilter(1.0D);
          this.gyroLowPass = new LowPassFilter(10.0D);
          this.gyroBiasLowPass = new LowPassFilter(0.15000000596046448D);
          this.isAccelStatic = new GyroscopeBiasEstimator.IsStaticCounter(10);
          this.isGyroStatic = new GyroscopeBiasEstimator.IsStaticCounter(10);
      }
  
      public void processGyroscope(Vector3d gyro, long sensorTimestampNs) {
          this.gyroLowPass.addSample(gyro, sensorTimestampNs);
          Vector3d.sub(gyro, this.gyroLowPass.getFilteredData(), this.smoothedGyroDiff);
          this.isGyroStatic.appendFrame(this.smoothedGyroDiff.length() < 0.00800000037997961D);
          if(this.isGyroStatic.isRecentlyStatic() && this.isAccelStatic.isRecentlyStatic()) {
              this.updateGyroBias(gyro, sensorTimestampNs);
          }
  
      }
  
      public void processAccelerometer(Vector3d accel, long sensorTimestampNs) {
          this.accelLowPass.addSample(accel, sensorTimestampNs);
          Vector3d.sub(accel, this.accelLowPass.getFilteredData(), this.smoothedAccelDiff);
          this.isAccelStatic.appendFrame(this.smoothedAccelDiff.length() < 0.5D);
      }
  
      public void getGyroBias(Vector3d result) {
          if(this.gyroBiasLowPass.getNumSamples() < 30) {
              result.setZero();
          } else {
              result.set(this.gyroBiasLowPass.getFilteredData());
              double rampUpRatio = Math.min(1.0D, (double)(this.gyroBiasLowPass.getNumSamples() - 30) / 100.0D);
              result.scale(rampUpRatio);
          }
  
      }
  
      private void updateGyroBias(Vector3d gyro, long sensorTimestampNs) {
          if(gyro.length() < 0.3499999940395355D) {
              double updateWeight = Math.max(0.0D, 1.0D - gyro.length() / 0.3499999940395355D);
              updateWeight *= updateWeight;
              this.gyroBiasLowPass.addWeightedSample(this.gyroLowPass.getFilteredData(), sensorTimestampNs, updateWeight);
          }
      }
  
      private static class IsStaticCounter {
          private final int minStaticFrames;
          private int consecutiveIsStatic;
  
          IsStaticCounter(int minStaticFrames) {
              this.minStaticFrames = minStaticFrames;
          }
  
          void appendFrame(boolean isStatic) {
              if(!isStatic) {
                  this.consecutiveIsStatic = 0;
              } else {
                  ++this.consecutiveIsStatic;
              }
  
          }
  
          boolean isRecentlyStatic() {
              return this.consecutiveIsStatic >= this.minStaticFrames;
          }
      }
  }
  