Repository navigation
Judge track fixes by their own times - #95
4 commits merged into
Conversation
The writer used a navigation fix only while it was under a minute old by the server's clock, and ignored every GNSS fix meanwhile. That dropped navigation fixes delivered late, and GNSS fixes for up to a minute after navigation stopped. Now every navigation fix is stored at its own time, and a GNSS fix is stored unless a navigation fix is within 15 s of it. On an R1S the navigation stream ran at 5.0 s (p99 5.1 s), so 15 s keeps the feeds from interleaving while letting GNSS take over as soon as navigation stops. A late fix no longer becomes the point later moves are measured from. Legacy now counts as a track of its own while it has three distinct fixes within 30 s, instead of two short gaps followed by up to five minutes of quiet. Replayed over 33 navigated R1S drives, the old rule held navigation fixes back for 2,445 s after legacy had gone quiet; this one never does, and a wake-up burst on an R2 holds for 30 s at most. The held navigation fix is no longer deleted when legacy takes over.
|
Ran your PR on my R2 (build 1. The density rule compares the wrong two times. That is not hypothetical. My box logged "legacy reports a dense fix stream" four times, naming three legacy 2. A navigation fix that was never stored still suppresses the next GPS fix. 3. Small ones. On my data it cost no fix. Replaying 749 unique navigation fixes captured on 2026-11-04, delivery delay Fixes plus tests: https://github.com/MrSerious0/rivianmate/tree/fix/nav-density-window (typecheck and lint |
Legacy counted as a dense track when the navigation fix was within 30 s of the oldest of its last three fixes. On a feed reporting once a minute those three span two minutes, so a navigation fix stamped before the newest legacy fix read as dense and was dropped. Now only the legacy fixes at or before the navigation fix count, and three of them must fall in the 30 s up to it. The feed is judged only when a delta brings a new navigation fix. The cached one was settled when it arrived; judging it again as it aged logged a switch of source that never happened. A navigation fix refused for stepping the track back no longer claims its 15 s, so it can't mute the GNSS fix that is the only point there. The replay test now uses a new monitor, so only the stored row stops the frame being stored twice, and checks the save doesn't fail. Co-authored-by: Grant Leisz <MrSerious0@users.noreply.github.com>
An R2 reports its own fix about once a minute, so its marker on the dashboard jumped once a minute even while navigation was sending a fix every 5 s. The map now follows the rule the stored track does: the navigation fix while one is running, and the vehicle's own fix once that is more than 15 s newer. Speed and heading come with the fix shown, so they match the marker. An R1, whose own fix is already a track, is unchanged, since the server doesn't keep its navigation fixes. A delta carrying only a navigation fix now reaches the live stream too, so the map moves as each one arrives. The live trail skips a fix older than the last one drawn, so it doesn't step back when navigation's fix was taken a moment before the GPS fix already shown. The out-of-date warning judges the fix the map shows. Geofences, charging and drive detection still read only the vehicle's own fix. The 15 s window moves to state-utils so the web shares it.
|
Thanks for running it on your R2 and for the fixes. I took your branch: On #1: agreed, and your fix is in. I think the four "dense" log lines came mostly from parallax deltas with no navigation fix in them. On #2: taken as-is. On #3: I reworked two of the tests.
New since your review: |
# Conflicts: # web/src/features/drives/DrivesPage.tsx
Merges main, track-fix-precedence (#95) and roamer-import (#97) into trips so all three ship in one merge to main, and one Docker Hub publish. Trips now uses the import code where Roamer moved it: isTimeZone from imports/time-zone and rangeOf from imports/plan. The import flow uses Trips' shared btn-secondary and btn-danger classes and the plural from lib/format.
R2 result — all three checks passRan it on the R2 tonight with navigation on, on 1. The planned route line draws. Yes. As soon as navigation was set, the route appeared on the 2. The marker moves every few seconds. Yes. Two navigated drives, measured from the database
3. The live trail stays behind the marker. Yes — no growing gap between the newest trail point and |
Summary
Follow-up to #93. The location writer now judges navigation and GNSS fixes by their own times instead of the server clock, and legacy counts as a dense track of its own by a simpler rule that lets go sooner. This fixes three edge cases from the #93 review: late navigation fixes being dropped, a gap of up to two minutes when navigation stops, and navigation fixes being held back after legacy goes quiet.
@MrSerious0, could you review this and, if you can, run it on your R2? I only have an R1S to test against.
Changes
location-writer.tsdriveAtfiles a late one into the drive it was taken on, as it already did for late GNSS fixes.NAV_COVERS_MS). The 15 s is measured between the fixes' own times, not against the server clock. This replacesNAV_FIX_FRESH_MS.(vehicle_id, ts)key. A frame seen again after a restart is stored once.vehicle-monitor.tsLEGACY_DENSE_MS) and the five-minute limit (LEGACY_QUIET_MS).preferLegacyno longer deletes the held navigation fix. It only stops accepting new ones. The writer stores a GNSS fix wherever no navigation fix is close to it, so a held fix can't keep legacy's out.Why these numbers
From an R1S database (Oct 1 – Nov 4: 5,538
trip_progressframes, 279 drives, 33 with navigation running):An R1 reporting every 5 s qualifies within 10 s and lets go 20–30 s into a quiet spell. A wake-up burst on an R2 holds for 30 s at most.
The extra switches happen mostly at stops, where neither feed stores a point. The replay treats stops as quiet spells, because the stored fixes skip a car that isn't moving.
Testing
Deployment
Additional Notes
trip_progressframes late. The archive keeps Rivian's time, not arrival time, and 6.5 matches the frame's time (p99 0.1 s, max 2.2 s). If frames are never late, the late-fix handling is just a safeguard.