Формули за мощност в колоезденето

Математическата основа на метриките в Bike Analytics

Ръководство за внедряване

Тази страница предоставя формули и поетапни методи за изчисление на всички метрики в Bike Analytics. Използвайте ги за собствени разработки, проверка или по-дълбоко разбиране на тренировките, базирани на мощност.

⚠️ Бележки по внедряването

  • Всички стойности на мощността са във ватове (W), времето е в секунди, освен ако не е посочено друго
  • FTP и CP са индивидуални прагове — не съществуват универсални стойности
  • Винаги валидирайте входящите данни за разумни граници (обикновено 0-2000W)
  • Обръщайте внимание на крайни случаи (делене на нула, отрицателна мощност)
  • Данните за мощността изискват интервали на запис от 1 секунда за максимална точност

Основни показатели за представяне

1. Коефициент на тренировъчен стрес (TSS)

Формула:

TSS = (duration_seconds × NP × IF) / (FTP × 3600) × 100
където IF = NP / FTP

Примерен модел:

Сценарий: 2-часово каране, NP = 235W, FTP = 250W

  1. Изчислете IF: IF = 235 / 250 = 0.94
  2. Продължителност в секунди: 2 часа × 3600 = 7200 секунди
  3. TSS = (7200 × 235 × 0.94) / (250 × 3600) × 100
  4. TSS = 1,590,720 / 900,000 × 100 = 176.7 TSS

Интерпретация: Тежка тренировка (>150 TSS), очаквайте нужда от 2-3 дни възстановяване

JavaScript имплементация:

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

// Пример за употреба:
const tss = calculateTSS(7200, 235, 250);
// Връща: 177

2. Нормализирана мощност (NP)

Алгоритъм (30-секундна пълзяща средна):

1. Изчислява се 30-секундната пълзяща средна мощност за цялото каране
2. Всяка 30-секундна стойност се повдига на 4-та степен
3. Изчислява се средната стойност на всички тези резултати на 4-та степен
4. Взема се корен 4-ти от получената средна стойност
NP = ⁴√(average of [30s_avg^4])

Защо 4-та степен?

Квартичната зависимост (4-та степен) отразява нелинейния физиологичен разход при променливи усилия. Каране с резки ускорения и възстановявания изразходва повече енергия от каране с постоянна мощност при еднакво усреднено ниво.

Пример:

  • Постоянно каране: 200W за 1 час → NP = 200W, Средна мощност = 200W
  • Променливо каране: Редуване на 300W/100W → Средна мощност = 200W, NP = 225W

Еднаква средна мощност, но променливото каране има 12% по-високо NP поради физиологичната цена на ускоренията

JavaScript имплементация:

function calculateNormalizedPower(powerData) {
  // powerData е масив от 1-секундни стойности на мощността

  // Стъпка 1: Изчисляване на 30-секундни пълзящи средни
  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);
  }

  // Стъпка 2: Повдигане на 4-та степен
  const powered = rollingAvgs.map(p => Math.pow(p, 4));

  // Стъпка 3: Средна стойност на 4-тите степени
  const avgPowered = powered.reduce((sum, p) => sum + p, 0) / powered.length;

  // Стъпка 4: Извличане на корен 4-ти
  const np = Math.pow(avgPowered, 0.25);

  return Math.round(np);
}

// Пример за употреба:
const powerData = [/* масив с 1-секундни данни */];
const np = calculateNormalizedPower(powerData);
// Връща: NP във ватове

3. Фактор на интензивност (IF)

Формула:

IF = NP / FTP

Граници за интерпретация:

IF Обхват Ниво на усилие Примерна тренировка
< 0.75 Възстановяване / Леко Активно възстановяване, Зона 1-2
0.75 - 0.85 Издръжливост Дълго равномерно каране, аеробна база
0.85 - 0.95 Темпо Sweet spot тренировка, темпови интервали
0.95 - 1.05 Праг (Threshold) FTP интервали, бягане по часовник
1.05 - 1.15 VO₂max 5-минутни интервали, критериум
> 1.15 Анаеробно Кратки спринтове, атаки, MTB избухвания

Примерно изчисление:

Сценарий: NP = 235W, FTP = 250W

IF = 235 / 250 = 0.94

Интерпретация: Високо темпо / подпрагово усилие, устойчиво за 2-3 часа

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

// Пример:
const if_value = calculateIF(235, 250);
// Връща: 0.94

4. Индекс на вариативност (VI)

Формула:

VI = NP / Average Power

