ROS - Урок 15 - Написание простого Сервиса и Клиента (C++)


Содержание

1. Написание простого Сервиса и Клиента (Service and Client) (C++)

Описание: Этот урок описывает, как создавать узлы сервиса и клиента (Service and Client) на C++.

1.1 Написание узла Сервиса (Service Node)

Здесь мы создадим узел сервиса («add_two_ints_server»), который получает два целых числа и возвращает их сумму.

Перейдите в каталог пакета beginner_tutorials, который вы создали на уроке создания пакета:
roscd beginner_tutorials


Пожалуйста, убедитесь, что вы следовали инструкциям на предыдущих уроках, т.к. для создания сервиса необходимо наличие файла AddTwoInts.srv

1.1.1 Код

Создайте файл src/add_two_ints_server.cpp в пакете beginner_tutorials и вставьте в него следующий код:

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"

bool add(beginner_tutorials::AddTwoInts::Request  &req,
         beginner_tutorials::AddTwoInts::Response &res )
{
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
  return true;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "add_two_ints_server");
  ros::NodeHandle n;

  ros::ServiceServer service = n.advertiseService("add_two_ints", add);
  ROS_INFO("Ready to add two ints.");
  ros::spin();

  return 0;
}


1.1.2 Разъяснение кода

Теперь давайте разберём код.

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"


beginner_tutorials/AddTwoInts.h — это заголовочный файл, созданный на основе файла srv, который мы создали ранее.

bool add(beginner_tutorials::AddTwoInts::Request  &req,
         beginner_tutorials::AddTwoInts::Response &res )


Эта функция, собственно и реализует работу сервиса по сложению двух целых чисел, которые она принимает в запросе (req), а ответ помещает в тип, определенный в srv-файле (res) и возвращает логический флаг(bool).

{
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
  return true;
}


Здесь два целых складываются и их сумма сохраняется в ответ сервиса. Затем, информация о запросе и ответе заносятся в журнал (выводится в консоль). Функция завершается возвратом true.

ros::ServiceServer service = n.advertiseService("add_two_ints", add);


Этой строчкой создаётся сервис и об этом сообщается мастеру ROS.

1.2 Написание клиентского узла (Client Node)

1.2.1 Код

Создайте файл src/add_two_ints_client.cpp в пакете beginner_tutorials и вставьте в него следующий код:
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>

int main(int argc, char **argv)
{
  ros::init(argc, argv, "add_two_ints_client");
  if (argc != 3)
  {
    ROS_INFO("usage: add_two_ints_client X Y");
    return 1;
  }

  ros::NodeHandle n;
  ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
  beginner_tutorials::AddTwoInts srv;
  srv.request.a = atoll(argv[1]);
  srv.request.b = atoll(argv[2]);
  if (client.call(srv))
  {
    ROS_INFO("Sum: %ld", (long int)srv.response.sum);
  }
  else
  {
    ROS_ERROR("Failed to call service add_two_ints");
    return 1;
  }

  return 0;
}


1.2.2 Разъяснение кода

Теперь давайте разберём код.

ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");

Эта строчка создает клиент для службы add_two_ints. Объект ros::ServiceClient используется для последующего вызова службы.

beginner_tutorials::AddTwoInts srv;
  srv.request.a = atoll(argv[1]);
  srv.request.b = atoll(argv[2]);


Здесь мы создаем экземпляр автоматически сгенерированного класса для общения с сервисом, и присваиваем значения параметрам запроса (request). Класс состоит из двух членов, запрос (request) и ответ (response). Он также содержит два определения классов Request и Response.

if (client.call(srv))


Здесь и происходит вызов сервиса. Так как после вызова сервис блокируются, то возврат из функции происходит только после завершения вызова. Если вызов сервиса удался, то call() вернёт true и результирующее значение в srv.response. Если же вызов не удался, по call() вернёт false и значение в srv.response будет недействительным.

1.3 Сборка ваших узлов

Снова отредактируйте CMakeLists.txt в beginner_tutorials:
$ rosed beginner_tutorials CMakeLists.txt 


и добавьте в конец следующие строчки:
rosbuild_add_executable(add_two_ints_server src/add_two_ints_server.cpp)
rosbuild_add_executable(add_two_ints_client src/add_two_ints_client.cpp)


Это приведёт к созданию двух исполняемых файла «add_two_ints_server» и «add_two_ints_client», которые, по-умолчанию, будут в директории «bin».

Для получения дополнительной информации об использовании CMake с ROS см. CMakeLists

Запустите make:
$ make


Если сборка не удаётся:
убедитесь, что вы следовали инструкциям на предыдущем уроке: создание AddTwoInts.srv

Наберите
rosls beginner_tutorials/srv_gen/cpp/include/beginner_tutorials/
и убедитесь, что имя .h файла совпадает с названиям у директивы include в .cpp файлах клиента и сервиса.

Теперь, когда вы написали простой сервис и клиента, давайте проверим их работу.

Ссылки:
http://www.ros.org/wiki/ROS/Tutorials/WritingServiceClient(c++)
  • 0
  • 29 декабря 2011, 21:14
  • noonv

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.