【ROS】如何让ROS中节点实现数据交换Ⅱ --服务通信

news/2024/10/19 13:25:02/
img

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。
本章将介绍如何通过服务通信的方式实现节点数据交换以及ROS相关指令

本章将介绍如何通过服务通信的方式实现节点数据交换以及ROS相关指令

  • 0.服务通信概念
  • 1.自定义srv消息
    • 1.1定义srv格式消息
    • 1.2修改配置文件
  • 2.自定义srv服务通信客户端python实现:
  • 3.自定义srv服务通信服务端python实现:
  • 4.优化客户端
  • 5.启动运行

在这里插入图片描述

0.服务通信概念

在ros中,一个节点想要获取某种服务(例如:一个节点想要获取此时的相机数据,节点就需要向相机发送一个请求,而相机接收到请求后可以根据消息类型将数据类型返回),这就是基本的服务通信使用场景。

以请求响应的方式实现不同节点间的数据交互
在这里插入图片描述
我们现阶段也不需要了解具体这代表什么意思,只需要知道:

client客户端/server服务端先后在rosmaster中注册本身信息,然后通过相同话题匹配.

  1. server 与 client 的启动无先后顺序要求
  2. server 与 client 都可以有多个
  3. server 与 client 连接后不再需要rosmaster,也就是说仅在尝试连接的时候需要rosmaster

1.自定义srv消息

srv消息是服务端与客户端之间通信的一个数据载体,可用数据类型与std_msgs里的数据类型一致,但需要自己定义.

步骤大概为以下几步:

  1. 根据需要定义srv格式消息
  2. 修改配置文件
  3. 编译生成中间文件并引用

1.1定义srv格式消息

这是一个自己定义的srv的消息格式
因为要实现的是两个数相加,所以这样定义。

其中—上方为client客户端发送的消息格式,下方为服务端响应的消息格式。

# 客户端请求
int32 num1
int32 num2
---
# 服务端响应
int32 ans

1.2修改配置文件

  1. 和定义msg类似,也要先修改功能包目录下的package.xml,
    在这里插入图片描述
    其中54行的message_generation是编译时的消息软件包
    而59行message_runtime是运行时的消息软件包
  2. 在CMakeList中找到这些地方并修改
     # 1.编译时的依赖包find_package(catkin REQUIRED COMPONENTSrospystd_msgsmessage_generation)# 2.加入自己定义的srv文件名字add_service_files(FILESAddints.srv )# 3.编译包时的消息依赖generate_messages(DEPENDENCIESstd_msgs)# 4.加入message_runtime,但官网没有这一步似乎也可以.catkin_package(**chmod +x py文件**CATKIN_DEPENDS rospy std_msgs message_runtime)
    
  3. 编译一下,可以在这个路径中找到刚刚编译完的中间件
    之后调用的方法如下
    # 
    from packagename.srv import * 
    
    至于为什么要import * 我们可以先来看看编译完产生的文件是什么样的

请添加图片描述

其产生了一个srv的中间件,出现了三个类,我们之后这三个类都需要使用到,所以一般都是直接import*

2.自定义srv服务通信客户端python实现:

先来分析下作为一个客户端我们需要做什么事

  1. 初始化ros节点
  2. 创建请求对象,设置通信话题
  3. 请求响应,获得响应结果
import rospyimport lesson3_srv.srv import *rospy.init_node("sum_client")client=rospy.ServiceProxy("sum2",Addints)if(len(sys.argv)!=3):rospy.logerr("参数不对")sys.exit(1)num=int(sys.argv[1])num2=int(sys.argv[2])response=client.call(num,num2)rospy.loginfo("%d",response.ans)

这里先导入了rospy的包以及消息类型,初始化了节点信息与话题。

创建了请求服务的对象,serviceprovy(话题,srv消息)

对传入的参数进行了一个处理
clint.call返回类型为自定义消息类型的格式,call(srv中的参数)

最后处理返回的消息

这就是客户端实现,当然还有一些优化内容,等服务端实现完在提

3.自定义srv服务通信服务端python实现:

先来分析下作为一个服务端我们需要做什么事

  1. 初始化节点
  2. 设置订阅话题
  3. 设置处理消息的回调函数
import rospyfrom lesson3_srv.srv import *def doNum(request):num1=request.num1num2=request.num2sum=num1+num2response=AddintsResponse()response.ans=sumrospy.loginfo("%d %d %d",request.num1,request.num2,response.ans)return responserospy.init_node("sum")server=rospy.Service("sum2",Addints,doNum)rospy.spin()

