Formules de Puissance en Cyclisme

Fondement Mathématique des Métriques Bike Analytics

Guide d'Implémentation

Cette page fournit des formules prêtes à copier-coller et des méthodes de calcul étape par étape pour toutes les métriques Bike Analytics. Utilisez-les pour des implémentations personnalisées, la vérification ou une compréhension approfondie de l'entraînement basé sur la puissance.

⚠️ Notes d'Implémentation

  • Toutes les valeurs de puissance en watts (W), temps en secondes sauf indication contraire
  • FTP et CP sont des seuils individuels—aucune valeur universelle
  • Toujours valider les entrées pour des plages raisonnables (0-2000W typique)
  • Gérer les cas limites (division par zéro, puissance négative)
  • Les données de puissance répétées des intervalles d'enregistrement de 1 seconde pour la précision

Vélo Métriques de Performance Essentielles

1. Training Stress Score (TSS)

Formule :

TSS = (durée_secondes × NP × IF) / (FTP × 3600) × 100
où IF = NP / FTP

Exemple Détaillé :

Scénario :Sortie de 2 heures, NP = 235W, FTP = 250W

  1. Calculateur IF : IF = 235 / 250 = 0.94
  2. Durée en secondes : 2 heures × 3600 = 7200 secondes
  3. TSS = (7200 × 235 × 0.94) / (250 × 3600) × 100
  4. TSS = 1,590,720 / 900,000 × 100 =176.7 TSS

Interprétation : Sortie d'entraînement difficile (>150 TSS), prévoir 2-3 jours de récupération

Implémentation JavaScript :

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. Puissance Normalisée (NP)

Algorithme (moyenne mobile de 30 secondes) :

1. Calculez la puissance moyenne de roulement sur 30 secondes pour l'ensemble du trajet
2. Augmentez chaque valeur de 30 secondes à la 4ème puissance
3. Faites la moyenne de toutes ces valeurs ^4
4. Prenez la 4ème racine de cette moyenne
NP = ⁴√ (moyenne de [30s_avg^4])

Pourquoi la Puissance 4 ?

La relation quartique (puissance 4) reflète le coût physiologique non linéaire des efforts variables. Une sortie avec des accélérations et des récupérations coûte plus d'énergie qu'une puissance constante à la même moyenne.

Exemple :

  • Sortie régulière : 200W pendant 1 heure → NP = 200W, Moyenne = 200W
  • Sortie variable : Alternance 300W/100W → Moyenne = 200W, NP = 225W

Même puissance moyenne, mais la sortie variable à un NP 12% plus élevé en raison du coût physiologique des accélérations

Implémentation JavaScript :

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. Facteur d'intensité (IF)

Formule :

PROTÉGER15X = NP / PROTÉGER10X

Plages d'Interprétation :

Plage IFNiveau d'EffortExemple d'Entraînement
< 0.75Récupération / FacileSortie de récupération active, Zone 1-2
0.75 - 0.85EnduranceLongue sortie régulière, base aérobie
0.85 - 0.95TempoEntraînement sweet spot, intervalles tempo
0.95 - 1.05SeuilIntervalles FTP, effort contre-la-montre
1.05 - 1.15VO₂maxIntervalles de 5 minutes, course de critérium
> 1.15AnaérobieSprints courts, attaques, accélérations VTT

Exemple de Calcul :

Scénario :NP = 235W, FTP = 250W

IF = 235 / 250 =0.94

Interprétation : Effort tempo élevé / sous-seuil, pendentif soutenable 2-3 heures

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

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

4.Indice de Variabilité (VI)

Formule :

VI = NP / Puissance moyenne

Interprétation par Discipline :

DisciplineVI TypiqueSignification
Route CLM / Effort Régulier1.00 - 1.05Puissance très constante, allure optimale
Course sur Route1.05 - 1.10Quelques accélérations, généralement régulières
Critérium1.10 - 1.20Accélérations et attaques fréquentes
VTT XC1.15 - 1.30+Très variable, accélérations constantes

Exemple de Calcul :

Course sur Route :NP = 240W, Puissance Moy = 230W

VI = 240 / 230 =1.04(allure régulière)

Course VTT :NP = 285W, Puissance Moy = 235W

VI = 285 / 235 =1.21(très variable, efforts par à-coups)

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' (Capacité Anaérobie)

5. Critical Power (CP) - Modèle Linéaire

Formule :

Temps = W' / (Puissance - CP)
Réorganisé : Puissance × Temps = CP × Temps + W'

Calcul à Partir de Plusieurs Efforts :

Nécessite 2-4 efforts maximaux à différentes durées (par ex., 3, 5, 12, 20 minutes)

Exemple de Données :

DuréePuissance (W)Travail Total (kJ)
3 min (180s)400W72 kJ
5 min (300s)365W109,5 kJ
12 min (720s)310W223,2 kJ
20 min (1200s)285W342 kJ

En utilisant la régression linéaire (Travail = CP × Temps + W') :

  • CP = 270W(pente de la ligne de régression)
  • W' = 18.5 kJ(ordonnée à l'origine)

Implémentation JavaScript :

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) - Modèle d'Équation Différentielle

Formules :

Dépense (quand P > CP) :
W'exp(t) = ∫(P(t) - CP) dt
Récupération (quand P < CP) :
W'rec(t) = W' × (1 - e^(-t/τ))
où τ = 546 × e^(-0,01 × ΔCP) + 316
et ΔCP = (CP - P(t))

Exemple Concret :

Caractéristiques du cycliste :CP = 270W, W' = 18.5 kJ

Scénario 1 - Attaque Difficile :

  • Le coureur accélère à 400W pendant 30 secondes
  • Dépense de W' : (400 - 270) × 30 = 3,900 J = 3.9 kJ
  • W'bal restant : 18.5 - 3.9 =14.6 kJ

Scénario 2 - Récupération :

  • Après l'attaque, redescend à 200W (70W sous CP) pendant 2 minutes
  • ΔCP = 270 - 200 = 70W
  • τ = 546 × e^(-0.01 × 70) + 316 = 588 secondes
  • Récupération en 120s : 18.5 × (1 - e^(-120/588)) =3.5 kJ récupérés
  • Nouveau W'bal : 14.6 + 3.5 =18.1 kJ

Implémentation JavaScript :

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

Tableau de gestion des performances (PMC) pour le cyclisme

7.Calculs CTL, ATL, TSB

Formules (Moyennes Mobiles Exponentiellement Pondérées) :

CTL_aujourd'hui = CTL_hier + (TSS_aujourd'hui - CTL_hier) / 42
ATL_aujourd'hui = ATL_hier + (TSS_aujourd'hui - ATL_hier) / 7
TSB_aujourd'hui = CTL_hier - ATL_hier

Définitions des Métriques :

  • CTL (Chronic Training Load) :Moyenne exponentiellement pondérée sur 42 jours - représente la forme
  • ATL (Acute Training Load) :Moyenne exponentiellement pondérée sur 7 jours - représente la fatigue
  • TSB (Training Stress Balance) :Forme = Condition - Fatigue

