/** * Calculate strides array * @return array */ public function calculate() { if (!$this->Trackdata->has(Trackdata\Entity::TIME) || !$this->Trackdata->has(Trackdata\Entity::DISTANCE) || !$this->Trackdata->has(Trackdata\Entity::CADENCE)) { return []; } $Time = $this->Trackdata->time(); $Distance = $this->Trackdata->distance(); $Cadence = $this->Trackdata->cadence(); $Size = $this->Trackdata->num(); $this->Strides[] = $Cadence[0] > 0 && $Time[0] > 0 ? round($Distance[0] * 1000 * 100 / ($Cadence[0] * 2 / 60 * $Time[0])) : 0; for ($i = 1; $i < $Size; ++$i) { $this->Strides[] = $Cadence[$i] > 0 && $Time[$i] - $Time[$i - 1] > 0 ? round(($Distance[$i] - $Distance[$i - 1]) * 1000 * 100 / ($Cadence[$i] * 2 / 60 * ($Time[$i] - $Time[$i - 1]))) : 0; } return $this->Strides; }
/** * Run fast smoothing for step size * * Although this does not look nice and is not the cleanest code, * direct access to the arrays is approx. 5-times faster. * (0.02s vs 0.11s for an array of 10.000 elements) */ protected function runFastSmoothingForSteps() { $distance = $this->Trackdata->distance(); $time = $this->Trackdata->time(); $lastDist = 0; $lastTime = 0; foreach ($distance as $i => $dist) { if ($i != 0 && $i % $this->StepSize == 0) { $pace = $dist - $lastDist > 0 ? round(($time[$i] - $lastTime) / ($dist - $lastDist)) : 0; if ($this->KeepArraySize) { for ($j = 0; $j < $this->StepSize; ++$j) { $this->Smoothed[] = $pace; } } else { $this->Smoothed[] = $pace; } $lastDist = $dist; $lastTime = $time[$i]; } } if ($this->KeepArraySize && !empty($distance)) { $pace = $dist - $lastDist > 0 ? round(($time[$i] - $lastTime) / ($dist - $lastDist)) : 0; for ($j = count($this->Smoothed), $num = $this->Trackdata->num(); $j < $num; ++$j) { $this->Smoothed[] = $pace; } } }
/** * Calculate power array * * A constant factor of 1.5 was used in previous versions - and I don't know why. * Without this factor results equal standard tools. * * @author Nils Frohberg * @author Hannes Christiansen * @see http://www.blog.ultracycle.net/2010/05/cycling-power-calculations * @param int $weight [kg] Weight of rider and bike * @param float $powerFactor constant factor * @return array */ public function calculate($weight = 75, $powerFactor = 1.0) { if (!$this->Trackdata->has(Trackdata\Entity::TIME) || !$this->Trackdata->has(Trackdata\Entity::DISTANCE)) { return []; } $everyNthPoint = ceil($this->Size / 1000); $n = $everyNthPoint; $grade = 0; $calcGrade = $this->knowsRoute() && $this->Route->hasElevations(); $ArrayTime = $this->Trackdata->time(); $ArrayDist = $this->Trackdata->distance(); $ArrayElev = $this->knowsRoute() ? $this->Route->elevations() : array(); $Frl = $weight * self::GRAVITY * self::CRR; $Fwpr = 0.5 * self::AREA * self::CW * $this->rho(); $Fslp = $weight * self::GRAVITY; for ($i = 0; $i < $this->Size - 1; $i++) { if ($i % $everyNthPoint == 0) { if ($i + $n > $this->Size - 1) { $n = $this->Size - $i - 1; } $distance = ($ArrayDist[$i + $n] - $ArrayDist[$i]) * 1000; $grade = $distance == 0 || !$calcGrade ? 0 : ($ArrayElev[$i + $n] - $ArrayElev[$i]) / $distance; } $distance = $ArrayDist[$i + 1] - $ArrayDist[$i]; $time = $ArrayTime[$i + 1] - $ArrayTime[$i]; if ($time > 0) { $Vmps = $distance * 1000 / $time; $Fw = $Fwpr * $Vmps * $Vmps; $Fsl = $Fslp * $grade; $this->Power[] = round(max($powerFactor * ($Frl + $Fw + $Fsl) * $Vmps, 0)); } else { $this->Power[] = 0; } } $this->Power[] = $this->Power[$this->Size - 2]; /* XXX */ return $this->Power; }