Add wattage predictions readme and py implementation to docs.
This commit is contained in:
parent
bbef8369ef
commit
a5c94a9230
|
|
@ -519,6 +519,7 @@ BLE service). This is displayed as an ECG trace and heart rate graph over time.
|
|||
### [Quiske RowP App](https://www.rowingperformance.com/tutorial)
|
||||
|
||||
The Quiske pod also allows for dynamic rowing on machines such as a Concept2 on slides.
|
||||
|
||||
* [Quiske Manual](https://www.rowingperformance.com/blog/the-virtual-coach-evolved)
|
||||
* [Quiske knows dynamic too](https://www.rowingperformance.com/blog/quiske-coach-knows-dynamic-too)
|
||||
* [Making Sense of the Data](https://www.rowingperformance.com/blog/making-sense-of-the-data)
|
||||
|
|
@ -546,7 +547,7 @@ is derived from the difference in speed of the seat and handle in the various
|
|||
stages of the stroke.
|
||||
|
||||
[For example](https://www.coachbergenroth.com/improve-your-rowing-with-the-quiske-pod/),
|
||||
when I approach the catch, I could see that my handle speed and deceleration
|
||||
when I approach the catch, I could see that my handle speed and deceleration
|
||||
was different from my seat deceleration. This data indicated to me that I was
|
||||
not establishing my forward body angle early enough on the recovery.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
# Wattage predictions
|
||||
|
||||
See [concept2_predictions.py](concept2_predictions.py)
|
||||
|
||||
## Zones
|
||||
|
||||
Heart rate zones are calculated based on HRR calculated from:
|
||||
|
||||
Resting heart rate (RHR) 58
|
||||
Maximum heart rate (MHR) 165
|
||||
Heart rate reserve (HRR) (MHR minus RHR) 107
|
||||
|
||||
| Training Band | %HRR | %2k (W) | range |
|
||||
|------------------------------|--------|---------------|-------|
|
||||
| Oxygen Utilisation 2 (UT2) | 65-70 | 45-60 | 15% |
|
||||
| Oxygen Utilisation 1 (UT1) | 70-80 | 60-70 | 10% |
|
||||
| Anaerobic Threshold (AT) | 80-85 | 70-80 | 10% |
|
||||
| VO2 Max/Transport (TR) | 85-95 | 80-105 | 25% |
|
||||
| Peak Power/Anaerobic (AN) | 95-100 | 105-115 | 10% |
|
||||
|
||||
From [Stumpy](https://thestumpyrower.wordpress.com/rowing-on-the-concept-2-ergometer/56-2/)
|
||||
|
||||
| Training Band | s.min1* | %2k (w)** | HRR*** |
|
||||
|---------------|---------|-----------|--------|
|
||||
| Oxygen Utilisation 2 | UT2 | 16-20 | 45-60 |
|
||||
| Oxygen Utilisation 1 | UT1 | 20-24 | 60-70 |
|
||||
| Anaerobic Threshold | AT | 24-28 | 70-80 |
|
||||
| VO2 Max/Transport | TR | 28-32 | 80-105 |
|
||||
| Peak Power/Anaerobic | AN | 32+ | 105-115 |
|
||||
|
||||
*s.min-1 is scientific notation for strokes/minute
|
||||
|
||||
**%2k (w) is the % of power output, measured in watts of a 2000m test – from this it is possible to calculate pace (time/500m)
|
||||
|
||||
***HRR% is Heart Rate Reserve %. When resting and maximum heart rates are know it is possible to calculate the heart rate at which one should train to have the most appropriate effect on the body’s systems.
|
||||
|
||||
## Example 1
|
||||
|
||||
### Heart rate 132 for 110W after 10 minutes
|
||||
|
||||
UT2 is 65%-70%, so 128-133 bpm.
|
||||
|
||||
132 is 4 (132 minus 128) into UT2 range of 5 (133 minus 128)
|
||||
|
||||
UT2 power is 45%-60% of max 2k power.
|
||||
|
||||
UT2 power range is 15% (60% minus 45%)
|
||||
|
||||
so 132 bmp should be 4 fifths into that 15% = 12%
|
||||
|
||||
so expected power is 110W/(45%+12%) = 193W
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
def calculate_wattage(resting_heart_rate, maximum_heart_rate, heart_rate, base_power_output):
|
||||
def get_zone_percentile(heart_rate, resting_heart_rate, maximum_heart_rate):
|
||||
HRR = maximum_heart_rate - resting_heart_rate
|
||||
zone = ((heart_rate - resting_heart_rate) / HRR) * 100
|
||||
|
||||
return round(zone, 2)
|
||||
|
||||
def get_hrr_range(zone):
|
||||
if zone <= 65:
|
||||
return (0, 65)
|
||||
elif zone <= 70:
|
||||
print("UT2 Zone")
|
||||
return (65, 70)
|
||||
elif zone <= 80:
|
||||
print("UT1 Zone")
|
||||
return (70, 80)
|
||||
elif zone <= 85:
|
||||
print("AT Zone")
|
||||
return (80, 85)
|
||||
elif zone <= 95:
|
||||
print("TR Zone")
|
||||
return (85, 95)
|
||||
else:
|
||||
print("AN Zone")
|
||||
return (95, 100)
|
||||
|
||||
def get_power_range(zone):
|
||||
if zone <= 65:
|
||||
return (0, 45)
|
||||
elif zone <= 70:
|
||||
print("UT2 Zone")
|
||||
return (45, 60)
|
||||
elif zone <= 80:
|
||||
print("UT1 Zone")
|
||||
return (60, 70)
|
||||
elif zone <= 85:
|
||||
print("AT Zone")
|
||||
return (70, 80)
|
||||
elif zone <= 95:
|
||||
print("TR Zone")
|
||||
return (80, 105)
|
||||
else:
|
||||
print("AN Zone")
|
||||
return (105, 115)
|
||||
|
||||
zone_percentage = get_zone_percentile(heart_rate, resting_heart_rate, maximum_heart_rate)
|
||||
print("Zone: " + str(zone_percentage))
|
||||
|
||||
min_power, max_power = get_power_range(zone_percentage)
|
||||
print("Min power: " + str(min_power))
|
||||
print("Max power: " + str(max_power))
|
||||
|
||||
min_hrr, max_hrr = get_hrr_range(zone_percentage)
|
||||
print("Min hrr: " + str(min_hrr))
|
||||
print("Max hrr: " + str(max_hrr))
|
||||
|
||||
power_range = max_power - min_power
|
||||
print("Power range: " + str(power_range))
|
||||
|
||||
hrr_range = max_hrr - min_hrr
|
||||
print("HRR range: " + str(hrr_range))
|
||||
print("Zone minus min hrr: " + str(zone_percentage - min_hrr))
|
||||
|
||||
# Calculate percentage of hrr range
|
||||
hrr_percentage = ((zone_percentage - min_hrr) / hrr_range)
|
||||
print("hrr %: " + str(hrr_percentage))
|
||||
|
||||
power_percentage = (min_power + hrr_percentage * power_range) / 100
|
||||
print("Power percentage: " + str(power_percentage))
|
||||
|
||||
|
||||
# Add base power output
|
||||
# predicted_power = power_percentage + base_power_output
|
||||
predicted_power = base_power_output / power_percentage
|
||||
|
||||
return round(predicted_power, 0)
|
||||
|
||||
# Example usage
|
||||
resting_heart_rate = 58
|
||||
maximum_heart_rate = 165
|
||||
heart_rate = 132
|
||||
base_power_output = 110
|
||||
|
||||
watts = calculate_wattage(resting_heart_rate, maximum_heart_rate, heart_rate, base_power_output)
|
||||
print(f"Predicted power: {watts} watts")
|
||||
Loading…
Reference in New Issue