adds unit tests to verify the rowing engine with real rower recordings
This commit is contained in:
parent
55cde69ce6
commit
5dddeb2ff5
|
|
@ -0,0 +1,69 @@
|
||||||
|
'use strict'
|
||||||
|
/*
|
||||||
|
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||||
|
*/
|
||||||
|
import { test } from 'uvu'
|
||||||
|
import * as assert from 'uvu/assert'
|
||||||
|
import loglevel from 'loglevel'
|
||||||
|
|
||||||
|
import rowerProfiles from '../../config/rowerProfiles.js'
|
||||||
|
import { createRowingEngine } from './RowingEngine.js'
|
||||||
|
import { replayRowingSession } from '../tools/RowingRecorder.js'
|
||||||
|
|
||||||
|
const log = loglevel.getLogger('RowingEngine.test')
|
||||||
|
log.setLevel('warn')
|
||||||
|
|
||||||
|
const createWorkoutEvaluator = function () {
|
||||||
|
const strokes = []
|
||||||
|
|
||||||
|
function handleStroke (stroke) {
|
||||||
|
strokes.push(stroke)
|
||||||
|
log.info(`stroke: ${strokes.length}, power: ${Math.round(stroke.power)}w, duration: ${stroke.duration.toFixed(2)}s, ` +
|
||||||
|
` drivePhase: ${stroke.durationDrivePhase.toFixed(2)}s, distance: ${stroke.distance.toFixed(2)}m`)
|
||||||
|
}
|
||||||
|
function handleStrokeStateChanged () {}
|
||||||
|
function handlePause () {}
|
||||||
|
function getNumOfStrokes () {
|
||||||
|
return strokes.length
|
||||||
|
}
|
||||||
|
function getMaxStrokePower () {
|
||||||
|
return strokes.map((stroke) => stroke.power).reduce((acc, power) => Math.max(acc, power))
|
||||||
|
}
|
||||||
|
function getMinStrokePower () {
|
||||||
|
return strokes.map((stroke) => stroke.power).reduce((acc, power) => Math.max(acc, power))
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
handleStroke,
|
||||||
|
handleStrokeStateChanged,
|
||||||
|
handlePause,
|
||||||
|
getNumOfStrokes,
|
||||||
|
getMaxStrokePower,
|
||||||
|
getMinStrokePower
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('sample data for WRX700 should produce plausible results with rower profile', async () => {
|
||||||
|
const rowingEngine = createRowingEngine(rowerProfiles.WRX700)
|
||||||
|
const workoutEvaluator = createWorkoutEvaluator()
|
||||||
|
rowingEngine.notify(workoutEvaluator)
|
||||||
|
await replayRowingSession(rowingEngine.handleRotationImpulse, { filename: 'recordings/WRX700_2magnets.csv' })
|
||||||
|
assert.is(workoutEvaluator.getNumOfStrokes(), 16, 'number of strokes does not meet expectation')
|
||||||
|
// todo: maximum power of the first stroke is too high because it does not contain a recovery part
|
||||||
|
// should fix that in the RowingEngine and adjust the maximum power here to 220
|
||||||
|
assert.ok(workoutEvaluator.getMaxStrokePower() < 370, `maximum stroke power should be below 370w, but is ${workoutEvaluator.getMaxStrokePower()}w`)
|
||||||
|
assert.ok(workoutEvaluator.getMinStrokePower() > 50, `minimum stroke power should be above 50w, but is ${workoutEvaluator.getMinStrokePower()}w`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('sample data for DKNR320 should produce plausible results with rower profile', async () => {
|
||||||
|
const rowingEngine = createRowingEngine(rowerProfiles.DKNR320)
|
||||||
|
const workoutEvaluator = createWorkoutEvaluator()
|
||||||
|
rowingEngine.notify(workoutEvaluator)
|
||||||
|
await replayRowingSession(rowingEngine.handleRotationImpulse, { filename: 'recordings/DKNR320.csv' })
|
||||||
|
assert.is(workoutEvaluator.getNumOfStrokes(), 10, 'number of strokes does not meet expectation')
|
||||||
|
// todo: maximum power of the first stroke is too high because it does not contain a recovery part
|
||||||
|
// should fix that in the RowingEngine and adjust the maximum power here to 200
|
||||||
|
assert.ok(workoutEvaluator.getMaxStrokePower() < 370, `maximum stroke power should be below 370w, but is ${workoutEvaluator.getMaxStrokePower()}w`)
|
||||||
|
assert.ok(workoutEvaluator.getMinStrokePower() > 75, `minimum stroke power should be above 75w, but is ${workoutEvaluator.getMinStrokePower()}w`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.run()
|
||||||
|
|
@ -62,7 +62,7 @@ peripheralManager.on('control', (event) => {
|
||||||
const gpioTimerService = fork('./app/gpio/GpioTimerService.js')
|
const gpioTimerService = fork('./app/gpio/GpioTimerService.js')
|
||||||
gpioTimerService.on('message', (dataPoint) => {
|
gpioTimerService.on('message', (dataPoint) => {
|
||||||
rowingEngine.handleRotationImpulse(dataPoint)
|
rowingEngine.handleRotationImpulse(dataPoint)
|
||||||
// fs.appendFile('recordings/wrx700_2magnets_long.csv', `${dataPoint}\n`, (err) => { if (err) log.error(err) })
|
// fs.appendFile('recordings/WRX700_2magnets.csv', `${dataPoint}\n`, (err) => { if (err) log.error(err) })
|
||||||
})
|
})
|
||||||
|
|
||||||
const rowingEngine = createRowingEngine(config.rowerSettings)
|
const rowingEngine = createRowingEngine(config.rowerSettings)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ This is the very minimalistic Backlog for further development of this project.
|
||||||
* validate FTMS with more training applications and harden implementation (i.e. Holofit and Coxswain)
|
* validate FTMS with more training applications and harden implementation (i.e. Holofit and Coxswain)
|
||||||
* record a longer rowing session and analyze two encountered problems: 1) rarely the stroke rate doubles for a short duration (might be a problem with stroke detection when measurements are imprecise), 2) in one occasion the measured power jumped to a very high value after a break (40000 watts)
|
* record a longer rowing session and analyze two encountered problems: 1) rarely the stroke rate doubles for a short duration (might be a problem with stroke detection when measurements are imprecise), 2) in one occasion the measured power jumped to a very high value after a break (40000 watts)
|
||||||
* add support for ANT+ heart rate monitors with USB dongles
|
* add support for ANT+ heart rate monitors with USB dongles
|
||||||
* presets for rowing machine specific config parameters
|
|
||||||
* add an option to automatically feed the measured damping constant back into the rowing engine
|
* add an option to automatically feed the measured damping constant back into the rowing engine
|
||||||
|
|
||||||
## Later
|
## Later
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
0.54800057
|
||||||
|
0.268049458
|
||||||
|
0.216636979
|
||||||
|
0.231423722
|
||||||
|
0.284531614
|
||||||
|
0.360516235
|
||||||
|
0.482000949
|
||||||
|
0.43154357
|
||||||
|
0.211636619
|
||||||
|
0.183476903
|
||||||
|
0.211438686
|
||||||
|
0.258253277
|
||||||
|
0.322601712
|
||||||
|
0.419122022
|
||||||
|
0.503416119
|
||||||
|
0.247547705
|
||||||
|
0.183943279
|
||||||
|
0.18996022
|
||||||
|
0.22674499
|
||||||
|
0.280166413
|
||||||
|
0.353291919
|
||||||
|
0.465764768
|
||||||
|
0.399939714
|
||||||
|
0.194878642
|
||||||
|
0.164347067
|
||||||
|
0.183165805
|
||||||
|
0.221021301
|
||||||
|
0.270787329
|
||||||
|
0.340818407
|
||||||
|
0.445469766
|
||||||
|
0.387934208
|
||||||
|
0.195407159
|
||||||
|
0.166335799
|
||||||
|
0.186449225
|
||||||
|
0.226147521
|
||||||
|
0.277143086
|
||||||
|
0.349279683
|
||||||
|
0.460192588
|
||||||
|
0.370720743
|
||||||
|
0.188971811
|
||||||
|
0.163149731
|
||||||
|
0.182686216
|
||||||
|
0.220796962
|
||||||
|
0.270990489
|
||||||
|
0.340495458
|
||||||
|
0.445263279
|
||||||
|
0.451159591
|
||||||
|
0.202756547
|
||||||
|
0.158435164
|
||||||
|
0.164154601
|
||||||
|
0.199352942
|
||||||
|
0.243400048
|
||||||
|
0.301640659
|
||||||
|
0.3847461
|
||||||
|
0.509093228
|
||||||
|
0.298548183
|
||||||
|
0.17824294
|
||||||
|
0.162219424
|
||||||
|
0.186324723
|
||||||
|
0.22541504
|
||||||
|
0.278458293
|
||||||
|
0.350756165
|
||||||
|
0.462008358
|
||||||
|
0.405086177
|
||||||
|
0.19120966
|
||||||
|
0.162582118
|
||||||
|
0.18241563
|
||||||
|
0.220221933
|
||||||
|
0.269459088
|
||||||
|
0.339834293
|
||||||
|
0.443984581
|
||||||
|
0.462005699
|
||||||
|
0.21064753
|
||||||
|
0.161225062
|
||||||
|
0.167056112
|
||||||
|
0.20001449
|
||||||
|
0.243339132
|
||||||
|
0.301283162
|
||||||
|
0.385138631
|
||||||
|
0.520107711
|
||||||
|
0.822650475
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
3.47124274
|
|
||||||
0.370380355
|
0.370380355
|
||||||
0.211917846
|
0.211917846
|
||||||
0.169332723
|
0.169332723
|
||||||
|
Loading…
Reference in New Issue