Pyöräilyn tehokaavat

Pyöräanalyysin mittareiden matemaattinen perusta

Käyttöönottoopas

Tällä sivulla on kopioi-liitä -kaavat ja vaiheittaiset laskentamenetelmät kaikille Bike Analytics -mittareille. Käytä näitä mukautettuihin toteutuksiin, todentamiseen tai tehopohjaisen koulutuksen syvempään ymmärtämiseen.

⚠️ Toteutusohjeet

  • Kaikki tehoarvot watteina (W), aika sekunteina, ellei toisin mainita
  • FTP ja CP ovat yksilökohtaisia ​​kynnysarvoja – ei universaaleja arvoja
  • Tarkista aina tulot kohtuullisilla alueilla (tyypillisesti 0-2000 W)
  • Käsittele reunatapauksia (jako nollalla, negatiivinen potenssi)
  • Tehotiedot vaativat 1 sekunnin tallennusvälin tarkkuuden vuoksi

Pyöräily Suorituskyvyn perustiedot

1. Harjoittelun stressipisteet (TSS)

Kaava:

TSS = (kesto_sekuntia × NP × IF) / (FTP × 3600) × 100
missä IF = NP / FTP

Toiminut esimerkki:

Skenaario:2 tunnin ajo, NP = 235W, FTP = 250W

  1. Laske IF: IF = 235 / 250 = 0,94
  2. Kesto sekunteina: 2 tuntia × 3600 = 7200 sekuntia
  3. TSS = (7200 × 235 × 0,94) / (250 × 3600) × 100
  4. TSS = 1 590 720 / 900 000 × 100 =176.7 TSS

Tulkinta: Kova harjoitusajo (>150 TSS), odota 2–3 päivän palautumista

JavaScriptin toteutus:

function calculateTSS(durationSeconds, normalizedPower, ftp) {
  const intensityFactor = normalizedPower / ftp;
  const tss = (durationSeconds * normalizedPower * intensityFactor) / (ftp * 3600) * 100;
  return Math.round(tss);
}

// Example usage:
const tss = calculateTSS(7200, 235, 250);
// Returns: 177

2. Normalisoitu teho (NP)

Algoritmi (30 sekunnin liukuva keskiarvo):

1. Laske 30 sekunnin liukuva keskimääräinen teho koko matkalle
2. Nosta jokainen 30 sekunnin arvo neljänteen potenssiin
3. Ota kaikkien näiden ^4 arvojen keskiarvo
4. Ota neljäs juuri tuosta keskiarvosta
NP = ⁴√ (keskiarvo [30s_avg^4])

Miksi neljäs voima?

Kvarttinen (4. potenssi) suhde heijastaa muuttuvien ponnistelujen epälineaarista fysiologista hintaa. Ajo, jossa on jännitteitä ja palautumia, maksaa enemmän energiaa kuin tasainen teho samalla keskiarvolla.

Esimerkki:

  • Tasainen ajo: 200 W 1 tunnin ajan → NP = 200 W, keskiarvo = 200 W
  • Muuttuva ajo: Vuorotteleva 300W/100W → Keskiarvo = 200W, NP = 225W

Sama keskimääräinen teho, mutta vaihtelevalla ajonopeudella on 12 % korkeampi NP ylijännitteiden fysiologisten kustannusten vuoksi

JavaScriptin toteutus:

function calculateNormalizedPower(powerData) {
  // powerData is array of 1-second power values

  // Step 1: Calculate 30-second rolling averages
  const rollingAvgs = [];
  for (let i = 29; i < powerData.length; i++) {
    const window = powerData.slice(i - 29, i + 1);
    const avg = window.reduce((sum, p) => sum + p, 0) / 30;
    rollingAvgs.push(avg);
  }

  // Step 2: Raise to 4th power
  const powered = rollingAvgs.map(p => Math.pow(p, 4));

  // Step 3: Average of 4th powers
  const avgPowered = powered.reduce((sum, p) => sum + p, 0) / powered.length;

  // Step 4: Take 4th root
  const np = Math.pow(avgPowered, 0.25);

  return Math.round(np);
}

// Example usage:
const powerData = [/* 1-second power array */];
const np = calculateNormalizedPower(powerData);
// Returns: NP in watts

3. Intensity Factor (IF)

Kaava:

IF = NP / FTP

Tulkinta-alueet:

IF valikoimaPyyntiponnistustasoEsimerkkiharjoitus
< 0,75Palautuminen / HelppoAktiivinen palautusajo, vyöhyke 1-2
0,75 - 0,85KestävyysPitkä tasainen matka, aerobinen pohja
0,85 - 0,95TempoSweet spot -harjoittelu, tempovälit
0,95 - 1,05KynnysFTP intervallit, aika-ajoponnistus
1,05 - 1,15VO₂max5 minuutin väliajat, kriteerikilpailu
> 1,15AnaerobinenLyhyet sprintit, hyökkäykset, MTB-purskeet

Laskentaesimerkki:

Skenaario:NP = 235 W, FTP = 250 W

IF = 235 / 250 =0,94

Tulkinta: Korkeatempoinen / kynnyksen alapuolella oleva ponnistus, kestävä 2-3 tuntia

function calculateIF(normalizedPower, ftp) {
  return (normalizedPower / ftp).toFixed(2);
}

// Example:
const if_value = calculateIF(235, 250);
// Returns: 0.94

4.Vaihtuvuusindeksi (VI)

Kaava:

VI = NP / keskimääräinen teho

Tulkinta tieteenalojen mukaan:

KuriTyypillinen VIMerkitys
Tie TT / Tasainen ponnistus1,00 - 1,05Erittäin tasainen teho, optimaalinen tahdistus
Maantieajo1,05 - 1,10Joitakin jännitteitä, yleensä tasaisia ​​
Kriteeri1,10 - 1,20Toistuvat kiihdytykset ja hyökkäykset
Maastopyörä XC1,15 - 1,30+Erittäin vaihtelevat, jatkuvat jännitteet

Laskentaesimerkki:

Road Race:NP = 240 W, keskimääräinen teho = 230 W

VI = 240 / 230 =1,04(tasainen tahdistus)

MTB Race:NP = 285 W, keskimääräinen teho = 235 W

VI = 285 / 235 =1,21(erittäin vaihteleva, purskeet)

function calculateVI(normalizedPower, averagePower) {
  return (normalizedPower / averagePower).toFixed(2);
}

// Example:
const vi_road = calculateVI(240, 230);  // Returns: 1.04
const vi_mtb = calculateVI(285, 235);   // Returns: 1.21

Critical Power & W' (anaerobinen kapasiteetti)

5. Kriittinen teho (CP) - Lineaarinen malli

Kaava:

Aika = W' / (teho - CP)
Järjestetty uudelleen: teho × aika = CP × aika + W'

Laskelma useista yrityksistä:

Vaatii 2–4 maksimiponnistusta eri kestoisin (esim. 3, 5, 12, 20 minuuttia)

Esimerkkitiedot:

KestoTeho (W)Työ yhteensä (kJ)
3 min (180s)400W72 kJ
5 min (300 s)365W109,5 kJ
12 min (720 s)310W223,2 kJ
20 min (1200s)285W342 kJ

Lineaarista regressiota käyttämällä (työ = CP × aika + W'):

  • CP = 270 W(regressioviivan kaltevuus)
  • W' = 18,5 kJ(y-leikkaus)

JavaScriptin toteutus:

function calculateCP_Linear(efforts) {
  // efforts = [{duration: seconds, power: watts}, ...]

  const times = efforts.map(e => e.duration);
  const work = efforts.map(e => e.power * e.duration / 1000); // kJ

  // Linear regression: work = CP * time + W'
  const n = efforts.length;
  const sumT = times.reduce((a, b) => a + b, 0);
  const sumW = work.reduce((a, b) => a + b, 0);
  const sumTW = times.reduce((sum, t, i) => sum + t * work[i], 0);
  const sumTT = times.reduce((sum, t) => sum + t * t, 0);

  const CP = (n * sumTW - sumT * sumW) / (n * sumTT - sumT * sumT);
  const Wprime = (sumW - CP * sumT) / n;

  return {
    CP: Math.round(CP * 10) / 10,      // watts
    Wprime: Math.round(Wprime * 10) / 10  // kJ
  };
}

// Example usage:
const efforts = [
  {duration: 180, power: 400},
  {duration: 300, power: 365},
  {duration: 720, power: 310},
  {duration: 1200, power: 285}
];

const result = calculateCP_Linear(efforts);
// Returns: { CP: 270.0, Wprime: 18.5 }

6. W' Balance (W'bal) - Differentiaaliyhtälömalli

