Executive summary
The simulator's measurement model is a guess, and it says so in its own docstring. Seven parameters — SNR, CFO, STO, I/Q amplitude and phase imbalance, oscillator phase noise, quantisation depth — were set from Atheros and Intel CSI-tool conventions in the literature, and flagged unproven pending a real capture.
The real capture has existed since 27 July. This card fits the seven parameters from it and then asks the only question that matters downstream: does the occupancy signature survive at the fitted values?
What each parameter is read from
| Parameter | Estimated from the empty-room corpus |
|---|---|
snr_db |
per-link amplitude variance against RSSI |
cfo_hz |
packet-to-packet common phase rotation across tones |
sto_samples |
linear phase-ramp slope across subcarriers, per packet |
iq_amp_imbalance_db, iq_phase_imbalance_deg |
mirror-tone conjugate correlation |
phase_noise_deg_rms |
residual per-tone phase RMS after CFO and STO removal |
n_bits |
read from the csiq container. Known, not fitted. |
symbol_duration_s is a constant of the standard and is not a free parameter.
The trap in the data path
The measurement lake cannot answer this. packets carries chain_amp_rms,
ratio_amp_db and ratio_phase_rad. The last two are inter-chain ratios taken
within one NIC, so a common carrier-frequency offset cancels exactly — the column
that looks like a phase measurement is the one column in which CFO is invisible.
The fit reads per-tone complex CSI from the csiq containers through the csi
package.
What a null means
If the fitted values land inside the shipped prior's neighbourhood, the simulator's measurement model was right by luck or by good reading, and every prior in-silico result keeps its current standing. That is a clean, quotable outcome.
If they land far outside — and the impairment grid says the region where the attenuation signature halves and the K-slope sign-flips is close by — then the project's published in-silico occupancy figures were computed at an impairment level the AX210 does not have, and each needs a stated correction rather than a footnote.
Secondary, if the primary lands
OccupancyDiffuse.from_real_anchor fits {k0_db, k_slope_db_per_person} from a real
anchor's (count, Rician-K) pairs. It is currently fitted against WiMANS and OPERAnet.
A first-party anchor is strictly better, but it needs labelled occupancy, which the
fleet does not yet have. Named here so it is not forgotten, and explicitly out of
scope for this session.