Why we built TrackNarrator
Race engineers live in plots and CSV files; drivers live in feelings and memory.
TrackNarrator is an attempt to bridge that gap.
Given real Toyota GR Cup telemetry from Barber Motorsports Park, the goal was to answer a simple question:
“After a session, what is the one page a coach wants, and what is the one story a driver can remember?”
Instead of yet another generic dashboard, TrackNarrator focuses on coaching-ready post-session insight: where did we gain or lose time, which laps actually matter, and how do we explain that in plain language.
What TrackNarrator does
- Ingests the official TRD Barber dataset (telemetry, weather, sections)
- Normalizes it into a unified SessionBundle v0.1.2 schema
- Computes key metrics for a single driver session:
- Total laps, best/median lap, session duration
- Lap time deltas vs a reference lap:
( \Delta t_{\text{lap}} = t_{\text{lap}} - t_{\text{reference}} ) - Simple moving-average trend for pace
- Detects notable laps and segments using robust statistics
- Produces a static, judge-friendly HTML demo that shows:
- KPI cards for laps and lap times
- A Lap Time Deltas chart with clear zero baseline and legend
- A “Coach Score & Performance Badge” summarizing consistency
- A “Key Events & Coaching Insights” block explaining what to talk about first
The hosted demo is available at:
- GitHub Pages demo: https://sofus-deng.github.io/tracknarrator
(This is a read-only viewer backed by pre-generated demo data from the Barber dataset.)
How we built it
Data & schema
- Started from the official TRD Barber Motorsports Park dataset (Race 1/2 files).
- Added a small “SPEC” document describing a unified
SessionBundleJSON schema. - Implemented a
prepare_barber_from_rawpipeline that:- Reads raw TRD CSVs from
data/barber/raw/ - Handles both “wide” and “long” telemetry formats
- Normalizes telemetry, weather, and section timing into canonical CSVs
- Reads raw TRD CSVs from
- Re-used the existing ingestion modules to build a single
bundle_sample_barber.jsonfixture that follows the schema.
Backend & analytics
- Python backend with a small service layer for:
- Ingestion of canonical CSVs into a
SessionBundle - Lap-time deltas, moving averages, and basic event detection
- Ingestion of canonical CSVs into a
- Emphasis on tests and robustness:
pytesttest suite with ~79–80% coverage- Extra tests to make sure CSV ingestion fails gracefully when columns are missing, files are empty, or numeric fields are malformed
- Shell scripts for “quality gates” that run tests and acceptance checks
Frontend demo
- A lightweight static demo hosted on GitHub Pages:
- Plain HTML + CSS + vanilla JavaScript (no heavy framework)
- A single-page layout optimized for judges on desktop
- Toast notifications instead of inline status text
- Clear copy explaining what the chart and KPIs mean, in non-technical language
The idea is that engineers can run the full pipeline locally, while judges can simply open the hosted demo and still see a realistic session view.
What we learned
- Telemetry is messy. Even within one dataset, formats differ (wide vs long telemetry, various header names). Investing in a small but clear schema spec and a “prepare from raw” step pays off quickly.
- Explain the plot, not just draw it. The biggest UX improvement came not from changing chart types, but from adding a zero baseline, legends, helper text, and coach-oriented wording.
- Static demos are underrated. A pre-generated
summary.json+coach_score.jsonplus a GitHub Pages viewer is enough to show the core idea without asking judges to spin up a full backend.
Challenges
- Choosing the right level of ambition. It is tempting to aim for full multi-driver, multi-session comparisons. For the hackathon timeline, we scoped that to design docs only and focused the implementation on a solid single-driver session flow.
- Making ingestion judge-friendly. Raw racing data has many files; we had to
decide which ones truly matter. The solution was:
- Use only the telemetry, weather, and section-timing files for the demo.
- Provide a simple script (
prepare_barber_from_raw.sh) that turns the raw ZIP into the exact CSVs the system expects.
- Balancing technical depth and clarity. The project uses schemas, tests, and pipelines, but the final demo must be readable by non-technical judges. Iterating on copy and layout took almost as long as the code.
What’s next
If we continue beyond the hackathon, the next steps would be:
- Implement the already-designed multi-driver comparison features:
- Head-to-head lap overlays
- Team dashboards for coach debriefs
- Narrative generation in English and Chinese
- Add simple “what-if” suggestions (e.g. “if you repeat your best sector 2 every lap, your projected race time improves by X seconds”).
- Integrate with additional circuits beyond Barber using the same SessionBundle schema.
For Hack the Track, TrackNarrator is a focused, judge-friendly slice of that vision: one driver, one session, one clear story.
Log in or sign up for Devpost to join the conversation.