Kaavat:

Menot (kun P > CP):
W'exp(t) = ∫(P(t) - CP) dt
Palautuminen (kun P < CP):
W'rec(t) = W' × (1 - e^(-t/τ))
missä τ = 546 × e^(-0,01 × ΔCP) + 316
ja ΔCP = (CP - P(t))

Tosimaailman esimerkki:

Pyöräilijän tiedot:CP = 270 W, W' = 18,5 kJ

Skenaario 1 - Kova hyökkäys:

  • Rider nousee 400 W:iin 30 sekunniksi
  • W'-kulut: (400 - 270) × 30 = 3 900 J = 3,9 kJ
  • W'bal jäljellä: 18,5 - 3,9 =14,6 kJ

Skenaario 2 – Palautuminen:

  • Hyökkäyksen jälkeen se laskee 200 W:iin (70 W alle CP:n) 2 minuutiksi
  • ΔCP = 270 - 200 = 70 W
  • τ = 546 × e^(-0,01 × 70) + 316 = 588 sekuntia
  • Palautuminen 120 sekunnissa: 18,5 × (1 - e^(-120/588)) =3,5 kJ talteen
  • Uusi W'bal: 14,6 + 3,5 =18,1 kJ

JavaScriptin toteutus:

function calculateWbalance(powerData, CP, Wprime) {
  // powerData = array of {time: seconds, power: watts}
  let wbal = Wprime * 1000; // Convert to joules
  const wbalHistory = [];

  for (let i = 1; i < powerData.length; i++) {
    const dt = powerData[i].time - powerData[i-1].time;
    const power = powerData[i].power;

    if (power > CP) {
      // Expenditure above CP
      const expenditure = (power - CP) * dt;
      wbal -= expenditure;
    } else {
      // Recovery below CP
      const deltaCP = CP - power;
      const tau = 546 * Math.exp(-0.01 * deltaCP) + 316;
      const recovery = (Wprime * 1000 - wbal) * (1 - Math.exp(-dt / tau));
      wbal += recovery;
    }

    // Ensure W'bal doesn't exceed max or go negative
    wbal = Math.max(0, Math.min(wbal, Wprime * 1000));

    wbalHistory.push({
      time: powerData[i].time,
      wbal: wbal / 1000, // kJ
      percent: (wbal / (Wprime * 1000)) * 100
    });
  }

  return wbalHistory;
}

// Example usage:
const powerData = [
  {time: 0, power: 200},
  {time: 1, power: 210},
  // ... rest of ride data
];

const wbalHistory = calculateWbalance(powerData, 270, 18.5);
// Returns array of W'bal values over time

Suorituskyvyn hallintakaavio (PMC) Pyöräilyä varten

7. CTL, ATL, TSB laskelmat

Kaavat (eksponentiaalisesti painotetut liukuvat keskiarvot):

CTL_today = CTL_yesterday + (TSS_today - CTL_yesterday) / 42
ATL_today = ATL_yesterday + (TSS_today - ATL_yesterday) / 7
TSB_today = CTL_yesterday - ATL_yesterday

Metrinen määritelmät:

  • CTL (krooninen harjoituskuorma):42 päivän eksponentiaalisesti painotettu keskiarvo - edustaa kuntoa
  • ATL (akuutti harjoituskuorma):7 päivän eksponentiaalisesti painotettu keskiarvo - edustaa väsymystä
  • TSB (harjoittelun stressitasapaino):Muoto = Kunto - Väsymys

