ROS поддерживает два основных механизма связи: темы и услуги. Темы имеют издателей и подписчиков и используются для отправки и приема сообщений (см. Exchange Data with ROS Publishers and Subscribers). Службы, с другой стороны, реализуют более тесную связь, позволяя обмен данными между запросом и ответом. Клиент службы отправляет сообщение запроса на сервер службы и ожидает ответа. Сервер использует данные в запросе, чтобы создать ответное сообщение и отправляет его обратно клиенту. Каждая услуга имеет тип, который определяет структуру сообщений запроса и ответа. Службы также имеют уникальное имя в сети ROS.
Эта коммуникация услуг имеет следующие характеристики:
Запрос на обслуживание (или сервисный вызов) используется для связи один к одному. Один узел инициирует запрос, и только один узел получит запрос и отправит ответ.
Клиент услуги и сервер службы тесно соединены при выполнении сервисного вызова. Сервер должен существовать во время вызова услуги, и после отправки запроса клиент блокируется до получения ответа.
Концепция услуг проиллюстрирована на следующем изображении:
В этом примере показано, как настроить серверы служб для объявления услуги в сети ROS. В сложение вы научитесь использовать сервисные клиенты для вызова сервера и получения ответа.
Необходимые условия: Запуск с ROS, подключение к сети ROS, обмен данными с ROS-издателями и подписчиками
Перед изучением концепций сервиса запустите мастер ROS в MATLAB ® и образец сети ROS. exampleHelperROSCreateSampleNetwork
создаст некоторые сервисные серверы для моделирования реалистичной сети ROS.
rosinit
Initializing ROS master on http://HYD-GDAVULUR:53363/. Initializing global node /matlab_global_node_86569 with NodeURI http://HYD-GDAVULUR:53367/
exampleHelperROSCreateSampleNetwork
Предположим, что при вызове службы вы хотите создать простой сервер обслуживания, на котором будет отображаться сообщение «A service client is calling». Создайте сервис с помощью rossvcserver
команда. Укажите имя службы и тип служебного сообщения. Также определите функцию обратного вызова как exampleHelperROSEmptyCallback
. Функции обратного вызова для серверов услуг имеют очень специфическую сигнатуру. Для получения дополнительной информации см. документацию rossvcserver
.
testserver = rossvcserver('/test', 'std_srvs/Empty', @exampleHelperROSEmptyCallback)
testserver = ServiceServer with properties: ServiceName: '/test' ServiceType: 'std_srvs/Empty' NewRequestFcn: @exampleHelperROSEmptyCallback
Вы можете увидеть свой новый сервис, /test
, при перечислении всех сервисов в сети ROS.
rosservice list
/add /reply /test
Вы можете получить больше информации о своем сервисе, используя rosservice
info
. Глобальный узел указан как узел, где сервисный сервер доступен, и вы также видите его std_srvs/Empty
тип услуги.
rosservice info /test
Node: /matlab_global_node_86569 URI: rosrpc://HYD-GDAVULUR:53368/ Type: std_srvs/Empty Args:
Используйте сервисные клиенты для запроса информации от сервера служб ROS. Чтобы создать клиент, используйте rossvcclient
с именем службы в качестве аргумента.
Создайте сервисный клиент для /test
сервис, который мы только что создали.
testclient = rossvcclient('/test')
testclient = ServiceClient with properties: ServiceName: '/test' ServiceType: 'std_srvs/Empty'
Создайте пустое сообщение запроса для службы. Используйте rosmessage
и передайте клиент как первый аргумент. Это позволит создать функцию запроса на обслуживание, которая имеет тип сообщения, заданный службой.
testreq = rosmessage(testclient)
testreq = ROS EmptyRequest message with properties: MessageType: 'std_srvs/EmptyRequest' Use showdetails to show the contents of the message
Когда вы хотите получить ответ от сервера, используйте call
функция, которая вызывает служебный сервер и возвращает ответ. Сервер службы, созданный вами ранее, вернет пустой ответ. В сложение он будет вызывать exampleHelperROSEmptyCallback
и отображает строку «Вызывает клиент службы». Можно также задать Timeout
параметр, который указывает, сколько времени клиент должен ждать ответа.
testresp = call(testclient,testreq,'Timeout',3);
До сих пор сервис-сервер не проделал никакой содержательной работы, но для расчетов и манипуляций с данными можно использовать сервисы. Создайте службу, которая добавляет два целых чисел.
Существует существующий тип сервиса, 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)
sumserver = ServiceServer with properties: ServiceName: '/sum' ServiceType: 'roscpp_tutorials/TwoInts' NewRequestFcn: @exampleHelperROSSumCallback
Чтобы вызвать сервер службы, необходимо создать клиент службы. Обратите внимание, что этот клиент может быть создан в любой точке сети ROS. В целях этого примера мы создадим клиента для /sum
сервис в MATLAB.
sumclient = rossvcclient('/sum')
sumclient = ServiceClient with properties: ServiceName: '/sum' ServiceType: 'roscpp_tutorials/TwoInts'
Создайте сообщение запроса. Можно задать два целых чисел, A
и B
, которые складываются вместе, когда вы используете call
команда.
sumreq = rosmessage(sumclient); sumreq.A = 2; sumreq.B = 1
sumreq = ROS TwoIntsRequest message with properties: MessageType: 'roscpp_tutorials/TwoIntsRequest' A: 2 B: 1 Use showdetails to show the contents of the message
Ожидается, что сумма этих двух чисел составит 3. Для вызова службы используйте следующую команду. Служебное ответное сообщение будет содержать Sum
свойство, которое хранит сложение A
и B
.
sumresp = call(sumclient,sumreq,'Timeout',3)
sumresp = ROS TwoIntsResponse message with properties: MessageType: 'roscpp_tutorials/TwoIntsResponse' Sum: 3 Use showdetails to show the contents of the message
Удалите примеры узлов и сервисных серверов из сети ROS.
exampleHelperROSShutDownSampleNetwork
Завершите работу хозяина ROS и удалите глобальный узел.
rosshutdown
Shutting down global node /matlab_global_node_86569 with NodeURI http://HYD-GDAVULUR:53367/ Shutting down ROS master on http://HYD-GDAVULUR:53363/.
Обратитесь к разделу Работа с базовыми сообщениями ROS, чтобы узнать, как сообщения ROS представлены в MATLAB.