Exemple Détaillé (Bloc d'Entraînement de 7 Jours) :

JourTSSCTLATLTSBStatut
Lun10075.080.0-5.0Entraînement
Mar5074.475.7-1.3Récupération
Mer12075.582.0-6.5Entraînement Difficile
Jeu073.770.3+3.4Jour de Repos
Ven8073.871.7+2.1Modéré
Sam15075.682.9-7.3Longue Sortie
Dim4074.876.8-2.0Récupération

Interprétation TSB :

Plage TSBStatutAction
< -30Risque ÉlevéAlerte surentraînement - réduire la charge
-30 à -10Entraînement IntensifConstruction de forme, surveiller la récupération
-10 à +5OptimalZone d'entraînement normale
+5 à +15Prêt à CourirForme de pointe - courir ce week-end
> +25DésentraînementPerte de forme - augmenter la charge

Implémentation JavaScript :

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

Rapport Poids-Puissance & Métriques d'Ascension

8. Rapport Poids-Puissance

Formule :

W/kg = Puissance (watts) / Masse corporelle (kg)

Repères FTP W/kg :

NiveauHomme W/kgFemme W/kgCatégorie
Récréatif2.5 - 3.52.0 - 3.0Cycliste loisir
Compétitif3.5 - 4.53.0 - 4.0Cat 3-4, coureur par groupes d'âge
Avancé4.5 - 5.54.0 - 5.0Cat 1-2, amateur fort
Élite Amateur5.5 - 6.05.0 - 5.5Niveau national
Professionnel6.0 - 7.0+5.5 - 6.5+World Tour, Grand Tour GC

Exemple de Calcul :

Scénario :Cycliste avec FTP = 275W, masse corporelle = 70kg

W/kg = 275 / 70 =3.93 W/kg

Interprétation : Niveau officiel, capable en courses vallonnées

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

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

9. VAM (Velocità Ascensionale Media)

Formule :

VAM (m/h) = Gain d'altitude (m) / Temps (heures)

Repères VAM :

VAM (m/h)NiveauExemple
600 - 900RécréatifCycliste club sur montée locale
900 - 1200CompétitifBon amateur sur Alpe d'Huez
1200 - 1500Élite AmateurGrimpeur niveau national
1500 - 1800ProfessionnelÉquipier World Tour
> 1800Vainqueur Grand TourPogačar, Vingegaard sur montées clés

Exemple de Calcul :

Scénario :Montée de l'Alpe d'Huez

  • Dénivelé positif : 1100 mètres
  • Temps : 55 minutes = 0.917 heures
  • VAM = 1100 / 0.917 =1200 m/h

Interprétation : Performance de grimpeur niveau compétitif

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

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

10. Estimation W/kg à Partir de VAM

Formule :

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

Exemple de Calcul :

Scénario :Montée avec pente moyenne de 8%, VAM = 1200 m/h

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

W/kg = 12 / 11 =4.36 W/kg

Vérification croisée : Avec un cycliste de 70kg → 305W de puissance soutenue en montée

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

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

Équation de Puissance Aérodynamique

11. Besoins en Puissance Totale

Formule Complète :

P_total = P_aéro + P_gravité + P_roulage + P_cinétique

Formules des Composantes :

Traînée Aérodynamique :
P_aéro = CdA × 0,5 × ρ × V³
Gravitationnelle (Montée) :
P_gravité = m × g × sin(θ) × V
Résistance au Roulement :
P_rolling = Crr × m × g × cos(θ) × V
Cinétique (Accélération) :
P_cinétique = m × a × V

Constantes & Variables :

  • CdA= Coefficient de traînée × surface frontale (m²)
    • Vélo route typique sur cocottes : 0.35-0.40 m²
    • Dans le cintre : 0.32-0.37 m²
    • Position contre-la-montre : 0.20-0.25 m²
  • ρ= Densité de l'air (1.225 kg/m³ au niveau de la mer, 15°C)
  • V= Vitesse (m/s)
  • m= Masse totale (cycliste + vélo, kg)
  • g= Gravité (9.81 m/s²)
  • θ= Angle de pente (radians ou degrés convertis)
  • Crr= Coefficient de résistance au roulement (~0.004 pour bons pneus route)
  • a= Accélération (m/s²)

Exemple Détaillé (CLM sur Route Plate) :

Scénario :

  • Vitesse : 40 km/h = 11.11 m/s
  • CdA : 0.22 m² (bonne position CLM)
  • Masse totale : 75kg (cycliste) + 8kg (vélo) = 83kg
  • Route plate (pente = 0°)
  • Vitesse constante (accélération = 0)

Calcul :

  1. P_aero= 0.22 × 0.5 × 1.225 × 11.11³ =185W
  2. P_gravity= 0W (route plate)
  3. P_rolling= 0.004 × 83 × 9.81 × 11.11 =36W
  4. P_cinétique= 0W (vitesse constante)
  5. P_total = 185 + 0 + 36 + 0 = 221W

Interprétation : Besoin de 221W pour maintenir 40 km/h en position CLM sur plaque de route

Implémentation JavaScript :

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 }

Fonctions Auxiliaires

Utilitaires de Conversion d'Unités

Implémentation JavaScript :

// 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)

Ressources d'Implémentation

Toutes les formules de cette page sont prêtes pour la production et validées par rapport à la littérature scientifique et aux données réelles de capteurs de puissance. Utilisez-les pour des outils d'analyse personnalisés, la vérification ou une compréhension approfondie des calculs d'entraînement adaptés à la puissance.

💡 Meilleures Pratiques

  • Valider les entrées :Vérifier les plages de puissance raisonnables (0-2000W), durées positives
  • Gérer les cas limites :Division par zéro, données null/undefined, FTP manquant
  • Arrondir de manière appropriée :CTL/ATL/TSB à 1 décimales, TSS en entier, W/kg à 2 décimales
  • Stocker la précision :Conserver la précision complète en base de données, arrondie uniquement pour l'affichage
  • Horaires des Fuseaux :Gérer UTC vs. heure locale de manière cohérente pour l'analyse multi-jours
  • Calibrage du capteur de puissance :Rappeler aux utilisateurs de faire le zéro avant les sorties
  • Validation FTP :Signaler les valeurs FTP suspectes (>500W ou <100W pour adultes)
  • Testeur minutieusement :Utiliser des fichiers de sortie validés pour vérifier les calculs

Données probantes et méthode éditoriale

AnalyticsZone explique des modèles publiés en sciences du sport, présente les formules et hypothèses, et relie les sources primaires ou officielles afin de vérifier la méthode.

Auteur: Albert Arnó, MD, PhD — fondateur d’onmedic (Barcelone), concepteur de systèmes eHealth depuis 2000.

Formules Puissance Cyclisme - Fondement Mathématique

Formules complètes puissance cyclisme : calcul TSS, algorithme NP, formule IF, équations modèle CP et suivi W'bal.

  • 2026-02-20
  • formules puissance cyclisme · formule TSS · formule puissance normalisée · formule puissance critique
  • Bibliographie