Työstetty esimerkki (7 päivän koulutusjakso):

PäiväTSSCTLATLTSBTila
ma10075,080,0-5,0Koulutus
Ti5074,475,7-1,3Takaisinperintä
ke12075,582,0-6,5Kova koulutus
to073,770,3+3,4Lepopäivä
pe8073,871,7+2,1Kohtalainen
la15075,682,9-7,3Pitkä matka
Aurinko4074,876,8-2,0Takaisinperintä

TSB Tulkinta:

TSB valikoimaTilaToimenpide
< -30Suuri riskiYlikuntovaroitus - vähennä kuormitusta
-30 - -10Harjoittelu kovaaKuntoilun rakentaminen, palautumisen seuranta
-10 - +5OptimaalinenNormaali harjoitusalue
+5 - +15Kilpailu valmiinaHuippumuoto - kilpailu tänä viikonloppuna
> +25Koulutuksen lopettaminenKunnon menetys - lisää kuormaa

JavaScriptin toteutus:

function calculatePMC(workouts) {
  // workouts = [{date: "YYYY-MM-DD", tss: number}, ...]
  let ctl = 0, atl = 0;
  const results = [];

  workouts.forEach(workout => {
    // Update CTL (42-day time constant)
    ctl = ctl + (workout.tss - ctl) / 42;

    // Update ATL (7-day time constant)
    atl = atl + (workout.tss - atl) / 7;

    // Calculate TSB (yesterday's CTL - today's ATL for traditional calculation)
    // For simplicity here using current values
    const tsb = ctl - atl;

    results.push({
      date: workout.date,
      tss: workout.tss,
      ctl: Math.round(ctl * 10) / 10,
      atl: Math.round(atl * 10) / 10,
      tsb: Math.round(tsb * 10) / 10,
      status: getTSBStatus(tsb)
    });
  });

  return results;
}

function getTSBStatus(tsb) {
  if (tsb < -30) return "High Risk";
  if (tsb < -10) return "Training Hard";
  if (tsb < 5) return "Optimal";
  if (tsb < 15) return "Race Ready";
  return "Detraining";
}

// Example usage:
const workouts = [
  {date: "2025-01-01", tss: 100},
  {date: "2025-01-02", tss: 50},
  {date: "2025-01-03", tss: 120},
  // ... more workouts
];

const pmc = calculatePMC(workouts);
// Returns array with CTL, ATL, TSB for each day

Teho-paino- ja kiipeilymittarit

8.Tehon ja painon suhde

Kaava:

W/kg = teho (wattia) / kehon massa (kg)

FTP W/kg Vertailuarvot:

TasoUros W/kgNaaras W/kgLuokka
Virkistys2,5 - 3,52,0 - 3,0Kuntosali
Kilpailukykyinen3,5 - 4,53,0 - 4,0Cat 3-4, ikäluokan kilpailija
Edistynyt4,5 - 5,54,0 - 5,0Kissa 1-2, vahva amatööri
Elite Amatööri5,5 - 6,05,0 - 5,5Kansallinen taso
Ammattilainen6,0 - 7,0+5,5 - 6,5+World Tour, Grand Tour GC

Laskentaesimerkki:

Skenaario:Pyöräilijä, jossa FTP = 275W, paino = 70kg

W/kg = 275 / 70 =3,93 W/kg

Tulkinta: Kilpailukykyinen taso, kykenevä mäkisiin kilpailuihin

function calculateWattsPerKg(power, bodyMassKg) {
  return (power / bodyMassKg).toFixed(2);
}

// Example:
const wpkg = calculateWattsPerKg(275, 70);
// Returns: 3.93

9. VAM (Velocità Ascensionale Media)

Kaava:

VAM (m/h) = korkeusvahvistus (m) / aika (tuntia)

VAM-vertailuarvot:

