ros入门:服务通信(c++)

ros服务通信的原理类似于RPC,其实现原理如下图所示

实验目标

  • 创建一个客户端和一个服务端
  • 客户端向服务端发送两个参数num1和num2
  • 服务端接收到客户端的两个参数num1和num2,并计算出num1+num2的求和结果,最后返回给客户端
  • 客户端接收服务端的计算结果

前期准备

创建相关文件

创建功能包ros_server_client

在根工作空间目录下执行

 catkin_create_pkg ros_server_client roscpp rospy std_msgs

在功能包ros_server_client下创建消息结构文件目录和文件

其中AddInts.srv文件的内容为

int32 num1
int32 num2
---
int32 sum

修改配置文件

修改package.xml的内容为

  <buildtool_depend>catkin</buildtool_depend><build_depend>roscpp</build_depend><build_depend>rospy</build_depend><build_depend>std_msgs</build_depend><build_depend>message_generation</build_depend><build_export_depend>roscpp</build_export_depend><build_export_depend>rospy</build_export_depend><build_export_depend>std_msgs</build_export_depend><exec_depend>roscpp</exec_depend><exec_depend>rospy</exec_depend><exec_depend>std_msgs</exec_depend><exec_depend>message_runtime</exec_depend>

修改CMakeLists.txt文件的内容为

find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation
)
add_service_files(FILESAddInts.srv
)
generate_messages(DEPENDENCIESstd_msgs
)
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES ros_server_clientCATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

编译生成中间文件

catkin_make

服务端实现

服务端代码实现

在工作空间下创建服务端代码文件ros_server.cc

#include"ros/ros.h"
#include"ros_server_client/AddInts.h"// 服务通信对象回调
bool responseHander(ros_server_client::AddInts::Request& request,ros_server_client::AddInts::Response& response){int num1=request.num1;int num2=request.num2;ROS_INFO("receive parameters: %d , %d",num1,num2);int sum=num1+num2;response.sum=sum;ROS_INFO("num1+num2=%d",sum);return true;
}int main(int argc,char* argv[]){// 防止中文乱码setlocale(LC_ALL,"");// 初始化ros节点ros::init(argc,argv,"ros_server_node");// 创建ros节点handlerros::NodeHandle ros_server_node_handler;// 创建服务通信对象ros::ServiceServer ros_server=ros_server_node_handler.advertiseService("addInts",responseHander);ROS_INFO("server start!");ros::spin();
}

修改CMakeLists.txt文件


## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(ros_server_node src/ros_server.cc)## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")## Add cmake target dependencies of the executable
## same as for the library above
add_dependencies(ros_server_node ${PROJECT_NAME}_gencpp)## Specify libraries to link a library or executable target against
target_link_libraries(ros_server_node${catkin_LIBRARIES}
)

编译生成代码

服务端测试

启动ros

roscore

启动服务端和客户端

 客户端实现

创建客户端代码文件ros_client.cc

客户端代码实现

#include"ros/ros.h"
#include"ros_server_client/AddInts.h"int main(int argc,char* argv[]){ros::init(argc,argv,"ros_client_node");ros::NodeHandle ros_client_node_handler;ros::ServiceClient ros_client=ros_client_node_handler.serviceClient<ros_server_client::AddInts>("addInts");ros_server_client::AddInts parms;parms.request.num1=10;parms.request.num2=20;bool response=ros_client.call(parms);if(response){ROS_INFO("response successfully!");ROS_INFO("response result is %d ",parms.response.sum);}else{ROS_INFO("response error!");}return 0;
}

修改CMakeLists.txt文件

add_executable(ros_server_node src/ros_server.cc)
add_executable(ros_client_node src/ros_client.cc)## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")## Add cmake target dependencies of the executable
## same as for the library above
add_dependencies(ros_server_node ${PROJECT_NAME}_gencpp)
add_dependencies(ros_client_node ${PROJECT_NAME}_gencpp)## Specify libraries to link a library or executable target against
target_link_libraries(ros_server_node${catkin_LIBRARIES}
)
target_link_libraries(ros_client_node${catkin_LIBRARIES}
)

编译代码测试

 代码优化,使用动态参数提交

