当前位置: 首页 > news >正文

【自动驾驶】ROS中自定义格式的服务通信,含命令行动态传参(c++)

目录

  • 通信流程
  • 创建服务器端及客户端
  • 新建服务通讯文件
  • 修改service的xml及cmakelist
  • CMakeLists.txt编辑 msg 相关配置
  • 编译消息相关头文件
  • 在cmakelist中包含头文件的路径
  • 在service包下编写service.cpp
  • 在client包下编写client.cpp
  • 测试运行
  • 查询服务的相关指令
    • 列出目前的所有服务:
    • 查询参数:
    • 显示某包下的服务
    • 显示服务消息的具体信息

服务通信是基于请求产生的通信。

通信流程

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

创建服务器端及客户端

cd 到ws/src目录下:

catkin_create_pkg service std_msgs rospy roscpp
catkin_create_pkg client std_msgs rospy roscpp

新建服务通讯文件

在服务端的src目录下,新建srv文件夹,并在内新建mymessage.srv

# 客户端请求时发送的两个数字
string a
string b
#客户端发送与服务端响应,中间使用---进行隔开,这里是简单把两个string拼接在一起
---
# 服务器响应发送的数据
string ab

修改service的xml及cmakelist

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

  <build_depend>message_generation</build_depend><exec_depend>message_runtime</exec_depend>

CMakeLists.txt编辑 msg 相关配置

find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation
)

需要加入 message_generation,必须有 std_msgs

#配置 srv 源文件

add_service_files(FILESAddInts.srv
)

生成消息时依赖于 std_msgs

generate_messages(DEPENDENCIESstd_msgs
)#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listenerCATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

编译消息相关头文件

退回到ws目录,使用catkin_make --pkg service
编译出相关的三个头文件
在这里插入图片描述

在cmakelist中包含头文件的路径

新生成的.h文件位于devel/include文件夹下,在请求及响应方的cmakelist中添加:

include_directories(
# include${catkin_INCLUDE_DIRS}"/root/work/ws/devel/include/"
)

在service包下编写service.cpp

服务端的功能主要是将收到的两个string连接起来。


#include "ros/ros.h"
#include "service/mymessage.h"
#include <string>
// bool 返回值由于标志是否处理成功
bool doReq(service::mymessage::Request& req,service::mymessage::Response& resp){std::stringstream ss;ss<<std::string(req.a)<<std::string(req.b);ROS_INFO("拼好的字符串:%s",ss.str().c_str());resp.ab = ss.str();return true;
}int main(int argc, char *argv[])
{setlocale(LC_ALL,"");// 2.初始化 ROS 节点ros::init(argc,argv,"testServer");// 3.创建 ROS 句柄ros::NodeHandle nh;// 4.创建服务以及注册回调函数ros::ServiceServer server = nh.advertiseService("mymessage",doReq);ROS_INFO("服务已经启动....");//     5.回调函数处理请求并产生响应//     6.由于请求有多个,需要调用 ros::spin()ros::spin();return 0;
}

同时在cmakelist中:

add_executable(${PROJECT_NAME}_node src/service.cpp)
target_link_libraries(${PROJECT_NAME}_node${catkin_LIBRARIES}
)

在service包下新增launch文件

<launch><node name="myservice" pkg="service" type="service_node" output="screen"/>
</launch>

在client包下编写client.cpp


// 1.包含头文件
#include "ros/ros.h"
#include "service/mymessage.h"int main(int argc, char *argv[])
{setlocale(LC_ALL,"");// argv[0]:指向程序名称 ./program 的字符串指针// argv[1]:指向 arg1 的字符串指针// argv[2]:指向 arg2 的字符串指针// 调用时动态传值,如果通过 launch 的 args 传参,需要传递的参数个数 +3,//launch 传参(0-文件路径 1传入的参数 2传入的参数 3节点名称 4日志路径)if (argc != 5){ROS_INFO("argc=(%d)",argc);ROS_ERROR("请提交两个字符串");return 1;}// 2.初始化 ROS 节点ros::init(argc,argv,"testClient");// 3.创建 ROS 句柄ros::NodeHandle nh;// 4.创建 客户端 对象ros::ServiceClient client = nh.serviceClient<service::mymessage>("mymessage");//等待服务启动成功//方式1ros::service::waitForService("mymessage");//方式2// client.waitForExistence();// 5.组织请求数据service::mymessage ai;//直接输入命令行的字符串ai.request.a = argv[1];ai.request.b = argv[2];// 6.发送请求,返回 bool 值,标记是否成功bool flag = client.call(ai);// 7.处理响应if (flag){ROS_INFO("请求正常处理,响应结果:%s",ai.response.ab.c_str());}else{ROS_ERROR("请求处理失败....");return 1;}return 0;
}

