Tutorial · Einsteiger · 1 Stunde
ROS 2 auf einem Raspberry Pi installieren und Workspace bauen
ROS 2 auf einem Raspberry Pi starten: das richtige OS wählen, aus apt installieren, einen colcon-Workspace bauen und Laptop und Roboter im WLAN finden.
Einführung
Nichts an ROS 2 ist schwierig, bis man es auf einem Roboter installiert – dann gehen drei unverbundene Dinge zugleich schief: Das Betriebssystem ist das falsche, der Workspace baut nicht in den Pi-Speicher, und der Laptop sieht die Nodes des Roboters nicht. Keines davon ist exakt ein ROS-Problem – weshalb die offiziellen Tutorials davor nicht warnen.
Das bringt von leerer SD-Karte zu ros2 topic list, das vom Laptop aus gegen Nodes auf dem Roboter funktioniert.
Das Betriebssystem wählen, nicht nur das Board
ROS-2-Binärpakete werden für Ubuntu gebaut, nicht Raspberry Pi OS. Raspberry Pi OS ist Debian-basiert – die apt-Pakete sind schlicht nicht da, und jeder Workaround – aus Quellen bauen, Docker, Conda – kostet Stunden, bevor man Robotercode geschrieben hat.
Also Ubuntu Server 24.04 LTS (64-Bit) installieren und auf die ROS-2-Version abstimmen, die dagegen gebaut ist. Zum Schreibzeitpunkt heißt diese Paarung Jazzy Jalisco, supportet bis 2029; die Installationsseite prüfen für das jeweils Aktuelle beim Lesen und den Namen durchgehend ersetzen.
Drei Dinge beim Flashen richtig machen:
- 64-Bit. ROS-2-arm64-Pakete existieren; armhf keine.
- Server, nicht Desktop. Ein Roboter hat keinen Monitor – und die Desktopumgebung kostet RAM, das man für Vision will.
- Pi 4 mit 4 GB oder Pi 5. Ein 2-GB-Board fährt ROS 2 gut, kompiliert es aber nicht bequem.
ROS 2 aus apt installieren
Die ROS-2-apt-Quelle hinzufügen, dann installieren. Das Repository-Setup ändert sich zwischen Releases – das hier ist also die Form statt Schnipsel zum Auswendiglernen:
sudo apt update && sudo apt install -y software-properties-common curl
sudo add-apt-repository universe
# Fetch and install the package that registers the ROS 2 apt repository and key.
export ROS_APT_SOURCE_VERSION=$(curl -s \
https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest \
| grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb \
"https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb"
sudo apt install -y /tmp/ros2-apt-source.deb
sudo apt update
sudo apt install -y ros-jazzy-ros-base ros-dev-tools
Beachte ros-base, nicht desktop. Das Desktop-Metapaket zieht RViz und Demo-GUIs heran, die ein headless Roboter nie fährt und deren Installation auf SD-Karte lange dauert. Visualisierung gehört auf deinen Laptop – dort das volle ros-jazzy-desktop installieren.
ros-dev-tools liefert colcon und rosdep. rosdep einmal initialisieren:
sudo rosdep init # skip if it says the file already exists
rosdep update
Erst den Underlay sourcen, dann dein Overlay
ROS 2 tut nichts, bis seine Umgebung gesourct ist – und hier lebt die meiste frühe Verwirrung.
source /opt/ros/jazzy/setup.bash
Das ist der Underlay – die installierte Distribution. Der eigene Workspace, einmal gebaut, ist ein Overlay obendrauf. Ein Overlay zu sourcen zieht implizit den Underlay mit, gegen den es gebaut wurde.
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
Den Underlay in .bashrc zu legen ist Standard und sicher. Dein Overlay dorthin zu legen ist eine Falle, die sich lohnt, früh zu meiden: An dem Tag, wo du zwei Workspaces hast oder gegen eine andere Distribution neu baust, startet jede neue Shell lautlos mit alter Umgebung – und du debuggst einen Nachmittag lang ein Phantom. Das Overlay explizit sourcen, pro Shell, im Terminal, das es braucht.
Einen Workspace und ein Paket erzeugen
Ein colcon-Workspace ist ein Verzeichnis mit src/ darin. Das ist die ganze Spezifikation.
mkdir -p ~/ros2_ws/src && cd ~/ros2_ws
ros2 pkg create --build-type ament_python --license Apache-2.0 my_robot
Dann bauen und darüberlegen:
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -y
colcon build --symlink-install
source install/setup.bash
--symlink-install verwenden. Es verlinkt deine Pythondateien in den Installationsraum statt sie zu kopieren – Codeeditieren wirkt also beim nächsten Start statt nach Neubau. Auf einem Pi, wo Neubau langsam ist, ist das der Unterschied zwischen Iterieren und Warten.
Nach dem Bau hält ~/ros2_ws build/, install/ und log/ neben src/. Nur src/ gehört in Versionskontrolle.
Bauen, ohne dem Pi den Speicher auszugehen
colcon build kompiliert Pakete parallel, ein Prozess pro Kern – und jedes C++-Kompilat kann den Großteil eines Gigabytes nehmen. Auf einem Vierkern-Pi sind das vier schwere Compiler zugleich – und der Bau stirbt mit Meldung über getöteten Prozess, oder das ganze Board hängt sich auf.
MAKEFLAGS="-j1" colcon build --parallel-workers 1 --symlink-install
Langsamer, und es beendet. Reine Pythonpakete haben dieses Problem nicht; es beißt, sobald man irgendetwas mit C++ darin baut. Ein paar Gigabyte Swap dazu funktionieren auch – auf SD-Karte allerdings quälend langsam.
Vom Laptop mit dem Roboter sprechen
ROS 2 hat keinen Master. Nodes finden sich per DDS-Discovery übers Netz – Laptop und Pi im selben LAN bilden also ohne Konfiguration überhaupt einen Graphen, wenn es funktioniert.
Dieselbe Domain auf beiden Rechnern setzen:
export ROS_DOMAIN_ID=42 # any value 0–101; the same on every machine
Die Domain partitioniert das Netz. Zwei Roboter im selben Raum auf Standarddomain hören die Topics des anderen und kämpfen darum – eine denkwürdige Art zu lernen, was diese Einstellung tut.
Vom Laptop verifizieren, bei laufendem Talker auf dem Pi:
ros2 topic list
ros2 node list
ros2 topic echo /chatter
Discovery WLAN-überlebensfähig machen
ros2 topic list, das nichts zeigt, während das Pi eindeutig publiziert, ist der häufigste einzelne ROS-2-Netzwerkfehler – und fast nie ROS’ Schuld.
Discovery nutzt Multicast, und viele Access Points leiten ihn nicht weiter. Consumer-WLAN-Router drosseln oder verwerfen Multicast häufig, und „Client-Isolation“- oder Gastnetzmodi blockieren Client-zu-Client-Verkehr glatt. Die Nodes laufen; die Pakete, die sie vorstellen würden, kommen nie an.
In dieser Reihenfolge durcharbeiten:
- Dasselbe Subnetz? Ein Laptop auf 5 GHz und ein Pi auf Gast-SSID sind nicht im selben Netz, wie ähnlich die Adressen aussehen.
- Dieselbe
ROS_DOMAIN_ID, in der Shell, die die Node wirklich fährt? Einexportin einem Terminal erreicht kein anderes – und keinen systemd-Dienst. - Kabelgebunden probieren. Funktioniert Ethernet und WLAN nicht, ist Multicast bewiesen, nicht ROS.
- Die Firewall prüfen.
sudo ufw allow in proto udp from <Subnetz>an beiden Enden, oder zum Testen deaktivieren. - Auf einen Discovery-Server zurückfallen. Fast DDS kann statt Multicast einen bekannten Endpunkt nutzen –
ROS_DISCOVERY_SERVERauf beiden Rechnern auf die Roboteradresse setzen. Das ist die verlässliche Antwort in einem Netz, das man nicht kontrolliert.
Noch eines, und es ist ein leises: Die Uhren synchron halten. TF2 vergleicht Zeitstempel über Rechner – und ein Pi ohne RTC startet mit falscher Zeit. chrony an beiden Enden installieren, sonst scheitert jeder Transform-Lookup mit Extrapolationsfehler, der wie ein ROS-Fehler aussieht.
Die Nodes des Roboters beim Start starten
Ein Roboter, in den man sich per SSH einwählen muss, um zu starten, ist ein ausgeschalteter Roboter. Eine systemd-Unit behebt es:
# /etc/systemd/system/my-robot.service
[Unit]
Description=Robot bringup
After=network-online.target
[Service]
User=ubuntu
Environment=ROS_DOMAIN_ID=42
ExecStart=/bin/bash -lc 'source /opt/ros/jazzy/setup.bash && \
source /home/ubuntu/ros2_ws/install/setup.bash && \
ros2 launch my_robot bringup.launch.py'
Restart=on-failure
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now my-robot
journalctl -u my-robot -f
Die Environment=-Zeile zählt mehr, als es aussieht. systemd liest deine .bashrc nicht – ein Dienst erbt also keine ROS-Variablen deiner interaktiven Shell: genau darum geht ein Roboter, der über SSH arbeitet, lautlos, wenn er sich selbst startet.
Wenn es schiefgeht
| Symptom | Meist |
|---|---|
ros2: command not found |
Der Underlay wurde in dieser Shell nie gesourct |
ros2 topic list leer vom Laptop |
Multicast blockiert oder ROS_DOMAIN_ID unpassend |
| Bau stirbt mittendrin ohne Fehler | Speicher aus – parallele Worker begrenzen |
| Deine Codeänderung wirkte nicht | Ohne --symlink-install gebaut oder Overlay nicht neu gesourct |
| Paket nach Bauen nicht gefunden | Overlay nicht gesourct, oder vor Bauende gesourct |
| TF-Fehler über Extrapolation in die Zukunft | Uhren zwischen Rechnern nicht synchronisiert |
| Über SSH in Ordnung, beim Start tot | systemd-Dienst ohne ROS-Umgebung |
Bei benimmender Umgebung ist die nächste Frage, was man hineintut – was ein Entwurfs- statt Installationsproblem ist. Nodes, Topics, Services und Actions deckt die Wahl zwischen Kommunikationsmustern ab, und TF2-Koordinatenframes den Teil, der danach Leute erwischt.
Den Graphen erkunden
Teil dieser Bauprojekte
Projekte und Lernpfade, die dieses Tutorial enthalten.
Weiterführende Literatur