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("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("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++)


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна конкурс манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение