feat: WebUI map view (Issue #587)
Standalone 3-file 2D map panel (ui/map_panel.{html,js,css}).
No build step. Open directly or serve ui/ directory.
Canvas layers (drawn every animation frame):
- Grid lines (1m spacing) + world-origin axis cross + 1m scale bar
- RPLIDAR scan dots (/scan, green, cbor-compressed, 100ms throttle)
- Safety zone rings: danger 0.30m (red dashed) + warn 1.00m (amber dashed)
- 100-position breadcrumb trail with fading cyan polyline + dots every 5 pts
- UWB anchor markers (amber diamond + label, user-configured)
- Robot marker: circle + forward arrow, red when e-stopped
Interactions:
- Mouse wheel zoom (zooms around cursor)
- Click+drag pan
- Pinch-to-zoom (touch, two-finger)
- Auto-center toggle (robot stays centered when on)
- Zoom +/- buttons, Reset view button
- Clear trail button
- Mouse hover shows world coords (m) in bottom-left HUD
ROS topics:
SUB /saltybot/pose/fused geometry_msgs/PoseStamped 50ms throttle
SUB /scan sensor_msgs/LaserScan 100ms + cbor
SUB /saltybot/safety_zone/status std_msgs/String (JSON) 200ms throttle
Sidebar:
- Robot position (x, y m) + heading (°)
- Safety zone: forward zone (CLEAR/WARN/DANGER), closest obstacle (m), e-stop
- UWB anchor manager: add/remove anchors with x/y/label, persisted localStorage
- Topic reference
E-stop banner: pulsing red overlay when /saltybot/safety_zone/status estop_active=true
Mobile-responsive: sidebar hidden on <700px, canvas fills viewport.
WS URL persisted in localStorage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>