Introduced AtmosphericPressure.

Part of #1424.
This commit is contained in:
Dennis Guse
2023-05-23 10:20:57 +02:00
parent 0395394e26
commit 4906d3f942
7 changed files with 103 additions and 46 deletions
@@ -0,0 +1,48 @@
package de.dennisguse.opentracks.data.models;
import java.util.Objects;
public class AtmosphericPressure {
public static AtmosphericPressure ofPA(float value_Pa) {
return new AtmosphericPressure(value_Pa * 100);
}
public static AtmosphericPressure ofHPA(float value_hPa) {
return new AtmosphericPressure(value_hPa);
}
private final float value;
private AtmosphericPressure(float value) {
this.value = value;
}
public float getPA() {
return value * 100;
}
public float getHPA() {
return value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AtmosphericPressure that = (AtmosphericPressure) o;
return Float.compare(that.value, value) == 0;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "AtmosphericPressure{" +
"value=" + value +
'}';
}
}
@@ -14,6 +14,7 @@ import androidx.annotation.VisibleForTesting;
import java.util.concurrent.TimeUnit;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.data.models.TrackPoint;
/**
@@ -25,9 +26,9 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
private boolean isConnected = false;
private float lastAcceptedPressureValue_hPa;
private AtmosphericPressure lastAcceptedSensorValue;
private float lastSeenSensorValue_hPa;
private AtmosphericPressure lastSeenSensorValue;
private Float altitudeGain_m;
private Float altitudeLoss_m;
@@ -43,7 +44,7 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
isConnected = sensorManager.registerListener(this, pressureSensor, (int) TimeUnit.SECONDS.toMicros(5), handler);
}
lastAcceptedPressureValue_hPa = Float.NaN;
lastAcceptedSensorValue = null;
reset();
}
@@ -116,30 +117,30 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
Log.w(TAG, "Not connected to sensor, cannot process data.");
return;
}
onSensorValueChanged(event.values[0]);
onSensorValueChanged(AtmosphericPressure.ofHPA(event.values[0]));
}
@VisibleForTesting
void onSensorValueChanged(float value_hPa) {
if (Float.isNaN(lastAcceptedPressureValue_hPa)) {
lastAcceptedPressureValue_hPa = value_hPa;
lastSeenSensorValue_hPa = value_hPa;
void onSensorValueChanged(AtmosphericPressure currentSensorValue) {
if (lastAcceptedSensorValue == null) {
lastAcceptedSensorValue = currentSensorValue;
lastSeenSensorValue = currentSensorValue;
return;
}
altitudeGain_m = altitudeGain_m != null ? altitudeGain_m : 0;
altitudeLoss_m = altitudeLoss_m != null ? altitudeLoss_m : 0;
PressureSensorUtils.AltitudeChange altitudeChange = PressureSensorUtils.computeChangesWithSmoothing_m(lastAcceptedPressureValue_hPa, lastSeenSensorValue_hPa, value_hPa);
PressureSensorUtils.AltitudeChange altitudeChange = PressureSensorUtils.computeChangesWithSmoothing_m(lastAcceptedSensorValue, lastSeenSensorValue, currentSensorValue);
if (altitudeChange != null) {
altitudeGain_m += altitudeChange.getAltitudeGain_m();
altitudeLoss_m += altitudeChange.getAltitudeLoss_m();
lastAcceptedPressureValue_hPa = altitudeChange.getCurrentSensorValue_hPa();
lastAcceptedSensorValue = altitudeChange.getCurrentSensorValue();
}
lastSeenSensorValue_hPa = value_hPa;
lastSeenSensorValue = currentSensorValue;
Log.v(TAG, "altitude gain: " + altitudeGain_m + ", altitude loss: " + altitudeLoss_m);
}
@@ -28,6 +28,7 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.data.models.BatteryLevel;
import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance;
@@ -69,8 +70,9 @@ public class BluetoothUtils {
))
);
public static final ServiceMeasurementUUID PRESSURE = new ServiceMeasurementUUID(
new UUID(0x181A00001000L, 0x800000805f9b34fbL),
private static final UUID ENVIRONMENTAL_SENSING_SERVICE = new UUID(0x181A00001000L, 0x800000805f9b34fbL);
public static final ServiceMeasurementUUID BAROMETRIC_PRESSURE = new ServiceMeasurementUUID(
ENVIRONMENTAL_SENSING_SERVICE,
new UUID(0x2A6D00001000L, 0x800000805f9b34fbL)
);
@@ -142,15 +144,15 @@ public class BluetoothUtils {
return null;
}
public static Integer parsePressure(BluetoothGattCharacteristic characteristic) {
public static AtmosphericPressure parseEnvironmentalSensing(BluetoothGattCharacteristic characteristic) {
byte[] raw = characteristic.getValue();
if (raw.length < 4) {
return null;
}
Float fPressure = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT, 0);
return Math.round(fPressure);
Integer pressure = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0);
return AtmosphericPressure.ofPA(pressure / 10f);
}
public static SensorDataCyclingPower.Data parseCyclingPower(String address, String sensorName, BluetoothGattCharacteristic characteristic) {
@@ -4,6 +4,8 @@ import android.hardware.SensorManager;
import androidx.annotation.VisibleForTesting;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
public class PressureSensorUtils {
//Everything above is considered a meaningful change in altitude.
@@ -18,17 +20,17 @@ public class PressureSensorUtils {
public static class AltitudeChange {
private final float currentSensorValue_hPa;
private final AtmosphericPressure currentSensorValue;
private final float altitudeChange_m;
public AltitudeChange(float currentSensorValue_hPa, float altitudeChange_m) {
this.currentSensorValue_hPa = currentSensorValue_hPa;
public AltitudeChange(AtmosphericPressure currentSensorValue, float altitudeChange_m) {
this.currentSensorValue = currentSensorValue;
this.altitudeChange_m = altitudeChange_m;
}
public float getCurrentSensorValue_hPa() {
return currentSensorValue_hPa;
public AtmosphericPressure getCurrentSensorValue() {
return currentSensorValue;
}
public float getAltitudeChange_m() {
@@ -47,16 +49,16 @@ public class PressureSensorUtils {
/**
* Applies exponential smoothing to sensor value before computation.
*/
public static AltitudeChange computeChangesWithSmoothing_m(float lastAcceptedSensorValue_hPa, float lastSeenSensorValue_hPa, float currentSensorValue_hPa) {
float nextSensorValue_hPa = EXPONENTIAL_SMOOTHING * currentSensorValue_hPa + (1 - EXPONENTIAL_SMOOTHING) * lastSeenSensorValue_hPa;
public static AltitudeChange computeChangesWithSmoothing_m(AtmosphericPressure lastAcceptedSensorValue, AtmosphericPressure lastSeenSensorValue, AtmosphericPressure currentSensorValue) {
AtmosphericPressure nextSensorValue = AtmosphericPressure.ofHPA(EXPONENTIAL_SMOOTHING * currentSensorValue.getHPA() + (1 - EXPONENTIAL_SMOOTHING) * lastSeenSensorValue.getHPA());
return computeChanges(lastAcceptedSensorValue_hPa, nextSensorValue_hPa);
return computeChanges(lastAcceptedSensorValue, nextSensorValue);
}
@VisibleForTesting
public static AltitudeChange computeChanges(float lastAcceptedSensorValue_hPa, float currentSensorValue_hPa) {
float lastSensorValue_m = SensorManager.getAltitude(p0, lastAcceptedSensorValue_hPa);
float currentSensorValue_m = SensorManager.getAltitude(p0, currentSensorValue_hPa);
public static AltitudeChange computeChanges(AtmosphericPressure lastAcceptedSensorValue, AtmosphericPressure currentSensorValue) {
float lastSensorValue_m = SensorManager.getAltitude(p0, lastAcceptedSensorValue.getHPA());
float currentSensorValue_m = SensorManager.getAltitude(p0, currentSensorValue.getHPA());
float altitudeChange_m = currentSensorValue_m - lastSensorValue_m;
if (Math.abs(altitudeChange_m) < ALTITUDE_CHANGE_DIFF_M) {
@@ -64,7 +66,7 @@ public class PressureSensorUtils {
}
// Limit altitudeC change by ALTITUDE_CHANGE_DIFF and computes pressure value accordingly.
AltitudeChange altitudeChange = new AltitudeChange(currentSensorValue_hPa, altitudeChange_m);
AltitudeChange altitudeChange = new AltitudeChange(currentSensorValue, altitudeChange_m);
if (altitudeChange.getAltitudeChange_m() > 0) {
return new AltitudeChange(getBarometricPressure(lastSensorValue_m + ALTITUDE_CHANGE_DIFF_M), ALTITUDE_CHANGE_DIFF_M);
} else {
@@ -78,7 +80,7 @@ public class PressureSensorUtils {
* {\color{White} p(h)} = p_0 \cdot \left( 1 - \frac{0{,}0065 \frac{\mathrm K}{\mathrm m} \cdot h}{T_0\ } \right)^{5{,}255}
*/
@VisibleForTesting
public static float getBarometricPressure(float altitude_m) {
return (float) (p0 * Math.pow(1.0 - 0.0065 * altitude_m / 288.15, 5.255f));
public static AtmosphericPressure getBarometricPressure(float altitude_m) {
return AtmosphericPressure.ofHPA((float) (p0 * Math.pow(1.0 - 0.0065 * altitude_m / 288.15, 5.255f)));
}
}