Первичный механизм для узлов ROS, чтобы обмениваться данными отправляет и получает сообщения. Сообщения передаются по теме, и каждая тема имеет уникальное имя в сети ROS. Если узел хочет поделиться информацией, он использует издателя, чтобы отправить данные в тему. Узел, который хочет получить ту информацию, использует подписчика на ту же самую тему. Помимо ее уникального имени, каждая тема также имеет тип сообщения, который определяет типы сообщений, которые способны к тому, чтобы быть переданным под той темой.
Эта коммуникация издателя и подписчика имеет следующие характеристики:
Темы используются для many-many коммуникации. Многие издатели могут отправить сообщения в ту же тему, и многие подписчики могут получить их.
Издатели и подписчики разъединяются через темы и могут быть созданы и уничтожены в любом порядке. Сообщение может быть опубликовано к теме, даже при отсутствии активных подписчиков.
Концепция тем, издателей и подписчиков проиллюстрирована на рисунке:
В этом примере показано, как опубликовать и подписаться на темы в сети ROS. Это также показывает как:
Ожидайте, пока новое сообщение не получено
Используйте коллбэки, чтобы обработать новые сообщения в фоновом режиме
Необходимые условия: Начало работы с ROS, подключением к сети ROS
Запустите ведущее устройство ROS в MATLAB® с помощью rosinit
команда.
rosinit
Launching ROS Core... Done in 0.70767 seconds. Initializing ROS master on http://192.168.0.10:53195. Initializing global node /matlab_global_node_58560 with NodeURI http://bat6312glnxa64:45185/
Создайте демонстрационную сеть ROS с несколькими издателями и подписчиками, использующими обеспеченную функцию помощника exampleHelperROSCreateSampleNetwork.
exampleHelperROSCreateSampleNetwork
Использование rostopic
list
видеть, какие темы доступны.
rostopic list
/pose /rosout /scan /tf
Используйте rostopic info
проверять, публикуют ли какие-либо узлы к /scan
тема. Команда ниже показов, что node_3
публикует к нему.
rostopic info /scan
Type: sensor_msgs/LaserScan Publishers: * /node_3 (http://bat6312glnxa64:44745/) Subscribers: * /node_1 (http://bat6312glnxa64:42913/) * /node_2 (http://bat6312glnxa64:43297/)
Использование rossubscriber
подписываться на /scan
тема. Если тема уже существует в сети ROS (как имеет место здесь), rossubscriber
обнаруживает его тип сообщения автоматически, таким образом, вы не должны задавать его. Используйте сообщения в формате struct для лучшего КПД.
laser = rossubscriber("/scan","DataFormat","struct"); pause(2)
Использование receive
ожидать нового сообщения. (Второй аргумент является тайм-аутом в секундах.) Выход scandata
содержит полученные данные о сообщении.
scandata = receive(laser,10)
scandata = struct with fields:
MessageType: 'sensor_msgs/LaserScan'
Header: [1x1 struct]
AngleMin: -0.5467
AngleMax: 0.5467
AngleIncrement: 0.0017
TimeIncrement: 0
ScanTime: 0.0330
RangeMin: 0.4500
RangeMax: 10
Ranges: [640x1 single]
Intensities: []
Некоторые типы сообщений имеют visualizers, сопоставленный с ними. Для сообщения LaserScan, rosPlot
строит данные сканирования. MaximumRange
пара "имя-значение" указывает максимальный диапазон графика.
figure
rosPlot(scandata,"MaximumRange",7)
Вместо использования receive
чтобы получить данные, можно задать функцию, которая будет названа, когда новое сообщение получено. Это позволяет другому коду MATLAB выполняться, в то время как подписчик ожидает новых сообщений. Коллбэки важны, если вы хотите использовать несколько подписчиков.
Подпишитесь на /pose
тема, с помощью функции обратного вызова exampleHelperROSPoseCallback
.
robotpose = rossubscriber("/pose",@exampleHelperROSPoseCallback,"DataFormat","struct")
robotpose = Subscriber with properties: TopicName: '/pose' LatestMessage: [] MessageType: 'geometry_msgs/Twist' BufferSize: 1 NewMessageFcn: @exampleHelperROSPoseCallback DataFormat: 'struct'
Один способ осуществлять обмен данными между вашей основной рабочей областью и функцией обратного вызова состоит в том, чтобы использовать глобальные переменные. Задайте две глобальных переменные pos
и orient
.
global pos global orient
Глобальные переменные pos
и orient
присвоены в exampleHelperROSPoseCallback
функционируйте, когда новые данные о сообщении будут получены на /pose
тема.
Ожидайте в течение нескольких секунд, чтобы убедиться, что подписчик может получить сообщения. Актуальнейшее положение и данные об ориентации будут всегда храниться в pos
и orient
переменные.
pause(2) pos
pos = 1×3
-0.0414 -0.0238 0.0301
orient
orient = 1×3
-0.0471 0.0429 0.0230
Если вы вводите в pos
и orient
несколько раз в командной строке, вы видите, что значения постоянно обновляются.
Остановите подписчика положения путем очищения переменной подписчика
clear robotpose
Примечание: существуют другие способы извлечь информацию из функций обратного вызова помимо использования глобальных переменных. Например, можно передать объект указателя в качестве дополнительного аргумента к функции обратного вызова. См. документацию Определения Коллбэка для получения дополнительной информации об определении функций обратного вызова.
Создайте издателя, который отправляет сообщения строки ROS в /chatter
тема (см. работу с Основными сообщениями ROS).
chatterpub = rospublisher("/chatter","std_msgs/String","DataFormat","struct")
chatterpub = Publisher with properties: TopicName: '/chatter' NumSubscribers: 0 IsLatching: 1 MessageType: 'std_msgs/String' DataFormat: 'struct'
pause(2) % Wait to ensure publisher is registered
Создайте и заполните сообщение ROS, чтобы отправить к /chatter
тема.
chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
chattermsg = struct with fields:
MessageType: 'std_msgs/String'
Data: 'hello world'
Используйте rostopic list
проверять что /chatter
тема доступна в сети ROS.
rostopic list
/chatter /pose /rosout /scan /tf
Задайте подписчика для /chatter
тема. exampleHelperROSChatterCallback
называется, когда новое сообщение получено и отображает содержимое строки в сообщении.
chattersub = rossubscriber("/chatter",@exampleHelperROSChatterCallback,"DataFormat","struct")
chattersub = Subscriber with properties: TopicName: '/chatter' LatestMessage: [] MessageType: 'std_msgs/String' BufferSize: 1 NewMessageFcn: @exampleHelperROSChatterCallback DataFormat: 'struct'
Опубликуйте сообщение к /chatter
тема. Строка отображена коллбэком подписчика.
send(chatterpub,chattermsg) pause(2)
ans = 'hello world'
exampleHelperROSChatterCallback
функция была вызвана, как только вы опубликовали сообщение строки.
Удалите демонстрационные узлы, издателей и подписчиков от сети ROS. Очистите глобальные переменные pos
и orient.
exampleHelperROSShutDownSampleNetwork clear global pos orient
Закройте ведущее устройство ROS и удалите глобальный узел.
rosshutdown
Shutting down global node /matlab_global_node_58560 with NodeURI http://bat6312glnxa64:45185/ Shutting down ROS master on http://192.168.0.10:53195.
Чтобы узнать больше, как сообщения ROS обработаны в MATLAB, смотрите работу с Основными сообщениями ROS и работу со Специализированными сообщениями ROS.
Чтобы исследовать сервисы ROS, обратитесь к Call and Provide ROS Services.