我们将创建一个服务器节点add_two_ints_server,它将会收到两个整数,并且返回它们的和。切换目录到之前建立的beginner_tutorials包下:

cd ~/catkin_ws/src/beginner_tutorials

编辑src/add_two_ints_server.cpp文件:

vim src/add_two_ints_server.cpp

也就是说我们写的客户点也是一个node节点,它的cpp和生成的可执行模块和前面的talker、listener是一样的,只不过他们用到了srv中的服务。

将下面的代码复制到文件中,保存后退出:

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

下面解释一下代码:

#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)

这个函数为两个整数相加提供了服务,它使用了在srv文件中定义的请求和响应类型,并且返回一个布尔类型的值。

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

在这里两个整数相加并存储在response中,然后输出了一些关于request和response的信息,最后返回一个真值。

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

这行代码创建了一个服务。



接下来创建一个客户端,打开一个终端输入:

vim src/add_two_ints_client.cpp

将下面的代码复制进去,保存后退出:

#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 != )
{
ROS_INFO("usage: add_two_ints_client X Y");
return ;
} ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
beginner_tutorials::AddTwoInts srv;
srv.request.a = atoll(argv[]);
srv.request.b = atoll(argv[]);
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return ;
} return ;
}

下面看一下代码解释:

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[]);
srv.request.b = atoll(argv[]);

我们示例了一个自动产生的服务类,并且在它的请求成员中分配值。一个服务类包括了两个成员,请求和服务。它同样包括了两个类的定义,请求和响应。

if (client.call(srv))

这句代码才开始真正调用了服务,因为服务调用被阻塞,当调用完成后就立即返回。如果服务调用成功,call()将会返回真及srv中的值。否则,call()将会返回假及srv中的值。

打开~/catkin_ws/src/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)

这将会创建两个可执行文件,add_two_ints_serveradd_two_ints_client,默认将会产生在~/catkin_ws/devel/lib/share/<package name>目录下,你可以直接运行它们,也可以通过rosrun来运行。

现在开始构建:构建完成之后,他们在这个目录的下面:catkin_ws/devel/lib/share/<package name>

cd ~/catkin_ws
catkin_make


ok了,一切准备就绪,现在就开始检验一下程序是否正确吧。打开一个终端,运行服务器:

rosrun beginner_tutorials add_two_ints_server

会出现一下提示:

Ready to add two ints.

再打开一个终端,运行客户端:

rosrun beginner_tutorials add_two_ints_client  

我们可以看到返回的结果如下:

Requesting +
+ =

说明你已经成功了。

最新文章

  1. Redhat6.4下安装Oracle10g
  2. 基于httpClient的https的无秘钥登陆
  3. c++ socket 客户端库 socks5 客户端 RudeSocket™ Open Source C++ Socket Library
  4. (转)android ListView详解
  5. 【Spring】关于Boot应用中集成Spring Security你必须了解的那些事
  6. Ehcache(2.9.x) - Configuration Guide, Configuring Cache
  7. C语言的static和extern关键字
  8. Andorid Clip 实现自定义的进度条效果实例
  9. HDU--2011
  10. alloc_page分配内存空间--Linux内存管理(十七)
  11. Java 浅拷贝,深拷贝
  12. 数组中的元素 增加push用法 unshift() 方法 和减少pop() 方法 shift() 和其他位置增删 splice() 方法 join() 方法 reverse() 方法 sort() 方法
  13. 11_python_闭包迭代器
  14. [测试] Markdown+Latex
  15. Oracle提示错误消息ORA-28001: the password has expired
  16. Spyder &amp; Python
  17. Liunx下NFS服务器的搭建与配置
  18. word record 3
  19. C预编译宏
  20. 3.Dynamic Layout 动态布局。在槽中处理布局

热门文章

  1. Redmine email配置
  2. Design Pattern Iterator 迭代器设计模式
  3. Error occured processing XML &amp;#39;Cannot find class [springmvc.extention.BeanArgumentResolver]&amp;#39;.
  4. tabBar隐藏与显现 hidesBottomBarWhenPushed
  5. [置顶] ubuntu12.04下编译opencv程序
  6. Android StrictMode介绍
  7. 图的邻接链表实现(c)
  8. ThinkPHP中 按条件查询后列表显示
  9. 有关文件夹与文件的查找,删除等功能 在 os 模块中实现
  10. Delphi组件开发-在窗体标题栏添加按钮(使用MakeObjectInstance(NewWndProc),并处理好多消息)