ROS学习-写一个简单的Service 和 Client

本文涉及的产品
资源编排,不限时长
简介: ROS学习-写一个简单的Service 和 Client

写一个Service节点

这里我们将会创建一个名为"add_two_ints_server"的Service节点,其接收两个整型数,并返回两个数的和。

首先,切换到我们之前所创建的“beginner_tutorials”包中:

roscd beginner_tutorials

同时,请确保我们在前面博客:ROS学习-创建一个ROS
msg和一个srv
中已经创建了这里所需要的AddTwoInts.srv文件。

Service节点源码

在“beginner_tutorials”包中的/src文件夹下创建一个“add_two_ints_server.cpp”文件。

touch src/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;
}

Service节点源码解释

现在,我们对上述源码进行分段解释:

首先是头文件引用:

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.

"ros/ros.h"是常用的ROS头文件,“beginner_tutorials/AddTwoInts.h"是在创建”.srv"文件过程中所生成的头文件。

接下来是是一个bool函数:

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

这个函数提供两个整型数相加的服务,其使用了在srv文件中所定义的请求AddTwoInts::Request和响应AddTwoInts::Response数据的类型,并返回一个bool类型。此外上述代码中还把一些关于请求和响应的信息通过ROS_INFO记录下来并显示了。

接下来使用下述代码创建了一个service节点,并广播。

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

写一个client节点

client节点源码

在“beginner_tutorials”包中的/src文件夹下创建一个“add_two_ints_client.cpp”文件。

touch 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 != 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;
}

client节点源码解释

类似的,我们对上述源码进行分段解释:

首先是头文件引用:

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>

接着是初始化节点:

ros::init(argc, argv, "add_two_ints_client");

判断参数数量是否满足使用要求:

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

为名字为:add_two_ints 的 service对象创建一个ros::ServiceClient对象。这个ros::ServiceClient对象在后续用来调用service。

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

接着,我们实例化一个自动生成的service类,并对其中的request成员赋值。一个service类包含两个成员,request 和 response。它还包括Request 和 Response两个类的定义。

最后,调用前述创建的service,并判断是否调用成功(返回true)。

if (client.call(srv))

如果服务调用成功,call()将返回true,srv.response中的值将有效。如果调用未成功,call()将返回false,srv.response中的值将无效。

编译节点

首先,再次在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)

切换到“catkin_ws”工作空间所在的文件路径,使用catkin_make命令进行编译。这将创建两个可执行文件, add_two_ints_server和 add_two_ints_client,默认生成到package包中的devel空间中。

catkin_make

运行节点

打开两个新的Terminal窗口,与上一篇博客中运行talker和listener节点类似的,我们也可以通过rosrun的方式,或者直接运行可执行文件的方式调用add_two_ints_server和add_two_ints_client节点。

第一个窗口中输入:

$ rosrun beginner_tutorials add_two_ints_server

返回结果:

[ INFO] [1637129512.406196185]: Ready to add two ints.

第二个窗口输入:

$ rosrun beginner_tutorials add_two_ints_client 2 3

返回结果:

[ INFO] [1637129869.838190279]: Sum: 5

同时,第一个窗口界面中也会返回以下结果:

[ INFO] [1637129869.838004528]: request: x=2, y=3
[ INFO] [1637129869.838039617]: sending back response: [5]
相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
目录
相关文章
|
6月前
|
传感器 机器人
[ROS2] --- service
[ROS2] --- service
142 0
|
API
ROS Service 相关API接口与命令行介绍
ROS Service 相关API接口与命令行介绍
193 0
|
1月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
1月前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
|
3月前
|
机器人
ROS2教程 05 服务Service
本文是关于ROS2(机器人操作系统2)中服务(Service)机制的教程,介绍了服务与话题(Topic)的区别、ROS2服务的相关命令,包括列出服务、查找服务、获取服务类型和调用服务,并通过示例代码展示了如何创建服务端(Server)和客户端(Client),以及如何测试服务调用过程。
155 0
ROS2教程 05 服务Service
|
C++
ROS学习-写一个tf broadcaster(C++)
ROS学习-写一个tf broadcaster(C++)
185 0
ROS学习-写一个tf broadcaster(C++)
|
数据可视化 Ubuntu 机器人
ROS学习-tf介绍
ROS学习-tf介绍
262 0
ROS学习-tf介绍
|
存储
ROS学习-记录和回放数据
ROS学习-记录和回放数据
440 0
ROS学习-记录和回放数据
|
存储
ROS学习-写一个简单的Publisher和Subscriber
ROS学习-写一个简单的Publisher和Subscriber
166 0
ROS学习-写一个简单的Publisher和Subscriber
|
传感器 数据可视化 机器人
ROS学习-下一步探索方向
ROS学习-下一步探索方向
120 0

推荐镜像

更多
下一篇
无影云桌面