【自动驾驶】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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Vue3】组件通信之mitt

【Vue3】组件通信之mitt 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日…

什么是智能加密?超好用神器智能加密软件推荐

信息安全已成为我们日常生活中不可忽视的一环。 随着网络攻击手段的不断升级和隐私泄露事件的频发&#xff0c;如何有效保护个人及企业的敏感数据成为了亟待解决的问题。 智能加密&#xff0c;作为信息安全领域的一项重要技术&#xff0c;正逐渐走进大众视野&#xff0c;以其高…

【数据结构七夕专属版】单链表及单链表的实现【附源码和源码讲解】

本篇是博主在学习数据结构时的心得&#xff0c;希望能够帮助到大家&#xff0c;也许有些许遗漏&#xff0c;但博主已经尽了最大努力打破信息差&#xff0c;如果有遗漏还请见谅&#xff0c;嘻嘻&#xff0c;前路漫漫&#xff0c;我们一起前进&#xff01;&#xff01;&#xff0…

超声波眼镜清洗机哪家强?盘点四款精品超声波清洗机机型

超声波清洗机因其卓越的清洁能力&#xff0c;成为了家庭和专业环境中清洁小物件的理想选择。无论是日常佩戴的眼镜、珍贵的珠宝首饰&#xff0c;还是精密的电子设备和实验工具&#xff0c;超声波清洗机都能提供深层、温和且高效的清洁。然而&#xff0c;面对市场上众多品牌和价…

原神4.8版本升级计划数据表

原神4.8版本角色数据升级计划表 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>原神4.8版本升级计划…

使用Anaconda安装多个版本的Python并与Pycharm进行对接

1、参考链接 Anaconda安装使用教程解决多Python版本问题_anaconda安装多个python版本-CSDN博客 基于上面的一篇博客的提示&#xff0c;我做了尝试。并在Pycharm的对接上做了拓展。 2、首先安装Anaconda 这个比较简单&#xff0c;直接安装即可&#xff1a; 3、设置conda.exe的…

【iOS】SideTable

目录 SideTablesStripedMapSideTable1. spinlock_t slock2. RefcountMap3. weak_table_t 总结 objc4源码地址&#xff1a; SideTable& table SideTables()[this]; // 获取对象的SideTable size_t& refcntStorage table.refcnts[this];SideTables 查源码SideTables…

K8s第三节:k8s1.23.1升级为k8s1.30.0

上回书说到我们使用了kubeadm安装了k8s1.23.1,但是在k8s1.24之前还是使用docker作为容器运行时&#xff0c;所以这一节我打算将我安装的k8s集群升级为1.30.0版本&#xff1b; 1、修改containerd 配置 因为我们安装的docker自带containerd&#xff0c;所以我们不需要重新安装con…

docker拉取MySQL后数据库连接失败解决方案

如果数据库连接失败&#xff0c;检查以下几个地方&#xff1a; 1&#xff1a;防火墙&#xff0c;查看防火墙是否打开&#xff1a; systemctl status firewalld 关闭状态&#xff1a; 开启状态&#xff1a; 如果是开启状态&#xff0c;则很有可能是防火墙拦截掉了3306端口的访问…

挖矿木马攻破了服务器

最近被国外的挖矿木马攻破了服务器 根据非法登录&#xff0c;用 #last指令查看登录ip 首先删掉登录主机 #kill -9 pts/0 第二步 #top 看看什么占用cpu高 第三步杀死狂刷CPU的服务 过一分钟后&#xff0c;服务又开始狂刷cpu。 第四步根据pid查到服务地址 #systemctl status…

HarmonyOS Flex布局

前置知识&#xff1a; 一次开发&#xff0c;多端部署:一套代码工程&#xff0c;一次开发上架&#xff0c;多端按需部署。支撑开发者快速高效的开发支持多种终端设备形态的应用&#xff0c;实现对不同设备兼容的同时&#xff0c;提供跨设备的流转、迁移和协同的分布式体验自适应…

[FSCTF 2023]细狗2.0

尝试输入cat /f* 输入&#xff1b;ls / 过滤了空格 输入 &#xff1b;ls 看到2个php, 空格绕过可以用注释替换空格 &#xff1b;ca\t/*123*/f* 发现不可以&#xff0c;看题解后发现使用${IFS}绕过 $IFS代替空格;$IFS、$IFS2、${IFS}、$IFS$9 Linux下有一个特殊的环境变量…

Java 文件上传七牛云

Java系列文章目录 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述四、解决方案&#xff1a;4.1 新建空间4.2 查找密钥4.3 进入开发者中心查找JavaSDK文档4.4 查找文件上传方法4.5 运行测试 五、总结&#xff1a;5.1 学习总结&#xff1a; 一、前言 学…

数据结构(其六)--树(一般的树)

目录 1.树的知识总览 2.树的基本概念 i.部分名词 ii.结点间的关系 iii.属性 3.树的常考性质 i.结点数 ii.度为m的树 与 m叉树 的区别&#xff08;m>0&#xff09; iii.树的第 i 层的结点数&#xff08;i>1&#xff09; ​编辑 iiii. 高度为h的m叉树的结点数 iiiii.高…

人工智能安全态势和趋势

吴世忠 中工院士 国家保密科技委主任 重大风险隐患呼唤加强安全研究&#xff0c;人工智能面临未来担忧 1 总体态势 1.1 相对于技术发展&#xff0c;安全研究严重滞后 1.2 我国研究十分活跃&#xff0c;论文数量遥遥领先 1.3 影响力美国排名第一&#xff0c;大厂大学作用大 1…

C#获取Network的相关信息

1&#xff0c;获取网络的通断。 //方法1&#xff1a;无效果&#xff0c;并不能反映当前网络通断 bool availableSystem.Windows.Forms.SystemInformation.Network//方法2&#xff1a;通过VB获取网络状态&#xff0c;可反映当前网络通断 Microsoft.VisualBasic.Devices.Network…

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(七)卡尔曼滤波器三:卡尔曼滤波器公式推导【转载】

卡尔曼滤波器三&#xff1a;卡尔曼公式推导 转载来源&#xff1a;卡尔曼滤波&#xff1a;从入门到精通 简述 考虑一个SLAM 问题&#xff0c;它由一个运动方程&#xff1a; x t f ( x t − 1 , u t ) ω t (1) \mathbf{x}_{t}f(\mathbf{x}_{t-1},\mathbf{u}_{t}) \omega_…

在国产芯片上实现YOLOv5/v8图像AI识别-【2.3】RK3588上使用C++启用多线程推理更多内容见视频

本专栏主要是提供一种国产化图像识别的解决方案&#xff0c;专栏中实现了YOLOv5/v8在国产化芯片上的使用部署&#xff0c;并可以实现网页端实时查看。根据自己的具体需求可以直接产品化部署使用。 B站配套视频&#xff1a;https://www.bilibili.com/video/BV1or421T74f 基础…

算法(数组+链表)

37.移除元素 数组的删除其实是元素的覆盖 比如刚开始五个元素删除了一个 他变成了四个元素 但是他的空间大小还是五 删除元素是o&#xff08;n&#xff09;erase的时间复杂度是o&#xff08;n&#xff09; 暴力实现 当使用两层for循环去删除元素的时候 比如要删除元素三 …

JNPF快速开发平台助力企业实现工作流自动化

随着企业信息化建设的不断深入&#xff0c;工作流自动化已成为提升企业效率、优化业务流程的关键手段。JNPF快速开发平台凭借其强大的功能和灵活的配置&#xff0c;为众多企业提供了实现工作流自动化的高效解决方案。 关于低代码开发平台的普及应用 随着信息技术的迅猛发展&…