ZwiftでZ2ライドをした時にほんまにZ2でいけたかを計算するために、各ハートレートゾーンごとの割合を出すphpスクリプトを作ってみた。.tcx、.fit、.gpxに対応。バイナリファイルである.fitと、子要素とか使いにくい.gpxはgpsbabelで.tcxに変換。gpsbabelの出力ファイルを-にしたら標準出力に表示してくれた。
#!/usr/bin/php <?php error_reporting(E_ERROR); $margins=array(60,75,85,95); $zones=array(0,0,0,0,0); $maxhr = 191; $duration = 3600; #unit:second $file = $argv[1]; $ext = strstr($file,'.'); switch($ext){ case ".gpx": $xml = simplexml_load_string(`gpsbabel -t -i gpx -f $file -o gtrnctr,course=0 -F -`); break; case ".fit": $xml = simplexml_load_string(`gpsbabel -t -i garmin_fit,allpoints=1 -f $file -o gtrnctr,course=0 -F -`); break; case ".tcx": $xml = simplexml_load_file($file); break; default; die("$ext is not supported."); } $elements = $xml->Activities->Activity->Lap->Track->Trackpoint; $endtime = strtotime($elements[0]->Time) + $duration ; foreach($elements as $element){ $data[] = array( 'time' => strtotime($element->Time), 'hr_ratio' => $element->HeartRateBpm->Value / $maxhr *100 ) ; } foreach($data as $i => $datum){ if($datum[$i] > $endtime){ break;} foreach($margins as $i => $margin){ if( $datum['hr_ratio'] <= $margin ){ $zones[$i]++; break; } } } foreach($zones as $n => $zone){ $zones_ratio[$n] = round( ($zone / array_sum($zones)) * 1000) /10; } $output = implode("\t",$zones_ratio); if(getenv('TERM')){ echo "$output\n"; }else{ exec("echo $output|zenity --text-info --height=100"); } ?>
時間を区切っているのはクールダウン部分を除外するため。
Z2は何%までかについては70%と75%の両方の説があるけど、Zwiftアプリが採用しているらしき75%を採用。
実行例。