Интерпретация по дисциплини:

Дисциплина Типичен VI Значение
Шосе TT / Равномерно усилие 1.00 - 1.05 Много постоянна мощност, оптимално темпо
Шосейно състезание 1.05 - 1.10 Някои ускорения, предимно равномерно
Критериум 1.10 - 1.20 Чести ускорения и атаки
Mountain Bike XC 1.15 - 1.30+ Висока вариативност, константни изблици

Примерно изчисление:

Шосейно състезание: NP = 240W, Средна мощност = 230W

VI = 240 / 230 = 1.04 (равномерно темпо)

MTB състезание: NP = 285W, Средна мощност = 235W

VI = 285 / 235 = 1.21 (силно променливо, интервални усилия)

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

// Пример:
const vi_road = calculateVI(240, 230);  // Връща: 1.04
const vi_mtb = calculateVI(285, 235);   // Връща: 1.21

Критична мощност и W' (Анаеробен капацитет)

5. Критична мощност (CP) - Линеен модел

Формула:

Time = W' / (Power - CP)
Преобразувана: Power × Time = CP × Time + W'

Изчисление от множество усилия:

Изисква 2-4 максимални усилия с различна продължителност (напр. 3, 5, 12, 20 минути)

Примерни данни:

Продължителност Мощност (W) Обща работа (kJ)
3 мин (180s) 400W 72 kJ
5 мин (300s) 365W 109.5 kJ
12 мин (720s) 310W 223.2 kJ
20 мин (1200s) 285W 342 kJ

Използвайки линейна регресия (Work = CP × Time + W'):

  • CP = 270W (наклон на регресионната линия)
  • W' = 18.5 kJ (пресечна точка с оста y)

JavaScript имплементация:

function calculateCP_Linear(efforts) {
  // efforts = [{duration: секунди, power: ватове}, ...]

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

  // Линейна регресия: 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,      // ватове
    Wprime: Math.round(Wprime * 10) / 10  // kJ
  };
}

// Пример за употреба:
const efforts = [
  {duration: 180, power: 400},
  {duration: 300, power: 365},
  {duration: 720, power: 310},
  {duration: 1200, power: 285}
];

const result = calculateCP_Linear(efforts);
// Връща: { CP: 270.0, Wprime: 18.5 }

6. W' Balance (W'bal) - Диференциален модел

Формули:

Изразходване (при P > CP):
W'exp(t) = ∫(P(t) - CP) dt
Възстановяване (при P < CP):
W'rec(t) = W' × (1 - e^(-t/τ))
където τ = 546 × e^(-0.01 × ΔCP) + 316
и ΔCP = (CP - P(t))

Пример от реалния свят:

Профил на колоездача: CP = 270W, W' = 18.5 kJ

Сценарий 1 - Тежка атака:

  • Колоездачът ускорява до 400W за 30 секунди
  • W' разход: (400 - 270) × 30 = 3,900 J = 3.9 kJ
  • Оставащ W'bal: 18.5 - 3.9 = 14.6 kJ

Сценарий 2 - Възстановяване:

  • След атаката пада на 200W (70W под CP) за 2 минути
  • ΔCP = 270 - 200 = 70W
  • τ = 546 × e^(-0.01 × 70) + 316 = 588 секунди
  • Възстановяване за 120s: 18.5 × (1 - e^(-120/588)) = 3.5 kJ възстановени
  • Нов W'bal: 14.6 + 3.5 = 18.1 kJ

JavaScript имплементация:

function calculateWbalance(powerData, CP, Wprime) {
  // powerData = масив от {time: секунди, power: ватове}
  let wbal = Wprime * 1000; // Преобразуване в джаули
  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) {
      // Разход над CP
      const expenditure = (power - CP) * dt;
      wbal -= expenditure;
    } else {
      // Възстановяване под 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;
    }

    // Уверяване, че W'bal не надвишава макс или не пада под нула
    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;
}

// Пример за употреба:
const powerData = [
  {time: 0, power: 200},
  {time: 1, power: 210},
  // ... останалите данни
];

const wbalHistory = calculateWbalance(powerData, 270, 18.5);
// Връща масив от стойности за W'bal във времето

Диаграма за управление на представянето (PMC)

7. Изчисления на CTL, ATL, TSB

Формули (експоненциално претеглени пълзящи средни):

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

