fix: live demo static pose & inaccurate sensing data (issue #86)

- Docker default changed from --source simulated to --source auto
  (auto-detects ESP32 on UDP 5005, falls back to simulation)
- Pose derivation now driven by real sensing features: motion_band_power,
  breathing_band_power, variance, dominant_freq_hz, change_points
- Temporal feature extraction: 100-frame circular buffer, Goertzel
  breathing rate estimation (0.1-0.5 Hz), frame-to-frame L2 motion
  detection, SNR-based signal quality metric
- Signal field driven by subcarrier variance spatial mapping instead
  of fixed animation circle
- UI data source indicators: LIVE/RECONNECTING/SIMULATED banner on
  sensing tab, estimation mode badge on live demo tab
- Setup guide panel explaining ESP32 count requirements for each
  capability level (1x: presence, 3x: localization, 4x+: full pose)
- Tick rate improved from 500ms to 100ms (2fps to 10fps)
- Fixed Option<f64> division bug from PR #83
- ADR-035 documents all decisions

Closes #86

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv
2026-03-02 10:54:07 -05:00
parent fdc7142dfa
commit 8166d8d822
11 changed files with 1647 additions and 336 deletions
+51
View File
@@ -1754,6 +1754,11 @@ canvas {
background: var(--color-error);
}
.sensing-dot.reconnecting {
background: var(--color-warning);
animation: pulse 1.5s infinite;
}
.sensing-source {
margin-left: auto;
font-size: var(--font-size-xs);
@@ -1761,6 +1766,52 @@ canvas {
font-family: var(--font-family-mono);
}
.sensing-about-text {
margin: 0;
font-size: 12px;
color: #aaa;
line-height: 1.5;
}
.sensing-about-text strong {
color: #ccc;
}
/* Data-source status banner (live / reconnecting / simulated) */
.sensing-source-banner {
display: block;
width: 100%;
padding: var(--space-8) var(--space-12);
margin-bottom: var(--space-12);
border-radius: var(--radius-md);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
font-family: var(--font-family-mono);
text-align: center;
letter-spacing: 0.06em;
text-transform: uppercase;
box-sizing: border-box;
}
.sensing-source-live {
background: rgba(0, 204, 136, 0.15);
border: 1px solid #00cc88;
color: #00cc88;
}
.sensing-source-reconnecting {
background: rgba(255, 180, 0, 0.12);
border: 1px solid var(--color-warning);
color: var(--color-warning);
animation: pulse 1.5s infinite;
}
.sensing-source-simulated {
background: rgba(255, 60, 60, 0.12);
border: 1px solid var(--color-error);
color: var(--color-error);
}
/* Big RSSI value */
.sensing-big-value {
font-size: var(--font-size-3xl);