Advertisement
flocsy

fractional heart rate zone

Mar 7th, 2025 (edited)
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.48 KB | Source Code | 0 0
  1. import Toybox.Lang;
  2. import Toybox.Test;
  3.  
  4. const TEST_HR_ZONES = [128, 153, 162, 180, 185, 190] as Array<Number>;
  5.  
  6. function computeHrZoneFlocsy(heartRate as Number) as Float {
  7. var z = INVALID_ZONE, fZ = INVALID_FRACTIONAL_ZONE;
  8. var heartRateZones = TEST_HR_ZONES;
  9. for (z = 0; z < 5 && heartRate >= heartRateZones[z] + 1; z++) {
  10. }
  11. var min = z > 0 ? heartRateZones[z - 1] + 1 : 30; // use 30 as min for zone 0 to get similar fractional zone number as Garmin
  12. var max = heartRateZones[z];
  13. fZ = z + (100.0 * (heartRate - min) / (max + 1 - min)) / 100;
  14. return fZ;
  15. }
  16. function computeHrZoneTouching(heartRate as Number) as Float {
  17. var z = INVALID_ZONE, fZ = INVALID_FRACTIONAL_ZONE;
  18. var heartRateZones = TEST_HR_ZONES;
  19. for (z = 0; z < 5 && heartRate >= heartRateZones[z]; z++) {
  20. }
  21. var min = z > 0 ? heartRateZones[z - 1] : 30; // use 30 as min for zone 0 to get similar fractional zone number as Garmin
  22. var max = heartRateZones[z];
  23. fZ = z + (100.0 * (heartRate - min) / (max - min)) / 100;
  24. return fZ;
  25. }
  26. const absolute_min = 30;
  27. function computeHrZoneFlowState(heartRate as Number) as Float {
  28. var z = INVALID_ZONE, fZ = INVALID_FRACTIONAL_ZONE;
  29. var heartRateZones = TEST_HR_ZONES;
  30. var absolute_max = heartRateZones[5];
  31.  
  32. // ofc this is superfluous bc Garmin can't read an HR less than 30,
  33. // but let's pretend we don't know that
  34. if (heartRate < absolute_min) {
  35. heartRate = absolute_min;
  36. }
  37.  
  38. // match garmin behaviour (any hr>= 220 will produce a decimal zone of 6.0)
  39. if (heartRate > absolute_max) {
  40. heartRate = absolute_max;
  41. }
  42.  
  43. for (z = 0; z < 5 && heartRate >= heartRateZones[z]; z++) {}
  44.  
  45. var min = z > 0 ? heartRateZones[z - 1] : absolute_min; // use 30 as min for zone 0 to get similar fractional zone number as Garmin
  46. var max = heartRateZones[z];
  47.  
  48. // This is closer to what I originally had in pseudocode
  49. fZ = z + (((heartRate - min) * 1.0) / (max - min));
  50. return fZ;
  51. }
  52. (:test)
  53. function compareHrZones(logger as Logger) as Boolean {
  54. var prev = 0;
  55. for (var hr = 0; hr < 256; hr++) {
  56. var old = computeHrZoneFlocsy(hr);
  57. var touching = computeHrZoneTouching(hr);
  58. var flowState = computeHrZoneFlowState(hr);
  59. logger.debug("HR: " + hr + ", HR zone: old: " + old + ", touching: " + touching + ", FlowState: " + flowState + ", angle: " + (flowState - prev));
  60. prev = flowState;
  61. }
  62. return true;
  63. }
  64.  
Tags: Monkey C
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement