1、说明

ROS的节点通信模式有多种,本文介绍service-client模式

本文的示例功能是计算 sum=a+b-c*n

下文中功能包的创建步骤不再做详细介绍

2、创建功能包

仍然和前例使用同一个工作空间

cd ~/projrct/catkin_ws/
catkin_create_pkg test_service roscpp std_msgs message_generation

这里还是显示指定依赖,避免后期修改编译配置

3、自定义通信数据类型

和 topic 模式不同的是,topic 使用msg文件声明类型,service-client使用srv文件声明类型

cd test_service
mkdir srv && cd srv
touch TestData.srv

编辑 TestData.srv 文件,如下:

int32 a
int32 b
int32 c
int32 n
---
int64 sum

service-client既然是一问一答模式,自然就需要request和response,这里的 --- 用于区分,必不可少

这时候,可以先编译一下包,以方便后面写代码

我们可以通过 rossrv 指令来检查自定义的类型是否被ROS识别了

rossrv show test_service/TestData

如果能打印出文件内容,表示已经被识别

4、编写代码

cd ~/project/catkin_ws/src/test_service/src
touch service_node.cpp
touch client_node.cpp

service_node.cpp 代码如下:

#include "ros/ros.h"
#include "test_service/TestData.h"//自动生成的自定义类型头文件 bool calc(test_service::TestData::Request &req, test_service::TestData::Response &res)
{
res.sum = req.a + req.b - req.c * req.n;
ROS_INFO("recieve request: a=%d, b=%d, c=%d, n=%d", req.a, req.b, req.c, req.n);
ROS_INFO("send response: sum=%ld", (long int)res.sum);
return true;
} int main(int argc, char **argv)
{
ros::init(argc, argv, "server_node");//初始化ROS节点,声明节点名称
ros::NodeHandle handle;//声明一个ros节点句柄 #创建服务,并讲服务加入到ROS网络中,在ROS网路中以calc作为唯一标识,其他节点使用此唯一标识进行请求
ros::ServiceServer service = handle.advertiseService("calc", calc);
ROS_INFO("service is ready!!!");
ros::spin();
return 0;
}

client_node.cpp 代码如下:

#include "ros/ros.h"
#include "test_service/TestData.h" int main(int argc, char **argv)
{
ros::init(argc, argv, "client_node");//初始化ROS节点,并声明节点名称
ros::NodeHandle handle; //定义client,并指定需要请求的service,使用之前定义的唯一标识
ros::ServiceClient client = handle.serviceClient<test_service::TestData>("calc");
test_service::TestData testData; testData.request.a = 100;
testData.request.b = 99;
testData.request.c = 12;
testData.request.n = 2;
if (client.call(testData))//发起请求
{
ROS_INFO("sum=%ld", (long int)testData.response.sum);
}
else
{
ROS_INFO("failed to call service add_two_ints");
}
return 0;
}

5、编译配置

查看一下 CMakeLists.txt 和 package.xml 中的关键项目

5.1、CMakeLists.txt

这里之列出一些关键项目

