ROS服务通信(七)C++、Python实现

2023-05-16

目录

简介

理论模型

 服务通信自定srv

创建srv 

编辑配置文件 

C++实现 

 vscode配置

 服务端实现

客户端实现

 优化

Python实现

服务端实现 

 客户端实现


简介

服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A

比如如下场景:

机器人巡逻过程中,控制系统分析传感器数据发现可疑物体或人... 此时需要拍摄照片并留存。

上述场景中,就使用到了服务通信。

  • 一个节点需要向相机节点发送拍照请求,相机节点处理请求,并返回处理结果

与上述应用类似的,服务通信更适用于对时时性有要求、具有一定逻辑处理的应用场景。

 

 

服务器启动,客户端发送客户数据,服务端进行计算并返回结果

理论模型

 

 服务通信自定srv

 

创建一个新的功能包

 

 建立依赖

创建srv 

 然后是创建自定义的srv

 复制以下代码

int32 num1
int32 num2
---
int32 sum

注意:---用来分隔请求与响应

编辑配置文件 

 

 

 构建的时候依赖这个包

生成服务

生成依赖

 

这是find_package里面依赖的包

 然后

ctrl shift b编译一下

会生成很多中间文件

 

生成请求端(客户端)文件

生成服务端文件

 

请求内容

 

服务内容

 python里也生成了对应文件

 小结:

实际上跟msg很像,只不过多了一个---来区分请求和响应的消息

C++实现 

 

 

 流程

  1. 编写服务端实现;
  2. 编写客户端实现;
  3. 编辑配置文件;
  4. 编译并执行。

 vscode配置

 

 

 复制路径

 服务端实现

 复制以下代码

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

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

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

// bool 返回值由于标志是否处理成功
bool doReq(demo03_server_client::AddInts::Request& req,
          demo03_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;
}

CMakeLists配置 

ctrl / 取消注释 

 

 上面的有些错误看下图改正一下即可

 然后测试一下

客户端实现

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

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

*/
// 1.包含头文件
#include "ros/ros.h"
#include "demo03_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<demo03_server_client::AddInts>("AddInts");
    //等待服务启动成功
    //方式1
    ros::service::waitForService("AddInts");
    //方式2
    // client.waitForExistence();
    // 5.组织请求数据
    demo03_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;
}

修改CMakeLists

 然后

ctrl shift b编译

开始测试

 输入数字

 优化

 

 

 再启动服务端

 此时就可以了

Python实现

 

服务端实现 

新建文件并且复制以下代码

 

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

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

"""
# 1.导包
import rospy
from demo03_server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
# 回调函数的参数是请求对象,返回值是响应对象
def doReq(req):
    # 解析提交的数据
    sum = req.num1 + req.num2#num1、num2来自于.srv文件
    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)
    # 4.回调函数处理请求并产生响应
    # 5.spin 函数
    rospy.spin()

授予执行权限

 配置CMakeLists

 然后进行编译

 客户端实现

 新建文件

复制以下代码

#! /usr/bin/env python

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

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

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


"""
#1.导包
import rospy
from demo03_server_client.srv import *
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)

授予权限

修改CMakeLists

 

 然后编译

 进行终端测试

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS服务通信(七)C++、Python实现 的相关文章

  • Django 代理模型的继承和多态性

    我正在开发一个我没有启动的 Django 项目 我面临着一个问题遗产 我有一个大模型 在示例中简化 称为MyModel这应该代表不同种类的物品 的所有实例对象MyModel应该具有相同的字段 但方法的行为根据项目类型的不同而有很大差异 到目
  • SQLAlchemy 通过关联对象声明式多对多自连接

    我有一个用户表和一个朋友表 它将用户映射到其他用户 因为每个用户可以有很多朋友 这个关系显然是对称的 如果用户A是用户B的朋友 那么用户B也是用户A的朋友 我只存储这个关系一次 除了两个用户 ID 之外 Friends 表还有其他字段 因此
  • 将 saxon 与 python 结合使用

    我需要使用 python 处理 XSLT 目前我正在使用仅支持 XSLT 1 的 lxml 现在我需要处理 XSLT 2 有没有办法将 saxon XSLT 处理器与 python 一起使用 有两种可能的方法 设置一个 HTTP 服务 接受
  • 将 Matplotlib 误差线放置在不位于条形中心的位置

    我正在 Matplotlib 中生成带有错误栏的堆积条形图 不幸的是 某些层相对较小且数据多样 因此多个层的错误条可能重叠 从而使它们难以或无法读取 Example 有没有办法设置每个误差条的位置 即沿 x 轴移动它 以便重叠的线显示在彼此
  • OpenCV Python cv2.mixChannels()

    我试图将其从 C 转换为 Python 但它给出了不同的色调结果 In C Transform it to HSV cvtColor src hsv CV BGR2HSV Use only the Hue value hue create
  • Python - StatsModels、OLS 置信区间

    在 Statsmodels 中 我可以使用以下方法拟合我的模型 import statsmodels api as sm X np array 22000 13400 47600 7400 12000 32000 28000 31000 6
  • 使用 on_bad_lines 将 pandas.read_csv 中的无效行写入文件

    我有一个 CSV 文件 我正在使用 Python 来解析该文件 我发现文件中的某些行具有不同的列数 001 Snow Jon 19801201 002 Crom Jake 19920103 003 Wise Frank 19880303 l
  • 根据列值突出显示数据框中的行?

    假设我有这样的数据框 col1 col2 col3 col4 0 A A 1 pass 2 1 A A 2 pass 4 2 A A 1 fail 4 3 A A 1 fail 5 4 A A 1 pass 3 5 A A 2 fail 2
  • 如何从网页中嵌入的 Tableau 图表中抓取工具提示值

    我试图弄清楚是否有一种方法以及如何使用 python 从网页中的 Tableau 嵌入图形中抓取工具提示值 以下是当用户将鼠标悬停在条形上时带有工具提示的图表示例 我从要从中抓取的原始网页中获取了此网址 https covid19 colo
  • SQLALchemy .query:类“Car”的未解析属性引用“query”

    我有一个这里已经提到的问题https youtrack jetbrains com issue PY 44557 https youtrack jetbrains com issue PY 44557 但我还没有找到解决方案 我使用 Pyt
  • Python 函数可以从作用域之外赋予新属性吗?

    我不知道你可以这样做 def tom print tom s locals locals def dick z print z name z name z guest Harry print z guest z guest print di
  • 如何使用 OpencV 从 Firebase 读取图像?

    有没有使用 OpenCV 从 Firebase 读取图像的想法 或者我必须先下载图片 然后从本地文件夹执行 cv imread 功能 有什么办法我可以使用cv imread link of picture from firebase 您可以
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • Pygame:有没有简单的方法可以找到按下的任何字母数字的字母/数字?

    我目前正在开发的游戏需要让人们以自己的名义在高分板上计时 我对如何处理按键有点熟悉 但我只处理过寻找特定的按键 有没有一种简单的方法可以按下任意键的字母 而不必执行以下操作 for event in pygame event get if
  • 无法在 Python 3 中导入 cProfile

    我试图将 cProfile 模块导入 Python 3 3 0 但出现以下错误 Traceback most recent call last File
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • Jupyter Notebook 内核一直很忙

    我已经安装了 anaconda 并且 python 在 Spyder IPython 等中工作正常 但是我无法运行 python 笔记本 内核被创建 它也连接 但它始终显示黑圈忙碌符号 防火墙或防病毒软件没有问题 我尝试过禁用两者 我也无法
  • 有人用过 Dabo 做过中型项目吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我们正处于一个新的 ERP 风格的客户端 服务器应用程序的开始阶段 该应用程序是作为 Python 富客户端开发的 我们目前正在评估 Dabo
  • 使用其构造函数初始化 OrderedDict 以便保留初始数据的顺序的正确方法?

    初始化有序字典 OD 以使其保留初始数据的顺序的正确方法是什么 from collections import OrderedDict Obviously wrong because regular dict loses order d O
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我

随机推荐

  • ipmitool使用

    BMC IPMI常用命令 BMC Baseboard Management Controler 提供了多种通道来和主机通信 xff0c 进而检测主机的温度 风扇转速 电压 电源和现场可替代器件 为了便于用户使用 xff0c 它提供了非常丰富
  • 基于LMI的等效滑模控制

    目录 前言 1 一阶欠驱动倒立摆系统 2 基于LMI的等效滑模控制器 3 simulink仿真 3 1 simulink模型 3 2 结果分析 3 2 结论 前言 关于LMI和滑模控制的结合上两篇文章已有介绍和仿真分析 xff0c 本篇文章
  • 基于扩张观测器(LESO)的滑模控制

    目录 前言 1 二阶系统LESO观测器设计 2 基于LESO的滑模控制器设计 3 仿真分析 普通高增益项 3 1仿真模型 3 2仿真结果 3 3 总结 4 仿真分析 优化后的高增益项 4 1 优化高增益项 4 2仿真结果 4 2 1 高增益
  • 基于遗传算法和粒子群算法的PID悬架控制、LQR悬架控制和滑模悬架控制

    目录 1 基于遗传算法和粒子群算法的的PID悬架控制 1 1 两种悬架系统 1 1 1 将路面激励整合到悬架系统 1 1 2 不将路面激励整合到悬架系统 1 1 3 总结 1 2 PID经典控制理论 1 3 优化PID参数的目标函数和约束条
  • 2自由度陀螺仪滑模控制和PID控制跟踪目标轨迹

    目录 前言 1 陀螺仪模型 2 滑模跟踪控制 3 PID控制 4 总结 1 陀螺仪模型 2 滑模跟踪控制 对于2自由度陀螺仪有两个方向x y跟踪 xff0c 所以需要分别为两个方向单独设计滑模面 xff0c 这里仍以简单的线性滑模面设计分析
  • 自抗扰控制ADRC之三种微分跟踪器TD仿真分析

    目录 前言 1 全程快速微分器 1 1仿真分析 1 2仿真模型 1 3仿真结果 1 4结论 2 Levant微分器 2 1仿真分析 2 2仿真模型 2 3仿真结果 3 非线性跟踪微分器 韩教授 3 1仿真分析 3 2小结 4 总结 前言 工
  • 自抗扰控制ADRC之扩张观测器

    目录 前言 1 被控对象 被观测对象 2 非线性观测器 2 1仿真分析 2 2仿真模型 2 3仿真结果 3 线性观测器 3 1仿真模型 3 2仿真结果 4 总结和学习问题 前言 什么叫观测器 xff1f 为什么该类观测称为扩张观测器 xff
  • 基于神经网络(RBF)补偿的双关节机械手臂自适应控制

    目录 前言 1 双关节机械手臂模型 1 1 实际模型 1 2 名义模型 2 控制律设计 3 神经网络补偿自适应律设计 3 1自适应律 3 2自适应律 4 仿真分析 4 1仿真模型 4 2 仿真结果 4 3 小结 5学习问题 前言 所谓的补偿
  • PID、模糊PID、SkyHook、LQR、H2/H∞、ADRC等悬架控制合集

    罗列一下现成的悬架模型以及应用的控制算法 xff1a PID 模糊PID SkyHook LQR H2 H ADRC等 xff0c 以及kalman观测器 xff1a 半车 前后 左右 整车悬架详细推导建模和simulink仿真分析 侧倾
  • 1086:角谷猜想(C C++)

    题目描述 谓角谷猜想 xff0c 是指对于任意一个正整数 xff0c 如果是奇数 xff0c 则乘3加1 xff0c 如果是偶数 xff0c 则除以2 xff0c 得到的结果再按照上述规则重复处理 xff0c 最终总能够得到1 如 xff0
  • 渗透测试工具之Metasploit Framework(MSF)

    一 Metasploit Framework xff08 MSF xff09 简介 Metasploit是当前信息安全与渗透测试领域最流行的术语 xff0c 它的出现颠覆了以往的已有的渗透测试的方式 几乎所有流行的操作系统都支持Metasp
  • Test Case Framework (TCF) 简介

    TCF is a system that simplifies the creation and execution of test cases automation for that matter with minimal setup e
  • 小菜鸡的第一天

    1 CPU分配 xff0c i5四核所以给Linux分配两个核 2 内存分配 xff0c 有16GB所以分配8个g 3 硬盘 xff0c 需要创立一个独立的分区 xff0c 最好300G以上 xff08 由于个人原因分配了60G xff09
  • 小菜鸡的第二天

    绝对路径 xff1a 以 开头 代表当前路径 xff0c 或者 代表上一级目录 xff0c 或者 插入U盘之后 xff0c 在 dev文件夹下输入 ls sd 可以看到U盘信息 xff0c 要想知道插入的U盘是哪个 xff0c 重新插拔再次
  • 小菜鸡的第三天

    压缩与解压 tar vcjf 43 文件名 tar bz2 xxx xxx是要压缩的文件名 压缩命令 tar vxjf 43 xxx tar bz2 xxx是要解压缩的文件名 解压缩命令 f xff1a 使用归档文件或ARCHIVE设备 c
  • 初级算法:判断数组是否存在重复元素

    qsort函数原型是 void qsort xff08 void base size t num size t width int cdecl compare const void const void xff09 4个参数 xff1a v
  • 初级算法:删除排序数组中的重复项

    因为数组是排序的 xff0c 只要是相同的肯定是挨着的 xff0c 我们只需要遍历所有数组 xff0c 然后前后两两比较 xff0c 如果有相同的就把后面的给删除 双指针解决 使用两个指针 xff0c 右指针始终往右移动 xff0c 如果右
  • 运算符重载

    加号运算符重载 作用 xff1a 实现两个自定义数据类型相加的运算 span class token keyword class span span class token class name Person span span class
  • .在python中的作用

    的作用 点把前后连起来 xff0c 构成一种索引机制 前面是库 后面是函数 ex xff1a pybullet setAdditionalSearchPath是指在pybullet的库中引用setAdditionalSearchPath这个
  • ROS服务通信(七)C++、Python实现

    目录 简介 理论模型 服务通信自定srv 创建srv 编辑配置文件 C 43 43 实现 vscode配置 服务端实现 客户端实现 优化 Python实现 服务端实现 客户端实现 简介 服务通信也是ROS中一种极其常用的通信模式 xff0c