ROS поддерживает два основных коммуникационных механизма: темы и сервисы. Темы имеют издателей и подписчиков и используются для отправки и получения сообщений (см., обмениваются Данными с Издателями ROS и Подписчиками). Сервисы, с другой стороны, реализуют более трудную связь путем разрешения коммуникации ответа запроса. Сервисный клиент отправляет сообщение запроса в сервисный сервер и ожидает ответа. Сервер будет использовать данные в просьбе создать сообщение ответа и передает его обратно клиенту. Каждый сервис имеет тип, который определяет структуру сообщений запроса и ответа. Сервисы также имеют имя, которое уникально в сети ROS.
Эта сервисная коммуникация имеет следующие характеристики:
Запрос на обслуживание (или сервисный вызов) используется для непосредственной коммуникации. Один узел будет инициировать запрос, и только один узел получит запрос и передаст ответ обратно.
Сервисный клиент и сервисный сервер сильно связываются, когда сервисный вызов выполняется. Сервер должен существовать во время сервисного вызова и если запрос отправлен, клиент блокируется, пока ответ не получен.
Концепция сервисов проиллюстрирована в следующем изображении:
Этот пример показывает вам, как настроить сервисные серверы, чтобы рекламировать сервис к сети ROS. Кроме того, вы изучите, как использовать сервисные клиенты, чтобы вызвать сервер и получить ответ.
Необходимые условия: Начало работы с ROS, подключением к сети ROS, обмениваются данными с издателями ROS и подписчиками
Прежде, чем исследовать сервисные концепции, запустите ведущее устройство ROS в MATLAB® и демонстрационной сети ROS. exampleHelperROSCreateSampleNetwork
создаст некоторые сервисные серверы, чтобы симулировать реалистическую сеть ROS.
rosinit
Launching ROS Core... ...Done in 3.16 seconds. Initializing ROS master on http://192.168.178.1:55438. Initializing global node /matlab_global_node_55791 with NodeURI http://ah-csalzber:51640/
exampleHelperROSCreateSampleNetwork
Предположим, что вы хотите сделать простой сервисный сервер, который отображает "Сервисный клиент, вызывает", когда вы вызываете сервис. Создайте сервис с помощью rossvcserver
команда. Задайте сервисное имя и сервисный тип сообщения. Также задайте функцию обратного вызова как exampleHelperROSEmptyCallback
. Функции обратного вызова для сервисных серверов имеют очень определенную подпись. Для получения дополнительной информации см. документацию rossvcserver
.
Для более быстрой эффективности используйте сервисы с сообщениями в формате структуры.
testserver = rossvcserver("/test","std_srvs/Empty",@exampleHelperROSEmptyCallback,"DataFormat","struct")
testserver = ServiceServer with properties: ServiceType: 'std_srvs/Empty' ServiceName: '/test' NewRequestFcn: @exampleHelperROSEmptyCallback DataFormat: 'struct'
Вы видите свой новый сервис, /test
, когда вы перечисляете все сервисы в сети ROS.
rosservice list
/add /matlab_global_node_55791/get_loggers /matlab_global_node_55791/set_logger_level /node_1/get_loggers /node_1/set_logger_level /node_2/get_loggers /node_2/set_logger_level /node_3/get_loggers /node_3/set_logger_level /reply /test
Можно получить больше информации о сервисном использовании rosservice
info
. Глобальный узел перечислен как узел, где сервисный сервер достижим, и вы также видите его std_srvs/Empty
сервисный тип.
rosservice info /test
Node: /matlab_global_node_55791 URI: rosrpc://ah-csalzber:51639 Type: std_srvs/Empty Args: MessageType
Используйте сервисные клиенты, чтобы запросить информацию у сервисного сервера ROS. Чтобы создать клиент, использовать rossvcclient
с сервисом называют как аргумент.
Создайте сервисный клиент для /test
сервис, который мы только создали.
testclient = rossvcclient("/test","DataFormat","struct")
testclient = ServiceClient with properties: ServiceType: 'std_srvs/Empty' ServiceName: '/test' DataFormat: 'struct'
Создайте пустое сообщение запроса для сервиса. Используйте rosmessage
функционируйте и передайте клиент в качестве первого аргумента. Это создаст функцию запроса на обслуживание, которая имеет тип сообщения и формат, который задан сервисом.
testreq = rosmessage(testclient)
testreq = struct with fields:
MessageType: 'std_srvs/EmptyRequest'
Убедитесь, что сервис соединяется с клиентом, ожидающим их, чтобы соединиться при необходимости.
waitForServer(testclient,"Timeout",3)
Когда это необходимо, чтобы получить ответ от сервера, используйте call
функция, которая вызывает сервисный сервер и возвращает ответ. Сервисный сервер, который вы создали прежде, возвратит пустой ответ. Кроме того, это вызовет exampleHelperROSEmptyCallback
функционируйте и отображается, строка "Сервисный клиент вызывает". Можно также задать Timeout
параметр, который указывает, сколько времени клиент должен ожидать ответа.
testresp = call(testclient,testreq,"Timeout",3);
Если вызов будет функционировать выше сбоев, он будет ошибка. Вместо ошибки, если вы предпочли бы реагировать на отказ вызова с помощью условных выражений, возвращают status
и statustext
выходные параметры от функции вызова. status
выведите указывает если вызов, за которым следуют, в то время как statustext
предоставляет дополнительную информацию. Подобные выходные параметры могут быть возвращены waitForServer
.
numCallFailures = 0; [testresp,status,statustext] = call(testclient,testreq,"Timeout",3); if ~status numCallFailures = numCallFailues + 1; fprintf("Call failure number %d. Error cause: %s\n",numCallFailures,statustext) else disp(testresp) end
MessageType: 'std_srvs/EmptyResponse'
До сих пор сервисный сервер не сделал никакой значимой работы, но можно использовать сервисы для расчетов и манипулирования данными. Создайте сервис, который добавляет два целых числа.
Существует существующий сервисный тип, roscpp_tutorials/TwoInts
, то, что мы можем использовать для этой задачи. Можно смотреть структуру сообщений запроса и ответа путем вызова rosmsg show
. Запрос содержит два целых числа, A
и B
, и ответ содержит их сложение в Sum
.
rosmsg show roscpp_tutorials/TwoIntsRequest
int64 A int64 B
rosmsg show roscpp_tutorials/TwoIntsResponse
int64 Sum
Создайте сервисный сервер с этим типом сообщения и функцией обратного вызова, которая вычисляет сложение. Для вашего удобства, exampleHelperROSSumCallback
функционируйте уже реализует это вычисление. Задайте функцию как коллбэк.
sumserver = rossvcserver("/sum","roscpp_tutorials/TwoInts",@exampleHelperROSSumCallback,"DataFormat","struct")
sumserver = ServiceServer with properties: ServiceType: 'roscpp_tutorials/TwoInts' ServiceName: '/sum' NewRequestFcn: @exampleHelperROSSumCallback DataFormat: 'struct'
Чтобы вызвать сервисный сервер, необходимо создать сервисный клиент. Обратите внимание на то, что этот клиент может быть создан где угодно в сети ROS. В целях этого примера мы создадим клиент для /sum
сервис в MATLAB.
sumclient = rossvcclient("/sum","DataFormat","struct")
sumclient = ServiceClient with properties: ServiceType: 'roscpp_tutorials/TwoInts' ServiceName: '/sum' DataFormat: 'struct'
Создайте сообщение запроса. Можно задать эти два целых числа, A
и B
, которые добавляются вместе, когда вы используете call
команда.
sumreq = rosmessage(sumclient); sumreq.A = int64(2); sumreq.B = int64(1)
sumreq = struct with fields:
MessageType: 'roscpp_tutorials/TwoIntsRequest'
A: 2
B: 1
Ожидание состоит в том, что сумма этих двух чисел будет 3. Чтобы вызвать сервис, используйте следующую команду. Сервисное сообщение ответа будет содержать Sum
свойство, которое хранит сложение A
и B
. Убедитесь, что сервисный сервер доступен перед звонком, и реагируйте соответственно, если это не.
if isServerAvailable(sumclient) sumresp = call(sumclient,sumreq,"Timeout",3) else error("Service server not available on network") end
sumresp = struct with fields:
MessageType: 'roscpp_tutorials/TwoIntsResponse'
Sum: 3
Удалите демонстрационные узлы и сервисные серверы от сети ROS.
exampleHelperROSShutDownSampleNetwork
Закройте ведущее устройство ROS и удалите глобальный узел.
rosshutdown
Shutting down global node /matlab_global_node_55791 with NodeURI http://ah-csalzber:51640/ Shutting down ROS master on http://192.168.178.1:55438.
Относитесь, чтобы работать с Основными сообщениями ROS, чтобы исследовать, как сообщения ROS представлены в MATLAB.