Asking the fleet what it is doing…
monad-knowledge Wi-Fi sensing lab · FIIT STU
Campaign

OPERAnet sim-to-real fingerprint — does ray-traced synthetic CSI reproduce the measured environment confound?

c-operanet-sim2real-fingerprint · exp-csi-static

Archive snapshot, as of 18 h ago — the run corpus is rebuilt once a day, so this page is not a live reading. The fleet panel is the live one; it refreshes every 30 s.

Sessions

No sessions yet — this campaign has a brief but no execution.

Brief

Question

On real OPERAnet CSI (OPERAnet cross-modal motion validation § leakage probe) WiFi activity recognition is environment-confounded: raw CSI identifies the room at 0.83 (leave-one-file-out, chance 0.5) and a high-capacity HAR keeps only 0.73 of its accuracy across rooms (LORO 0.51 vs random 0.70) while staying flat across persons. So the real, deployment-relevant generalization boundary is the environment. Does our ray-traced synthetic-CSI pipeline (sionna-csi-runner) reproduce that environment fingerprint — a comparable cross-room separability and cross-room degradation — when the same occupancy signal is simulated across several distinct room geometries (ResPlan floors)?

Framing discipline. A sim-to-real calibration probe, not a hypothesis test. The honest deliverable is the head-to-head fingerprint comparison (synthetic floor-ID vs real 0.83; synthetic occupancy retention vs real 0.73). A match validates the ray-tracer's environment coding and licenses synthetic-CSI pretraining for cross-environment recalibration (the ble-periodic-calibration direction); a mismatch localises the defect (scene diversity / wall-material palette / body prior) into a refit target for exp-csi-calibration. No accuracy headline against self-authored synthetic noise.

What we already know

  • OPERAnet cross-modal motion validation (real, CC0): the leakage probe — raw-CSI room-ID LOFO 0.83, HAR cross-room retention 0.73, person axis flat. These are the dimensionless targets (REAL_TARGETS in operanet_sim2real.py).
  • c-csi-band-calibration / c-csi-roomscale-calibration established the "reproduce a real-measured statistic" calibration-probe pattern (vs WiMANS). This mirrors it against OPERAnet.
  • c-csi-cross-geometry-resplan validated exp-csi-static across these exact ResPlan floors — the known-good sim_params shape reused here.
  • Methodology (2026-06-24 audit) MUST be used: monad_knowledge/sim/reduction_stats.py (PHYSICAL_BOUNDS, bootstrap CIs) and the explicit sim_campaign_attach_run loop after CLI fan-out.

