Các công thức Công suất Đạp xe
Nền tảng toán học của các chỉ số trong Bike Analytics
Hướng dẫn triển khai
Trang này cung cấp các công thức có thể sao chép và các phương pháp tính toán từng bước cho tất cả các chỉ số của Bike Analytics. Hãy sử dụng chúng cho các lần triển khai tùy chỉnh, xác minh hoặc để hiểu sâu hơn về việc tập luyện dựa trên công suất.
⚠️ Lưu ý khi triển khai
- Tất cả các giá trị công suất tính bằng watt (W), thời gian tính bằng giây trừ khi có quy định khác
- FTP và CP là các ngưỡng đặc thù của từng cá nhân—không có giá trị chung cho tất cả
- Luôn xác thực dữ liệu đầu vào trong phạm vi hợp lý (thường là 0-2000W)
- Xử lý các trường hợp ngoại lệ (chia cho không, công suất âm)
- Dữ liệu công suất yêu cầu khoảng thời gian ghi 1 giây để đảm bảo độ chính xác
Các chỉ số Hiệu suất Cốt lõi
1. Điểm Căng thẳng Tập luyện (TSS)
Công thức:
Ví dụ cụ thể:
Kịch bản: Chuyến đạp 2 giờ, NP = 235W, FTP = 250W
- Tính IF: IF = 235 / 250 = 0,94
- Thời gian tính bằng giây: 2 giờ × 3600 = 7200 giây
- TSS = (7200 × 235 × 0,94) / (250 × 3600) × 100
- TSS = 1.590.720 / 900.000 × 100 = 176,7 TSS
Giải mã: Buổi tập nặng (>150 TSS), dự kiến cần 2-3 ngày phục hồi
Triển khai JavaScript:
function calculateTSS(durationSeconds, normalizedPower, ftp) {
const intensityFactor = normalizedPower / ftp;
const tss = (durationSeconds * normalizedPower * intensityFactor) / (ftp * 3600) * 100;
return Math.round(tss);
}
// Ví dụ sử dụng:
const tss = calculateTSS(7200, 235, 250);
// Trả về: 177
2. Công suất Chuẩn hóa (NP)
Thuật toán (Trung bình trượt 30 giây):
Tại sao lại dùng Lũy thừa 4?
Mối quan hệ bậc bốn (lũy thừa 4) phản ánh sự tiêu tốn sinh lý không tuyến tính của các nỗ lực biến thiên. Một chuyến đạp có các đợt bứt tốc và hồi phục sẽ tiêu tốn nhiều năng lượng hơn so với việc đạp ở mức công suất ổn định với cùng mức trung bình.
Ví dụ:
- Đạp ổn định: 200W trong 1 giờ → NP = 200W, Trung bình = 200W
- Đạp biến thiên: Luân phiên 300W/100W → Trung bình = 200W, NP = 225W
Cùng mức công suất trung bình, nhưng chuyến đạp biến thiên có NP cao hơn 12% do tiêu tốn sinh lý từ các đợt bứt tốc
Triển khai JavaScript:
function calculateNormalizedPower(powerData) {
// powerData là mảng các giá trị công suất từng giây
// Bước 1: Tính trung bình trượt 30 giây
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);
}
// Bước 2: Lũy thừa 4
const powered = rollingAvgs.map(p => Math.pow(p, 4));
// Bước 3: Trung bình của các lũy thừa 4
const avgPowered = powered.reduce((sum, p) => sum + p, 0) / powered.length;
// Bước 4: Khai căn bậc 4
const np = Math.pow(avgPowered, 0.25);
return Math.round(np);
}
// Ví dụ sử dụng:
const powerData = [/* mảng công suất từng giây */];
const np = calculateNormalizedPower(powerData);
// Trả về: NP tính bằng watts
3. Hệ số Cường độ (IF)
Công thức:
Các phạm vi giải mã:
| Phạm vi IF | Mức độ nỗ lực | Ví dụ buổi tập |
|---|---|---|
| < 0,75 | Phục hồi / Nhẹ nhàng | Đạp phục hồi chủ động, Vùng 1-2 |
| 0,75 - 0,85 | Sức bền | Đạp ổn định thời gian dài, nền tảng hiếu khí |
| 0,85 - 0,95 | Tempo | Tập luyện Sweet spot, các quãng tập tempo |
| 0,95 - 1,05 | Ngưỡng (Threshold) | Các quãng tập FTP, nỗ lực đua tính giờ |
| 1,05 - 1,15 | VO₂max | Các quãng tập 5 phút, đua criterium |
| > 1,15 | Kỵ khí (Anaerobic) | Nước rút ngắn, tấn công, bứt tốc MTB |
Ví dụ tính toán:
Kịch bản: NP = 235W, FTP = 250W
IF = 235 / 250 = 0,94
Giải mã: Nỗ lực tempo cao / cận ngưỡng, có thể duy trì trong 2-3 giờ
function calculateIF(normalizedPower, ftp) {
return (normalizedPower / ftp).toFixed(2);
}
// Ví dụ:
const if_value = calculateIF(235, 250);
// Trả về: 0.94
4. Chỉ số Biến thiên (VI)
Công thức:
Giải mã theo bộ môn:
| Bộ môn | VI điển hình | Ý nghĩa |
|---|---|---|
| Đua TT đường trường / Nỗ lực ổn định | 1,00 - 1,05 | Công suất rất nhất quán, phân phối lực tối ưu |
| Đua đường trường (Road) | 1,05 - 1,10 | Có một số đợt bứt tốc, nhìn chung là ổn định |
| Đua Criterium | 1,10 - 1,20 | Tăng tốc và tấn công thường xuyên |
| Mountain Bike XC | 1,15 - 1,30+ | Biến thiên rất cao, bứt tốc liên tục |
Ví dụ tính toán:
Đua đường trường: NP = 240W, Công suất TB = 230W
VI = 240 / 230 = 1,04 (phân phối lực ổn định)
Đua MTB: NP = 285W, Công suất TB = 235W
VI = 285 / 235 = 1,21 (biến thiên rất lớn, nỗ lực bùng nổ)
function calculateVI(normalizedPower, averagePower) {
return (normalizedPower / averagePower).toFixed(2);
}
// Ví dụ:
const vi_road = calculateVI(240, 230); // Trả về: 1.04
const vi_mtb = calculateVI(285, 235); // Trả về: 1.21
Công suất Tới hạn & W' (Khả năng kỵ khí)
5. Công suất Tới hạn (CP) - Mô hình Tuyến tính
Công thức:
Tính toán từ nhiều nỗ lực:
Yêu cầu 2-4 nỗ lực tối đa ở các khoảng thời gian khác nhau (ví dụ: 3, 5, 12, 20 phút)
Dữ liệu ví dụ:
| Thời gian | Công suất (W) | Tổng công thực hiện (kJ) |
|---|---|---|
| 3 phút (180s) | 400W | 72 kJ |
| 5 phút (300s) | 365W | 109,5 kJ |
| 12 phút (720s) | 310W | 223,2 kJ |
| 20 phút (1200s) | 285W | 342 kJ |
Sử dụng hồi quy tuyến tính (Tổng công = CP × Thời gian + W'):
- CP = 270W (độ dốc của đường hồi quy)
- W' = 18,5 kJ (giao điểm trục tung)
Triển khai 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
// Hồi quy tuyến tính: 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
};
}
// Ví dụ sử dụng:
const efforts = [
{duration: 180, power: 400},
{duration: 300, power: 365},
{duration: 720, power: 310},
{duration: 1200, power: 285}
];
const result = calculateCP_Linear(efforts);
// Trả về: { CP: 270.0, Wprime: 18.5 }
6. Cân bằng W' (W'bal) - Mô hình Phương trình Vi phân
Công thức:
W'exp(t) = ∫(P(t) - CP) dt
W'rec(t) = W' × (1 - e^(-t/τ))
và ΔCP = (CP - P(t))
Ví dụ thực tế:
Thông số người đạp: CP = 270W, W' = 18,5 kJ
Kịch bản 1 - Tấn công mạnh:
- Người đạp bứt tốc lên 400W trong 30 giây
- W' tiêu tốn: (400 - 270) × 30 = 3.900 J = 3,9 kJ
- W'bal còn lại: 18,5 - 3,9 = 14,6 kJ
Kịch bản 2 - Hồi phục:
- Sau khi tấn công, hạ xuống 200W (thấp hơn CP 70W) trong 2 phút
- ΔCP = 270 - 200 = 70W
- τ = 546 × e^(-0,01 × 70) + 316 = 588 giây
- Hồi phục trong 120s: 18,5 × (1 - e^(-120/588)) = 3,5 kJ được hồi phục
- W'bal mới: 14,6 + 3,5 = 18,1 kJ
Triển khai JavaScript:
function calculateWbalance(powerData, CP, Wprime) {
// powerData = mảng các {time: seconds, power: watts}
let wbal = Wprime * 1000; // Đổi sang 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) {
// Tiêu tốn trên mức CP
const expenditure = (power - CP) * dt;
wbal -= expenditure;
} else {
// Hồi phục dưới mức 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;
}
// Đảm bảo W'bal không vượt quá mức tối đa hoặc âm
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;
}
// Ví dụ sử dụng:
const powerData = [
{time: 0, power: 200},
{time: 1, power: 210},
// ... dữ liệu còn lại
];
const wbalHistory = calculateWbalance(powerData, 270, 18.5);
// Trả về mảng các giá trị W'bal theo thời gian
Biểu đồ Quản lý Hiệu suất (PMC)
7. Tính toán CTL, ATL, TSB
Công thức (Trung bình trượt lũy thừa):
Định nghĩa các chỉ số:
- CTL (Chronic Training Load): Trung bình trượt lũy thừa 42 ngày - đại diện cho Thể lực (Fitness)
- ATL (Acute Training Load): Trung bình trượt lũy thừa 7 ngày - đại diện cho Sự mệt mỏi (Fatigue)
- TSB (Training Stress Balance): Phong độ (Form) = Thể lực - Sự mệt mỏi
Ví dụ cụ thể (Khối tập luyện 7 ngày):
| Ngày | TSS | CTL | ATL | TSB | Trạng thái |
|---|---|---|---|---|---|
| Thứ 2 | 100 | 75,0 | 80,0 | -5,0 | Tập luyện |
| Thứ 3 | 50 | 74,4 | 75,7 | -1,3 | Phục hồi |
| Thứ 4 | 120 | 75,5 | 82,0 | -6,5 | Tập nặng |
| Thứ 5 | 0 | 73,7 | 70,3 | +3,4 | Ngày nghỉ |
| Thứ 6 | 80 | 73,8 | 71,7 | +2,1 | Vừa phải |
| Thứ 7 | 150 | 75,6 | 82,9 | -7,3 | Đạp dài |
| Chủ Nhật | 40 | 74,8 | 76,8 | -2,0 | Phục hồi |
Giải mã TSB:
| Phạm vi TSB | Trạng thái | Hành động |
|---|---|---|
| < -30 | Rủi ro cao | Cảnh báo tập quá sức - giảm khối lượng |
| -30 đến -10 | Tập luyện tích cực | Đang xây dựng thể lực, theo dõi phục hồi |
| -10 đến +5 | Tối ưu | Vùng tập luyện bình thường |
| +5 đến +15 | Sẵn sàng thi đấu | Phong độ đỉnh cao - thi đấu vào cuối tuần này |
| > +25 | Sụt giảm thể lực | Mất thể lực - nên tăng khối lượng tập |
Triển khai JavaScript:
function calculatePMC(workouts) {
// workouts = [{date: "YYYY-MM-DD", tss: number}, ...]
let ctl = 0, atl = 0;
const results = [];
workouts.forEach(workout => {
// Cập nhật CTL (hằng số thời gian 42 ngày)
ctl = ctl + (workout.tss - ctl) / 42;
// Cập nhật ATL (hằng số thời gian 7 ngày)
atl = atl + (workout.tss - atl) / 7;
// Tính TSB (CTL hôm qua - ATL hôm nay cho cách tính truyền thống)
// Để đơn giản ở đây dùng các giá trị hiện tại
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";
}
// Ví dụ:
const workouts = [
{date: "2025-01-01", tss: 100},
{date: "2025-01-02", tss: 50},
{date: "2025-01-03", tss: 120},
// ... thêm các buổi tập
];
const pmc = calculatePMC(workouts);
// Trả về mảng với các thông số CTL, ATL, TSB cho mỗi ngày
Công suất trên Trọng lượng & Các chỉ số Leo núi
8. Tỷ lệ Công suất trên Trọng lượng
Công thức:
Các mức chuẩn FTP W/kg:
| Cấp độ | Nam (W/kg) | Nữ (W/kg) | Phân loại |
|---|---|---|---|
| Giải trí | 2,5 - 3,5 | 2,0 - 3,0 | Đạp xe thể dục |
| Có tính cạnh tranh | 3,5 - 4,5 | 3,0 - 4,0 | Hệ phong trào, Cat 3-4 |
| Nâng cao | 4,5 - 5,5 | 4,0 - 5,0 | Hệ phong trào mạnh, Cat 1-2 |
| Nghiệp dư ưu tú | 5,5 - 6,0 | 5,0 - 5,5 | Cấp đội tuyển quốc gia |
| Chuyên nghiệp | 6,0 - 7,0+ | 5,5 - 6,5+ | World Tour, Grand Tour GC |
Ví dụ tính toán:
Kịch bản: Người đạp có FTP = 275W, nặng 70kg
W/kg = 275 / 70 = 3,93 W/kg
Giải mã: Cấp độ thi đấu tốt, có khả năng đua ở các chặng đồi núi
function calculateWattsPerKg(power, bodyMassKg) {
return (power / bodyMassKg).toFixed(2);
}
// Ví dụ:
const wpkg = calculateWattsPerKg(275, 70);
// Trả về: 3.93
9. VAM (Velocità Ascensionale Media)
Công thức:
Các mức chuẩn VAM:
| VAM (m/h) | Cấp độ | Ví dụ |
|---|---|---|
| 600 - 900 | Giải trí | Người đạp CLB trên các con dốc địa phương |
| 900 - 1200 | Có tính cạnh tranh | Người nghiệp dư khá trên Alpe d'Huez |
| 1200 - 1500 | Nghiệp dư ưu tú | Người chuyên leo núi cấp quốc gia |
| 1500 - 1800 | Chuyên nghiệp | VĐV hỗ trợ (domestique) World Tour |
| > 1800 | Vô địch Grand Tour | Pogačar, Vingegaard ở các con dốc quan trọng |
Ví dụ tính toán:
Kịch bản: Leo con dốc Alpe d'Huez
- Độ cao leo được: 1100 mét
- Thời gian: 55 phút = 0,917 giờ
- VAM = 1100 / 0,917 = 1200 m/h
Giải mã: Hiệu suất leo núi mức độ thi đấu tốt
function calculateVAM(elevationGainMeters, timeMinutes) {
const hours = timeMinutes / 60;
return Math.round(elevationGainMeters / hours);
}
// Ví dụ:
const vam = calculateVAM(1100, 55);
// Trả về: 1200 m/h
10. Ước tính W/kg từ VAM
Công thức:
Ví dụ tính toán:
Kịch bản: Leo dốc với độ dốc TB 8%, VAM = 1200 m/h
W/kg = 1200 / 100 / (8 + 3)
W/kg = 12 / 11 = 4,36 W/kg
Đối chiếu: Với người đạp nặng 70kg → công suất duy trì ~305W khi leo dốc
function estimateWkgFromVAM(vam, gradientPercent) {
return (vam / 100 / (gradientPercent + 3)).toFixed(2);
}
// Ví dụ:
const wkg = estimateWkgFromVAM(1200, 8);
// Trả về: 4.36
Phương trình Công suất Khí động học
11. Yêu cầu Công suất Tổng thể
Công thức đầy đủ:
Các công thức thành phần:
P_aero = CdA × 0,5 × ρ × V³
P_gravity = m × g × sin(θ) × V
P_rolling = Crr × m × g × cos(θ) × V
P_kinetic = m × a × V
Các hằng số & Biến số:
- CdA = Hệ số lực cản × diện tích mặt trước (m²)
- Tay trên hoods (xe road): 0,35-0,40 m²
- Tay dưới drops: 0,32-0,37 m²
- Tư thế TT: 0,20-0,25 m²
- ρ = Mật độ không khí (1,225 kg/m³ ở mực nước biển, 15°C)
- V = Vận tốc (m/s)
- m = Tổng khối lượng (người + xe, kg)
- g = Gia tốc trọng trường (9,81 m/s²)
- θ = Góc dốc (đổi từ độ hoặc radian)
- Crr = Hệ số lực cản lăn (~0,004 cho lốp road tốt)
- a = Gia tốc (m/s²)
Ví dụ cụ thể (Đua TT đường bằng):
Kịch bản:
- Vận tốc: 40 km/h = 11,11 m/s
- CdA: 0,22 m² (tư thế TT tốt)
- Tổng khối lượng: 75kg (người) + 8kg (xe) = 83kg
- Đường bằng (độ dốc = 0°)
- Tốc độ ổn định (gia tốc = 0)
Tính toán:
- P_aero = 0,22 × 0,5 × 1,225 × 11,11³ = 185W
- P_gravity = 0W (đường bằng)
- P_rolling = 0,004 × 83 × 9,81 × 11,11 = 36W
- P_kinetic = 0W (tốc độ ổn định)
- P_tổng = 185 + 0 + 36 + 0 = 221W
Giải mã: Cần duy trì 221W để giữ tốc độ 40 km/h ở tư thế TT trên đường bằng
Triển khai JavaScript:
function calculatePowerRequired(params) {
const {
velocityKph,
CdA = 0.32, // m²
rho = 1.225, // kg/m³
mass = 83, // kg (người + xe)
gradientPercent = 0, // %
Crr = 0.004, // lực cản lăn
accelerationMps2 = 0 // m/s²
} = params;
// Đổi vận tốc sang m/s
const V = velocityKph / 3.6;
// Đổi độ dốc sang góc
const theta = Math.atan(gradientPercent / 100);
// Tính từng thành phần
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)
};
}
// Ví dụ: Đua TT ở 40 km/h
const power_tt = calculatePowerRequired({
velocityKph: 40,
CdA: 0.22,
mass: 83,
gradientPercent: 0
});
// Trả về: { total: 221, aero: 185, gravity: 0, rolling: 36, kinetic: 0 }
// Ví dụ: Leo dốc 8% ở tốc độ 15 km/h
const power_climb = calculatePowerRequired({
velocityKph: 15,
CdA: 0.38,
mass: 75,
gradientPercent: 8
});
// Trả về: { total: 265, aero: 27, gravity: 244, rolling: 11, kinetic: 0 }
Các hàm hỗ trợ
Các tiện ích chuyển đổi đơn vị
Triển khai JavaScript:
// Chuyển đổi thời gian
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')}`;
}
// Chuyển đổi tốc độ
function kphToMps(kph) {
return kph / 3.6;
}
function mpsToKph(mps) {
return mps * 3.6;
}
// Chuyển đổi năng lượng
function joulesToKJ(joules) {
return joules / 1000;
}
function kJToJoules(kJ) {
return kJ * 1000;
}
function wattsToKJ(watts, durationSeconds) {
return (watts * durationSeconds) / 1000;
}
// Ví dụ:
formatDuration(7265); // Trả về: "2:01:05"
kphToMps(40); // Trả về: 11.11 m/s
wattsToKJ(250, 3600); // Trả về: 900 kJ (1 giờ tại 250W)
Tài nguyên triển khai
Tất cả các công thức trên trang này đều đã sẵn sàng để đưa vào sản xuất và được xác thực dựa trên các tài liệu khoa học cũng như dữ liệu thực tế từ thiết bị đo công suất. Hãy sử dụng chúng cho các công cụ phân tích tùy chỉnh, xác minh hoặc để hiểu sâu hơn về tính toán trong tập luyện dựa trên công suất.
💡 Các quy tắc tốt nhất (Best Practices)
- Xác thực đầu vào: Kiểm tra các phạm vi công suất hợp lý (0-2000W), thời gian dương
- Xử lý ngoại lệ: Lỗi chia cho không, dữ liệu null/undefined, thiếu FTP
- Làm tròn phù hợp: CTL/ATL/TSB lấy 1 chữ số thập phân, TSS lấy số nguyên, W/kg lấy 2 chữ số thập phân
- Lưu trữ với độ chính xác cao: Giữ nguyên các chữ số thập phân trong cơ sở dữ liệu, chỉ làm tròn khi hiển thị
- Múi giờ: Xử lý nhất quán giữa giờ UTC và giờ địa phương khi phân tích dữ liệu nhiều ngày
- Hiệu chuẩn thiết bị: Nhắc nhở người dùng thực hiện zero-offset trước khi đạp
- Xác thực FTP: Cảnh báo các giá trị FTP bất thường (>500W hoặc <100W đối với người lớn)
- Kiểm tra kỹ lưỡng: Sử dụng các tệp tin đạp xe đã biết kết quả đúng để xác minh các phép tính