forked from upstream-mirrors/OpenTracks
Sensors: Fix excessive altitude gain by enforcing SAMPLING_PERIOD on internal barometer.
On some modern devices like Pixel 8 Pro, the internal pressure sensor ignores the requested sampling period in registerListener and sends data at high frequency (~50Hz). This floods the AltitudeChangeHandler with noise, causing absurdly high altitude gain (e.g., 38km for a flat run). This commit adds a manual throttle in BarometerInternal to strictly respect the SAMPLING_PERIOD (5s), allowing the exponential smoothing to work as intended.
This commit is contained in:
@@ -9,6 +9,8 @@ import android.util.Log;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
|
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
|
||||||
@@ -17,12 +19,14 @@ public class BarometerInternal implements Driver {
|
|||||||
|
|
||||||
private static final String TAG = BarometerInternal.class.getSimpleName();
|
private static final String TAG = BarometerInternal.class.getSimpleName();
|
||||||
|
|
||||||
private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5);
|
private static final Duration SAMPLING_PERIOD = Duration.ofSeconds(5);
|
||||||
|
|
||||||
private final DriverObserver<AtmosphericPressure> observer;
|
private final DriverObserver<AtmosphericPressure> observer;
|
||||||
|
|
||||||
private android.hardware.SensorManager sensorService;
|
private android.hardware.SensorManager sensorService;
|
||||||
|
|
||||||
|
private Instant lastEventTime = Instant.EPOCH;
|
||||||
|
|
||||||
private final SensorEventListener sensorEventListener = new SensorEventListener() {
|
private final SensorEventListener sensorEventListener = new SensorEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
@@ -31,6 +35,13 @@ public class BarometerInternal implements Driver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instant currentTime = Instant.now();
|
||||||
|
|
||||||
|
if (lastEventTime.plus(SAMPLING_PERIOD).isAfter(currentTime)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastEventTime = currentTime;
|
||||||
observer.onDataReceived(AtmosphericPressure.ofHPA(event.values[0]));
|
observer.onDataReceived(AtmosphericPressure.ofHPA(event.values[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +59,9 @@ public class BarometerInternal implements Driver {
|
|||||||
public void connect(Context context, Handler handler, String addressIgnored) {
|
public void connect(Context context, Handler handler, String addressIgnored) {
|
||||||
sensorService = (android.hardware.SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
sensorService = (android.hardware.SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
||||||
Sensor pressureSensor = sensorService.getDefaultSensor(Sensor.TYPE_PRESSURE);
|
Sensor pressureSensor = sensorService.getDefaultSensor(Sensor.TYPE_PRESSURE);
|
||||||
|
int samplingPeriodUs = (int) TimeUnit.MICROSECONDS.convert(SAMPLING_PERIOD);
|
||||||
|
|
||||||
if (pressureSensor != null && sensorService.registerListener(sensorEventListener, pressureSensor, SAMPLING_PERIOD, handler)) {
|
if (pressureSensor != null && sensorService.registerListener(sensorEventListener, pressureSensor, samplingPeriodUs, handler)) {
|
||||||
observer.onConnected(null, null);
|
observer.onConnected(null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user