feat: WebUI gimbal control panel (Issue #551) #557

Merged
sl-jetson merged 1 commits from sl-webui/issue-551-gimbal-webui into main 2026-03-14 11:36:50 -04:00
Collaborator

Summary

Implements Issue #551 — gimbal control panel with live camera preview.

Deliverables

Standalone page (ui/gimbal_panel.html + gimbal_panel.js + gimbal_panel.css):

  • No build step — serve the ui/ directory directly
  • roslib.js from CDN, configurable WebSocket URL (persisted in localStorage)
  • 2-D canvas pan/tilt joystick: click-drag and touch (pointer capture API)
  • Live camera stream: base64 CompressedImage → <img> tag, FPS badge overlay
  • Camera selector: FRONT / REAR / LEFT / RIGHT
  • Angle overlay on video feed (updates from /gimbal/state)
  • Preset buttons: CENTER / LEFT / RIGHT / UP / DOWN
  • Home button (0° / 0°)
  • Person-tracking toggle → publishes std_msgs/Bool
  • Mobile-responsive CSS grid (2-col desktop → 1-col mobile)

React component (ui/social-bot/src/components/GimbalPanel.jsx):

  • Same features, wired into shared rosbridge connection from App.jsx
  • Added as TELEOP → Gimbal tab (sits next to Drive tab from #534)
  • flex-col full-height layout, mobile-responsive lg: breakpoint

ROS Topics

Topic Type Direction
/gimbal/cmd geometry_msgs/Vector3 (x=pan°, y=tilt°) publish
/gimbal/state geometry_msgs/Vector3 subscribe
/gimbal/tracking_enabled std_msgs/Bool publish
/camera/<name>/image_raw/compressed sensor_msgs/CompressedImage subscribe

Test plan

  • Open ui/gimbal_panel.html in browser, connect to rosbridge
  • Click/drag on pad — verify /gimbal/cmd published with correct pan/tilt
  • Touch-drag on mobile — verify touch pointer capture works
  • Camera feed appears when /camera/front/image_raw/compressed is active
  • Switch camera selector — feed switches topic
  • Click each preset — verify angles sent
  • Home button → (0°, 0°) sent
  • Tracking toggle → /gimbal/tracking_enabled true/false
  • State feedback updates ACTUAL PAN/TILT display
  • React tab: TELEOP → Gimbal works in dashboard

🤖 Generated with Claude Code

## Summary Implements Issue #551 — gimbal control panel with live camera preview. ### Deliverables **Standalone page** (`ui/gimbal_panel.html` + `gimbal_panel.js` + `gimbal_panel.css`): - No build step — serve the `ui/` directory directly - roslib.js from CDN, configurable WebSocket URL (persisted in localStorage) - 2-D canvas pan/tilt joystick: click-drag and touch (pointer capture API) - Live camera stream: base64 CompressedImage → `<img>` tag, FPS badge overlay - Camera selector: FRONT / REAR / LEFT / RIGHT - Angle overlay on video feed (updates from /gimbal/state) - Preset buttons: CENTER / LEFT / RIGHT / UP / DOWN - Home button (0° / 0°) - Person-tracking toggle → publishes std_msgs/Bool - Mobile-responsive CSS grid (2-col desktop → 1-col mobile) **React component** (`ui/social-bot/src/components/GimbalPanel.jsx`): - Same features, wired into shared rosbridge connection from App.jsx - Added as **TELEOP → Gimbal** tab (sits next to Drive tab from #534) - flex-col full-height layout, mobile-responsive lg: breakpoint ### ROS Topics | Topic | Type | Direction | |---|---|---| | `/gimbal/cmd` | `geometry_msgs/Vector3` (x=pan°, y=tilt°) | publish | | `/gimbal/state` | `geometry_msgs/Vector3` | subscribe | | `/gimbal/tracking_enabled` | `std_msgs/Bool` | publish | | `/camera/<name>/image_raw/compressed` | `sensor_msgs/CompressedImage` | subscribe | ## Test plan - [ ] Open `ui/gimbal_panel.html` in browser, connect to rosbridge - [ ] Click/drag on pad — verify `/gimbal/cmd` published with correct pan/tilt - [ ] Touch-drag on mobile — verify touch pointer capture works - [ ] Camera feed appears when `/camera/front/image_raw/compressed` is active - [ ] Switch camera selector — feed switches topic - [ ] Click each preset — verify angles sent - [ ] Home button → (0°, 0°) sent - [ ] Tracking toggle → `/gimbal/tracking_enabled` true/false - [ ] State feedback updates ACTUAL PAN/TILT display - [ ] React tab: TELEOP → Gimbal works in dashboard 🤖 Generated with Claude Code
sl-webui added 1 commit 2026-03-14 10:29:56 -04:00
Adds a full gimbal control panel with live camera preview:

Standalone page (ui/gimbal_panel.html + .js + .css):
- Self-contained HTML page, no build step, served directly
- roslib.js via CDN, connects to rosbridge WebSocket
- 2-D canvas pan/tilt pad: click-drag + touch pointer capture
- Live camera stream (front/rear/left/right selector, base64 CompressedImage)
- FPS badge + angle overlay on video feed
- Preset positions: CENTER / LEFT / RIGHT / UP / DOWN
- Home button (0° / 0°)
- Person-tracking toggle → /gimbal/tracking_enabled
- Current angle display from /gimbal/state feedback
- WS URL persisted in localStorage

React component (GimbalPanel.jsx) + App.jsx integration:
- Same features in dashboard — TELEOP group → Gimbal tab
- Shares rosbridge connection from parent
- Mobile-responsive: stacks vertically on mobile, side-by-side on lg+

ROS topics:
  PUB /gimbal/cmd              geometry_msgs/Vector3
  SUB /gimbal/state            geometry_msgs/Vector3
  PUB /gimbal/tracking_enabled std_msgs/Bool
  SUB /camera/*/image_raw/compressed sensor_msgs/CompressedImage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sl-jetson merged commit df6b79d676 into main 2026-03-14 11:36:50 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: seb/saltylab-firmware#557
No description provided.