wifi-densepose/v2
WilliamMalone cb5977de7e Fix antenna-regime presence over-read: de-saturate motion_score + correct CSI header offsets
After external IPEX antennas were added to the ESP32-S3 mesh nodes, a confirmed-empty
room read "present" indefinitely. Two root-cause bugs:

1. motion_score saturation. `variance_motion` and `mbp_motion` used fixed divisors
   (/10, /25) calibrated for the antenna-less regime. Antennas raised amplitudes ~5x
   and these amplitude^2 energies ~30x, pinning both terms at the 1.0 clamp — so
   raw_motion could not fall near the presence floor and the adaptive baseline
   subtraction in smooth_and_classify was defeated. Normalize both by signal power
   (mean_amp^2) — the same dimensionless sqrt-of-power-ratio form already used by
   temporal_motion_score — making motion_score amplitude-scale-invariant. This fixes
   the single shared extract_features_from_frame used by BOTH the aggregate and the
   per-node paths, so room-level presence benefits too. (csi.rs carries the identical
   change in its dead mirror copy to keep the two in sync.)

2. parse_esp32_frame header offsets were 2 bytes early vs the firmware layout
   (csi_collector.c csi_serialize_frame: seq @ [12..16), rssi @ [16], noise_floor @
   [17]). rssi was decoded from sequence-counter byte 2 — which stays 0 for the first
   65,536 frames — yielding an impossible rssi=0 dBm that zeroed the RSSI fusion
   weights and the SNR-based signal_quality. The I/Q payload at byte 20 was already
   correct (CSI_HEADER_SIZE == 20), so amplitude-derived features were unaffected.

Adds regression tests asserting motion_score is amplitude-scale-invariant and that a
quiet high-amplitude signal does not saturate. Full binary suite green (103 tests).

Validated live on the 2-node mesh: RSSI now reports real values (-28..-74 dBm, was 0)
and an empty room now produces genuine low-motion frames. A residual over-read remains
(real multi-subcarrier CSI reads elevated even when empty) — that intrinsic empty-vs-
still ambiguity needs a learned reference (adaptive classifier retrain), tracked separately.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:02:57 -06:00
..
.cargo fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
.claude-flow chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
crates Fix antenna-regime presence over-read: de-saturate motion_score + correct CSI header offsets 2026-06-03 08:02:57 -06:00
data chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
docs chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
examples chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
patches/ruvector-crv chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
Cargo.lock feat(swarm): add ruview-swarm crate — drone swarm control system (ADR-148) (#862) 2026-05-30 16:00:59 -04:00
Cargo.toml feat(swarm): add ruview-swarm crate — drone swarm control system (ADR-148) (#862) 2026-05-30 16:00:59 -04:00
rust-toolchain.toml v2: pin Rust 1.89 and fix sensing-server UI path when run from v2 (#523) 2026-05-17 18:00:36 -04:00
ruvector.db feat(worldmodel): ADR-147 — OccWorld world model integration, wifi-densepose-worldmodel v0.3.0 (#856) 2026-05-29 16:53:51 -04:00