ruview @ multistatic-timing-fixes-2026-09-09
integrity
- size
- 60.0 MiB
- downloaded
- last checked
- detected
- raw version: universal archives only
release notes
RuView multistatic timing & positioning fixes — 2026-09-09
Nine community contributions landed today, all focused on one theme: getting multiple sensor nodes to actually agree on the same physical moment and the same physical location. That sounds basic, but it turns out to be the hardest part of making several WiFi sensors work together as one system instead of three independent guesses.
What actually changes
Nodes now measure their own speed correctly, even when data arrives in bursts. The counter that tracks how fast a sensor is really sending data was quietly wrong whenever packets clumped together (which happens constantly over WiFi/UDP) — a burst of several readings in quick succession got counted as just one, so the system underestimated how fast a node was actually running. Fixed by measuring time gaps the right way around, so the reported speed now matches reality.
Multiple sensors can finally look at the same instant in time. Each sensor used to decide "have 20 milliseconds passed since MY last reading?" independently — which meant two perfectly healthy sensors, both running at the right speed, could end up sampling completely different moments, with nothing in common to compare. The fix synchronizes that decision to a shared clock across the mesh, so sensors that are supposed to be looking at the same moment now actually are — a prerequisite for combining several sensors' views into one accurate picture.
A safety check that was supposed to catch bad timing... never actually could. A guard rail meant to reject data if sensors were too out-of-sync had a math error: it was checking the wrong quantity, so it would never trigger even when it should have. Now fixed and verified with a real end-to-end test.
Room positions are now correctly remembered, even when a sensor briefly drops out. This is a fix to something we shipped five days ago — thank you to the contributor who caught it. The original fix (assigning each sensor's configured position by "the Nth sensor currently online") had a subtle flaw: if one sensor went quiet, every sensor after it in the lineup would silently inherit the wrong position, since they'd all shift up one slot. Positions are now tied permanently to each sensor's actual ID, so a sensor going offline no longer scrambles everyone else's coordinates.
New optional antenna-selection support for a specific hardware variant (Seeed XIAO ESP32-C6), letting that board choose between its internal and external antenna — useful for controlled signal-strength comparisons. Fully opt-in; does nothing on other boards.
Documentation additions: a from-the-field operational runbook for flashing and running the ESP32-C6 firmware (the kind of guide written after getting each step wrong at least once), an architecture record explaining why device-free position estimation kept failing and what was learned from measuring it three different ways, and a rigorously honest write-up of a real nine-sensor experiment comparing three different timing strategies — including a reported prediction that turned out wrong and a mid-experiment methodology hiccup, disclosed rather than hidden.
Thank you to this round's contributors
- clonea1 — eight of today's nine contributions: the burst-timing fix, mesh-time alignment, the timing-guard math fix, the node-position correction (including catching a real bug in code merged five days ago), the antenna-selection groundwork's supporting docs, the operational runbook, the architecture record, and the measured timing-gate comparison.
- proffesor-for-testing (Dragan Spiridonov) — the XIAO ESP32-C6 antenna-selection feature.
Every change here was independently verified against the actual running code before merging — not just taken on the strength of its description.
What this doesn't include
Two related, still-open gaps surfaced during review, not fixed by this batch:
- The governed fusion path (the one that actually feeds provenance and trust tracking) still has its own separate instance of the position-tracking system that was never wired up to use configured positions at all — a different code path from the one fixed here. Tracked in #1870.
- A large, well-documented field report (#1804) raising real architecture questions about occupancy counting, still-person detection, and automatic gain control — partially answered, with several questions still needing the maintainer's own call on intended design.
Merged pull requests
| PR | Title | Contributor |
|---|---|---|
| #1855 | chore: ignore host-test binaries by shape, not by a list that goes stale | clonea1 |
| #1857 | fix(server): recover the true CSI frame rate through bursty UDP delivery | clonea1 |
| #1858 | docs: measured comparison of three CSI frame-selection gates, and the harness | clonea1 |
| #1859 | feat(firmware): align the CSI rate gate to mesh time | clonea1 |
| #1860 | fix(sensing-server): key node positions by node id, not by list position | clonea1 |
| #1861 | docs(firmware): add the ESP32-C6 operational runbook | clonea1 |
| #1862 | docs(adr): ADR-345 — per-link CSI attribution and node-to-node ranging | clonea1 |
| #1867 | feat(firmware): add XIAO ESP32-C6 antenna selection | proffesor-for-testing |
| #1872 | fix(signal): the derived soft guard flagged the schedule it was derived from | clonea1 |
All nine were independently reviewed against the underlying code before merge, including one merge-conflict resolution (#1858 vs. an unrelated concurrently-merged docs PR) handled during integration.
Known open issues (not fixed by this batch)
- #1870 — the governed
StreamingEnginefusion path owns a separateMultistaticFuserinstance that is never configured with node positions at all; distinct from the instance fixed in #1860. - #1804 — detailed field report on occupancy-counting and still-person-detection gaps; partially addressed in comments, several architecture questions remain open for maintainer input.
download
curl -fL -o multistatic-timing-fixes-2026-09-09.zip https://ratatoskr.space/pkg/ruview/multistatic-timing-fixes-2026-09-09.zip
printf '%s %s\n' '9efc3980047b068a28e59cefdab853607b0f9781235ba81b14897370786ff14a' 'multistatic-timing-fixes-2026-09-09.zip' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/ruview/multistatic-timing-fixes-2026-09-09.zip"
$out = "multistatic-timing-fixes-2026-09-09.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "9efc3980047b068a28e59cefdab853607b0f9781235ba81b14897370786ff14a") { throw "sha256 mismatch" }
curl -fL -o multistatic-timing-fixes-2026-09-09.tar.gz https://ratatoskr.space/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz
printf '%s %s\n' '1f4ba63a808e9df0a37f65c2edc96d560c4bf9216e62c8e7b41b9f113cc96636' 'multistatic-timing-fixes-2026-09-09.tar.gz' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz"
$out = "multistatic-timing-fixes-2026-09-09.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "1f4ba63a808e9df0a37f65c2edc96d560c4bf9216e62c8e7b41b9f113cc96636") { throw "sha256 mismatch" }
download via yggdrasil mesh
curl -fL -o multistatic-timing-fixes-2026-09-09.zip http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/multistatic-timing-fixes-2026-09-09.zip
printf '%s %s\n' '9efc3980047b068a28e59cefdab853607b0f9781235ba81b14897370786ff14a' 'multistatic-timing-fixes-2026-09-09.zip' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/multistatic-timing-fixes-2026-09-09.zip"
$out = "multistatic-timing-fixes-2026-09-09.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "9efc3980047b068a28e59cefdab853607b0f9781235ba81b14897370786ff14a") { throw "sha256 mismatch" }
curl -fL -o multistatic-timing-fixes-2026-09-09.tar.gz http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz
printf '%s %s\n' '1f4ba63a808e9df0a37f65c2edc96d560c4bf9216e62c8e7b41b9f113cc96636' 'multistatic-timing-fixes-2026-09-09.tar.gz' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz"
$out = "multistatic-timing-fixes-2026-09-09.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "1f4ba63a808e9df0a37f65c2edc96d560c4bf9216e62c8e7b41b9f113cc96636") { throw "sha256 mismatch" }
| artifact | format | size | hashes |
|---|---|---|---|
| multistatic-timing-fixes-2026-09-09.zip | zip | 60.2 MiB |
blake3-24 d7338eaba7c9a7875574d3371132466e31646414c78f6015
sha256 9efc3980047b068a28e59cefdab853607b0f9781235ba81b14897370786ff14a
sha1 2610419147233994c922344cad96a566da3f1b12
|
| multistatic-timing-fixes-2026-09-09.tar.gz | tar.gz | 57.9 MiB |
blake3-24 2fab4566fa2e8ffd9663ea8cd36451e876efcee3fc8303ae
sha256 1f4ba63a808e9df0a37f65c2edc96d560c4bf9216e62c8e7b41b9f113cc96636
sha1 52bbbcfc602bcb1c0c35249b90bbcf9b47e2b87b
|
install
http_archive(
name = "ruview",
urls = ["https://ratatoskr.space/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz"],
integrity = "sha256-H0umOoCOnfCjf2XC7cltVgxL+SFuYsjntBufETzJZjY=",
strip_prefix = "ruview-multistatic-timing-fixes-2026-09-09",
)
.url = "https://ratatoskr.space/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz",
install via yggdrasil mesh
http_archive(
name = "ruview",
urls = ["http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz"],
integrity = "sha256-H0umOoCOnfCjf2XC7cltVgxL+SFuYsjntBufETzJZjY=",
strip_prefix = "ruview-multistatic-timing-fixes-2026-09-09",
)
.url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/multistatic-timing-fixes-2026-09-09.tar.gz",