Source for file PolarAutoLap.class.php
Documentation is available at PolarAutoLap.class.php
* Class to automatize laps generation for distance steps and interval training
* @author Jean-Philippe Brunon <jp75018@free.fr>
* @copyright 2007-2009 Jean-Philippe Brunon
* @license http://www.opensource.org/licenses/gpl-license.php GPL
* @version $Id: PolarAutoLap.class.php 64 2009-03-25 13:42:20Z jp75018 $
* General configuration file
require_once ('conf/config.php');
* Output is language dependant
require_once ('lang/strings_' .
$GLOBALS['lang'] .
'.inc.php');
* HTML output (formatting)
require_once ('include/html.php');
* Class to automatize laps generation for distance steps and interval training
* Sport standard alias (use to compute mechanical energy)
* @param string $sport_alias Standard sport alias
* Generate laps array from detailed HR data for every time or distance step, or
* @param string $lap_type Lap type in ('time','distance','altitude')
* @param array $data Heart rate data
* @param integer $interval Recording interval (seconds)
* @param integer $distance Real distance (meters, if speed measure)
* @param integer $rest_hr Rest heart rate of runner
* @param integer $weight Weight of runner (Kg), to compute energy if > 0
* @param integer $step_or_delta_h Lap step (sec*10 or meters) or delta H
* @param integer $vma VMA in km/h to compute physio energy
* @return array Array of laps with same structure as 'plw_lap' SQL table
$rest_hr, $weight, $step_or_delta_h, $vma)
$step =
$step_or_delta_h;
// Compute subtotal groups from time step
default :
// 150, 9000, 36000
$step =
$step_or_delta_h;
// Compute subtotal groups from distance step
$delta_h =
$step_or_delta_h;
$is_hr = isset
($data[0]['hr']);
$is_speed = isset
($data[0]['speed']);
$is_cad = isset
($data[0]['cadence']);
$is_alti = isset
($data[0]['altitude']);
// Compute ratio to adjust distance
for ($i =
0; $i <
$data_nb; $i++
)
{ $d +=
$data[$i]['speed']; }
{ $d_ratio =
$distance /
($d *
($interval /
36)); }
if ($lap_type ==
'altitude')
// Store cumulated distance to check lap distance not too short
for ($i =
0; $i <
$data_nb; $i++
)
$data_dist[$i] =
$data_dist[$i -
1] +
$d_ratio *
$data[$i]['speed'] *
$interval /
36;
// If 'altitude' laps, 1st pass to set pointers to data for slope change
if ($lap_type ==
'altitude')
// Minimum altitude change : 2 * MIN_DELTA_ALTITUDE or 2% of exe delta H
if (($delta_h /
50) >
$min_delta_h)
{ $min_delta_h =
$delta_h /
50; }
// Minimum lap distance : 100m or 0.25% of total distance
if (($distance /
400) >
$min_lap_dist)
{ $min_lap_dist =
$distance /
400; }
// Minimum lap duration : 20" or 0.25% of total duration
$exe_elapsed =
$interval *
$data_nb;
if (($exe_elapsed /
400) >
$min_lap_time)
{ $min_lap_time =
$exe_elapsed /
400; }
-
0.20, -
0.15, -
0.10, -
0.08, -
0.06, -
0.04, -
0.02, -
0.01, -
0.005,
0, 0.005, 0.01, 0.02, 0.04, 0.06, 0.08, 0.10, 0.15, 0.20
while (list
($sl_ind, $sl) =
each($slopes))
$local_min =
$data[0]['altitude'];
$local_max =
$data[0]['altitude'];
$d =
$d_ratio *
$interval *
$data[0]['speed'] /
36;
for ($i =
1; $i <
$data_nb; $i++
)
// Pseudo-rotation => Homothety by distance from depart
// If no speed : If distance => Constant speed, if not => 10.8 km/h
{ $d =
$i *
$distance /
$data_nb; }
{ $d =
$i *
$interval *
3; } // 3 m/s = 10.8 km/h
$altitude =
$data[$i]['altitude'] +
$sl *
$d;
if (($altitude >=
($local_min +
$min_delta_h)) &&
($p_local !=
'min'))
if ($sl ==
0) // If slope = 0 => Store for priority
$local_max_ind =
$local_min_ind;
if ($altitude >
$local_max)
if (($altitude <=
($local_max -
$min_delta_h)) &&
if ($sl ==
0) // If slope = 0 => Store for priority
$local_min_ind =
$local_max_ind;
if ($altitude <
$local_min)
if ($altitude <
$alti_local_min)
{ $alti_local_min =
$altitude; }
{ $d +=
$d_ratio *
$interval *
$data[$i]['speed'] /
36; }
// Remove some pointers if too close (loop till nb of points change)
$slope_nb =
count($slope_tab);
$prev_slope_nb =
$slope_nb +
1;
while ($slope_nb <
$prev_slope_nb)
$prev_slope_nb =
$slope_nb;
for ($i =
0; $i <
$slope_nb; $i++
)
$lap_too_short =
(($data_dist[$slope_tab[$i]] -
$data_dist[$prev_data_ind]) <
$min_lap_dist) ?
true :
false;
$lap_too_short =
((($slope_tab[$i] -
$prev_data_ind) *
$interval) <
$min_lap_time) ?
true :
false;
if ($i ==
($slope_nb -
1))
{ unset
($slope_tab[$i -
1]); }
if ((! in_array($slope_tab[$i], $zero_slope)) ||
in_array($prev_data_ind, $zero_slope) ||
($i ==
0))
{ unset
($slope_tab[$i]); }
if (in_array($slope_tab[$i], $zero_slope) &&
(! in_array($prev_data_ind, $zero_slope)))
{ unset
($slope_tab[$i -
1]); }
$prev_data_ind =
$slope_tab[$i];
$slope_nb =
count($slope_tab);
$hr_ini =
$data[0]['hr'];
$hr_min =
$data[0]['hr'];
$hr_max =
$data[0]['hr'];
$speed_ini =
$data[0]['speed'];
$speed_min =
$data[0]['speed'];
$speed_max =
$data[0]['speed'];
$cadence_ini =
$data[0]['cadence'];
$cadence_min =
$data[0]['cadence'];
$cadence_max =
$data[0]['cadence'];
$alti_ini =
$data[0]['altitude'];
$alti_min =
$data[0]['altitude'];
$alti_max =
$data[0]['altitude'];
$alti_local_min =
$data[0]['altitude'];
for ($i =
0; $i <
$data_nb; $i++
)
$speed =
$data[$i]['speed'];
$dd =
$d_ratio *
$interval *
$speed /
36;
$end_lap =
(($t_lap +
$interval *
10) >=
$step) ?
true :
false;
$end_lap =
(($d_lap +
$dd) >=
$step) ?
true :
false;
if ($i ==
($data_nb -
1))
if ($i ==
($data_nb -
1))
$dt =
(($step -
$d_lap) /
$dd) *
$interval *
10;
default :
// time, altitude
if ($data[$i]['hr'] <
$hr_min)
{ $hr_min =
$data[$i]['hr']; }
if ($data[$i]['hr'] >
$hr_max)
{ $hr_max =
$data[$i]['hr']; }
if ($data[$i]['cadence'] <
$cadence_min)
{ $cadence_min =
$data[$i]['cadence']; }
if ($data[$i]['cadence'] >
$cadence_max)
{ $cadence_max =
$data[$i]['cadence']; }
if ($data[$i]['cadence'] >
0)
$stride =
250 *
$speed /
(3 *
$data[$i]['cadence']);
if (($stride >
$stride_max) &&
($stride <=
STRIDE_MAX))
{ $stride_max =
$stride; }
$sum_alti +=
$data[$i]['altitude'] *
$dt /
10;
if ($data[$i]['altitude'] <
$alti_min)
{ $alti_min =
$data[$i]['altitude']; }
if ($data[$i]['altitude'] >
$alti_max)
{ $alti_max =
$data[$i]['altitude']; }
$ascend +=
$data[$i]['altitude'] -
$alti_local_min;
$alti_local_min =
$data[$i]['altitude'];
if ($data[$i]['altitude'] <
$alti_local_min)
{ $alti_local_min =
$data[$i]['altitude']; }
if ($weight &&
$is_speed)
$cin_en +=
$speed *
$speed -
$p_speed *
$p_speed;
$speed *
$speed /
46656; // delta_dist * C * V * V
// Subtotal every 'step_nb' lap if time or distance,
// local min / max if 'altitude'
$laps[$lap_nb]['subtotal'] =
($lap_nb %
$step_nb) ?
'no':
'yes';
$laps[$lap_nb]['subtotal'] =
in_array($i, $zero_slope) ?
'yes':
'no';
$laps[$lap_nb]['elapsed'] =
round($i *
$interval *
10 +
$dt);
$laps[$lap_nb]['lap_elapsed'] =
round($t_lap);
{ $laps[$lap_nb]['distance'] =
round($lap_d); }
$beat_nb +=
$data[$i]['hr'] *
$dt /
600;
$laps[$lap_nb]['ini_hr'] =
$hr_ini;
$laps[$lap_nb]['min_hr'] =
$hr_min;
$laps[$lap_nb]['avg_hr'] =
round($beat_nb /
($t_lap /
600), 2);
$laps[$lap_nb]['max_hr'] =
$hr_max;
$laps[$lap_nb]['end_hr'] =
$data[$i]['hr'];
$laps[$lap_nb]['beat_sum'] =
$beat_nb;
$laps[$lap_nb]['ini_speed'] =
$speed_ini;
$laps[$lap_nb]['min_speed'] =
$speed_min;
$laps[$lap_nb]['avg_speed'] =
round(360 *
$lap_d /
$t_lap, 2);
$laps[$lap_nb]['max_speed'] =
$speed_max;
$laps[$lap_nb]['end_speed'] =
$speed;
$stride_nb +=
$data[$i]['cadence'] *
$dt /
300;
$laps[$lap_nb]['ini_cadence'] =
$cadence_ini;
$laps[$lap_nb]['min_cadence'] =
$cadence_min;
$laps[$lap_nb]['avg_cadence'] =
round($stride_nb /
($t_lap /
300), 2);
$laps[$lap_nb]['max_cadence'] =
$cadence_max;
$laps[$lap_nb]['end_cadence'] =
$data[$i]['cadence'];
{ $laps[$lap_nb]['avg_stride'] =
round(($lap_d*
100) /
$stride_nb,2); }
$laps[$lap_nb]['max_stride'] =
round($stride_max, 2);
$laps[$lap_nb]['ini_altitude'] =
$alti_ini;
$laps[$lap_nb]['min_altitude'] =
$alti_min;
$laps[$lap_nb]['avg_altitude'] =
round(10 *
$sum_alti /
$t_lap);
$laps[$lap_nb]['max_altitude'] =
$alti_max;
$laps[$lap_nb]['end_altitude'] =
$data[$i]['altitude'];
$laps[$lap_nb]['ascend'] =
$ascend;
$laps[$lap_nb]['physio_energy'] =
$cin_en *=
$weight /
2592; // 2592 = 2 * (10 * 3.6)^2
$air_en =
round($air_en *
$weight);
$descend =
$ascend +
$alti_ini -
$data[$i]['altitude'];
$laps[$lap_nb]['meca_energy'] =
round($cin_en +
$pot_en_up -
$pot_en_down +
$mov_en +
$grn_en +
$air_en);
$d_lap =
$d_lap +
$dd -
$step;
default :
// time, altitude
$t_lap =
10 *
$interval -
$dt;
$beat_nb =
$data[$i]['hr'] *
(10 *
$interval -
$dt) /
600;
$hr_ini =
$data[$i]['hr'];
$hr_min =
$data[$i]['hr'];
$hr_max =
$data[$i]['hr'];
$stride_nb =
$data[$i]['cadence'] *
(10 *
$interval -
$dt) /
300;
$cadence_ini =
$data[$i]['cadence'];
$cadence_min =
$data[$i]['cadence'];
$cadence_max =
$data[$i]['cadence'];
$sum_alti =
$data[$i]['altitude'] *
(10 *
$interval -
$dt) /
10;
$alti_ini =
$data[$i]['altitude'];
$alti_min =
$data[$i]['altitude'];
$alti_max =
$data[$i]['altitude'];
if ($is_speed &&
($lap_type ==
'distance'))
if ($d >=
$distance) // End of data = end of lap
$t_lap +=
10 *
$interval;
$beat_nb +=
$data[$i]['hr'] *
$interval /
60;
if ($data[$i]['hr'] <
$hr_min)
{ $hr_min =
$data[$i]['hr']; }
if ($data[$i]['hr'] >
$hr_max)
{ $hr_max =
$data[$i]['hr']; }
if ($data[$i]['cadence'] <
$cadence_min)
{ $cadence_min =
$data[$i]['cadence']; }
if ($data[$i]['cadence'] >
$cadence_max)
{ $cadence_max =
$data[$i]['cadence']; }
$stride_nb +=
$data[$i]['cadence'] *
$interval /
30;
if ($data[$i]['cadence'] >
0)
$stride =
250 *
$speed /
(3 *
$data[$i]['cadence']);
if (($stride >
$stride_max) &&
($stride <=
STRIDE_MAX))
{ $stride_max =
$stride; }
$sum_alti +=
$data[$i]['altitude'] *
$interval;
if ($data[$i]['altitude'] <
$alti_min)
{ $alti_min =
$data[$i]['altitude']; }
if ($data[$i]['altitude'] >
$alti_max)
{ $alti_max =
$data[$i]['altitude']; }
$ascend +=
$data[$i]['altitude'] -
$alti_local_min;
$alti_local_min =
$data[$i]['altitude'];
if ($data[$i]['altitude'] <
$alti_local_min)
{ $alti_local_min =
$data[$i]['altitude']; }
if ($weight &&
$is_speed)
$cin_en +=
$speed *
$speed -
$p_speed *
$p_speed;
$speed *
$speed /
46656; // delta_dist * C * V * V
// Last lap is always a subtotal
$laps[count($laps)]['subtotal'] =
'yes';
* Generate laps array from Polar laps and interval training expression
* Two elements can be separated or not by an implicit recovery.
* Example : 3000m + 3000m
* One work or recovery element can consist in several Polar laps. There are 2
* - Work element : Polar laps are not merged to keep intermediate times.
* Example : 5000m whith a Polar lap every 1000m
* - Recovery element : Polar laps are merged.
* @param array $polar_laps Polar laps from database
* @param array $intervals Array of work / recovery elements
* @param integer $vma VMA in km/h (from database or computed),
* used to predict minimum speeds for work and
* maximum speeds for recovery
* @return array Array of laps with same structure as 'plw_lap' SQL table
* or null if Polar laps and interval training expression
// TODO : Try to "guess" if no speed measure...
Use 100% VMA = 6' / 85% VMA = 1H as upper limit with V = V0 - C*Log(D)
(linear speed decrease with log(distance), V (km/h), distance (km)
=> C = 0.15*VMA / (Log(0.85*VMA) - Log(0.1*VMA))
=> V0 = VMA + C * Log(0.1*VMA)
Min for work element / Max for recovery element = 2/3 upper limit
$c =
0.15 *
$vma /
(log(0.85 *
$vma) -
log(0.1 *
$vma));
$v0 =
$vma +
$c *
log(0.1 *
$vma);
// Compute speed and duration for standard distances for linear interpolation
50, 100, 150, 200, 250, 300, 400, 500,
600, 800, 1000, 1500, 2000, 2500, 3000, 4000,
5000, 6000, 8000, 10000, 15000, 20000, 21098, 42195
for ($i =
0; $i <
count($std_dist); $i++
)
$distance =
$std_dist[$i];
$max_speed =
$v0 -
$c *
log($std_dist[$i] /
1000);
$min_time =
3.6 *
$std_dist[$i] /
$max_speed;
$std_int[$i]['distance'] =
$std_dist[$i];
$std_int[$i]['speed'] =
$max_speed;
$std_int[$i]['duration'] =
$min_time;
// Loop on intervals to compute min work / max recovery speeds
for ($i =
0; $i <
count($intervals); $i++
)
// Work / recovery limit speed = 2/3 of max speed for distance / duration
if ($intervals[$i]['work_distance'])
$intervals[$i]['work_distance'], 'distance', $std_int);
if ($intervals[$i]['work_duration'])
$intervals[$i]['work_duration'], 'duration', $std_int);
if ($intervals[$i]['reco_distance'])
$intervals[$i]['reco_distance'], 'distance', $std_int);
if ($intervals[$i]['reco_duration'])
$intervals[$i]['reco_duration'], 'duration', $std_int);
Build cumulated laps (pyramid of N * (N + 1) values) with distance,
duration, average speed, and delta with limit speed from duration
(> 0 => work, < 0 => recovery)
$laps_copy =
$polar_laps;
while (list
($rank, $lap) =
each($polar_laps))
while (list
($rank_2, $lap_2) =
each($laps_copy))
$lap_cum[$rank][$rank_2]['distance'] =
$lap['distance'];
$lap_cum[$rank][$rank_2]['duration'] =
$lap['lap_elapsed'];
if (($prev_rank >
0) &&
($prev_rank_2 >
0))
$lap_cum[$rank][$rank_2]['distance'] +=
$lap_cum[$prev_rank][$prev_rank_2]['distance'];
$lap_cum[$rank][$rank_2]['duration'] +=
$lap_cum[$prev_rank][$prev_rank_2]['duration'];
$lap_cum[$rank][$rank_2]['avg_speed'] =
36 *
$lap_cum[$rank][$rank_2]['distance'] /
$lap_cum[$rank][$rank_2]['duration'];
$lap_cum[$rank][$rank_2]['delta'] =
$lap_cum[$rank][$rank_2]['avg_speed'] -
0.667 *
$this->_get_max_speed(
$lap_cum[$rank][$rank_2]['duration'] /
10, 'duration', $std_int);
// Create a list of cumulated laps sorted by 'delta' [N * (N + 1) values]
while (list
($rank, $lap_sum) =
each($lap_cum))
while (list
($rank_2, $lap) =
each($lap_sum))
$sorted_cum[$i++
] =
array($rank, $rank_2, $lap['delta']);
printf(" %5d[%+.2f]", $lap['distance'], $lap['delta']);
while (list
($rank_2, $lap) =
each($lap_sum))
while (list
($rank, $lap_sum) =
each($lap_cum))
{ echo
'-------------'; }
while (list
($rank, $lap_sum) =
each($lap_cum))
usort(&$sorted_cum, array($this, '_sort_cum_cmp'));
for ($i =
0; $i <
count($sorted_cum); $i++
)
if ($sorted_cum[$i][1] >
1)
{ $str_end =
sprintf("-> %2d", $sorted_cum[$i][0]); }
printf("%4d : %2d %s / %+5.2f / ", $i,
$sorted_cum[$i][0] -
$sorted_cum[$i][1] +
1, $str_end, $sorted_cum[$i][2]);
$duration =
$lap_cum[$sorted_cum[$i][0]][$sorted_cum[$i][1]]['duration'] /
10;
$distance =
$lap_cum[$sorted_cum[$i][0]][$sorted_cum[$i][1]]['distance'];
$avg_speed =
$lap_cum[$sorted_cum[$i][0]][$sorted_cum[$i][1]]['avg_speed'];
printf("%7.1f s / %5d m / %5.2f %s\n",
$duration, $distance, $avg_speed, $GLOBALS['str_abbr_speed_km_h']);
for ($i =
0; $i <
count($intervals); $i++
)
if ($intervals[$i]['work_distance'])
$str_work =
sprintf("W =%5d m [min:%5.2f %s]",
$intervals[$i]['work_distance'], $intervals[$i]['work_min_speed'],
$GLOBALS['str_abbr_speed_km_h']);
if ($intervals[$i]['work_duration'])
$str_work =
sprintf("W =%5d s [min:%5.2f %s]",
$intervals[$i]['work_duration'], $intervals[$i]['work_min_speed'],
$GLOBALS['str_abbr_speed_km_h']);
if ($intervals[$i]['reco_distance'])
$str_reco =
sprintf("R =%5d m [max:%5.2f %s]",
$intervals[$i]['reco_distance'], $intervals[$i]['reco_max_speed'],
$GLOBALS['str_abbr_speed_km_h']);
if ($intervals[$i]['reco_duration'])
$str_reco =
sprintf("R =%5d s [max:%5.2f %s]",
$intervals[$i]['reco_duration'], $intervals[$i]['reco_max_speed'],
$GLOBALS['str_abbr_speed_km_h']);
printf("%2d : %2d x { %s / %s }\n", $i, $intervals[$i]['repeat_nb'],
while (list
($rank, $lap) =
each($polar_laps))
printf("%3d : %7.1f s / %5d m / %4.1f %s\n", $rank,
$lap['lap_elapsed'] /
10, $lap['distance'], $lap['avg_speed'] /
10,
$GLOBALS['str_abbr_speed_km_h']);
Loop on intervals to find candidate lap groups in cumulated laps
1. closely match interval distance or duration within a tolerance
(tolerance is larger if distance / duration is small),
2. speed >= min work speed if work, speed <= max recovery speed if recovery
3. Sort candidates having max 'delta' if work, min delta if recovery.
- Unknown recovery possible (work with > 1 repeat, null recovery).
- Polar laps not in intervals are merged
- Keep laps if more than 1 Polar lap in interval =>
. Guess exact lap distance if interval distance with proportion / rounding
. If not possible => Merge Polar laps
Success only if all intervals are matched in right order
for ($i =
0; $i <
count($intervals); $i++
)
//print_r($intervals[$i]);
for ($rep =
0; $rep <
$intervals[$i]['repeat_nb']; $rep++
)
if ($intervals[$i]['work_distance'])
{ $value =
$intervals[$i]['work_distance']; $unit =
'distance'; }
if ($intervals[$i]['work_duration'])
{ $value =
$intervals[$i]['work_duration']; $unit =
'duration'; }
if ($intervals[$i]['reco_distance'])
{ $value =
$intervals[$i]['reco_distance']; $unit =
'distance'; }
{ $value =
$intervals[$i]['reco_duration']; $unit =
'duration'; }
if (! (list
($rank, $lap) =
each($polar_laps)))
$sum_duration +=
$lap['lap_elapsed'];
$sum_distance +=
$lap['distance'];
// Caution : Recovery of last repetition is optional !
//print_r($this->_merge_laps($polar_laps));
return $polar_laps; // Do nothing !
* Merge several laps to one lap
* @param array $laps Array of laps to merge (>=1 elements)
// Initial values + init min and max
if (isset
($laps[1]['ini_hr']))
{ $merged['ini_hr'] =
$laps[1]['ini_hr']; }
if (isset
($laps[1]['min_hr']))
{ $merged['min_hr'] =
$laps[1]['min_hr']; }
if (isset
($laps[1]['max_hr']))
{ $merged['max_hr'] =
$laps[1]['max_hr']; }
if (isset
($laps[1]['ini_speed']))
{ $merged['ini_speed'] =
$laps[1]['ini_speed']; }
if (isset
($laps[1]['min_speed']))
{ $merged['min_speed'] =
$laps[1]['min_speed']; }
if (isset
($laps[1]['max_speed']))
{ $merged['max_speed'] =
$laps[1]['max_speed']; }
if (isset
($laps[1]['ini_cadence']))
{ $merged['ini_cadence'] =
$laps[1]['ini_cadence']; }
if (isset
($laps[1]['min_cadence']))
{ $merged['min_cadence'] =
$laps[1]['min_cadence']; }
if (isset
($laps[1]['max_cadence']))
{ $merged['max_cadence'] =
$laps[1]['max_cadence']; }
if (isset
($laps[1]['max_stride']))
{ $merged['max_stride'] =
$laps[1]['max_stride']; }
if (isset
($laps[1]['ini_altitude']))
{ $merged['ini_altitude'] =
$laps[1]['ini_altitude']; }
if (isset
($laps[1]['min_altitude']))
{ $merged['min_altitude'] =
$laps[1]['min_altitude']; }
if (isset
($laps[1]['max_altitude']))
{ $merged['max_altitude'] =
$laps[1]['max_altitude']; }
// Loop on laps to cumulate values + min / max
for ($i =
1; $i <=
count($laps); $i++
)
$merged['lap_elapsed'] +=
$laps[$i]['lap_elapsed'];
if (isset
($laps[$i]['distance']))
$merged['distance'] +=
$laps[$i]['distance'];
if (isset
($merged['min_hr']))
if ($laps[$i]['min_hr'] <
$merged['min_hr'])
{ $merged['min_hr'] =
$laps[$i]['min_hr']; }
if (isset
($merged['max_hr']))
if ($laps[$i]['max_hr'] >
$merged['max_hr'])
{ $merged['max_hr'] =
$laps[$i]['max_hr']; }
if (isset
($merged['min_speed']))
if ($laps[$i]['min_speed'] <
$merged['min_speed'])
{ $merged['min_speed'] =
$laps[$i]['min_speed']; }
if (isset
($merged['max_speed']))
if ($laps[$i]['max_speed'] >
$merged['max_speed'])
{ $merged['max_speed'] =
$laps[$i]['max_speed']; }
if (isset
($merged['min_cadence']))
if ($laps[$i]['min_cadence'] <
$merged['min_cadence'])
{ $merged['min_cadence'] =
$laps[$i]['min_cadence']; }
if (isset
($merged['max_cadence']))
if ($laps[$i]['max_cadence'] >
$merged['max_cadence'])
{ $merged['max_cadence'] =
$laps[$i]['max_cadence']; }
if (isset
($merged['max_stride']))
if ($laps[$i]['max_stride'] >
$merged['max_stride'])
{ $merged['max_stride'] =
$laps[$i]['max_stride']; }
if (isset
($merged['min_altitude']))
if ($laps[$i]['min_altitude'] <
$merged['min_altitude'])
{ $merged['min_altitude'] =
$laps[$i]['min_altitude']; }
if (isset
($merged['max_altitude']))
if ($laps[$i]['max_altitude'] >
$merged['max_altitude'])
{ $merged['max_altitude'] =
$laps[$i]['max_altitude']; }
if (isset
($laps[$i]['ascend']))
{ $merged['ascend'] +=
$laps[$i]['ascend']; }
if (isset
($laps[$i]['physio_energy']))
{ $merged['physio_energy'] +=
$laps[$i]['physio_energy']; }
if (isset
($laps[$i]['meca_energy']))
{ $merged['meca_energy'] +=
$laps[$i]['meca_energy']; }
if (isset
($laps[$i]['beat_sum']))
{ $merged['beat_sum'] +=
$laps[$i]['beat_sum']; }
if (isset
($laps[$i]['avg_cadence']))
{ $pond_cadence +=
$laps[$i]['avg_cadence'] *
$laps[$i]['lap_elapsed']; }
if (isset
($laps[$i]['avg_altitude']))
{ $pond_altitude +=
$laps[$i]['avg_altitude'] *
$laps[$i]['lap_elapsed'];}
// End values + compute average values
$merged['elapsed'] =
$laps[$i -
1]['elapsed'];
if (isset
($laps[1]['avg_hr']))
round(600 *
$merged['beat_sum'] /
$merged['lap_elapsed'], 2);
if (isset
($laps[$i -
1]['end_hr']))
{ $merged['end_hr'] =
$laps[$i -
1]['end_hr']; }
if (isset
($laps[1]['avg_speed']))
round(360 *
$merged['distance'] /
$merged['lap_elapsed'], 2);
if (isset
($laps[$i -
1]['end_speed']))
{ $merged['end_speed'] =
$laps[$i -
1]['end_speed']; }
$merged['avg_cadence'] =
round($pond_cadence /
$merged['lap_elapsed'], 2);
if (isset
($merged['distance']))
round(30000 *
$merged['distance'] /
$pond_cadence, 2);
if (isset
($laps[$i -
1]['end_cadence']))
{ $merged['end_cadence'] =
$laps[$i -
1]['end_cadence']; }
$merged['avg_altitude'] =
round($pond_altitude /
$merged['lap_elapsed'], 2);
if (isset
($laps[$i -
1]['end_altitude']))
{ $merged['end_altitude'] =
$laps[$i -
1]['end_altitude']; }
if (isset
($laps[$i -
1]['description']))
{ $merged['description'] =
$laps[$i -
1]['description']; }
* Callback comparison function to sort cumulated laps by 'delta' value
* @param array $v1 1st value where [2] is delta value
* @param array $v2 2nd value where [2] is delta value
* @return integer -1 if v1 < v2, +1 if V2 > v1, 0 if v1 = v2
return ($v1[2] <
$v2[2]) ? -
1 :
1;
* Get maximum average speed for a given distance or duration
* Use dichotomy algorithm, to find closest lower and upper pre-computed speeds,
* then linear approximation.
* @param string $unit Unit for value in ('distance','duration').
* Distance in meters, duration in seconds.
* @param array $std_int Pre-computed data for standard distances, each
* element is array('distance' => <meters>,
* 'duration' => seconds, 'speed' => km/h)
* @return float Maximum average speed in km/h
$max =
count($std_int) -
1;
$i =
floor(($min +
$max) /
2);
if ($std_int[$i][$unit] >
$value)
$max_speed =
$std_int[$min]['speed'] +
($std_int[$max]['speed'] -
$std_int[$min]['speed']) *
($value -
$std_int[$min][$unit]) /
($std_int[$max][$unit] -
$std_int[$min][$unit]);
Documentation generated on Sat, 28 Mar 2009 23:15:43 +0000 by phpDocumentor 1.4.1