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

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

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

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

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

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

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

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

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

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

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

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

rosinit
Launching ROS Core...
Done in 0.70767 seconds.
Initializing ROS master on http://192.168.0.10:53195.
Initializing global node /matlab_global_node_58560 with NodeURI http://bat6312glnxa64:45185/

Создайте демонстрационную сеть 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://bat6312glnxa64:44745/)
 
Subscribers:
* /node_1 (http://bat6312glnxa64:42913/)
* /node_2 (http://bat6312glnxa64:43297/)

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

laser = rossubscriber("/scan","DataFormat","struct");
pause(2)

Использование receive ожидать нового сообщения. (Второй аргумент является тайм-аутом в секундах.) Выход scandata содержит полученные данные о сообщении.

scandata = receive(laser,10)
scandata = struct with fields:
       MessageType: 'sensor_msgs/LaserScan'
            Header: [1x1 struct]
          AngleMin: -0.5467
          AngleMax: 0.5467
    AngleIncrement: 0.0017
     TimeIncrement: 0
          ScanTime: 0.0330
          RangeMin: 0.4500
          RangeMax: 10
            Ranges: [640x1 single]
       Intensities: []

Некоторые типы сообщений имеют visualizers, сопоставленный с ними. Для сообщения LaserScan, rosPlot строит данные сканирования. MaximumRange пара "имя-значение" указывает максимальный диапазон графика.

figure
rosPlot(scandata,"MaximumRange",7)

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

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

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

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

robotpose = rossubscriber("/pose",@exampleHelperROSPoseCallback,"DataFormat","struct")
robotpose = 
  Subscriber with properties:

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

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

global pos
global orient

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

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

pause(2) 
pos
pos = 1×3

   -0.0414   -0.0238    0.0301

orient
orient = 1×3

   -0.0471    0.0429    0.0230

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

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

clear robotpose

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

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

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

chatterpub = rospublisher("/chatter","std_msgs/String","DataFormat","struct")
chatterpub = 
  Publisher with properties:

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

pause(2) % Wait to ensure publisher is registered

Создайте и заполните сообщение ROS, чтобы отправить к /chatter тема.

chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
chattermsg = struct with fields:
    MessageType: 'std_msgs/String'
           Data: 'hello world'

Используйте rostopic list проверять что /chatter тема доступна в сети ROS.

rostopic list
/chatter
/pose   
/rosout 
/scan   
/tf     

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

chattersub = rossubscriber("/chatter",@exampleHelperROSChatterCallback,"DataFormat","struct")
chattersub = 
  Subscriber with properties:

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

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

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