Tham khảo Kỹ thuật & Công thức

Triển khai Toán học Hoàn chỉnh

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ố Run Analytics. Sử dụng chúng cho các triển khai tùy chỉnh, xác minh hoặc hiểu sâu hơn về các tính toán.

⚠️ Lưu ý Triển khai

  • Tất cả thời gian nên được chuyển đổi sang giây để tính toán
  • Tính toán rTSS sử dụng Hệ số Cường độ bình phương (IF²)
  • Luôn xác thực đầu vào cho các phạm vi hợp lý
  • Xử lý các trường hợp biên (chia cho 0, giá trị âm)

Các Chỉ số Hiệu suất Cốt lõi

Tốc độ Chạy tới hạn (CRS)

Công thức:

CRS (m/s) = (D₂ - D₁) / (T₂ - T₁)
Pace CRS (phút/km) = 16.667 / CRS (m/s)

🧪 Máy tính Tương tác - Thử nghiệm Công thức

Pace CRS (phút/km):
4:17
Các bước tính toán:
CRS (m/s) = (3600 - 1200) / (900 - 270) = 3.81 m/s
Pace (phút/km) = 1000 / 3.81 = 262 giây = 4:22

Triển khai JavaScript:

function calculateCRS(distance1, time1, distance2, time2) {
  // Chuyển đổi thời gian sang giây
  const t1 = typeof time1 === 'string' ? timeToSeconds(time1) : time1;
  const t2 = typeof time2 === 'string' ? timeToSeconds(time2) : time2;

  // Tính toán vận tốc CRS bằng m/s
  const crs_ms = (distance2 - distance1) / (t2 - t1);

  // Tính toán pace mỗi km bằng giây
  const pace_per_km = 1000 / crs_ms;

  // Chuyển đổi sang định dạng mm:ss
  const minutes = Math.floor(pace_per_km / 60);
  const seconds = Math.round(pace_per_km % 60);

  return {
    velocity_ms: crs_ms,
    pace_seconds: pace_per_km,
    pace_formatted: `${minutes}:${seconds.toString().padStart(2, '0')}`
  };
}

Điểm Căng thẳng Chạy bộ (rTSS)

Công thức Hoàn chỉnh:

rTSS = (IF²) × Thời lượng (giờ) × 100
IF = NSS / Tốc độ Ngưỡng
NSS = Tổng Quãng đường / Tổng Thời gian (m/phút)

🧪 Máy tính Tương tác - Thử nghiệm Công thức

rTSS Tính toán:
31
Các bước tính toán:
NSS = 5000m / 25phút = 200 m/phút
FTP = 1000 / (255/60) = 235.3 m/phút
IF = 200 / 235.3 = 0.850
rTSS = 0.850² × (25/60) × 100 = 31

Triển khai JavaScript:

function calculateRTSS(distance, timeMinutes, ftpMetersPerMin) {
  // Tính Tốc độ Chạy Chuẩn hóa (Normalized Run Speed)
  const nss = distance / timeMinutes;

  // Tính Hệ số Cường độ (Intensity Factor)
  const intensityFactor = nss / ftpMetersPerMin;

  // Tính giờ
  const hours = timeMinutes / 60;

  // Tính rTSS sử dụng hệ số cường độ bình phương
  const rtss = Math.pow(intensityFactor, 2) * hours * 100;

  return Math.round(rtss);
}

// Ví dụ sử dụng:
const rtss = calculateRTSS(3000, 55, 64.5);
// Trả về: 65

// Helper: Chuyển đổi Pace CRS sang Tốc độ Chạy (m/phút)
function crsPaceToSpeed(crsPacePerKmSeconds) {
  // Tốc độ m/phút = 1000m / (pace tính bằng phút)
  return 1000 / (crsPacePerKmSeconds / 60);
}

// Ví dụ: CRS là 4:15 (255 giây)
const speed = crsPaceToSpeed(255); // Trả về: 235.3 m/phút

Hiệu quả Cơ sinh học: Tỷ lệ Dọc

Công thức:

