Skip to content

plan 0002: sprint mode (autocross) concept + numbered docs/plans structure - #115

Merged
TheAngryRaven merged 9 commits into
BETAfrom
claude/sprint-mode-race-types-wt9s7o
Aug 2, 2026
Merged

plan 0002: sprint mode (autocross) concept + numbered docs/plans structure#115
TheAngryRaven merged 9 commits into
BETAfrom
claude/sprint-mode-race-types-wt9s7o

Conversation

@TheAngryRaven

Copy link
Copy Markdown
Owner

Summary

Docs-only. Two related pieces:

  1. Plan 0002 — Sprint mode concept (docs/plans/0002-sprint-mode.md): the researched concept + cross-repo roadmap for a new point-to-point "sprint" race mode (autocross / hillclimb / stage-style events) alongside the existing circuit behavior. Sprint mode is the primary focus of the next beta version. Decisions already locked in the doc:

    • race_mode device setting (circuit default / sprint), toggled via webapp SSET, applied on reboot; sprint tracks in a new /TRACKS/SPRINT/ folder (circuit tracks untouched — fully backwards compatible).
    • Timing engine lands in DovesLapTimer BETA first (SprintTimer + CourseManager::selectCourse()): the crossing math (_detectLineCrossing()) is already line-agnostic; what's missing is structural (finish-line field, run-based accounting, course selection without the lap-shaped CourseDetector).
    • Session = heat, pinned by a real user's cadence report (heats of ~4 runs, 30–45 s queue stops, engine kept running, X4 recording across the heat) — matches the existing camera 30 s engine-off auto-stop; run boundaries never touch the camera or end the session. Best run is per-session.
    • DOVEX: trailing race_mode header column, values CIRCUIT/SPRINT (empty/absent = CIRCUIT), purely a webapp loading helper — same back-compat mechanism as device_name.
    • Phasing: DovesLapTimer → this firmware → DovesDataViewer (last).
  2. Numbered docs/plans/ structure, adopting DovesDataViewer's convention so plan numbers act as lightweight ticket numbers: existing docs moved to plans/0000-firmware-ota-phase0.md and plans/0001-insta360-ble-current-implementation.md (chronological by original commit date), plans README added, path references in CLAUDE.md/CHANGELOG.md fixed, and a docs/plans/ row added to CLAUDE.md's File Map.

Type of change

  • Bug fix (no user-visible behavior change beyond the fix)
  • New feature / behavior
  • Refactor (no behavior change)
  • Tests only
  • CI / tooling / docs
  • Breaking change (track files, log format, BLE protocol, or a removed mode)

How it was verified

  • Host unit tests pass (ctest --test-dir tests/build)
  • clang-tidy clean
  • Compiles for the XIAO nRF52840 Sense
  • Tested on real hardware — describe what you exercised:

Docs-only change — no source touched, so the firmware checks don't apply. Verified all repo references to the moved docs were updated (CLAUDE.md:685, CHANGELOG.md, File Map) and that file/line anchors cited in plan 0002 were spot-checked against the actual sources in all three repos during research.

Checklist

  • CHANGELOG.md updated under [Unreleased] (if user-visible) — N/A, no user-visible firmware change
  • ARCHITECTURE.md / CLAUDE.md updated (if a module or interface changed) — File Map row for docs/plans/
  • New testable logic has a matching test in tests/ — N/A, no logic
  • Branch is focused — refactors / behavior / tests are not mixed together

Related issues

Related library groundwork: TheAngryRaven/DovesLapTimer#32 (crossing-event callback), #30, #34, #35.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb


Generated by Claude Code

claude added 5 commits August 2, 2026 04:44
Concept/research doc for a new point-to-point 'sprint' race mode
(separate start and finish lines, runs instead of laps) alongside the
existing circuit behavior: race_mode device setting, /TRACKS/SPRINT
folder, SprintTimer in DovesLapTimer BETA, firmware session-lifecycle
changes, DataViewer work last. No code changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
User report: heats of ~4 runs with 30-45 s queue stops, long break
between heats, X4 left recording per heat (~20 min videos). Pins the
session model to session = heat, matching the existing camera 30 s
engine-off auto-stop; run boundaries never touch the camera or end the
session. Auto-idle change downgraded to a safety margin.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
…per-session

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
… trailing column)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
Move firmware-ota-phase0 -> plans/0000, insta360-ble-current-
implementation -> plans/0001, sprint-mode-concept -> plans/0002
(chronological by original commit date), add the plans README, and fix
the doc-path references in CLAUDE.md and CHANGELOG.md. Plan numbers now
act as lightweight ticket numbers, cited from commit messages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Coverage — host-testable units

📂 Overall coverage

Metric Coverage
Lines 🟢 791/801 (98.8%)
Functions 🟢 83/83 (100.0%)
Branches 🟢 618/687 (90.0%)

📄 File coverage