#include"ros/ros.h"
#include"ros_server_client/AddInts.h"int main(int argc,char* argv[]){if(argc!=3){ROS_INFO("parms numbers error!");return 1;}ros::init(argc,argv,"ros_client_node");ros::NodeHandle ros_client_node_handler;ros::ServiceClient ros_client=ros_client_node_handler.serviceClient<ros_server_client::AddInts>("addInts");ros_server_client::AddInts parms;// 获取命令行参数parms.request.num1=atoi(argv[1]);parms.request.num2=atoi(argv[2]);// 这行代码的作用是,如果服务端尚未启动,那么客户端将会被挂起,直到服务端启动后才请求响应结果ros_client.waitForExistence();bool response=ros_client.call(parms);if(response){ROS_INFO("response successfully!");ROS_INFO("response result is %d ",parms.response.sum);}else{ROS_INFO("response error!");}return 0;
}

重新编译执行

测试1:先启动服务端,再启动客户端

测试2:先启动客户端,再启动服务端 

参考:

063服务通信_理论模型_Chapter2-ROS通信机制_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3238.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

域控操作二十四:主域故障辅域接替

模拟环境&#xff1a;上海DC1故障无法开机&#xff0c;导致只有一个DNS的电脑无法上网&#xff08;实际可以添加DC2但是为了实验就不说了&#xff09; FSMO还在DC1上 使用powershell把角色迁移到DC2 ntdsutil roles connections connect to server DC2SHA.whbk.cn quitSeize …

网络安全认证的证书有哪些?

在网络安全领域&#xff0c;专业认证不仅是个人技术能力的象征&#xff0c;也是职业发展的重要推动力。随着网络安全威胁的日益严峻&#xff0c;对网络安全专业人才的需求也在不断增长。本文将介绍一些网络安全认证的证书&#xff0c;帮助有志于从事网络安全行业的人士了解并选…

【MIT-OS6.S081笔记1】xv6环境搭建

最近开始做一个操作系统的神课MIT-OS6.S081&#xff0c;我做的是老版本的2020版本的&#xff0c;环境使用的是VirtualBox的Ubuntu系统&#xff0c;在这里记录一下学习的过程。首先需要搭建一下环境&#xff0c;参考官网Tools Used in 6.S081&#xff0c;这个知乎文章也写得很好…

html练习2

实现下列图片的效果 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>* {margin: 0;padding: 0;}#menu {background-color: #0c0048;width: 100%;height: 50px;margin: auto;…

ViT面试知识点

文章目录 VITCLIPBlipSAMFast TransformerYOLO系列问题 BatchNorm是对一个batch-size样本内的每个特征做归一化&#xff0c;LayerNorm是对每个样本的所有特征做归一化。 Layer Normalization&#xff08;层归一化&#xff0c;简称LayerNorm&#xff09;是一种在深度学习中常用…

意大利名模 Vittoria Ceretti

1998年出生&#xff0c;相貌一般&#xff0c;身材高&#xff0c;世界著名的维多利亚秘密花园时装秀入选模特之一&#xff0c;但愿她没上过萝莉岛。

Java - 免费图文识别_Java_免费_图片转文字_文字识别_spring ai_spring ai alibaba

本文主要是介绍借助阿里云免费的大模型额度来做高质量的图转文识别&#xff0c;图片转文字&#xff0c;或者文字识别都可以使用&#xff0c;比传统的OCR模式要直接和高效很多 。 本文使用的技术是spring ai qwen vl 。 Qwen vl有 100万Token 免费额度&#xff0c;可以用来免费…

MR30分布式IO模块与高效PLC协同

在现代工业自动化领域中&#xff0c;数据采集与控制系统扮演着至关重要的角色。其中&#xff0c;可编程逻辑控制器&#xff08;PLC&#xff09;和分布式IO模块&#xff08;Distributed I/O Modules&#xff09;是这一领域的两大核心组件。本文将详细介绍MR30分布式IO模块与PLC如…

深基坑结构施工安全在自动化监测不知道怎么布设测点?不知道用什么设备?

01 基坑监测背景 随着我国城市建设的发展&#xff0c;基坑规模和开挖深度不断增加。在基坑开挖过程中&#xff0c;如何尽快的在第一时间了解基坑的变形情况&#xff0c;并动态评估基坑的结构安全&#xff0c;避免事故的发生。与其它监测方法相比&#xff0c;实现自动化监测、信…

一张图简单讲述Mamba的演进过程

