ROS2从入门到精通1-2:详解ROS2服务通信机制与自定义服务

目录

  • 0 专栏介绍
  • 1 服务通信模型
  • 2 服务模型实现(C++)
  • 3 服务模型实现(Python)
  • 4 自定义服务
  • 5 话题、服务通信的异同

0 专栏介绍

本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。

🚀详情:《ROS2从入门到精通》


1 服务通信模型

服务是 ROS 图中节点之间的另一种通信方法。服务基于服务器-客户端模型,不同于话题的发布者-订阅者模型。话题允许节点订阅数据流并获取持续更新,而服务只在客户端特别调用时才提供数据。二者更详细的对比请参考第5节

在这里插入图片描述

在这里插入图片描述

2 服务模型实现(C++)

实验目标:客户端提交请求给turtlesim功能包的/spawn服务,在界面上生成新的乌龟。

  • 服务器

    本实验中无需编程,为turtlesim::Spawn定义的/spwan服务

  • 客户端

    void OnResultCallBack(rclcpp::Client<turtlesim::srv::Spawn>::SharedFuture result) {
        auto response = result.get();
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Request service successfully! [turtle id: %s]", response->name.c_str());
    }
    
    void request() {
        auto spawn = std::make_shared<turtlesim::srv::Spawn::Request>();          
        spawn->name = "winter_turtle";
        spawn->x = 1.0;
        spawn->y = 1.0;
        spawn->theta = 1.57;
    
        while (!client_->wait_for_service(std::chrono::seconds(1))) {                                                   
            if (!rclcpp::ok()) {
                RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
                return;
            }
            RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
        }
    
        auto result = client_->async_send_request(spawn, std::bind(&ClientNode::OnResultCallBack, this, std::placeholders::_1));
    }
    

服务通信的效果如下所示:

在这里插入图片描述

3 服务模型实现(Python)

实验目标:客户端提交请求给turtlesim功能包的/spawn服务,在界面上生成新的乌龟。

  • 服务器

    本实验中无需编程,为turtlesim::Spawn定义的/spwan服务

  • 客户端

    class ClientNode(Node):
        def __init__(self, name):
            super().__init__(name)
            self.client = self.create_client(Spawn, '/spawn') 
    
            while not self.client.wait_for_service(timeout_sec=1.0):
                self.get_logger().info('service not available, waiting again...') 
            self.request = Spawn.Request()
                        
        def sendRequest(self):
            self.request.name = "winter_turtle"
            self.request.x = 1.0
            self.request.y = 1.0
            self.request.theta = 1.57
            self.future = self.client.call_async(self.request)
    

服务通信的效果如下所示:

在这里插入图片描述

4 自定义服务

自定义服务的通用流程如下:

  • 功能包下新建srv文件夹,在其中添加自定义服务xxx.srv,注意请求和响应数据结构使用---分割
  • 功能包package.xml中添加编译依赖与执行依赖
    <buildtool_depend>rosidl_default_generators</buildtool_depend>
    <exec_depend>rosidl_default_runtime</exec_depend>
    <member_of_group>rosidl_interface_packages</member_of_group>
    
  • 功能包CMakeLists.txt中添加编译消息相关依赖
    find_package(rosidl_default_generators REQUIRED)
    rosidl_generate_interfaces(${PROJECT_NAME}
    	"xxx.srv"
    	DEPENDENCIES xxx_srvs
    )
    
    ament_export_dependencies(rosidl_default_runtime)
    
  • 编译自定义消息,在install/<pkg_name>/include中生成由xxx.srv编译的C++可识别的xxx.hpp头文件
  • 引入xxx.hpp即可调用自定义服务

下面给出一个实例

添加如下自定义服务实现一个加法服务,并按上面步骤配置依赖

# client
int32 a
int32 b
---
# server
int32 sum

