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

Первичный механизм для узлов ROS, чтобы обмениваться данными отправляет и получает сообщения. Сообщения передаются по теме, и каждая тема имеет уникальное имя в сети ROS. Если узел хочет поделиться информацией, он использует издателя, чтобы отправить данные в тему. Узел, который хочет получить ту информацию, использует подписчика на ту же самую тему. Помимо ее уникального имени, каждая тема также имеет тип сообщения, который определяет типы сообщений, которые способны к тому, чтобы быть переданным под той темой.

Эта коммуникация издателя и подписчика имеет следующие характеристики:

  • Темы используются для many-many коммуникации. Многие издатели могут отправить сообщения в ту же тему, и многие подписчики могут получить их.

  • Издатели и подписчики разъединяются через темы и могут быть созданы и уничтожены в любом порядке. Сообщение может быть опубликовано к теме, даже при отсутствии активных подписчиков.

Концепция тем, издателей и подписчиков проиллюстрирована на рисунке:

В этом примере показано, как опубликовать и подписаться на темы в сети ROS. Это также показывает как:

  • Ожидайте, пока новое сообщение не получено

  • Используйте коллбэки, чтобы обработать новые сообщения в фоновом режиме

Необходимые условия: Начало работы с ROS, подключением к сети ROS

Подпишитесь и ожидайте сообщений

Запустите ведущее устройство ROS в MATLAB® с помощью rosinit команда.

rosinit
Launching ROS Core...
Done in 0.78372 seconds.
Initializing ROS master on http://192.168.0.10:57348.
Initializing global node /matlab_global_node_98311 with NodeURI http://bat1071901glnxa64:43203/

Создайте демонстрационную сеть ROS с несколькими издателями и подписчиками, использующими обеспеченную функцию помощника exampleHelperROSCreateSampleNetwork.

exampleHelperROSCreateSampleNetwork

Использование rostopic list видеть, какие темы доступны.

rostopic list
/pose  
/rosout
/scan  
/tf    

Используйте rostopic info проверять, публикуют ли какие-либо узлы к /scan тема. Команда ниже показов, что node_3 публикует к нему.

rostopic info /scan
Type: sensor_msgs/LaserScan
 
Publishers:
* /node_3 (http://bat1071901glnxa64:43247/)
 
Subscribers:
* /node_1 (http://bat1071901glnxa64:46821/)
* /node_2 (http://bat1071901glnxa64:35047/)

Использование rossubscriber подписываться на /scan тема. Если тема уже существует в сети ROS (как имеет место здесь), rossubscriber обнаруживает его тип сообщения автоматически, таким образом, вы не должны задавать его.

laser = rossubscriber('/scan');
pause(2)

Использование 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, rosPlot строит данные сканирования. MaximumRange пара "имя-значение" указывает максимальный диапазон графика.

figure
plot(scandata,'MaximumRange',7)

Figure contains an axes. The axes with title Laser Scan contains an object of type line.

Подпишитесь Используя функции обратного вызова

Вместо использования receive чтобы получить данные, можно задать функцию, которая будет названа, когда новое сообщение получено. Это позволяет другому коду MATLAB выполняться, в то время как подписчик ожидает новых сообщений. Коллбэки важны, если вы хотите использовать несколько подписчиков.

Подпишитесь на /pose тема, с помощью функции обратного вызова exampleHelperROSPoseCallback.

robotpose = rossubscriber('/pose',@exampleHelperROSPoseCallback)
robotpose = 
  Subscriber with properties:

        TopicName: '/pose'
    LatestMessage: [0x1 Twist]
      MessageType: 'geometry_msgs/Twist'
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSPoseCallback
       DataFormat: 'object'

Один способ осуществлять обмен данными между вашей основной рабочей областью и функцией обратного вызова состоит в том, чтобы использовать глобальные переменные. Задайте две глобальных переменные pos и orient.

global pos
global orient

Глобальные переменные pos и orient присвоены в exampleHelperROSPoseCallback функционируйте, когда новые данные о сообщении будут получены на /pose тема.

Ожидайте в течение нескольких секунд, чтобы убедиться, что подписчик может получить сообщения. Актуальнейшее положение и данные об ориентации будут всегда храниться в pos и orient переменные.

pause(2) 
pos
pos = 1×3

   -0.1612   -0.2381    0.0105

orient
orient = 1×3

   -0.2323    0.2905    0.1572

Если вы вводите в pos и orient несколько раз в командной строке, вы видите, что значения постоянно обновляются.

Остановите подписчика положения путем очищения переменной подписчика

clear robotpose

Примечание: существуют другие способы извлечь информацию из функций обратного вызова помимо использования глобальных переменных. Например, можно передать объект указателя в качестве дополнительного аргумента к функции обратного вызова. См. документацию Определения Коллбэка для получения дополнительной информации об определении функций обратного вызова.

Опубликуйте сообщения

Создайте издателя, который отправляет сообщения строки ROS в /chatter тема (см. работу с Основными сообщениями ROS).

chatterpub = rospublisher('/chatter','std_msgs/String')
chatterpub = 
  Publisher with properties:

         TopicName: '/chatter'
    NumSubscribers: 0
        IsLatching: 1
       MessageType: 'std_msgs/String'
        DataFormat: 'object'

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   
/tf     

Задайте подписчика для /chatter тема. exampleHelperROSChatterCallback называется, когда новое сообщение получено и отображает содержимое строки в сообщении.

chattersub = rossubscriber('/chatter', @exampleHelperROSChatterCallback)
chattersub = 
  Subscriber with properties:

        TopicName: '/chatter'
    LatestMessage: [0x1 String]
      MessageType: 'std_msgs/String'
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSChatterCallback
       DataFormat: 'object'

Опубликуйте сообщение к /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_98311 with NodeURI http://bat1071901glnxa64:43203/
Shutting down ROS master on http://192.168.0.10:57348.

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