Tỷ lệ Dọc (%) = (Dao động Dọc ÷ Chiều dài Sải bước) × 100

🧪 Máy tính Tương tác - Thử nghiệm Công thức

Tỷ lệ Dọc:
7.4%
Tính toán:
Tỷ lệ Dọc = (8.5 / 115) × 100 = 7.4%

Triển khai JavaScript:

function calculateVerticalRatio(oscillationCm, strideLengthCm) {
  return (oscillationCm / strideLengthCm) * 100;
}

function calculateEfficiencyFactor(paceMetersPerMin, avgHeartRate) {
  return paceMetersPerMin / avgHeartRate;
}

Đang chạy Cơ học Sải bước

Tần suất Sải bước (SR)

Công thức:

SR = 60 / Thời gian Chu kỳ (giây)
SR = (Số bước / Thời gian tính bằng giây) × 60

🧪 Máy tính Tương tác - Thử nghiệm Công thức

Nhịp bước (SPM):
180
Tính toán:
Nhịp bước = (180 / 60) × 60 = 180 SPM

Triển khai JavaScript:

function calculateCadence(stepCount, timeSeconds) {
  return (stepCount / timeSeconds) * 60;
}

// Ví dụ:
const spm = calculateCadence(180, 60);
// Trả về: 180 SPM

Chiều dài Sải bước

Công thức:

Chiều dài Sải bước = Quãng đường / (Số bước / 2)
Chiều dài Sải bước = Vận tốc / (Nhịp bước / 120)

Triển khai JavaScript:

function calculateStrideLength(distanceMeters, stepCount) {
  // Chiều dài sải bước là quãng đường / số cặp sải bước (trái+phải)
  return distanceMeters / (stepCount / 2);
}

// Ví dụ (1000m, 800 bước):
const strideLength = calculateStrideLength(1000, 800);
// Trả về: 2.50 mét mỗi sải bước

Vận tốc từ SR và DPS

Công thức:

Vận tốc (m/s) = (SR / 60) × DPS

Triển khai JavaScript:

function calculateVelocity(strideRate, dps) {
  return (strideRate / 60) * dps;
}

// Ví dụ:
const velocity = calculateVelocity(70, 1.6);
// Trả về: 1.87 m/s

Chỉ số Sải bước (SI)

Công thức:

SI = Vận tốc (m/s) × DPS (m/sải)

Triển khai JavaScript:

function calculateStrideIndex(velocity, dps) {
  return velocity * dps;
}

// Ví dụ:
const si = calculateStrideIndex(1.5, 1.7);
// Trả về: 2.55

Biểu đồ Quản lý Hiệu suất (PMC) để chạy

Tính toán CTL, ATL, TSB

Công thức:

CTL hôm nay = CTL hôm qua + (TSS hôm nay - CTL hôm qua) × (1/42)
ATL hôm nay = ATL hôm qua + (TSS hôm nay - ATL hôm qua) × (1/7)
TSB = CTL hôm qua - ATL hôm qua

Triển khai JavaScript:

function updateCTL(previousCTL, todayTSS) {
  return previousCTL + (todayTSS - previousCTL) * (1/42);
}

function updateATL(previousATL, todayTSS) {
  return previousATL + (todayTSS - previousATL) * (1/7);
}

function calculateTSB(yesterdayCTL, yesterdayATL) {
  return yesterdayCTL - yesterdayATL;
}

// Tính PMC cho chuỗi bài tập
function calculatePMC(workouts) {
  let ctl = 0, atl = 0;
  const results = [];

  workouts.forEach(workout => {
    ctl = updateCTL(ctl, workout.tss);
    atl = updateATL(atl, workout.tss);
    const tsb = calculateTSB(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
    });
  });

  return results;
}

// Ví dụ sử dụng:
const workouts = [
  { date: '2025-01-01', tss: 50 },
  { date: '2025-01-02', tss: 60 },
  { date: '2025-01-03', tss: 45 },
  // ... các bài tập khác
];

const pmc = calculatePMC(workouts);
// Trả về mảng với CTL, ATL, TSB cho mỗi ngày

