ROS学习第九节——服务通信

news2025/2/24 7:42:33

1.基本介绍

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

  • ROS master(管理者)
  • Server(服务端)
  • Client(客户端)

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

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

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.服务端和客户端都可以存在多个。

2.具体实现

2.1创建srv文件

创建服务通信功能包

注意是右键工作空间下面的src文件夹Create Kitcan Package ,并添加依赖

新建srv文件夹,添加编程文件

服务通信中,数据分成两部分,请求与响应,在 srv 文件中请求和响应使用---分割,具体实现如下:

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

 编辑配置文件

package.xml中添加编译依赖与执行依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
  <!-- 
  exce_depend 以前对应的是 run_depend 现在非法
  -->

CMakeLists.txt编辑 srv 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
# 需要加入 message_generation,必须有 std_msgs

add_service_files(
  FILES
  AddInts.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

 修改完成以后编译

2.2服务通信自定义srv(C++)

2.2.1服务端

 VScode配置

找到该文件夹,在终端中打开,pwd,查看路径,复制路径到图片所示文件中

在功能包下的src文件夹里面新建编程文件

编写以下代码

/*
    需求: 
        编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器
        服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,
        客户端再解析

    服务器实现:
        1.包含头文件
        2.初始化 ROS 节点
        3.创建 ROS 句柄
        4.创建 服务 对象
        5.回调函数处理请求并产生响应
        6.由于请求有多个,需要调用 ros::spin()

*/
#include "ros/ros.h"
#include "server_client/AddInts.h"

// bool 返回值由于标志是否处理成功
bool doReq(server_client::AddInts::Request& req,
          server_client::AddInts::Response& resp){
    int num1 = req.num1;
    int num2 = req.num2;

    ROS_INFO("服务器接收到的请求数据为:num1 = %d, num2 = %d",num1, num2);

    //逻辑处理
    if (num1 < 0 || num2 < 0)
    {
        ROS_ERROR("提交的数据异常:数据不可以为负数");
        return false;
    }

    //如果没有异常,那么相加并将结果赋值给 resp
    resp.sum = num1 + num2;
    return true;


}

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    // 2.初始化 ROS 节点
    ros::init(argc,argv,"AddInts_Server");
    // 3.创建 ROS 句柄
    ros::NodeHandle nh;
    // 4.创建 服务 对象
    ros::ServiceServer server = nh.advertiseService("AddInts",doReq);
    ROS_INFO("服务已经启动....");
    //     5.回调函数处理请求并产生响应
    //     6.由于请求有多个,需要调用 ros::spin()
    ros::spin();
    return 0;
}

修改配置文件

add_executable(demo01_server src/demo01_server.cpp)

add_dependencies(demo01_server  ${PROJECT_NAME}_gencpp)
target_link_libraries(demo01_server
  ${catkin_LIBRARIES}
)

 运行代码查看效果

 使用ros服务器工具进行查验代码

rosservice call AddInts "num1: 5
num2: 10"

 2.2.2客户端

新建编程文件如图

 输入以下代码

/*
    需求: 
        编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器
        服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,
        客户端再解析

    服务器实现:
        1.包含头文件
        2.初始化 ROS 节点
        3.创建 ROS 句柄
        4.创建 客户端 对象
        5.请求服务,接收响应

*/
// 1.包含头文件
#include "ros/ros.h"
#include "server_client/AddInts.h"

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");

    // 调用时动态传值,如果通过 launch 的 args 传参,需要传递的参数个数 +3
    if (argc != 3)
    // if (argc != 5)//launch 传参(0-文件路径 1传入的参数 2传入的参数 3节点名称 4日志路径)
    {
        ROS_ERROR("请提交两个整数");
        return 1;
    }


    // 2.初始化 ROS 节点
    ros::init(argc,argv,"AddInts_Client");
    // 3.创建 ROS 句柄
    ros::NodeHandle nh;
    // 4.创建 客户端 对象
    ros::ServiceClient client = nh.serviceClient<server_client::AddInts>("AddInts");
    //等待服务启动成功
    //方式1
    ros::service::waitForService("AddInts");
    //方式2
    // client.waitForExistence();
    // 5.组织请求数据
    server_client::AddInts ai;
    ai.request.num1 = atoi(argv[1]);
    ai.request.num2 = atoi(argv[2]);
    // 6.发送请求,返回 bool 值,标记是否成功
    bool flag = client.call(ai);
    // 7.处理响应
    if (flag)
    {
        ROS_INFO("请求正常处理,响应结果:%d",ai.response.sum);
    }
    else
    {
        ROS_ERROR("请求处理失败....");
        return 1;
    }

    return 0;
}

