• C++编写简单的Service和Client


    编写Service节点

    • 这里,我们将创建一个简单的service节点("add_two_ints_server"),该节点将接收到两个整形数字,并返回它们的和。
    • 进入先前你在catkin workspace教程中所创建的包所在的目录:

      $ roscd practice/

    在beginner_tutorials包中创建src/add_two_ints_server.cpp文件,

    $ gedit 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;
    }
    View Code

    注意:beginner_tutorials改成你的包的名字

    代码解释

    • 现在,让我们来逐步分析代码。
    #include "ros/ros.h"
    #include "beginner_tutorials/AddTwoInts.h"
    
    • beginner_tutorials/AddTwoInts.h是由编译系统自动根据我们先前创建的srv文件生成的对应该srv文件的头文件。
    bool add(beginner_tutorials::AddTwoInts::Request  &req,
             beginner_tutorials::AddTwoInts::Response &res)
    
    • 这个函数提供两个int值求和的服务,int值从request里面获取,而返回数据装入response内,这些数据类型都定义在srv文件内部,函数返回一个boolean值。
    {
      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值已经相加,并存入了response。
    • 然后一些关于request和response的信息被记录下来。
    • 最后,service完成计算后返回true值。

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

    • 这里,service已经建立起来,并在ROS内发布出来。

    编写Client节点

    代码

    • 在beginner_tutorials包中创建src/add_two_ints_client.cpp文件,

      $ gedit 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;
      }
      View Code

    代码解释

    • 现在,让我们来逐步分析代码。
    ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
    
    • 这段代码为add_two_ints service创建一个client。
    • ros::ServiceClient 对象待会用来调用service。
    beginner_tutorials::AddTwoInts srv;
    srv.request.a = atoll(argv[1]);
    srv.request.b = atoll(argv[2]);
    
    • 这里,我们实例化一个由ROS编译系统自动生成的service类,并给其request成员赋值。
    • 一个service类包含两个成员request和response。
    • 同时也包括两个类定义Request和Response。
    if (client.call(srv))
    
    • 这段代码是在调用service。
    • 由于service的调用是模态过程(调用的时候占用进程阻止其他代码的执行),一旦调用完成,将返回调用结果。
    • 如果service调用成功,call()函数将返回true,srv.response里面的值将是合法的值。
    • 如果调用失败,call()函数将返回false,srv.response里面的值将是非法的。

    编译节点

    • 再来编辑一下beginner_tutorials里面的CMakeLists.txt
    • 文件位于~/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_server"和"add_two_ints_client",这两个可执行程序默认被放在你的devel space下的包目录下,默认为~/catkin_ws/devel/lib/share/。

    • 你可以直接调用可执行程序,或者使用rosrun命令去调用它们。

    • 它们不会被装在/bin目录下,因为当你在你的系统里安装这个包的时候,这样做会污染PATH变量。

    • 如果你希望在安装的时候你的可执行程序在PATH变量里面,你需要设置一下install target,请参考:catkin/CMakeLists.txt

    • 关于CMakeLists.txt文件更详细的描述请参考:catkin/CMakeLists.txt

    • 现在运行catkin_make命令:

    # In your catkin workspace
    cd ~/catkin_ws
    catkin_make

    运行Service

    • 让我们从运行Service开始:
    $ rosrun beginner_tutorials add_two_ints_server     (C++)
    $ rosrun beginner_tutorials add_two_ints_server.py  (Python)
    
    • 你将会看到如下类似的信息:
    Ready to add two ints.
    

    运行Client

    • 现在,运行Client并附带一些参数:
    $ rosrun beginner_tutorials add_two_ints_client 1 3     (C++)
    $ rosrun beginner_tutorials add_two_ints_client.py 1 3  (Python)
    
    • 你将会看到如下类似的信息:
    request: x=1, y=3
    sending back response: [4]
      
  • 相关阅读:
    文件上传
    图片压缩
    Java Utils工具类大全
    一些常用的常量
    压缩文档相关的工具类
    提供些获取系统信息相关的工具方法
    提供些常用的字符串相关的工具方法
    流相关的操作方法封装
    封装一些正则相关的操作
    随机数
  • 原文地址:https://www.cnblogs.com/long5683/p/9984745.html
Copyright © 2020-2023  润新知