Informacja o kadencji jest w pliku .tcx rejestrowana (przez GarminaEdge 500) w następujący sposób:
<Activities> <Activity Sport="Biking"> <Lap StartTime="2017-08-31T14:51:16Z"> <Cadence>77</Cadence> ... <Track> <Trackpoint> <Time>2017-08-31T14:52:02Z</Time> <Cadence>0</Cadence> </Trackpoint> <Trackpoint> <Time>2017-08-31T14:52:06Z</Time> <Cadence>46</Cadence> </Trackpoint> <Trackpoint> <Time>2017-08-31T14:52:07Z</Time> <Cadence>53</Cadence> </Trackpoint>
Lap-ów może być wiele. Każdy zawiera element Track
, w którym zapisana jest informacja o fragmencie trasy. Pomiędzy Lap
a Track
znajduje się nagłówek zawierający różne obliczone/zbiorcze informacje, m.in. średnią kadencję. Co by oznaczało, że w powyższym przykładzie średnia kadencja wynosiła 77 obrotów/min. Na odcinku od 14:52:02Z do 14:52:06Z (4 sekundy) średnia kadencja wyniosła 46 o/min, zaś na odcinku 14:52:06Z--07Z (1s) 53 o/min.
Można też policzyć kadencję samodzielnie, co pozwoli na uzyskanie dodatkowej informacji. Liczenie kadencji jest proste. Mnożąc średnią kadencję odcinka razy czas w sekundach otrzymamy liczbę obrotów korby na tym odcinku (kadencję należy podzielić przez 60 bo jest podana w minutach). Odcinki o zerowej kadencji pomija się (Garmin też tak oblicza BTW). Dzieląc łączną liczbę obrotów przez czas otrzymamy średnią kadencję. Ja dodałem opcję pomijania odcinków o pewnej minimalnej prędkości (np. 8 kmh) -- takie odcinki to zwykle jakieś nietypowe fragmenty, zaniżające tylko średnią.
#!/usr/bin/perl # Cadence calculator for GarminEdge tcx files (or converted fits) # tprzechlewski@gmail.com use Getopt::Long; my $prev_Time = -1; my $parsingTrack ='N'; my $regCadence = 'N'; my $min_speed = -1; # minimum speed my $trackNo=1; GetOptions( "s=f" => \$min_speed, ); $min_speedMS = ($min_speed *1000)/3600.0; if ($min_speed > 0) { print "*** Segments with speed below $min_speed kmh skipped ***\n"; } while (<>) { chomp(); # Order is importany (first check for <Track>: if ( /<Track>/ ) { if ( $regCadence eq 'N' ) { ## Check if Cadence is registered print STDERR "*** No cadence registered! ***\n"; exit 1; } else { $parsingTrack = 'Y' ; print STDERR "### Parsing track #$trackNo...\n"; $trackNo++; } } # Parsing header: if ($parsingTrack eq 'N' ) { if ( /<TotalTimeSeconds>/) { $edge_LapTime = xmlEleValue('TotalTimeSeconds', $_) ; } elsif (/<Cadence>/) { $edge_LapCadence = xmlEleValue('Cadence', $_) ; $regCadence = 'Y' } elsif (/<DistanceMeters>/) { $edge_LapDist = xmlEleValue('DistanceMeters', $_) ; } ##print STDERR "## Parsing track info: $_\n"; next; } ## start parsing Track now: if (/Speed>/) { $speed = xmlEleValue ('Speed', $_); } elsif ($_ =~ /<Time>(.*)T(.*)Z<\/Time>/ ) { $time = $2; ($h, $m, $s ) = split /:/, $time; $current_time = $h * 60 * 60 + $m * 60 + $s ; ##print STDERR "$current_time\n"; } elsif (/<Cadence>/ ) { $cadence = xmlEleValue ('Cadence', $_); } elsif (/<DistanceMeters>/ ) { $distance = xmlEleValue ('DistanceMeters', $_); } elsif ($_ =~ /<\/Trackpoint>/ ) { if ( $prevTime > 0 ) {## pomija pierwsze $lastTime = $current_time ; if ($cadence > 0 && $speed > $min_speedMS ) { $timeDiff = $current_time - $prevTime; $total_time_cycled += $timeDiff ; $total_cycles += $cadence * $timeDiff / 60; $prevTime = $current_time ; } else { $timeDiff = $current_time - $prevTime; $total_time_idle += $timeDiff ; $prevTime = $current_time ; } } else { $prevTime = $current_time ; $firstTime = $current_time ; } } if ( /<\/Track>/ ) { $total_Time = $total_time_idle + $total_time_cycled; printf "Time = Idle: %d s Spinning: %d s Total: %d s\n", $total_time_idle, $total_time_cycled, $total_Time; printf "Time = Idle: %.2f%% Spinning: %.2f%% Total: %.2f%%\n", $total_time_idle/$total_Time *100, $total_time_cycled/$total_Time * 100, $total_Time/$total_Time *100; print "Rotations (total) = $total_cycles\n"; print "Mean cadence (computed) = " . $total_cycles/$total_time_cycled * 60 . "\n"; $totalTimeTime = $lastTime - $firstTime; print "Total time (last - first) = $totalTimeTime s\n"; print "Registered (header) values: lap time: $edge_LapTime " . "cadence: $edge_LapCadence lap distance (m): $edge_LapDist\n"; ## reset values ## ## ## $grand_total_time_idle += $total_time_idle; $grand_total_time_cycled += $total_time_cycled ; $grand_total_cycles += $total_cycles ; $grand_total_Dist += $edge_LapDist; $total_time_idle = $total_time_cycled = $total_cycles = 0 ; $prev_Time = -1; $parsingTrack ='N'; $regCadence = 'N'; } } ##/while ## Grand Totals: $trackNo--; $grand_total_Time = $grand_total_time_idle + $grand_total_time_cycled; print "====== Totals/means for $trackNo tracks =====\n"; printf "Time = Idle: %d s Spinning: %d s Total: %d s\n", $grand_total_time_idle, $grand_total_time_cycled, $grand_total_Time; printf "Time = Idle: %.2f%% Spinning: %.2f%% Total: %.2f%%\n", $grand_total_time_idle/$grand_total_Time *100, $grand_total_time_cycled/$grand_total_Time * 100, $grand_total_Time/$grand_total_Time *100; print "Rotations (total) = $grand_total_cycles\n"; print "Mean cadence (computed) = " . $grand_total_cycles/$grand_total_time_cycled * 60 . "\n"; print "Total distance (registered): $grand_total_Dist (m)\n"; ## ### ### ### ### ### sub xmlEleValue { my $en = shift; # element name my $el = shift; # line $el =~ /<$en>(.*)<\/$en>/; return "$1"; }
Przykładowy wydruk dla pliku fit/tcx zawierającego trzy segmenty:
$ cadencecalc.pl 2017-08-31.tcx ### Parsing track #1... Time = Idle: 552 s Spinning: 2082 s Total: 2634 s Time = Idle: 20.96% Spinning: 79.04% Total: 100.00% Rotations (total) = 2684.95 Mean cadence (computed) = 77.3760806916427 Total time (last - first) = 2634 s Registered (header) values: lap time: 2438.06 cadence: 77 lap distance (m): 16339.2 ### Parsing track #2... Time = Idle: 80 s Spinning: 652 s Total: 732 s Time = Idle: 10.93% Spinning: 89.07% Total: 100.00% Rotations (total) = 860.716666666666 Mean cadence (computed) = 79.2070552147239 Total time (last - first) = 3366 s Registered (header) values: lap time: 731.05 cadence: 79 lap distance (m): 4994.82 ### Parsing track #3... Time = Idle: 29 s Spinning: 105 s Total: 134 s Time = Idle: 21.64% Spinning: 78.36% Total: 100.00% Rotations (total) = 120.716666666667 Mean cadence (computed) = 68.9809523809524 Total time (last - first) = 3500 s Registered (header) values: lap time: 134.378 cadence: 69 lap distance (m): 761.78 ====== Totals/means for 3 tracks ===== Time = Idle: 661 s Spinning: 2839 s Total: 3500 s Time = Idle: 18.89% Spinning: 81.11% Total: 100.00% Rotations (total) = 3666.38333333333 Mean cadence (computed) = 77.4860866502289 Total distance (registered): 22095.8 (m)
Podając jako minimalną prędkość 9 km/h otrzymamy:
$ cadencecalc.pl -s 9 2017-08-31.tcx *** Segments with speed below 9 kmh skipped *** ### Parsing track #1... Time = Idle: 654 s Spinning: 1980 s Total: 2634 s Time = Idle: 24.83% Spinning: 75.17% Total: 100.00% Rotations (total) = 2582.11666666667 Mean cadence (computed) = 78.2459595959596 Total time (last - first) = 2634 s Registered (header) values: lap time: 2438.06 cadence: 77 lap distance (m): 16339.2 ### Parsing track #2... Time = Idle: 80 s Spinning: 652 s Total: 732 s Time = Idle: 10.93% Spinning: 89.07% Total: 100.00% Rotations (total) = 860.716666666666 Mean cadence (computed) = 79.2070552147239 Total time (last - first) = 3366 s Registered (header) values: lap time: 731.05 cadence: 79 lap distance (m): 4994.82 ### Parsing track #3... Time = Idle: 29 s Spinning: 105 s Total: 134 s Time = Idle: 21.64% Spinning: 78.36% Total: 100.00% Rotations (total) = 120.716666666667 Mean cadence (computed) = 68.9809523809524 Total time (last - first) = 3500 s Registered (header) values: lap time: 134.378 cadence: 69 lap distance (m): 761.78 ====== Totals/means for 3 tracks ===== Time = Idle: 763 s Spinning: 2737 s Total: 3500 s Time = Idle: 21.80% Spinning: 78.20% Total: 100.00% Rotations (total) = 3563.55 Mean cadence (computed) = 78.1194738765071 Total distance (registered): 22095.8 (m)
Idle oznacza czas w którym nie kręcimy i/lub jedziemy poniżej prędkości minimalnej (podawany jest czas w sekundach i udział w całości). Rotations to liczba obrotów. Obliczone wartości wyglądają na prawidłowe na co wskazywałoby, że są bliskie wartościom liczonym przez Garmina.
Brak komentarzy:
Prześlij komentarz