exponenta event banner

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

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

Эта связь между издателем и абонентом имеет следующие характеристики:

  • Темы используются для общения «многие ко многим». Несколько издателей могут отправлять сообщения в одну и ту же тему, а несколько подписчиков могут их получать.

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

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

  • Дождитесь получения нового сообщения или

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

Предпосылки: начало работы с ROS 2, подключение к сети ROS 2

Подписка и ожидание сообщений

Создайте образец сети ROS 2 с несколькими издателями и подписчиками.

exampleHelperROS2CreateSampleNetwork

Использовать ros2 topic list для просмотра доступных тем.

ros2 topic list
/parameter_events

Предположим, что вы хотите подписаться на /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.0156    0.0281    0.0175
disp(orient)
   -0.0493    0.0102   -0.0113

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

Остановите абонента позы, очистив переменную абонента

clear poseSub
clear controlNode

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

Опубликовать сообщения

Создание издателя, который отправляет строковые сообщения 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
/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 

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