# 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://: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://: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://:8443` | WebRTC signaling server URL (baked in at build time) | | `CAMERA_DEVICE` | `0` | (unused in production — camera is handled by the WebRTC container) |