Наряду с нодами, ROS предоставляет ещё один тип программ, называемый сервисами. Их главное отличие заключается в способе общения. Если нода посылает сообщение на топик и не заботится о том, получил ли его кто-нибудь, то при обращении к сервису нужно указать конкретно, к какому именно. Кроме того, сервис возвращает своему клиенту ответ, так что связь оказывается двусторонней и направленной. Как следует из названия, данный тип программ введён для выполнения вспомогательных действий и оказания услуг. Если провести аналогию с вокзалом, топик - это информационное табло отправления/прибытия поездов (оператор публикует актуальную информацию, пассажир идёт в нужное время на требуемый путь), а сервисом будет являться покупка билета или обращение в справочное окно.
Сервис подразумевает наличие клиента и сервера. Клиент отправляет запрос (request), а сервер возвращает ответ (response). Список доступных в данный момент сервисов можно получить по команде
rosservice list
Связанные с конкретным запущенным нодом сервисы отображаются в разделе "Services" по запросу
rosnode info имя_нода
Можно также узнать, к чему относится конкретный сервис. Для этого служит команда
rosservice node имя_сервиса
Общение происходит с помощью специальных сообщений. Узнать тип данных конкретного сервиса можно с помощью запроса
rosservice info имя_сервиса
Для описания сообщения служит команда, аналогичная rosmsg:
rossrv show тип_сообщения
Работать с сервисами можно как из командной строки, так и из программы. Для вызова из терминал служит команда
rosservice call имя_сервиса запрос
Например,
rosservice call /spawn 3 3 0 Mikey
поместит черепаху Mikey в положение x=3, y=3 под углом theta=0.
Попробуем по примеру из официального руководства создать свой сервис, который складывает 2 целых числа. Прежде всего, нам понадобится новый тип сообщения, включающий оба слагаемых и их сумму, а также папка, где должны располагаться все сервисные сообщения (в ROS она должна называться srv).
roscd ros_test
mkdir srv
По сути, сообщение описывается обычным текстовым файлом и его можно создать вручную, однако для данной операции уже есть файл в папке руководства, и его можно просто скопировать
roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
При работе с rospy от пользователя в большинстве случаев не требуется каких-либо дополнительных действий, кроме создания исполняемых файлов, но сервисы являются исключением. Во-первых, в файле package.xml необходимо добавить строки
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
которые объявляют зависимости пакета на этапе сборки и выполнения. После этого необходимо отредактировать файл CMakeLists.txt. Во-первых, нужно дополнить find_rospackage:
find_rospackage(catkin REQUIRED COMPONENTS
rospy
std_msgs
message_generation
)
Во-вторых, найти, раскомментировать add_service_files, и указать тип сообщения
add_service_files(
FILES
AddTwoInts.srv
)
В третьих, раскомментировать строки
generate_messages(
DEPENDENCIES
std_msgs
)
DEPENDENCIES
std_msgs
)
После сохранения изменений переходим в основную директорию и выполняем сборку
cd ../..
catkin_make install
rosmake ros_test
В результате ROS подготовит файлы для работы с Python, C++, Lisp и, возможно, чем-то ещё. После этого можно переходить к коду.
Ниже приведён код сервера add_server.py. Используемые для обмена сообщения импортируются из ros_test.srv. При запуске программы функция add_two_ints_server() создаёт ноду, но помимо неё определяется сервис, для которого указываются тип сообщения и функция, которая вызывается при обращении. rospy.spin() обеспечивает возможность многократного обращения к сервису. В данном случае, при получении запроса функция handle_add_two_ints() вычисляет сумму переданных чисел, выводит результат на экран и возвращает его клиенту (AddTwoIntsRepsonse() была сгенерирована системой автоматически при выполнении предыдущих команд).
Работа клиента начинается с проверки корректности вызова. Если всё верно, запускается функция add_two_ints_client(), которая ожидает появление сервиса 'add_two_ints', после чего отправляет запрос на выполнение требуемой операции (сложения двух чисел), и при получении ответа возвращает результат, который затем печатается на экране.
Остаётся сделать файлы исполняемыми
chmod +x scripts/add_server.py
chmod +x scripts/add_client.py
и проверить их работу
roscore
rosrun ros_test add_server.py
rosrun ros_test add_client.py 3 5
Комментариев нет:
Отправить комментарий