修改配置文件

add_executable(demo01_server  src/demo01_server.cpp)
add_executable(demo02_client  src/demo02_client.cpp)

add_dependencies(demo01_server  ${PROJECT_NAME}_gencpp)
add_dependencies(demo02_client  ${PROJECT_NAME}_gencpp)

target_link_libraries(demo01_server
  ${catkin_LIBRARIES}
)
target_link_libraries(demo02_client
  ${catkin_LIBRARIES}
)

 运行查看结果

https://mp.csdn.net/mp_download/manage/download/UpDetailed

2.3服务通信自定义srv(Python)

路径配置

右键文件夹复制路径

/home/xiaoming/demo0/devel/lib/python2.7/dist-packages

 

2.3.1服务端创建

创建代码文件夹及代码文件

#! /usr/bin/env python
# -*- coding: UTF-8 -*-
"""
    需求: 
        编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器
        服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,
        客户端再解析

    服务器端实现:
        1.导包
        2.初始化 ROS 节点
        3.创建服务对象
        4.回调函数处理请求并产生响应
        5.spin 函数

"""
# 1.导包
import rospy
from server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
# 回调函数的参数是请求对象,返回值是响应对象
def doReq(req):
    # 解析提交的数据
    sum = req.num1 + req.num2
    rospy.loginfo("提交的数据:num1 = %d, num2 = %d, sum = %d",req.num1, req.num2, sum)

    # 创建响应对象,赋值并返回
    # resp = AddIntsResponse()
    # resp.sum = sum
    resp = AddIntsResponse(sum)
    return resp


if __name__ == "__main__":
    # 2.初始化 ROS 节点
    rospy.init_node("addints_server_p")
    # 3.创建服务对象
    server = rospy.Service("AddInts",AddInts,doReq)
    rospy.loginfo("服务器已经启动了!")
    # 4.回调函数处理请求并产生响应
    # 5.spin 函数
    rospy.spin()

添加可执行文件

 编辑可执行文件