定义一个服务器、一个客户端,限于篇幅只贴出部分代码,完整代码见文末。

  • 服务器
    class ServerNode : public rclcpp::Node
    {
        public:
            ServerNode() : Node("lab_srv_server_own") {
                server_ = create_service<own_srv_lab::srv::Add>(
                    "/add_service",
                    std::bind(&ServerNode::OnAddSrvCallBack, this, std::placeholders::_1, std::placeholders::_2)
                ); 
            }
    
        private:
            rclcpp::Service<own_srv_lab::srv::Add>::SharedPtr server_;
    
            void OnAddSrvCallBack(
                const std::shared_ptr<own_srv_lab::srv::Add::Request> request, 
                std::shared_ptr<own_srv_lab::srv::Add::Response> response
            ) {
                response->sum = request->a + request->b;
                RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %d" " b: %d", request->a, request->b);
                RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%d]", response->sum);
            }
    };
    
  • 客户端
    ClientNode() : Node("lab_srv_client_own") {
        client_ = create_client<own_srv_lab::srv::Add>("/add_service"); 
    }
    
    void request(int a, int b) {
        auto add_srv = std::make_shared<own_srv_lab::srv::Add::Request>();
        add_srv->a = a;          
        add_srv->b = b;
    
        while (!client_->wait_for_service(std::chrono::seconds(1))) {                                                   
            if (!rclcpp::ok()) {
                RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
                return;
            }
            RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
        }
    
        auto result = client_->async_send_request(add_srv, std::bind(&ClientNode::OnResultCallBack, this, std::placeholders::_1));
    }
    

服务通信效果如下所示:

在这里插入图片描述

5 话题、服务通信的异同

对比话题服务
通信模式发布-订阅请求-响应
同步性异步同步
缓冲区
实时性
节点关系多对多一对多(1个server对应一个服务)
通信格式.msg.srv
使用场景连续高频的数据传输,例如激光雷达、里程计传输数据偶尔调用的功能,例如图像识别

完整代码通过下方博主名片联系获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux(CentOS7)配置系统服务以及开机自启动

目录 前言 两种方式 /etc/systemd/system/ 进入 /etc/systemd/system/ 文件夹 创建 nginx.service 文件 重新加载 systemd 配置文件 ​编辑 配置开机自启 /etc/init.d/ 进入 /etc/init.d/ 文件夹 创建 mysql 文件 编写脚本内容 添加/删除系统服务 配置开机自启 …

【官方推荐】华清远见Hi3861鸿蒙开发板助力全国大学生嵌入式芯片与系统设计竞赛(海思赛道)

为提高全国高校学生在嵌入式芯片及系统设计领域和可编程逻辑器件应用领域的自主创新设计与工程实践能力&#xff0c;培养具有创新思维、具备解决复杂工程问题能力且拥有团队合作精神的优秀人才&#xff0c;全国大学生嵌入式芯片与系统设计竞赛组织委员会举办第七届&#xff08;…

唐山一日游归来

这是学习笔记的第 2481篇文章 春天了&#xff0c;开始了躁动。去哪里玩呢&#xff1f;发现大模型是个很不错的选择&#xff0c;我哥在豆包上发了需求&#xff0c;然后自动生成了如下的旅行安排&#xff0c;说实话&#xff0c;这安排还是很细致的&#xff0c;可以把原本手工搜索…

如何在电脑上录屏?简单几步轻松搞定

随着信息技术的快速发展&#xff0c;电脑录屏已经成为一项必备技能。无论是录制游戏精彩时刻、制作教程、还是保存线上会议记录&#xff0c;录屏都可以帮助你更高效地完成任务。可是如何在电脑上录屏呢&#xff1f;本文将介绍两种在电脑上录屏的方法&#xff0c;这两种方法各有…

Redis超好用可视化工具--RedisInsight工具安装

RedisInsight 保姆级安装 RedisInsight 是Redis官方出品的可视化redis管理工具&#xff0c;具有很强大的功能。接下来&#xff0c;让我们一起去完成这款炫酷工具的安装 1. RedisInsight 下载 RedisInsight 官方下载地址&#xff0c;https://redis.io/docs/connect/insight/ …

Notepad++:格式化json字符串(带转义)

目录 一、效果呈现 二、去除json字符串转义 三、格式化json字符串 一、效果呈现 格式化前 带字符串转义&#xff0c;带unicode编码字符 格式化后 二、去除json字符串转义 方法&#xff1a;采用Notepad的普通替换 第一&#xff1a;\"替换为" 第二&#xff1a;\\…

大数据-TXT文本重复行计数工具

支持系统类型&#xff1a;Windows 64位系统 Linux 64位系统 苹果64位系统 硬盘要求&#xff1a;固态硬盘&#xff08;有效剩余磁盘空间大小最低3倍于大数据文件的大小&#xff09; 内存要求&#xff1a;最低8G&#xff08;例如只有几百G数据&#xff09; 如果处理TB级大数据文…

调用第三方服务组件改造+Jmeter5.x性能压测实践

调用第三方服务组件改造Jmeter5.x性能压测实践

【opencv】教程代码 —ShapeDescriptors