Tính toán Nâng cao

CRS từ Nhiều Quãng đường (Phương pháp Hồi quy)

Triển khai JavaScript:

function calculateCRSRegression(distances, times) {
  // Hồi quy tuyến tính: distance = a + b*time
  const n = distances.length;
  const sumX = times.reduce((a, b) => a + b, 0);
  const sumY = distances.reduce((a, b) => a + b, 0);
  const sumXY = times.reduce((sum, x, i) => sum + x * distances[i], 0);
  const sumXX = times.reduce((sum, x) => sum + x * x, 0);

  const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
  const intercept = (sumY - slope * sumX) / n;

  return {
    crs: slope, // Vận tốc chạy tới hạn (m/s)
    anaerobic_capacity: intercept // Năng lực yếm khí (m)
  };
}

// Ví dụ với nhiều quãng đường kiểm tra:
const distances = [100, 200, 400, 800];
const times = [65, 150, 340, 720]; // bằng giây
const result = calculateCRSRegression(distances, times);
// Trả về: { crs: 1.18, anaerobic_capacity: 15.3 }

Hệ số Cường độ từ Pace

Triển khai JavaScript:

function calculateIntensityFactor(actualPaceMinKm, thresholdPaceMinKm) {
  // Chuyển đổi chuỗi pace "mm:ss" sang giây nếu cần
  const actualSecs = typeof actualPaceMinKm === 'string' ? timeToSeconds(actualPaceMinKm) : actualPaceMinKm;
  const thresholdSecs = typeof thresholdPaceMinKm === 'string' ? timeToSeconds(thresholdPaceMinKm) : thresholdPaceMinKm;

  // IF là Tốc độ Ngưỡng / Tốc độ Thực tế (pace nhanh hơn = giá trị giây nhỏ hơn)
  return thresholdSecs / actualSecs;
}

// Ví dụ:
const if_value = calculateIntensityFactor("4:45", "4:15");
// Trả về: 0.895 (chạy ở 89.5% ngưỡng)

Phân tích Tính Nhất quán của Pace

Triển khai JavaScript:

function analyzePaceConsistency(segments) {
  const paces = segments.map(kilometer => kilometer.distance / kilometer.time);
  const avgPace = paces.reduce((a, b) => a + b) / paces.length;

  const variance = paces.reduce((sum, pace) =>
    sum + Math.pow(pace - avgPace, 2), 0) / paces.length;
  const stdDev = Math.sqrt(variance);
  const coefficientOfVariation = (stdDev / avgPace) * 100;

  return {
    avgPace,
    stdDev,
    coefficientOfVariation,
    consistency: coefficientOfVariation < 5 ? "Xuất sắc" :
                 coefficientOfVariation < 10 ? "Tốt" :
                 coefficientOfVariation < 15 ? "Trung bình" : "Biến động"
  };
}

// Ví dụ:
const segments = [
  { distance: 100, time: 70 },
  { distance: 100, time: 72 },
  { distance: 100, time: 71 },
  // ...
];
const analysis = analyzePaceConsistency(segments);
// Trả về: { avgPace: 1.41, stdDev: 0.02, coefficientOfVariation: 1.4, consistency: "Xuất sắc" }

Phát hiện Mệt mỏi từ Hiệu quả Sải bước

Triển khai JavaScript:

function detectFatigue(segments) {
  // So sánh Tỷ lệ Dọc của đoạn đầu và đoạn cuối
  const firstSegment = segments[0];
  const lastSegment = segments[segments.length - 1];

  const ratioIncrease = lastSegment.verticalRatio - firstSegment.verticalRatio;

  return {
    startRatio: firstSegment.verticalRatio,
    endRatio: lastSegment.verticalRatio,
    increase: Math.round(ratioIncrease * 10) / 10,
    fatigueLevel: ratioIncrease < 0.2 ? "Tối thiểu" :
                  ratioIncrease < 0.5 ? "Trung bình" :
                  ratioIncrease < 1.0 ? "Đáng kể" : "Nghiêm trọng"
  };
}

