TelemetrySign in

Track progress s

Source engine/src/dtta/engine/track/{centerline,projection}.py · parameters centerline_*, proj_*.

The shared coordinate for every comparison is the distance s (metres) along a fixed closed centerline, measured from the start/finish gate in the direction of travel. It is not the racing line: a lap's lateral offset from the centerline is a measured quantity, and two laps taking different lines are aligned at physically identical places.

Centerline construction

  1. Valid GPS points of the racing laps are ordered by a provisional progress parameter (unwrapped polar angle about the track centroid, which works for ovals).
  2. They are binned into centerline_bins (180) angular bins; the median x, y of each bin forms a closed polyline (empty bins are filled by circular interpolation, then a circular median over ±1 bin is applied).
  3. The polyline is smoothed with a least-squares Fourier series of the closed curve: the smallest number of harmonics (from 4 up to centerline_max_harmonics = 32) whose RMS residual to the bin medians is at most centerline_smooth_rms_m (1 m).
  4. The curve is resampled at uniform arc length centerline_ds_m (1 m): C(s)C(s), s[0,L)s \in [0, L), with heading ψc(s)=atan2(y,x)\psi_c(s) = \operatorname{atan2}(y', x') and signed curvature κ=(xyyx)/(x2+y2)3/2\kappa = (x'y'' - y'x'')/(x'^2 + y'^2)^{3/2} from central differences.
  5. s = 0 is placed at the gate; direction is the direction of travel.

The centerline is versioned (its hash is an input of every downstream artifact). Segment boundaries are stored as fractions of LL so they survive a rebuild.

Continuity-constrained projection

Independent nearest-neighbour projection can snap a noisy point to the opposite straight of a narrow oval or to a parallel pit lane. Instead, each lap is projected sequentially with a prediction window:

  • Predicted progress: spred=sprev+viΔts_{pred} = s_{prev} + v_i\,\Delta t.
  • Search window: [spredmax(5m,  0.5vΔt+3σs),  spred+max(10m,  1.5vΔt+3σs)][s_{pred} - \max(5\,\mathrm{m},\; 0.5 v\Delta t + 3\sigma_s),\; s_{pred} + \max(10\,\mathrm{m},\; 1.5 v\Delta t + 3\sigma_s)] with σs\sigma_s = proj_sigma_s_m (3 m).
  • Among the centerline points in the window the one with the smallest perpendicular distance n|n| is chosen, provided n|n| \le proj_n_max_m (30 m) and ssprevs \ge s_{prev} - proj_back_tol_m (2 m).
  • Confidence: c=clip(1n/nmax)clip(1sspred/window)c = \mathrm{clip}(1 - |n|/n_{max}) \cdot \mathrm{clip}(1 - |s - s_{pred}|/\text{window}).
  • If no candidate qualifies the sample is marked lost, s=spreds = s_{pred}, confidence 0. More than proj_lost_limit (5) consecutive lost samples invalidates the lap (projection_lost).
  • The gate crossing pins (tstart,0)(t_{start}, 0) and (tend,L)(t_{end}, L) so s unwraps continuously through the gate.

The signed lateral offset nn is positive to the left of the direction of travel.

From samples to a grid

t(s) for a lap is a monotone piecewise-cubic interpolant (PCHIP) through the running maximum of the projected s values, anchored at (0,0)(0, 0) and (L,T)(L, T), evaluated on the 1 m grid. PCHIP preserves monotonicity and cannot overshoot. Speed, path accelerations, lateral offset and projection confidence are linearly interpolated onto the same grid. Every chart, the map cursor and the readout use these grid values directly; the browser never interpolates between them.

Verified

  • Real fixtures: proj_lost_count = 0 and mean projection confidence 0.85–0.96 on every racing lap.
  • Synthetic (engine/tests/synthetic): a 40 m-wide oval with 3 m GPS noise never projects to the wrong straight; a pit lane 8 m outside the front stretch creates no lap; a 20 m infield excursion is lost for ≤ 5 samples and the lap survives; crossing the gate with ±3 m noise unwraps s without a discontinuity.
  • Centerline arc length on a synthetic ellipse within 0.1 % of the analytic value; curvature sign tested.