package ride import "time" const MovingTimeAlgorithmVersion = "v1" // movingTimeMinSpeedMps is the minimum implied speed between two consecutive // track points for the interval to count as moving (1 km/h). const movingTimeMinSpeedMps = 1.0 / 3.6 // Baseline backtest (356 rides, `-backtest`): mean err 3.9% (stderr 0.4), // p50 1.6, p75 4.6, p90 8.4, p95 12.1, p99 44.9. // Worst offenders overcount stationary GPS jitter (lunch stops) and // undercount trainer rides with little GPS movement. Tuned in future commits. func MovingTime(r Ride) time.Duration { var moving time.Duration for i := 1; i < r.Len(); i++ { dt := r.Timestamp(i).Sub(r.Timestamp(i - 1)) if dt <= 0 { continue } dd := r.DistanceM(i) - r.DistanceM(i - 1) if dd/dt.Seconds() > movingTimeMinSpeedMps { moving += dt } } return moving }