exponenta event banner

Работа с базовыми сообщениями ROS 2

Сообщения АФК являются основным контейнером для обмена данными в АФК 2. Издатели и подписчики обмениваются данными, используя сообщения по указанным темам для переноса данных между узлами. Дополнительные сведения об отправке и получении сообщений см. в разделе Обмен данными с издателями и подписчиками ROS 2.

Для идентификации структуры данных каждое сообщение имеет тип сообщения. Например, данные датчика от лазерного сканера обычно посылаются в сообщении типа sensor_msgs/LaserScan. Каждый тип сообщения идентифицирует элементы данных, которые содержатся в сообщении. Каждое имя типа сообщения представляет собой комбинацию имени пакета, за которым следуют косая черта/и имя типа:

MATLAB ® поддерживает многие типы сообщений ROS 2, которые обычно встречаются в приложениях робототехники. В этом примере рассматриваются некоторые способы создания, проверки и заполнения сообщений ROS 2 в MATLAB.

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

Поиск типов сообщений

Использовать exampleHelperROS2CreateSampleNetwork для заполнения сети ROS 2 тремя узлами и установки издателей образцов и подписчиков по конкретным темам.

exampleHelperROS2CreateSampleNetwork

Использовать ros2 topic list -t для поиска доступных тем и связанных с ними типов сообщений.

ros2 topic list -t
            Topic                       MessageType           
    _____________________    _________________________________

    {'/parameter_events'}    {'rcl_interfaces/ParameterEvent'}

Чтобы узнать больше о типе сообщения темы, используйте ros2message для создания пустого сообщения того же типа. ros2message поддерживает заполнение закладки для типа сообщения. Чтобы быстро заполнить имена типов сообщений, введите первые несколько символов имени, которое требуется заполнить, и нажмите клавишу Tab.

scanData = ros2message("sensor_msgs/LaserScan")
scanData = struct with fields:
        MessageType: 'sensor_msgs/LaserScan'
             header: [1x1 struct]
          angle_min: 0
          angle_max: 0
    angle_increment: 0
     time_increment: 0
          scan_time: 0
          range_min: 0
          range_max: 0
             ranges: 0
        intensities: 0

созданное сообщение, scanData, имеет много полей, связанных с данными, обычно получаемыми от лазерного сканера. Например, минимальное расстояние считывания сохраняется в range_min свойство и максимальное расстояние считывания в range_max собственность.

Теперь созданное сообщение можно удалить.

clear scanData

Для просмотра полного списка всех типов сообщений, доступных для тем и служб, используйте ros2 msg list.

Изучение структуры сообщений и получение данных сообщений

Сообщения ROS 2 представлены в виде структур, а данные сообщения хранятся в полях. MATLAB предоставляет удобные способы поиска и изучения содержимого сообщений.

Использовать ros2 msg show для просмотра определения типа сообщения.

ros2 msg show geometry_msgs/Twist
# This expresses velocity in free space broken into its linear and angular parts.

Vector3  linear
Vector3  angular

Если вы подписались на /pose вы можете получать и просматривать отправляемые сообщения.

controlNode = ros2node("/base_station");
poseSub = ros2subscriber(controlNode,"/pose","geometry_msgs/Twist")
poseSub = 
  ros2subscriber with properties:

        TopicName: '/pose'
    LatestMessage: []
      MessageType: 'geometry_msgs/Twist'
    NewMessageFcn: []
          History: 'keeplast'
            Depth: 10
      Reliability: 'reliable'
       Durability: 'volatile'

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

poseData = receive(poseSub,10)
poseData = struct with fields:
    MessageType: 'geometry_msgs/Twist'
         linear: [1x1 struct]
        angular: [1x1 struct]

Сообщение имеет тип geometry_msgs/Twist. В сообщении есть два других поля: linear и angular. Значения этих полей сообщений можно просмотреть путем непосредственного доступа к ним.

poseData.linear
ans = struct with fields:
    MessageType: 'geometry_msgs/Vector3'
              x: 0.0457
              y: -0.0015
              z: 0.0300

poseData.angular
ans = struct with fields:
    MessageType: 'geometry_msgs/Vector3'
              x: -0.0358
              y: -0.0078
              z: 0.0416

Можно видеть, что каждое из значений этих полей сообщений фактически само по себе является сообщением. geometry_msgs/Twist является составным сообщением, состоящим из двух geometry_msgs/Vector3 сообщения.

Доступ к данным для этих вложенных сообщений работает точно так же, как и доступ к данным в других сообщениях. Доступ к x компонента linear сообщение с помощью этой команды:

xPose = poseData.linear.x
xPose = 0.0457

Установка данных сообщения

Также можно задать значения свойств сообщений. Создание сообщения с типом geometry_msgs/Twist.

twist = ros2message("geometry_msgs/Twist")
twist = struct with fields:
    MessageType: 'geometry_msgs/Twist'
         linear: [1x1 struct]
        angular: [1x1 struct]

Числовые свойства этого сообщения инициализируются как 0 по умолчанию. Можно изменить любое из свойств этого сообщения. Установить linear.y поле до 5.

twist.linear.y = 5;

Можно просмотреть данные сообщения, чтобы убедиться, что изменения вступили в силу.

twist.linear
ans = struct with fields:
    MessageType: 'geometry_msgs/Vector3'
              x: 0
              y: 5
              z: 0

После заполнения сообщения данными его можно использовать с издателями и подписчиками.

Копировать сообщения

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

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

tempMsgBlank = ros2message("sensor_msgs/Temperature");
tempMsgCopy = tempMsgBlank
tempMsgCopy = struct with fields:
    MessageType: 'sensor_msgs/Temperature'
         header: [1x1 struct]
    temperature: 0
       variance: 0

Изменение temperature свойство tempMsg и обратите внимание, что содержимое tempMsgBlank остаются неизменными.

tempMsgCopy.temperature = 100
tempMsgCopy = struct with fields:
    MessageType: 'sensor_msgs/Temperature'
         header: [1x1 struct]
    temperature: 100
       variance: 0

tempMsgBlank
tempMsgBlank = struct with fields:
    MessageType: 'sensor_msgs/Temperature'
         header: [1x1 struct]
    temperature: 0
       variance: 0

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

thermometerNode = ros2node("/thermometer");
tempPub = ros2publisher(thermometerNode,"/temperature","sensor_msgs/Temperature");
tempMsgs(10) = tempMsgBlank;    % Pre-allocate message structure array
for iMeasure = 1:10
    % Copy blank message fields
    tempMsgs(iMeasure) = tempMsgBlank;
    
    % Record sample temperature
    tempMsgs(iMeasure).temperature = 20+randn*3;
    
    % Only calculate the variation once sufficient data observed
    if iMeasure >= 5
        tempMsgs(iMeasure).variance = var([tempMsgs(1:iMeasure).temperature]);
    end
    
    % Pass the data to subscribers
    send(tempPub,tempMsgs(iMeasure))
end
errorbar([tempMsgs.temperature],[tempMsgs.variance])

Figure contains an axes. The axes contains an object of type errorbar.

Сохранить и загрузить сообщения

Можно сохранять сообщения и содержимое для последующего использования.

Получение нового сообщения от абонента.

poseData = receive(poseSub,10)
poseData = struct with fields:
    MessageType: 'geometry_msgs/Twist'
         linear: [1x1 struct]
        angular: [1x1 struct]

Сохраните данные позы в MAT-файл с помощью save функция.

save("poseFile.mat","poseData")

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

clear poseData

Теперь можно загрузить данные сообщения путем вызова load функция. Это загружает poseData сверху в messageData структура. poseData - поле данных структуры.

messageData = load("poseFile.mat")
messageData = struct with fields:
    poseData: [1x1 struct]

Исследовать messageData.poseData для просмотра содержимого сообщения.

messageData.poseData
ans = struct with fields:
    MessageType: 'geometry_msgs/Twist'
         linear: [1x1 struct]
        angular: [1x1 struct]

Теперь можно удалить файл MAT.

delete("poseFile.mat")

Отключение от сети ROS 2

Удалите образцы узлов, издателей и подписчиков из сети ROS 2.

exampleHelperROS2ShutDownSampleNetwork

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