forked from upstream-mirrors/OpenTracks
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user