From 40188774b105e077379ea9ad98968b6a9729546e Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 10 Jun 2021 21:22:40 +0200 Subject: [PATCH] Bugfix: cycling sensors report wheel count as UINT32. Garmin Speed Sensor 2 actually counts forward: it was an UINT16 overflow problem (removed workaround). Fixes #810. --- README_TESTED_SENSORS.md | 2 -- .../opentracks/util/UintUtilsTest.java | 23 +++++++++++++++++++ .../content/sensor/SensorDataCycling.java | 13 ++++------- .../opentracks/util/StringUtils.java | 2 +- .../dennisguse/opentracks/util/UintUtils.java | 6 ++--- 5 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 src/androidTest/java/de/dennisguse/opentracks/util/UintUtilsTest.java diff --git a/README_TESTED_SENSORS.md b/README_TESTED_SENSORS.md index d7633b47b..1035dd9f1 100644 --- a/README_TESTED_SENSORS.md +++ b/README_TESTED_SENSORS.md @@ -23,8 +23,6 @@ However, often only one value is provided. * Has updatable firmware that requires an account for garmin.com * This sensor reports speed data as cadence. A workaround is in place. - * This sensor sometimes counts backwards (unknown software version). - A workaround is in place. * Wahoo Speed (Model: WFRPMSPD) diff --git a/src/androidTest/java/de/dennisguse/opentracks/util/UintUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/util/UintUtilsTest.java new file mode 100644 index 000000000..f47c2ca33 --- /dev/null +++ b/src/androidTest/java/de/dennisguse/opentracks/util/UintUtilsTest.java @@ -0,0 +1,23 @@ +package de.dennisguse.opentracks.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class UintUtilsTest { + + @Test + public void diff() { + assertEquals(0, UintUtils.diff(1, 1, UintUtils.UINT16_MAX)); + assertEquals(1, UintUtils.diff(2, 1, UintUtils.UINT16_MAX)); + assertEquals(3, UintUtils.diff(5, 2, UintUtils.UINT16_MAX)); + assertEquals(65534, UintUtils.diff(1, 2, UintUtils.UINT16_MAX)); + + assertEquals(65530, UintUtils.diff(UintUtils.UINT16_MAX, 5, UintUtils.UINT16_MAX)); + } + + @Test + public void realData() { + assertEquals(3, UintUtils.diff(381616, 381615, UintUtils.UINT32_MAX)); + } +} \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java index 1ee86eea1..314dbc621 100644 --- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java +++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java @@ -15,8 +15,6 @@ import de.dennisguse.opentracks.util.UnitConversions; /** * Provides cadence in rpm and speed in milliseconds from Bluetooth LE Cycling Cadence and Speed sensors. - *

- * https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=261449 */ public final class SensorDataCycling { @@ -96,7 +94,7 @@ public final class SensorDataCycling { public static class DistanceSpeed extends SensorData { - private final Integer wheelRevolutionsCount; // UINT16 + private final Integer wheelRevolutionsCount; // UINT32 private final Integer wheelRevolutionsTime; // UINT16; 1/1024s public DistanceSpeed(String sensorAddress) { @@ -133,8 +131,7 @@ public final class SensorDataCycling { return; } - long wheelDiff = UintUtils.diff(wheelRevolutionsCount, previous.wheelRevolutionsCount, UintUtils.UINT16_MAX); - wheelDiff = Math.abs(wheelDiff); //HACK for Garmin Speed 2 as some of those seem to count backwards + long wheelDiff = UintUtils.diff(wheelRevolutionsCount, previous.wheelRevolutionsCount, UintUtils.UINT32_MAX); Distance distance = wheelCircumference.multipliedBy(wheelDiff); Distance distanceOverall = distance; @@ -164,11 +161,11 @@ public final class SensorDataCycling { if (!(obj instanceof DistanceSpeed)) return false; DistanceSpeed comp = (DistanceSpeed) obj; - if (hasData() && comp.hasData() == hasData()) { - return getWheelRevolutionsCount() == comp.getWheelRevolutionsCount() && getWheelRevolutionsTime() == comp.getWheelRevolutionsTime(); - } else { + if (!(hasData() && comp.hasData())) { return false; } + + return getWheelRevolutionsCount() == comp.getWheelRevolutionsCount() && getWheelRevolutionsTime() == comp.getWheelRevolutionsTime(); } public static class Data { diff --git a/src/main/java/de/dennisguse/opentracks/util/StringUtils.java b/src/main/java/de/dennisguse/opentracks/util/StringUtils.java index 20b22b8cb..a77a23d9b 100644 --- a/src/main/java/de/dennisguse/opentracks/util/StringUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/StringUtils.java @@ -215,7 +215,7 @@ public class StringUtils { } StringBuilder builder = new StringBuilder(); - builder.append("[").append(category).append("]"); + builder.append(getCategory(category)); if (description != null && description.length() != 0) { builder.append(" ").append(description); } diff --git a/src/main/java/de/dennisguse/opentracks/util/UintUtils.java b/src/main/java/de/dennisguse/opentracks/util/UintUtils.java index be579f19e..5e252fc36 100644 --- a/src/main/java/de/dennisguse/opentracks/util/UintUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/UintUtils.java @@ -11,14 +11,14 @@ public class UintUtils { /** * Computes a - b for UINT with overflow (b < a). * - * @return diff or -1 (invalid) + * @return diff */ public static long diff(long a, long b, final long UINT_MAX) { if (a < 0 || b < 0) { - return -1; + throw new RuntimeException("a or b cannot be less than zero."); } if (a > UINT_MAX || b > UINT_MAX) { - return -1; + throw new RuntimeException("a or b are outside of the allowed range." + a + " " + b); } if (a >= b) {