sl-webui 57420807ca feat(webui): live camera viewer — multi-stream + detection overlays (Issue #177)
UI (src/hooks/useCamera.js, src/components/CameraViewer.jsx):
  - 7 camera sources: front/left/rear/right CSI, D435i RGB/depth, panoramic
  - Compressed image subscription via rosbridge (sensor_msgs/CompressedImage)
  - Client-side 15fps gate (drops excess frames, reduces JS pressure)
  - Per-camera FPS indicator with quality badge (FULL/GOOD/LOW/NO SIGNAL)
  - Detection overlays: face boxes + names (/social/faces/detections),
    gesture icons (/social/gestures), scene object labels + hazard colours
    (/social/scene/objects); overlay mode selector (off/faces/gestures/objects/all)
  - 360° panoramic equirect viewer with mouse/touch drag azimuth pan
  - Picture-in-picture: up to 3 pinned cameras via ⊕ button
  - One-click recording (MediaRecorder → MP4/WebM download)
  - Snapshot to PNG with detection overlay composite + timestamp watermark
  - Cameras tab added to TELEMETRY group in App.jsx

Jetson (rosbridge bringup):
  - rosbridge_params.yaml: whitelist + /camera/depth/image_rect_raw/compressed,
    /camera/panoramic/compressed, /social/faces/detections,
    /social/gestures, /social/scene/objects
  - rosbridge.launch.py: D435i colour republisher (JPEG 75%) +
    depth republisher (compressedDepth/PNG16 preserving uint16 values)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 10:47:01 -05:00

72 lines
3.7 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# rosbridge_params.yaml — rosbridge_websocket server configuration
#
# WebSocket endpoint: ws://<jetson-ip>:9090
# Browser client lib: roslibjs (cdn.jsdelivr.net/npm/roslib)
#
# Topic whitelist limits bandwidth and prevents unintended exposure.
# Glob patterns follow Python fnmatch: * matches everything (incl. /).
#
# Bandwidth budget (worst case, all subscriptions active):
# /map ~100 KB/update × 0.2 Hz = ~20 KB/s
# /scan ~5 KB/scan × 5.5 Hz = ~28 KB/s
# /saltybot/imu ~0.2 KB/msg × 50 Hz = ~10 KB/s
# /tf ~1 KB/msg × 10 Hz = ~10 KB/s
# 4× cameras ~20 KB/frame × 5 Hz = ~400 KB/s (JPEG quality 75)
# ─────────────────────────────────────────────────────
# Total ~470 KB/s ≈ 3.8 Mbps
#
# Use throttle_rate in roslibjs subscribe() calls to cap per-topic rates:
# viewer.subscribe({ topic: '/map', throttle_rate: 5000 }) // 0.2 Hz
rosbridge_websocket:
ros__parameters:
# ── Network ──────────────────────────────────────────────────────────────
port: 9090
host: "0.0.0.0" # bind all interfaces (Jetson LAN + USB-C)
address: ""
# ── Authentication ────────────────────────────────────────────────────────
authenticate: false # no auth on local network; enable if exposed
# ── Message size ──────────────────────────────────────────────────────────
# OccupancyGrid /map can exceed 1 MB for large environments.
max_message_size: 10000000 # 10 MB
# ── Topic/service/param whitelists ────────────────────────────────────────
# JSON-encoded glob list. "*" in a glob matches any chars including "/".
# Only topics matching at least one pattern are accessible to clients.
topics_glob: >-
["/map",
"/person/target",
"/person/detections",
"/camera/*/image_raw/compressed",
"/camera/depth/image_rect_raw/compressed",
"/camera/panoramic/compressed",
"/social/faces/detections",
"/social/gestures",
"/social/scene/objects",
"/scan",
"/cmd_vel",
"/saltybot/imu",
"/saltybot/balance_state",
"/tf",
"/tf_static"]
services_glob: "[]" # no service calls via WebSocket
params_glob: "[]" # no parameter access via WebSocket
# ── Connection management ─────────────────────────────────────────────────
# Time (s) before dropping a client that stops responding.
unregister_timeout: 10.0
# Fragment timeout: max seconds to wait for all fragments of a large message.
fragment_timeout: 600
# Delay between consecutive outgoing messages (ms). 0 = unlimited.
# Set > 0 (e.g. 10) if browser JS event loop is overwhelmed.
delay_between_messages: 0
# ── Logging ───────────────────────────────────────────────────────────────
# Set to true to log every publish/subscribe call (verbose, dev only).
bson_only_mode: false