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]

证明调用了add_two_ints_server.cpp文件中的add函数。

Guess you like

Origin blog.csdn.net/wxc_1998/article/details/121371611