fix(sensing): UDP relay for multi-node node_id firmware clobber#497
fix(sensing): UDP relay for multi-node node_id firmware clobber#497Viscous106 wants to merge 1 commit intoruvnet:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a host-side workaround for an ESP32 firmware bug that causes all UDP CSI/vitals packets to report node_id=1, preventing the sensing server from distinguishing multiple nodes (and blocking multistatic fusion in practice). It also includes several sensing-server/UI changes related to calibration and visualization.
Changes:
- Add a Python UDP relay (
scripts/csi_node_id_relay.py) that rewrites packetbyte[4](node_id) based on source IP, plus unit tests. - Adjust sensing-server FieldModel calibration logic (status guard) and single-link FieldModel configuration.
- Update UI pages (new
heatmap.html; tweakviz.htmlWebSocket URL and Three.js CDN version).
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
v2/crates/wifi-densepose-sensing-server/src/field_bridge.rs |
Updates FieldModel single-link config and calibration feed guard; adds tests. |
v2/crates/wifi-densepose-sensing-server/Cargo.toml |
Changes wifi-densepose-signal feature flags (enables eigenvalue). |
v2/Cargo.lock |
Lockfile updates from dependency/feature resolution changes. |
ui/viz.html |
Updates Three.js CDN version and WebSocket URL to /api/v1/stream/pose. |
ui/heatmap.html |
Adds a new top-down RF heatmap visualization page polling REST endpoints. |
scripts/csi_node_id_relay.py |
Implements UDP relay + node_id rewrite logic. |
scripts/test_csi_node_id_relay.py |
Adds unit tests for rewrite logic and passthrough behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
a65b1b4 to
aa34ff5
Compare
There was a problem hiding this comment.
Pull request overview
Adds a host-side workaround for an ESP32 firmware bug that causes all CSI UDP packets to report node_id=1, enabling multi-node sensing/multistatic behavior end-to-end. The PR also bundles supporting fixes in the sensing server field-model calibration path and UI updates for live visualization.
Changes:
- Add a UDP relay script that rewrites the packet
node_idbyte based on source IP, plus unit tests for rewrite/passthrough behavior. - Fix sensing-server FieldModel single-link config to use 64 subcarriers and allow calibration feeding from the initial
Uncalibratedstate (with Rust unit tests). - Update UI endpoints/visualizations (viz WS URL; add
heatmap.html) and adjust Rust dependency features for eigenvalue-based processing.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
v2/crates/wifi-densepose-sensing-server/src/field_bridge.rs |
Single-link FieldModel config and calibration feed guard fixes; adds regression tests. |
v2/crates/wifi-densepose-sensing-server/Cargo.toml |
Enables wifi-densepose-signal eigenvalue feature (BLAS/ndarray-linalg). |
v2/Cargo.lock |
Lockfile updates from dependency resolution changes. |
ui/viz.html |
Switches WS endpoint path and makes host/port dynamic; adjusts three.js version. |
ui/heatmap.html |
Adds a new top-down heatmap view consuming /api/v1/sensing/latest + calibration status. |
scripts/csi_node_id_relay.py |
New UDP relay that rewrites node_id based on source IP and forwards to sensing-server. |
scripts/test_csi_node_id_relay.py |
Adds Python unit tests for packet rewrite logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
aa34ff5 to
5ac3258
Compare
There was a problem hiding this comment.
Pull request overview
Adds a host-side workaround for ESP32 firmware clobbering node_id (all nodes sending node_id=1), plus related end-to-end updates to make multi-node operation usable from ingestion through visualization.
Changes:
- Add a UDP relay script that rewrites packet
byte[4](node_id) based on source IP, plus a Python test file for rewrite logic. - Fix/extend sensing-server field model behavior for calibration start conditions and ESP32 CSI subcarrier dimensionality (incl. Rust unit tests).
- Update UI: adjust
viz.htmlThree.js/WebSocket wiring and add a newheatmap.htmllive 2D view.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
v2/crates/wifi-densepose-sensing-server/src/field_bridge.rs |
Sets single-link subcarrier count to 64; allows calibration feeding from Uncalibrated; adds unit tests. |
v2/crates/wifi-densepose-sensing-server/Cargo.toml |
Changes wifi-densepose-signal feature selection (enables eigenvalue). |
v2/Cargo.lock |
Updates resolved dependency graph accordingly. |
ui/viz.html |
Downgrades Three.js to match non-module OrbitControls path; updates WebSocket endpoint URL. |
ui/heatmap.html |
Adds a new live heatmap-style UI page driven by REST endpoints. |
scripts/csi_node_id_relay.py |
New UDP relay that rewrites node_id by source IP before forwarding. |
scripts/test_csi_node_id_relay.py |
New Python tests for packet rewrite/passthrough behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Closes ruvnet#374 May fix ruvnet#386 (same root cause, unverified on Windows)
5ac3258 to
b2a40da
Compare
|
@claude review |
|
@ruvnet Have a look at the pr and tell me if there are changes needed I was checking out ruview and needed this fixes so I did it for myself and then found out that there are issues related so opening this pr please have a review and tell me for further changes needed . I have 2 esp32-S3 right now and planning to buy some more for testing so i am in for a long time commitment. |
also i didnt have windows i use Arch Linux so I couldnt test out the fixes in windows env please have the testing for windows on your end. |
ESP32 firmware (v0.4.3.1) overwrites
node_idto1betweenapp_mainandcsi_collector_init. All nodes sendnode_id=1sosensing-servercollapses them into a single node — multistatic fusion never engages.scripts/csi_node_id_relay.pyrewritesbyte[4]by source IP before forwarding tosensing-server. Includes 12 unit tests.Closes #374
May fix #386 (same root cause, unverified on Windows)
"Note: field_bridge.rs calibration fixes and heatmap.html are bundled here because they're needed for multi-node operation to work end-to-end. Happy to split into separate PRs if preferred."
Problem
When 2+ ESP32 nodes are flashed and provisioned with different
node_idvalues, thesensing-serveronly ever sees"total": 1. Multistatic fusion never engages. On Docker (issue #374) this manifests as only 1 node's packets arriving inside the container. On multi-node setups (issue #386) packets flow but pose never moves.Root cause: ESP32 firmware v0.4.3.1 clobbers
g_nvs_config.node_idto1betweenapp_mainandcsi_collector_init. Every node shipsbyte[4] = 1regardless of NVS provisioning.Serial boot log from node provisioned with
node_id=2:Fix
scripts/csi_node_id_relay.py— UDP relay that rewritesbyte[4]by source IP before forwarding tosensing-server.Before / After
Before — both nodes collapse to
node_id=1:{"nodes":[{"node_id":1,"status":"active"}],"total":1}After — both nodes visible, multistatic fusion active:
{"nodes":[{"node_id":1,"status":"active"},{"node_id":2,"status":"active"}],"total":2}Signal improvement after fusion engaged:
Relay stats after 10 min — node 2 had 13,000 rewrites, every packet arriving as
node_id=1:forwarded: {'192.168.13.222': 13000, '192.168.3.246': 13000} rewrites=13000Usage
Tests
12 unit tests in
scripts/test_csi_node_id_relay.pycovering rewrite logic, passthrough cases, all three packet magics, and custom IP maps.