您的位置:首页 > 其它

ROS学习(基于Ubuntu 15.04 和ROS Jade)第三章 ROS核心教程 之 13 编写简单的服务器和客户端

2017-08-02 13:27 471 查看

引言

本节介绍如何编写服务器和客户端节点。

1.编写service节点

我们将创建一个简单的service节点(add_two_ints_server),该节点接收两个整形数字并返回它们的和。要确保已经安装之前的教程创建了所需要的srv。

在beginner_tutorials/src目录中创建add_two_ints_server.cpp文件

1.1 源代码

#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.2 explained

#include "beginner_tutorials/AddTwoInts.h"


beginner_tutorials/AddTwoInts.h
是之前由编译器根据我们创建的srv文件生成的头文件。

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


这是一个请求回调函数,当请求到达时,执行此函数。

- 两个参数一个是请求的数据req,另一个是应当的数据res。

- 该函数将请求数据的两个成员相加并装入应答数据。

- 打印了一些消息,用于记录。

- 最后任务完成返回true。

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


nodehandle::advertiseService()用于告知master 该节点提供了什么样的服务,服务名为第一个参数,第二个参数为收到服务请求后的处理函数。

2. 编写Client节点

在src/目录中创建add_two_ints_client.cpp文件。

2.1 源码

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


2.2 源码解释

if (argc != 3)
{
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}


这里检查了传入的参数。节点名和两个被求和值。因为用的了ROS_INFO()函数,所以在此之前先要执行ros::init().

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


这里使用nodehandle::serviceClient<>()成员函数创建了一个ROS客户端,接下来将使用该客户端调用ROS 服务。

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


这里实例化了一个服务,并给其请求成员赋值。

if (client.call(srv))


这里调用了服务。

service的调用时阻塞的,调用成功返回true,此时response的值是有效的。若调用失败则返回false,此时response的值是无效的。

3. 编译

3.1 修改CMakeLists.txt文件

修改beginner_tutorials中的CMakeLists.txt,添加以下内容:

add_executable(add_two_ints_server src/add_two_ints_server.cpp)
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
add_dependencies(add_two_ints_server beginner_tutorials_gencpp)

add_executable(add_two_ints_client src/add_two_ints_client.cpp)
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
add_dependencies(add_two_ints_client beginner_tutorials_gencpp)


CMakeLists.txt文件的编写参考以下:

http://wiki.ros.org/catkin/CMakeLists.txt


3.2 执行编译

在catkin workspace下执行catkin_make命令:

$ cd ~/catkin_ws
$ catkin_make


这将在devel space目录下生成两个可执行程序 “add_two_ints_server”和“add_two_ints_client”,执行后分别是服务器节点和客户端节点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