Bugfix: Cadence/Speed computation incorrectly truncated time to long instead of float.

This commit is contained in:
Dennis Guse
2020-05-10 16:36:26 +02:00
parent e3a8143d58
commit e55924dae3
4 changed files with 45 additions and 14 deletions
@@ -12,7 +12,7 @@ import de.dennisguse.opentracks.util.UintUtils;
public class SensorDataCyclingTest {
@Test
public void compute_cadence() {
public void compute_cadence_1() {
// given
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024); // 1s
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 2048); // 2s
@@ -24,6 +24,19 @@ public class SensorDataCyclingTest {
Assert.assertEquals(60, current.getCadence_rpm(), 0.01);
}
@Test
public void compute_cadence_2() {
// given
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 6184);
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 8016);
// when
current.compute(previous);
// then
Assert.assertEquals(33.53, current.getCadence_rpm(), 0.01);
}
@Test
public void compute_cadence_sameCount() {
// given
@@ -77,6 +90,19 @@ public class SensorDataCyclingTest {
Assert.assertEquals(60, current.getCadence_rpm(), 0.01);
}
@Test
public void compute_speed() {
// given
SensorDataCycling.Speed previous = new SensorDataCycling.Speed("sensorAddress", "sensorName", 1, 6184);
SensorDataCycling.Speed current = new SensorDataCycling.Speed("sensorAddress", "sensorName", 2, 8016);
// when
current.compute(previous, 2150);
// then
Assert.assertEquals(1.20, current.getSpeed_mps(), 0.01);
}
@Test
public void compute_speed_rollOverCount() {
// given
@@ -64,13 +64,13 @@ public final class SensorDataCycling {
public void compute(Cadence previous) {
if (hasData() && previous != null && previous.hasData()) {
long timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024 * UnitConversions.S_TO_MS;
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.");
cadence_rpm = INVALID_VALUE_FLOAT;
} else {
long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX);
float cadence_ms = crankDiff / (float) timeDiff_ms;
float cadence_ms = crankDiff / timeDiff_ms;
cadence_rpm = (float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN);
}
}
@@ -79,7 +79,7 @@ public final class SensorDataCycling {
@NonNull
@Override
public String toString() {
return "cadence=" + getCadence_rpm() + "_" + getCrankRevolutionsTime();
return "cadence=" + getCadence_rpm() + " time=" + getCrankRevolutionsTime() + " count=" + getCrankRevolutionsCount();
}
@Override
@@ -125,7 +125,7 @@ public final class SensorDataCycling {
public void compute(Speed previous, int wheel_circumference_mm) {
if (hasData() && previous != null && previous.hasData()) {
long timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024 * UnitConversions.S_TO_MS;
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
if (timeDiff_ms <= 0) {
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
speed_mps = INVALID_VALUE_FLOAT;
@@ -140,7 +140,7 @@ public final class SensorDataCycling {
@NonNull
@Override
public String toString() {
return "speed=" + getSpeed_mps() + "_" + getWheelRevolutionsTime();
return "speed=" + getSpeed_mps() + " time=" + getWheelRevolutionsTime() + " count=" + getWheelRevolutionsCount();
}
@Override
@@ -32,11 +32,11 @@ import de.dennisguse.opentracks.util.UnitConversions;
/**
* Bluetooth LE sensor manager: manages connections to Bluetooth LE sensors.
*
* <p>
* Note: should only be instantiated once.
*
* <p>
* TODO: listen for Bluetooth enabled/disabled events.
*
* <p>
* TODO: In case, a cycling (Cadence and Speed) sensor reports both values, testing is required.
* We establish two GATT separate GATT connections (as if two different sensors were used).
* However, it is not clear if this is allowed.
@@ -151,18 +151,23 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
@Override
public synchronized void onChanged(SensorData sensorData) {
if (sensorData instanceof SensorDataCycling.Cadence) {
if (sensorData.equals(sensorDataSet.getCyclingCadence())) {
SensorDataCycling.Cadence previous = sensorDataSet.getCyclingCadence();
Log.d(TAG, "previous " + previous + "; current" + sensorData);
if (sensorData.equals(previous)) {
Log.d(TAG, "onChanged: cadence data repeated.");
return;
}
((SensorDataCycling.Cadence) sensorData).compute(sensorDataSet.getCyclingCadence());
((SensorDataCycling.Cadence) sensorData).compute(previous);
}
if (sensorData instanceof SensorDataCycling.Speed) {
if (sensorData.equals(sensorDataSet.getCyclingSpeed())) {
SensorDataCycling.Speed previous = sensorDataSet.getCyclingSpeed();
Log.d(TAG, "previous " + previous + "; current" + sensorData);
if (sensorData.equals(previous)) {
Log.d(TAG, "onChanged: speed data repeated.");
return;
}
((SensorDataCycling.Speed) sensorData).compute(sensorDataSet.getCyclingSpeed(), PreferencesUtils.getWheelCircumference(context));
((SensorDataCycling.Speed) sensorData).compute(previous, PreferencesUtils.getWheelCircumference(context));
}
sensorDataSet.set(sensorData);
@@ -17,7 +17,7 @@ public class UintUtils {
if (a < 0 || b < 0) {
return -1;
}
if (a > UINT_MAX && b > UINT_MAX) {
if (a > UINT_MAX || b > UINT_MAX) {
return -1;
}