improves metrics of first stroke by setting reasonable initial values

This commit is contained in:
Lars Berning 2022-01-31 19:55:27 +01:00
parent 6792ca77c1
commit 2210c46162
No known key found for this signature in database
GPG Key ID: 028E73C9E1D8A0B3
3 changed files with 14 additions and 8 deletions

View File

@ -34,8 +34,8 @@ function createRowingEngine (rowerSettings) {
let drivePhaseAngularDisplacement let drivePhaseAngularDisplacement
let driveLinearDistance let driveLinearDistance
let recoveryPhaseStartTime let recoveryPhaseStartTime
let recoveryPhaseStartAngularDisplacement
let recoveryPhaseAngularDisplacement let recoveryPhaseAngularDisplacement
let recoveryPhaseStartAngularDisplacement
let recoveryPhaseLength let recoveryPhaseLength
let recoveryStartAngularVelocity let recoveryStartAngularVelocity
let recoveryEndAngularVelocity let recoveryEndAngularVelocity
@ -293,6 +293,9 @@ function createRowingEngine (rowerSettings) {
} }
function reset () { function reset () {
// to init displacements with plausible defaults we assume, that one rowing cycle transforms to nine meters of distance...
const defaultDisplacementForRowingCycle = 8.0 / Math.pow(((rowerSettings.dragFactor / 1000000) / rowerSettings.magicConstant), 1.0 / 3.0)
movingDragAverage.reset() movingDragAverage.reset()
cyclePhase = 'Recovery' cyclePhase = 'Recovery'
totalTime = 0.0 totalTime = 0.0
@ -301,11 +304,15 @@ function createRowingEngine (rowerSettings) {
drivePhaseStartTime = 0.0 drivePhaseStartTime = 0.0
drivePhaseStartAngularDisplacement = 0.0 drivePhaseStartAngularDisplacement = 0.0
drivePhaseLength = 2.0 * rowerSettings.minimumDriveTime drivePhaseLength = 2.0 * rowerSettings.minimumDriveTime
drivePhaseAngularDisplacement = rowerSettings.numOfImpulsesPerRevolution // split defaultDisplacementForRowingCycle to aprox 1/3 for the drive phase
drivePhaseAngularDisplacement = (1.0 / 3.0) * defaultDisplacementForRowingCycle
driveLinearDistance = 0.0 driveLinearDistance = 0.0
recoveryPhaseStartTime = -2 * rowerSettings.minimumRecoveryTime // Make sure that the first CurrentDt will trigger a detected stroke by faking a recovery phase that is long enough // Make sure that the first CurrentDt will trigger a detected stroke by faking a recovery phase that is long enough
recoveryPhaseStartAngularDisplacement = -1.0 * rowerSettings.numOfImpulsesPerRevolution recoveryPhaseStartTime = -2 * rowerSettings.minimumRecoveryTime
recoveryPhaseAngularDisplacement = rowerSettings.numOfImpulsesPerRevolution // and split defaultDisplacementForRowingCycle to aprox 2/3 for the recovery phase
recoveryPhaseAngularDisplacement = (2.0 / 3.0) * defaultDisplacementForRowingCycle
// set this to the number of impulses required to generate the angular displacement as assumed above
recoveryPhaseStartAngularDisplacement = Math.round(-1.0 * (2.0 / 3.0) * defaultDisplacementForRowingCycle / angularDisplacementPerImpulse)
recoveryPhaseLength = 2.0 * rowerSettings.minimumRecoveryTime recoveryPhaseLength = 2.0 * rowerSettings.minimumRecoveryTime
recoveryStartAngularVelocity = angularDisplacementPerImpulse / rowerSettings.minimumTimeBetweenImpulses recoveryStartAngularVelocity = angularDisplacementPerImpulse / rowerSettings.minimumTimeBetweenImpulses
recoveryEndAngularVelocity = angularDisplacementPerImpulse / rowerSettings.maximumTimeBetweenImpulses recoveryEndAngularVelocity = angularDisplacementPerImpulse / rowerSettings.maximumTimeBetweenImpulses

View File

@ -61,7 +61,7 @@ test('sample data for WRX700 should produce plausible results with rower profile
await replayRowingSession(rowingEngine.handleRotationImpulse, { filename: 'recordings/WRX700_2magnets.csv' }) await replayRowingSession(rowingEngine.handleRotationImpulse, { filename: 'recordings/WRX700_2magnets.csv' })
assert.is(workoutEvaluator.getNumOfStrokes(), 16, 'number of strokes does not meet expectation') assert.is(workoutEvaluator.getNumOfStrokes(), 16, 'number of strokes does not meet expectation')
assertPowerRange(workoutEvaluator, 50, 220) assertPowerRange(workoutEvaluator, 50, 220)
assertDistanceRange(workoutEvaluator, 159, 163) assertDistanceRange(workoutEvaluator, 165, 168)
assertStrokeDistanceSumMatchesTotal(workoutEvaluator) assertStrokeDistanceSumMatchesTotal(workoutEvaluator)
}) })
@ -72,7 +72,7 @@ test('sample data for DKNR320 should produce plausible results with rower profil
await replayRowingSession(rowingEngine.handleRotationImpulse, { filename: 'recordings/DKNR320.csv' }) await replayRowingSession(rowingEngine.handleRotationImpulse, { filename: 'recordings/DKNR320.csv' })
assert.is(workoutEvaluator.getNumOfStrokes(), 10, 'number of strokes does not meet expectation') assert.is(workoutEvaluator.getNumOfStrokes(), 10, 'number of strokes does not meet expectation')
assertPowerRange(workoutEvaluator, 75, 200) assertPowerRange(workoutEvaluator, 75, 200)
assertDistanceRange(workoutEvaluator, 65, 68) assertDistanceRange(workoutEvaluator, 71, 73)
assertStrokeDistanceSumMatchesTotal(workoutEvaluator) assertStrokeDistanceSumMatchesTotal(workoutEvaluator)
}) })

View File

@ -186,7 +186,6 @@ function createWorkoutRecorder () {
const minimumRecordingTimeInSeconds = 10 const minimumRecordingTimeInSeconds = 10
const rotationImpulseTimeTotal = rotationImpulses.reduce((acc, impulse) => acc + impulse, 0) const rotationImpulseTimeTotal = rotationImpulses.reduce((acc, impulse) => acc + impulse, 0)
const strokeTimeTotal = strokes.reduce((acc, stroke) => acc + stroke.strokeTime, 0) const strokeTimeTotal = strokes.reduce((acc, stroke) => acc + stroke.strokeTime, 0)
console.log(`strokeTimeTotal: ${strokeTimeTotal} rotationImpulseTimeTotal: ${rotationImpulseTimeTotal} `)
if (rotationImpulseTimeTotal < minimumRecordingTimeInSeconds || strokeTimeTotal < minimumRecordingTimeInSeconds) { if (rotationImpulseTimeTotal < minimumRecordingTimeInSeconds || strokeTimeTotal < minimumRecordingTimeInSeconds) {
log.debug(`recording time is less than ${minimumRecordingTimeInSeconds}s, skipping creation of recording files...`) log.debug(`recording time is less than ${minimumRecordingTimeInSeconds}s, skipping creation of recording files...`)
return return