plan 0016: Manual drag mode — the christmas tree - #161
Open
TheAngryRaven wants to merge 1 commit into
Open
Conversation
Drag now asks Automatic or Manual after the distance. Manual stages
like a strip: stop, and the 9-px bar lights a white staging pip, three
yellows at the sportsman 500 ms cadence, then green — mirrored on the
OLED as STOP TO STAGE, a big 3..2..1, and a flashing GO. Movement
during the yellows is a RED LIGHT foul; 5 s still after green is
FAILED TO LAUNCH; both flash red and wait for a button. Runs end on a
results screen (ET, trap, 0-60, and a new reaction time = green ->
interpolated rollout crossing, both epoch ms). The screen is pinned to
staging info for the whole manual session; hold Select 2 s to end it.
Automatic mode is behavior-identical (one extra menu hop).
- New host-tested pure unit drag_tree.{h,cpp}: the ONE state machine
driving both the LED strip (renderStrip) and the OLED (countdownDigit
/ flashPhase) so they can never disagree; 17 doctest cases (exact
stage timings, fouls from every yellow, exit-hold semantics, golden
strip frames). Flash half-period 500 ms — the 3 Hz OLED aliases
anything faster.
- drag_timer grows setLaunchEnabled (default true; while disabled a
rollout-at-speed re-arms — a pre-green move is the tree's foul, never
a run) and runStartEpochMs() for the RT computation; 3 new tests.
- Glue: dragStagingLoop() in the gpsStatusPageLoop slot (Inputs/step/
Effects, resetButtons on consumption); the launch gate re-asserted
every loop (open exactly while green); pin cleared only by
endRaceSession so every session ender releases it.
- UI: PAGE_DRAG_MODE (-18) Auto/Manual/Back; PAGE_DRAG_STAGING (-19)
pinned via the gpsLockHold construction. Fixed a plan-0015 layout
bug while here: subtext after size-3 text needs a size-3 newline or
it renders on the ET's bottom glyph rows.
- NeoPixel: tree renders strip-only as a new cascade arm (status LEDs
live, search pip wins without a fix, normal scale during the run);
paceValid gains !dragManualActive() (constant false for auto).
- Sim: 6 new golden fixtures including a FULL manual pass through the
real pipeline (park -> tree -> green -> 70 mph -> results with RT);
goldens regenerated (23 fixtures), soak/determinism/oracles pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKa62h4fhn61pKn1LygrMK
Coverage — host-testable units📂 Overall coverage
📄 File coverage
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Drag now asks Automatic or Manual after the distance (new
PAGE_DRAG_MODE). Automatic is plan 0015's behavior, unchanged. Manual stages like a real strip:----w----), then three yellows at the sportsman 500 ms cadence (---ywy---→--yywyy--→-yyywyyy-), then green (gyyywyyyg) — mirrored on the OLED asSTOP TO STAGE, a big3…2…1countdown (size-7 glyphs), and a flashingGO.dragStagingLoop()beforedisplayLoop()); hold Select 2 s in any non-running state to end the session (a held side button disarms it so the reboot combo wins; auto-idle stays the backstop).Mechanism: the new host-tested pure unit
drag_tree.{h,cpp}is the ONE state machine driving both the LED strip (renderStrip) and the OLED (countdownDigit/flashPhase) so the two can never disagree; flash phases derive from timestamps at a 500 ms half-period (the 3 Hz OLED aliases anything faster). The tree never duplicates physics — it observesdrag_timer, whose new launch gate (setLaunchEnabled, default true = automatic byte-identical) stays closed except while the tree shows green, so a pre-green move re-arms instead of ever becoming a run. The LED tree renders strip-only as a new arm of the NeoPixel strip cascade (status LEDs stay live; search pip wins without a fix; the normal RPM/speed scale takes over during the pass itself).Also fixes a plan-0015 layout bug found while building the results screen: subtext printed after size-3 text with size-1 newlines rendered on the ET's bottom glyph rows (lap-time page + both new screens now advance with a size-3 newline).
Design record:
docs/plans/0016-manual-drag-tree.md.Type of change
How it was verified
ctest --test-dir tests/build) — 607 cases: 17 newdrag_treecases (exact stage-entry timings, fouls from every yellow, failed-launch, green-no-run and mid-run aborts, exit-hold semantics incl. the results-press pass-through and side-button disarm, golden strip frames for every stage + both flash phases) and 3 newdrag_timercases (launch gate held/re-enabled,runStartEpochMsvs the analytic crossing)clang-tidyclean — left to CIBETA)Checklist
CHANGELOG.mdupdated under[Unreleased](if user-visible)ARCHITECTURE.md/CLAUDE.mdupdated (if a module or interface changed)tests/Related issues
Builds on plan 0015 (PR #148, merged). Design record:
docs/plans/0016-manual-drag-tree.md.🤖 Generated with Claude Code
https://claude.ai/code/session_01BKa62h4fhn61pKn1LygrMK
Generated by Claude Code