diff --git a/examples/darth-vader.txt b/examples/darth-vader.txt new file mode 100644 index 0000000..c7290f2 --- /dev/null +++ b/examples/darth-vader.txt @@ -0,0 +1,29 @@ +Name: Darth Vader +Author: HumanPowerPerformance.com +Description: + Sign up for coaching with HumanPowerPerformance.com and get custom workouts and training plans + +Warmup: 5:00 55% + +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% +Rest: 3:00 82% +Interval: 00:20 130% + +Cooldown: 5:00 55% diff --git a/package.json b/package.json index 3f94ffb..569207f 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "scripts": { "lint:ts": "tsc --noEmit", "test": "ts-node src/index.ts examples/threshold-pushing.txt", + "test:2": "ts-node src/index.ts examples/darth-vader.txt", "format:js": "prettier --write src/" }, "devDependencies": { diff --git a/src/index.ts b/src/index.ts index 8d4fcec..ae63ec2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import * as fs from "fs"; import { parse } from "./parser"; import { tokenize } from "./tokenizer"; +import { tss } from "./tss"; const filename = process.argv[2]; @@ -10,4 +11,15 @@ const file = fs.readFileSync(filename, "utf8"); const workout = parse(tokenize(file)); -console.log(workout); +console.log(workout.intervals); + +workout.intervals.forEach((interval, i) => { + console.log(`#${i} TSS: ${tss([interval])}`); +}); + +console.log("Total TSS: " + tss(workout.intervals)); + +const duration = + workout.intervals.map(({ duration }) => duration).reduce((a, b) => a + b, 0) / + 60; +console.log(`Total duration: ${duration} minutes`); diff --git a/src/tss.ts b/src/tss.ts new file mode 100644 index 0000000..2398e66 --- /dev/null +++ b/src/tss.ts @@ -0,0 +1,37 @@ +import { Interval } from "./ast"; + +// Training Stress Score formula from Training and Racing with a Power Meter: +// +// TSS = (s * W * IF) / (FTP * 3600) * 100 +// +// s - duration in seconds +// W - power in watts +// IF - intensity factor (power / FTP) + +const steadyTss = (duration: number, power: number): number => { + const intensity = power / 100; + + return ((duration * intensity * intensity) / 3600) * 100; +}; + +const rangeTss = (duration: number, from: number, to: number): number => { + let score = 0; + const step = 1; + for (let i = 0; i < duration; i += step) { + let power = from + (to - from) * (i / duration); + score += steadyTss(step, power); + } + return score; +}; + +const intervalTss = ({ duration, power }: Interval): number => { + if (power.from === power.to) { + return steadyTss(duration, power.from); + } else { + return rangeTss(duration, power.from, power.to); + } +}; + +export const tss = (intervals: Interval[]): number => { + return intervals.map(intervalTss).reduce((a, b) => a + b, 0); +};