Cadence set to 0 when connected but user is not pedaling. Fixes #931.

Speed set to 0 when connected but last value is outdated. Fixes #930.
Bug: overflow when reset sensors (cadence and speed). Fixes #833.
Moving time stops when is not moving (the last track point is not moving) and restarts when last track point is moving.
This commit is contained in:
Román Martínez
2021-09-06 21:42:08 +02:00
parent d69a726e0e
commit d99fb5ea47
9 changed files with 110 additions and 14 deletions
@@ -50,8 +50,14 @@ public abstract class SensorData<T> {
return value != null;
}
@NonNull
protected abstract T getNoneValue();
public T getValue() {
return value;
if (isRecent()) {
return value;
}
return getNoneValue();
}
/**
@@ -63,7 +69,7 @@ public abstract class SensorData<T> {
/**
* Is the data recent considering the current time.
*/
public boolean isRecent() {
private boolean isRecent() {
return Instant.now()
.isBefore(time.plus(BluetoothRemoteSensorManager.MAX_SENSOR_DATE_SET_AGE_MS));
}
@@ -59,17 +59,30 @@ public final class SensorDataCycling {
return crankRevolutionsTime;
}
@NonNull
@Override
protected Float getNoneValue() {
return 0f;
}
public void compute(Cadence previous) {
if (hasData() && previous != null && previous.hasData()) {
float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
if (timeDiff_ms <= 0) {
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
value = null;
} else {
long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX);
float cadence_ms = crankDiff / timeDiff_ms;
value = (float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN);
return;
}
// TODO We have to treat with overflow according to the documentation: read https://github.com/OpenTracksApp/OpenTracks/pull/953#discussion_r711625268
if (crankRevolutionsCount < previous.crankRevolutionsCount) {
Log.e(TAG, "Crank revolutions count difference is invalid: cannot compute cadence.");
return;
}
long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX);
float cadence_ms = crankDiff / timeDiff_ms;
value = (float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN);
}
}
@@ -121,6 +134,16 @@ public final class SensorDataCycling {
return wheelRevolutionsTime;
}
@NonNull
@Override
protected Data getNoneValue() {
if (value != null) {
return new Data(value.distance, value.distanceOverall, Speed.zero());
} else {
return new Data(Distance.of(0), Distance.of(0), Speed.zero());
}
}
public void compute(DistanceSpeed previous, Distance wheelCircumference) {
if (hasData() && previous != null && previous.hasData()) {
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
@@ -131,6 +154,10 @@ public final class SensorDataCycling {
return;
}
if (wheelRevolutionsCount < previous.wheelRevolutionsCount) {
Log.e(TAG, "Wheel revolutions count difference is invalid: cannot compute speed.");
return;
}
long wheelDiff = UintUtils.diff(wheelRevolutionsCount, previous.wheelRevolutionsCount, UintUtils.UINT32_MAX);
Distance distance = wheelCircumference.multipliedBy(wheelDiff);
@@ -217,6 +244,12 @@ public final class SensorDataCycling {
public DistanceSpeed getDistanceSpeed() {
return this.value != null ? this.value.second : null;
}
@NonNull
@Override
protected Pair<Cadence, DistanceSpeed> getNoneValue() {
return new Pair<>(null, null);
}
}
}
@@ -18,4 +18,10 @@ public class SensorDataCyclingPower extends SensorData<Float> {
public String toString() {
return super.toString() + " power=" + value;
}
@NonNull
@Override
protected Float getNoneValue() {
return 0f;
}
}
@@ -18,4 +18,10 @@ public class SensorDataHeartRate extends SensorData<Float> {
public String toString() {
return super.toString() + " heart=" + value;
}
@NonNull
@Override
protected Float getNoneValue() {
return 0f;
}
}
@@ -53,6 +53,16 @@ public final class SensorDataRunning extends SensorData<SensorDataRunning.Data>
return totalDistance;
}
@NonNull
@Override
protected Data getNoneValue() {
if (value != null) {
return new Data(Speed.zero(), 0f, ((Data) value).distance);
} else {
return new Data(Speed.zero(), 0f, Distance.of(0));
}
}
public void compute(SensorDataRunning previous) {
Distance overallDistance = null;
if (hasTotalDistance() && previous != null && previous.hasTotalDistance()) {