VAM (m/h)TasoEsimerkki
600 - 900VirkistysKlubin ratsastaja paikallisessa nousussa
900 - 1200KilpailukykyinenHyvä amatööri Alpe d'Huezissa
1200 - 1500Elite AmatööriKansallisen tason kiipeilijä
1500 - 1800AmmattilainenWorld Tour kotimainen
> 1800Grand Tour -voittajaPogačar, Vingegaard avainkiipeilyissä

Laskentaesimerkki:

Skenaario:Alpe d'Huez -kiipeily

  • Korkeusnousu: 1100 metriä
  • Aika: 55 minuuttia = 0,917 tuntia
  • VAM = 1100 / 0,917 =1200 m/h

Tulkinta: Kilpailutason kiipeilysuoritus

function calculateVAM(elevationGainMeters, timeMinutes) {
  const hours = timeMinutes / 60;
  return Math.round(elevationGainMeters / hours);
}

// Example:
const vam = calculateVAM(1100, 55);
// Returns: 1200 m/h

10. VAM to W/kg arvio

Kaava:

W/kg ≈ VAM (m/h) / 100 / (gradientti % + 3)

Laskentaesimerkki:

Skenaario:Kiipeä 8 %:n keskigradientilla, VAM = 1200 m/h

W/kg = 1200 / 100 / (8 + 3)

W/kg = 12 / 11 =4,36 W/kg

Ristitarkastus: 70 kg painavalla kuljettajalla → 305 W jatkuvaa tehoa nousussa

function estimateWkgFromVAM(vam, gradientPercent) {
  return (vam / 100 / (gradientPercent + 3)).toFixed(2);
}

// Example:
const wkg = estimateWkgFromVAM(1200, 8);
// Returns: 4.36

Aerodynaaminen tehoyhtälö

11. Kokonaistehotarve

Täydellinen kaava:

P_yhteensä = P_aero + P_painovoima + P_rullaus + P_kineettinen

Komponenttikaavat:

Aerodynaaminen vastus:
P_aero = CdA × 0,5 × ρ × V³
Gravitaatio (kiipeily):
P_painovoima = m × g × sin(θ) × V
Vierintävastus:
P_rullaus = Crr × m × g × cos(θ) × V
Kineettinen (kiihtyvyys):
P_kineettinen = m × a × V

Vakiot ja muuttujat:

  • CdA= Vastuskerroin × etupinta-ala (m²)
    • Tyypilliset maantiepyörän suojukset: 0,35-0,40 m²
    • Pisarat: 0,32-0,37 m²
    • TT-sijainti: 0,20-0,25 m²
  • ρ= Ilman tiheys (1,225 kg/m³ merenpinnan tasolla, 15°C)
  • V= Nopeus (m/s)
  • m= Kokonaismassa (ajaja + pyörä, kg)
  • g= Painovoima (9,81 m/s²)
  • θ= Gradienttikulma (radiaaneja tai asteita muunnettu)
  • Crr= Vierintävastuskerroin (~0,004 hyville maantierenkaille)
  • a= Kiihtyvyys (m/s²)

Työstetty esimerkki (tasainen tie TT):

Skenaario:

  • Nopeus: 40 km/h = 11,11 m/s
  • CdA: 0,22 m² (hyvä TT-asento)
  • Kokonaismassa: 75kg (ratsastaja) + 8kg (pyörä) = 83kg
  • Tasainen tie (kaltevuus = 0°)
  • Vakionopeus (kiihtyvyys = 0)

Laskenta:

  1. P_aero= 0,22 × 0,5 × 1,225 × 11,11³ =185W
  2. P_painovoima= 0W (tasainen tie)
  3. P_rolling= 0,004 × 83 × 9,81 × 11,11 =36W
  4. P_kineettinen= 0W (vakionopeus)
  5. P_yhteensä= 185 + 0 + 36 + 0 =221W

Tulkinta: Tarvitsee 221 W nopeuden ylläpitämiseen 40 km/h TT-asennossa tasaisella tiellä

JavaScriptin toteutus:

