Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ src/
│ ├── megasquirt.rs # MegaSquirt (MS1/MS2/MS3) TunerStudio CSV parser
│ ├── mhd.rs # MHD Tuning CSV parser (BMW N54/N55/S55/B58)
│ ├── motorsport_electronics.rs # Motorsport Electronics ME221/ME442 (ME Tuner) CSV parser
│ ├── racechrono.rs # RaceChrono CSV v3 session export parser (GPS + sensors + OBD/CAN)
│ ├── bluedriver.rs # BlueDriver OBD-II scan tool CSV parser
│ └── dynamicefi.rs # DynamicEFI EBL WhatsUp (GM TBI) CSV parser
└── ui/
Expand Down Expand Up @@ -291,6 +292,7 @@ The parser system uses a trait-based design for supporting multiple ECU formats:
- **`parsers/megasquirt.rs`** - MegaSquirt (MS1/MS2/MS3/MS3Pro) TunerStudio CSV parser
- **`parsers/mhd.rs`** - MHD Tuning CSV parser (BMW N54/N55/S55/B58 flashed with MHD)
- **`parsers/motorsport_electronics.rs`** - Motorsport Electronics ME221/ME442 (ME Tuner) CSV parser
- **`parsers/racechrono.rs`** - RaceChrono CSV v3 session export parser (lap-timing app; GPS + phone sensors + OBD/CAN merged on a unix-time base)
- **`parsers/bluedriver.rs`** - BlueDriver OBD-II scan tool CSV parser (UTF-16 with BOM)
- **`parsers/dynamicefi.rs`** - DynamicEFI EBL WhatsUp CSV parser (modified GM TBI systems)

Expand All @@ -309,6 +311,7 @@ Note: `EcuType` also reserves `Aem`, `MaxxEcu`, and `MotEc` variants for formats
- MegaSquirt MS1/MS2/MS3 (TunerStudio CSV export)
- MHD Tuning (CSV export — BMW N54/N55/S55/B58)
- Motorsport Electronics ME221/ME442 (ME Tuner CSV export)
- RaceChrono / RaceChrono Pro (CSV v3 session export — lap-timing app)
- Woolich Racing Tuned (WRT CSV export — motorcycle ECUs)
- BlueDriver (OBD-II scan tool CSV export)
- DynamicEFI EBL WhatsUp (modified GM TBI CSV export)
Expand Down Expand Up @@ -346,6 +349,12 @@ because it also leads with a `Time` column, and only matches a first column of e

**Load-bearing invariant:** a parser whose own fingerprint lives inside that comment preamble must run its `detect()` against the **raw** text, before the strip. `Mhd::detect` is the current case, which is why it is dispatched ahead of `dispatch_text_content` rather than inside the chain. Anything added to the chain itself sees comment-stripped content.

**RaceChrono parser load-bearing behaviors** (`src/parsers/racechrono.rs`):

- **Time base is the unix `timestamp` column, never `elapsed_time`** - `elapsed_time` resets to zero at every fragment boundary (a fragment is one recording segment; sessions paused/resumed at the track have several), so re-basing `timestamp` to the first record is the only way to get a monotonic time axis. Monotonic times are required because computed-channel time-shift lookups binary-search the `times` vector.
- **Duplicate column names are disambiguated by source, unique names stay raw** - RaceChrono exports the same column name once per source (`speed` from GPS and calc, `device_update_rate` from every sensor). Duplicates get the sources-row label appended (`speed (gps)`); unique names — including `latitude`/`longitude` — must stay exactly as exported because `find_gps_channels` in `src/ui/widgets/track_map.rs` matches those names *exactly* (lowercased), and a suffix would silently disable the GPS Track Map for RaceChrono logs. When the short labels themselves collide (two location devices both labeled `gps`), the first occurrence keeps its bare name — so `latitude` still survives — and later ones carry the full source tag (`latitude (101: gps)`).
- **Detection accepts any `Format,N` version; `parse` rejects non-v3** - so a v1/v2 export surfaces a clear "re-export as CSV v3" error instead of falling through to the Haltech default parser and failing cryptically.

**Haltech parser load-bearing behaviors** (`src/parsers/haltech.rs`, added for wall-clock-timestamped exports):

