Beta 4.2.0 - drag timer - #160
Open
TheAngryRaven wants to merge 14 commits into
Open
Conversation
… is answered 9134 Hz, 96 us mean, 37 ms worst iteration, SLP 12.0, with a GPS lock, logging and the camera recording. The instrument validates itself: 9134 Hz x 96 us = 87.7% of the second inside loop(), and SLP — computed by a different route — reads 12.0%. All fourteen slots sum to ~99.8. SLP 12% also settles what the previous build could not distinguish: the CPU is not sleeping through the second, so the loop genuinely runs at ~9 kHz and the old pegged rate was the display clamp rather than the timebase bug. There was no way to know that until the window was wall-clocked. Headroom, against the binding constraint (one iteration per 40 ms PVT frame): ~420x on the mean, 43x on the worst iteration against the 4 KB GPS ring, 108x against the watchdog. Nothing here justifies an nRF5340 on throughput, and SLP 12% caps what leaving the Arduino core could reclaim. Also records where the 88% goes — it is polling, not work. GPS is called 9134 times a second to service a 25 Hz stream; DSP renders 3 times and early-returns ~9000; BTN is six digitalReads per iteration with nobody touching a button. Rate-limiting the polls would reclaim most of it without changing silicon. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CqENxo91S1VL3sM9PTWMf1
Main menu -> Drag -> pick 1/8 Mile / 1000 ft / 1/4 Mile / 1/2 Mile /
1 Mile and the session starts: no track file, no detection. Stage at a
standstill, rollout-style launch (11.25 in past a re-latching standstill
anchor, ET start interpolated between 25 Hz fixes), run ends at the
target distance with interpolated ET + trap speed and a 0-60 split, then
re-arms automatically for the next pass. All passes land in one DOVEX
session with race_mode=DRAG (laps line = run ETs, same trailing-column
scheme as SPRINT).
- New host-tested pure unit drag_timer.{h,cpp}: the whole run state
machine (ARMED/STAGED/LAUNCHED), the distance table, silent aborts
(mid-run standstill, >=2 s fix gap — also how queue-creep phantom
launches self-cancel), 14 doctest cases.
- Sketch glue mirrors sprint: dragTimer != nullptr IS drag mode, drag
branch first in every activeTimer*() helper, run capture on the
run-count edge, trackDetected latched, idle-grace re-arm on each run
AND each fresh STAGED latch.
- UI: Drag main-menu row, PAGE_DRAG_DISTANCE picker (scrolling window),
drag branches on the lap-time/pace/best pages (live ET, *staged*,
trap/0-60 subtext, live 0-60 readout), LED pace pip suppressed between
runs like sprint.
- Sim: golden walk updated for the new menu row + a picker fixture;
goldens regenerated; soak/determinism/goldens/oracles all pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKa62h4fhn61pKn1LygrMK
…ranch-8jmgzr docs(0011): record the wall-clocked hardware run — the board question…
Six findings from the branch review, all fixed: - Time base: the glue fed getGpsTimeInMilliseconds() (time-of-day, wraps to zero at UTC midnight — evening sessions) into a unit whose contract says epoch ms. Both call sites now feed getGpsUnixTimestampMillis(), and the unit's non-monotonic guard resyncs on a backwards step instead of rejecting every subsequent fix — one step used to wedge the drag timer for the rest of the session. - Launch edge: a >=2 s fix gap while STAGED now re-stages instead of evaluating the launch, so a launch that happened inside a GPS dropout can't interpolate its ET start back to a parked-car fix. - Prove-out gate: a launch must reach 15 mph within 5 s of the ET start or the run is silently abandoned — a wave-off driven to the pits at 4 mph never holds the sub-2 mph standstill abort and used to record 660 ft of pit road as a ~90 s "run". - activeTimerTotalDistance() converts the drag branch to meters, matching every other branch of the accessor. - distanceFeet() delegates to the haversine unit (x 5280) instead of carrying a second copy of the formula and Earth radius. - The seconds.hundredths split rendering is now one function (displayPrintSplitSeconds) shared by the results subtext and the pace page's live 0-60 readout. Five new regression tests cover the wedge recovery, the staged-gap launch, the wave-off, a slow-but-real pass, and duplicate timestamps. Plan 0015 doc + CLAUDE.md constants updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BKa62h4fhn61pKn1LygrMK
…mggk0b plan 0015: Drag mode — distance runs without a track
Coverage — host-testable units📂 Overall coverage
📄 File coverage
|
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
…mggk0b plan 0016: Manual drag mode — the christmas tree
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcdBRTn52QpCQWkyVm5Lkg
parseMac/formatMac (settings-string codec), macReverse (human <-> ble_gap_addr_t LSB-first, aliasing-safe), macIsWildcard, macAccepts — the byte-order reversal the scan callback depends on finally moves under host test, with a case pinning that a same-order compare rejects. kPairingTimeoutMs (120 s, camera parity) and kMacStrLen live with the other tunables. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcdBRTn52QpCQWkyVm5Lkg
Runtime MAC filter boots from the SENSOREGG_MAC fallback and loads sensoregg_mac at SENSOREGG_SETUP(); the scan callback stays protocol- blind (it additionally memcpys the advertiser address into a per-slot field of the existing double buffer, ready-flag-last preserved) and bypasses the MAC filter while the capture window is open. Capture runs in the main-loop drain on the parsed pairingActive bit: persist first, then the RAM filter, then close the window — a failed SD write retries on the next frame. 120 s window timeout; bench latch (eggTestActive) and the pairing window now force the race-gated scanner on; packet-rate meter for the test page. Twelve new public accessors with no-op twins. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcdBRTn52QpCQWkyVm5Lkg
Main-menu row 'Egg' (index 6, appended after Camera so nothing shifts), PAGE_PAIR_EGG (-20) cloning the camera page's shape — paired = Back/Test/Unpair with Back at index 0, unpaired = window-gated capture status with B2 cancel and B1 reserved for future manual entry — and PAGE_EGG_TEST (-21): rf tri-state + proto version, EGT/CJ/AUX/BAT, sequence + measured packet rate, live PAIR/FAULT flags, active MAC filter, Back. All five display_ui coupling points wired under the build flag; the camera test page now latches the egg bench scan on enter/exit, restoring the desk-soak behavior its comment promised (stale since plan 0012's race gate — comment fixed). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcdBRTn52QpCQWkyVm5Lkg
Flag-0 sim never renders the Egg pages; stubs mirror the module's full surface so a future flag-1 sim build links. Golden hashes verified UNCHANGED — the gate does not leak into stock renders. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcdBRTn52QpCQWkyVm5Lkg
…ables Also fixes the two stale subsystem-14 blocks that still described a PW-ADV-1-only 14-byte parser and hardcoded-MAC-only pairing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcdBRTn52QpCQWkyVm5Lkg
plan 0017: SensorEgg pairing menu + live-data test page
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.
tbd