สูตรคำนวณกำลังในการปั่นจักรยาน

รากฐานทางคณิตศาสตร์ของตัวชี้วัดใน Bike Analytics

คู่มือการนำไปใช้งาน

หน้านี้รวบรวมสูตรคำนวณที่พร้อมนำไปใช้งานและวิธีการคำนวณทีละขั้นตอนสำหรับตัวชี้วัดทั้งหมดใน Bike Analytics คุณสามารถนำไปใช้สำหรับการเขียนโปรแกรมของคุณเอง การตรวจสอบความถูกต้องของข้อมูล หรือเพื่อทำความเข้าใจการซ้อมด้วยพลังงานอย่างลึกซึ้งยิ่งขึ้น

⚠️ หมายเหตุการนำไปใช้งาน

  • ค่าพลังงานทังหมดมีหน่วยเป็น วัตต์ (W), เวลาเป็น วินาที (s) นอกจากระบุไว้เป็นอย่างอื่น
  • ค่า FTP และ CP เป็นเกณฑ์เฉพาะบุคคล—ไม่มีค่ามาตรฐานสากล
  • ควรตรวจสอบข้อมูลนำเข้าให้อยู่ในระยะที่เหมาะสมเสมอ (ปกติคือ 0-2000W)
  • จัดการกับกรณีพิเศษ (Edge cases) เช่น การหารด้วยศูนย์ หรือค่าพลังงานติดลบ
  • ข้อมูลพลังงานต้องการความถี่ในการบันทึกทุกๆ 1 วินาทีเพื่อความแม่นยำ

ตัวชี้วัดสมรรถภาพหลัก

