Tutorial · Beginner · 1 uur

Installeer ROS 2 op een Raspberry Pi en bouw een workspace

Krijg ROS 2 draaiend op een Raspberry Pi: kies het juiste OS, installeer via apt, bouw een colcon-workspace en laat laptop en robot elkaar over wifi vinden.

Inleiding

Niets in ROS 2 is moeilijk tot je het op een robot probeert te installeren, en dan gaan er ineens drie losstaande dingen tegelijk mis: het besturingssysteem is het verkeerde, de workspace bouwt niet in het geheugen van de Pi, en de laptop ziet de nodes van de robot niet. Strikt genomen zijn het geen ROS-problemen, en daarom waarschuwen de officiële tutorials je er niet voor.

Dit brengt je van een lege SD-kaart naar een werkende ros2 topic list op je laptop, tegen nodes op de robot.

Kies het besturingssysteem, niet alleen het bord

De binaire bestanden van ROS 2 zijn gebouwd voor Ubuntu, niet voor Raspberry Pi OS. Raspberry Pi OS is Debian-gebaseerd, dus de apt-pakketten zijn er simpelweg niet, en elke omweg—bouwen uit broncode, Docker, conda—kost je uren voordat je één regel robotcode hebt geschreven.

Installeer dus Ubuntu Server 24.04 LTS (64-bit) en koppel die aan de ROS 2-release die ertegen gebouwd is. Op het moment van schrijven is die koppeling Jazzy Jalisco, ondersteund tot 2029; kijk op de installatiepagina wat er op dat moment actueel is en vervang de naam overal.

Drie dingen die je bij het flashen goed moet doen:

  • 64-bit. Er bestaan ROS 2-arm64-pakketten; armhf-pakketten niet.
  • Server, geen Desktop. Een robot heeft geen monitor, en de desktopomgeving kost RAM die je liever voor beeldverwerking over houdt.
  • Pi 4 met 4 GB, of een Pi 5. Een 2 GB-bord draait ROS 2 prima, maar kan het niet comfortabel compileren.

Installeer ROS 2 via apt

Voeg de ROS 2-aptsource toe en installeer daarna. De repository-installatie is het deel dat per release verandert, dus dit is de vorm en geen fragment om uit je hoofd te leren:

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

Let op: ros-base, niet desktop. Het metapakket desktop trekt RViz en de demo-GUI’s mee, die een robot zonder scherm nooit draait en die op een SD-kaart lang duren om te installeren. Visualisatie hoort op je laptop, waar je de volledige ros-jazzy-desktop installeert.

ros-dev-tools is wat je colcon en rosdep geeft. Initialiseer rosdep één keer:

sudo rosdep init      # skip if it says the file already exists
rosdep update

Source de underlay en daarna je overlay

ROS 2 doet niets tot zijn omgeving is gesourced, en hier zit de meeste vroege verwarring.

source /opt/ros/jazzy/setup.bash

Dat is de underlay—de geïnstalleerde distributie. Je eigen workspace is na het bouwen een overlay daar bovenop. Een overlay sourcen trekt de underlay waartegen hij gebouwd is impliciet mee.

echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc

De underlay in .bashrc zetten is standaard en veilig. Je overlay daar zetten is een valkuil die je beter vroeg vermijdt: op de dag dat je twee workspaces hebt, of opnieuw bouwt tegen een andere distributie, start elke nieuwe shell stilletjes met een verouderde omgeving en debug je een spook een middag lang. Source de overlay expliciet, per shell, in de terminal die hem nodig heeft.

Maak een workspace en een pakket

Een colcon-workspace is een map met daarin een src/. Dat is de hele specificatie.

mkdir -p ~/ros2_ws/src && cd ~/ros2_ws
ros2 pkg create --build-type ament_python --license Apache-2.0 my_robot

Bouw hem daarna en maak hem er een overlay van:

cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -y
colcon build --symlink-install
source install/setup.bash

Gebruik --symlink-install. Daarmee worden je Python-bestanden in de installatieruimte gelinkt in plaats van gekopieerd, dus een wijziging in een node werkt de volgende keer dat je hem draait in plaats van na een herbouw. Op een Pi, waar een herbouw langzaam is, is dat het verschil tussen itereren en wachten.

Na de bouw bevat ~/ros2_ws naast src/ ook build/, install/ en log/. Alleen src/ hoort in versiebeheer.

Bouw zonder dat de Pi uit zijn geheugen loopt

colcon build compileert pakketten parallel, één proces per kern, en elke C++-compilatie kan ruim een gigabyte kosten. Op een Pi met vier kernen zijn dat vier zware compilers tegelijk, en de bouw sterft met een melding over een beëindigd proces—of het hele bord loopt vast.

MAKEFLAGS="-j1" colcon build --parallel-workers 1 --symlink-install

Langzamer, en hij komt klaar. Pakketten in zuiver Python hebben dat probleem niet; het bijt je zodra je iets met C++ erin bouwt. Een paar gigabytes swap toevoegen werkt ook, al is dat op een SD-kaart pijnlijk traag.

