Skip to content

fix: WebSocket race condition, data source indicators, auto-start pose detection#96

Merged
ruvnet merged 3 commits intomainfrom
feat/rvf-training-ui-improvements
Mar 2, 2026
Merged

fix: WebSocket race condition, data source indicators, auto-start pose detection#96
ruvnet merged 3 commits intomainfrom
feat/rvf-training-ui-improvements

Conversation

@ruvnet
Copy link
Owner

@ruvnet ruvnet commented Mar 2, 2026

Summary

  • Fix WebSocket onOpen race conditionsetupEventHandlers() replaced ws.onopen after the socket was already open, so the pose service never received the "connected" signal and never processed incoming frames. Now manually triggers the connected path when the socket is already open.
  • Add 4-state data source indicators across Dashboard, Sensing, and Live Demo tabs: LIVE (ESP32), SIMULATED (server without hardware), RECONNECTING, OFFLINE (server unreachable)
  • Hot-plug ESP32 auto-detection in the Rust sensing server — runs both UDP listener and simulation in auto mode, switches based on ESP32_TIMEOUT (3s)
  • Auto-start pose detection when a backend is reachable (live or server-simulated)
  • Hide duplicate controls in PoseDetectionCanvas when enableControls: false
  • Add standalone Demo button in LiveDemoTab for offline animated demo (no server needed)

Files Changed

  • ui/services/websocket.service.js — Fix onOpen race condition
  • ui/services/sensing.service.js — 4-state data source tracking with callbacks
  • ui/components/LiveDemoTab.js — Auto-start, source banner, Demo button
  • ui/components/DashboardTab.js — Data source indicator
  • ui/components/SensingTab.js — Data source indicator
  • ui/components/PoseDetectionCanvas.js — Hide controls when disabled
  • ui/style.css — Banner and button styles
  • ui/index.html — Sensing service script tag
  • rust-port/.../sensing-server/src/main.rs — Hot-plug ESP32 detection
  • docs/adr/ADR-036-rvf-training-pipeline-ui.md — Updated status

Test plan

  • Verified ESP32 live data flows (source: esp32)
  • Verified pose data renders with real keypoints
  • Verified WebSocket connection establishes (status shows "Connected")
  • Verify Dashboard/Sensing/LiveDemo all show correct data source state
  • Verify auto-start triggers when server is running
  • Verify Demo button runs offline animated demo without server

🤖 Generated with claude-flow

ruvnet added 3 commits March 2, 2026 11:39
Implement full model training, management, and inference pipeline:

Backend (Rust):
- recording.rs: CSI recording API (start/stop/list/download/delete)
- model_manager.rs: RVF model loading, LoRA profile switching, model library
- training_api.rs: Training API with WebSocket progress streaming, simulated
  training mode with realistic loss curves, auto-RVF export on completion
- main.rs: Wire new modules, recording hooks in all CSI paths, data dirs

UI (new components):
- ModelPanel.js: Dark-mode model library with load/unload, LoRA dropdown
- TrainingPanel.js: Recording controls, training config, live Canvas charts
- model.service.js: Model REST API client with events
- training.service.js: Training + recording API client with WebSocket progress

UI (enhancements):
- LiveDemoTab: Model selector, LoRA profile switcher, A/B split view toggle,
  training quick-panel with 60s recording shortcut
- SettingsPanel: Full dark mode conversion (issue #92), model configuration
  (device, threads, auto-load), training configuration (epochs, LR, patience)
- PoseDetectionCanvas: 10-frame pose trail with ghost keypoints and motion
  trajectory lines, cyan trail toggle button
- pose.service.js: Model-inference confidence thresholds

UI (plumbing):
- index.html: Training tab (8th tab)
- app.js: Panel initialization and tab routing
- style.css: ~250 lines of training/model panel dark-mode styles

191 Rust tests pass, 0 failures. Closes #92.

Refs: ADR-036, #93

Co-Authored-By: claude-flow <ruv@ruv.net>
Training pipeline (training_api.rs):
- Replace simulated training with real signal-based training loop
- Load actual CSI data from .csi.jsonl recordings or live frame history
- Extract 180 features per frame: subcarrier amplitudes, temporal variance,
  Goertzel frequency analysis (9 bands), motion gradients, global stats
- Train calibrated linear CSI-to-pose mapping via mini-batch gradient descent
  with L2 regularization (ridge regression), Xavier init, cosine LR decay
- Self-supervised: teacher targets from derive_pose_from_sensing() heuristics
- Real validation metrics: MSE and PCK@0.2 on 80/20 train/val split
- Export trained .rvf with real weights, feature normalization stats, witness
- Add infer_pose_from_model() for live inference from trained model
- 16 new tests covering features, training, inference, serialization

UI fixes:
- Fix double-URL bug in model.service.js and training.service.js
  (buildApiUrl was called twice — once in service, once in apiService)
- Fix route paths to match Rust backend (/api/v1/train/*, /api/v1/recording/*)
- Fix request body formats (session_name, nested config object)
- Fix top-level await in LiveDemoTab.js blocking module graph
- Dynamic imports for ModelPanel/TrainingPanel in app.js
- Center nav tabs with flex-wrap for 8-tab layout

Co-Authored-By: claude-flow <ruv@ruv.net>
…art pose detection

- Fix WebSocket onOpen race condition in websocket.service.js where
  setupEventHandlers replaced onopen after socket was already open,
  preventing pose service from receiving connection signal
- Add 4-state data source indicator (LIVE/SIMULATED/RECONNECTING/OFFLINE)
  across Dashboard, Sensing, and Live Demo tabs via sensing.service.js
- Add hot-plug ESP32 auto-detection in sensing server (auto mode runs
  both UDP listener and simulation, switches on ESP32_TIMEOUT)
- Auto-start pose detection when backend is reachable
- Hide duplicate PoseDetectionCanvas controls when enableControls=false
- Add standalone Demo button in LiveDemoTab for offline animated demo
- Add data source banner and status styling

Co-Authored-By: claude-flow <ruv@ruv.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant