Сообщения АФК являются основным контейнером для обмена данными в АФК 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 = 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 - поле данных структуры.
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