Skip to content

Autotune: Vehicle-Specific Threshold Calibration#18

Closed
jctoledo wants to merge 7 commits intomainfrom
autotune
Closed

Autotune: Vehicle-Specific Threshold Calibration#18
jctoledo wants to merge 7 commits intomainfrom
autotune

Conversation

@jctoledo
Copy link
Copy Markdown
Owner

@jctoledo jctoledo commented Jan 1, 2026

Autotune Feature - Per-Mode Calibration

This enables users to tune the parameters for event detection (ACCEL, BRAKE, CORNER, etc) to their specific vehicle. Simply go to /autotune and start calibration by driving around. Settings get saved to NVS and are ready to use on /

Changes

  • /autotune page with real-time event detection UI
  • Independent NVS storage for each driving mode (Track, Canyon, City, Highway, Custom)
  • Active mode persists across power cycles
  • Session persistence during calibration (sessionStorage, 1-hour expiry)
  • Removed dead code: PROFILE_SCALES, generateAllProfiles(), MIN_SPEED_MS
  • Synchronized defaults between settings.rs and dashboard JS
  • Added From trait impls to reduce type conversion boilerplate

Autotune UI (/autotune)

Workflow:

  1. Select mode to calibrate (City/Canyon/Track/Highway)
  2. Start calibration and drive in that style for 10-20 minutes
  3. UI detects and counts accel/brake/turn events in real-time
  4. Live display shows EMA-filtered longitudinal G, lateral G, centripetal acceleration, speed
  5. Progress bar and confidence indicator (LOW/MEDIUM/HIGH based on event counts)
  6. Apply saves thresholds to ESP32 NVS + browser localStorage

Event Detection (matches mode.rs dynamics):

  • EMA α=0.85 tuned for 25Hz polling to simulate 200Hz firmware behavior
  • Noise floor 0.08g rejects road bumps
  • 200ms minimum duration, 400ms cooldown between events
  • Turn detection requires lateral G + yaw rate sign consistency

Threshold Calculation:

  • IQR outlier rejection on collected peak values
  • Entry = median × 0.7
  • Exit = entry × 0.5 (hysteresis)

Session Persistence: Navigate away and back within 1 hour - calibration progress restored (events, selected mode, recording state).

Analysis

Value proposition: Vehicle/driver-specific threshold tuning. A sports car pulling 1.0g lateral needs different thresholds than a minivan at 0.5g.

Target users: Track/autocross enthusiasts analyzing lap data. For casual users, default presets work fine.

Future potential: Event detection infrastructure supports more granular labels:

  • Heavy/moderate/light braking intensity
  • Corner entry vs apex vs exit phases
  • Trail braking detection (brake + turn overlap)
  • Lift-off oversteer warning (decel + high yaw rate)

Peak values, duration, and delta-V are already captured per event.

Test Sequence

espflash erase-flash && cargo espflash flash --release --monitor

  1. Dashboard (/) → tap "Tune" → opens /autotune
  2. Select Track, tap "Start Calibration", drive aggressively
  3. Watch event counters increment, progress bar fill
  4. Tap "Apply" → confirms save, returns to dashboard
  5. Dashboard → tap City preset → independent City values load
  6. Tap "Tune" → select City, calibrate with normal driving, Apply
  7. Power cycle → last active mode and its calibrated settings restored
  8. Dashboard preset buttons load each mode's saved thresholds

- Add /autotune page with real-time event detection UI
- Independent NVS storage per driving mode (Track/Canyon/City/Highway/Custom)
- Active mode persists across power cycles
- Session persistence during calibration (1-hour expiry)
- Remove dead code: PROFILE_SCALES, generateAllProfiles(), MIN_SPEED_MS
- Sync defaults between settings.rs and dashboard JS
- Add From trait impls to reduce type conversion boilerplate
- Fix docs/index.html outdated autotune description
@jctoledo jctoledo marked this pull request as ready for review January 14, 2026 04:19
Dashboard and autotune were sending settings without specifying the target
mode, causing settings to be saved to the currently active mode instead of
the user's selected mode.

- applySettings() now sends mode change first, waits 150ms, then settings
- sendSettings() accepts optional mode parameter for mode-aware saves
- selectPreset() and saveCfg() pass current preset mode to sendSettings()
@jctoledo jctoledo closed this Jan 19, 2026
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.

1 participant