Getting started¶
This is the path from a box of parts to a robot that maps a room and drives it. Steps 1 and 2 run anywhere; from step 3 on you need the hardware, so they run on the Pi.
If you want to try the software before building anything, skip to Simulation — it needs no hardware and runs the same launch files.
Prerequisites¶
- The robot, assembled. Printing, assembly and wiring are covered in Printing & assembly and Wiring & power; the parts list is the BOM.
- A Raspberry Pi 5 running 64-bit Linux. Ubuntu 24.04 and Raspberry Pi OS
Bookworm both work — the
Raspberry Pi Imager route is
Raspberry Pi OS (other) → Raspberry Pi OS Lite. To hand a clean Pi its
identity, network and build in one shot instead, render a cloud-init image
with
pixi run provision(see the fleet runbook). - pixi installed. Everything else — ROS 2 Jazzy, Nav2, the drivers — is pulled in by pixi. There is no system ROS install.
1. Clone¶
Forgot --recurse-submodules? pixi run submodules fetches them afterwards.
2. Build¶
Artifacts land in build/, install/ and log/, all git-ignored. If a build
complains about CMakeCache.txt naming the wrong source directory (a path
rename, usually), delete build/ and build again.
Built on your workstation? Copy it to the Pi with pixi run sync, or
pixi run -e dev sync-watch to keep it copying on every save. Launch files,
config and Python go live without a rebuild (colcon --symlink-install); only
C++ needs pixi run build again on the Pi.
3. Set up the Pi¶
One time, on the robot:
That installs the udev rules that give the hardware stable names
(/dev/mote_servos, /dev/mote_lidar, /dev/mote_camera), disables WiFi power
save, and installs the systemd units. The units are installed but not
enabled — autostart would flatten the battery on a desk. Opt in when the
robot lives on the floor:
See Bringup & reliability for what those services do, and what the pre-flight self-check refuses to start without.
4. Configure the servos¶
The drive wheels are expected at servo IDs 7 (left) and 9 (right) at 1 Mbaud. Fresh Feetech STS3215 servos all ship as ID 1, so assign IDs before first use, connecting one servo at a time when prompted:
The servo bus tools cover the rest of the bus
utilities — pinging, swapping IDs, and calibrating velocity_scale.
The arm is on the same bus
An SO-101 arm's six servos share the wheels' bus at IDs 1–6, so it needs no extra electronics — and no udev rule of its own. A serial port has no kernel-level exclusion, so exactly one process may hold it, and that process is the controller manager. See the arm docs.
5. Map a space¶
The stack runs in two phases: build a map with SLAM, then drive it without.
pixi run mapping # bringup + SLAM
pixi run teleop # in another terminal: drive it around
pixi run save-map # save the map + posegraph into the active site
Instead of driving it yourself, pixi run explore covers the space
autonomously — run it on the Pi, so a WiFi drop cannot end the mission.
save-map writes an immutable map revision into the active site's floor, runs a
cleaning pass over it, and validates it. Sites, maps &
zones explains what a site bundle is, why maps are revisions,
and how to teach named places.
6. Drive the map¶
Send goals from RViz (pixi run rviz, which selects the dev environment), or connect a Foxglove desktop to
ws://<robot-id>:8765 — the bridge is part of the base bringup, and the shipped
layout has teleop, a map view and the pause control. Teleop
always wins over Nav2 without cancelling the mission; the
drive path explains the
arbitration.
Once places are named, missions become commands:
See Missions for the fetch and goto grammar.
At this point you have a working robot stack: maps, SLAM, Nav2, teleop and missions. From here:
- Perception turns the webcam into obstacles Nav2 can see and objects a mission can fetch — with the heavy models on an inference server rather than the Pi.
- The fleet layer puts several robots behind one dashboard, with enrollment, dispatch and a shared map registry.
- Simulation runs all of it against Gazebo.
Contributing¶
A pre-commit config handles hygiene checks, shell linting and Python error checking. Wire it in once per clone:
To work on these docs:
pixi run docs # live-reloading site on http://127.0.0.1:8000
pixi run docs-build # what CI runs, with --strict
AI aided contributions are welcome, but only if you can explain and vouch for every change.