Back to Ruview

ADR-029: Project RuvSense -- Sensing-First RF Mode for Multistatic WiFi DensePose

docs/adr/ADR-029-ruvsense-multistatic-sensing-mode.md

0.7.018.6 KB
Original Source

ADR-029: Project RuvSense -- Sensing-First RF Mode for Multistatic WiFi DensePose

FieldValue
StatusProposed
Date2026-03-02
Decidersruv
CodenameRuvSense -- RuVector-Enhanced Sensing for Multistatic Fidelity
Relates toADR-012 (ESP32 Mesh), ADR-014 (SOTA Signal Processing), ADR-016 (RuVector Training), ADR-017 (RuVector Signal+MAT), ADR-018 (ESP32 Implementation), ADR-024 (AETHER Embeddings), ADR-026 (Survivor Track Lifecycle), ADR-027 (MERIDIAN Generalization)

1. Context

1.1 The Fidelity Gap

Current WiFi-DensePose achieves functional pose estimation from a single ESP32 AP, but three fidelity metrics prevent production deployment:

MetricCurrent (Single ESP32)Required (Production)Root Cause
Torso keypoint jitter~15cm RMS<3cm RMSSingle viewpoint, 20 MHz bandwidth, no temporal smoothing
Multi-person separationFails >2 people, frequent ID swaps4+ people, zero swaps over 10 minUnderdetermined with 1 TX-RX link; no person-specific features
Small motion sensitivityGross movement onlyBreathing at 3m, heartbeat at 1.5mInsufficient phase sensitivity at 2.4 GHz; noise floor too high
Update rate~10 Hz effective20 HzSingle-channel serial CSI collection
Temporal stabilityDrifts within hoursStable over daysNo coherence gating; model absorbs environmental drift

1.2 The Insight: Sensing-First RF Mode on Existing Silicon

You do not need to invent a new WiFi standard. The winning move is a sensing-first RF mode that rides on existing silicon (ESP32-S3), existing bands (2.4/5 GHz), and existing regulations (802.11n NDP frames). The fidelity improvement comes from three physical levers:

  1. Bandwidth: Channel-hopping across 2.4 GHz channels 1/6/11 triples effective bandwidth from 20 MHz to 60 MHz, 3x multipath separation
  2. Carrier frequency: Dual-band sensing (2.4 + 5 GHz) doubles phase sensitivity to small motion
  3. Viewpoints: Multistatic ESP32 mesh (4 nodes = 12 TX-RX links) provides 360-degree geometric diversity

1.3 Acceptance Test

Two people in a room, 20 Hz update rate, stable tracks for 10 minutes with no identity swaps and low jitter in the torso keypoints.

Quantified:

  • Torso keypoint jitter < 30mm RMS (hips, shoulders, spine)
  • Zero identity swaps over 600 seconds (12,000 frames)
  • 20 Hz output rate (50 ms cycle time)
  • Breathing SNR > 10dB at 3m (validates small-motion sensitivity)

2. Decision

2.1 Architecture Overview

Implement RuvSense as a new bounded context within wifi-densepose-signal, consisting of 6 modules:

wifi-densepose-signal/src/ruvsense/
├── mod.rs              // Module exports, RuvSense pipeline orchestrator
├── multiband.rs        // Multi-band CSI frame fusion (§2.2)
├── phase_align.rs      // Cross-channel phase alignment (§2.3)
├── multistatic.rs      // Multi-node viewpoint fusion (§2.4)
├── coherence.rs        // Coherence metric computation (§2.5)
├── coherence_gate.rs   // Gated update policy (§2.6)
└── pose_tracker.rs     // 17-keypoint Kalman tracker with re-ID (§2.7)

2.2 Channel-Hopping Firmware (ESP32-S3)

Modify the ESP32 firmware (firmware/esp32-csi-node/main/csi_collector.c) to cycle through non-overlapping channels at configurable dwell times:

c
// Channel hop table (populated from NVS at boot)
static uint8_t s_hop_channels[6] = {1, 6, 11, 36, 40, 44};
static uint8_t s_hop_count = 3;   // default: 2.4 GHz only
static uint32_t s_dwell_ms = 50;  // 50ms per channel

At 100 Hz raw CSI rate with 50 ms dwell across 3 channels, each channel yields ~33 frames/second. The existing ADR-018 binary frame format already carries channel_freq_mhz at offset 8, so no wire format change is needed.

