moves rower configuration into a config file and adds rower presets
This commit is contained in:
parent
0586fc11d8
commit
55cde69ce6
|
|
@ -11,7 +11,7 @@
|
|||
"ecmaVersion": 12,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"ignorePatterns": ["**/*.min.js"],
|
||||
"ignorePatterns": ["**/*.min.js", "**/tools/ConfigManager.js"],
|
||||
"rules": {
|
||||
"camelcase": 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,3 +77,4 @@ node_modules
|
|||
._*
|
||||
tmp/
|
||||
build/
|
||||
config/config.js
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@
|
|||
|
||||
Starts the central manager in a forked thread since noble does not like
|
||||
to run in the same thread as bleno
|
||||
todo: check if noble would also work if we move this into a worker thread
|
||||
(would save some ressources)
|
||||
*/
|
||||
import { createCentralManager } from './CentralManager.js'
|
||||
import process from 'process'
|
||||
import config from '../config.js'
|
||||
import config from '../tools/ConfigManager.js'
|
||||
import log from 'loglevel'
|
||||
|
||||
log.setLevel(config.loglevel.default)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
This manager creates the different Bluetooth Low Energy (BLE) Peripherals and allows
|
||||
switching between them
|
||||
*/
|
||||
import config from '../config.js'
|
||||
import config from '../tools/ConfigManager.js'
|
||||
import { createFtmsPeripheral } from './FtmsPeripheral.js'
|
||||
import { createPm5Peripheral } from './Pm5Peripheral.js'
|
||||
import log from 'loglevel'
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
|
||||
This file contains the app specific configuration.
|
||||
Modify it to your needs.
|
||||
*/
|
||||
import log from 'loglevel'
|
||||
export default {
|
||||
loglevel: {
|
||||
// the default loglevel
|
||||
default: log.levels.INFO,
|
||||
// the log level of some modules can be set individually to filter noise
|
||||
RowingEngine: log.levels.WARN
|
||||
},
|
||||
// selects the Bluetooth Low Energy Profile
|
||||
// supported modes: FTMS, FTMSBIKE, PM5
|
||||
bluetoothMode: 'FTMS'
|
||||
}
|
||||
|
|
@ -16,51 +16,45 @@ import { createTimer } from './Timer.js'
|
|||
|
||||
const log = loglevel.getLogger('RowingEngine')
|
||||
|
||||
// *****************************************************
|
||||
// These constants are specific to your Rowing Machine
|
||||
// *****************************************************
|
||||
function createRowingEngine (rowerSettings) {
|
||||
// How many impulses are triggered per revolution of the flywheel
|
||||
// i.e. the number of magnets if used with a reed sensor
|
||||
const numOfImpulsesPerRevolution = rowerSettings.numOfImpulsesPerRevolution
|
||||
|
||||
// How many impulses are triggered per revolution of the flywheel
|
||||
// i.e. the number of magnets if used with a reed sensor
|
||||
const numOfImpulsesPerRevolution = 2
|
||||
// Needed to determine the damping constant of the rowing machine. This value can be measured in the recovery phase
|
||||
// of the stroke (some ergometers do this constantly).
|
||||
// However I still keep it constant here, as I still have to figure out the damping physics of a water rower (see below)
|
||||
// To measure it for your rowing machine, comment in the logging at the end of "startDrivePhase" function. Then do some
|
||||
// strokes on the rower and estimate a value.
|
||||
const omegaDotDivOmegaSquare = rowerSettings.omegaDotDivOmegaSquare
|
||||
|
||||
// Needed to determine the damping constant of the rowing machine. This value can be measured in the recovery phase
|
||||
// of the stroke (some ergometers do this constantly).
|
||||
// However I still keep it constant here, as I still have to figure out the damping physics of a water rower (see below)
|
||||
// To measure it for your rowing machine, comment in the logging at the end of "startDrivePhase" function. Then do some
|
||||
// strokes on the rower and estimate a value.
|
||||
const omegaDotDivOmegaSquare = 0.046
|
||||
// The moment of inertia of the flywheel kg*m^2
|
||||
// A way to measure it is outlined here: https://dvernooy.github.io/projects/ergware/, "Flywheel moment of inertia"
|
||||
// You could also roughly estimate it by just doing some strokes and the comparing the calculated power values for
|
||||
// plausibility. Note that the power also depends on omegaDotDivOmegaSquare (see above).
|
||||
const jMoment = rowerSettings.jMoment
|
||||
|
||||
// The moment of inertia of the flywheel kg*m^2
|
||||
// A way to measure it is outlined here: https://dvernooy.github.io/projects/ergware/, "Flywheel moment of inertia"
|
||||
// You could also roughly estimate it by just doing some strokes and the comparing the calculated power values for
|
||||
// plausibility. Note that the power also depends on omegaDotDivOmegaSquare (see above).
|
||||
const jMoment = 0.49
|
||||
// Set this to true if you are using a water rower
|
||||
// The mass of the water starts rotating, when you pull the handle, and therefore acts
|
||||
// like a massive flywheel
|
||||
// Liquids are a tricky thing and therefore the dumping constant does not seem to be
|
||||
// that constant on water rowers...
|
||||
// This is WIP, but for now this setting is used to figure out the drive and recovery phases
|
||||
// differently on water rowers
|
||||
const liquidFlywheel = rowerSettings.liquidFlywheel
|
||||
|
||||
// Set this to true if you are using a water rower
|
||||
// The mass of the water starts rotating, when you pull the handle, and therefore acts
|
||||
// like a massive flywheel
|
||||
// Liquids are a tricky thing and therefore the dumping constant does not seem to be
|
||||
// that constant on water rowers...
|
||||
// This is WIP, but for now this setting is used to figure out the drive and recovery phases
|
||||
// differently on water rowers
|
||||
const liquidFlywheel = true
|
||||
// A constant that is commonly used to convert flywheel revolutions to a rowed distance
|
||||
// see here: http://eodg.atm.ox.ac.uk/user/dudhia/rowing/physics/ergometer.html#section9
|
||||
const c = 2.8
|
||||
|
||||
// A constant that is commonly used to convert flywheel revolutions to a rowed distance
|
||||
// see here: http://eodg.atm.ox.ac.uk/user/dudhia/rowing/physics/ergometer.html#section9
|
||||
const c = 2.8
|
||||
// jMoment * ωdot = -kDamp * ω^2 during non-power part of stroke
|
||||
const kDamp = jMoment * omegaDotDivOmegaSquare
|
||||
|
||||
// jMoment * ωdot = -kDamp * ω^2 during non-power part of stroke
|
||||
const kDamp = jMoment * omegaDotDivOmegaSquare
|
||||
// s = (k/c)^(1/3)*θ
|
||||
const distancePerRevolution = 2.0 * Math.PI * Math.pow((kDamp / c), 1.0 / 3.0)
|
||||
|
||||
// s = (k/c)^(1/3)*θ
|
||||
const distancePerRevolution = 2.0 * Math.PI * Math.pow((kDamp / c), 1.0 / 3.0)
|
||||
|
||||
function createRowingEngine () {
|
||||
let workoutHandler
|
||||
|
||||
const kDampEstimatorAverager = createWeightedAverager(3)
|
||||
|
||||
let kPower = 0.0
|
||||
let jPower = 0.0
|
||||
let kDampEstimator = 0.0
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { fork } from 'child_process'
|
|||
import log from 'loglevel'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import fs from 'fs'
|
||||
import config from './config.js'
|
||||
import config from './tools/ConfigManager.js'
|
||||
import { createRowingEngine } from './engine/RowingEngine.js'
|
||||
import { createRowingStatistics } from './engine/RowingStatistics.js'
|
||||
import { createWebServer } from './WebServer.js'
|
||||
|
|
@ -65,7 +65,7 @@ gpioTimerService.on('message', (dataPoint) => {
|
|||
// fs.appendFile('recordings/wrx700_2magnets_long.csv', `${dataPoint}\n`, (err) => { if (err) log.error(err) })
|
||||
})
|
||||
|
||||
const rowingEngine = createRowingEngine()
|
||||
const rowingEngine = createRowingEngine(config.rowerSettings)
|
||||
const rowingStatistics = createRowingStatistics()
|
||||
rowingEngine.notify(rowingStatistics)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
|
||||
Merges the different config files and presents the configuration to the application
|
||||
*/
|
||||
import defaultConfig from '../../config/default.config.js'
|
||||
|
||||
async function getConfig () {
|
||||
let customConfig
|
||||
try {
|
||||
customConfig = await import('../../config/config.js')
|
||||
} catch (exception) {}
|
||||
|
||||
return customConfig !== undefined ? deepMerge(defaultConfig, customConfig.default) : defaultConfig
|
||||
}
|
||||
|
||||
function deepMerge (...objects) {
|
||||
const isObject = obj => obj && typeof obj === 'object'
|
||||
|
||||
return objects.reduce((prev, obj) => {
|
||||
Object.keys(obj).forEach(key => {
|
||||
const pVal = prev[key]
|
||||
const oVal = obj[key]
|
||||
|
||||
if (Array.isArray(pVal) && Array.isArray(oVal)) {
|
||||
prev[key] = pVal.concat(...oVal)
|
||||
} else if (isObject(pVal) && isObject(oVal)) {
|
||||
prev[key] = deepMerge(pVal, oVal)
|
||||
} else {
|
||||
prev[key] = oVal
|
||||
}
|
||||
})
|
||||
|
||||
return prev
|
||||
}, {})
|
||||
}
|
||||
|
||||
const config = await getConfig()
|
||||
|
||||
export default config
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
|
||||
This file contains the default configuration of the Open Rowing Monitor.
|
||||
|
||||
!!! Note that changes to this file will be OVERWRITTEN when you update to a new version
|
||||
of Open Rowing Monitor. !!!
|
||||
|
||||
To change the settings you should modify the 'config.js' in this folder. If 'config.js' does not
|
||||
exist, you can use the example file from the 'install' folder.
|
||||
*/
|
||||
import rowerProfiles from './rowerProfiles.js'
|
||||
|
||||
export default {
|
||||
// available log levels: trace, debug, info, warn, error, silent
|
||||
loglevel: {
|
||||
// the default loglevel
|
||||
default: 'info',
|
||||
// the log level of of the rowing engine (stroke detection and physics model)
|
||||
RowingEngine: 'warn'
|
||||
},
|
||||
|
||||
// selects the Bluetooth Low Energy Profile
|
||||
// supported modes: FTMS, FTMSBIKE, PM5
|
||||
bluetoothMode: 'FTMS',
|
||||
|
||||
// the rower specific settings. Either choose a profile from config/rowerProfiles.js or
|
||||
// define the settings individually. If you find good settings for a new rowing device
|
||||
// please send them to us (together with a raw recording of 10 strokes) so we can add
|
||||
// the device to the profiles.
|
||||
rowerSettings: rowerProfiles.DEFAULT
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
|
||||
This file contains the rower specific settings for different models of ergometers.
|
||||
|
||||
These have been generated by the community. If your rower is not listed here and you did find
|
||||
good settings for your rowing device please send them to us (together with a raw recording of
|
||||
10 strokes) so we can add the device here.
|
||||
*/
|
||||
export default {
|
||||
|
||||
// Profile for an example rower
|
||||
DEFAULT: {
|
||||
// How many impulses are triggered per revolution of the flywheel
|
||||
// i.e. the number of magnets if used with a reed sensor
|
||||
numOfImpulsesPerRevolution: 1,
|
||||
|
||||
// Needed to determine the damping constant of the rowing machine. This value can be measured in the recovery phase
|
||||
// of the stroke (some ergometers do this constantly).
|
||||
// However I still keep it constant here, as I still have to figure out the damping physics of a water rower (see below)
|
||||
// To measure it for your rowing machine, comment in the logging at the end of "startDrivePhase" function. Then do some
|
||||
// strokes on the rower and estimate a value.
|
||||
omegaDotDivOmegaSquare: 0.02,
|
||||
|
||||
// The moment of inertia of the flywheel kg*m^2
|
||||
// A way to measure it is outlined here: https://dvernooy.github.io/projects/ergware/, "Flywheel moment of inertia"
|
||||
// You could also roughly estimate it by just doing some strokes and the comparing the calculated power values for
|
||||
// plausibility. Note that the power also depends on omegaDotDivOmegaSquare (see above).
|
||||
jMoment: 0.49,
|
||||
|
||||
// Set this to true if you are using a water rower
|
||||
// The mass of the water starts rotating, when you pull the handle, and therefore acts
|
||||
// like a massive flywheel
|
||||
// Liquids are a tricky thing and therefore the dumping constant does not seem to be
|
||||
// that constant on water rowers...
|
||||
// This is WIP, but for now this setting is used to figure out the drive and recovery phases
|
||||
// differently on water rowers
|
||||
liquidFlywheel: false
|
||||
},
|
||||
|
||||
// Sportstech WRX700
|
||||
WRX700: {
|
||||
numOfImpulsesPerRevolution: 2,
|
||||
omegaDotDivOmegaSquare: 0.046,
|
||||
jMoment: 0.49,
|
||||
liquidFlywheel: true
|
||||
},
|
||||
|
||||
// DKN R-320 Air Rower
|
||||
DKNR320: {
|
||||
numOfImpulsesPerRevolution: 1,
|
||||
omegaDotDivOmegaSquare: 0.019,
|
||||
jMoment: 0.4,
|
||||
liquidFlywheel: true
|
||||
}
|
||||
}
|
||||
|
|
@ -60,4 +60,4 @@ If your machine does not have something like this or if the sensor is not access
|
|||
* PAS sensor (i.e. from an E-bike)
|
||||
* Optical chopper wheel
|
||||
|
||||
You should now adjust the rower specific parameters in `app/engine/RowingEngine.js` to suit your rowing machine.
|
||||
You should now adjust the rower specific parameters in `config/config.js` to suit your rowing machine.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
|
||||
You can modify this file to configure Open Rowing Monitor to your needs.
|
||||
This file should be placed in the 'config' folder of Open Rowing Monitor.
|
||||
|
||||
All available configuration parameters are visible in config/config.default.js
|
||||
To modify a parameter, copy it to this file and modify the value.
|
||||
|
||||
Changes to this file are persisted when you update to new versions.
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import rowerProfiles from './rowerProfiles.js'
|
||||
|
||||
export default {
|
||||
/*
|
||||
// example: change the default log level:
|
||||
loglevel: {
|
||||
default: 'debug'
|
||||
},
|
||||
|
||||
// example: set a rower profile:
|
||||
rowerSettings: rowerProfiles.DKNR320
|
||||
|
||||
// example: set custom rower settings:
|
||||
rowerSettings: {
|
||||
numOfImpulsesPerRevolution: 1,
|
||||
omegaDotDivOmegaSquare: 0.03,
|
||||
jMoment: 0.3,
|
||||
liquidFlywheel: false
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
@ -76,6 +76,9 @@ print
|
|||
print "Downloading and compiling Runtime dependencies..."
|
||||
sudo npm install
|
||||
sudo npm run build
|
||||
if ! [[ -f "config/config.js" ]]; then
|
||||
cp install/config.js config/
|
||||
fi
|
||||
|
||||
print
|
||||
print "Setting up Open Rowing Monitor as autostarting system service..."
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "openrowingmonitor",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"description": "A rowing monitor for rowing exercise machines",
|
||||
"main": "app/server.js",
|
||||
"author": "Lars Berning",
|
||||
|
|
|
|||
Loading…
Reference in New Issue