- **Last-known-value substitution** - Unparseable/blank fields are filled with the last successfully parsed value for that column (`0.0` before the first valid sample), matching the approach used in `parsers/ecumaster.rs`. This preserves column alignment instead of shifting subsequent columns when a field fails to parse.
Expand Down Expand Up @@ -408,7 +417,7 @@ The Track Map widget can draw map tile backgrounds. Tiles are **opt-in** (off by

## Key Features

- **Multi-ECU Support** - Haltech, ECUMaster, RomRaider, Speeduino, rusEFI, AiM, Link, Emerald, MegaSquirt, MHD Tuning, Motorsport Electronics, Woolich Racing Tuned, BlueDriver, DynamicEFI, and Locomotive log formats
- **Multi-ECU Support** - Haltech, ECUMaster, RomRaider, Speeduino, rusEFI, AiM, Link, Emerald, MegaSquirt, MHD Tuning, Motorsport Electronics, RaceChrono, Woolich Racing Tuned, BlueDriver, DynamicEFI, and Locomotive log formats
- **Computed Channels** - Create virtual channels from mathematical formulas with time-shifting (e.g., `RPM[-1]`, `Boost@-0.5s`)
- **Analysis Algorithms** - AFR/Lambda drift and zone detection, derived metrics (VE, injector duty cycle), signal filters, and descriptive statistics (`src/analysis/`)
- **GPS Track Map** - Right-side data panel with a track map: lap detection, channel-colored polyline (Viridis/Turbo with editable range), hover-scrub/click-seek cursor sync, and opt-in Esri/OSM tile backgrounds (`src/ui/widgets/track_map.rs`, `src/tiles.rs`, `src/laps.rs`). GPS coordinate encodings are auto-detected and normalized to decimal degrees (`GpsCoordSpec` in `src/laps.rs`): NMEA `DDMM.mmmm`, milli/micro/1e-7-scaled integer degrees, and 0-360 longitude. Detection is conservative - values already in valid degree ranges are never transformed, and radians are deliberately not detected (ambiguous with genuine near-equator degree tracks).
Expand Down Expand Up @@ -491,6 +500,7 @@ Example log files are in `exampleLogs/` organized by ECU type:
- `exampleLogs/megasquirt/` - MegaSquirt TunerStudio CSV exports, plus a `_gps.mlg` fixture with synthetic GPS channels (generated by `examples/inject_fake_gps_mlg.rs`; the coordinates are a fake closed loop, not a real location)
- `exampleLogs/mhd/` - MHD Tuning CSV exports (VIN redacted)
- `exampleLogs/motorsportElectronics/` - Motorsport Electronics ME Tuner CSV exports
- `exampleLogs/racechrono/` - RaceChrono CSV v3 session excerpt (user-contributed track session, trimmed; covers blank-heavy pit-lane rows, the genuine fragment 0->1 boundary where `elapsed_time` resets, and fully-populated on-track rows)
- `exampleLogs/bluedriver/` - BlueDriver OBD-II CSV exports
- `exampleLogs/obdlink/` - OBDLink (iOS) OBD-II CSV exports (parsed by the RomRaider chain)
- `exampleLogs/dynamicEFI/` - DynamicEFI EBL WhatsUp CSV exports
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ultralog"
version = "2.13.0"
version = "2.13.1"
edition = "2024"
# egui/eframe 0.36 is the binding constraint on the minimum supported Rust
# version; edition 2024 itself only needs 1.85.
Expand Down
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A high-performance, cross-platform ECU log viewer written in Rust.

![CI](https://github.com/ClassicMiniDIY/UltraLog/actions/workflows/ci.yml/badge.svg)
![License](https://img.shields.io/badge/license-AGPL--3.0-blue.svg)
![Version](https://img.shields.io/badge/version-2.10.1-green.svg)
![Version](https://img.shields.io/badge/version-2.13.1-green.svg)

---

Expand Down Expand Up @@ -165,6 +165,32 @@ Configurable units for 8 measurement categories:
- **Supported devices:** BMW N54, N55, S55, B58 and other platforms flashed with MHD
- **Supported data:** Boost and boost target, wastegate duty, RPM, coolant and intake temps, per-cylinder timing correction, lambda/AFR per bank, fuel rail pressure, load, gear, torque, and all logged channels

### Motorsport Electronics - Full Support

- **File type:** CSV exports from the ME Tuner software (ME221/ME442 ECUs)
- **Features:** Unit inference from channel names, seconds-based `Time` column detected ahead of RomRaider's millisecond convention so timestamps scale correctly
- **Supported devices:** ME221 and ME442 — common on turbo/supercharged MX-5s, Ford Focus ST150, Honda S2000, Toyota Starlet, and Mitsubishi Evo builds
- **Supported data:** RPM, MAP, TPS, sync status, and all channels logged by ME Tuner

### DynamicEFI EBL WhatsUp - Full Support

- **File type:** CSV exports from DynamicEFI's EBL WhatsUp software (modified GM TBI systems)
- **Features:** `HH:MM:SS` RUNTIME timestamp handling at 1-second resolution, Y/N flag and P/N gear-indicator mapping to numeric values, trailing-comma handling
- **Supported data:** BLM, BPC, INT, and the other GM TBI channel abbreviations, plus all logged channels

### Locomotive Datalogger - Full Support

- **File type:** CSV exports with a `TimeStamp:` / `Customer:` / `UnitNumber:` metadata header
- **Features:** Wall-clock timestamp parsing from day-of-week-prefixed data rows, metadata capture (customer, unit number, software part number and version)
- **Supported data:** All channels recorded by the datalogger

### RaceChrono - Full Support

- **File type:** CSV v3 session exports from the RaceChrono / RaceChrono Pro lap-timing app (Android/iOS)
- **Features:** GPS, phone-sensor, and OBD/CAN channels merged on a unix-time base; duplicate column names disambiguated by source (`speed (gps)` vs `speed (calc)`); paused-and-resumed multi-fragment sessions; `.C` temperature notation normalized to °C; GPS Track Map works out of the box (lap detection, channel-colored track polyline)
- **Supported data:** Latitude, longitude, altitude, speed, bearing, and fix quality from GPS; accelerometer, gyroscope, and magnetometer axes; lap and fragment numbers; and any OBD/CAN channels the session logged (RPM, oil temp, throttle, and more)
- **Note:** Export the session as **CSV v3** from RaceChrono — the other RaceChrono export formats (`.vbo`, `.rcz`, CSV v1/v2) are not supported

### Coming Soon
- AEM
- MaxxECU
Expand Down
29 changes: 21 additions & 8 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
<title>UltraLog - Free ECU Log Viewer & Analyzer | Haltech, ECUMaster, Speeduino, AiM & More</title>
<meta name="title" content="UltraLog - Free ECU Log Viewer & Analyzer | Haltech, ECUMaster, Speeduino, AiM & More">
<meta name="description"
content="UltraLog is a free, open-source ECU datalog viewer built with Rust. Analyze logs from Haltech, ECUMaster, RomRaider, Speeduino, rusEFI, AiM, Link, Emerald, BlueDriver, and MegaSquirt ECUs. Features include stacked plot areas, histogram heatmaps, scatter plots, computed channels, MCP server for AI integration, and professional analysis tools. Download for Windows, macOS, and Linux.">
content="UltraLog is a free, open-source ECU datalog viewer built with Rust. Analyze logs from Haltech, ECUMaster, RomRaider, Speeduino, rusEFI, AiM, Link, Emerald, BlueDriver, MegaSquirt, MHD, Woolich, and RaceChrono lap-timing sessions. Features include stacked plot areas, histogram heatmaps, scatter plots, computed channels, MCP server for AI integration, and professional analysis tools. Download for Windows, macOS, and Linux.">
<meta name="keywords"
content="ECU log viewer, datalog analyzer, Haltech NSP, ECUMaster EMU Pro, RomRaider, Speeduino MLG, rusEFI, AiM XRK DRK, Link ECU LLG, Emerald K6 M3D, automotive tuning software, engine tuning, AFR analysis, boost log, free tuning software, open source ECU, car data logger, dyno analysis, motorsport data, fuel map analysis, ignition timing, lambda analysis, volumetric efficiency, injector duty cycle, Butterworth filter, scatter plot, histogram heatmap, computed channels, Rust application, stacked plots, MCP server, Model Context Protocol, Claude Desktop, BlueDriver OBD-II, AI log analysis">
content="ECU log viewer, datalog analyzer, Haltech NSP, ECUMaster EMU Pro, RomRaider, Speeduino MLG, rusEFI, AiM XRK DRK, Link ECU LLG, Emerald K6 M3D, automotive tuning software, engine tuning, AFR analysis, boost log, free tuning software, open source ECU, car data logger, dyno analysis, motorsport data, fuel map analysis, ignition timing, lambda analysis, volumetric efficiency, injector duty cycle, Butterworth filter, scatter plot, histogram heatmap, computed channels, Rust application, stacked plots, MCP server, Model Context Protocol, Claude Desktop, BlueDriver OBD-II, AI log analysis, RaceChrono CSV, lap timing analysis, track day data, GPS track map">
<meta name="author" content="Cole Gentry">
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1">
<meta name="googlebot" content="index, follow">
Expand Down Expand Up @@ -107,13 +107,13 @@
"@type": "SoftwareApplication",
"name": "UltraLog",
"alternateName": ["UltraLog ECU Viewer", "UltraLog Datalog Analyzer"],
"description": "A high-performance, cross-platform ECU log viewer and analyzer built with Rust. Supports Haltech, ECUMaster, RomRaider, Speeduino, rusEFI, AiM, Link, and Emerald ECU formats with advanced analysis tools.",
"description": "A high-performance, cross-platform ECU log viewer and analyzer built with Rust. Supports Haltech, ECUMaster, RomRaider, Speeduino, rusEFI, AiM, Link, Emerald, MegaSquirt, MHD, Motorsport Electronics, RaceChrono, Woolich, BlueDriver, DynamicEFI, and Locomotive log formats with advanced analysis tools.",
"url": "https://ultralog.co/",
"applicationCategory": "UtilitiesApplication",
"applicationSubCategory": "Automotive Software",
"operatingSystem": ["Windows 10", "Windows 11", "macOS", "Linux"],
"softwareVersion": "2.13.0",
"releaseNotes": "https://github.com/ClassicMiniDIY/UltraLog/releases/tag/v2.10.1",
"softwareVersion": "2.13.1",
"releaseNotes": "https://github.com/ClassicMiniDIY/UltraLog/releases/tag/v2.13.1",
"downloadUrl": "https://github.com/ClassicMiniDIY/UltraLog/releases/latest",
"installUrl": "https://github.com/ClassicMiniDIY/UltraLog/releases/latest",
"screenshot": [
Expand Down Expand Up @@ -1427,7 +1427,7 @@ <h1 id="hero-heading" class="tagline" itemprop="headline">Unlock Your Performanc
<div class="hero-badges">
<span class="version-badge">
<span class="new-tag">New</span>
v2.13.0
v2.13.1
</span>
<a href="https://github.com/ClassicMiniDIY/UltraLog" class="opensource-badge" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-github" aria-hidden="true"></i> Open Source
Expand Down Expand Up @@ -1530,8 +1530,15 @@ <h3>Computed Math Channels</h3>
<!-- What's New -->
<section class="whats-new-section">
<h2>What's New</h2>
<p class="section-subtitle">GPS track maps with satellite imagery, stacked plots, AI-powered analysis via MCP, and more</p>
<p class="section-subtitle">RaceChrono lap-timing imports, GPS track maps with satellite imagery, stacked plots, AI-powered analysis via MCP, and more</p>
<div class="new-features-grid">
<div class="new-feature-card">
<div class="feature-header">
<div class="feature-icon orange"><i class="fa-solid fa-flag-checkered" aria-hidden="true"></i></div>
<h3>RaceChrono Imports</h3>
</div>
<p>Open RaceChrono and RaceChrono Pro CSV v3 session exports directly — GPS, phone sensors, and OBD/CAN channels on one timeline, with lap numbers and the track map ready out of the box. Analyze your track days on a big screen instead of your phone.</p>
</div>
<div class="new-feature-card">
<div class="feature-header">
<div class="feature-icon green"><i class="fa-solid fa-map-location-dot" aria-hidden="true"></i></div>
Expand Down Expand Up @@ -1740,7 +1747,13 @@ <h2>Supported ECUs</h2>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> Link ECU (LLG)</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> Emerald K6/M3D</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> MegaSquirt</span>
<span class="ecu-badge new"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> BlueDriver OBD-II</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> BlueDriver OBD-II</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> Woolich Racing Tuned</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> MHD Tuning</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> Motorsport Electronics</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> DynamicEFI</span>
<span class="ecu-badge supported"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> Locomotive</span>
<span class="ecu-badge new"><i class="fa-solid fa-circle-check" aria-hidden="true"></i> RaceChrono</span>
</div>
</section>

Expand Down
2 changes: 1 addition & 1 deletion docs/sitemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
<url>
<loc>https://ultralog.co/</loc>
<lastmod>2026-08-18</lastmod>
<lastmod>2026-08-19</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
<image:image>
Expand Down
Loading