1. Написание простого сервиса и клиента (Python)
Описание: Этот урок описывает, как писать узлы сервиса/службы и клиента (Service and Client) на питоне.
1.1 Написание узла Сервиса (Service Node)
Здесь мы создадим узел сервиса («add_two_ints_server»), который будет получать два целых числа и возвращать их сумму.
Перейдите в каталог пакета beginner_tutorials, который вы создали на уроке создания пакета:
roscd beginner_tutorials
Пожалуйста, убедитесь, что вы следовали инструкциям на предыдущих уроках, т.к. для создания сервиса необходимо наличие файла AddTwoInts.srv
1.1.1 Код
Создайте файл nodes/add_two_ints_server.py в пакете beginner_tutorials и вставьте внутрь следующий код:
#!/usr/bin/env python import roslib; roslib.load_manifest('beginner_tutorials') from beginner_tutorials.srv import * import rospy def handle_add_two_ints(req): print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b)) return AddTwoIntsResponse(req.a + req.b) def add_two_ints_server(): rospy.init_node('add_two_ints_server') s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints) print "Ready to add two ints." rospy.spin() if __name__ == "__main__": add_two_ints_server()
Не забудьте сделать файл узла исполняемым:
chmod +x nodes/add_two_ints_server.py
1.1.2 Разъяснение кода
Теперь давайте разберём код.
Для написания сервиса с помощью rospy требуется совсем немного. Мы заявляем о своём узле с помощью init_node() и затем объявляем наш сервис:
s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
Это объявление имени нового сервиса add_two_ints с типом услуги — AddTwoInts. Все запросы, передаются функции handle_add_two_ints. handle_add_two_ints вызывается с экземплярами AddTwoIntsRequest и возвращает экземпляры AddTwoIntsResponse .
Так же, как с примером подписчика, rospy.spin() удерживает ваш код от выхода, пока сервиса не будет отключён.
1.2 Написание клиентского узла (Client Node)
1.2.1 Код
Создайте файл nodes/add_two_ints_client.py в пакете beginner_tutorials и вставьте в него следующий код:
#!/usr/bin/env python import roslib; roslib.load_manifest('beginner_tutorials') import sys import rospy from beginner_tutorials.srv import * def add_two_ints_client(x, y): rospy.wait_for_service('add_two_ints') try: add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts) resp1 = add_two_ints(x, y) return resp1.sum except rospy.ServiceException, e: print "Service call failed: %s"%e def usage(): return "%s [x y]"%sys.argv[0] if __name__ == "__main__": if len(sys.argv) == 3: x = int(sys.argv[1]) y = int(sys.argv[2]) else: print usage() sys.exit(1) print "Requesting %s+%s"%(x, y) print "%s + %s = %s"%(x, y, add_two_ints_client(x, y))
Не забудьте сделать файл узла исполняемым:
chmod +x nodes/add_two_ints_client.py
1.2.2 Разъяснение кода
Теперь давайте разберём код.
Клиентский код для вызова сервиса также прост. Для клиентов, вам не нужно вызывать init_node(). Первым идёт вызов:
rospy.wait_for_service('add_two_ints')
— это удобный метод, который блокирует выполнение скрипта, пока сервис с именем add_two_ints не станет доступен. Далее, мы создаем дескриптор (handle) для вызова сервиса:
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
Мы можем использовать этот дескриптор так же, как нормальную функцию и просто вызовем его:
resp1 = add_two_ints(x, y) return resp1.sum
Так как, мы объявили тип сервиса, как тип, который принимает AddTwoInts, то вызов add_two_ints осуществляет генерацию запроса AddTwoIntsRequest. Возвращаемое значение — это объект AddTwoIntsResponse. Если вызов не удался, то возможно возникновение ислючение rospy.ServiceException, так что вы можете установить соответствующий блок try/except.
1.3 Сборка ваших узлов
Мы используем CMake в качестве нашей системы сборки, да, вы должны использовать его даже для узлов Python. Это делается для того, чтобы убедиться, что создается автоматически сгенерированный Python-код для сообщений и сервисов. Мы также используем Makefile для удобства.
roscreate-pkg автоматически создаёт Makefile, так что вам не придется его редактировать.
Для сборки запустите:
$ make
Теперь, когда вы написали простой сервис и клиента, давайте проверим их работу.
Ссылки
http://www.ros.org/wiki/ROS/Tutorials/WritingServiceClient(python)