Обменивайтесь данными с издателями ROS и подписчиками

Первичный механизм для узлов 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

Удалите демонстрационные узлы, издателей и подписчиков от сети 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/.

Следующие шаги