adds more tests to averagers
This commit is contained in:
parent
f6c46c0f9f
commit
36fe899e81
|
|
@ -8,7 +8,7 @@
|
|||
They are arranged that dataPoints[0] is the youngest, and dataPoints[flankLength] the oldest
|
||||
*/
|
||||
import loglevel from 'loglevel'
|
||||
import { createMovingAverager } from './MovingAverager.js'
|
||||
import { createMovingAverager } from './averager/MovingAverager.js'
|
||||
const log = loglevel.getLogger('RowingEngine')
|
||||
|
||||
function createMovingFlankDetector (rowerSettings) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
Also Dave Vernooy has some good explanations here: https://dvernooy.github.io/projects/ergware
|
||||
*/
|
||||
import loglevel from 'loglevel'
|
||||
import { createMovingAverager } from './MovingAverager.js'
|
||||
import { createMovingAverager } from './averager/MovingAverager.js'
|
||||
import { createMovingFlankDetector } from './MovingFlankDetector.js'
|
||||
|
||||
const log = loglevel.getLogger('RowingEngine')
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
This Module calculates the training specific metrics.
|
||||
*/
|
||||
import { EventEmitter } from 'events'
|
||||
import { createMovingIntervalAverager } from './MovingIntervalAverager.js'
|
||||
import { createWeightedAverager } from './WeightedAverager.js'
|
||||
import { createMovingIntervalAverager } from './averager/MovingIntervalAverager.js'
|
||||
import { createWeightedAverager } from './averager/WeightedAverager.js'
|
||||
|
||||
import loglevel from 'loglevel'
|
||||
const log = loglevel.getLogger('RowingEngine')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
This Averager can calculate the moving average of a continuous flow of data points
|
||||
|
||||
Please note: The array contains flankLength + 1 measured currentDt's, thus flankLength number of flanks between them
|
||||
Please note: The array contains flankLength + 1 measured currentDt's, thus flankLength number
|
||||
of flanks between them.
|
||||
They are arranged that dataPoints[0] is the youngest, and dataPoints[flankLength] the oldest
|
||||
*/
|
||||
function createMovingAverager (length, initValue) {
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
*/
|
||||
import { test } from 'uvu'
|
||||
import * as assert from 'uvu/assert'
|
||||
|
||||
import { createMovingAverager } from './MovingAverager.js'
|
||||
|
||||
test('average should be initValue on empty dataset', () => {
|
||||
const movingAverager = createMovingAverager(10, 5.5)
|
||||
assert.is(movingAverager.getMovingAverage(), 5.5)
|
||||
})
|
||||
|
||||
test('an averager of length 1 should return the last added value', () => {
|
||||
const movingAverager = createMovingAverager(1, 3)
|
||||
movingAverager.pushValue(9)
|
||||
assert.is(movingAverager.getMovingAverage(), 9)
|
||||
})
|
||||
|
||||
test('an averager of length 2 should return average of last 2 added elements', () => {
|
||||
const movingAverager = createMovingAverager(2, 3)
|
||||
movingAverager.pushValue(9)
|
||||
movingAverager.pushValue(4)
|
||||
assert.is(movingAverager.getMovingAverage(), 6.5)
|
||||
})
|
||||
|
||||
test('elements outside of range should not be considered', () => {
|
||||
const movingAverager = createMovingAverager(2, 3)
|
||||
movingAverager.pushValue(9)
|
||||
movingAverager.pushValue(4)
|
||||
movingAverager.pushValue(3)
|
||||
assert.is(movingAverager.getMovingAverage(), 3.5)
|
||||
})
|
||||
|
||||
test('replacing the last element should work as expected', () => {
|
||||
const movingAverager = createMovingAverager(2, 3)
|
||||
movingAverager.pushValue(9)
|
||||
movingAverager.pushValue(5)
|
||||
movingAverager.replaceLastPushedValue(12)
|
||||
assert.is(movingAverager.getMovingAverage(), 10.5)
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
|
@ -6,9 +6,10 @@
|
|||
of data points for a certain (time) interval
|
||||
*/
|
||||
function createMovingIntervalAverager (movingDuration) {
|
||||
let dataPoints = []
|
||||
let duration = 0.0
|
||||
let sum = 0.0
|
||||
let dataPoints
|
||||
let duration
|
||||
let sum
|
||||
reset()
|
||||
|
||||
function pushValue (dataValue, dataDuration) {
|
||||
// add the new dataPoint to the front of the array
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
*/
|
||||
import { test } from 'uvu'
|
||||
import * as assert from 'uvu/assert'
|
||||
|
||||
import { createWeightedAverager } from './WeightedAverager.js'
|
||||
|
||||
test('average should be 0 on empty dataset', () => {
|
||||
const weightedAverager = createWeightedAverager(10)
|
||||
assert.is(weightedAverager.weightedAverage(), 0)
|
||||
})
|
||||
|
||||
test('average of one value is value', () => {
|
||||
const weightedAverager = createWeightedAverager(10)
|
||||
weightedAverager.pushValue(13.78)
|
||||
assert.is(weightedAverager.weightedAverage(), 13.78)
|
||||
})
|
||||
|
||||
test('average of a and b is (2*b + a) / 3', () => {
|
||||
const weightedAverager = createWeightedAverager(10)
|
||||
weightedAverager.pushValue(5) // a
|
||||
weightedAverager.pushValue(2) // b
|
||||
assert.is(weightedAverager.weightedAverage(), 3)
|
||||
})
|
||||
|
||||
test('average should be 0 after reset', () => {
|
||||
const weightedAverager = createWeightedAverager(10)
|
||||
weightedAverager.pushValue(5)
|
||||
weightedAverager.pushValue(2)
|
||||
weightedAverager.reset()
|
||||
assert.is(weightedAverager.weightedAverage(), 0)
|
||||
})
|
||||
|
||||
test('average should be a after pushing a after a reset', () => {
|
||||
const weightedAverager = createWeightedAverager(10)
|
||||
weightedAverager.pushValue(5)
|
||||
weightedAverager.pushValue(2)
|
||||
weightedAverager.reset()
|
||||
weightedAverager.pushValue(7)
|
||||
assert.is(weightedAverager.weightedAverage(), 7)
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
|
@ -6,8 +6,10 @@ Open Rowing Monitor uses some great work by others. Thank you for all the great
|
|||
|
||||
* Dave Vernooy's project description on [ErgWare](https://dvernooy.github.io/projects/ergware) has some good information on the maths involved in a rowing ergometer.
|
||||
|
||||
* Bluetooth is quite a complex beast, luckily the Bluetooth SIG releases all the [specifications here](https://www.bluetooth.com/specifications/specs)
|
||||
* Bluetooth is quite a complex beast, luckily the Bluetooth SIG releases all the [specifications here](https://www.bluetooth.com/specifications/specs).
|
||||
|
||||
* The app icon is based on this [image of a rowing machine](https://thenounproject.com/term/rowing-machine/659265) by [Gan Khoon Lay](https://thenounproject.com/leremy/) licensed under [CC BY 2.0](https://creativecommons.org/licenses/by/2.0/).
|
||||
|
||||
* The frontend uses some icons from [Font Awesome](https://fontawesome.com/), licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
||||
|
||||
* Thank you to [Jaap van Ekris](https://github.com/JaapvanEkris) for his contributions to this project.
|
||||
|
|
|
|||
Loading…
Reference in New Issue