Saturday, June 23, 2012

910XT HRV

Record and Analyze HRV from 910XT

Enable RR recording

Turn on the FR910XT and go into the menu screen. Press UP then DOWN and repeat 10 times (if you count up-down as one cycle then this is 5 cycles).
You should now have entered the "diagnostic menu". From here select HRV on the top and press Enter. Now you can enable the hrv recording.

Getting RR values from FIT

For now I used fitdump and awk/sed to get rr values from the fit file into another file.

fitdump activity.fit |grep -A1 hrv | grep time|awk '{print $4}'|sed 's/(\([0-9]*\)),/\1/g'

If there's values much too high you could filter them e.g.
awk '$1<1500'

 

Analyze

You can use the hrv toolkit.
 plt_rrs -m -R hrv_values1



get_hrv -m -S -R 2012-06-24_08-08-32-80-97354.hrv



Or there is the HRV Analysis which is a windows application but works under wine:





Or for some less sophisticated plot try this, use the above output and filter again with awk:
awk ' { OFS="\t"}{total=total+$1; print total,$1}'  > hrv_values

gnuplot:
gnuplot> plot "hrv_values" using 1:2 title 'HRV' with impulse
gnuplot> 


Saturday, June 9, 2012

http://g.co/doodle/xy3xeq

BRT Cuesheets

How to parse cue-sheets from bikeroutetoaster (in order to prepare an aid-station summary)

Consider this, you are using  http://www.bikeroutetoaster.com/ (brt) to create a running course where you want to provide aid stations. In brt you do this by adding course-points (other points are track-points). When you add a new course-point or convert any existing track-point to a course-point you are asked to give it a name, type, and directions (or general description). For aid stations set type to Food.
brt then generates xml code which you can download on the cuesheet page. The xml looks something like this:

...
    <point>  
    <lat>48.614215</lat>  
    <lng>8.967376</lng>  
    <legDistance>5.57</legDistance>  
    <totalDistance>26.26</totalDistance>  
    <height>522</height>  
    <pointType>Food</pointType>  
    <name>VP1</name>  
    <directions>Parkplatz Kohltor (Hildrizhausen)</directions>  
   </point>  
   <point>  
    <lat>48.60916</lat>  
    <lng>8.96905</lng>  
    <legDistance>0.58</legDistance>  
    <totalDistance>26.83</totalDistance>  
    <height>517</height>  
    <pointType>Right</pointType>  
    <name />  
    <directions />  
   </point>  
...

So what I wanted from this was a listing that shows all points marked as Food (aid stations), at which mile/kilometer they are reached and the delta distance. In addition I output transit times for aid stations given estimated min/max finisher times. This gives some idea how long each aid station should be available.

The perl code to do this is printed here (download link below).
To run this script just provide the xml cuesheet filename as an argument on the commandline. $min_h and $max_h specify the expected minimum and maximum finisher times in hours.

