ROS Service 通信简单示例

需求

在无人机任务执行的过程中,可能会遇到不可识别的单位,需要将采集到的数据,传输给数据处理节点,并获取有关信息。

在此,我们将实现client提交两个整数,server负责计算并返回给client。

服务端 Service Node

思路

  1. 初始化 ROS 节点和句柄;

  2. 创建服务并发布到 ROS;

  3. 编写回调函数;

cpp实现

创建 add_two_ints_server.cpp 文件:

#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;
}

代码解释

beginner_tutorials/AddTwoInts.h是我们前面创建的.srv文件生成的头文件。

这一方法为实现两个int相加服务。它携带两个参数,分别为.srv文件的 Request 和 Response 部分,并返回一个 boolean 值。

两个整数相加并存储在 Response 部分。

打印请求响应相关信息。

最后完成服务并返回 true

这一语句将创建并发布服务信息。第一个参数是 service名字,第二个是回调函数名。

Notes :

  • 转化长整型的原因:beginner_tutorials::AddTwoIntsResponse_<std::allocator<void> >::_sum_type {aka long int}

服务端 Client Node

思路

  1. 初始化 ROS 节点、句柄;

  2. 创建该服务的Client 对象;

  3. 填写srv消息的request部分;

  4. 调用服务;

cpp实现

创建 add_two_ints_client.cpp 文件:

代码解释

这将为 add_two_ints 服务创建一个客户端。ros::Service Client 对象用于稍后调用服务。

在这里,我们实例化一个自动生成的服务类,并将值分配给它的成员变量 request。 一个服务类包含两个部分,请求request和响应response。它还包含两个类定义,请求Request 和响应 Response

这是实际调用服务的地方。该服务调用是阻塞的,调用返程即返回。 如果服务调用成功, call() 将返回 true 并且 srv.response 中的值将是有效的。 如果调用不成功, call() 将返回 false 并且 srv.response 中的值将无效。

编译

CMakeLists.txt

catkin_make

如果编译失败,很大的原因是因为前面创建AddTwoInts.srv的问题。

运行

运行 roscore

运行 Server Node

打开新终端,设置环境变量,运行节点:

运行 Client Node

在client节点:

在 server节点:

优化

值得注意的是,在这里我们先启动了 server,后启动了client。如果先启动 client,服务会调用失败。

在这里我们可以使用client.waitForExistence()ros::service::waitForService("add_two_ints")来进行程序的优化。即使client先启动也会一直等待服务的启动。

launch文件启动

在 launch 文件夹下创建 server_client.launch 文件,输入:

Notesargs是命令行参数,即 add_two_ints_client a b。事实上使用 launch 文件启动,后面还会有两个参数__name:=xxx__logs:=xxx

打开命令行,输入执行:

Reference

Last updated