Вызов и предоставление услуг ROS

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

Удалите примеры узлов и сервисных серверов из сети 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/.

Следующие шаги