// Ví dụ:
const segments = [
  { verticalRatio: 7.2 }, { verticalRatio: 7.3 }, { verticalRatio: 8.1 }
];
const fatigue = detectFatigue(segments);
// Trả về: { startRatio: 7.2, endRatio: 8.1, increase: 0.9, fatigueLevel: "Đáng kể" }

Xác thực Dữ liệu

Kiểm tra Chất lượng Dữ liệu Bài tập

Triển khai JavaScript:

function validateWorkoutData(workout) {
  const issues = [];

  // Kiểm tra phạm vi pace hợp lý (3:00-8:00 mỗi km)
  const avgPaceSecs = workout.totalTime / (workout.totalDistance / 1000);
  if (avgPaceSecs < 180 || avgPaceSecs > 480) {
    issues.push(`Pace trung bình bất thường: ${Math.round(avgPaceSecs)}s mỗi km`);
  }

  // Kiểm tra Tỷ lệ Dọc hợp lý (4% - 15%)
  if (workout.avgVerticalRatio < 4 || workout.avgVerticalRatio > 15) {
    issues.push(`Tỷ lệ Dọc bất thường: ${workout.avgVerticalRatio}%`);
  }

  // Kiểm tra nhịp bước hợp lý (120-220 SPM)
  const avgCadence = calculateCadence(workout.totalSteps, workout.totalTime);
  if (avgCadence < 120 || avgCadence > 220) {
    issues.push(`Nhịp bước bất thường: ${Math.round(avgCadence)} SPM`);
  }

  // Kiểm tra các đoạn bị thiếu (khoảng trống thời gian)
  if (workout.segments && workout.segments.length > 1) {
    for (let i = 1; i < workout.segments.length; i++) {
      const gap = workout.segments[i].startTime -
                  (workout.segments[i-1].startTime + workout.segments[i-1].duration);
      if (gap > 300) { // khoảng trống 5 phút
        issues.push(`Phát hiện khoảng trống lớn giữa các đoạn ${i} và ${i+1}`);
      }
    }
  }

  return {
    isValid: issues.length === 0,
    issues
  };
}

// Ví dụ:
const workout = {
  totalDistance: 2000,
  totalTime: 1800, // 30 phút
  totalStrides: 800,
  segments: [/* dữ liệu km */]
};
const validation = validateWorkoutData(workout);
// Trả về: { isValid: true, issues: [] }

Hàm Hỗ trợ

Tiện ích Chuyển đổi Thời gian

Triển khai JavaScript:

// Chuyển đổi mm:ss sang giây
function timeToSeconds(timeString) {
  const parts = timeString.split(':');
  return parseInt(parts[0]) * 60 + parseInt(parts[1]);
}

// Chuyển đổi giây sang mm:ss
function secondsToTime(seconds) {
  const minutes = Math.floor(seconds / 60);
  const secs = Math.round(seconds % 60);
  return `${minutes}:${secs.toString().padStart(2, '0')}`;
}

// Chuyển đổi giây sang hh:mm:ss
function secondsToTimeDetailed(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')}`;
}

// Ví dụ:
timeToSeconds("1:33"); // Trả về: 93
secondsToTime(93); // Trả về: "1:33"
secondsToTimeDetailed(3665); // Trả về: "1:01:05"

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 cho sản xuất và được xác thực dựa trên tài liệu khoa học. 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ề các tính toán hiệu suất chạy bộ.

💡 Thực hành Tốt nhất

  • Xác thực đầu vào: Kiểm tra các phạm vi hợp lý trước khi tính toán
  • Xử lý trường hợp biên: Chia cho 0, giá trị âm, dữ liệu null
  • Làm tròn phù hợp: CTL/ATL/TSB đến 1 chữ số thập phân, rTSS đến số nguyên
  • Lưu trữ độ chính xác: Giữ độ chính xác đầy đủ trong cơ sở dữ liệu, làm tròn để hiển thị
  • Kiểm tra kỹ lưỡng: Sử dụng dữ liệu tốt đã biết để xác minh tính toán