//
// 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;
}
}
}