catkin_install_python(PROGRAMS
  scripts/demo01_server_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

 运行显示效果

 2.3.2客户端创建

创建编程文件并输入代码

#! /usr/bin/env python
# -*- coding: UTF-8 -*-
"""
    需求: 
        编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器
        服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,
        客户端再解析

    客户端实现:
        1.导包
        2.初始化 ROS 节点
        3.创建请求对象
        4.发送请求
        5.接收并处理响应

    优化:
        加入数据的动态获取


"""
#1.导包
import rospy
from server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
import sys

if __name__ == "__main__":

    #优化实现
    if len(sys.argv) != 3:
        rospy.logerr("请正确提交参数")
        sys.exit(1)


    # 2.初始化 ROS 节点
    rospy.init_node("AddInts_Client_p")
    # 3.创建请求对象
    client = rospy.ServiceProxy("AddInts",AddInts)
    # 请求前,等待服务已经就绪
    # 方式1:
    # rospy.wait_for_service("AddInts")
    # 方式2
    client.wait_for_service()
    # 4.发送请求,接收并处理响应
    # 方式1
    # resp = client(3,4)
    # 方式2
    # resp = client(AddIntsRequest(1,5))
    # 方式3
    req = AddIntsRequest()
    # req.num1 = 100
    # req.num2 = 200 

    #优化
    req.num1 = int(sys.argv[1])
    req.num2 = int(sys.argv[2]) 

    resp = client.call(req)
    rospy.loginfo("响应结果:%d",resp.sum)

 添加可执行文件

 修改可执行文件

catkin_install_python(PROGRAMS
  scripts/demo01_server_p.py
  scripts/demo02_client_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

运行查看效果

 https://mp.csdn.net/mp_download/manage/download/UpDetailed

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

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

相关文章

远程控制电脑的软件哪个比较好用

有多种软件选项可用于远程控制计算机&#xff0c;最适合您的软件选项取决于您的具体需要和要求。 以下是一些最流行的远程控制软件选项及其功能和优势&#xff1a; TeamViewer TeamViewer 是使用最广泛的远程控制软件选项之一。 它具有用户友好的界面&#xff0c;并提供文件传…

Vue核心 Vue简介 初识

Vue核心 Vue简介 初识 1.1.Vue核心 Vue简介 初识 1.1.1.Vue核心 Vue简介 初识 英文官网 中文官网 1.1.2.介绍与描述 Vue 是一套用来动态构建用户界面的渐进式JavaScript框架 构建用户界面&#xff1a;把数据通过某种办法变成用户界面渐进式&#xff1a;Vue可以自底向上逐层…

YOLO V8实战入门篇 | Anaconda3 | ultralytics

目录 一、虚拟环境1.1 Anaconda3 安装1.2 创建适用YOLO V8的虚拟环境 二、YOLO v82.1 YOLO v8简介2.2 下载YOLO v8源码2.3 安装依赖 三、运行目标检测模型 一、虚拟环境 1.1 Anaconda3 安装 https://blog.csdn.net/weixin_42855758/article/details/122795125 参考这个链接&a…

NDK OpenCV 身份证信息离线识别

NDK系列之OpenCV 身份证信息离线识别技术实战&#xff0c;本节主要是通过OpenCV C库&#xff0c;实现身份证信息识别&#xff0c;如身份证号码识别&#xff0c;本节使用到的技术点同样适用于车牌号识别、银行卡号码识别等。 实现效果&#xff1a; 本节主要内容&#xff1a; 1…

数据库底层运行原理之——事务管理器

一般所有关系型数据库内部都有自己的事务机制&#xff0c;进程是如何保证每个查询在自己的事务内执行的&#xff0c;通过这篇文章来简单介绍一下。 我们可以理解为数据库是由多种相互交互的组件构成的&#xff0c;数据库一般可以用如下图形来理解&#xff1a; 事务管理器就是今…

两种方法,计算带地形起伏的地表面积

很多同学会经常计算占地面积, 就会用到投影面积计算和椭球体面积计算; 还有一些,需要去计算表面积, 也就是带地形起伏的地表面积, 这......咋办呢? 我们来介绍两种方法, 计算下面这个区域的地表面积—— 两种方法各有优势, 大家各取所需 方法一:表面体积工具 这…

【hello Linux】进程优先级

目录 1. 基本概念 2. 查看系统进程&#xff1a;&#xff08;包括优先级&#xff09; 2.1 使用命令查看系统进程 2.2 各字段分析 2.3 优先级的修正解释 2.4 使用 top 命令修改优先级 其他概念 Linux&#x1f337; 1. 基本概念 进程的优先权&#xff08; priority&#xff09;&…

Java版企业电子招投标系统源代码之电子招投标系统建设的重点和未来趋势

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…

网工神器:PNETLab模拟器踩坑过程(一)

0、前言 由于工作需要&#xff0c;想测试一下SD-WAN&#xff0c;手边既没有测试环境又没有测试设备。突然想到为什么不用模拟器测试。经过我一番操作好像发现了新大陆&#xff0c;没想到模拟器的世界发生了翻天覆地的变化。真是“一日学习一日功&#xff0c;一日不学十日空”。…

【IoT】以一款实际产品为例,来谈谈如何做商业计划分析

本篇内容以笔者早期刚转型做产品时,实际负责的一款产品为例,来谈谈如何做产品的商业计划分析。 首先简单介绍一下这款产品: 这是一款电子便签产品,目的是为了替换纸质便签,增加一些智能化的提醒控制。 该产品通过蓝牙与手机端连接,应用端配置好提醒信息后一键同步至产…

鼠标悬停发光按钮,流转边框

提示&#xff1a;css 动画实现&#xff0c;鼠标悬停发光按钮&#xff0c;流转边框。鼠标border可以旋转 前言 提示&#xff1a;以下是本篇文章的代码内容,供大家参考,相互学习 一、html代码 <!DOCTYPE html> <html><head><meta http-equiv"content…

企业信息化建设该怎么做?方向和手段都在这了

企业信息化建设该怎么做&#xff1f; 如果现在是十年前&#xff0c;我一定会说&#xff0c;做信息化需要寻找熟悉不同编程语言、有经验的程序员。 但是现在&#xff0c;如果不是特别复杂的信息化系统&#xff0c;其实公司完全可以使用零代码平台自主开发&#xff0c;不需要再…

[计算机图形学]光线追踪:加速结构(前瞻预习/复习回顾)

一、前言 上篇我们提到了&#xff0c;如果在光线追踪中&#xff0c;我们真的用每个像素发出的光线&#xff0c;以及在场景中弹射之后的光线与场景中的许多模型的上千万个三角形求交那将是一个非常慢的计算过程&#xff0c;所以&#xff0c;本篇我们将介绍一些加速结构来加速这个…

【FTP服务】

目录 一、FTP服务二、FTP服务器安装配置FTP服务的安装匿名访问开启防火墙设置本地用户修改配置文件 以图形化的格式来写入文件 三、设置白名单&#xff0c;黑名单用户 一、FTP服务 作用: 是用来传输文件的协议 端口: FTP服务器默认使用TCP协议的20、21端口与客户端进行通信 2…

OpenHarmony生态贡献获肯定,华秋践行加速硬件创业初心

4月19日,以“开源正当时,共赢新未来”为主题的开放原子开源基金会OpenHarmony开发者大会2023(以下简称“大会”)成功举办。大会现场,来自开放原子开源基金会和OpenHarmony项目的领导与专家、以及共建单位、行业伙伴和社区开发者们共聚一堂。值得信赖的电子产业一站式服务平台华…

【软件测试】四面成功上岸美团

最后&#xff0c;总结一下个人认为比较重要的知识点&#xff1a;接口自动化测试 &#xff1a;测试框架&#xff0c;多个有关联的接口的用例编写&#xff0c;用例的组织及存储&#xff0c;接口测试的覆盖率&#xff0c;RESTAssured 的封装等。UI 自动化测试 &#xff1a;iOS 和 …

二维码+互联网云技术在中建二局施工项目管理中的应用实践

中建二局&#xff08;全称&#xff1a;中国建筑第二工程局有限公司&#xff09;是世界500强企业—中国建筑股份有限公司的全资子公司&#xff0c;是集房建、基建、核电、火电、风电等多种建设和投资相融合的、国内最具综合实力的大型国有企业集团公司。中建二局具有土木建筑、设…

Jetson Orin Nano下部署 Yolo v5

在网上找了好多关于Jetson Nano部署Yolo v5的帖子&#xff0c;由于每个人的环境和版本都不同&#xff0c;过程也都有所不同&#xff0c;因此在Jetson Orin Nano CLB上安装Yolo v5也有必要记录一下过程&#xff0c;以便后续无脑重装&#xff0c;让我们开始。 由于我这个Jetson …

【IT成神路之我在起点学网络~】

什么是网络&#xff0c;一开始我以为是能刷刷剧&#xff0c;让我看到心仪idol&#xff0c;坐在家中看祖国大好河山就是网络。 长时间浸泡在网络上&#xff0c;不得不让我思索我为什么能看到高清不卡顿的精彩视频。 于是乎……我开始大肆搜索网络的资料内容。 IT嘛&#xff0…

OCR技术大揭秘:纸质文档数字化的新选择

引言 OCR&#xff08;Optical Character Recognition&#xff09;即光学字符识别技术&#xff0c;是一种将纸质或电子文档中的印刷文字转化为可编辑和可搜索的数字文本的技术。随着数字化和信息化的快速发展&#xff0c;OCR 技术逐渐成为处理大量纸质或电子文档的主要手段之一…