Руководство · Начальный · 1 час
Установка ROS 2 на Raspberry Pi и рабочее пространство
Запустите ROS 2 на Raspberry Pi: выберите операционную систему, установите из apt, соберите рабочее пространство colcon и настройте обмен по Wi-Fi.
Введение
В ROS 2 ничто не кажется сложным, пока вы не попытаетесь установить его на робота. В этот момент одновременно ломаются три несвязанные вещи: операционная система оказывается не той, рабочее пространство не собирается в памяти Pi, а ноутбук не видит узлы робота. Строго говоря, это не проблемы ROS, поэтому официальные руководства и не предупреждают о них.
С помощью этого руководства вы перейдёте от пустой SD-карты к тому, что команда ros2 topic list на ноутбуке работает с узлами, запущенными на роботе.
Выберите операционную систему, а не только плату
Бинарные пакеты ROS 2 собраны для Ubuntu, а не для Raspberry Pi OS. Raspberry Pi OS основан на Debian, поэтому пакетов apt там просто нет, а каждое обходное решение — сборка из исходников, Docker, conda — стоит часов ещё до написания кода робота.
Поэтому установите Ubuntu Server 24.04 LTS (64-разрядная версия) и согласуйте её с выпуском ROS 2, собранным под неё. На момент написания такая пара — Jazzy Jalisco, поддерживаемая до 2029 года; проверьте страницу установки, чтобы узнать актуальную версию, и замените название во всех местах.
При записи образа на SD-карту нужно правильно выбрать три вещи:
- 64-разрядная версия. Пакеты ROS 2 arm64 существуют; пакетов armhf нет.
- Server (сервер), а не Desktop (рабочий стол). У робота нет монитора, а графическая среда расходует RAM, который нужен для зрения.
- Pi 4 с 4 GB или Pi 5. Плата с 2 GB нормально запускает ROS 2, но не позволяет комфортно собирать пакеты ROS.
Установка ROS 2 из apt
Добавьте источник apt для ROS 2, затем выполните установку. Настройка репозитория меняется от выпуска к выпуску, поэтому ниже приведена общая форма, а не фрагмент для запоминания:
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
Обратите внимание: нужен ros-base, а не desktop. Метапакет desktop подтягивает RViz и демонстрационные графические интерфейсы (GUIs), которые робот без монитора никогда не запустит, а на SD-карте их установка занимает очень много времени. Визуализация должна выполняться на ноутбуке, где вы устанавливаете полный ros-jazzy-desktop.
ros-dev-tools предоставляет colcon и rosdep. Один раз инициализируйте rosdep:
sudo rosdep init # skip if it says the file already exists
rosdep update
Подключите базовый слой (underlay), затем наложенный слой (overlay)
ROS 2 ничего не делает, пока не подключено его окружение, и именно здесь возникает большая часть ранней путаницы.
source /opt/ros/jazzy/setup.bash
Это базовый слой (underlay) — установленный дистрибутив. Ваше собственное рабочее пространство после сборки становится наложенным слоем (overlay) поверх него. Подключение наложенного слоя неявно подключает и базовый слой, на котором он был собран.
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
Размещение базового слоя в .bashrc — стандартная и безопасная практика. Размещение там же наложенного слоя — ловушка, от которой стоит избавиться сразу: в день, когда у вас появятся два рабочих пространства или когда вы пересоберёте рабочее пространство для другого дистрибутива, каждый новый терминал будет молча начинать с устаревшего окружения, и вы полдня будете отлаживать фантомную проблему. Подключайте наложенный слой явно, отдельно для каждого терминала, там, где он нужен.
Создайте рабочее пространство и пакет
Рабочее пространство colcon — это каталог с src/ внутри. Вот и всё описание.
mkdir -p ~/ros2_ws/src && cd ~/ros2_ws
ros2 pkg create --build-type ament_python --license Apache-2.0 my_robot
Затем соберите его и подключите наложенный слой:
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -y
colcon build --symlink-install
source install/setup.bash
Используйте --symlink-install. Он связывает файлы Python с местом установки, а не копирует их, поэтому изменение узла вступает в силу при следующем запуске, а не после пересборки. На Pi, где пересборка идёт медленно, это разница между итерациями и ожиданием.
После сборки в ~/ros2_ws находятся build/, install/ и log/ рядом с src/. Под контролем версий следует хранить только src/.
Сборка без исчерпания памяти Pi
colcon build компилирует пакеты параллельно, по одному процессу на ядро, и каждая компиляция C++ может занимать почти гигабайт. На четырёхъядерном Pi это четыре тяжёлых компилятора одновременно, и сборка завершается сообщением об остановленном процессе — либо вся плата полностью зависает.
MAKEFLAGS="-j1" colcon build --parallel-workers 1 --symlink-install
Так медленнее, но сборка завершается. У чистых пакетов Python этой проблемы нет; она возникает, как только вы собираете что-то с C++. Добавление нескольких гигабайт подкачки тоже помогает, хотя на SD-карте это исключительно медленно.
Свяжитесь с роботом с ноутбука
В ROS 2 нет главного узла (master). Узлы находят друг друга с помощью обнаружения DDS (DDS discovery) по сети, поэтому ноутбук и Pi в одной локальной сети (LAN) могут образовать единый граф вообще без настройки — если всё работает.
Задайте одинаковый домен на обеих машинах:
export ROS_DOMAIN_ID=42 # any value 0–101; the same on every machine
Домен разделяет сеть. Два робота в одной комнате с доменом по умолчанию будут слышать темы друг друга и бороться за них — это запоминающийся способ понять, что делает эта настройка.
Проверьте с ноутбука, пока на Pi работает узел talker:
ros2 topic list
ros2 node list
ros2 topic echo /chatter
Обеспечьте обнаружение через Wi-Fi
Случай, когда ros2 topic list показывает пустоту, хотя Pi явно публикует данные, — самая частая сетевая ошибка ROS 2, и почти никогда она не является виной ROS.
Обнаружение использует многоадресную передачу (multicast), а многие точки доступа её не пересылают. Бытовые маршрутизаторы часто ограничивают скорость многоадресного трафика или отбрасывают его, а режим «client isolation» (изоляция клиентов) или гостевая сеть полностью блокируют трафик между клиентами. Узлы работают; пакеты, которые должны были представить их друг другу, просто не приходят.
Проверяйте в таком порядке:
- Одна подсеть? Ноутбук в сети 5 GHz и Pi в гостевой SSID находятся в разных сетях, как бы ни были похожи их адреса.
- Одинаковый
ROS_DOMAIN_IDв том терминале, где действительно работает узел?exportв одном терминале не попадает в другой и не попадает в службу systemd. - Попробуйте проводную связь. Если Ethernet работает, а Wi-Fi нет, вы доказали, что дело в многоадресной передаче, а не в ROS.
- Проверьте брандмауэр. Выполните
sudo ufw allow in proto udp from <subnet>на обоих концах или отключите его на время проверки. - Вернитесь к серверу обнаружения. Fast DDS может использовать известную конечную точку вместо многоадресной передачи — задайте
ROS_DISCOVERY_SERVERна адрес робота на обеих машинах. Это надёжное решение в сети, которой вы не управляете.
Ещё один, менее заметный момент: поддерживайте синхронизацию часов. TF2 сравнивает метки времени между машинами, а Pi без RTC загружается с неверным временем. Установите chrony на обоих концах, иначе каждый поиск преобразования завершится ошибкой экстраполяции, похожей на ошибку ROS.
Запускайте узлы робота при загрузке
Робот, в который нужно подключаться по SSH, чтобы запустить узлы, фактически выключен. Исправьте это модулем systemd:
# /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
Строка Environment= важнее, чем кажется. systemd не читает ваш .bashrc, поэтому служба не наследует ни одной переменной ROS из интерактивного терминала — именно поэтому робот, работающий по SSH, замолкает при самостоятельном запуске.
Когда что-то идёт не так
| Симптом | Обычно |
|---|---|
ros2: command not found |
Базовый слой не был подключён в этом терминале |
ros2 topic list пуст на ноутбуке |
Многоадресная передача заблокирована или ROS_DOMAIN_ID не совпадает |
| Сборка прервалась без ошибки | Не хватает памяти — ограничьте число параллельных рабочих процессов |
| Изменение кода не дало эффекта | Сборка без --symlink-install или наложенный слой не подключён заново |
| Пакет не найден после сборки | Наложенный слой не подключён или подключён до завершения сборки |
| Ошибки TF об экстраполяции в будущее | Часы на машинах не синхронизированы |
| По SSH работает, при загрузке не работает | Служба systemd не получает окружение ROS |
Когда окружение работает, следующий вопрос — что в него поместить. Это уже вопрос проектирования, а не установки. Узлы, темы, сервисы и действия описывают выбор между шаблонами взаимодействия, а системы координат TF2 — часть, на которой люди спотыкаются после этого.
Исследуйте граф
Входит в эти сборки
Проекты и учебные пути, в которые входит это руководство.
Дополнительные материалы