Note (Issue #127 fix): In promiscuous mode, CSI callbacks fire 100-500+ times/sec — far exceeding the channel dwell rate. The firmware now rate-limits UDP sends to 50 Hz and applies a 100 ms ENOMEM backoff if lwIP buffers are exhausted. This is essential for stable channel hopping under load.

NDP frame injection: esp_wifi_80211_tx() injects deterministic Null Data Packet frames (preamble-only, no payload, ~24 us airtime) at GPIO-triggered intervals. This is sensing-first: the primary RF emission purpose is CSI measurement, not data communication.

2.3 Multi-Band Frame Fusion

Aggregate per-channel CSI frames into a wideband virtual snapshot:

rust
/// Fused multi-band CSI from one node at one time slot.
pub struct MultiBandCsiFrame {
    pub node_id: u8,
    pub timestamp_us: u64,
    /// One canonical-56 row per channel, ordered by center frequency.
    pub channel_frames: Vec<CanonicalCsiFrame>,
    /// Center frequencies (MHz) for each channel row.
    pub frequencies_mhz: Vec<u32>,
    /// Cross-channel coherence score (0.0-1.0).
    pub coherence: f32,
}

Cross-channel phase alignment uses ruvector-solver::NeumannSolver to solve for the channel-dependent phase rotation introduced by the ESP32 local oscillator during channel hops. The system:

[Φ₁, Φ₆, Φ₁₁] = [Φ_body + δ₁, Φ_body + δ₆, Φ_body + δ₁₁]

NeumannSolver fits the δ offsets from the static subcarrier components (which should have zero body-caused phase shift), then removes them.

2.4 Multistatic Viewpoint Fusion

With N ESP32 nodes, collect N MultiBandCsiFrame per time slot and fuse with geometric diversity:

TDMA Sensing Schedule (4 nodes):

SlotTXRX₁RX₂RX₃Duration
0Node ABCD4 ms
1Node BACD4 ms
2Node CABD4 ms
3Node DABC4 ms
4--Processing + fusion30 ms
Total50 ms = 20 Hz

Synchronization: GPIO pulse from aggregator node at cycle start. Clock drift at ±10ppm over 50 ms is ~0.5 us, well within the 1 ms guard interval.

Cross-node fusion uses ruvector-attn-mincut::attn_mincut where time-frequency cells from different nodes attend to each other. Cells showing correlated motion energy across nodes (body reflection) are amplified; cells with single-node energy (local multipath artifact) are suppressed.

Multi-person separation via ruvector-mincut::DynamicMinCut:

  1. Build cross-link temporal correlation graph (nodes = TX-RX links, edges = correlation coefficient)
  2. DynamicMinCut partitions into K clusters (one per detected person)
  3. Attention fusion (§5.3 of research doc) runs independently per cluster

2.5 Coherence Metric

Per-link coherence quantifies consistency with recent history:

rust
pub fn coherence_score(
    current: &[f32],
    reference: &[f32],
    variance: &[f32],
) -> f32 {
    current.iter().zip(reference.iter()).zip(variance.iter())
        .map(|((&c, &r), &v)| {
            let z = (c - r).abs() / v.sqrt().max(1e-6);
            let weight = 1.0 / (v + 1e-6);
            ((-0.5 * z * z).exp(), weight)
        })
        .fold((0.0, 0.0), |(sc, sw), (c, w)| (sc + c * w, sw + w))
        .pipe(|(sc, sw)| sc / sw)
}

The static/dynamic decomposition uses ruvector-solver to separate environmental drift (slow, global) from body motion (fast, subcarrier-specific).

2.6 Coherence-Gated Update Policy

rust
pub enum GateDecision {
    /// Coherence > 0.85: Full Kalman measurement update
    Accept(Pose),
    /// 0.5 < coherence < 0.85: Kalman predict only (3x inflated noise)
    PredictOnly,
    /// Coherence < 0.5: Reject measurement entirely
    Reject,
    /// >10s continuous low coherence: Trigger SONA recalibration (ADR-005)
    Recalibrate,
}

When Recalibrate fires:

  1. Freeze output at last known good pose
  2. Collect 200 frames (10s) of unlabeled CSI
  3. Run AETHER contrastive TTT (ADR-024) to adapt encoder
  4. Update SONA LoRA weights (ADR-005), <1ms per update
  5. Resume sensing with adapted model

2.7 Pose Tracker (17-Keypoint Kalman with Re-ID)

Lift the Kalman + lifecycle + re-ID infrastructure from wifi-densepose-mat/src/tracking/ (ADR-026) into the RuvSense bounded context, extended for 17-keypoint skeletons:

ParameterValueRationale
State dimension6 per keypoint (x,y,z,vx,vy,vz)Constant-velocity model
Process noise σ_a0.3 m/s²Normal walking acceleration
Measurement noise σ_obs0.08 mTarget <8cm RMS at torso
Mahalanobis gateχ²(3) = 9.03σ ellipsoid (same as ADR-026)
Birth hits2 frames (100ms at 20Hz)Reject single-frame noise
Loss misses5 frames (250ms)Brief occlusion tolerance
Re-ID featureAETHER 128-dim embeddingBody-shape discriminative (ADR-024)
Re-ID window5 secondsSufficient for crossing recovery

Track assignment uses ruvector-mincut's DynamicPersonMatcher (already integrated in metrics.rs, ADR-016) with joint position + embedding cost:

cost(track_i, det_j) = 0.6 * mahalanobis(track_i, det_j.position)
                      + 0.4 * (1 - cosine_sim(track_i.embedding, det_j.embedding))

3. GOAP Integration Plan (Goal-Oriented Action Planning)

3.1 Action Dependency Graph

Phase 1: Foundation
  Action 1: Channel-Hopping Firmware ──────────────────────┐
      │                                                      │
      v                                                      │
  Action 2: Multi-Band Frame Fusion ──→ Action 6: Coherence │
      │                                  Metric              │
      v                                    │                 │
  Action 3: Multistatic Mesh              v                 │
      │                              Action 7: Coherence    │
      v                                  Gate               │
Phase 2: Tracking                         │                 │
  Action 4: Pose Tracker ←────────────────┘                 │
      │                                                      │
      v                                                      │
  Action 5: End-to-End Pipeline @ 20 Hz ←────────────────────┘
      │
      v
Phase 4: Hardening
  Action 8: AETHER Track Re-ID
      │
      v
  Action 9: ADR-029 Documentation (this document)

3.2 Cost and RuVector Mapping

#ActionCostPreconditionsRuVector CratesEffects
1Channel-hopping firmware4/10ESP32 firmware existsNone (pure C)bandwidth_extended = true
2Multi-band frame fusion5/10Action 1solver, attentionfused_multi_band_frame = true
3Multistatic mesh aggregation5/10Action 2mincut, attn-mincutmultistatic_mesh = true
4Pose tracker4/10Action 3, 7mincutpose_tracker = true
5End-to-end pipeline6/10Actions 2-4temporal-tensor, attention20hz_update = true
6Coherence metric3/10Action 2solvercoherence_metric = true
7Coherence gate3/10Action 6attn-mincutcoherence_gating = true
8AETHER re-ID4/10Actions 4, 7attentionidentity_stable = true
9ADR documentation2/10All aboveNoneDecision documented

Total cost: 36 units. Minimum viable path to acceptance test: Actions 1-5 + 6-7 = 30 units.

3.3 Latency Budget (50ms cycle)

StageBudgetMethod
UDP receive + parse<1 msADR-018 binary, 148 bytes, zero-alloc
Multi-band fusion~2 msNeumannSolver on 2×2 phase alignment
Multistatic fusion~3 msattn_mincut on 3-6 nodes × 64 velocity bins
Model inference~30-40 msCsiToPoseTransformer (lightweight, no ResNet)
Kalman update<1 ms17 independent 6D filters, stack-allocated
Total~37-47 msFits in 50 ms

4. Hardware Bill of Materials

ComponentQtyUnit CostPurpose
ESP32-S3-DevKitC-14$10TX/RX sensing nodes
ESP32-S3-DevKitC-11$10Aggregator (or x86/RPi host)
External 5dBi antenna4-8$3Improved gain, directional coverage
USB-C hub (4 port)1$15Power distribution
Wall mount brackets4$2Ceiling/wall installation
Total$73-91Complete 4-node mesh

5. RuVector v2.0.4 Integration Map

All five published crates are exercised:

CrateActionsIntegration PointAlgorithmic Advantage
ruvector-solver2, 6Phase alignment; coherence matrix decompositionO(√n) Neumann convergence
ruvector-attention2, 5, 8Cross-channel weighting; ring buffer; embedding similaritySublinear attention for small d
ruvector-mincut3, 4Viewpoint diversity partitioning; track assignmentO(n^1.5 log n) dynamic updates
ruvector-attn-mincut3, 7Cross-node spectrogram fusion; coherence gatingAttention + mincut in one pass
ruvector-temporal-tensor5Compressed sensing window ring buffer50-75% memory reduction

6. IEEE 802.11bf Alignment

RuvSense's TDMA sensing schedule is forward-compatible with IEEE 802.11bf (WLAN Sensing, published 2024):

RuvSense Concept802.11bf Equivalent
TX slotSensing Initiator
RX slotSensing Responder
TDMA cycleSensing Measurement Instance
NDP frameSensing NDP
AggregatorSensing Session Owner

When commercial APs support 802.11bf, the ESP32 mesh can interoperate by translating SSP slots into 802.11bf Sensing Trigger frames.


7. Dependency Changes

Firmware (C)

New files:

  • firmware/esp32-csi-node/main/sensing_schedule.h
  • firmware/esp32-csi-node/main/sensing_schedule.c

Modified files:

  • firmware/esp32-csi-node/main/csi_collector.c (add channel hopping, link tagging)
  • firmware/esp32-csi-node/main/main.c (add GPIO sync, TDMA timer)

Rust

New module: crates/wifi-densepose-signal/src/ruvsense/ (6 files, ~1500 lines estimated)

Modified files:

  • crates/wifi-densepose-signal/src/lib.rs (export ruvsense module)
  • crates/wifi-densepose-signal/Cargo.toml (no new deps; all ruvector crates already present per ADR-017)
  • crates/wifi-densepose-sensing-server/src/main.rs (wire RuvSense pipeline into WebSocket output)

No new workspace dependencies. All ruvector crates are already in the workspace Cargo.toml.


8. Implementation Priority

PriorityActionsWeeksMilestone
P01 (firmware)2Channel-hopping ESP32 prototype
P02 (multi-band)2Wideband virtual frames
P13 (multistatic)2Multi-node fusion
P14 (tracker)117-keypoint Kalman
P16, 7 (coherence)1Gated updates
P25 (end-to-end)220 Hz pipeline
P28 (AETHER re-ID)1Identity hardening
P39 (docs)0.5This ADR finalized
Total~10 weeksAcceptance test

9. Consequences

9.1 Positive

  • 3x bandwidth improvement without hardware changes (channel hopping on existing ESP32)
  • 12 independent viewpoints from 4 commodity $10 nodes (C(4,2) × 2 links)
  • 20 Hz update rate with Kalman-smoothed output for sub-30mm torso jitter
  • Days-long stability via coherence gating + SONA recalibration
  • All five ruvector crates exercised — consistent algorithmic foundation
  • $73-91 total BOM — accessible for research and production
  • 802.11bf forward-compatible — investment protected as commercial sensing arrives
  • Cognitum upgrade path — same software stack, swap ESP32 for higher-bandwidth front end

9.2 Negative

  • 4-node deployment requires physical installation and calibration of node positions
  • TDMA scheduling reduces per-node CSI rate (each node only transmits 1/4 of the time)
  • Channel hopping introduces ~1-5ms gaps during esp_wifi_set_channel() transitions
  • 5 GHz CSI on ESP32-S3 may not be available (ESP32-C6 supports it natively)
  • Coherence gate may reject valid measurements during fast body motion (mitigation: gate only on static-subcarrier coherence)

9.3 Risks

RiskProbabilityImpactMitigation
ESP32 channel hop causes CSI gapsMediumReduced effective rateMeasure gap duration; increase dwell if >5ms
CSI callback rate exhausts lwIP pbufsResolvedGuru meditation crash50 Hz rate limiter + 100 ms ENOMEM backoff (Issue #127, PR #132)
5 GHz CSI unavailable on S3HighLose frequency diversityFallback: 3-channel 2.4 GHz still provides 3x BW; ESP32-C6 for dual-band
Model inference >40msMediumMiss 20 Hz targetRun model at 10 Hz; Kalman predict at 20 Hz interpolates
Two-person separation fails at 3 nodesLowIdentity swapsAETHER re-ID recovers; increase to 4-6 nodes
Coherence gate false-triggersLowMissed updatesGate on environmental coherence only, not body-motion subcarriers

ADRRelationship
ADR-012Extended: RuvSense adds TDMA multistatic to single-AP mesh
ADR-014Used: All 6 SOTA algorithms applied per-link
ADR-016Extended: New ruvector integration points for multi-link fusion
ADR-017Extended: Coherence gating adds temporal stability layer
ADR-018Modified: Firmware gains channel hopping, TDMA schedule, HT40
ADR-022Complementary: RuvSense is the ESP32 equivalent of Windows multi-BSSID
ADR-024Used: AETHER embeddings for person re-identification
ADR-026Reused: Kalman + lifecycle infrastructure lifted to RuvSense
ADR-027Used: GeometryEncoder, HardwareNormalizer, FiLM conditioning

11. References

  1. IEEE 802.11bf-2024. "WLAN Sensing." IEEE Standards Association.
  2. Geng, J., Huang, D., De la Torre, F. (2023). "DensePose From WiFi." arXiv:2301.00250.
  3. Yan, K. et al. (2024). "Person-in-WiFi 3D." CVPR 2024, pp. 969-978.
  4. Chen, L. et al. (2026). "PerceptAlign: Geometry-Aware WiFi Sensing." arXiv:2601.12252.
  5. Kotaru, M. et al. (2015). "SpotFi: Decimeter Level Localization Using WiFi." SIGCOMM.
  6. Zheng, Y. et al. (2019). "Zero-Effort Cross-Domain Gesture Recognition with Wi-Fi." MobiSys.
  7. Zeng, Y. et al. (2019). "FarSense: Pushing the Range Limit of WiFi-based Respiration Sensing." MobiCom.
  8. AM-FM (2026). "A Foundation Model for Ambient Intelligence Through WiFi." arXiv:2602.11200.
  9. Espressif ESP-CSI. https://github.com/espressif/esp-csi