#创建包时自动添加
find_package(catkin REQUIRED COMPONENTS
message_generation
roscpp
std_msgs
) ## Generate services in the 'srv' folder
#需要手动添加,由注释可知,srv文件需要放在srv文件夹下
add_service_files(
FILES
TestData.srv
)
#创建包时自动添加,作用是自动创建自定义类型的代码文件,类型依赖std_msgs库
generate_messages(
DEPENDENCIES
std_msgs
)
#手动添加,service-client模式需要生成两个二进制文件
add_executable(${PROJECT_NAME}_service_node src/service_node.cpp)
add_dependencies(${PROJECT_NAME}_service_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(${PROJECT_NAME}_service_node
${catkin_LIBRARIES}
) add_executable(${PROJECT_NAME}_client_node src/client_node.cpp)
add_dependencies(${PROJECT_NAME}_client_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(${PROJECT_NAME}_client_node
${catkin_LIBRARIES}
)

5.2、package.xml

<?xml version="1.0"?>
<package format="2">
<name>test_service</name>
<version>0.0.0</version>
<description>The test_service package</description>
<maintainer email="eco@todo.todo">eco</maintainer>
<license>TODO</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>message_generation</build_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<build_export_depend>message_generation</build_export_depend>
<exec_depend>message_runtime</exec_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>

这里有三个依赖比较关键

<build_depend>message_generation</build_depend>
<build_export_depend>message_generation</build_export_depend>
<exec_depend>message_runtime</exec_depend>

6、编译运行

编译:

catkin_make -DCATKIN_WHITELIST_PACKAGES="test_service"

开启节点管理器

roscore

运行service节点

cd ~/project/catkin_ws/
source devel/setup.bash
rosrun test_service test_service_service_node

运行client节点

cd ~/project/catkin_ws/
source devel/setup.bash
rosrun test_service test_service_client_node

运行如下:

rosrun test_service test_service_serviceode
[ INFO] [1620440457.958186943]: service is ready!!!
[ INFO] [1620440460.409754974]: recieve request: a=100, b=99, c=12, n=2
[ INFO] [1620440460.409789657]: send response: sum=175
rosrun test_service test_service_client_node
[ INFO] [1620440460.410109766]: sum=175

ROS节点通信(二)service和client的更多相关文章

  1. ROS学习(十三)—— 编写简单的Service和Client (C++)

    一.编写Service节点 1.节点功能: 我们将创建一个简单的service节点("add_two_ints_server"),该节点将接收到两个整形数字,并返回它们的和. 2. ...

  2. SLAM+语音机器人DIY系列:(二)ROS入门——6.编写简单的service和client

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  3. ROS学习笔记三(理解ROS节点)

    要求已经在Linux系统中安装一个学习用的ros软件包例子: sudo apt-get install ros-indigo-ros-tutorials ROS图形概念概述 nodes:节点,一个节点 ...

  4. ROS学习笔记二:ROS系统架构及概念

    本文主要是了解ROS的系统架构.文件夹结构以及工作所需的核心文件. ROS系统架构主要被设计和划分为三部分,每一部分代表一个层级的概念:文件系统级(The filesystem level).计算图级 ...

  5. ROS服务通信(C++)

    ROS服务通信C++ 效果图 结构总览 友情提醒 每一步编辑完,执行一下 Ctrl+Shift+B进行编译,及时排查错误 准备工作 第一步:创建工作空间 配置:roscpp rospy std_msg ...

  6. ROS学习(六)—— 理解ROS节点

    一.准备工作 下载一个轻量级的模拟器 sudo apt-get install ros-kinetic-ros-tutorials 二.图概念的理解 1.Nodes:一个节点就是一个可执行文件,用来与 ...

  7. C++编写简单的Service和Client

    在上一步的基础上 编写Service节点 这里,我们将创建一个简单的service节点("add_two_ints_server"),该节点将接收到两个整形数字,并返回它们的和. ...

  8. ROS节点理解--5

    理解 ROS节点(原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/) Description: 本教程主要介绍 ROS 图(graph)概念 并讨 ...

  9. ROS-4 : ROS节点和主题

    依照<ROS-3 : Catkin工作空间和ROS功能包>,创建catkin工作空间,并在起src下创建功能包ros_demo_pkg,依赖项为roscpp.std_msgs.action ...

  10. ROS节点开机自启的方法

    ROS节点开机自启的方法(Ubuntu- melodic) 一. 使用命令 sudo apt install ros-melodic-robot-upstart 安装 robot-upstart工具包 ...

随机推荐

  1. Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final) 个人题解(A - D)

    1443A. Kids Seating 题意: 给你一个整数n,现在你需要从编号 \(1\) ~ $4 ⋅ n \(中选出\)n\(个编号使得这些编号之间\)g c d ≠ 1$ ,不能整除. 看了半 ...

  2. mybatis-plus数据批量插入

    为了提高数据处理效率,大量数据需要插入数据时可以采用批量数据插入的策略提高数据插入的效率. 如下是实现方法 1.代码结构 2.实体类 package little.tiger.one.applicat ...

  3. 十、docker镜像的分层

    系列导航 一.docker入门(概念) 二.docker的安装和镜像管理 三.docker容器的常用命令 四.容器的网络访问 五.容器端口转发 六.docker数据卷 七.手动制作docker镜像 八 ...

  4. 五、mycat水平分库

    系列导航 一.Mycat实战---为什么要用mycat 二.Mycat安装 三.mycat实验数据 四.mycat垂直分库 五.mycat水平分库 六.mycat全局自增 七.mycat-ER分片 一 ...

  5. yakit的web fuzzer功能的使用

    问题 yakit没有Burp 的 Intruder 爆破模块,那么yakit该怎么进行参数爆破?yakit参数爆破的方式与burp有什么区别? 前言 手工测试场景中需要渗透人员对报文进行反复的发送畸形 ...

  6. 概率图模型 · 蒙特卡洛采样 · MCMC | 非常好的教学视频

    https://www.bilibili.com/video/BV17D4y1o7J2?p=1 非常感谢!感觉学会一点了,应该能写作业了

  7. 函数传参中,形参类型为何使用const char*,而不是用char*

    1.当传递常量字符串给 char* 类型的形参时,C++ 编译器可能会发出警告,因为 char* 可以用于修改字符串内容.而使用 const char* 类型,则指示调用者不应该修改传入的字符串内容, ...

  8. 【MLA】内存泄漏检查

    项目地址:skullboyer/MLA (github.com) 介绍 MLA 即 Memory Leak Analyzer,是一个排查内存泄漏的分析器 实现机制是在malloc时记录分配位置信息,在 ...

  9. HttpClient获取不到最新的系统代理

    默认情况下,HttpClient是默认采用系统代理,但是,如果你在程序运行过程中,手动修改系统代理,对于HttpClient是无效的,它依然会用老的代理去访问. 解决方法 使用下面的代码,你可以自己实 ...

  10. ECharts——快速入门

    ECharts快速入门 引入 ECharts <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...