From 7535dff3e40573f6772ab89c75430edb7ec36a49 Mon Sep 17 00:00:00 2001 From: arsen Date: Sun, 17 May 2026 02:54:37 +0700 Subject: [PATCH] fix(sensing-server): feature_state path keeps last raw amplitudes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After 3393c1e8 made FW emit ~80 % feature_state packets and ~20 % raw CSI, the server's feature_state path was overwriting NodeInfo.amplitude with vec![] on every feature_state tick. raw.html's per-node bar chart ended up freezing for hundreds of milliseconds between rare raw-CSI packets, and /api/v1/sensing/latest mostly snapshotted an empty amps vector even though raw CSI was flowing. Fix: in the feature_state SensingUpdate builder, hand out ns.frame_history.back() (the last raw amps vector that the raw-CSI path pushed) instead of an empty Vec. Bars now refresh on every WS update (verified: 100/100 updates carry amps in a 4-s sample, was ~20/100 before the patch). Classifier behaviour unchanged — amp_presence_override still runs only when actual raw CSI arrives; this only affects what the UI displays. --- .../wifi-densepose-sensing-server/src/main.rs | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/v2/crates/wifi-densepose-sensing-server/src/main.rs b/v2/crates/wifi-densepose-sensing-server/src/main.rs index e5941ce3..6bdcda3b 100644 --- a/v2/crates/wifi-densepose-sensing-server/src/main.rs +++ b/v2/crates/wifi-densepose-sensing-server/src/main.rs @@ -4400,14 +4400,24 @@ async fn udp_receiver_task(state: SharedState, udp_port: u16) { } // Build nodes array with all active nodes. + // ADR-101 follow-up: feature_state packets carry no + // raw CSI of their own, but the raw-CSI path has + // been pushing amplitudes into ns.frame_history. + // Hand the most recent vector out so raw.html bars + // don't go blank between rare raw-CSI packets + // (current FW emits ~80 % feature_state, ~20 % raw). let active_nodes: Vec = s.node_states.iter() .filter(|(_, n)| n.last_frame_time.map_or(false, |t| now.duration_since(t).as_secs() < 10)) - .map(|(&id, n)| NodeInfo { - node_id: id, - rssi_dbm: n.rssi_history.back().copied().unwrap_or(0.0), - position: [2.0, 0.0, 1.5], - amplitude: vec![], - subcarrier_count: 0, + .map(|(&id, n)| { + let last_amps = n.frame_history.back().cloned().unwrap_or_default(); + let sub_count = last_amps.len(); + NodeInfo { + node_id: id, + rssi_dbm: n.rssi_history.back().copied().unwrap_or(0.0), + position: [2.0, 0.0, 1.5], + amplitude: last_amps, + subcarrier_count: sub_count, + } }) .collect();