Makes it easier to work on an individual part in isolation. Also change the vscode devconsole visualiser to one that works with includes
raspbot_v2
ROS 2 robot platform based on the Yahboom Raspbot V2. Multiple services run as Docker containers, coordinated by Docker Compose.
Sub-projects
| Directory | Description |
|---|---|
| robot/ | Differential-drive motor control, pan/tilt camera, and ultrasonic range sensor |
| lidar/ | RPLIDAR A1 laser scanner |
| oled/ | OLED display dashboard |
| wifi/ | Wi-Fi hotspot fallback manager |
| camera_publisher/ | V4L2 camera → ROS 2 topic publisher |
| webrtc_streamer/ | WebRTC browser stream server |
| webui/ | Browser-based robot controller |
| ansible/ | Provisioning playbook for the Raspberry Pi |
Setting up the robot
1. Flash Raspberry Pi OS
Use the Raspberry Pi Imager to write Raspberry Pi OS (64-bit, Lite recommended) to a microSD card.
Before writing, open Advanced options (⚙) and configure:
| Setting | Value |
|---|---|
| Hostname | raspbot-v2.local |
| SSH | Enabled |
| Username / Password | Your preferred credentials |
| Wi-Fi | Your network SSID and password (if not using Ethernet) |
Write the image, insert the card, and power on the Pi. Once it is reachable on the network (test with ping raspbot-v2.local), proceed to the next step.
2. Provision with Ansible
The ansible/ directory contains a playbook that handles the remaining setup (enabling SPI, installing Docker). See ansible/README.md for full instructions.
Building
Prerequisites
-
Docker with BuildKit enabled
-
For cross-compilation from an amd64 host, register QEMU user-space emulation once:
docker run --rm --privileged tonistiigi/binfmt --install arm64
Build all images
docker compose build
Or build a single service:
docker compose build robot
docker compose build lidar
Deploying
Pipe images directly to the target over SSH — no intermediate file or registry needed:
# Upload all images
docker save $(docker compose config --images) | ssh <user>@raspbot-v2.local docker load
# Upload a single image
docker save raspbot_v2_oled:latest | ssh <user>@raspbot-v2.local docker load
docker compose config --images resolves all image names from the compose file, including any environment variable substitutions.
Then copy the compose file and any .env to the target:
scp docker-compose.yml <user>@raspbot-v2.local:~/
Replace <user> with the username configured in ansible/inventory.ini.
Launching
Start everything
docker compose up
To run in the background:
docker compose up -d
docker compose logs -f # follow logs
docker compose down # stop and remove containers
Environment variables
Create a .env file alongside docker-compose.yml to override defaults:
ROS_DOMAIN_ID=0
LIDAR_PORT=/dev/ttyUSB0
LIDAR_FRAME_ID=laser
WIFI_SSID=MyNetwork
| Variable | Default | Description |
|---|---|---|
ROS_DOMAIN_ID |
0 |
ROS 2 domain — must match on all nodes |
LIDAR_PORT |
/dev/ttyUSB0 |
Host device node for the RPLIDAR |
LIDAR_FRAME_ID |
laser |
frame_id in published LaserScan messages |
WIFI_SSID |
(empty) | Target SSID; if unset the Wi-Fi container creates a hotspot immediately |
HOTSPOT_SSID |
raspbot-hotspot |
Fallback hotspot SSID |
HOTSPOT_PASSWORD |
raspbot1234 |
Fallback hotspot passphrase |
Project layout
.
├── docker-compose.yml
├── docker-entrypoint.sh
├── robot/ # Motor controller, pan/tilt, ultrasonic
├── lidar/ # RPLIDAR A1
├── oled/ # OLED display dashboard
├── wifi/ # Wi-Fi hotspot fallback
├── camera_publisher/ # V4L2 camera → ROS 2 topic
├── webrtc_streamer/ # WebRTC browser stream
├── webui/ # Browser-based controller UI
└── ansible/ # Raspberry Pi provisioning