1. คะแนนความเครียดจากการฝึกซ้อม (Training Stress Score - 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. พลังงานนอร์มัลไลซ์ (Normalized Power - NP)

อัลกอริทึม (ค่าเฉลี่ยเคลื่อนที่ 30 วินาที):

1. คำนวณค่าเฉลี่ยเคลื่อนที่ 30 วินาที (30-second rolling average) ตลอดการปั่น
2. ยกกำลังสี่ (4th power) ของค่าเฉลี่ย 30 วินาทีในแต่ละจุด
3. หาค่าเฉลี่ยของค่าที่ยกกำลังสี่ทั้งหมดนั้น
4. ถอดรากที่สี่ (4th root) ของค่าเฉลี่ยนั้น
NP = ⁴√(average of [30s_avg^4])

ทำไมต้องยกกำลังสี่?

ความสัมพันธ์แบบยกกำลังสี่ (Quartic relationship) สะท้อนถึงภาระทางสรีรวิทยา (Physiological cost) ที่ไม่ได้เป็นเส้นตรงตามความพยายาม การปั่นที่มีจังหวะเร่งและจังหวะพักจะใช้พลังงานในแง่ของความเหนื่อยล้ามากกว่าการปั่นด้วยพลังคงที่แม้จะมีค่าเฉลี่ยเท่ากัน

ตัวอย่าง:

  • การปั่นที่สม่ำเสมอ: 200W นาน 1 ชั่วโมง → NP = 200W, ค่าเฉลี่ย = 200W
  • การปั่นที่ผันผวน: สลับ 300W/100W → ค่าเฉลี่ย = 200W, NP = 225W

แม้ค่าเฉลี่ยจะเท่ากัน แต่การปั่นที่ผันผวนจะมีค่า NP สูงกว่า 12% เนื่องจากภาระทางร่างกายจากการเร่งเครื่อง

การเขียนโค้ดภาษา JavaScript:

function calculateNormalizedPower(powerData) {
  // powerData คืออาร์เรย์ของค่าพลังงานในแต่ละวินาที (1-second power values)

  // ขั้นตอนที่ 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: ยกกำลังสี่
  const powered = rollingAvgs.map(p => Math.pow(p, 4));

  // ขั้นตอนที่ 3: หาค่าเฉลี่ยของค่าที่ยกกำลังสี่
  const avgPowered = powered.reduce((sum, p) => sum + p, 0) / powered.length;

  // ขั้นตอนที่ 4: ถอดรากที่สี่
  const np = Math.pow(avgPowered, 0.25);

  return Math.round(np);
}

// ตัวอย่างการใช้งาน:
const powerData = [/* อาร์เรย์ของค่าพลังงาน */];
const np = calculateNormalizedPower(powerData);
// ผลลัพธ์: ค่า NP ในหน่วยวัตต์

3. ปัจจัยความเข้มข้น (Intensity Factor - IF)

สูตรคำนวณ:

IF = NP / FTP

เกณฑ์ในการตีความ:

ช่วงค่า IF ระดับความพยายาม ตัวอย่างการซ้อม
< 0.75 พักฟื้น / เบามาก (Recovery / Easy) การปั่นเพื่อฟื้นฟู (Active recovery), Zone 1-2
0.75 - 0.85 ความทนทาน (Endurance) การปั่นต่อเนื่องระยะยาว, การสร้างฐานแอโรบิก
0.85 - 0.95 เทมโป (Tempo) การซ้อมแบบ Sweet spot, เทมโปอินเทอร์วอล
0.95 - 1.05 เทรชโฮลด์ (Threshold) FTP อินเทอร์วอล, การปั่นแบบไทม์ไทรอัล
1.05 - 1.15 VO₂max อินเทอร์วอล 5 นาที, การแข่งไครทีเรียม
> 1.15 แอนแอโรบิก (Anaerobic) การสปริ๊นท์สั้นๆ, การยิงหนี, การแข่ง MTB

ตัวอย่างการคำนวณ:

สถานการณ์: NP = 235W, FTP = 250W

IF = 235 / 250 = 0.94

การตีความ: เป็นความพยายามระดับ High Tempo / Sub-threshold ที่สามารถทำต่อเนื่องได้ 2-3 ชั่วโมง

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

// ตัวอย่าง:
const if_value = calculateIF(235, 250);
// ผลลัพธ์: 0.94

4. ดัชนีความผันผวน (Variability Index - VI)

สูตรคำนวณ:

VI = NP / Average Power

การตีความตามประเภทของการปั่น:

ประเภทการปั่น ค่า VI ปกติ ความหมาย
เสือหมอบทางราบ (TT) / ความพยายามสม่ำเสมอ 1.00 - 1.05 ให้พลังงานที่สม่ำเสมอมาก, การคุมจังหวะ (Pacing) ที่ดีที่สุด
การแข่งขันเสือหมอบ (Road Racing) 1.05 - 1.10 มีจังหวะเร่งบ้าง แต่โดยรวมยังสม่ำเสมอ
ไครทีเรียม (Criterium) 1.10 - 1.20 มีการเร่งเครื่องและความพยายามหนีกลุ่มบ่อยครั้ง
เสือภูเขา XC 1.15 - 1.30+ มีความผันผวนสูงมาก, มีการระเบิดพลังตลอดเวลา

ตัวอย่างการคำนวณ:

การแข่งเสือหมอบ: NP = 240W, พลังงานเฉลี่ย = 230W

VI = 240 / 230 = 1.04 (การคุมจังหวะสม่ำเสมอ)

การแข่งเสือภูเขา: 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. พลังงานวิกฤต (Critical Power - CP) - แบบจำลองเชิงเส้น

สูตรคำนวณ:

เวลา = W' / (พลังงาน - CP)
จัดรูปใหม่: พลังงาน × เวลา = CP × เวลา + W'

การคำนวณจากความพยายามหลายครั้ง:

ต้องการความพยายามสูงสุด (Maximal efforts) 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

ใช้การวิเคราะห์การถดถอยเชิงเส้น (งาน = CP × เวลา + W'):

  • CP = 270W (ความชันของเส้นถดถอย)
  • W' = 18.5 kJ (จุดตัดแกน Y)

การเขียนโค้ดภาษา 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

  // วิเคราะห์การถดถอยเชิงเส้น: 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' (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 (ต่ำกว่า CP อยู่ 70W) นาน 2 นาที
  • ΔCP = 270 - 200 = 70W
  • τ = 546 × e^(-0.01 × 70) + 316 = 588 วินาที
  • พลังงานที่ฟื้นมาใน 120 วินาที: 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 ตลอดช่วงเวลา

แผนภูมิการจัดการประสิทธิภาพ (Performance Management Chart - 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): ความสมบูรณ์ของร่างกาย (Form) = Fitness - Fatigue

ตัวอย่างการคำนวณ (บล็อกการซ้อม 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 ความเสี่ยงสูง (High Risk) สัญญาณการซ้อมเกิน (Overtraining) - ควรลดภาระงานลง
-30 ถึง -10 ซ้อมหนัก (Training Hard) กำลังสร้างความฟิต, ควรติดตามการพักฟื้นอย่างใกล้ชิด
-10 ถึง +5 เหมาะสม (Optimal) โซนการซ้อมปกติ
+5 ถึง +15 พร้อมแข่งขัน (Race Ready) ร่างกายอยู่ในจุดสูงสุด - เหมาะสำหรับลงแข่งในสุดสัปดาห์
> +25 สูญเสียความฟิต (Detraining) เริ่มสูญเสียความฟิต - ควรเพิ่มภาระงาน

การเขียนโค้ดภาษา JavaScript:

function calculatePMC(workouts) {
  // workouts = [{date: "YYYY-MM-DD", tss: number}, ...]
  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. อัตราส่วนกำลังต่อน้ำหนัก (Power-to-Weight Ratio)

สูตรคำนวณ:

W/kg = พลังงาน (วัตต์) / มวลร่างกาย (กก.)

เกณฑ์มาตรฐาน FTP W/kg:

ระดับ ชาย (W/kg) หญิง (W/kg) ประเภทนักปั่น
ปั่นเพื่อสันทนาการ 2.5 - 3.5 2.0 - 3.0 เน้นออกกำลังกาย
นักปั่นสายแข่งขัน 3.5 - 4.5 3.0 - 4.0 กลุ่ม Cat 3-4, นักแข่งรุ่นอายุ
นักปั่นระดับสูง 4.5 - 5.5 4.0 - 5.0 กลุ่ม Cat 1-2, สมัครเล่นขาแรง
สมัครเล่นระดับอีลีท 5.5 - 6.0 5.0 - 5.5 ระดับชาติ
นักปั่นอาชีพ 6.0 - 7.0+ 5.5 - 6.5+ ระดับ World Tour, ลุ้นแชมป์ Grand Tour

ตัวอย่างการคำนวณ:

สถานการณ์: นักปั่นที่มีค่า 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 (อัตราการไต่ความเร็วเฉลี่ย)

สูตรคำนวณ:

VAM (ม./ชม.) = ระยะไต่ความสูง (เมตร) / ระยะเวลา (ชั่วโมง)

เกณฑ์มาตรฐาน VAM:

VAM (ม./ชม.) ระดับ ตัวอย่าง
600 - 900 ปั่นเพื่อสันทนาการ นักปั่นชมรมบนเนินแถวบ้าน
900 - 1200 นักปั่นสายแข่งขัน สมัครเล่นขาแรงที่ Alpe d'Huez
1200 - 1500 สมัครเล่นระดับอีลีท นักไต่เขาฟอร์มระดับชาติ
1500 - 1800 นักปั่นอาชีพ นักปั่นอาชีพระดับ World Tour (Domestique)
> 1800 ผู้ชนะรายการ Grand Tour Pogačar, Vingegaard บนเขาลูกสำคัญ

ตัวอย่างการคำนวณ:

สถานการณ์: การปั่นขึ้นเขา Alpe d'Huez

  • ระยะไต่ความสูง: 1100 เมตร
  • ระยะเวลา: 55 นาที = 0.917 ชั่วโมง
  • VAM = 1100 / 0.917 = 1200 ม./ชม.

การตีความ: สมรรถภาพการขึ้นเขาระดับนักปั่นสายแข่งขัน

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

// ตัวอย่าง:
const vam = calculateVAM(1100, 55);
// ผลลัพธ์: 1200 ม./ชม.

10. การประมาณค่า W/kg จากค่า VAM

สูตรคำนวณ:

W/kg ≈ VAM (ม./ชม.) / 100 / (ความลาดชัน% + 3)

ตัวอย่างการคำนวณ:

สถานการณ์: การขึ้นเขาที่มีความลาดชันเฉลี่ย 8%, VAM = 1200 ม./ชม.

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_gravity + P_rolling + P_kinetic

สูตรคำนวณแยกตามส่วนประกอบ:

แรงต้านอากาศ (Aerodynamic Drag):
P_aero = CdA × 0.5 × ρ × V³
แรงโน้มถ่วง (ขณะขึ้นเขา) (Gravitational):
P_gravity = m × g × sin(θ) × V
ความเสียดทานจากการหมุน (Rolling Resistance):
P_rolling = Crr × m × g × cos(θ) × V
พลังงานจลน์ (ขณะเร่งความเร็ว) (Kinetic Acceleration):
P_kinetic = m × a × V

ค่าคงที่และตัวแปร:

  • CdA = สัมประสิทธิ์แรงต้านอากาศ × พื้นที่หน้าตัด (m²)
    • ตำแหน่งบนชิฟเตอร์ (Hoods) ปกติ: 0.35-0.40 m²
    • ตำแหน่งดรอป (Drops): 0.32-0.37 m²
    • ตำแหน่งแอโร (TT position): 0.20-0.25 m²
  • ρ = ความหนาแน่นของอากาศ (1.225 kg/m³ ที่ระดับน้ำทะเล, อุณหภูมิ 15°C)
  • V = ความเร็ว (m/s)
  • m = มวลรวม (นักปั่น + จักรยาน, kg)
  • g = แรงโน้มถ่วง (9.81 m/s²)
  • θ = มุมความชัน (เรเดียนหรือองศาที่แปลงแล้ว)
  • Crr = สัมประสิทธิ์ความเสียดทานจากการหมุน (~0.004 สำหรับยางเสือหมอบคุณภาพสูง)
  • a = อัตราเร่ง (m/s²)

ตัวอย่างการคำนวณ (การปั่นไทม์ไทรอัลทางราบ):

สถานการณ์:

  • ความเร็ว: 40 กม./ชม. = 11.11 ม./วินาที
  • CdA: 0.22 m² (ตำแหน่งแอโรที่ดี)
  • มวลรวม: 75กก. (นักปั่น) + 8กก. (จักรยาน) = 83กก.
  • ถนนราบ (ความชัน = 0°)
  • ความเร็วคงที่ (อัตราเร่ง = 0)

ขั้นตอนการคำนวณ:

  1. P_aero = 0.22 × 0.5 × 1.225 × 11.11³ = 185W
  2. P_gravity = 0W (ทางราบ)
  3. P_rolling = 0.004 × 83 × 9.81 × 11.11 = 36W
  4. P_kinetic = 0W (ความเร็วคงที่)
  5. P_total = 185 + 0 + 36 + 0 = 221W

การตีความ: ต้องใช้พละกำลังที่ 221W เพื่อรักษาความเร็ว 40 กม./ชม. ในท่าปั่นแบบแอโรบนทางราบ

การเขียนโค้ดภาษา JavaScript:

function calculatePowerRequired(params) {
  const {
    velocityKph,
    CdA = 0.32,              // m²
    rho = 1.225,             // kg/m³
    mass = 83,               // kg (นักปั่น + จักรยาน)
    gradientPercent = 0,     // %
    Crr = 0.004,             // ความเสียดทานจากการหมุน
    accelerationMps2 = 0     // m/s²
  } = params;

  // แปลงความเร็วเป็น m/s
  const V = velocityKph / 3.6;

  // แปลงความชันเป็นมุม
  const theta = Math.atan(gradientPercent / 100);

  // คำนวณแต่ละส่วนประกอบ
  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)
  };
}

// ตัวอย่าง: การปั่นที่ความเร็ว 40 กม./ชม.
const power_tt = calculatePowerRequired({
  velocityKph: 40,
  CdA: 0.22,
  mass: 83,
  gradientPercent: 0
});
// ผลลัพธ์: { total: 221, aero: 185, gravity: 0, rolling: 36, kinetic: 0 }

// ตัวอย่าง: ขึ้นเขาชัน 8% ที่ความเร็ว 15 กม./ชม.
const power_climb = calculatePowerRequired({
  velocityKph: 15,
  CdA: 0.38,
  mass: 75,
  gradientPercent: 8
});
// ผลลัพธ์: { total: 265, aero: 27, gravity: 244, rolling: 11, kinetic: 0 }

ฟังก์ชันเสริม (Helper Functions)

เครื่องมือจัดการหน่วยการวัด

การเขียนโค้ดภาษา JavaScript:

// การแปลงเวลา
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')}`;
}

// การแปลงความเร็ว
function kphToMps(kph) {
  return kph / 3.6;
}

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

// การแปลงพลังงาน
function joulesToKJ(joules) {
  return joules / 1000;
}

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

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

// ตัวอย่าง:
formatDuration(7265);        // ผลลัพธ์: "2:01:05"
kphToMps(40);                // ผลลัพธ์: 11.11 m/s
wattsToKJ(250, 3600);        // ผลลัพธ์: 900 kJ (1 ชั่วโมงที่ 250W)

ทรัพยากรสำหรับการนำไปใช้งาน

สูตรคำนวณทั้งหมดในหน้านี้พร้อมสำหรับการนำไปใช้งานจริง และได้รับการตรวจสอบความถูกต้องตามเอกสารทางวิชาการและข้อมูลจริงจากอุปกรณ์วัดพลังงาน คุณสามารถนำไปใช้เพื่อสร้างเครื่องมือวิเคราะห์ข้อมูลของคุณเอง การตรวจสอบความถูกต้อง หรือเพื่อทำความเข้าใจการคำนวณเบื้องหลังการซ้อมด้วยพลังงานอย่างลึกซึ้งยิ่งขึ้น

💡 แนวทางปฏิบัติที่ดีที่สุด (Best Practices)

  • ตรวจสอบความถูกต้องของข้อมูลนำเข้า: ตรวจสอบช่วงค่าพลังงานที่เหมาะสม (0-2000W) และระยะเวลาต้องเป็นค่าบวก
  • จัดการกับกรณีพิเศษ (Edge cases): การหารด้วยศูนย์, ข้อมูลที่เป็นค่าว่างหรือไม่ระบุค่า, หรือข้อมูล FTP ที่หายไป
  • การปัดเศษทศนิยมอย่างเหมาะสม: ปัดค่า CTL/ATL/TSB เป็นทศนิยม 1 ตำแหน่ง, ค่า TSS เป็นจำนวนเต็ม, และค่า W/kg เป็นทศนิยม 2 ตำแหน่ง
  • เก็บค่าความละเอียดสูง: ควรเก็บค่าความละเอียดเต็มไว้ในฐานข้อมูล และปัดเศษเฉพาะเมื่อต้องการแสดงผลเท่านั้น
  • เขตเวลา (Time zones): จัดการเวลาแบบ UTC และเวลาท้องถิ่นให้สอดคล้องกันสำหรับการวิเคราะห์ข้อมูลแบบหลายวัน
  • การปรับเทียบอุปกรณ์วัดพลังงาน: แนะนำให้ผู้ใช้งานทำการ zero-offset ก่อนเริ่มการปั่นเสมอ
  • การตรวจสอบความถูกต้องของค่า FTP: ตรวจหากค่า FTP ที่น่าสงสัย (เช่น >500W หรือ <100W สำหรับผู้ใหญ่)
  • ทดสอบอย่างละเอียด: ใช้ไฟล์การปั่นที่ทราบค่าความถูกต้องแน่นอนแล้วเพื่อนำมาตรวจสอบผลการคำนวณของระบบ