Asimov API set up
End-to-end setup for running the Asimov API service on a Raspberry Pi.
Running the Asimov API on a Raspberry Pi
End-to-end setup for a Raspberry Pi running the Asimov API service. This walks through installing the service, finding your audio/video devices, and launching against a LiveKit server on your laptop.
Looking for the API itself (commands, telemetry, joint order)? See the Asimov API manual.
1. Prereqs
- A Raspberry Pi running a recent Debian/Ubuntu image.
- Python 3.12 or newer. Bookworm ships Python 3.11, which will fail the
install — use
uvor pyenv to get 3.12. - System libraries (Debian/Ubuntu):
sudo apt update sudo apt install -y portaudio19-dev libgl1 libglib2.0-0 # protobuf-compiler is only needed if you edit .proto files - A USB or CSI camera and a USB audio device (mic + speaker — same device or separate is fine).
2. Install
git clone <repo-url> ~/asimov-api
cd ~/asimov-api
make install # creates .venv and installs the packageIf python on your $PATH is not 3.12, create the venv explicitly with uv:
uv venv --python 3.12 ~/asimov-api/.venv
~/asimov-api/.venv/bin/pip install -e .The protobuf files are committed, so you don't need make proto unless you've
edited proto/*.proto.
3. Find your camera
# List video devices
v4l2-ctl --list-devices
# For each /dev/videoN, check whether it exposes a usable format
for N in $(ls /dev/video* | sed 's|/dev/video||'); do
echo "=== /dev/video$N ==="
v4l2-ctl -d /dev/video$N --list-formats 2>/dev/null | head -5
doneNote the index N of the device that lists at least one format (often
MJPG or YUYV). You'll pass it as --camera-device N.
4. Find your audio devices
# Speakers / playback
aplay -l
# Microphones / capture
arecord -lNote the human-readable name of your USB audio device (e.g. ReSpeaker,
XVF3800, USB Audio). You'll pass that name — or a substring of it — to
--mic-device and --speaker-device. ALSA's default device often doesn't
work for USB capture, so it's safer to name the device explicitly.
Sample rate gotcha
Some cheap USB audio devices only accept 16 kHz output. If you hear
[Errno -9997] Invalid sample rate when the speaker starts, pass
--speaker-sample-rate 16000.
Software volume (optional)
If your USB device has no hardware mixer (check amixer -c <card>),
add a software volume plugin in ~/.asoundrc:
pcm.your_softvol {
type softvol
slave.pcm "hw:CARD=YourDevice,DEV=0"
control.name "SoftMaster"
control.card "YourDevice"
}Replace YourDevice with your card's ID (from aplay -l). Then use
--speaker-device your_softvol and adjust with:
amixer -D your_softvol sset SoftMaster 80%5. Launch
The service connects to a LiveKit server for video/audio/teleop and to the motor firmware over UDP.
On your laptop, start LiveKit and mint a viewer token. The
LIVEKIT_ENABLE_DATA_TRACKS=true env var is required — telemetry rides on a
LiveKit data track, which --dev mode doesn't enable by default:
LIVEKIT_ENABLE_DATA_TRACKS=true livekit-server --dev --bind 0.0.0.0
lk token create --api-key devkey --api-secret secret \
--identity viewer --room robot --join --valid-for 24hNote your laptop's LAN IP. On the Raspberry Pi:
env PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python PYTHONPATH=~/asimov-api/src \
~/asimov-api/.venv/bin/python -m edge.main \
--firmware-host <robot-compute-ip-or-127.0.0.1> \
--livekit-url ws://<laptop-lan-ip>:7880 \
--livekit-key devkey --livekit-secret secret \
--serial MENLO-0001 --force-cloud \
--mic-device <your-mic-name> \
--speaker-device <your-speaker-name> \
--camera-device <N>Use --firmware-host 127.0.0.1 if you aren't running the motor firmware yet
— UDP goes nowhere, but the media pipeline (camera/mic/speaker) still works.
--force-cloud is required — it bypasses BLE provisioning and tells the
service to start LiveKit immediately.
6. Verify
Tail the logs:
journalctl -t edge -f # if running as a systemd service
# otherwise: just watch the terminal you launched it inLook for these tags coming up cleanly:
[MAIN]startup banner[CAMERA]opened your/dev/videoNwith a non-zero resolution[MICROPHONE]and[SPEAKER]opened at their sample rates[CLOUD]connected to your LiveKit URL and joined the room[FW_LINK]firstRobotStatearrived (only if firmware is up)
In a viewer connected to the same LiveKit room, you should see the camera feed, hear the mic audio, and be able to send audio back to the speaker.
7. Stop
pkill -f "edge.main"Troubleshooting
| Symptom | Likely cause |
|---|---|
pip install fails on requires-python | Python 3.11 active — use uv venv --python 3.12 … |
pyaudio build fails | Missing portaudio19-dev |
| Camera opens but no frames | Wrong --camera-device index, or /dev/videoN is the metadata node — pick one that lists a video format |
[Errno -9997] Invalid sample rate | USB audio device only supports 16 kHz — add --speaker-sample-rate 16000 |
| No mic input but speaker works | Default device has 0 input channels — pass --mic-device <name> explicitly |
| Viewer connects but no video/audio | --force-cloud not passed, or LiveKit URL/key/secret wrong |
How is this guide?