Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Создание собственных сообщений для топиков

Что вы узнаете в этом разделе:

  • Когда нужно создавать собственные сообщения
  • Как создать пакет для хранения сообщений
  • Как описать структуру нового сообщения в файле .msg
  • Как настроить сборку пакета для генерации сообщений
  • Как использовать созданные сообщения в Python программах
  • Основные типы данных для сообщений ROS

Собственные типы сообщений

Ранее мы использовали встроенные типы сообщений (или сообщения сторонних пакетов). В ROS созданы сообщения для обработки большинства необходимых типовых (данные датчиков, моторы, одометрия и тп). Перед созданием нового сообщения, необходимо убедиться что для вашей задачи не существует стандартного сообщения.

В части работы с топиками, мы рассматривали пример мониторинга температуры CPU RaspberryPi. Предположим ситуацию, что для мониторинга состояния CPU нам также важен параметр текущей частоты CPU (современные процессоры понижают частоту, когда нагрузка на CPU низкая, и повышают при возрастании нагрузки)

У RaspberryPI 4 ядра, каждое из которых может иметь собственную частоту. Итого, наше сообщение должно содержать температуру и информацию о частоте 4 ядер CPU.

Создание собственного сообщения (собсвтенного типа сообщения) — довольно сложная часть, которая затрагивает множество систем ROS. Ваше сообщение должно быть правильно создано и установлено в систему. Автоматизировать этот процесс помогает сборщик colcon.

Создание пакета для сообщений

Хорошей практикой может служить создание отдельного пакета для хранения сообщений и их генерации. Также в пакет созданные для python программ с опцией --build-type ament_python не получится добавить генерацию сообщения.

Удостоверимся, что мы находимся в рабочем пространстве user_ws, в директории с исходным кодом пакетов.

cd ~/user_ws/src

Создадим пакет robot_msgs для работы с нашими сообщениями

ros2 pkg create --build-type ament_cmake --license Apache-2.0 robot_msgs
===
going to create a new package
package name: robot_msgs
destination directory: /home/pi/user_ws/src
package format: 3
version: 0.0.0
....

Создание файла с сообщением

Сообщения для топиков принято хранить в директории msg пакета. Создадим эту директорию.

mkdir msg

Создадим файл, который опишет наше новое сообщение msg/CPUInfo.msg. Имя файла, определит название сообщения.

float32 temp
int32 cpu0_freq 
int32 cpu1_freq
int32 cpu2_freq
int32 cpu3_freq

На каждой строчке необходимо указать тип переменной и название переменной которую мы хотим использовать.

Базовые типы сообщений можно посмотреть на странице https://docs.ros.org/en/jazzy/Concepts/Basic/About-Interfaces.html#field-types

Также можно создавать переменные, используя уже созданные типы сообщений. Например в логики пакета std_msgs, можно переписать файл сообщения как

std_msgs/Float32 temp
std_msgs/Int32 cpu0_freq 
std_msgs/Int32 cpu1_freq
std_msgs/Int32 cpu2_freq
std_msgs/Int32 cpu3_freq

Настройка сборки пакета

Файл с сообщением мы создали, далее нам необходимо правильно установить сообщение в систему ROS. Для этого необходимо внести изменение в стандартные параметры сборки, которые мы получили при создании простого пакета.

В корне проекта находится файл CMakeLists.txt, мы должны удостовериться, что он содержит данные о необходимых зависимостях и инструкцию по сборке сообщений.

Для нашего сообщения, в файл необходимо добавить (до директивы ament_package())

find_package(std_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/CPUInfo.msg"
  DEPENDENCIES std_msgs
)

Где

# Указание зависимости на пакет `std_msgs`, этот пакет содержит необходимые сообщения Float32 и UInt32 
find_package(std_msgs REQUIRED)

# Указание зависимости на пакет `rosidl_default_generators`, который реализует дополнительную опцию сборки `rosidl_generate_interfaces()`
find_package(rosidl_default_generators REQUIRED)

# Команда сборки сообщений, и перечень файлов для сообщений
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/CPUInfo.msg"
  DEPENDENCIES std_msgs
)

Также необходимо внести изменения в файл package.xml, в теле элемента <package>

<depend>std_msgs</depend>
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

Сборка и тестирование пакета

Соберем пакет

cd ~/user_ws
colcon build --packages-select robot_msgs
====
Starting >>> robot_msgs
Finished <<< robot_msgs [9.01s]

Summary: 1 package finished [9.22s]

Мы видим, что пакет успешно "собран". Проверим, что сообщения появились в системе ROS.

Если рабочее пространство user_ws не добавлено в систему - не забывайте выполнять команду source ./install/local_setup.sh

ros2 interface list --only-msgs
...
    robot_msgs/msg/CPUInfo
...

Сообщение появилось в системе.

Использование созданных сообщения в python программах

Создадим простой демонстрационный пример подключения и использования сообщения в файл src/cpu_info_msg.py. Файл необходимо создать в вашем основном пакете ros_base_course из прошлого урока.

from robot_msgs.msg import CPUInfo

msg = CPUInfo()
msg.temp = 55.1
msg.cpu0_freq = 1600000
msg.cpu1_freq = 1600000
msg.cpu2_freq = 1600000
msg.cpu3_freq = 1600000


print(msg)

Запустим и проверим его

python3 ./cpu_info_msg.py
robot_msgs.msg.CPUInfo(temp=55.1, cpu0_freq=1600000, cpu1_freq=1600000, cpu2_freq=1600000, cpu3_freq=1600000)

Сообщение доступно в общей инфраструктуре ROS и корректно работает.