1:  #!/usr/bin/perl  
2:  # Copyright Andreas Loeffler <al@exitzero.de>  
3:  # parse cuesheet xml files generated by http://www.bikeroutetoaster.com  
4:  # it will output information about coursepoints that are marked as type "Food"  
5:  # use this to provide information about your aid stations if you plan for  
6:  # some running event  
7:  # Example: $ parse-cuesheet.pl cuesheet-sut100q2.xml  
8:  use strict;  
9:  use warnings;  
10:  # use module  
11:  use XML::Simple;  
12:  use Data::Dumper;  
13:  use Date::Calc qw(:all);  
14:  my $xmlfile = $ARGV[0];  
15:  die "usage: parse-cuesheet.pl brt-cuesheet (xml)\n" unless (defined $xmlfile && -s $xmlfile);  
16:  # create object  
17:  my $xml = new XML::Simple (KeyAttr=>[]);  
18:  # read XML file  
19:  my $data = $xml->XMLin($ARGV[0]);  
20:  print "xml file: $ARGV[0]\n";  
21:  my $min_h = 16;  
22:  my $max_h = 30;  
23:  my @start = (2012, 10, 13, 8, 0, 0);  
24:  my @end = Add_Delta_DHMS(@start, 0, $max_h, 0, 0);  
25:  my @now = Today_and_Now();  
26:  my @d_dhms = Delta_DHMS(@now, @start);  
27:  my $days = Delta_Days($now[0], $now[1], $now[2],  
28:             $start[0], $start[1], $start[2]);  
29:  my $vpn = 1;  
30:  my $prev;  
31:  my @d;  
32:  my %vps;  
33:  my $points; # points hashref  
34:  my $units;  
35:  my $pt = 0;  
36:  my $have_point = 0;  
37:  my $total_distance = 0;  
38:  my $toMi = 0.6214;  
39:  my $toKm = 1;  
40:  print "start: @start\n";  
41:  print "end:  @end\n";  
42:  print "now: @now\n";  
43:  print "Noch $d_dhms[0] Tage, $d_dhms[1] Stunden und $d_dhms[2] Minuten bis zum Start\n";  
44:  print "Zielschluss: @end\n\n";  
45:  $units = $data->{distanceUnits};  
46:  print "distanceUnits: $units\n";  
47:  if ($units eq 'miles') {  
48:     $toMi = 1;  
49:     $toKm = 1.6092;  
50:  }  
51:  foreach my $p (@{$data->{points}->{point}})  
52:  {  
53:     next unless ($p->{pointType} eq 'Food');  
54:  #   print $p->{name}, "\n";  
55:  #   print "lat/lng: ", $p->{lat}, "/", $p->{lng}, "\n";  
56:  #   print "total dist: ", $p->{totalDistance}, "\n";  
57:  #   print "point type: ", $p->{pointType}, "\n";  
58:  #   print "\n";  
59:     if (!defined $prev){ $prev = $p->{totalDistance};}  
60:     my $delta = $p->{totalDistance} - $prev;  
61:     $prev = $p->{totalDistance};  
62:     printf "%s:\t%5.1f mi / %5.1f km ", $p->{name}, $p->{totalDistance} * $toMi, $p->{totalDistance} * $toKm;  
63:     printf "delta %5.2f mi / %5.2f km\n", $delta * $toMi, $delta * $toKm;  
64:     push @d, $delta;  
65:     $vps{$p->{name}} = $p->{totalDistance};  
66:     if ($p->{name} eq "ZIEL") { $total_distance = $p->{totalDistance}};  
67:     $vpn++;  
68:  }  
69:  my $avg = 0;  
70:  foreach (@d) {  
71:     $avg += $_;  
72:  }  
73:  printf "avg milage between aid stations: %.2f mi / %.2f km\n", ($avg / $#d) * $toMi, ($avg / $#d) * $toKm;  
74:  print "\n";  
75:  print "Durchgangszeiten:\n";  
76:  printf "total: %.2f km\n", $total_distance * $toKm;  
77:  my $min_pace = ($max_h * 60 * 60) / ($total_distance * $toKm);  
78:  my $max_pace = ($min_h * 60 * 60) / ($total_distance * $toKm);  
79:  printf "min pace (min/km) = %.2d:%.2d\n", $min_pace/60,$min_pace % 60;  
80:  printf "max pace (min/km) = %.2d:%.2d\n", $max_pace/60,$max_pace % 60;  
81:  foreach (sort keys %vps) {  
82:     next unless defined $vps{$_};  
83:     my @first_h_m = (($vps{$_} * $max_pace)/(60*60),  
84:             (($vps{$_} * $max_pace)/60) % 60);  
85:     my @last_h_m = (($vps{$_} * $min_pace)/(60*60),  
86:             (($vps{$_} * $min_pace)/60) % 60);  
87:     my @first_date = Add_Delta_DHMS(@start, 0, @first_h_m, 0);  
88:     my @last_date = Add_Delta_DHMS(@start, 0, @last_h_m, 0);  
89:     my @vp_delta = Delta_DHMS(@first_date, @last_date);  
90:     printf "%s\t%6.2f\t", $_, $vps{$_};  
91:     printf " von %s %.2d:%.2d (%.2d:%.2d)",  
92:       Day_of_Week_Abbreviation(Day_of_Week($first_date[0], $first_date[1], $first_date[2])),  
93:       $first_date[3], $first_date[4], @first_h_m;  
94:     printf " bis %s %.2d:%.2d (%.2d:%.2d)",  
95:       Day_of_Week_Abbreviation(Day_of_Week($last_date[0], $last_date[1], $last_date[2])),  
96:       $last_date[3], $last_date[4], @last_h_m;  
97:     printf " (VP offen fuer %.2d:%.2d Stunden)\n", $vp_delta[1], $vp_delta[2];  
98:     #printf "day %s\n", Day_of_Week_Abbreviation(Day_of_Week($first_date[0], $first_date[1], $first_date[2]));  
99:  }  

Download the perl script here.


Sample output:
xml file: sut100s-cuesheet.xml
start: 2012 10 13 8 0 0
end:   2012 10 14 14 0 0
now: 2012 6 9 21 1 7
Noch 125 Tage, 10 Stunden und 58 Minuten bis zum Start
Zielschluss: 2012 10 14 14 0 0

distanceUnits: kms
VP1:  16.3 mi /  26.3 km  delta  0.00 mi /  0.00 km
VP2:  30.1 mi /  48.5 km  delta 13.81 mi / 22.22 km
VP3:  44.5 mi /  71.6 km  delta 14.35 mi / 23.09 km
VP4:  56.2 mi /  90.4 km  delta 11.69 mi / 18.81 km
VP5:  67.3 mi / 108.3 km  delta 11.17 mi / 17.97 km
VP6:  80.1 mi / 128.8 km  delta 12.73 mi / 20.48 km
VP7:  93.0 mi / 149.7 km  delta 12.96 mi / 20.86 km
ZIEL: 101.0 mi / 162.6 km  delta  8.03 mi / 12.92 km
avg milage between aid stations: 12.10 mi / 19.48 km

Durchgangszeiten:
total: 162.61 km
min pace (min/km) = 11:04
max pace (min/km) = 05:54
VP1  26.26  von Sat 10:35 (02:35)  bis Sat 12:50 (04:50) (VP offen fuer 02:15 Stunden)
VP2  48.48  von Sat 12:46 (04:46)  bis Sat 16:56 (08:56) (VP offen fuer 04:10 Stunden)
VP3  71.57  von Sat 15:02 (07:02)  bis Sat 21:12 (13:12) (VP offen fuer 06:10 Stunden)
VP4  90.38  von Sat 16:53 (08:53)  bis Sun 00:40 (16:40) (VP offen fuer 07:47 Stunden)
VP5 108.35  von Sat 18:39 (10:39)  bis Sun 03:59 (19:59) (VP offen fuer 09:20 Stunden)
VP6 128.83  von Sat 20:40 (12:40)  bis Sun 07:46 (23:46) (VP offen fuer 11:06 Stunden)
VP7 149.69  von Sat 22:43 (14:43)  bis Sun 11:36 (27:36) (VP offen fuer 12:53 Stunden)
ZIEL 162.61  von Sun 00:00 (16:00)  bis Sun 14:00 (30:00) (VP offen fuer 14:00 Stunden)