同时在cmakelist中:

add_executable(${PROJECT_NAME}_node src/client.cpp)
target_link_libraries(${PROJECT_NAME}_node${catkin_LIBRARIES}
)

在client包下新增launch文件

<launch><arg name="a" default="empty"/><arg name="b" default="empty"/><node name="myclient" pkg="client" type="client_node" args="$(arg a) $(arg b)" output="screen"/>
</launch>

测试运行

source /root/work/ws/devel/setup.bash
roslaunch service start.launch 
#通过如下命令行的形式传入参数,launch文件中使用$(arg a)引用参数的值
roslaunch client start.launch a:=abcd b:=5678

在这里插入图片描述

查询服务的相关指令

列出目前的所有服务:

rosservice list

得到服务列表:

/mymessage
/myservice/get_loggers
/myservice/set_logger_level
/rosout/get_loggers
/rosout/set_logger_level

查询参数:

rosservice args /mymessage

输出:

a b

显示某包下的服务

rossrv package service

得出:

service/mymessage

显示服务消息的具体信息

rossrv show mymessage

得出具体信息

[service/mymessage]:
string a
string b
---
string ab

相关文章:

【自动驾驶】ROS中自定义格式的服务通信,含命令行动态传参(c++)

目录 通信流程创建服务器端及客户端新建服务通讯文件修改service的xml及cmakelistCMakeLists.txt编辑 msg 相关配置编译消息相关头文件在cmakelist中包含头文件的路径在service包下编写service.cpp在client包下编写client.cpp测试运行查询服务的相关指令列出目前的所有服务&…...

优思学院|PDCA和DMAIC之间如何选择?

在现代组织中&#xff0c;提升方法、质量和效率是企业追求卓越、保持竞争力的核心目标。在这条道路上&#xff0c;DMAIC&#xff08;定义、测量、分析、改进、控制&#xff09;和PDCA&#xff08;计划、执行、检查、行动&#xff09;被广泛应用于持续改进和问题解决。这两者虽然…...

5 款最佳 Micro SD 卡恢复软件,助您恢复文件

您是否对数据恢复存在某些疑问&#xff0c;并想知道如何恢复 Micro SD 卡上的文件&#xff1f;如果是&#xff0c;那么在本文中您将找到答案。网上有许多专门用于从 Micro SD 卡或格式化的 Micro 卡恢复已删除文件而设计的软件。因此&#xff0c;在本文中&#xff0c;我们将向您…...

【使用教程】CiA402中的“原点回归模式”和“轮廓位置模式”搭配使用操作实例

使用“原点回归模式”配合“轮廓位置模式”是步进或伺服电机使用过程中最常用的方法&#xff0c;其对于提高自动化生产线的准确性和效率具有重要意义&#xff0c;本文将对正常使用控制电机中发送的命令及顺序进行简要说明。 说明&#xff1a;“原点回归”以“堵转回原点”的方式…...

服务器网络不通排查方案

服务器网络不通排查方案 最近遇到了服务器上服务已经启动&#xff0c;但是在浏览器上无法访问的问题&#xff0c;记录一下排查流程 文章目录 服务器网络不通排查方案netstart排查网络连接信息netstat 命令netstat -aptn 命令 iptables总结 netstart排查网络连接信息 netstat …...

Spring Boot + Vue 跨域配置(CORS)问题解决历程

在使用 Spring Boot 和 Vue 开发前后端分离的项目时&#xff0c;跨域资源共享&#xff08;CORS&#xff09;问题是一个常见的挑战。接下来&#xff0c;我将分享我是如何一步步解决这个问题的&#xff0c;包括中间的一些试错过程&#xff0c;希望能够帮助到正在经历类似问题的你…...

Think | 大模型迈向AGI的探索和对齐

注&#xff1a;节选自我于24年初所写的「融合RL与LLM思想探寻世界模型以迈向AGI」散文式风格文章&#xff0c;感兴趣的小伙伴儿可以访问我的主页置顶或专栏收录&#xff0c;并制作了电子书供大家参考&#xff0c;有需要的小伙伴可以关注私信我&#xff0c;因为属于技术散文风格…...

