Fix spurious 0.00s lap from duplicate portal speed events#36
Merged
Conversation
Real portal hardware delivers two `speed` PortalEvents per physical crossing (BLE notification echo / firmware double-send) within a few ms with identical readings. portalStore.dispatch created a Pass for each, so the race engine folded them into a real lap followed by a ~0.00s lap. Add a 250ms same-speed dedupe in the "speed" case so a duplicate indication of one crossing is collapsed into a single pass: the live gauge still updates but no pass is appended and bestMph is unchanged. Requiring both the time window and an equal `raw` value leaves distinct synchronous speeds unaffected. Dedupe state is cleared on reset() and on disconnect. Fix is transport-agnostic and also corrects inflated History/Garage pass counts. Closes #35 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Problem
In race mode, every physical car pass over the portal recorded two laps: a spurious
0.00slap immediately followed by the real lap time. A 5-lap race ended after only 3 real crossings, with laps showing0.00, 2.07, 0.00, 1.53, 0.00. The same duplication inflated pass counts in History and Garage.Root cause
The real portal hardware delivers two
speedPortalEvents per single physical crossing (a BLE notification echo / firmware double-send), arriving within a few milliseconds of each other with identical decoded readings.portalStore.dispatch(case "speed") created a separatePassfor each event, and the race screen folds each fresh pass intoraceEngine.recordGate— so two passes ~0ms apart produced a real lap followed by a ~0.00s lap.The mock/demo portal emits exactly one speed per pass (seconds apart), so demo mode never reproduced it. Both BLE transports and the mock converge on
portalStore.dispatch, so the fix lives there and is transport-agnostic.raceEngine.ts,race.tsx, and the mock are unchanged.Fix
Add a 250ms same-speed dedupe to the
"speed"case inportalStore.dispatch. A car physically cannot cross the gate twice within a few hundred ms, so araw-equal speed event arriving withinPASS_DEDUPE_MSof the previous pass is treated as a duplicate indication: the live gauge (lastSpeed) still updates, but no new pass is appended andbestMphis not bumped. Requiring both the time window and an equalrawvalue means distinct synchronous speeds are unaffected. Dedupe state (lastPassAt/lastPassRaw) is cleared onreset()and on disconnect, consistent with the existingpassCounterpattern.Tests
Added three cases to
portalStore.test.ts(usingvi.spyOn(Date, "now")):npm run typecheckandnpm testboth pass (181 mobile + 49 protocol tests).Closes #35