Uitleg
Welke metrics gebruikt deze tool, en waarom.
Hieronder staat per metric: wat het is, hoe wij het uit jouw data berekenen, en hoe het doorwerkt in de planner. Alle berekeningen zijn deterministisch, geen black-box, geen ML.
VDOT, actuele fitness
VDOT is Jack Daniels' VO₂max-equivalent: een getal (~30–85) dat aangeeft hoe snel je nu bent over een race-inspanning. Het is de centrale fitness-as in de hele tool.
Toon de cijfers
VO₂(v) = -4.60 + 0.182258·v + 0.000104·v² (v in m/min) %VO₂max(t) = 0.8 + 0.1894·e^(-0.0128·t) + 0.2990·e^(-0.1933·t) (t in min) VDOT = VO₂(v) / %VO₂max(t)
Hoe wij hem schatten: per run berekenen we een race-equivalent VDOT via Daniels-formule, met een correctie voor klimmen (+6 s/km per 1% gemiddeld stijgingspercentage). We nemen vervolgens de rollende 90-dagen-best van alle runs ≥ 3 km, dat filtert easy runs eruit en pakt je piekrace-vorm.
Trend: we fitten een lineaire regressie op de laatste 24 maanden van die VDOT-tijdreeks. De helling (vdot_slope_per_year) bepaalt hoeveel je waarschijnlijk groeit tot race-datum.
Doorwerking:
- Bepaalt al je tempo-zones (Easy/Marathon/T/I/R).
- Wordt geprojecteerd naar race-datum (max ±4 VDOT-punten over een blok).
- De inverse-functie (
race_time_from_vdot) levert het voorgestelde doel.
Tempo-zones (Daniels)
Pace-zones worden volledig afgeleid uit VDOT, niet uit hartslag, niet uit RPE. We berekenen v_vo2 (snelheid bij 100% VO₂max) door de VO₂-polynomiaal te inverteren, en schalen die met vaste percentages:
Toon de cijfers
Easy (E) 70–65 % van v_vo2 Marathon (M) 84 % van v_vo2 Threshold (T) 88 % van v_vo2 ← lactaat-drempel Interval (I) 98 % van v_vo2 ← VO₂max-stimulatie Repetition (R) 105 % van v_vo2 ← neuromusculair / snelheid
Dit zijn de tempo's die op je /profile en in elke workout-pill van het schema verschijnen.
Volume, acuut, chronisch & ACWR
We tellen alle hardloopkilometers per ISO-week (maandag-zondag). Daaruit volgen drie afgeleiden:
- Acute load (7d), som van de laatste 7 dagen. Wat je net aan het doen bent.
- Chronische load (28d / 4-wk gemiddelde), wat je consistente basis is. Dit getal vult de planner als "huidige weekkilometers".
- ACWR (Acute:Chronic Workload Ratio) = acute / chronic. Sportwetenschap (Gabbett 2016) wijst de "sweet spot" 0.8–1.3 aan; ≥ 1.5 markeren we als blessurerisico (rode toon op het dashboard).
Chronische trend: 8-weekse rolling average van weekvolume, maandelijks gesampled (laatste 36 maanden). Dit is de blauwe lijn in de trend-grafiek.
Historische piek (peak_cap_km): hoogste 4-weeks gemiddelde dat je ooit haalde, fungeert als veilig plafond voor het piekvolume in de planner.
Persoonlijke ramp (ramp_pct_per_week): mediaan van je historische week-over-week groei in 6-wekenvensters waarin je ≥ 25 km/wk draaide, geclamped op 4–15%. Dit is jouw eigen "veilige opbouwsnelheid", niet de generieke 10%-regel.
Trainability, kun je nu een blok aan?
Een samengestelde score op 4 axes die antwoord geeft op: "is dit een goed moment om een planning te starten?"
- Consistency, % van laatste 12 weken met ≥ 3 runs.
- ACWR-band, straft uitschieters (acute load > 1.5× chronic).
- Setback-vrij, kijkt naar onverklaarbare dips ≥ 40% in weekvolume; recente dip = score omlaag.
- Long-run consistency, typische long-run aanwezig + percentage van de weken.
De gemiddelde score (0–100) verschijnt als "Trainability" op je profielpagina. Hoog = klaar voor structurele opbouw; laag = eerst basis herstellen.
Hartslag, zones & aerobic efficiency
Alleen runs met opgenomen hartslag tellen mee. We halen HRmax niet uit een formule (220-leeftijd is onnauwkeurig) maar uit jouw eigen data: gemiddelde van de top-2% hoogste max-heart-rates over alle runs. Robuust tegen uitschieters.
Toon de cijfers
Z1 (Recovery) 60–70 % HRmax Z2 (Aerobic) 70–80 % HRmax ← langste deel easy runs Z3 (Tempo) 80–87 % HRmax Z4 (Threshold) 87–93 % HRmax Z5 (VO₂max) 93–100 % HRmax
- Avg HR recent (8wk), gemiddelde van avg_heart_rate van runs uit de laatste 8 weken (gewogen op duur).
- Easy-run HR compliance, % van easy-pace runs uit de laatste 12 weken (≥ 3 km, pace > threshold + 30 s/km) waar de gem. HR ≤ 78% HRmax bleef. Hoog = goede aerobic-discipline; laag = je easy runs zijn eigenlijk moderate.
- Aerobic efficiency trend, lineaire regressie van (snelheid m/min ÷ avg HR) door de tijd. Positief = je wordt zuiniger bij dezelfde inspanning. Sanity-bounds: 0.5 < eff < 4.0, HR ∈ [100, 210].
Growth outlook, hoe snel kun je nog groeien?
Op basis van vier factoren wijzen we een readiness-bucket toe:
- Rebuilding, chronisch < 15 km/wk. Eerst basis opbouwen.
- Developing, 15–25 km/wk, weinig recente blokken.
- Fit / Active, 25–45 km/wk, consistent.
- High volume, > 45 km/wk; marginale gains in plaats van grote sprongen.
De bucket bepaalt een basis-range voor verwachte VDOT-winst over 12 weken (low–high), die we dan aanpassen op:
- Experience (jaren consistent gedraaid).
- Recente VDOT-slope (positief = upgrade, dalend = downgrade).
- Setback-aanwezigheid in laatste 12 weken (volume-dip ≥ 40%).
De projectie wordt vertaald naar concrete winst (sec/km) op een 10k via race_time_from_vdot, en gerendered als de "Realistisch alternatief" tegel op de plan-pagina.
Suggested goal time, hoe komt de tool aan het voorstel?
Op de planner-pagina, zodra afstand + race-datum bekend zijn, doen we dit:
Toon de cijfers
weeks = (race_date − today) / 7 slope = clamp(vdot_slope_per_year, −3, +3) gain = clamp(slope × weeks/52, −4, +4) projected_vdot = current_vdot + gain suggest_vdot = endurance_adjusted_vdot(projected_vdot, distance, weekly_km) suggested_time_s = race_time_from_vdot(distance_m, suggest_vdot)
De trend wordt geplafonneerd op ±3 VDOT-punten per jaar. Reden: die trend komt uit een regressie over je béste inspanningen, en zo'n reeks stijgt bijna vanzelf zodra je meer data opbouwt. Ongeplafonneerd zouden we een toevallige opleving doortrekken tot een doeltijd die ver onder je beste run ooit ligt.
De drie chips zijn afgeleid van die projectie:
- Behoudend = projectie × 1.03 (3% trager dan projectie)
- Projectie = exact de tijd uit bovenstaande formule
- Stretch = projectie × 0.97 (3% sneller, vereist optimale uitvoering)
Feasibility, is dit doel realistisch?
Nadat je een doeltijd hebt ingevuld toetsen we het op twee axes:
- VDOT-as: required = VDOT die de doeltijd vraagt; projected = wat we voor race-datum verwachten op basis van slope.
- Volume-as: required = piekvolume nodig voor de afstand; projected = wat je vanuit chronisch + persoonlijke ramp kunt halen in de beschikbare weken, geclamped op je historische piek.
Per as: comfortable (≤ 0 delta) / stretching (≤ ~5%) / ambitious (≤ ~12%) / unrealistic (> 12%). De overall verdict is de slechtste van de twee.
Schema-opbouw
Vanuit huidige weekkilometers naar piek, dan taper:
- Ramp, wekelijkse stijging =
ramp_pct_per_week(jouw eigen, niet generieke 10%). Elke 4e week een cut-back (−25%). - Piek, heuristiek per afstand (10k ~70 km, HM ~90 km, marathon ~110 km), maar geclamped op
peak_cap_km(historische piek). - Taper, 2 weken voor marathon, 1 week voor kortere afstanden.
- Wekelijkse blokken, verdeeld over
days_per_week: 1 long, 1 quality (T/I/R afhankelijk van afstand), rest easy. - Niveau-classificatie, gebaseerd op jouw huidige VDOT (niet die van je doel). Een beginner met een ambitieus doel krijgt dus geen advanced-workouts.
- Long-run floor, in de eerste base-weken wordt de long-run niet onder je bestaande
typical_long_run_kmgezet (gecapt op 45% van het weekvolume, zodat de rest van de week niet uitgeperst wordt). - Setback-modus, als
last_setback_days_ago < 60: startvolume ×0.85, ramp ×0.7. Conservatief opbouwen na onderbreking.
Wat we (nog) niet doen — eerlijk:
- Feasibility-verdict wordt getoond, maar (nog) niet teruggevoerd in het schema. Een "unrealistic" doel krijgt nu hetzelfde plan.
- VDOT-trend (
vdot_slope_per_year) zit in de haalbaarheidscheck, maar stuurt de intensiteitsverdeling nog niet bij. - Archetype-personalisatie (Sprinter / Endurance / Hybrid) kleurt de UI, maar past nog geen workout-mix aan. Staat op de roadmap.
- Easy-pace HR-compliance meten we, maar gebruiken we nog niet om je easy-tempo aan te scherpen.
Welke ruwe data gebruiken we?
Per activiteit slaan we deze velden op (uit GPX/FIT/Strava-API):
Toon de cijfers
start_time, duration_s, distance_m, elevation_gain_m, avg_pace_s_per_km, avg_hr, max_hr (uit raw), sport, source, external_id, raw (volledige payload)
Bij Strava-bulk-exports verrijken we elke activiteit met velden uit activities.csv (opgeslagen onder raw.csv):
- Gear name (schoenmodel)
- Calories
- GAP distance (grade-adjusted)
- Weer: temperatuur, gevoelstemperatuur, vochtigheid, wind, neerslag, bewolking, UV
- Perceived effort + equivalent effort
Wat we niet gebruiken: leeftijd, geslacht, gewicht (we kennen ze niet), subjectieve self-reports, social signals.