Skip to content

Release v2.13.1 — RaceChrono CSV v3 support - #85

Merged
SomethingNew71 merged 7 commits into
mainfrom
release/2.13.1
Aug 20, 2026
Merged

Release v2.13.1 — RaceChrono CSV v3 support#85
SomethingNew71 merged 7 commits into
mainfrom
release/2.13.1

Conversation

@SomethingNew71

Copy link
Copy Markdown
Collaborator

Summary

Adds native support for RaceChrono / RaceChrono Pro CSV v3 session exports (user request from a track-day driver), plus the v2.13.1 version bump and a site/docs catch-up.

New parser: RaceChrono CSV v3 (src/parsers/racechrono.rs)

  • Key,Value metadata preamble (quoted values, multi-line Notes), units row (.C → °C), and per-column sources row
  • Duplicate column names disambiguated by source (speed (gps) vs speed (calc)); unique names — latitude/longitude included — stay raw so the GPS Track Map lights up automatically
  • Time axis built from the unix timestamp column, re-based to t=0 — elapsed_time resets at every fragment boundary in paused/resumed sessions so it cannot be the time base
  • Blank fields carry the last known value (channels update at different rates), matching Haltech/ECUMaster/MHD
  • Detection claims any Format,N RaceChrono file so v1/v2 exports get a clear "re-export as CSV v3" error instead of a Haltech fall-through
  • Hardened from a pre-PR parser-expert review: survives spreadsheet round-trip comma padding, keeps bare latitude/longitude with dual location devices, never aborts a file on one malformed row, classifies the sources row by its numbered device tags, errors on zero data rows

Verified against a real 125MB / 515,531-line user session: 34 channels, all 515,519 data rows, 2.5h time range, ~0.4s parse, track map channels detected. The committed fixture is a 400-row excerpt including the genuine fragment 0→1 elapsed_time reset.

Unit preferences (src/units.rs)

°C/°F, m/s, and meter-sourced channels now honor the temperature/speed/distance display preferences (meters map to feet under the imperial preference — altitude through km→mi would display as 0.00x mi). Display-time only.

Version + docs sweep

  • Cargo.toml/Cargo.lock → 2.13.1
  • ultralog.co: JSON-LD softwareVersion + hero badge → v2.13.1, releaseNotes link fixed (was v2.10.1), RaceChrono What's New card, six missing ECU badges, SEO meta, sitemap
  • README: version shield fixed (was 2.10.1), RaceChrono section, plus the missing Motorsport Electronics / DynamicEFI / Locomotive sections
  • CLAUDE.md: parser contracts documented (timestamp-vs-elapsed_time, GPS channel naming invariant)

Test plan

  • 32 RaceChrono-specific tests (22 unit + 10 integration incl. fragment-boundary and detection-vs-corpus), 8 new unit-conversion tests
  • Full suite green (1050+ tests), cargo fmt --check, cargo clippy --all-targets -- -D warnings
  • test_parser CLI run against the full 125MB reference session

Parses session exports from the RaceChrono / RaceChrono Pro lap-timing
app, which merges GPS, phone-sensor, and OBD/CAN channels into one
comma-delimited table (requested by a user for track-day analysis).

Format handling:
- Key,Value metadata preamble (Format, Session title, Track name, ...)
  with quoted-value support, terminated by a blank line
- Units row normalized (.C -> °C) and sources row parsed per column
- Duplicate column names disambiguated with the source label
  (speed (gps) vs speed (calc)); unique names — latitude/longitude
  included — stay raw so GPS Track Map exact-name matching keeps working
- Times re-based from unix timestamps to seconds since the first record;
  elapsed_time is not usable as a time base because it resets at every
  fragment boundary in paused/resumed sessions
- Blank fields carry the last known value per column (channels update at
  different rates), matching the Haltech/ECUMaster/MHD parsers
- Detection claims any Format,N RaceChrono file so v1/v2 exports get a
  clear "re-export as CSV v3" error instead of a Haltech fall-through

Verified against a real 125MB / 515k-row user session: 34 channels,
2.5h time range, all rows parsed, track map channels detected. Fixture
is a 400-row excerpt of that session covering pit-lane (blank-heavy)
and on-track (fully populated) records across a fragment boundary.
…ings

Addresses the findings from the pre-PR ecu-parser-expert review pass:

- Survive a spreadsheet round-trip: Excel/Numbers/Sheets pad every
  preamble line with trailing commas to the widest row, which previously
  hard-errored on Format,3,,, and corrupted quoted titles. Padding is
  now stripped from metadata values, an all-comma line reads as the
  blank preamble terminator, and trailing empty header columns no
  longer become ghost channels
- Keep bare latitude/longitude with two location devices: when
  duplicate columns share the same short source label (100: gps +
  101: gps), the first occurrence keeps its bare name so the GPS Track
  Map still matches, and later ones carry the full source tag
- Never abort the file on one bad row: a garbage row where the data
  should start previously raised "too many non-data rows"; malformed
  rows are now skipped and counted, and the annotation-row scan stops
  after units + sources
- Classify the sources row by its numbered device tags so a file
  missing the units row does not get source tags as units
