Сообщения ROS являются основным контейнером для обмена данными в ROS 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 для типа сообщения. Чтобы быстро заполнить имена типов сообщений, введите первые несколько символов имени, которое вы хотите заполнить, и нажмите клавишу 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 по умолчанию. Можно изменить любые свойства этого сообщения. Установите inear.y l поле до 5.
twist.linear.y = 5;
Можно просмотреть данные сообщения, чтобы убедиться, что ваше изменение вступило в эффект.
twist.linear
ans = struct with fields:
MessageType: 'geometry_msgs/Vector3'
x: 0
y: 5
z: 0
Как только сообщение заполнено вашими данными, вы можете использовать его с издателями и подписчиками.
Сообщения ROS 2 являются структурами. Они могут быть скопированы непосредственно, чтобы сделать новое сообщение. Каждая копия и исходные сообщения имеют свои данные.
Сделайте новое пустое сообщение, чтобы передать данные о температуре, а затем сделайте копию для изменения.
tempMsgBlank = ros2message("sensor_msgs/Temperature");
tempMsgCopy = tempMsgBlanktempMsgCopy = 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])

Можно сохранять сообщения и хранить содержимое для дальнейшего использования.
Получите новое сообщение от абонента.
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 - поле данных struct.
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.
exampleHelperROS2ShutDownSampleNetwork