Сообщения и типы msg

У каждого топика есть строгий тип сообщения — разбираем, что такое .msg и какие типы встречаются.

Тип сообщения (message type) — это описанная в файле .msg структура данных, которую несёт топик: набор полей с именами и типами.

Зачем типизировать сообщения

Чтобы издатель и подписчик понимали друг друга, данные в топике должны иметь строгую форму. В ROS форму описывают в файле .msg — это как заранее согласованный бланк. Издатель заполняет бланк, подписчик читает по тем же полям. Если форма не совпадает, ROS просто не соединит узлы. Типизация ловит ошибки на этапе связи, а не во время движения робота.

Как выглядит .msg

Файл .msg — это простой список «тип имя». Например, простейшее сообщение со строкой из пакета std_msgs:

# std_msgs/msg/String
string data

А вот сообщение Twist для скорости — оно вложенное: внутри два вектора по три компоненты:

# geometry_msgs/msg/Twist
Vector3 linear     # x, y, z — линейная скорость
Vector3 angular    # x, y, z — угловая скорость

Стандартные пакеты сообщений

Большинство нужных типов уже определены в стандартных пакетах — не нужно изобретать свои. Используйте готовые: их понимают все инструменты и пакеты экосистемы.

ПакетПримеры типовДля чего
std_msgsString, Int32, Bool, Float64примитивы
geometry_msgsTwist, Pose, Point, Quaternionдвижение и геометрия
sensor_msgsLaserScan, Image, Imu, PointCloud2данные датчиков
nav_msgsOdometry, Path, OccupancyGridнавигация и карты

Просмотр типа

Чтобы увидеть структуру любого сообщения, есть команда ros2 interface show:

ros2 interface show geometry_msgs/msg/Twist

Вывод:

Vector3 linear
        float64 x
        float64 y
        float64 z
Vector3 angular
        float64 x
        float64 y
        float64 z

Заголовок Header

Многие сообщения датчиков начинаются с поля std_msgs/Header. В нём лежат временная метка (stamp) и frame_id — имя системы координат, в которой даны данные. Например, у /scan в Header будет frame_id: laser, что означает «эти расстояния измерены относительно лидара». Header критичен для TF2 и синхронизации данных с разных датчиков по времени.

Как работает под капотом

Из файла .msg система сборки во время компиляции пакета генерирует код для каждого языка: класс на Python (для rclpy) и структуру на C++ (для rclcpp). Поэтому в Python вы работаете с обычным объектом msg.linear.x = 0.2, а под капотом он сериализуется в бинарный формат DDS и так передаётся по сети. Числа имеют фиксированный размер (float64, int32), что делает сериализацию компактной и быстрой.

Частые ошибки

  • Изобретать свой тип, когда есть стандартный. Готовые пакеты ждут именно sensor_msgs/LaserScan, а не вашу копию.
  • Забыть заполнить Header.stamp/frame_id. TF2 и синхронизация без них работать не будут.
  • Перепутать единицы. Скорости в м/с и рад/с, углы в радианах — это соглашение ROS, не градусы.

Итоги

  • Тип сообщения описывается в .msg как список полей; он строго задаёт форму данных топика.
  • Большинство типов уже есть в std_msgs, geometry_msgs, sensor_msgs, nav_msgs.
  • ros2 interface show показывает структуру любого типа.
  • Header с stamp и frame_id нужен для времени и систем координат.
Проверьте себя
1. Что описывает файл .msg?
AМаршрут робота
BСтруктуру данных сообщения: поля с именами и типами
CСписок узлов
DКонфигурацию сети
2. В каком пакете лежит тип LaserScan для лидара?
Astd_msgs
Bsensor_msgs
Cgeometry_msgs
Dnav_msgs
3. Что хранит поле Header в сообщениях датчиков?
AИмя узла и его версию
BВременную метку (stamp) и систему координат (frame_id)
CСписок подписчиков
DСкорость колёс