File Lines Functions Branches
BirdsEye/camera_fsm.cpp 🟢 222/230 (96.5%) 🟢 20/20 (100.0%) 🟡 126/144 (87.5%)
BirdsEye/crc32.cpp 🟢 30/30 (100.0%) 🟢 4/4 (100.0%) 🟢 24/24 (100.0%)
BirdsEye/dovex_header.cpp 🟢 100/101 (99.0%) 🟢 6/6 (100.0%) 🔴 61/92 (66.3%)
BirdsEye/filename_validator.cpp 🟢 14/14 (100.0%) 🟢 1/1 (100.0%) 🟢 30/30 (100.0%)
BirdsEye/gps_stats.cpp 🟢 25/25 (100.0%) 🟢 3/3 (100.0%) 🟢 8/8 (100.0%)
BirdsEye/gps_status_page.cpp 🟢 25/25 (100.0%) 🟢 3/3 (100.0%) 🟢 24/24 (100.0%)
BirdsEye/gps_time.cpp 🟢 45/45 (100.0%) 🟢 6/6 (100.0%) 🟢 30/32 (93.8%)
BirdsEye/gps_validation.cpp 🟢 24/24 (100.0%) 🟢 2/2 (100.0%) 🟢 66/66 (100.0%)
BirdsEye/haversine.cpp 🟢 8/8 (100.0%) 🟢 1/1 (100.0%) ⚫ 0/0 (0.0%)
BirdsEye/insta360_protocol.cpp 🟢 140/140 (100.0%) 🟢 16/16 (100.0%) 🟡 86/98 (87.8%)
BirdsEye/lap_format.cpp 🟢 18/18 (100.0%) 🟢 1/1 (100.0%) 🟢 9/9 (100.0%)
BirdsEye/sat_bars.cpp 🟢 33/33 (100.0%) 🟢 2/2 (100.0%) 🟢 51/54 (94.4%)
BirdsEye/sd_access_policy.cpp 🟢 9/9 (100.0%) 🟢 3/3 (100.0%) 🟢 18/18 (100.0%)
BirdsEye/sd_format_page.cpp 🟢 25/25 (100.0%) 🟢 3/3 (100.0%) 🟢 25/26 (96.2%)
BirdsEye/sensoregg_protocol.cpp 🟢 44/45 (97.8%) 🟢 7/7 (100.0%) 🟢 33/34 (97.1%)
BirdsEye/tach_filter.cpp 🟢 15/15 (100.0%) 🟢 3/3 (100.0%) 🟡 7/8 (87.5%)
BirdsEye/wake_cause.cpp 🟢 14/14 (100.0%) 🟢 2/2 (100.0%) 🟢 20/20 (100.0%)

claude added 4 commits August 2, 2026 18:05
…or; plan 0003: RPM spark/cylinder settings

Fold in the latest user decisions: no race_mode device setting (mode
follows the detected track's folder), sprint courses selected by newest
date_created (same venue, new course every event), start+finish + up to
2 optional splits (single split legal), and the full on-device
course-creator UI spec (no text entry; auto-named NEWTRACK/NEWCOURSE
files). Adds design notes: ISO timestamp for date_created, point-capture
averaging, first track-JSON writer, 4KB-buffer pruning question,
both-kinds-in-range tiebreak. New plan 0003 splits out the spark_mode +
cylinder_count settings for true-RPM display/logging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
…ync-prune, single-source RPM

- date_created: ISO timestamp decided (same stamp in generated names)
- point capture: 3 s hold, ~75 fixes averaged, h_acc gating
- pruning: webapp sync keeps last single day of courses on device
  (sync -> delete -> push new file); v1 may ship first with disclaimer
- race_mode setting returns as the both-kinds-in-range tiebreak only:
  circuit default yields to a sprint course created today; sprint always
  prefers the newest sprint course (fixed rally layouts)
- plan 0003: true RPM computed once before the Kalman (tuning stays in
  true-RPM units), tachLastReported is the single source of truth

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
… restarts, DNF is normal op

Session arming unchanged (RPM ~1 s brings systems up). Runs are purely
line-driven: start crossing begins a run and cancels/restarts any run in
progress (botched-course re-launch); finish completes; finish ignored
while no run active. DNF records nothing special. Notes the
direction-agnostic backward-crossing nuance and the self-healing
property of the restart rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
…ing* on lap/pace pages), keep 'laps' verbiage

Design complete: all open questions resolved. Between runs the device
remains in normal race mode with every page live; Current Lap and Pace
show *waiting* while no run is active. Lap wording kept everywhere (AX
drivers call them laps) - no relabeling, no page-constant churn, DOVEX
laps_ms line unchanged; the race_mode header column alone informs the
webapp.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnTP6BdA9xjLR5hSWE9frb
@TheAngryRaven
TheAngryRaven merged commit a737913 into BETA Aug 2, 2026
8 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