Первичный механизм для узлов ROS, чтобы обмениваться данными должен отправить и получить сообщения. Сообщения передаются по теме, и каждая тема имеет уникальное имя в сети ROS. Если узел захочет поделиться информацией, он будет использовать издателя, чтобы отправить данные в тему. Узел, который хочет получить ту информацию, будет использовать подписчика на ту же самую тему. Помимо ее уникального имени, каждая тема также имеет тип сообщения, который определяет типы сообщений, которым позволяют быть переданными.
Эта коммуникация издателя/подписчика имеет следующие характеристики:
Темы используются для many-many коммуникации. Многие издатели могут отправить сообщения в ту же тему, и многие подписчики могут получить их.
Издатель и подписчики разъединяются через темы и могут быть созданы и уничтожены в любом порядке. Сообщение может быть опубликовано к теме, даже при отсутствии активных подписчиков.
Концепция тем, издателей и подписчиков проиллюстрирована в следующем изображении:
Этот пример показывает, как опубликовать и подписаться на темы в сети ROS. Это также показывает как:
Ожидайте, пока новое сообщение не получено, или
Используйте коллбэки, чтобы обработать новые сообщения в фоновом режиме
Предпосылки: Запуск с ROS, соединитесь с сетью ROS
Запустите ведущее устройство ROS в MATLAB® и создайте демонстрационную сеть ROS с несколькими издателями и подписчиками.
rosinit
Initializing ROS master on http://bat6230glnxa64:39237/. Initializing global node /matlab_global_node_27928 with NodeURI http://bat6230glnxa64:41125/
exampleHelperROSCreateSampleNetwork
Используйте rostopic
list
, чтобы видеть, какие темы доступны. Примите, что вы хотите подписаться на /scan
тему.
rostopic list
/pose /rosout /scan
Используйте rostopic info
, чтобы проверять, публикуют ли какие-либо узлы к теме /scan
. Команда ниже показов, которые node_3
публикует к нему.
rostopic info /scan
Type: sensor_msgs/LaserScan Publishers: * /node_3 (http://bat6230glnxa64:35443/) Subscribers: * /node_2 (http://bat6230glnxa64:40983/) * /node_1 (http://bat6230glnxa64:42155/)
Используйте rossubscriber
, чтобы подписаться на /scan
тему. Если тема уже существует в сети ROS (как имеет место здесь), rossubscriber
обнаруживает свой тип сообщения автоматически, таким образом, вы не должны задавать его.
laser = rossubscriber('/scan')
laser = Subscriber with properties: TopicName: '/scan' MessageType: 'sensor_msgs/LaserScan' LatestMessage: [0x1 LaserScan] BufferSize: 1 NewMessageFcn: []
Используйте receive
, чтобы ожидать нового сообщения (второй аргумент является тайм-аутом в секундах). Вывод scandata
содержит полученные данные о сообщении.
scandata = receive(laser,10)
scandata = ROS LaserScan message with properties: MessageType: 'sensor_msgs/LaserScan' Header: [1x1 Header] AngleMin: -0.5216 AngleMax: 0.5243 AngleIncrement: 0.0016 TimeIncrement: 0 ScanTime: 0.0330 RangeMin: 0.4500 RangeMax: 10 Ranges: [640x1 single] Intensities: [0x1 single] Use showdetails to show the contents of the message
Некоторые типы сообщений имеют удобный visualizers, сопоставленный с ними. Для сообщения LaserScan plot
строит данные сканирования. MaximumRange
пара "имя-значение" задает максимальную область значений графика.
figure
plot(scandata,'MaximumRange',7)
Вместо того, чтобы использовать receive
, чтобы получить данные, можно задать функцию, которая будет названа, когда новое сообщение получено. Это позволяет другому коду MATLAB выполняться, в то время как подписчик ожидает новых сообщений. Коллбэки важны, если вы хотите использовать несколько подписчиков.
Подпишитесь на тему /pose
, с помощью функции обратного вызова exampleHelperROSPoseCallback
. Один способ осуществлять обмен данными между вашей основной рабочей областью и функцией обратного вызова состоит в том, чтобы использовать глобальные переменные. Также задайте две глобальных переменные pos
и orient
.
robotpose = rossubscriber('/pose',@exampleHelperROSPoseCallback)
robotpose = Subscriber with properties: TopicName: '/pose' MessageType: 'geometry_msgs/Twist' LatestMessage: [1x1 Twist] BufferSize: 1 NewMessageFcn: @exampleHelperROSPoseCallback
global pos global orient
pos
глобальных переменных и orient
присвоены в функции exampleHelperROSPoseCallback
, когда новые данные о сообщении получены по теме /pose
.
Ожидайте в течение нескольких секунд, чтобы убедиться, что подписчик может получить сообщения. Актуальнейшее положение и данные об ориентации будут всегда храниться в переменных pos
и orient
.
pause(2) pos
pos = 1×3
0.1151 0.0436 -0.0411
orient
orient = 1×3
0.0303 -0.0253 0.1623
Если вы вводите в pos
и orient
несколько раз в командной строке, вы видите, что значения постоянно обновляются.
Остановите подписчика положения путем очищения переменной подписчика
clear robotpose
Примечание: существуют другие способы извлечь информацию от функций обратного вызова помимо использования глобальных переменных. Например, можно передать объект указателя в качестве дополнительного аргумента к функции обратного вызова. См. Определение Коллбэка (MATLAB) документация для получения дополнительной информации об определении функций обратного вызова.
Создайте издателя, который отправляет сообщения строки ROS в тему /chatter
(см. работу с Основными сообщениями ROS).
chatterpub = rospublisher('/chatter', 'std_msgs/String')
chatterpub = Publisher with properties: TopicName: '/chatter' IsLatching: 1 NumSubscribers: 0 MessageType: 'std_msgs/String'
pause(2) % Wait to ensure publisher is registered
Создайте и заполните сообщение ROS, чтобы отправить к теме /chatter
.
chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
chattermsg = ROS String message with properties: MessageType: 'std_msgs/String' Data: 'hello world' Use showdetails to show the contents of the message
Используйте rostopic list
, чтобы проверить, что тема /chatter
доступна в сети ROS.
rostopic list
/chatter /pose /rosout /scan
Задайте подписчика для темы /chatter
. exampleHelperROSChatterCallback
называется, когда новое сообщение получено и отображает содержимое строки в сообщении.
chattersub = rossubscriber('/chatter', @exampleHelperROSChatterCallback)
chattersub = Subscriber with properties: TopicName: '/chatter' MessageType: 'std_msgs/String' LatestMessage: [0x1 String] BufferSize: 1 NewMessageFcn: @exampleHelperROSChatterCallback
Опубликуйте сообщение к теме /chatter
. Заметьте, что строка отображена коллбэком подписчика.
send(chatterpub,chattermsg) pause(2)
ans = 'hello world'
Функция exampleHelperROSChatterCallback
была вызвана, как только вы опубликовали сообщение строки.
Удалите демонстрационные узлы, издателей и подписчиков от сети ROS. Также очистите глобальные переменные pos
и orient
exampleHelperROSShutDownSampleNetwork clear global pos orient
Закройте ведущее устройство ROS и удалите глобальный узел.
rosshutdown
Shutting down global node /matlab_global_node_27928 with NodeURI http://bat6230glnxa64:41125/ Shutting down ROS master on http://bat6230glnxa64:39237/.
Чтобы узнать больше, как сообщения ROS обработаны в MATLAB, смотрите работу с Основными сообщениями ROS и работу со Специализированными сообщениями ROS
Чтобы исследовать сервисы ROS, обратитесь к Call and Provide ROS Services.