forked from upstream-mirrors/OpenTracks
Review comments for revision fd70af575b77 addressed.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Google Inc.
|
* Copyright 2011 Google Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
@@ -22,19 +22,21 @@ import java.util.List;
|
|||||||
* A history of Zephyr stride counter reading.
|
* A history of Zephyr stride counter reading.
|
||||||
* These can be used as an alternate method to calculate the correct cadence.
|
* These can be used as an alternate method to calculate the correct cadence.
|
||||||
* This is a work around for an issue with some HxM firmware.
|
* This is a work around for an issue with some HxM firmware.
|
||||||
|
*
|
||||||
* @author Dominik Ršttsches
|
* @author Dominik Ršttsches
|
||||||
*/
|
*/
|
||||||
public class StrideReadings {
|
public class StrideReadings {
|
||||||
|
|
||||||
private static final int NUM_READINGS_FOR_AVERAGE = 10;
|
// visible for testing
|
||||||
private static final int MIN_READINGS_FOR_AVERAGE = 5;
|
protected static final int NUM_READINGS_FOR_AVERAGE = 10;
|
||||||
|
protected static final int MIN_READINGS_FOR_AVERAGE = 5;
|
||||||
|
|
||||||
protected static final int CADENCE_NOT_AVAILABLE = -1;
|
protected static final int CADENCE_NOT_AVAILABLE = -1;
|
||||||
|
|
||||||
// TODO: Check whether 1Hz assumption is okay for cadence calculation
|
// TODO: Check whether 1Hz assumption is okay for cadence calculation
|
||||||
// otherwise add heart beat timestamp to this list and compute
|
// otherwise add heart beat timestamp to this list and compute
|
||||||
// cadence from these timestamps.
|
// cadence from these timestamps.
|
||||||
private List<Integer> strideReadingsHistory;
|
private final List<Integer> strideReadingsHistory;
|
||||||
|
|
||||||
public StrideReadings() {
|
public StrideReadings() {
|
||||||
strideReadingsHistory = new LinkedList<Integer>();
|
strideReadingsHistory = new LinkedList<Integer>();
|
||||||
@@ -65,9 +67,14 @@ public class StrideReadings {
|
|||||||
timeSinceOldestReadingSecs * 60);
|
timeSinceOldestReadingSecs * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int mod(int x, int y)
|
/**
|
||||||
|
* Modulo operation with positive return values, Java's remainder operator doesn't change sign.
|
||||||
|
*
|
||||||
|
* @return x mod y
|
||||||
|
*/
|
||||||
|
private static int mod(int x, int y)
|
||||||
{
|
{
|
||||||
int result = x % y;
|
int result = x % y;
|
||||||
return result < 0? result + y : result;
|
return result < 0 ? result + y : result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -62,22 +62,20 @@ public class ZephyrMessageParser implements MessageParser {
|
|||||||
// a workaround based on the stride counter.
|
// a workaround based on the stride counter.
|
||||||
// Firmware values range from field 3 to 10 (inclusive) of the byte buffer.
|
// Firmware values range from field 3 to 10 (inclusive) of the byte buffer.
|
||||||
byte[] hardwareFirmwareId = Arrays.copyOfRange(buffer, 3, 11);
|
byte[] hardwareFirmwareId = Arrays.copyOfRange(buffer, 3, 11);
|
||||||
boolean computeFromStrides = Arrays.equals(hardwareFirmwareId, CADENCE_BUG_FW_ID);
|
|
||||||
|
|
||||||
Sensor.SensorData.Builder cadence = Sensor.SensorData.newBuilder();
|
Sensor.SensorData.Builder cadence = Sensor.SensorData.newBuilder();
|
||||||
|
|
||||||
if(computeFromStrides) {
|
if (Arrays.equals(hardwareFirmwareId, CADENCE_BUG_FW_ID)) {
|
||||||
if(strideReadings == null) {
|
if (strideReadings == null) {
|
||||||
strideReadings = new StrideReadings();
|
strideReadings = new StrideReadings();
|
||||||
}
|
}
|
||||||
strideReadings.updateStrideReading(buffer[54] & 0xFF);
|
strideReadings.updateStrideReading(buffer[54] & 0xFF);
|
||||||
|
|
||||||
if(strideReadings.getCadence() != StrideReadings.CADENCE_NOT_AVAILABLE) {
|
if (strideReadings.getCadence() != StrideReadings.CADENCE_NOT_AVAILABLE) {
|
||||||
cadence = cadence.setValue(strideReadings.getCadence())
|
cadence.setValue(strideReadings.getCadence()).setState(Sensor.SensorState.SENDING);
|
||||||
.setState(Sensor.SensorState.SENDING);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cadence = cadence
|
cadence
|
||||||
.setValue(SensorUtils.unsignedShortToIntLittleEndian(buffer, 56) / 16)
|
.setValue(SensorUtils.unsignedShortToIntLittleEndian(buffer, 56) / 16)
|
||||||
.setState(Sensor.SensorState.SENDING);
|
.setState(Sensor.SensorState.SENDING);
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-37
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Google Inc.
|
* Copyright 2011 Google Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
@@ -15,41 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.apps.mytracks.services.sensors;
|
package com.google.android.apps.mytracks.services.sensors;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Dominik Ršttsches
|
* @author Dominik Ršttsches
|
||||||
*/
|
*/
|
||||||
public class StrideReadingsTest extends TestCase {
|
public class StrideReadingsTest extends TestCase {
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides access to private members in classes.
|
|
||||||
* from http://onjava.com/pub/a/onjava/2003/11/12/reflection.html
|
|
||||||
*/
|
|
||||||
private Object getPrivateField (Object o, String fieldName) {
|
|
||||||
/* Check we have valid arguments */
|
|
||||||
Assert.assertNotNull(o);
|
|
||||||
Assert.assertNotNull(fieldName);
|
|
||||||
/* Go and find the private field... */
|
|
||||||
final Field fields[] = o.getClass().getDeclaredFields();
|
|
||||||
for (int i = 0; i < fields.length; ++i) {
|
|
||||||
if (fieldName.equals(fields[i].getName())) {
|
|
||||||
try {
|
|
||||||
fields[i].setAccessible(true);
|
|
||||||
return fields[i].get(o);
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
Assert.fail ("IllegalAccessException accessing " + fieldName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Assert.fail ("Field '" + fieldName + "' not found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNoReadingOnStartup() {
|
public void testNoReadingOnStartup() {
|
||||||
StrideReadings strideReadings = new StrideReadings();
|
StrideReadings strideReadings = new StrideReadings();
|
||||||
assertEquals(StrideReadings.CADENCE_NOT_AVAILABLE, strideReadings.getCadence());
|
assertEquals(StrideReadings.CADENCE_NOT_AVAILABLE, strideReadings.getCadence());
|
||||||
@@ -58,28 +30,33 @@ public class StrideReadingsTest extends TestCase {
|
|||||||
public void testAverageCadenceAvailable() {
|
public void testAverageCadenceAvailable() {
|
||||||
StrideReadings strideReadings = new StrideReadings();
|
StrideReadings strideReadings = new StrideReadings();
|
||||||
// 2 steps / second => Cadence is 120 / minute
|
// 2 steps / second => Cadence is 120 / minute
|
||||||
for(int i=1;i<=30;i++) {
|
for (int i=1;i<=30;i++) {
|
||||||
strideReadings.updateStrideReading(i*2);
|
strideReadings.updateStrideReading(i*2);
|
||||||
if(i > (Integer)getPrivateField(strideReadings, "NUM_READINGS_FOR_AVERAGE")) {
|
if (i >= StrideReadings.MIN_READINGS_FOR_AVERAGE) {
|
||||||
assertEquals(120, strideReadings.getCadence());
|
assertEquals(120, strideReadings.getCadence());
|
||||||
|
} else {
|
||||||
|
assertEquals(StrideReadings.CADENCE_NOT_AVAILABLE, strideReadings.getCadence());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tests for correct calculation after rolling over at 128 strides,
|
/**
|
||||||
* just like the HxM seems to do it. */
|
* Tests for correct calculation after rolling over at 128 strides,
|
||||||
|
* just like the HxM seems to do it.
|
||||||
|
*/
|
||||||
public void testRollover() {
|
public void testRollover() {
|
||||||
StrideReadings strideReadings = new StrideReadings();
|
StrideReadings strideReadings = new StrideReadings();
|
||||||
// 1 step per second => Cadence is 60 / minute
|
// 1 step per second => Cadence is 60 / minute
|
||||||
// Updating readings counting upwards from initialStrides -
|
// Updating readings counting upwards from initialStrides -
|
||||||
// initialStrides set to a value below 128 to ensure rollover.
|
// initialStrides set to a value below 128 to ensure rollover.
|
||||||
int numReadingsRequired = (Integer)getPrivateField(strideReadings, "NUM_READINGS_FOR_AVERAGE");
|
int initialStrides = 128 - StrideReadings.NUM_READINGS_FOR_AVERAGE - 5;
|
||||||
int initialStrides = 128 - numReadingsRequired - 5;
|
|
||||||
|
|
||||||
for(int i=1;i<=numReadingsRequired+10;i++) {
|
for (int i=1;i<=StrideReadings.NUM_READINGS_FOR_AVERAGE+10;i++) {
|
||||||
strideReadings.updateStrideReading((initialStrides + i) % 128);
|
strideReadings.updateStrideReading((initialStrides + i) % 128);
|
||||||
if(i > numReadingsRequired) {
|
if (i >= StrideReadings.MIN_READINGS_FOR_AVERAGE) {
|
||||||
assertEquals(60, strideReadings.getCadence());
|
assertEquals(60, strideReadings.getCadence());
|
||||||
|
} else {
|
||||||
|
assertEquals(StrideReadings.CADENCE_NOT_AVAILABLE, strideReadings.getCadence());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user