检测和显示图像的轮廓 在图像中搜索并显示轮廓边缘多边形、轮廓矩形和包围圆 获取包含检测到的轮廓的椭圆和旋转的矩形 图像轮廓检测和轮廓凸包 计算图像中的轮廓的矩&#xff08;包括面积、重心等&#xff09;并进行显示 创建和绘制一个多边形图像然后计算并显示图像上每个点到…

浮点数(小数)在计算机中如何用二进制存储?

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/137182814 出自【进步*于辰的博客】 注&#xff1a;为了阐述更加严谨&#xff0c;本篇文章中将使…

c语言例题,计算字符串长度,递归思想

c语言中&#xff0c;计算字符串长度算是一个比较经典的题了&#xff0c;而今天我们运用两种不同的求解方法来写出不同的程序来实现计算字符串的功能。 主函数 先看到主函数&#xff0c;主函数中设置了一串7个字符的字符串&#xff0c;而后面接下来定义了两个变量len1和len2&am…

【键值皆有序map 线段树 数学 】100240. 最小化曼哈顿距离

本文涉及知识点 键值皆有序map 线段树 数学 LeetCode100240. 最小化曼哈顿距离 给你一个下标从 0 开始的数组 points &#xff0c;它表示二维平面上一些点的整数坐标&#xff0c;其中 points[i] [xi, yi] 。 两点之间的距离定义为它们的曼哈顿距离。 请你恰好移除一个点&am…

【蓝桥杯第十三届省赛B】(部分详解)

九进制转十进制 #include <iostream> #include<math.h> using namespace std; int main() {cout << 2*pow(9,3)0*pow(9,2)2*pow(9,1)2*pow(9,0) << endl;return 0; }顺子日期 #include <iostream> using namespace std; int main() {// 请在此…

SOC内部集成网络MAC外设+ PHY网络芯片方案:MII/RMII 接口与 MDIO 接口

一. 简介 本文来了解一下常用的一种网络硬件方案&#xff1a;SOC内部集成网络MAC外设 PHY网络芯片方案。 其中涉及的 MII接口&#xff0c;RMII接口&#xff08;MII接口与RMII接口二选一&#xff09;&#xff0c;MDIO接口&#xff0c;RJ45。 二. MII/RMII 接口&#xff0c;M…

unity学习(74)——服务器Dispose异常

1.返回的1 2 11是怪物初始化&#xff0c;源代码中也没有 2. 3.客户端中的网络连接初始化如下&#xff1a; 4.不是因为超时&#xff0c;设置10s为超时期限后&#xff0c;客户端和服务器有时依然会报错&#xff01; 5.我感觉就是update中发包给弄坏的&#xff01; 6.不在“帧”…

【prometheus】k8s集群部署Grafana安装并接入Promethues数据源

目录 一、概述 1.1 优点 1.2 特点 二、grafana部署 三、grafana接入Promethues数据源 四、grafana可视化展示物理节点指标数据 五、grafana可视化展示k8s组件指标数据 5.1 kube-state-metrics简介 5.2 安装kube-state-metrics组件 一、概述 Grafana是一款用Go语言开发…

CodeTON Round 8 D. Learning to Paint 【DP求前k大】

D. Learning to Paint 题意 有一个 n n n 个格子长度的条带&#xff0c;格子从左到右编号为 1 → n 1 \rarr n 1→n&#xff0c;可以选择若干子段&#xff08;或不选&#xff09;的格子&#xff0c;给定一个二维数组 a a a 每选择一个 [ l i , r i ] [l_i,r_i] [li​,ri​…

5G无线接入网和接口协议

**部分笔记** 4.3无线协议架构 NR无线协议分为两个平面&#xff1a;用户面和控制面。 用户面&#xff08;UP&#xff09;:协议栈及用户数据采用的协议 控制面(Control Plane&#xff0c;CP)协议栈即系统的控制信令传输采用的协议簇。 虚线标注的是信令数据的流向。一个UE在…

[计算机效率] 文件加密工具:Lockdir

3.11 文件加密工具&#xff1a;Lockdir Lockdir是一款安全性高、使用简单、体积极小的便携式文件夹加密器&#xff0c;无需安装&#xff0c;一键加密&#xff0c;一键解密&#xff0c;加密算法高&#xff0c;是优秀的加密工具。其主要特点包括&#xff1a; 加密操作简易&#…

遥感动态监测技术

很多人对动态监测和动态检测两个名词有疑惑。我们可以这样理解&#xff0c;动态监测是一个广义的名词&#xff0c;泛指数据预处理、变化信息发现与提取、变化信息挖掘与应用等&#xff0c;以对整个流程的叙述。动态检测是一个狭义的名词&#xff0c;主要指部分数据预处理、变化…