为什么选择在Facebook投放广告?

2024年了你还没对 Facebook 广告产生兴趣&#xff1f;那你可就亏大了&#xff01; 今天这篇文章&#xff0c;我们会分享它对你扩大业务的好处。要知道&#xff0c;Facebook 广告凭借它庞大的用户群和先进的定位选项&#xff0c;已经是企业主们有效接触目标受众的必备神器。接下…...

10 ARM 体系

10 ARM 体系 ARM体系1、基本概念1.1 常见的处理器1.2 ARM7三级指令流水线1.3 初识PC寄存器 2、 ARM核的七种工作模式3、ARM核七种异常 ARM体系 1、基本概念 1.1 常见的处理器 PowerPC处理器&#xff1a;飞思卡尔MPC系列 DSP:TI达芬奇系列 FPGA&#xff1a;Xilinx赛灵思的ZYN…...

ubuntu中设置开机自动运行的(sudo)指令

ubuntu版本&#xff1a;22.04.4 在Ubuntu中设置开机自动运行某一条&#xff08;需要sudo权限的&#xff09;指令&#xff0c;我们可以通过编辑系统的启动脚本来实现&#xff1a; 创建一个新的启动脚本&#xff1a;创建一个新的脚本文件&#xff0c;并将其放置在 /etc/init.d/ 目…...

删掉Elasticsearch6.x 的 .security-6索引会怎么样?

背景 玩了下 Elasticsearch 的认证&#xff0c;启动 ES 并添加认证后&#xff0c;看到索引列表额外多了一个 .security-6 。以为是没用的&#xff0c;手欠就给删掉了&#xff0c;然后 Elasticsearch 就访问不了了。 只好再重新部署&#xff0c;再看索引内容&#xff0c;发现这…...

Navicat Premium15 下载与安装(免费版)以及链接SqlServer数据库

转自:https://blog.csdn.net/m0_75188141/article/details/139842565...

Vue3配置vite.config.js代理解决跨域问题

前言: 当浏览器发出一个请求时,只要请求URL的协议、域名、端口三者之间任意一个与当前页面URL不同,就称为跨域。 跨域一般出现在开发阶段,由于线上环境前端代码被打包成了静态资源,因而不会出现跨域问题,这篇文章主要给大家介绍了关于Vue3配置vite.config.js解决跨域问题的相…...

Solidity面试题,由浅入深

Solidity是Ethereum智能合约的主要编程语言&#xff0c;面试题的设计旨在评估候选人对Solidity语言特性的掌握程度&#xff0c;以及他们对区块链和智能合约的理解。下面列出了一些常见的Solidity面试题&#xff0c;涵盖基础知识到高级概念&#xff0c;并简要说明每个问题的答案…...

变量的注意或许需要调试

输入一个自然数N&#xff08;1<N<9&#xff09;&#xff0c;从小到大输出用1~N组成的所有排列&#xff0c;也就说全排列。例如输入3则输出 123 132 213 231 312 321 输入格式: 输入一个自然数N&#xff08;1<N<9&#xff09; 输出格式: N的全排列&#xff0c;每行一…...

C# 增删改查教程 代码超级简单

目录 一.留言 二 .帮助类 三 .增删改查代码展示 一.留言 大家好&#xff0c;前几篇文章我们更新了 C# 三层架构的相关代码&#xff0c;主要写了登录&#xff0c;以及增删改查的相关代码&#xff0c;用的三层架构的框架&#xff0c;那么本篇文章一次性更新C#的增删改查相关代…...

OceanBase V4.2特性解析:OB Oracle模式下的 SDO_GEOMETRY 空间数据类型

1. 背景 1.1. SDO_GEOMETRY的应用场景及能力 在数字化城市、物联网和新能源汽车等领域蓬勃发展的背景下&#xff0c;空间数据类型的存储和分析需求日益增长&#xff1b;对于涉及位置信息服务和地理位置信息应用而言&#xff0c;数据库中具备对sdo_geometry数据类型的支持无疑…...

简介面向对象的封装、继承、多态和抽象

面向对象&#xff08;Object-Oriented&#xff09;的特点通常归纳为四个核心概念&#xff1a;封装、继承、多态和抽象。 1. 封装&#xff08;Encapsulation&#xff09; 定义: 封装是将对象的属性&#xff08;数据&#xff09;和方法&#xff08;操作&#xff09;打包在一起&…...

OpenCV + CUDA + cuDNN模块编译

简介 在追求高端性能与资源优化并重的应用场景中&#xff0c;如边缘计算设备或资源受限的开发板上运行YOLO等复杂深度学习模型&#xff0c;采用C结合OpenCV与GPU加速技术相较于传统的Python环境展现出显著优势。这种策略不仅极大地提升了执行效率&#xff0c;还显著降低了运行时…...

Redis 缓存预热、雪崩、穿透、击穿

缓存预热 缓存预热是什么 缓存预热就是系统上线后&#xff0c;提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候&#xff0c;先查询数据库&#xff0c;然后再将数据缓存的问题&#xff01;用户直接查询事先被预热的缓存数据&#xff01;解决方案 使用 PostConstr…...

仿RabbiteMq简易消息队列基础篇(gtest的使用)

TOC gtest介绍 gtest是google的一个开源框架&#xff0c;它主要用于写单元测试&#xff0c;检查自己的程序是否符合预期行为。可在多个平台上使用&#xff08;包含Linux&#xff0c;MAC OC&#xff0c;Windows等&#xff09;。它提供了丰富的断言&#xff0c;致命和非致命失败…...

图像处理中的图像梯度和幅值是什么???(通俗讲解)

在边缘检测和特征提取等任务中&#xff0c;图像的梯度和幅值是图像处理中非常重要的概念。 目录 一、图像的梯度1.1 专业解释1.2 通俗理解1.3 计算方式 二、梯度的幅值2.1 专业解释2.2 通俗理解2.3 计算方式 一、图像的梯度 1.1 专业解释 图像的梯度可以看作是图像中亮度或颜…...

01.计算机网络导论

引言 协议分层 协议分层使我们可以将大任务化简成几个更小、更简单的任务。模块化指的是独立的协议层。一个协议层&#xff08;模块&#xff09;可以定义为一个具有输入和输出而不需要考虑输入是如何变成输出的黑匣子。当向两台机器提供相同输入得到相同输出时&#xff0c;它…...

API网关:SpringCloud GateWay

一. 网关的作用及背景 1.API网关的作用 请求路由 在我们的系统中由于同一个接口新老两套系统都在使用&#xff0c;我们需要根据请求上下文将请求路由到对应的接口。 统一鉴权 对于鉴权操作不涉及到业务逻辑&#xff0c;那么可以在网关层进行处理&#xff0c;不用下层到业务…...

【Leetcode 383】赎金信 —— 哈希表 有注解

给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入&#…...

Linux 常见的冷知识集锦

一、前言 本文旨在记录那些常见的Linux概念和名词&#xff0c;但这些又没经常直接使用到&#xff0c;更多在底层运行&#xff0c;见过却又不是特别清楚的碎片知识&#xff0c;以温故知新。 二、知识点和概念说明 2.1、POSIX标准/协议 POSIX&#xff08;Portable Operating S…...

【喜报】科大睿智祝贺青岛海信网络科技通过CMMI5级评估

​ 青岛海信网络科技股份有限公司成立于1998年&#xff0c;是海信集团B2B产业的核心力量。其主要从事城市交通、公共交通、智慧公路、交通枢纽、智慧停车、智能网联、大数据管理、城市治理、应急管理、轨道交通智能化和医院、校园、园区等智能化建设领域的产品和解决方案开发、…...

2024全国大学生电子设计大赛全国初赛 E题 三子棋游戏装置 一等奖满分最简方案

感想&#xff1a;电赛初赛控制类题还是蛮简单的&#xff0c;别被五花八门的硬件搞懵了&#xff08;决赛当我没说&#xff09;。抓住核心&#xff0c;理念都是通用的。我是计科专业的&#xff0c;因此选择的控制类E题&#xff0c;相对来说背的知识要少很多&#xff0c;更考验智商…...

尚品汇-ES(三十一)

目录&#xff1a; &#xff08;1&#xff09;封装搜索相关实体对象 &#xff08;2&#xff09;搜索接口封装 &#xff08;3&#xff09;在service-list-client模块添加远程接口 &#xff08;1&#xff09;封装搜索相关实体对象 搜索参数实体&#xff1a;SearchParam 搜索参…...

NC 跳台阶

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 一只青蛙一次…...