2.2.3 服务通信自定义srv调用A(C++) · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程
068服务通信(C++)3_客户端优化_Chapter2-ROS通信机制_哔哩哔哩_bilibili
一、理论模型
服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A。比如如下场景:
机器人巡逻过程中,控制系统分析传感器数据发现可疑物体或人... 此时需要拍摄照片并留存。
在上述场景中,就使用到了服务通信。
- 一个节点需要向相机节点发送拍照请求,相机节点处理请求,并返回处理结果
与上述应用类似的,服务通信更适用于对时时性有要求、具有一定逻辑处理的应用场景。
1.概念
以请求响应的方式实现不同节点之间数据交互的通信模式。
2.作用
用于偶然的、对时时性有要求、有一定逻辑处理需求的数据传输场景。
3.
二、自定义srv
需求:
服务通信中,客户端提交两个整数至服务端,服务端求和并响应结果到客户端,请创建服务器与客户端通信的数据载体。
流程:
srv 文件内的可用数据类型与 msg 文件一致,且定义 srv 实现流程与自定义 msg 实现流程类似:
-
按照固定格式创建srv文件
-
编辑配置文件
-
编译生成中间文件
srv=请求部分+相应部分
1.在src下新建功能包并添加依赖
2.按照固定格式创建srv文件
新建文件夹->新建文件(该文件是自定义的服务消息的载体)
请求与相应部分使用---分割
3.编辑配置文件
①
注意不要用同一个复制只改中间名,这两个前后不一致
②
③
放开注释成都
更改名
④
放开注释(添加依赖)
⑤
放开注释
添加
4.编译(ctrl+shift+B)
5.生成中间文件
三、需求分析及vscode配置
1.
需求:
编写服务通信,客户端提交两个整数至服务端,服务端求和并响应结果到客户端。
分析:
在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:
- 服务端
- 客户端
- 数据
流程:
- 编写服务端实现;
- 编写客户端实现;
- 编辑配置文件;
- 编译并执行。
2.vscode配置
在devel中使用集成终端打开,打印路径,复制路径到c_cpp_properties.json中,修改格式与上文对齐(如果在话题通信中配置就不需要重复操作)
四、服务方实现
1.新建文件,搭建框架(删除char 后面的const修饰)
2.包含头文件
3.初始化ROS节点
4.创建节点句柄
5.创建一个服务对象,定义回调函数
回调函数返回值为bool值
有中文输出需要此函数:
加上打印语句
6. spin()函数
7.配置
①
参数1——要映射的名称,建议和原名称一致
参数2——被执行的cpp源文件名
②
③
更改为:
8.编译,测试
(1)roscore
(2)启动服务器端
(3)调用命令测试
rosservice call addInts空一个tab双击能够补齐,再改动num数字
五、客户端实现
1.新建文件夹,搭建框架
2. 包含头文件
头文件报错编译一下就好
3.初始化ROS节点
4.创建节点句柄
5.创建一个客户端对象
6.提交请求并处理相应
(1)创建addInts对象
(2)组织请求 ![](https://i-blog.csdnimg.cn/blog_migrate/eb56a82295c04cca3ff1244501a3155e.png)
(3)处理响应
有中文输出,使用该函数,否则乱码:
7.配置
①
②
8.编译
9.测试
(1)先运行服务端
rosrun 包名 服务
(2)再运行客户端
rosrun 包名 客户端 参数1 参数2
10.优化
(1)实现参数的动态提交![](https://i-blog.csdnimg.cn/blog_migrate/9196fefad0a573004fc032adae1fc760.png)
获取命令中的参数
argc就是arg count,就是程序的参数个数。argc≥1,这个1是指该函数本身,所以有一个参数的话argc=2,函数本身1+参数1=argc2。
在该例中argc=3,因为第一个参数是程序名,第二个才是12,第三个是34
char* argv[]是一个数组 每个元素都存储一个指针 也就是你传进去参数的地址
atoi是字符串转成int
结果:
(2)解决先启动客户端导致运行失败问题
①方法一
在客户端发送请求前添加:
②方法二
该函数传入参数为被等待的服务
两个函数都必须卸载 bool flag前面,否则会出现一直响应失败的现象(需要理解一下这两行代码和if的先后关系)