Ожидайте нового сообщения
Первичный механизм для ROS 2 узла, чтобы обмениваться данными должен отправить и получить сообщения. Сообщения передаются по теме, и каждая тема имеет уникальное имя в сети ROS 2. Если узел хочет поделиться информацией, он должен использовать издателя, чтобы отправить данные в тему. Узел, который хочет получить ту информацию, должен использовать подписчика в той же самой теме. Помимо ее уникального имени, каждая тема также имеет тип сообщения, который определяет тип сообщений, которым позволяют быть переданными в определенной теме.
Эта коммуникация издателя-подписчика имеет следующие характеристики:
Темы используются в many-many коммуникации. Несколько издателей могут отправить сообщения в ту же тему, и несколько подписчиков могут получить их.
Издатель и подписчики разъединяются через темы и могут быть созданы и уничтожены в любом порядке. Сообщение может быть опубликовано к теме, даже при отсутствии активных подписчиков.
В этом примере показано, как опубликовать и подписаться на темы в сети ROS 2. Это также показывает как:
Ожидайте, пока новое сообщение не получено, или
Используйте коллбэки, чтобы обработать новые сообщения в фоновом режиме
Предпосылки: Запуск с ROS 2, соединитесь с сетью ROS 2
Подпишитесь и ожидайте сообщений
Создайте демонстрационную сеть ROS 2 с несколькими издателями и подписчиками.
exampleHelperROS2CreateSampleNetwork
Используйте ros2 topic list
видеть, какие темы доступны.
ros2 topic list
/clock /parameter_events /pose /scan
Примите, что вы хотите подписаться на /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
тема, с помощью функции обратного вызова 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.0138 0.0458 -0.0259
disp(orient)
0.0176 -0.0211 0.0172
Если вы вводите в pos
и orient
несколько раз в командной строке вы видите, что значения постоянно обновляются.
Остановите подписчика положения путем очищения переменной подписчика
clear poseSub clear controlNode
Примечание: существуют другие способы извлечь информацию из функций обратного вызова помимо использования глобальных переменных. Например, можно передать объект указателя в качестве дополнительного аргумента к функции обратного вызова. См. Определение Коллбэка (MATLAB) документация для получения дополнительной информации об определении функций обратного вызова.
Опубликуйте сообщения
Создайте издателя, который отправляет сообщения строки 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 /clock /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'
exampleHelperROS2ChatterCallback
функция была вызвана, когда подписчик получил сообщение строки.
Отключитесь от сети ROS 2
Удалите демонстрационные узлы, издателей и подписчиков от сети ROS 2. Также очистите глобальные переменные pos
и orient
clear global pos orient clear
Следующие шаги
sub
— ros2subscriber
объектros2subscriber
объект, заданный как указатель, который подписывается на определенную тему.
timeout
— Период тайм-аутаКоличество времени перед receiver
функция будет ошибка, если сообщение не будет получено.
Типы данных: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
msg
— Сообщение ROS 2Message
указатель на объектСообщение ROS 2, заданное как Message
указатель на объект.
Выбор между получает и использование коллбэка:
Используйте receive
когда ваша программа должна ожидать, пока следующее сообщение не получено по теме, и никакой другой обработки не должно происходить тем временем.
Если вы хотите, чтобы ваша программа продолжала бежать и была уведомлена каждый раз, когда новое сообщение прибывает, рассмотрите использование коллбэка вместо, получают.
Если вы хотите, чтобы ваша программа периодически использовала новые данные, полученные подписчиком, рассмотрите доступ к LatestMessage
свойство вместо использования получает или коллбэк.
У вас есть модифицированная версия этого примера. Вы хотите открыть этот пример со своими редактированиями?
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.