- Join multi-line quoted metadata values (a Note with embedded
  newlines), bounded to 100 continuation lines
- Error on zero data rows instead of silently loading an empty chart,
  matching the MegaSquirt parser
- Pre-size row storage and drop the per-row Vec<&str> allocation
  (~25% faster on the 125MB reference session, now ~0.4s)

The fixture now splices at the session's genuine fragment 0->1
boundary, so the elapsed_time reset the timestamp-based time axis
exists to handle is exercised by a real transition, and detection is
asserted against the other text-format example logs since RaceChrono
runs first in the dispatch chain.
UnitPreferences::convert_value only converted a fixed set of canonical
source units (K, kPa, km/h, km, ...), so channels that parsers emit in
°C, °F, m/s, or meters never honored the user's display preferences.
This hit RaceChrono (GPS speed in m/s, temps in °C, altitude/accuracy/
distance in m) and the °C emitted by the AiM, ECUMaster, Emerald, MHD,
RomRaider, and Woolich parsers.

- °C and °F sources now convert through the temperature preference
- m/s sources convert through the speed preference (m/s -> km/h -> mph)
- meter sources map to the imperial short-distance counterpart: metric
  keeps meters, miles preference shows feet — forcing altitude or GPS
  accuracy through km -> mi would display as 0.00x mi

Conversion stays display-time only (chart cursor/legend and channel
cards); cached log data is untouched.
…mats

- Version: JSON-LD softwareVersion, hero badge, and the README shield
  (which was still on 2.10.1); releaseNotes now points at the v2.13.1
  tag instead of v2.10.1
- What's New: RaceChrono Imports card leads the grid
- Supported ECUs: adds the six missing badges (Woolich, MHD, Motorsport
  Electronics, DynamicEFI, Locomotive, RaceChrono as New) and demotes
  BlueDriver's New tag
- SEO: meta description, keywords, and JSON-LD description now list the
  full format roster including RaceChrono lap-timing sessions
- Sitemap lastmod refreshed
Copilot AI lite review requested due to automatic review settings August 20, 2026 00:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ships UltraLog v2.13.1 with a new native parser for RaceChrono / RaceChrono Pro CSV v3 session exports, alongside unit-display conversions needed for RaceChrono-style channels (°C/°F, m/s, meters-as-feet) and a docs/site version sweep to reflect the release and supported formats.

Changes:

  • Add a new RaceChrono text parser (CSV v3) including metadata preamble parsing, unit normalization, source-based column disambiguation, and unix-timestamp time base.
  • Extend unit preferences to convert values whose source units are °C, °F, m/s, and m at display time.
  • Wire RaceChrono into the app/CLI dispatch paths and add fixtures + integration tests; bump version and refresh README/site/docs.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/parsers/racechrono_tests.rs New integration tests covering detection, parsing, time base, disambiguation, and units.
tests/parsers/mod.rs Registers the new RaceChrono test module.
tests/common/mod.rs Adds the RaceChrono CSV v3 excerpt fixture path constant.
src/units.rs Adds °C/°F, m/s, and meters-to-feet display conversions + tests.
src/parsers/types.rs Adds Meta::RaceChrono, Channel::RaceChrono, and EcuType::RaceChrono wiring.
src/parsers/racechrono.rs New RaceChrono CSV v3 parser implementation + unit tests.
src/parsers/mod.rs Exposes the RaceChrono parser module and re-exports RaceChrono.
src/bin/test_parser.rs Adds RaceChrono detection and parsing to the CLI tool.
src/app.rs Adds RaceChrono to the main text-dispatch detection chain.
README.md Updates version badge and documents RaceChrono + other supported formats.
exampleLogs/racechrono/session_massa_finalese_v3_excerpt.csv Adds a RaceChrono CSV v3 excerpt fixture for tests.
docs/sitemap.xml Updates sitemap lastmod.
docs/index.html Updates SEO content and version/release links; adds RaceChrono “What’s New” and supported-format badges.
CLAUDE.md Documents RaceChrono parser contracts and updates supported formats list.
Cargo.toml Bumps crate version to 2.13.1.
Cargo.lock Bumps crate version to 2.13.1 in the lockfile.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/parsers/racechrono.rs
Comment on lines +299 to +305
if meta.format_version != SUPPORTED_FORMAT_VERSION {
return Err(format!(
"RaceChrono CSV format version {} is not supported — re-export the session as CSV v3",
meta.format_version
)
.into());
}
- Explicit error when the Format metadata line is missing, instead of
  the misleading "version 0 is not supported" (Copilot review comment)
- Fix ROMRAIDER_EUROPEAN fixture path casing (exampleLogs/RomRaider) —
  macOS resolved the lowercase path but Linux CI could not, which
  failed the new detection-corpus test and had been silently skipping
  the guarded RomRaider/OBDLink example-file tests on CI
- Wrap the bare URL in the RaceChronoMeta::creator doc comment in
  backticks so `cargo doc` passes with RUSTDOCFLAGS="-D warnings"
@SomethingNew71
SomethingNew71 merged commit 5a4a039 into main Aug 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants