Raspbot Web UI
Browser-based controller for the Raspbot V2. Displays a live WebRTC camera feed and provides keyboard / on-screen controls for robot movement and camera pan/tilt.
Architecture
Browser
│
├─── WebSocket /ws ──────────► FastAPI backend (port 8080)
│ │
│ └─ rclpy node
│ ├─ publishes /cmd_vel
│ ├─ publishes /joint_command
│ ├─ subscribes /joint_states
│ └─ subscribes /ultrasonic/range
│
└─── WebSocket ws://<host>:8443 ──► GStreamer WebRTC server (separate container)
The FastAPI backend is the ROS 2 node — no rosbridge needed. The Vite/React frontend is built into static files and served directly by FastAPI in production.
ROS topics
| Direction | Topic | Type |
|---|---|---|
| Publish | /cmd_vel |
geometry_msgs/Twist |
| Publish | /joint_command |
sensor_msgs/JointState (joints: pan, tilt) |
| Subscribe | /joint_states |
sensor_msgs/JointState |
| Subscribe | /ultrasonic/range |
sensor_msgs/Range |
Controls
| Input | Action |
|---|---|
| W / ↑ | Drive forward |
| S / ↓ | Drive backward |
| A / ← | Turn left |
| D / → | Turn right |
| Pan slider | Camera pan (±90°) |
| Tilt slider | Camera tilt (−30° to +55°) |
| Centre button | Return camera to home position |
The D-pad buttons on screen mirror the keyboard controls and work on touch devices.
Development (devcontainer)
Running locally in the devcontainer gives a fast edit → reload loop without needing to rebuild Docker images.
Prerequisites
Rebuild the devcontainer at least once after the Node.js addition to .devcontainer/Dockerfile was made — VS Code will prompt you, or run Dev Containers: Rebuild Container from the command palette.
Running
./webui/dev.sh
Then open http://localhost:5173.
The script will:
- Create a Python venv at
webui/backend/.venv(first run only) - Install backend and frontend dependencies
- Start the FastAPI backend on port 8080
- Start the Vite dev server on port 5173, proxying
/wsto the backend
Both processes are stopped together with Ctrl+C.
ROS domain ID
The devcontainer uses ROS_DOMAIN_ID=42 by default, but the robot and lidar containers default to 0. Override when running the script to match whichever domain the robot is on:
ROS_DOMAIN_ID=0 ./webui/dev.sh
WebRTC camera
The camera feed connects to the GStreamer signaling server at ws://<hostname>:8443 by default. If your WebRTC container runs on a different host or port, set VITE_WEBRTC_WS_URL before starting the frontend (it is baked into the bundle at build time, but the dev server reads it from the shell):
VITE_WEBRTC_WS_URL=ws://raspbot-v2.local:8443 ./webui/dev.sh
Production (Docker Compose)
Build
docker compose build webui
To bake a specific WebRTC server URL into the bundle:
VITE_WEBRTC_WS_URL=ws://raspbot-v2.local:8443 docker compose build webui
Run
docker compose up webui
Or start everything together:
docker compose up
The web UI is served on port 8080 of the host.
Configuration
| Variable | Default | Description |
|---|---|---|
ROS_DOMAIN_ID |
0 |
ROS 2 DDS domain — must match the robot container |
VITE_WEBRTC_WS_URL |
ws://<page-hostname>:8443 |
WebRTC signaling server URL (baked in at build time) |
CAMERA_DEVICE |
0 |
(unused in production — camera is handled by the WebRTC container) |