Praat vanaf je laptop met de robot

ROS 2 heeft geen master. Nodes vinden elkaar via DDS-discovery over het netwerk, wat betekent dat een laptop en een Pi op hetzelfde LAN zonder enige configuratie één graph kunnen vormen—als het werkt.

Zet hetzelfde domein op beide machines:

export ROS_DOMAIN_ID=42        # any value 0–101; the same on every machine

Het domein deelt het netwerk in. Twee robots in dezelfde ruimte op het standaarddomein horen elkaars topics en beginnen er ruzie over te maken, en dat is een onvergetelijke manier om uit te vinden wat deze instelling doet.

Schematische weergave van een ROS 2-opstelling met twee machines: een Raspberry Pi op de robot die camera-, detector- en drivenodes draait, en een laptop met RViz en opdrachtregeltools, verbonden door een wifiwolk met het label DDS-discovery via multicast. Beide machines zijn geannoteerd met hetzelfde ROS_DOMAIN_ID, en een notitie markeert het accesspoint als het onderdeel dat multicast blokkeert.
Eén ROS 2-graph over twee machines: nodes op de robot, visualisatie op de laptop, en daartussen een stap discovery die afhangt van het accesspoint dat multicast doorstuurt. SVG downloaden

Controleer vanaf de laptop, met een talker op de Pi:

ros2 topic list
ros2 node list
ros2 topic echo /chatter

Laat discovery wifi overleven

ros2 topic list dat niets toont terwijl de Pi duidelijk wel publiceert, is het meest voorkomende netwerkprobleem in ROS 2, en het is vrijwel nooit de schuld van ROS.

Discovery gebruikt multicast, en veel accesspoints sturen het niet door. Consumentrouters voor wifi beperken de multicast-snelheid of laten het vallen, en “clientisolatie” of gastnetwerkmodi blokkeren verkeer tussen clients helemaal. De nodes draaien; de pakketten die ze zouden introduceren komen nooit aan.

Werk het in deze volgorde door:

  1. Hetzelfde subnet? Een laptop op 5 GHz en een Pi op een gast-SSID zitten niet in hetzelfde netwerk, hoe gelijk de adressen er ook uitzien.
  2. Hetzelfde ROS_DOMAIN_ID, in de shell die de node daadwerkelijk draait? Een export in de ene terminal bereikt de andere niet, en bereikt een systemd-service evenmin.
  3. Probeer bekabeld. Werkt Ethernet wel en wifi niet, dan heb je bewezen dat het multicast is en niet ROS.
  4. Controleer de firewall. sudo ufw allow in proto udp from <subnet> aan beide kanten, of schakel hem uit tijdens het testen.
  5. Val terug op een discovery-server. Fast DDS kan een bekend eindpunt gebruiken in plaats van multicast—stel ROS_DISCOVERY_SERVER in op het adres van de robot, op beide machines. Dat is het betrouwbare antwoord op een netwerk dat je niet beheert.

Nog een punt, en het is een stille: houd de klokken gesynchroniseerd. TF2 vergelijkt tijdstempels over machines heen, en een Pi zonder RTC start op een verkeerde tijd. Installeer chrony aan beide kanten, anders faalt elke transform-lookup met een extrapolatiefout die op een ROS-bug lijkt.

Start de nodes van de robot bij het opstarten

Een robot waarvoor je moet SSH-en om hem te starten, is een robot die uit staat. Een systemd-unit lost dat op:

# /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

De regel Environment= is belangrijker dan hij lijkt. systemd leest je .bashrc niet, dus een service erft geen van de ROS-variabelen die je interactieve shell heeft—en dat is precies waarom een robot die over SSH werkt stilvalt zodra hij zichzelf opstart.

Als het misgaat

Symptoom Meestal
ros2: command not found De underlay is in deze shell nooit gesourced
ros2 topic list leeg vanaf de laptop Multicast geblokkeerd, of een verschillende ROS_DOMAIN_ID
Bouw sterft halverwege zonder foutmelding Onvoldoende geheugen — beperk het aantal parallelle workers
Je codewijziging had geen effect Gebouwd zonder --symlink-install, of overlay niet opnieuw gesourced
Pakket niet gevonden na het bouwen Overlay niet gesourced, of gesourced voordat de bouw klaar was
TF-fouten over extrapolatie naar de toekomst Klokken niet gesynchroniseerd tussen machines
Werkt over SSH, dood bij het opstarten systemd-service mist de ROS-omgeving

Als de omgeving zich gedraagt, is de volgende vraag wat je erin moet stoppen—en dat is een ontwerpprobleem, geen installatieprobleem. Nodes, topics, services en actions behandelt de keuze tussen de communicatiepatronen, en TF2-coördinaatframes het stuk dat daarna mensen op de verkeerde voet zet.

Verken de graaf

Onderdeel van deze bouwprojecten

Projecten en leerroutes waarin deze tutorial voorkomt.

Verder lezen

Bronnen