这张图表提供了 RNN&#xff08;1986&#xff09;、LSTM&#xff08;1997&#xff09;、Transformer&#xff08;2017&#xff09;和 Mamba&#xff08;2024&#xff09;四种不同的神经网络架构在训练阶段、测试阶段和额外问题方面的对比。可以看出&#xff0c;Mamba 作为一种最…

Spring在多线程环境下如何确保事务一致性

Spring在多线程环境下如何确保事务一致性 问题在现如何解决异步执行多线程环境下如何确保事务一致性事务王国回顾事务实现方式回顾编程式事务利用编程式事务解决问题问题分析完了&#xff0c;那么如何解决问题呢&#xff1f;小结 问题在现 我先把问题抛出来&#xff0c;大家就…

c加加11第二弹~

1lambda 1.1.lambda表达式书写格式 [capture-list] (parameters) mutable -> return-type { statement} 1.2lambda表达式各部分说明 [capture-list] : 捕捉列表&#xff0c;该列表总是出现在lambda函数的开始位置&#xff0c;编译器根据[]来判断接下来的代码是否为lamb…

服装品牌必备:智能商品管理系统,打造高效运营新引擎!

在如今瞬息万变的服装市场中&#xff0c;企业的生产链、供应链、销售链及库存管理等各个环节的复杂度与日俱增。随着业务版图的不断扩张&#xff0c;SKU数量呈爆炸式增长&#xff0c;传统的人工管理模式已难以支撑高效运营的需求&#xff0c;信息化、数字化转型已成为行业共识。…

B站狂神说+mybatis增删改查操作

文章目录 1.新增mapper接口2.修改mapper接口同级目录下的xml文件&#xff08;UserMapper.xml&#xff09;3.编写src同级别目录下的test文件4.万能的Map 1.新增mapper接口 package com.aloha.dao;import com.aloha.pojo.User;import java.util.List;public interface UserMappe…

美的品牌店铺运营全解析:洞察用户行为驱动增长

美的品牌店铺运营与用户行为分析 一、店铺运营表现分析&#xff1a; 共获取320个美的店铺的数据及其店铺的商品&#xff0c;共3***0个商品&#xff0c;选取销售额最高的10个店铺美的官方旗舰店、美的空调旗舰店、华凌官方旗舰店、美的冰箱旗舰店、美的日邦企业店、美的集成灶旗…

【笔记】变压器-热损耗-频响曲线推导 - 02 预备知识

0.题外话 周五&#xff0c;在处理一个电路设计时&#xff0c;关联到了日本的TDK公司。目前&#xff0c;市面上大量出货的开关电源用标准型号 - 高频铁氧体变压器 - PQ系列&#xff0c;型号实际是TDK的公司标准。那个尺寸参数是TDK自行制定的。似乎。 我一下意识到为什么日本会…

计算机网络——网络层导论

转发是局部功能——数据平面 路由是全局的功能——控制平面 网卡 网卡&#xff0c;也称为网络适配器&#xff0c;是计算机硬件中的一种设备&#xff0c;主要负责在计算机和网络之间进行数据传输。 一、主要功能 1、数据传输&#xff1a; 发送数据时&#xff0c;网卡将计算机…

人像抠图怎么抠?5款AI抠图工具帮你一键抠人像!

在当今这个视觉盛宴频现的时代&#xff0c;一张背景简洁、人物鲜明的照片往往能瞬间捕获观者的目光。 人像抠图无疑是一项极为关键的技术。它不仅能帮助我们精准地将人物从繁琐的背景中抽离&#xff0c;还为后续的创意编辑与合成铺设了广阔的舞台。今日&#xff0c;将为大家分…

你不知道的C语言知识(第八期:动态内存管理)

本期介绍&#x1f356; 主要介绍&#xff1a;C语言中一些大家熟知知识点中的盲区&#xff0c;这是第八期&#xff0c;主讲动态内存管理。 文章目录 1. 为什么会存在动态内存2. 动态内存管理库函数2.1 malloc函数2.2 calloc函数2.3 realloc函数2.4 free函数 3. 内存泄漏&内存…

vue项目新打开一个tab页或者新窗口的方法

router.resolve&#xff1a;返回一个路由地址的规范化版本。同时包含一个包含任何现有 base 的 href 属性。默认情况下&#xff0c;用于 router.currentRoute 的 currentLocation 应该在特别高阶的用例下才会被覆写。 打开新标签页方法 const openNewTab ()> {// 打开新标…