这里先导包

然后通过service(话题名称,srv消息类型,回调函数)创建服务对象

刚刚客户端传入的数据,会作为回调函数的参数

先将其取出,之后通过AddintsResponse的方法创建一个返回对象,改变ans后返回此时的返回值是给了客户端

4.优化客户端

这里的客户端有个很小的问题,仅能在服务器启动后进行通信,若服务器没有启动,而先启动了客户端就会出错,ros官方提供了两个解决方法,二者选其一即可

# rospy.wait_for_service(话题名称)
# client.wait_for_service()

所以改进的客户端代码如下:

import rospyimport sysfrom lesson3_srv.srv import *rospy.init_node("sum_client")client=rospy.ServiceProxy("sum2",Addints)if(len(sys.argv)!=3):rospy.logerr("参数不对")sys.exit(1)num=int(sys.argv[1])num2=int(sys.argv[2])#client.wait_for_service()rospy.wait_for_service("sum2")response=client.call(num,num2)rospy.loginfo("%d",response.ans)

5.启动运行

  1. 先添加可执行权限 chmod +x py文件
  2. 之后配置一下CMakeList.txt
     catkin_install_python(PROGRAMSscripts/demo01_server.pyscripts/demo01_client.pyDESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
    
  3.  rosrun lesson3_srv demo01_client.pyrosrun lesson3_srv demo01_server.py
    

运行效果:传入2 3 返回值为 5
在这里插入图片描述
在这里插入图片描述

至此服务通信内容结束


http://www.ppmy.cn/news/107126.html

相关文章

制造可靠性,我关注的点(总论)

在我过去处理的事件中,有许多是和制造、售后(含售后人员及用户)相关的。 先谈下制造可靠性,本文先做个总论,后面再针对具体的几点另外写几篇文章。 针对制造,从可靠性角度,我主要关注如下几点…

安卓手机使用Termux搭建Hexo个人博客网站【内网穿透公网访问】

文章目录 1. 安装 Hexo2. 安装cpolar内网穿透3. 公网远程访问4. 固定公网地址 转载自cpolar极点云的文章:安卓手机使用Termux搭建Hexo个人博客网站【内网穿透公网访问】 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章&#…

HTML+CSS实训——Day06——发现页的用JavaScript修改

仓库链接:https://github.com/MengFanjun020906/HTML_SX 前言 昨天学习了javascript的一些知识点&#xff0c;今天要学习dom的操作了&#xff0c;也就是文档对象模型的操作。 dom操作 <body><div id"i1">这是一个div</div><script>// dom…

跨模态检索综述

跨模态检索问题的描述 图1&#xff1a;跨 模 态 检 索 的 形 式 。 跨 模 态 检索 允 许 查 询 样 例 和 候 选 对 象 属 于 不 同 模 态 的 数 据 &#xff0c; 比 如 图 像搜索文本 &#xff0c; 文 本 搜 索 视 频 等 &#xff0c; 这 种 灵 活 多 变 的 检索方 式 能 够 满…

Three.js——七、Group层级模型

关于Group Group 层级模型 通过 THREE.Group 类创建一个组对象 group,然后通过 add 方法把网格模型 mesh1、mesh2 作为设置为组对象 group 的子对象&#xff0c;然后在通过执行 scene.add(group)把组对象 group 作为场景对象的 scene 的子对象。也就是说场景对象是 scene 是 …

Golang中的协程(goroutine)

目录 进程 线程 并发 并行 协程(goroutine) 使用sync.WaitGroup等待协程执行完毕 多协程和多线程 进程 进程就是程序在操作系统中的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;进程是一个动态概念&#xff0c;是程序在执行过程中分配和管理…

RSA加密 多线程读写不安全

转自&#xff1a;&#xff08;一场开源 RSA 库引发的“血案”&#xff09; 导读 RSA 加密算法是一种非对称加密算法&#xff0c;该算法极为可靠&#xff0c;在现有技术条件下&#xff0c;很难破解&#xff0c;因此在软件开发中被广泛使用。你不必担心&#xff0c;本文不会介绍…

C++11 auto类型推导

1.类型推导 C11引入了auto 和 decltype 关键字实现类型推导&#xff0c;通过这两个关键字不仅能方便地获取复杂的类型&#xff0c;而且还能简化书写&#xff0c;提高编码效率。 auto 类型推导的语法和规则 在之前的 C 版本中&#xff0c;auto 关键字用来指明变量的存储类型…