adds more settings, adds auto adjust for damping
This commit is contained in:
parent
1b895972af
commit
b019fb3bd4
|
|
@ -27,7 +27,7 @@ function createRowingEngine (rowerSettings) {
|
|||
// 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
|
||||
let omegaDotDivOmegaSquare = rowerSettings.omegaDotDivOmegaSquare
|
||||
|
||||
// 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"
|
||||
|
|
@ -49,13 +49,13 @@ function createRowingEngine (rowerSettings) {
|
|||
const c = rowerSettings.magicConstant
|
||||
|
||||
// jMoment * ωdot = -kDamp * ω^2 during non-power part of stroke
|
||||
const kDamp = jMoment * omegaDotDivOmegaSquare
|
||||
let kDamp = jMoment * omegaDotDivOmegaSquare
|
||||
|
||||
// s = (k/c)^(1/3)*θ
|
||||
const distancePerRevolution = 2.0 * Math.PI * Math.pow((kDamp / c), 1.0 / 3.0)
|
||||
|
||||
let workoutHandler
|
||||
const kDampEstimatorAverager = createWeightedAverager(3)
|
||||
const kDampEstimatorAverager = createWeightedAverager(5)
|
||||
const flankDetector = createMovingFlankDetector(rowerSettings)
|
||||
let prevDt = rowerSettings.maximumTimeBetweenImpulses
|
||||
let kPower = 0.0
|
||||
|
|
@ -169,8 +169,15 @@ function createRowingEngine (rowerSettings) {
|
|||
if (strokeElapsed - driveElapsed !== 0) {
|
||||
kDampEstimatorAverager.pushValue(kDampEstimator / (strokeElapsed - driveElapsed))
|
||||
}
|
||||
log.debug(`estimated kDamp: ${jMoment * (-1 * kDampEstimatorAverager.weightedAverage())}`)
|
||||
log.info(`estimated omegaDotDivOmegaSquare: ${-1 * kDampEstimatorAverager.weightedAverage()}`)
|
||||
const _kDamp = jMoment * (-1 * kDampEstimatorAverager.weightedAverage())
|
||||
const _omegaDotDivOmegaSquare = -1 * kDampEstimatorAverager.weightedAverage()
|
||||
log.debug(`estimated kDamp: ${_kDamp}`)
|
||||
log.info(`estimated omegaDotDivOmegaSquare: ${_omegaDotDivOmegaSquare}`)
|
||||
if (rowerSettings.autoAdjustDampingConstant) {
|
||||
log.debug('auto adjusting kDamp and omegaDotDivOmegaSquare to new values')
|
||||
kDamp = _kDamp
|
||||
omegaDotDivOmegaSquare = _omegaDotDivOmegaSquare
|
||||
}
|
||||
workoutHandler.handleStrokeStateChanged({
|
||||
strokeState: 'DRIVING'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import log from 'loglevel'
|
|||
log.setLevel(config.loglevel.default)
|
||||
|
||||
export function createGpioTimerService () {
|
||||
if (Gpio.accessible) {
|
||||
if (config.gpioHighPriority) {
|
||||
// setting top (near-real-time) priority for the Gpio process, as we don't want to miss anything
|
||||
log.debug('setting priority for the Gpio-service to maximum (-20)')
|
||||
try {
|
||||
|
|
@ -23,16 +25,16 @@ export function createGpioTimerService () {
|
|||
} catch (err) {
|
||||
log.debug('need root permission to set priority of Gpio-Thread')
|
||||
}
|
||||
}
|
||||
|
||||
if (Gpio.accessible) {
|
||||
// mode can be rising, falling, both
|
||||
const reedSensor = new Gpio(17, 'in', 'rising')
|
||||
// read the sensor data from one of the Gpio pins of Raspberry Pi
|
||||
const sensor = new Gpio(config.gpioPin, 'in', 'rising')
|
||||
// use hrtime for time measurement to get a higher time precision
|
||||
let hrStartTime = process.hrtime()
|
||||
|
||||
// assumes that GPIO-Port 17 is set to pullup and reed is connected to GND
|
||||
// therefore the value is 1 if the reed sensor is open
|
||||
reedSensor.watch((err, value) => {
|
||||
sensor.watch((err, value) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,46 +7,60 @@
|
|||
!!! 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. Simply copy the
|
||||
To change the settings you should modify the 'config/config.js' file. Simply copy the
|
||||
options that you would like to change into that file. 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
|
||||
// Available log levels: trace, debug, info, warn, error, silent
|
||||
loglevel: {
|
||||
// the default loglevel
|
||||
// The default loglevel
|
||||
default: 'info',
|
||||
// the log level of of the rowing engine (stroke detection and physics model)
|
||||
// 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
|
||||
// Defines the GPIO Pin that is used to read the sensor data from the rowing machine
|
||||
// see: https://www.raspberrypi.org/documentation/usage/gpio for the pin layout of the device
|
||||
// If you want to use the internal pull-up resistor of the Raspberry Pi you should
|
||||
// also configure the pin for that in /boot/config.txt, i.e. 'gpio=17=pu,ip'
|
||||
// see: https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md
|
||||
gpioPin: 17,
|
||||
|
||||
// Experimental setting: enable this to boost the system level priority of the thread that
|
||||
// measures the rotation speed of the flywheel. This might improve the precision of the
|
||||
// measurements (especially on rowers with a fast spinning flywheel)
|
||||
gpioHighPriority: false,
|
||||
|
||||
// Selects the Bluetooth Low Energy Profile
|
||||
// Supported modes: FTMS, FTMSBIKE, PM5
|
||||
bluetoothMode: 'FTMS',
|
||||
|
||||
// turn this on if you want support for Bluetooth Low Energy heart rate monitors
|
||||
// will currenty the hear rate and battery level of the first device found
|
||||
// Turn this on if you want support for Bluetooth Low Energy heart rate monitors
|
||||
// Will currenty connect to the first device found
|
||||
heartrateMonitorBLE: true,
|
||||
|
||||
// turn this on if you want support for ANT+ heart rate monitors
|
||||
// you will need an ANT+ USB stick for this to work, the following models might work:
|
||||
// Turn this on if you want support for ANT+ heart rate monitors
|
||||
// You will need an ANT+ USB stick for this to work, the following models might work:
|
||||
// - Garmin USB or USB2 ANT+ or an off-brand clone of it (ID 0x1008)
|
||||
// - Garmin mini ANT+ (ID 0x1009)
|
||||
heartrateMonitorANT: false,
|
||||
|
||||
// defines the name that is used to announce the FTMS Rower via Bluetooth Low Energy (BLE)
|
||||
// some rowing training applications expect that the rowing device is announced with a certain name
|
||||
// Defines the name that is used to announce the FTMS Rower via Bluetooth Low Energy (BLE)
|
||||
// Some rowing training applications expect that the rowing device is announced with a certain name
|
||||
ftmsRowerPeripheralName: 'OpenRowingMonitor',
|
||||
|
||||
// defines the name that is used to announce the FTMS Bike via Bluetooth Low Energy (BLE)
|
||||
// most bike training applications are fine with any device name
|
||||
// Defines the name that is used to announce the FTMS Bike via Bluetooth Low Energy (BLE)
|
||||
// Most bike training applications are fine with any device name
|
||||
ftmsBikePeripheralName: 'OpenRowingBike',
|
||||
|
||||
// the rower specific settings. Either choose a profile from config/rowerProfiles.js or
|
||||
// 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.
|
||||
// !! Only change this setting in the config/config.js file, and leave this on DEFAULT as that
|
||||
// is the fallback for the default profile settings
|
||||
rowerSettings: rowerProfiles.DEFAULT
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,19 +22,20 @@ export default {
|
|||
minimumTimeBetweenImpulses: 0.014,
|
||||
maximumTimeBetweenImpulses: 0.5,
|
||||
// Percentage change between successive intervals
|
||||
maximumDownwardChange: 0.2, // effectively the maximum deceleration
|
||||
maximumDownwardChange: 0.25, // effectively the maximum deceleration
|
||||
maximumUpwardChange: 1.75, // effectively the maximum acceleration
|
||||
// Settings for the rowing phase detection (in seconds)
|
||||
flankLength: 1,
|
||||
flankLength: 2,
|
||||
numberOfErrorsAllowed: 0,
|
||||
minimumDriveTime: 0.300,
|
||||
minimumRecoveryTime: 0.750,
|
||||
// Settings for the rowing phase detection (in seconds)
|
||||
minimumDriveTime: 0.500,
|
||||
minimumRecoveryTime: 0.800,
|
||||
|
||||
// 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.
|
||||
// of the stroke.
|
||||
// To display it for your rowing machine, set the logging level of the RowingEngine to 'info'. Then start rowing and
|
||||
// you will see the measured values in the log.
|
||||
// Open Rowing Monitor can also automatically adjust this value based on the measured damping. To do so, set the setting
|
||||
// autoAdjustDampingConstant to true (see below).
|
||||
omegaDotDivOmegaSquare: 0.02,
|
||||
|
||||
// The moment of inertia of the flywheel kg*m^2
|
||||
|
|
@ -43,6 +44,11 @@ export default {
|
|||
// plausibility. Note that the power also depends on omegaDotDivOmegaSquare (see above).
|
||||
jMoment: 0.49,
|
||||
|
||||
// Set this to true, if you want to automatically update omegaDotDivOmegaSquare and kDamp based on the measured
|
||||
// values in the stroke recovery phase. If your rower produces stable damping values, then this could be a good
|
||||
// option to dynamically adjust your measurements to the damper setting of your rower.
|
||||
autoAdjustDampingConstant: false,
|
||||
|
||||
// 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
|
||||
// Concept2 seems to use 2.8, which they admit is an arbitrary number which came close
|
||||
|
|
@ -66,12 +72,6 @@ export default {
|
|||
numOfImpulsesPerRevolution: 2,
|
||||
minimumTimeBetweenImpulses: 0.05,
|
||||
maximumTimeBetweenImpulses: 1,
|
||||
maximumDownwardChange: 0.25,
|
||||
maximumUpwardChange: 2,
|
||||
flankLength: 2,
|
||||
numberOfErrorsAllowed: 0,
|
||||
minimumDriveTime: 0.500,
|
||||
minimumRecoveryTime: 0.800,
|
||||
omegaDotDivOmegaSquare: 0.046,
|
||||
jMoment: 0.49,
|
||||
liquidFlywheel: true
|
||||
|
|
@ -82,12 +82,6 @@ export default {
|
|||
numOfImpulsesPerRevolution: 1,
|
||||
minimumTimeBetweenImpulses: 0.15,
|
||||
maximumTimeBetweenImpulses: 0.5,
|
||||
maximumDownwardChange: 0.25,
|
||||
maximumUpwardChange: 1.75,
|
||||
flankLength: 2,
|
||||
numberOfErrorsAllowed: 0,
|
||||
minimumDriveTime: 0.500,
|
||||
minimumRecoveryTime: 0.800,
|
||||
omegaDotDivOmegaSquare: 0.019,
|
||||
jMoment: 0.4,
|
||||
liquidFlywheel: true
|
||||
|
|
|
|||
|
|
@ -30,5 +30,10 @@ export default {
|
|||
jMoment: 0.3,
|
||||
liquidFlywheel: false
|
||||
}
|
||||
|
||||
// example: set a rower profile, but overwrite some settings:
|
||||
rowerSettings: Object.assign(rowerProfiles.DKNR320, {
|
||||
autoAdjustDampingConstant: true
|
||||
})
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue