(无人机方向)ros小白学习之路(四)ROS通信机制---服务通信

文章目录

  • 前言
  • ROS服务通讯
    • 定义
    • 应用场景
    • 实现
      • 0.Server注册
      • 1.Client注册
      • 2.ROS Master实现信息匹配
      • 3.Client发送请求
      • 4.Server发送响应
    • 服务通信自定义srv
      • 创建功能包,然后创建srv文件夹,再创建Addints.srv
      • 用Vscode编写此文件
      • 编写package.xml
      • 编写CMakeLists.txt文件
      • 注意==不要把自定义文件的有关CMakeLists放在最后一行设置,不然会报错:==
      • 一切编写好后,编译此功能包
    • 服务通讯案例的C++编写
      • .cpp文件编写
      • CMakeLists.txt编写
    • 服务通讯案例的C++编写
      • CMakeLists.txt编写
    • ROS服务命令工具:RosSRV和RosService
      • RosService


前言

ROS服务通讯

定义

[1]服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A.
[2]以请求响应的方式实现不同节点之间数据交互的通信模式。
[3]需要两个节点.一个是服务端一个是客户端.
服务端节点通过名称提供服务,当客户端节点发送请求消息时,它响应这个消息并将结果发送到客户段节点.
客户端节点往往需要一直等待服务器响应

应用场景

服务通信更适用于对时时性有要求、具有一定逻辑处理的应用场景。
一般用于需要实现交互式"请求—响应"的机器人应用中

实现

转载于http://www.autolabor.com.cn/book/ROSTutorials/di-2-zhang-ros-jia-gou-she-ji/23-fu-wu-tong-xin/221-fu-wu-tong-xin-li-lun-mo-xing.html

服务通信较之于话题通信更简单些,理论模型如下图所示,该模型中涉及到三个角色:

  1. ROS master(管理者)
  2. Server(服务端)
  3. Client(客户端)

ROS Master 负责保管 Server 和 Client 注册的信息,并匹配话题相同的 Server 与 Client ,帮助
Server 与 Client 建立连接,连接建立后,Client 发送请求信息,Server 返回响应信息。

(无人机方向)ros小白学习之路(四)ROS通信机制---服务通信_第1张图片

整个流程由以下步骤实现:

0.Server注册

Server 启动后,会通过RPC在 ROS Master 中注册自身信息,其中包含提供的服务的名称。ROS Master
会将节点的注册信息加入到注册表中。

1.Client注册

Client 启动后,也会通过RPC在 ROS Master 中注册自身信息,包含需要请求的服务的名称。ROS Master
会将节点的注册信息加入到注册表中。

2.ROS Master实现信息匹配

ROS Master 会根据注册表中的信息匹配Server和 Client,并通过 RPC 向 Client 发送 Server 的 TCP
地址信息。

3.Client发送请求

Client 根据步骤2 响应的信息,使用 TCP 与 Server 建立网络连接,并发送请求数据。

4.Server发送响应

Server 接收、解析请求的数据,并产生响应结果返回给 Client。

注意

  1. 客户端请求被处理时,需要保证服务器已经启动

  2. 服务端和客户端都可以存在多个。

服务通信自定义srv

创建功能包,然后创建srv文件夹,再创建Addints.srv

catkin_create_pkg plumbing_server_client roscpp rospy std_msgs
cd ~/catkin_1/srv/plumbing_server_client/srv
mkdir Addints.srv

用Vscode编写此文件

#客户端请求时发送的内容
int32 num1
int32 num2
---
#服务器响应发送的数据
int32 sum

编写package.xml

  <build_export_depend>message_generationbuild_export_depend>
  <exec_depend>message_runtimeexec_depend>

编写CMakeLists.txt文件

[1]引用自定义srv文件
(无人机方向)ros小白学习之路(四)ROS通信机制---服务通信_第2张图片
找到这个代码,修改如下

add_service_files(
FILES
Addints.srv
 )

[2]设置自定义文件的依赖文件.不然定义的消息类型找不的

(无人机方向)ros小白学习之路(四)ROS通信机制---服务通信_第3张图片

找到这个代码,修改如下

generate_messages(
      DEPENDENCIES
      std_msgs
)

可以看到我们的自定义文件是设置的依赖于是std_msgs文件

[3]
设置功能包依赖项(roscpp 等等)的依赖文件
找到这个代码并作出如下修改
(无人机方向)ros小白学习之路(四)ROS通信机制---服务通信_第4张图片

注意不要把自定义文件的有关CMakeLists放在最后一行设置,不然会报错:

报错:enerate_messages() must be called after add_message_files()
解决方法

一切编写好后,编译此功能包

编译好后会生成中间文件:
[1]C++使用的可以在工作空间目录下的devel/include/plumbing_server_client看到生成的头文件
[2]Python使用的可以在工作空间目录下的devel/lib/python3/plumbing_server_client看到生成的头文件


> 现在就实现了一个自定义srv

服务通讯案例的C++编写

需求:

编写服务通信,客户端提交两个整数至服务端,服务端求和并响应结果到客户端。

分析:

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

  • [1] 服务端
  • [2] 客户端
  • [3] 数据

流程:

  • 编写服务端实现;
  • 编写客户端实现;
  • 编辑配置文件;
  • 编译并执行。

.cpp文件编写

(无人机方向)ros小白学习之路(四)ROS通信机制---服务通信_第5张图片

CMakeLists.txt编写

(无人机方向)ros小白学习之路(四)ROS通信机制---服务通信_第6张图片

服务通讯案例的C++编写

#include 
#include 

int main(int argc,char *argv[])
{
    setlocale(LC_ALL," ");
ros::init(argc,argv,"client");
ros::NodeHandle nh;
ros::ServiceClient client=nh.serviceClient<plumbing_server_client::Addints>("addints");
plumbing_server_client::Addints ai;
//组织请求
ai.request.num1=100;
ai.request.num2=200;
//处理响应
bool flag=client.call(ai);
if(flag==true)
ROS_INFO("结果为:%d",ai.response.sum);
    return 0;

CMakeLists.txt编写

add_executable(demo2_client_node src/demo2_client.cpp)
 add_dependencies(demo2_client_node ${PROJECT_NAME}_gencpp)
 target_link_libraries(demo2_client_node
 ${catkin_LIBRARIES}
)

ROS服务命令工具:RosSRV和RosService

RosService

  • rosservice call /service args 使用给定的参数调用服务
  • rosservice find service_type 根据给定的服务类型查找服务
  • rosservice info /services 打印有关给定服务的消息
  • rosservice list 列出系统运行的活动服务
  • rosservice type /service 打印给定服务的服务类型
  • rosservice uri /service 打印服务的RORPC URI

你可能感兴趣的:(学习记录,ros,ubuntu,无人机,学习,机器人)