Топики и модель publish/subscribe
Топики — основной способ обмена данными в ROS; разбираем, как устроена модель publish/subscribe.
Топик (topic) — именованный канал, в который одни узлы публикуют сообщения, а другие на них подписываются. Это асинхронная связь «многие-ко-многим».
Зачем нужны топики
Топики — это «трубы данных» робота. Лидар измеряет расстояния 10 раз в секунду и публикует их в топик /scan. Ему всё равно, кто слушает: построитель карты, модуль объезда препятствий, логгер — может слушать любой из них или сразу все. Издатель и подписчики не знают друг о друге и не ждут друг друга: лидар продолжает публиковать, даже если подписчиков ноль. Это и есть асинхронность.
Такая развязка бесценна. Можно подключить новый узел-анализатор к существующему топику, не трогая ни строчки в коде лидара. Можно заменить настоящий лидар на симулятор — топик тот же, остальная система не заметит подмены.
Многие-ко-многим
У одного топика может быть несколько издателей и несколько подписчиков одновременно. Например, в топик /cmd_vel могут писать и автономный планировщик, и узел джойстика (ручное управление) — а слушает их один base_controller.
издатели топик подписчики
+----------+ +-----------------+
| lidar |---+ +--->| map_builder |
+----------+ | +---------+ | +-----------------+
+--->| /scan |----+
+---------+ | +-----------------+
+--->| obstacle_avoid |
+-----------------+
Осмотр топиков с консоли
Семейство команд ros2 topic позволяет исследовать живые топики, не написав ни строчки кода — это главный инструмент отладки.
# Все активные топики
ros2 topic list
# Печатать сообщения топика в реальном времени
ros2 topic echo /scan
# Частота публикации
ros2 topic hz /scan
# Тип сообщения и число издателей/подписчиков
ros2 topic info /scanВывод (ros2 topic list):
/scan /odom /cmd_vel /tf /rosout
Публикация из терминала
Можно даже опубликовать сообщение вручную — удобно, чтобы проверить, как робот реагирует на команду, без написания узла:
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist \
"{linear: {x: 0.2}, angular: {z: 0.0}}"Как работает под капотом
За топиками стоит DDS. Когда узел создаёт издателя для /scan, DDS объявляет об этом по сети (discovery). Подписчики того же топика находят издателя и устанавливают прямое соединение. Дальше сообщения идут напрямую от издателя к подписчикам, минуя какой-либо центр. Важно: издатель и подписчик должны совпадать не только по имени топика, но и по типу сообщения и по совместимым политикам QoS — иначе связь не установится.
Частые ошибки
- Опечатка в имени топика.
/scanи/Scan— разные топики; подписчик ничего не получит. - Разные типы сообщений. Издатель шлёт LaserScan, подписчик ждёт PointCloud — связи не будет.
- Несовместимый QoS. Частая причина «топик есть в list, а echo молчит» — расхождение политик надёжности.
Итоги
- Топик — именованный канал; издатели публикуют, подписчики получают.
- Связь асинхронная и многие-ко-многим; стороны не знают друг о друге.
- ros2 topic list/echo/hz/info — главные инструменты отладки.
- Для связи нужны совпадение имени, типа сообщения и совместимый QoS.