Дефиниции на метриките:

  • CTL (Chronic Training Load): 42-дневна експоненциално претеглена средна — представлява вашата физическа форма (fitness)
  • ATL (Acute Training Load): 7-дневна експоненциално претеглена средна — представлява натрупаната умора (fatigue)
  • TSB (Training Stress Balance): Форма = Физическа форма - Умора

Работен пример (7-дневен тренировъчен блок):

Ден TSS CTL ATL TSB Статус
Пон 100 75.0 80.0 -5.0 Тренировка
Вто 50 74.4 75.7 -1.3 Възстановяване
Сря 120 75.5 82.0 -6.5 Тежка тренировка
Чет 0 73.7 70.3 +3.4 Почивен ден
Пет 80 73.8 71.7 +2.1 Умерена
Съб 150 75.6 82.9 -7.3 Дълго каране
Нед 40 74.8 76.8 -2.0 Възстановяване

Интерпретация на TSB:

TSB Обхват Статус Действие
< -30 Висок риск Предупреждение за претрениране — намалете натоварването
-30 до -10 Тежка тренировка Изграждане на форма, следете възстановяването
-10 до +5 Оптимално Нормална тренировъчна зона
+5 до +15 Готов за състезание Пикова форма — подходящо за състезание
> +25 Загуба на форма Липса на стимул — увеличете натоварването

JavaScript имплементация:

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

  workouts.forEach(workout => {
    // Обновяване на CTL (42-дневна времева константа)
    ctl = ctl + (workout.tss - ctl) / 42;

    // Обновяване на ATL (7-дневна времева константа)
    atl = atl + (workout.tss - atl) / 7;

    // Изчисляване на TSB (CTL от вчера - ATL от днес за стандартно изчисление)
    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";
}

// Пример за употреба:
const workouts = [
  {date: "2025-01-01", tss: 100},
  {date: "2025-01-02", tss: 50},
  {date: "2025-01-03", tss: 120},
  // ... още тренировки
];

const pmc = calculatePMC(workouts);
// Връща масив с CTL, ATL, TSB за всеки ден

Мощност към тегло и изкачване

8. Съотношение мощност-тегло

Формула:

W/kg = Power (watts) / Body Mass (kg)

FTP W/kg Бенчмаркове:

Ниво Мъже W/kg Жени W/kg Категория
Любителско 2.5 - 3.5 2.0 - 3.0 Фитнес колоездач
Състезателно 3.5 - 4.5 3.0 - 4.0 Кат 3-4, ветерани
Напреднало 4.5 - 5.5 4.0 - 5.0 Кат 1-2, силен аматьор
Елитен аматьор 5.5 - 6.0 5.0 - 5.5 Национално ниво
Професионално 6.0 - 7.0+ 5.5 - 6.5+ World Tour, Гран Тур GC

Примерно изчисление:

Сценарий: Колоездач с FTP = 275W, телесна маса = 70кг

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

Интерпретация: Състезателно ниво, подходящо за хълмисти състезания

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

// Пример:
const wpkg = calculateWattsPerKg(275, 70);
// Връща: 3.93

9. VAM (Velocità Ascensionale Media)

Формула:

VAM (m/h) = Elevation Gain (m) / Time (hours)

VAM Бенчмаркове (m/h):

VAM (m/h) Ниво Пример
600 - 900 Любителско Клубен колоездач на местно изкачване
900 - 1200 Състезателно Добър аматьор на Алп д'Юез
1200 - 1500 Елитен аматьор Катерач на национално ниво
1500 - 1800 Професионално World Tour грегари
> 1800 Гран Тур Победител Погачар, Вингегор на ключови височини

Примерно изчисление:

Сценарий: Изкачване на Алп д'Юез

  • Денивелация: 1100 метра
  • Време: 55 минути = 0.917 часа
  • VAM = 1100 / 0.917 = 1200 m/h

Интерпретация: Представяне на състезателно ниво

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

// Пример:
const vam = calculateVAM(1100, 55);
// Връща: 1200 m/h

10. Оценка на W/kg от VAM

Формула:

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

Примерно изчисление:

Сценарий: Изкачване с 8% среден наклон, VAM = 1200 m/h

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

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

Проверка: При колоездач 70кг → 305W поддържана мощност на изкачването

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

// Пример:
const wkg = estimateWkgFromVAM(1200, 8);
// Връща: 4.36

Уравнение за аеродинамична мощност

11. Общи изисквания за мощност

Пълна формула:

P_total = (P_aero + P_rolling + P_gravity + P_drivetrain) / Efficiency

Където P_aero е доминиращият компонент при високи скорости (над 30 км/ч).