当前位置: 首页 > 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…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...