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

Сообщения являются первичным контейнером для обмена данными в ROS. Темы и сервисы используют сообщения, чтобы нести данные между узлами. (См., обмениваются Данными с ROS Publishers and Subscribers and Call and Provide ROS Services для получения дополнительной информации о темах и службами),

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

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

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

Найдите типы сообщений

Инициализируйте ведущее устройство ROS и глобальный узел.

rosinit
Launching ROS Core...
Done in 0.6886 seconds.
Initializing ROS master on http://192.168.0.10:56665.
Initializing global node /matlab_global_node_10095 with NodeURI http://bat6312glnxa64:42681/

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

exampleHelperROSCreateSampleNetwork

Существуют различные узлы в сети с несколькими темами и аффилированными издателями и подписчиками.

Вы видите полный список доступных тем путем вызова rostopic list.

rostopic list
/pose  
/rosout
/scan  
/tf    

Если вы хотите знать больше о типе данных, которые отправляются через /scan тема, используйте rostopic info команда, чтобы исследовать его. /scan имеет тип сообщения sensor_msgs/LaserScan.

rostopic info /scan
Type: sensor_msgs/LaserScan
 
Publishers:
* /node_3 (http://bat6312glnxa64:33361/)
 
Subscribers:
* /node_1 (http://bat6312glnxa64:40935/)
* /node_2 (http://bat6312glnxa64:44577/)

Выход команды также говорит вам, которых узлы публикуют и подписывают на тему. Чтобы узнать об издателях и подписчиках, смотрите Call and Provide ROS Services.

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

Для лучшего КПД при создании сообщений или передачи, используйте сообщения в формате структуры.

scandata = rosmessage("sensor_msgs/LaserScan","DataFormat","struct")
scandata = struct with fields:
       MessageType: 'sensor_msgs/LaserScan'
            Header: [1x1 struct]
          AngleMin: 0
          AngleMax: 0
    AngleIncrement: 0
     TimeIncrement: 0
          ScanTime: 0
          RangeMin: 0
          RangeMax: 0
            Ranges: [0x1 single]
       Intensities: [0x1 single]

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

Чтобы видеть полный список всех типов сообщений, доступных для тем и сервисов, используйте rosmsg list.

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

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

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

posesub = rossubscriber("/pose","DataFormat","struct")
posesub = 
  Subscriber with properties:

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

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

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.0315
              Y: 0.0406
              Z: -0.0373

posedata.Angular
ans = struct with fields:
    MessageType: 'geometry_msgs/Vector3'
              X: 0.0413
              Y: 0.0132
              Z: -0.0402

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

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

xpos = posedata.Linear.X
xpos = 0.0315

Если вы хотите быстрые сводные данные всех данных, содержавшихся в сообщении, вызовите rosShowDetails функция. rosShowDetails работает над сообщениями любого типа и рекурсивно отображает все поля данных сообщения.

rosShowDetails(posedata)
ans = 
    '
       MessageType :  geometry_msgs/Twist
       Linear         
         MessageType :  geometry_msgs/Vector3
         X           :  0.03147236863931789
         Y           :  0.04057919370756193
         Z           :  -0.03730131837064939
       Angular        
         MessageType :  geometry_msgs/Vector3
         X           :  0.04133758561390194
         Y           :  0.01323592462254095
         Z           :  -0.04024595950005905'

rosShowDetails помогает вам во время отладки и, когда это необходимо, быстро исследовать содержимое сообщения.

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

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

twist = rosmessage("geometry_msgs/Twist","DataFormat","struct")
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

Если сообщение заполняется с вашими данными, можно использовать его с издателями, подписчиками и сервисами. Смотрите Данные о Exchange с примерами ROS Publishers and Subscribers and Call and Provide ROS Services.

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

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

Получите новое сообщение от подписчика.

posedata = receive(posesub,10)
posedata = struct with fields:
    MessageType: 'geometry_msgs/Twist'
         Linear: [1x1 struct]
        Angular: [1x1 struct]

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

save('posedata.mat','posedata')

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

clear posedata

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

messageData = load('posedata.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('posedata.mat')

Массивы в сообщениях

Некоторые сообщения от ROS хранятся в или содержат массивы других сообщений.

В вашей рабочей области, переменной tf содержит демонстрационное сообщение. (exampleHelperROSCreateSampleNetwork скрипт создал переменную.) В этом случае это - сообщение типа tf/tfMessage используемый для координатных преобразований.

tf
tf = struct with fields:
    MessageType: 'tf/tfMessage'
     Transforms: [1x53 struct]

tf имеет два поля: MessageType содержит стандартный массив данных и Transforms содержит объектный массив. Существует 53 сообщения, хранившие в Transforms, и у всех них есть та же структура.

Расширьте tf в Transforms видеть структуру:

tf.Transforms
ans=1×53 struct array with fields:
    MessageType
    Header
    ChildFrameId
    Transform

Каждый объект в Transforms имеет четыре свойства. Можно расшириться, чтобы видеть Transform поле Transforms.

tformFields = tf.Transforms.Transform

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

cellTransforms = {tf.Transforms.Transform}
cellTransforms=1×53 cell array
  Columns 1 through 4

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 5 through 8

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 9 through 12

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 13 through 16

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 17 through 20

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 21 through 24

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 25 through 28

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 29 through 32

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 33 through 36

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 37 through 40

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 41 through 44

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 45 through 48

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Columns 49 through 52

    {1x1 struct}    {1x1 struct}    {1x1 struct}    {1x1 struct}

  Column 53

    {1x1 struct}

Это помещает все 53 объектных записи в массив ячеек, позволяя вам получить доступ к ним с индексацией.

Кроме того, можно получить доступ к элементам массива тем же путем, вы получаете доступ к стандартным векторам MATLAB:

tf.Transforms(5)
ans = struct with fields:
     MessageType: 'geometry_msgs/TransformStamped'
          Header: [1x1 struct]
    ChildFrameId: '/imu_link'
       Transform: [1x1 struct]

Доступ к компоненту перевода пятого преобразования в списке 53:

tf.Transforms(5).Transform.Translation
ans = struct with fields:
    MessageType: 'geometry_msgs/Vector3'
              X: 0.0599
              Y: 0
              Z: -0.0141

Закройте сеть ROS

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

exampleHelperROSShutDownSampleNetwork

Закройте ведущее устройство ROS и удалите глобальный узел.

rosshutdown
Shutting down global node /matlab_global_node_10095 with NodeURI http://bat6312glnxa64:42681/
Shutting down ROS master on http://192.168.0.10:56665.

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