While recording: show cadence and speed from different sensor types correctly.

Fixes #970.
This commit is contained in:
Dennis Guse
2021-10-14 07:42:58 +02:00
parent 45571c68c9
commit 900910e9f7
5 changed files with 81 additions and 36 deletions
@@ -54,6 +54,9 @@ public abstract class SensorData<T> {
protected abstract T getNoneValue(); protected abstract T getNoneValue();
public T getValue() { public T getValue() {
if (!hasValue()) {
return null;
}
if (isRecent()) { if (isRecent()) {
return value; return value;
} }
@@ -43,7 +43,6 @@ public final class SensorDataRunning extends SensorData<SensorDataRunning.Data>
return cadence; return cadence;
} }
@VisibleForTesting
public Speed getSpeed() { public Speed getSpeed() {
return speed; return speed;
} }
@@ -1,7 +1,10 @@
package de.dennisguse.opentracks.content.sensor; package de.dennisguse.opentracks.content.sensor;
import android.util.Pair;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPoint;
public final class SensorDataSet { public final class SensorDataSet {
@@ -27,8 +30,36 @@ public final class SensorDataSet {
this.runningDistanceSpeedCadence = toCopy.runningDistanceSpeedCadence; this.runningDistanceSpeedCadence = toCopy.runningDistanceSpeedCadence;
} }
public SensorDataHeartRate getHeartRate() { public Pair<Float, String> getHeartRate() {
return heartRate; if (heartRate != null) {
return new Pair<>(heartRate.getValue(), heartRate.getSensorNameOrAddress());
}
return null;
}
public Pair<Float, String> getCadence() {
if (cyclingCadence != null) {
return new Pair<>(cyclingCadence.getValue(), cyclingCadence.getSensorNameOrAddress());
}
if (runningDistanceSpeedCadence != null) {
return new Pair<>(runningDistanceSpeedCadence.getCadence(), runningDistanceSpeedCadence.getSensorNameOrAddress());
}
return null;
}
public Pair<Speed, String> getSpeed() {
if (cyclingDistanceSpeed != null && cyclingDistanceSpeed.hasValue() && cyclingDistanceSpeed.getValue().getSpeed() != null) {
return new Pair<>(cyclingDistanceSpeed.getValue().getSpeed(), cyclingCadence.getSensorNameOrAddress());
}
if (runningDistanceSpeedCadence != null && runningDistanceSpeedCadence.hasValue() && runningDistanceSpeedCadence.getValue().getSpeed() != null) {
return new Pair<>(runningDistanceSpeedCadence.getSpeed(), runningDistanceSpeedCadence.getSensorNameOrAddress());
}
return null;
} }
public SensorDataCycling.Cadence getCyclingCadence() { public SensorDataCycling.Cadence getCyclingCadence() {
@@ -64,17 +95,20 @@ public final class SensorDataSet {
} }
public void fillTrackPoint(TrackPoint trackPoint) { public void fillTrackPoint(TrackPoint trackPoint) {
if (heartRate != null) { if (getHeartRate() != null) {
trackPoint.setHeartRate_bpm(heartRate.getValue()); trackPoint.setHeartRate_bpm(getHeartRate().first);
} }
if (cyclingCadence != null && cyclingCadence.hasValue()) { if (getCadence() != null) {
trackPoint.setCadence_rpm(cyclingCadence.getValue()); trackPoint.setCadence_rpm(getCadence().first);
}
if (getSpeed() != null) {
trackPoint.setSpeed(getSpeed().first);
} }
if (cyclingDistanceSpeed != null && cyclingDistanceSpeed.hasValue()) { if (cyclingDistanceSpeed != null && cyclingDistanceSpeed.hasValue()) {
trackPoint.setSensorDistance(cyclingDistanceSpeed.getValue().getDistanceOverall()) trackPoint.setSensorDistance(cyclingDistanceSpeed.getValue().getDistanceOverall());
.setSpeed(cyclingDistanceSpeed.getValue().getSpeed());
} }
if (cyclingPower != null && cyclingPower.hasValue()) { if (cyclingPower != null && cyclingPower.hasValue()) {
@@ -82,9 +116,7 @@ public final class SensorDataSet {
} }
if (runningDistanceSpeedCadence != null && runningDistanceSpeedCadence.hasValue()) { if (runningDistanceSpeedCadence != null && runningDistanceSpeedCadence.hasValue()) {
trackPoint.setSensorDistance(runningDistanceSpeedCadence.getValue().getDistance()) trackPoint.setSensorDistance(runningDistanceSpeedCadence.getValue().getDistance());
.setSpeed(runningDistanceSpeedCadence.getValue().getSpeed())
.setCadence_rpm(runningDistanceSpeedCadence.getValue().getCadence());
} }
} }
@@ -204,7 +204,7 @@ public class StringUtils {
} }
public static Pair<String, String> getHeartRateParts(Context context, Float heartrate_bpm) { public static Pair<String, String> getHeartRateParts(Context context, Float heartrate_bpm) {
String value = context.getString(R.string.value_none); String value = context.getString(R.string.value_unknown);
if (heartrate_bpm != null) { if (heartrate_bpm != null) {
value = StringUtils.formatDecimal(heartrate_bpm, 0); value = StringUtils.formatDecimal(heartrate_bpm, 0);
} }
@@ -213,7 +213,7 @@ public class StringUtils {
} }
public static Pair<String, String> getCadenceParts(Context context, Float cadence_rpm) { public static Pair<String, String> getCadenceParts(Context context, Float cadence_rpm) {
String value = context.getString(R.string.value_none); String value = context.getString(R.string.value_unknown);
if (cadence_rpm != null) { if (cadence_rpm != null) {
value = StringUtils.formatDecimal(cadence_rpm, 0); value = StringUtils.formatDecimal(cadence_rpm, 0);
} }
@@ -222,7 +222,7 @@ public class StringUtils {
} }
public static Pair<String, String> getPowerParts(Context context, Float power_w) { public static Pair<String, String> getPowerParts(Context context, Float power_w) {
String value = context.getString(R.string.value_none); String value = context.getString(R.string.value_unknown);
if (power_w != null) { if (power_w != null) {
value = StringUtils.formatDecimal(power_w, 0); value = StringUtils.formatDecimal(power_w, 0);
} }
@@ -40,6 +40,9 @@ public class StatisticDataBuilder {
String description = null; String description = null;
Pair<String, String> valueAndUnit = null; Pair<String, String> valueAndUnit = null;
boolean isWide = false; boolean isWide = false;
final String sensorUnknown = context.getString(R.string.value_unknown);
if (fieldKey.equals(context.getString(R.string.stats_custom_layout_total_time_key))) { if (fieldKey.equals(context.getString(R.string.stats_custom_layout_total_time_key))) {
valueAndUnit = new Pair<>(StringUtils.formatElapsedTime(recordingData.getTrackStatistics().getTotalTime()), null); valueAndUnit = new Pair<>(StringUtils.formatElapsedTime(recordingData.getTrackStatistics().getTotalTime()), null);
title = context.getString(R.string.stats_total_time); title = context.getString(R.string.stats_total_time);
@@ -49,14 +52,15 @@ public class StatisticDataBuilder {
} else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_distance_key))) { } else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_distance_key))) {
valueAndUnit = StringUtils.getDistanceParts(context, recordingData.getTrackStatistics().getTotalDistance(), metricUnits); valueAndUnit = StringUtils.getDistanceParts(context, recordingData.getTrackStatistics().getTotalDistance(), metricUnits);
title = context.getString(R.string.stats_distance); title = context.getString(R.string.stats_distance);
} else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_speed_key)) || fieldKey.equals(context.getString(R.string.stats_custom_layout_pace_key))) { } else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_speed_key)) || fieldKey.equals(context.getString(R.string.stats_custom_layout_pace_key))) {
boolean reportSpeed = fieldKey.equals("speed"); boolean reportSpeed = fieldKey.equals("speed");
title = fieldKey.equals("speed") ? context.getString(R.string.stats_speed) : context.getString(R.string.stats_pace); title = reportSpeed ? context.getString(R.string.stats_speed) : context.getString(R.string.stats_pace);
Speed speed = latestTrackPoint != null && latestTrackPoint.hasSpeed() ? latestTrackPoint.getSpeed() : null;
if (sensorDataSet != null && sensorDataSet.getCyclingDistanceSpeed() != null && sensorDataSet.getCyclingDistanceSpeed().hasValue()) { if (sensorDataSet != null && sensorDataSet.getSpeed() != null) {
valueAndUnit = StringUtils.getSpeedParts(context, sensorDataSet.getCyclingDistanceSpeed().getValue().getSpeed(), metricUnits, reportSpeed); valueAndUnit = StringUtils.getSpeedParts(context, sensorDataSet.getSpeed().first, metricUnits, reportSpeed);
description = context.getString(R.string.description_speed_source_sensor, sensorDataSet.getCyclingDistanceSpeed().getSensorNameOrAddress()); description = context.getString(R.string.description_speed_source_sensor, sensorDataSet.getSpeed().second);
} else { } else {
Speed speed = latestTrackPoint != null && latestTrackPoint.hasSpeed() ? latestTrackPoint.getSpeed() : null;
valueAndUnit = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed); valueAndUnit = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
description = context.getString(R.string.description_speed_source_gps); description = context.getString(R.string.description_speed_source_gps);
} }
@@ -95,25 +99,32 @@ public class StatisticDataBuilder {
if (latestTrackPoint != null && latestTrackPoint.hasLocation()) { if (latestTrackPoint != null && latestTrackPoint.hasLocation()) {
valueAndUnit = new Pair<>(StringUtils.formatCoordinate(context, latestTrackPoint.getLatitude(), latestTrackPoint.getLongitude()), null); valueAndUnit = new Pair<>(StringUtils.formatCoordinate(context, latestTrackPoint.getLatitude(), latestTrackPoint.getLongitude()), null);
} else { } else {
valueAndUnit = new Pair<>(context.getString(R.string.value_none), null); valueAndUnit = new Pair<>(context.getString(R.string.value_unknown), null);
} }
} else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_heart_rate_key))) { } else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_heart_rate_key))) {
title = context.getString(R.string.stats_sensors_heart_rate); title = context.getString(R.string.stats_sensors_heart_rate);
if (sensorDataSet != null && sensorDataSet.getHeartRate() != null && sensorDataSet.getHeartRate().hasValue()) { if (sensorDataSet != null && sensorDataSet.getHeartRate() != null) {
valueAndUnit = StringUtils.getHeartRateParts(context, sensorDataSet.getHeartRate().getValue()); valueAndUnit = StringUtils.getHeartRateParts(context, sensorDataSet.getHeartRate().first);
description = sensorDataSet.getHeartRate().getSensorNameOrAddress(); description = sensorDataSet.getHeartRate().second;
} else { } else {
valueAndUnit = StringUtils.getHeartRateParts(context, null); valueAndUnit = StringUtils.getHeartRateParts(context, null);
description = context.getString(R.string.value_none); description = sensorUnknown;
} }
} else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_cadence_key))) { } else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_cadence_key))) {
title = context.getString(R.string.stats_sensors_cadence); title = context.getString(R.string.stats_sensors_cadence);
if (sensorDataSet != null && sensorDataSet.getCyclingCadence() != null && sensorDataSet.getCyclingCadence().hasValue()) {
valueAndUnit = StringUtils.getCadenceParts(context, sensorDataSet.getCyclingCadence().getValue()); Float cadence = null;
description = sensorDataSet.getCyclingCadence().getSensorNameOrAddress(); if (sensorDataSet != null) {
} else { Pair<Float, String> cadenceData = sensorDataSet.getCadence();
valueAndUnit = StringUtils.getCadenceParts(context, null); if (cadenceData != null) {
description = context.getString(R.string.value_none); cadence = cadenceData.first;
description = cadenceData.second;
}
}
valueAndUnit = StringUtils.getCadenceParts(context, cadence);
if (description == null) {
description = sensorUnknown;
} }
} else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_power_key))) { } else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_power_key))) {
title = context.getString(R.string.stats_sensors_power); title = context.getString(R.string.stats_sensors_power);
@@ -122,7 +133,7 @@ public class StatisticDataBuilder {
description = sensorDataSet.getCyclingPower().getSensorNameOrAddress(); description = sensorDataSet.getCyclingPower().getSensorNameOrAddress();
} else { } else {
valueAndUnit = StringUtils.getPowerParts(context, null); valueAndUnit = StringUtils.getPowerParts(context, null);
description = context.getString(R.string.value_none); description = sensorUnknown;
} }
} }
@@ -134,7 +145,7 @@ public class StatisticDataBuilder {
} }
/** /**
* Builds a list of StatisticData with sensors connected but not in statisticDataList. * Builds a list of StatisticData with sensors configured but not in statisticDataList.
*/ */
private static List<StatisticData> getSensorStatsDataIfNeeded(Context context, TrackRecordingService.RecordingData recordingData, List<StatisticData> statisticDataList, boolean metricUnits) { private static List<StatisticData> getSensorStatsDataIfNeeded(Context context, TrackRecordingService.RecordingData recordingData, List<StatisticData> statisticDataList, boolean metricUnits) {
List<StatisticData> sensorDataList = new ArrayList<>(); List<StatisticData> sensorDataList = new ArrayList<>();
@@ -142,10 +153,10 @@ public class StatisticDataBuilder {
if (sensorDataSet == null) { if (sensorDataSet == null) {
return sensorDataList; return sensorDataList;
} }
if (statisticDataList.stream().noneMatch(i -> i.getField().getTitle().equals(context.getString(R.string.stats_sensors_heart_rate))) && sensorDataSet.getHeartRate() != null && sensorDataSet.getHeartRate().hasValue()) { if (statisticDataList.stream().noneMatch(i -> i.getField().getTitle().equals(context.getString(R.string.stats_sensors_heart_rate))) && sensorDataSet.getHeartRate() != null) {
sensorDataList.add(build(context, recordingData, "heart_rate", true, metricUnits)); sensorDataList.add(build(context, recordingData, "heart_rate", true, metricUnits));
} }
if (statisticDataList.stream().noneMatch(i -> i.getField().getTitle().equals(context.getString(R.string.stats_sensors_cadence))) && sensorDataSet.getCyclingCadence() != null && sensorDataSet.getCyclingCadence().hasValue()) { if (statisticDataList.stream().noneMatch(i -> i.getField().getTitle().equals(context.getString(R.string.stats_sensors_cadence))) && sensorDataSet.getCadence() != null) {
sensorDataList.add(build(context, recordingData, "cadence", true, metricUnits)); sensorDataList.add(build(context, recordingData, "cadence", true, metricUnits));
} }
if (statisticDataList.stream().noneMatch(i -> i.getField().getTitle().equals(context.getString(R.string.stats_sensors_power))) && sensorDataSet.getCyclingPower() != null && sensorDataSet.getCyclingPower().hasValue()) { if (statisticDataList.stream().noneMatch(i -> i.getField().getTitle().equals(context.getString(R.string.stats_sensors_power))) && sensorDataSet.getCyclingPower() != null && sensorDataSet.getCyclingPower().hasValue()) {