Опубликовать сообщение ROS 2 в разделе
Основным механизмом обмена данными между узлами ROS 2 является отправка и прием сообщений. Сообщения передаются по теме, и каждая тема имеет уникальное имя в сети ROS 2. Если узел хочет поделиться информацией, он должен использовать издателя для отправки данных в раздел. Узел, который хочет получить эту информацию, должен использовать абонента для этой же темы. Помимо своего уникального имени, каждая тема также имеет тип сообщения, который определяет тип сообщений, которые разрешено передавать в конкретной теме.
Эта коммуникация издатель-абонент имеет следующие характеристики:
Темы используются для общения «многие ко многим». Несколько издателей могут отправлять сообщения в одну тему, и несколько подписчиков могут их получать.
Издатель и подписчики разделены на темы и могут быть созданы и уничтожены в любом порядке. Сообщение может быть опубликовано в тему, даже если нет активных подписчиков.
В этом примере показано, как публиковать и подписываться на темы в сети ROS 2. Также показано, как:
Подождите, пока будет получено новое сообщение, или
Используйте коллбэки для обработки новых сообщений в фоновом режиме
Необходимые условия: Запуск с ROS 2, Подключение к сети ROS 2
Подписка и ожидание сообщений
Создайте пример сети ROS 2 с несколькими издателями и подписчиками.
exampleHelperROS2CreateSampleNetwork
Использование ros2 topic list
чтобы увидеть, какие темы доступны.
ros2 topic list
/parameter_events
Предположим, что вы хотите подписаться на /scan
тема. Использование ros2subscriber
подписаться на /scan
тема. Укажите имя узла с абонентом. Если тема уже существует в сети ROS 2, ros2subscriber
определяет его тип сообщения автоматически, поэтому вам не нужно указывать его.
detectNode = ros2node("/detection"); pause(2) laserSub = ros2subscriber(detectNode,"/scan"); pause(2)
Использование receive
чтобы дождаться нового сообщения. Задайте тайм-аут 10 секунд. Область выхода scanData
содержит полученные данные сообщения.
scanData = receive(laserSub,10);
Теперь можно удалить абонента laserSub
и связанный с ним узел.
clear laserSub clear detectNode
Подписка с использованием функций обратного вызова
Вместо использования receive
для получения данных можно задать функцию, которая будет вызываться при получении нового сообщения. Это позволяет выполнять другой код MATLAB во время ожидания абонентом новых сообщений. Коллбэки необходимы, если вы хотите использовать несколько абонентов.
Подпишитесь на /pose
topic, использование функции обратного вызова exampleHelperROS2PoseCallback
, который принимает полученное сообщение в качестве входов. Одним из способов обмена данными между вашей основной рабочей областью и функцией обратного вызова является использование глобальных переменных. Задайте две глобальные переменные pos
и orient
.
controlNode = ros2node("/base_station"); poseSub = ros2subscriber(controlNode,"/pose",@exampleHelperROS2PoseCallback); global pos global orient
Глобальные переменные pos
и orient
назначаются в exampleHelperROS2PoseCallback
функция, когда новые данные сообщения получены на /pose
тема.
function exampleHelperROS2PoseCallback(message) % Declare global variables to store position and orientation global pos global orient % Extract position and orientation from the ROS message and assign the % data to the global variables. pos = [message.linear.x message.linear.y message.linear.z]; orient = [message.angular.x message.angular.y message.angular.z]; end
Подождите, пока сеть опубликует другое /pose
сообщение. Отображение обновленных значений.
pause(3) disp(pos)
-0.0156 0.0281 0.0175
disp(orient)
-0.0493 0.0102 -0.0113
Если вы вводите pos
и orient
несколько раз в командной строке можно увидеть, что значения постоянно обновляются.
Остановите абонента положения путем очистки переменной абонента
clear poseSub clear controlNode
Примечание: Существуют другие способы извлечения информации из функций обратного вызова, помимо использования globals. Для примера можно передать объект указателя в качестве дополнительного аргумента в функцию обратного вызова. Для получения дополнительной информации об определении функций обратного вызова см. документацию «Определение обратного вызова».
Публикация сообщений
Создайте издателя, который отправляет строковые сообщения ROS 2 в /chatter
тема.
chatterPub = ros2publisher(node_1,"/chatter","std_msgs/String");
Создайте и заполните ROS 2 сообщение для отправки в /chatter
тема.
chatterMsg = ros2message(chatterPub);
chatterMsg.data = 'hello world';
Использование ros2 topic list
чтобы проверить, что /chatter
тема доступна в сети ROS 2.
ros2 topic list
/chatter /parameter_events /pose /scan
Определите абонента для /chatter
тема. exampleHelperROS2ChatterCallback
вызывается при получении нового сообщения и отображает строку содержимое сообщения.
chatterSub = ros2subscriber(node_2,"/chatter",@exampleHelperROS2ChatterCallback)
chatterSub = ros2subscriber with properties: TopicName: '/chatter' LatestMessage: [] MessageType: 'std_msgs/String' NewMessageFcn: @exampleHelperROS2ChatterCallback History: 'keeplast' Depth: 10 Reliability: 'reliable' Durability: 'volatile'
Опубликовать сообщение в /chatter
тема. Обратите внимание, что строка отображается при коллбэке абонента.
send(chatterPub,chatterMsg) pause(3)
ans = 'hello world'
The exampleHelperROS2ChatterCallback
функция была вызвана, когда абонент получил строку сообщение.
Отсоединение от сети ROS 2
Удалите примеры узлов, издателей и подписчиков из сети ROS 2. Также очистите глобальные переменные pos
и orient
clear global pos orient clear
Следующие шаги
pub
— ros2publisher
объектros2publisher
ros2publisher
объект, заданный как указатель, который публикует указанную тему.
msg
- сообщение ROS 2Message
структураСообщение ROS 2, заданное как структура, с совместимыми полями для этого типа сообщения.
У вас есть измененная версия этого примера. Вы хотите открыть этот пример с вашими правками?
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.