服务(Service)是节点之间同步通信的一种方式,允许客户端(Client)节点发布请求(Request),由服务端(Server)节点处理后反馈应答(Response)。
我们以一个简单的加法运算为例,具体研究ROS中的服务应用。在该例程中,Client发布两个需要相加的的 int 类型变量,Server 节点接收请求后完成运算并返回加法运算结果。
1、自定义服务数据
srv文件就是ROS中定义服务数据的文件,一般放置在功能包目录下的srv文件夹中。
打开RoboWare软件,选中前面建立的功能包 “learning” ,右击选择 “新建Srv文件夹” ;然后选中文件夹 srv ,右击选择 “新建SRV文件” ,文件名为 “AddTwoInts.srv" 。如下图所示:
针对加法运算例程中的服务需求,srv文件内容如下:
int64 a
int64 b
---
int64 sum
该文件包含请求与应答两个数据域,数据域中的内容与话题消息的数据类型相同,只是在请求与应答的描述之间,需要使用 “ — ” 进行分割。
2、创建Server
首先创建Server节点,提供加法运算的功能。
在 src 文件夹下新建 server.cpp ,内容如下:
#include "ros/ros.h"
#include "learning/AddTwoInts.h"
//service 回调函数,输入参数req, 输出参数 res
bool add(learning :: AddTwoInts :: Request &req,
learning :: AddTwoInts :: Response &res )
{
//将输入参数中的请求数据相加,结果放到应答变量中
res.sum = req.a + req.b ;
ROS_INFO("request : x=%1d, y=%1d", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%1d]", (long int)res.sum);
return true;
}
int main(int argc, char *argv[])
{
//ROS节点初始化
ros::init(argc, argv, "add_two_ints_server");
//创立节点句柄
ros::NodeHandle n;
//创建一个名为add_two_ints的Server,注册回调函数add()
ros::ServiceServer service = n.advertiseService("add_two_ints", add);
//循环等待回调函数
ROS_INFO("Ready to add two ints.");
ros::spin();
return 0;
}
2、创建Client
在 src 文件夹下新建client.cpp ,内容如下:
#include <cstdlib>
#include "ros/ros.h"
#include "learning/AddTwoInts.h"
int main(int argc, char *argv[])
{
//ROS节点初始化
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;
//创建一个Clint,请求add_two_ints_server
//消息类型是learning::AddTwoInts
ros::ServiceClient client = n.serviceClient<learning::AddTwoInts>("add_two_ints");
//创建learning :: AddTwoInts 类型的service消息
learning :: AddTwoInts srv;
srv.request.a = atoll (argv[1]);
srv.request.b = atoll (argv[2]);
//发布service请求,等待加法运算的应答结果
if(client.call(srv))
{
ROS_INFO("Sum: %1d", (long int)srv.response.sum);
}
else
{
ROS_INFO("Failed to call service add_two_ints");
return 1;
}
return 0;
}
代码编辑完成后,编辑CMakeList.txt ,RoboWare会自动配置好, 如下图所示:
3、编辑运行服务
3.1、编译工作空间
3.2、启动 roscore
3.3、运行 Server 节点
上图是Server 节点启动后的日志信息。
3.4、运行 Client 节点
上图是Client 节点启动后发布的服务请求,并成功收到的反馈结果。
上图是 Server 接受到服务调用后完成加法求解,并将结果反馈给 Client