ROS编写自己的服务

想要使用ROS编写一个自己的service,无奈网上都是beginner_tutorial 的各种改版,里面的AddTwoInts.srv 文件怎么写没有人说,多少人是在道听途说呢?于是乎,自己写一个.

料想需要这篇文章的朋友已经有一定的ROS基础,熟悉创建包,了解主要的文件关系,因此一些细节不再详述.下面正式开始.


一. 服务的格式定义与编译


1.1 编写 .srv 文件

创建了一个包 test_pkg,用于存放各种测试文件.默认地,该包中会包括 CMakeLists.txt ,package.xml 两个文件和 src文件夹.再在该包中创建一个文件夹 srv

srv 文件中新建 .srv 文件,此处以两个数相乘为例,故取名为 multiply.srv,文件内容如下

float64 a
float64 b
---
float64 c

其中,三条短线上方的代表请求参数,下方的代表相应参数.这是ROS规定的格式.注意不能用float,个人测试没编译通过.


1.2 编译

修改 CMakeLists.txt 文件

  • find_package() 中包含 message_generation
  • 取消注释或添加 add_service_files(FILES multiply.srv)
  • 取消注释或添加 generate_messages(DEPENDENCIES std_msgs)

修改 package.xml 文件

  • 取消注释或添加 <build_depend>message_generation</build_depend>
  • 取消注释或添加 <exec_depend>message_runtime</exec_depend>

在ROS空间下执行

catkin_make

如果编译没有报错,说明一切正常.此时可以稍微检查一下效果.


1.3 编译测试

输入指令

rossrv show test_pkg/multiply 

将输出

float64 a
float64 b
---
float64 c

查找文件 multiply.h

find -name multiply.h

将输出路径

./devel/include/test_pkg/multiply.h

我们并没有手动写过这个头文件,这是系统根据multiply.srv 自动生成的,这个文件一会儿将使用!


二. 编写服务端与客户端


2.1 源文件

2.1.1 服务端源文件

src 文件夹下创建服务端源文件,此处命名为 server.cpp ,其内容如下

#include "ros/ros.h"
#include "test_pkg/multiply.h"

/*
 * 乘法计算回调函数
 * @param req, 请求参数
 * @param res, 响应参数
 */
bool multiplyCallback(test_pkg::multiply::Request &req, test_pkg::multiply::Response &res)
{
    res.c = req.a * req.b;
    return true;
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "server");
    ros::NodeHandle nh;

    // 创建一个服务 multiply_service,当被调用时触发回调函数 multiplyCallback
    ros::ServiceServer server = nh.advertiseService("multiply_service", multiplyCallback);
 
    ros::spin();
    return 0;
}

其使用了之前系统生成的multiply.h 文件夹.在回调函数中,完成乘法运算.

2.1.2 客户端源文件

src 文件夹下创建客户端源文件,此处命名为 client.cpp ,其内容如下

#include "ros/ros.h"
#include "test_pkg/multiply.h"

int main(int argc, char **argv)
{
    ros::init(argc, argv, "client");
    ros::NodeHandle nh;

    // 客户端也调用服务 multiply_service
    ros::ServiceClient client = nh.serviceClient<test_pkg::multiply>("multiply_service");

    // 参数赋值,调用服务测试
    test_pkg::multiply srv;
    srv.request.a = 6.0;
    srv.request.b = 6.0;

    if (client.call(srv))
    {
        ROS_INFO("Success! %f * %f = %f", srv.request.a, srv.request.b, srv.response.c);
    }
    else
    {
        ROS_INFO("Failed to call service multiply_service");
	return 1;
    }

    return 0;
}

客户端通过 .call 函数调用服务端,调用成功或失败后都有对应的输出.


2.2 编译文件

2.2.1 修改 CMakeLists.txt 文件
  • 添加或取消注释,使得有
add_executable(server src/server.cpp)
target_link_libraries(server ${catkin_LIBRARIES})
add_dependencies(server test_pkg_gencpp)

add_executable(client src/client.cpp)
target_link_libraries(client ${catkin_LIBRARIES})
add_dependencies(client test_pkg_gencpp)

include_directories(include ${catkin_INCLUDE_DIRS})
2.2.2 编译

执行指令

catkin_make -DCATKIN_WHITELIST_PACKAGES=test_pkg # 编译指定的包

source ./devel/setup.bash 						# 使生效

2.3 测试

在三个终端分别输入

roscore
rosrun test_pkg server
rosrun test_pkg client

结果如下

ROS编写自己的服务

除了以上常规的测试之外,还可以直接在终端调用服务. 在roscoreserver 运行的时候,使用rosservice list查看当前服务, 使用 call 调用服务

rosservice call /multiply_service 3 3
ROS编写自己的服务

计算结果为 9 9 9,前面的 c 是之前 .srv 文件里定义的变量名.

完整package下载链接: https://pan.baidu.com/s/1r7d0pVBPRdV4sqtYFcSPng 提取码: 46gt

— 完 —

上一篇:2021“MINIEYE杯”中国大学生算法设计超级联赛(2)1011.I love max and multiply (思维,位运算)


下一篇:编译原理笔记 2