Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Сервисы

Что вы узнаете в этом разделе:

  • Что такое сервисы в ROS и чем они отличаются от топиков
  • Модель взаимодействия Request-Response
  • Что такое клиент и сервер сервиса
  • Как работать с сервисами через консоль (CLI)
  • Как просмотреть список доступных сервисов
  • Как получить информацию о сервисе и вызвать его

Сервис (Service)

Ранее мы познакомились с такой сущностью как топики. По сути, работа с ними, это широко используемая Publisher-Subscriber модель коммуникации. Одни программы постоянно публикуют данные, другие эти данные получают. Использовать ее удобно, когда у нас есть постоянный поток данных (например данные датчиков и тп).

Но это не единственная модель коммуникации. Сегодня мы поговорим об еще одной модели взаимодействия между модулями в ROS, это модель Сервис (Service), которая использует паттерн взаимодействия Request-Response.

Эта модель коммуникации очень похожа на "удаленный" вызов функции. Одна программа вызывает функцию создавая Запрос (ServiceRequest), а другая программа получая запрос, формирует Ответ (ServiceResponse), и возвращает ее программе вызвавшей сервис.

Аналогия из жизни: Сервис можно сравнить с походом в ресторан. Клиент (Service client) делает заказ (запрос) официанту: "Принесите мне пиццу". Официант (сервер, Service server) передает заказ на кухню, получает готовое блюдо (ответ) и приносит его клиенту. Это взаимодействие "вопрос-ответ": клиент задает вопрос и ждет конкретный ответ. В отличие от топиков, где данные "текут" постоянно, сервис работает по принципу "спросил-получил ответ". Это как звонок в службу поддержки: вы звоните, задаете вопрос, получаете ответ и разговор заканчивается.

Запрос и Ответ обычно содержат переменные, необходимы для работы программы, но также они могут быть пустыми.

Мы можем выделить еще два определения, которые касаются Сервисов

  • Клиент (Service client) -- это программа, которая создает Запрос, и отправляет его на Сервер.
  • Сервер (Service server) -- это программа, которая ожидает Запрос от Клиента, производит вычисления и отправляет результат вычислений Ответ (в том числе и "пустым" ответом).

Service

Работа с сервисами через cli

Для работы с сервисами есть утилита ros2 service

Запустим команду и посмотрим вывод основных параметров

ros2 service
===

Основные команды:
  call  Вызов сервиса
  info  Получение информации о сервисе
  list  Список доступных сервисов

Получение списка доступных сервисов

Выполним команду

ros2 service list
===
/board_info
....
/camera/list_parameters
...
/domain_id
/power/reset
/reset
...
/start_motor
/stop_motor

Получение информации о сервисе

Мы получили список названий доступных сервисов (запущенных). Разобраться, какие сервисы что делают, можно в инструкции к Роботу или в описании установленных и запущенных пакетов.

Например, в инструкции указано, что сервис /start_motor (std_srvs/srv/Empty) запустит мотор лидара.

Посмотрим информацию о сервисе.

ros2 service info /stop_motor
===

Type: std_srvs/srv/Empty
Clients count: 0
Services count: 1

Мы получили тип сообщения std_srvs/srv/Empty (пустое сообщение) которое нам необходимо использовать для вызова сервиса.

Вызов сервиса

Вызовем сервис остановки мотора лидара с "пустым" сообщением.

ros2 service call /stop_motor std_srvs/srv/Empty "{}"
===
waiting for service to become available...
requester: making request: std_srvs.srv.Empty_Request()

response:
std_srvs.srv.Empty_Request()

При выполнении команды мы видим создание пустого запроса std_srvs.srv.Empty_Request() и получение ответа std_srvs.srv.Empty_Request(). После получения ответа, лидар должен перестать вращаться.

В данном случае сервис используется без параметров (у функции остановить мотор нет параметров), также сервису нечего сообщить о результате своей работы.

Рассмотрим пример вызова сервиса, которые вернет параметры системной платы Turtlebro.

Для этого вызовем сервис /board_info

ros2 service call /board_info turtlebro/srv/BoardInfo "request: {}"
waiting for service to become available...
requester: making request: turtlebro.srv.BoardInfo_Request(request=std_msgs.msg.Empty())

response:
turtlebro.srv.BoardInfo_Response(mcu_id=std_msgs.msg.String(data='002300533034510A30323536'), firmware_version=std_msgs.msg.String(data='TB2_microros'))

Мы получили данные о серийном номере MCU и версии системной прошивки платы

  • mcu_id: 002300533034510A30323536
  • firmware_version: TB2_microros