function calculatePowerRequired(params) {
  const {
    velocityKph,
    CdA = 0.32,              // m²
    rho = 1.225,             // kg/m³
    mass = 83,               // kg (rider + bike)
    gradientPercent = 0,     // %
    Crr = 0.004,             // rolling resistance
    accelerationMps2 = 0     // m/s²
  } = params;

  // Convert velocity to m/s
  const V = velocityKph / 3.6;

  // Convert gradient to angle
  const theta = Math.atan(gradientPercent / 100);

  // Calculate each component
  const P_aero = CdA * 0.5 * rho * Math.pow(V, 3);
  const P_gravity = mass * 9.81 * Math.sin(theta) * V;
  const P_rolling = Crr * mass * 9.81 * Math.cos(theta) * V;
  const P_kinetic = mass * accelerationMps2 * V;

  return {
    total: Math.round(P_aero + P_gravity + P_rolling + P_kinetic),
    aero: Math.round(P_aero),
    gravity: Math.round(P_gravity),
    rolling: Math.round(P_rolling),
    kinetic: Math.round(P_kinetic)
  };
}

// Example: TT at 40 km/h
const power_tt = calculatePowerRequired({
  velocityKph: 40,
  CdA: 0.22,
  mass: 83,
  gradientPercent: 0
});
// Returns: { total: 221, aero: 185, gravity: 0, rolling: 36, kinetic: 0 }

// Example: 8% climb at 15 km/h
const power_climb = calculatePowerRequired({
  velocityKph: 15,
  CdA: 0.38,
  mass: 75,
  gradientPercent: 8
});
// Returns: { total: 265, aero: 27, gravity: 244, rolling: 11, kinetic: 0 }

Aputoiminnot

Yksikkömuunnosapuohjelmat

JavaScriptin toteutus:

// Time conversions
function hoursToSeconds(hours) {
  return hours * 3600;
}

function minutesToSeconds(minutes) {
  return minutes * 60;
}

function secondsToHours(seconds) {
  return seconds / 3600;
}

function formatDuration(seconds) {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = Math.round(seconds % 60);
  return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}

// Speed conversions
function kphToMps(kph) {
  return kph / 3.6;
}

function mpsToKph(mps) {
  return mps * 3.6;
}

// Energy conversions
function joulesTo kJ(joules) {
  return joules / 1000;
}

function kJToJoules(kJ) {
  return kJ * 1000;
}

function wattsToKJ(watts, durationSeconds) {
  return (watts * durationSeconds) / 1000;
}

// Examples:
formatDuration(7265);        // Returns: "2:01:05"
kphToMps(40);                // Returns: 11.11 m/s
wattsToKJ(250, 3600);        // Returns: 900 kJ (1 hour at 250W)

Toteutusresurssit

Kaikki tällä sivulla olevat kaavat ovat tuotantovalmiita ja validoituja tieteellisen kirjallisuuden ja todellisten tehomittaritietojen perusteella. Käytä niitä mukautettuihin analytiikkatyökaluihin, todentamiseen tai tehopohjaisten harjoittelulaskelmien syvempään ymmärtämiseen.

💡 Parhaat käytännöt

  • Vahvista syötteet:Tarkista kohtuulliset tehoalueet (0-2000W), positiiviset kestoajat
  • Kahvan reunakotelot:Jako nollalla, nolla/määrittämätön data, puuttuu FTP
  • Pyöristä asianmukaisesti:CTL/ATL/TSB 1 desimaalin tarkkuudella, TSS kokonaislukuina, W/kg 2 desimaalin tarkkuudella
  • Tallennustarkkuus:Säilytä täysi tarkkuus tietokannassa, pyöreä vain näyttöä varten
  • Aikavyöhykkeet:Käsittele UTC vs.paikallista aikaa johdonmukaisesti usean päivän analyysiä varten
  • Tehomittarin kalibrointi:Muistuta käyttäjiä nolla-offsetista ennen ajoa
  • FTP-vahvistus:Ilmoita epäilyttävät FTP-arvot (>500W tai <100W aikuisille)
  • Testaa perusteellisesti:Käytä tunnettuja ajotiedostoja vahvistaaksesi laskelmat