fix(calibration): bind the grid whose frames come from one population - #1919
Open
jingilibili wants to merge 1 commit into
Open
fix(calibration): bind the grid whose frames come from one population#1919jingilibili wants to merge 1 commit into
jingilibili wants to merge 1 commit into
Conversation
A field model compares a runtime window mean against a calibration reference
built the same way. That comparison only means something when both come from the
same transmitter population, and the field model binds exactly one subcarrier
grid. Selection ordered candidates by max gap, then rate, then width, so a faster
but mixed grid could win.
MEASURED on the room B rig, three ESP32-S3 nodes, 30 s capture per node:
grid 306 ~15 Hz RSSI spread 1-3 dB (the array's own ping traffic)
grid 192 ~13 Hz RSSI spread 15-43 dB (access point plus ambient clients)
With the mixed 192 grid bound, injecting 2000 pps from the host moved the
residual median from 9.4 to 17.4 while the operator sat motionless - a larger
change than the occupant's own effect (empty 10.4 versus seated 11.9), because
the residual was following the frame population and not the room.
Changes:
- RawGridObservation records the frame's reported RSSI.
- CalibrationGridEvidence reports rssi_spread_db and rssi_median_dbm.
- select_calibration_grid orders by RSSI spread first (homogeneity), then max
gap, then rate, then width. Eligibility gates (span, rate, gap) are unchanged.
Also measured, and the reason a one-node array cannot work: a node cannot hear
its own transmissions, so the steady population on the 306 grid is the *other*
nodes' traffic. With two of three nodes powered down, node 3 saw 1.6 Hz on 306
and 0.2 Hz on 192, both at -58 dBm, and a 600 pps injection from the host did not
raise either (1.2 Hz and 0.9 Hz). The calibration needs at least two nodes.
Tests: cargo test -p wifi-densepose-sensing-server --bin sensing-server (323
passed), including calibration_grid_selection_prefers_a_homogeneous_population.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A field model compares a runtime window mean against a calibration reference built
the same way, and it binds exactly one subcarrier grid. That comparison only
means something when both windows come from the same transmitter population.
select_calibration_gridordered candidates by max gap, then rate, then width, soa faster but mixed grid could win.
Measurement
Three ESP32-S3 nodes on one access point, 30 s capture per node, frames counted
straight off the UDP socket:
The 306 grid carries the array's own traffic: each node pings the gateway
(
CONFIG_CSI_SELF_PING_HZ, documented as "a stable OFDM CSI source") and cannothear its own transmission, so what a node hears on that grid is the other
nodes. That population is strong and homogeneous.
With the mixed 192 grid bound, injecting 2000 pps from the host moved the field
model's residual median from 9.4 to 17.4 while the operator sat motionless -
a larger change than the occupant's own effect in the same session (empty room
median 10.4, seated median 11.9). The residual was following the frame population
instead of the room.
Related, and worth knowing when a report looks impossible: with two of the three
nodes powered down, node 3 saw 1.6 Hz on the 306 grid and 0.2 Hz on 192, both at
-58 dBm, and a 600 pps injection from the host raised neither (1.2 Hz and 0.9 Hz).
A one-node array has no steady population to calibrate against.
Change
RawGridObservationrecords the frame's reported RSSI.CalibrationGridEvidencereportsrssi_spread_dbandrssi_median_dbm.select_calibration_gridorders by RSSI spread first, then max gap, then rate,then width. The eligibility gates (10 s span, 2 Hz, 5 s gap) are unchanged, and
a grid without RSSI evidence falls back to the previous ordering exactly.
Tests
Limits
channel 11) on one day. The spread is used for ordering only, never as a hard
cutoff, so a rig whose grids all look homogeneous keeps its previous choice.
empty versus 11.9 seated), which is a separate problem: this change removes the
traffic-driven part of the variance, it does not by itself make the residual a
validated presence signal.