What the supervisor does

  1. Smoke first: one cell (resplan-12439-floor-0, n_agents=0, 5 GHz) locally to confirm the runner stages floor_geometry.json + scene.json and emits a valid links.parquet.
  2. Fan out exp-csi-static over the 4 floors × 4 n_agents × 2 seeds grid (32 runs, 5 GHz). Systematic on CI for the full grid (fan-out → project key, not the operator's laptop).
  3. Attach each run explicitly (sim_campaign_attach_run loop).
  4. Run operanet_sim2real.py (config = per-run links.parquet paths grouped by floor/n_agents): synthetic floor-ID (LORO, all-floors + 2-floor), cross-floor occupancy retention, and the head-to-head table vs REAL_TARGETS.
  5. Synthesise the calibration verdict: reproduces / under-codes / over-codes the environment fingerprint.

Figure render request

operanet_sim2real — two bars: (a) environment-ID accuracy, real OPERAnet room-ID (0.83) vs synthetic 2-floor floor-ID, with chance line; (b) cross-room accuracy retention, real HAR (0.73) vs synthetic occupancy, with the no-degradation line.

Dispatch

Fan-out → CI (project key) per the local-vs-remote rule. After committing this brief + the reduction:

/campaign-systematic c-operanet-sim2real-fingerprint      # or: gh workflow run sim-campaign.yml -f campaign_id=c-operanet-sim2real-fingerprint

A single local smoke cell (/campaign-curious, or sim_run_launch sim_id=exp-csi-static where=local with n_placements small) is fine to confirm the chain before the CI fan-out.

Smoke passed (2026-07-13): exp-csi-static on resplan-12439-floor-0 (n_agents=0, n_placements=6, 5 GHz), run 01KXD2QMMSH3DRDW7EBMEK2EQ6, gate_passed, exit 0, 98 s wall-clock (GHCR image reused, no local build). Emitted valid links.parquet (6 frames × 5 links; mean_amp_db ≈ −68 dB) + csi.hdf5

  • scene.json; operanet_sim2real.py:_frame_features ingests it cleanly. Chain sim→reduction confirmed; ready for the CI fan-out (4 floors × 4 n_agents × 2 seeds).

Results — local fan-out (2026-07-13)

Deterministic-supervisor fan-out: 4 exp-csi-static sweeps (one per floor) × n_agents{0,2,4,6} × seed{0,1}, 5 GHz, n_placements=24 → 31 runs collected (744 per-frame samples), reduced by operanet_sim2real.py. (First attempt failed when the PostGIS tunnel dropped mid-fan-out; re-run after restore succeeded.)

probe synthetic real target verdict
environment fingerprint (2-floor room-ID, chance 0.5) 0.98 0.83 reproduced, OVER-codes
environment fingerprint (4-floor, chance 0.25) 0.95 strong
occupancy signal (within-floor, chance 0.25) 0.13 at chance
occupancy (cross-floor) 0.24 at chance
cross-room retention undefined 0.73 inconclusive (occupancy at chance)

Verdict (calibration probe).

  1. Environment fingerprint is reproduced — and over-coded. Ray-traced synthetic CSI identifies the floor at 0.95 (4-way) / 0.98 (2-floor) vs the real 0.83. The direction matches the real finding (synthetic CSI is strongly environment-confounded, confirming environment as the hard generalization axis) but the sim signature is near-deterministic because it lacks real nuisance variability (hardware noise, temporal drift, furniture change). Refit target: apply the exp-csi-static hardware-impairment layer + per-run nuisance so the synthetic fingerprint drops toward the measured 0.83 before using synthetic CSI to pretrain cross-environment recalibration — otherwise sim-pretrained transfer will read optimistic.
  2. Occupancy signal is at chance in the static config (within-floor 0.13, cross-floor 0.24 vs 0.25) — random-placement body attenuation does not survive into per-frame link-stat features, so cross-room retention is undefined. This mirrors the real result (occupancy/activity needed temporal dynamics, not a static snapshot): the retention arm must be re-run on the coupled exp-csi-crowd (JuPedSim→Sionna) chain, not exp-csi-static.

Figure: operanet_sim2real.png (a) environment-ID real vs synth; (b) synthetic occupancy at chance. Runs labelled campaign_id=c-operanet-sim2real-fingerprint.

Occupancy arm re-run on the coupled exp-csi-crowd chain (2026-07-13)

The static occupancy null (0.13) was a static-snapshot artefact, so the arm was re-run on the coupled walk-notebook(JuPedSim)→sionna chain — temporal motion, per-frame occlusion. On resplan-12439-floor-0 (the one floor with a proven seek_and_occupy/seat + east-entry spawn_bbox_cm=[1900,0,2489,1857] config; a first attempt with target_subtype: room and no spawn bbox turned all agents away → empty trajectory), crowd size {2,4,8,14} × 2 seeds = 8 coupled runs (150 RT frames each, 1200 frames total), classifying n_agents from per-frame link features under leave-one-run-out RandomForest:

config within-floor occupancy accuracy chance
static exp-csi-static (random placements) 0.13 0.25
coupled exp-csi-crowd (temporal motion) 0.60 ± 0.39 0.25

Temporal coupling recovers the occupancy signal — 0.60 (≈2.4× chance) vs the static 0.13. The crowd-count information lives in the temporal CSI dynamics of moving bodies, not in a static placement snapshot. This mirrors the real OPERAnet finding (activity/occupancy needed temporal dynamics) and validates the coupled chain as the correct substrate for the occupancy/retention question. (High fold variance — 8 leave-one-run-out folds, 2 runs/count — so the point estimate is directional; a seeded ladder with more runs/count would tighten it.) Figure: operanet_crowd_occupancy.png.

Cross-floor retention — floor-2 tuned (resplan-7421), 2026-07-13

A second floor was tuned for the coupled chain: only resplan-7421-floor-0 has seats (6, all in bedroom-0; resplan-1374/147440 have zero → seek_and_occupy/seat impossible). Spawn placed in the living-0 corridor (spawn_bbox_cm=[600,150,1400,900]) so agents walk SE to the seats; smoke confirmed motion (150 frames, occluders 0–2). Fan-out: crowd {2,4,8,14} × 2 seeds = 8 coupled runs, matched to the 12439 set. Cross-floor reduction (collect_crossfloor.py, train-one/test-other):

quantity value note
within-floor occupancy — resplan-12439 0.60 graded regime
within-floor occupancy — resplan-7421 0.02 saturated regime (below chance)
cross-floor occupancy 0.25 = chance
nominal retention (cross ÷ mean-within) 0.81 confounded — see below
real HAR cross-room retention 0.73 not apples-to-apples here

The finding is a mechanism, not a clean retention number. Mean link occlusion vs crowd size: 12439 rises monotonically (0.003→0.003→0.196→0.401 for n=2/4/8/14; amp-std 4.7→12.4) — a graded regime where occupancy is observable (0.60). 7421 is flat at ~0.32 for every crowd size (amp-std ~13.4) — a saturated regime: even 2 agents block the auto-placed link as much as 14, so it is count-blind (within-floor 0.02). Cross-floor transfer is therefore at chance (0.25) and the nominal 0.81 retention is an artefact of averaging a working floor with a saturated one — not a valid analogue of the real 0.73.

Why this matters. Synthetic CSI reproduces the graded-vs-saturated occupancy-observability dichotomy — whether a link resolves graded crowd count depends on its geometry relative to the crowd path (the same phenomenon behind the real environment confound and the BLE-anchor saturation finding c-ble-csi-coregistration). A clean cross-floor retention number vs the real 0.73 requires both floors' links to be in the graded regime; 7421's auto-placed link is saturated. Next step: place/select the floor-2 link for a graded response (link-placement tuning, gis place-device), then re-run — a link-geometry design task, not a pipeline gap. Figure: operanet_crossfloor.png.

Link-placement retune on 7421 → clean cross-floor retention (2026-07-13)

The 7421 saturation was a link-placement artefact: the auto-placed Rx sat in bedroom-0 buried in the parked-seat cluster, so 1–2 bodies blocked it regardless of total. New experiment csi-link-resplan-7421-graded places Tx + all 3 Rx in the living-0 corridor spanning the spawn→bedroom-0 walk path (mirrors 12439's graded living-0 link; primary Rx at [1027,1146] = a 500 cm vertical link). Re-ran crowd {2,4,8,14}×2 seeds.

quantity saturated link graded link (retuned)
within-floor occupancy — 7421 0.02 0.72
within-floor occupancy — 12439 0.60
cross-floor occupancy 0.37
chance (4 counts) 0.25 0.25
cross-floor retention (sim) 0.57
real HAR cross-room retention 0.73

Clean cross-floor retention = 0.57 (sim) vs 0.73 (real). With both floors individually observable (within-floor 0.60 and 0.72, both ≫ chance), the synthetic occupancy model transfers across environments at retention 0.57 — a steeper drop than the real 0.73. Consistent with and reinforcing the environment-fingerprint verdict (sim floor-ID 0.98 vs real room-ID 0.83): because the ray-tracer over-codes environment, a count model learned on one floor generalizes worse to another than real activity does across real rooms. Same refit target: add hardware-impairment / per-run nuisance to soften the synthetic environment signature toward reality.

Sub-finding. On the retuned 7421 corridor link, direct LoS occlusion stays ~0 (mean 0.002→0.007 across counts) yet occupancy is classifiable at 0.72 — the crowd signal arrives via multipath / channel statistics (amp/K/delay-spread), not blockage. On 12439 the graded link does get LoS occlusion (0.003→0.40). Two distinct routes to observability, both defeating the saturated-placement failure. Caveat: 2 floors, 8 runs/floor, leave-one-run-out fold std ~0.30–0.39 → 0.57 is directional, not tight.

Figure: operanet_crossfloor_graded.png.

Impairment / nuisance layer — does it close the gap? (2026-07-13)

Re-ran both graded crowd floors with the commodity-NIC impairment_profile (SNR 20 dB, CFO 200 Hz, STO 0.5, IQ 0.3 dB/2°, phase-noise 1° RMS, 10-bit quantization, per-run noise draws). Each run keeps the clean csi.hdf5 oracle + emits csi_impaired.hdf5; features recomputed identically from both raw tensors (collect_impairment.py) so the comparison isolates the impairment.

metric clean impaired real
environment fingerprint (2-floor ID) 0.999 1.000 0.83
within-floor occupancy 0.364 0.312
cross-floor occupancy 0.257 0.194
cross-floor retention 0.708 0.623 0.73

The impairment does NOT close the gap — and the reason is the finding.

  1. The environment fingerprint is unchanged (~1.0). Commodity-NIC noise does not soften it, because the over-coding is structural — deterministic ray-traced geometry/materials — not a noise-floor effect. Thermal/phase noise can't blur a per-floor geometry signature. (Caveat: on only 2 very dissimilar floors, floor-ID is saturated at ~1.0 even clean; the sensitive test is the 4-floor static setup where clean floor-ID was 0.95 — a proper softening test would re-run that under impairment.)
  2. The impairment degrades occupancy (retention 0.71→0.62, within-floor 0.36→0.31) — noise erodes the fragile count signal, moving retention away from the real 0.73, not toward it.

Conclusion / corrected refit target. Hardware impairment is the wrong knob for the environment over-coding: it answers the orthogonal "does occupancy survive a commodity NIC?" question (answer: it degrades) but leaves the structural fingerprint intact. To soften the synthetic environment signature toward the real 0.83 the sim needs structural/material nuisance — furniture-layout variation, wall-material randomization, multi-scene averaging — not measurement noise. That reframes the exp-csi-calibration refit from a noise-model fit to a scene-diversity fit. Figure: operanet_impairment.png. (Feature set here is the 4-dim raw-tensor stat, so absolute occupancy numbers differ from the links.parquet-based 0.57; the clean-vs-impaired delta is the valid signal.)

Scene-diversity nuisance — the right knob (2026-07-13)

Implemented the corrected refit via SceneOverrides.furniture (host-side box-scatterer injection, no image rebuild): per-run randomized metal-box layouts (5 layouts/floor, 6 boxes, positions inside each floor's rooms, meters per the cm→m gotcha) on the 4-floor static setup, n_agents=0. Floor-ID (leave-one-run-out) over the furniture-diverse runs:

setup environment-ID (3 floors, chance 0.33)
empty scene (deterministic baseline) ~0.97–1.0
+ impairment layer (SNR 20 dB) ~1.0 (no change)
+ scene-diversity (metal furniture) 0.67 ± 0.47
real room-ID 0.83

Scene diversity blurs the fingerprint; measurement noise does not. Per-run furniture randomization drops synthetic environment-ID from the deterministic ~1.0 to 0.67 — the over-coding is structural, softened by scene/material variability, not hardware impairment. Metal furniture is aggressive (may overshoot past the real 0.83) → furniture material/density is the tunable to calibrate to 0.83, making exp-csi-calibration a scene-diversity fit not a noise fit. Caveats: resplan-7421's 5 runs failed (metal box clipped a wall on the small floor), so 3 floors; fold std 0.47 → directional. Figure: operanet_scene_diversity.png.