Initial web ui and control for robot

This commit is contained in:
2026-04-30 21:35:18 +00:00
parent d64e1c24c8
commit 91f5f4d3ab
23 changed files with 2688 additions and 4 deletions
+124
View File
@@ -0,0 +1,124 @@
# 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
```bash
./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 `/ws` to 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:
```bash
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):
```bash
VITE_WEBRTC_WS_URL=ws://raspbot-v2.local:8443 ./webui/dev.sh
```
---
## Production (Docker Compose)
### Build
```bash
docker compose build webui
```
To bake a specific WebRTC server URL into the bundle:
```bash
VITE_WEBRTC_WS_URL=ws://raspbot-v2.local:8443 docker compose build webui
```
### Run
```bash
docker compose up webui
```
Or start everything together:
```bash
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) |