ROS 2基础概念#6:服务(Service)| ROS 2学习笔记

服务(Service)是 ROS 2 计算图中节点通信的另一种方法。 服务基于调用和响应模型,而不是主题的发布者-订阅者模型。 虽然主题允许节点订阅数据流并获取持续更新,但服务仅在客户端专门调用时才提供数据。

ROS 2服务的基本概念

ROS 2服务定义了一种一对一的通信模式。在这种模式下,一个节点可以作为服务服务器(Service Server),另一个节点可以作为服务客户端(Service Client)。服务客户端向服务服务器发起请求,并同步等待服务器的响应。

服务通信基于预先定义的服务类型进行,服务类型定义了请求和响应的结构。这些类型在ROS 2中通过.srv文件定义,类似于消息类型是通过.msg文件定义的。.srv文件的每一部分分别定义了请求和响应的数据结构。

服务的类型

ROS 2服务包含如下两种类型

  • 服务服务器(Service Server)
  • 服务客户端(Service Client)

在ROS 2中,服务指的是远程过程调用。 换句话说,一个节点可以对另一个节点进行远程过程调用,该节点将进行计算并返回结果。

此结构反映在服务消息定义的外观中:

uint32 request
---
uint32 response

在 ROS 2 中,服务预计会快速返回,因为客户端通常正在等待结果。 服务永远不应该用于运行时间较长的进程,特别是在特殊情况下可能需要抢占的进程。 如果您的服务将进行长时间运行的计算,请考虑改用动作(action)。

服务由服务名称标识,该名称看起来很像主题名称(但位于不同的命名空间中)。

一个服务由两部分组成:服务服务器和服务客户端。

服务服务器

服务服务器是接受远程过程请求并对其执行某些计算的实体。 例如,假设 ROS 2 消息包含以下内容:

uint32 a
uint32 b
---
uint32 sum

服务服务器将是接收此消息、将 a 和 b 加在一起并返回总和的实体。

注意:

每个服务名称只能有一个服务服务器。 当多个服务服务器具有相同的服务名称时,未定义哪个服务服务器将接收客户端请求。

服务客户端

服务客户端是请求远程服务服务器代表其执行计算的实体。 从上面的示例来看,服务客户端是创建包含 a 和 b 的初始消息的实体,并等待服务服务器计算总和并返回结果。

与服务服务器不同,可以有任意数量的服务客户端使用相同的服务名称。

服务(Service)描述规范

服务在 ROS 包的 srv/ 目录中的 .srv 文件中进行描述和定义。服务描述文件由请求和响应消息类型组成,以—分隔。 任何两个以 — 连接的 .msg 文件都是合法的服务说明。

下面一个非常简单的服务示例,它接收一个字符串并返回一个字符串:

string str
---
string str

当然,也可能变得更复杂(如果您想引用同一包中的消息,则不得提及包名称):

#request constants
int8 FOO=1
int8 BAR=2
#request fields
int8 foobar
another_pkg/AnotherMessage msg
---
#response constants
uint32 SECRET=123456
#response fields
another_pkg/YetAnotherMessage val
CustomMessageDefinedInThisPackage value
uint32 an_integer

你也可以把一个服务嵌套进另外一个服务中。

服务实例分析

假设我们正在开发一个机器人应用,在这个应用中,机器人需要从一个传感器服务中获取温度读数。我们可以定义一个GetTemperature.srv服务,其请求部分为空(不需要输入参数),响应部分包含一个浮点数表示的温度值。

定义.srv文件

# GetTemperature.srv
float64 temperature

服务服务器

服务服务器的回调函数接收到请求后,会从传感器获取温度读数,并将这个值作为响应返回给客户端。

include "rclcpp/rclcpp.hpp"
include "example_interfaces/srv/get_temperature.hpp"void handle_temperature_request(
const std::shared_ptr request,
std::shared_ptr response)
{
response->temperature = read_sensor_temperature(); // 假设这个函数从传感器读取温度
RCLCPP_INFO(rclcpp::get_logger("server"), "Sending back response: [%f]", response->temperature);
}int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("temperature_sensor_server");
auto server = node->create_service("get_temperature", handle_temperature_request);
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}

服务客户端

客户端发起请求时不需要提供任何数据,它只需要等待温度读数的响应。

#include "rclcpp/rclcpp.hpp"
#include "example_interfaces/srv/get_temperature.hpp"int main(int argc, char **argv)
{rclcpp::init(argc, argv);auto node = rclcpp::Node::make_shared("temperature_sensor_client");auto client = node->create_client<example_interfaces::srv::GetTemperature>("get_temperature");auto request = std::make_shared<example_interfaces::srv::GetTemperature::Request>();auto future = client->async_send_request(request);// 等待响应if (rclcpp::spin_until_future_complete(node, future)

ROS 2服务命令行工具

在使用如下的命令行工具前,先启动两个 turtlesim 节点: /turtlesim 和 /teleop_turtle

打开一个 Terminal 并运行:

ros2 run turtlesim turtlesim_node 

打开另外一个 Terminal 并运行:

ros2 run turtlesim turtle_teleop_key

列举所有的ROS 2服务

在新终端中运行如下命令将返回系统中当前活动的所有服务的列表:

ros2 service list

将得到类似如下的结果:

/clear
/kill
/reset
/spawn
/teleop_turtle/describe_parameters
/teleop_turtle/get_parameter_types
/teleop_turtle/get_parameters
/teleop_turtle/list_parameters
/teleop_turtle/set_parameters
/teleop_turtle/set_parameters_atomically
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically

您将看到两个节点都有相同的六个服务,其名称中包含参数。 ROS 2 中的几乎每个节点都有这些参数构建的基础设施服务。现在,让我们关注turtlesim特定的服务:/clear, /kill, /reset, /spawn, /turtle1/set_pen, /turtle1/teleport_absolute和/turtle1/teleport_relative。

查看服务类型

服务具有描述服务的请求和响应数据的结构的类型。 服务类型的定义与主题类型类似,不同之处在于服务类型有两部分:一个用于请求的消息,另一个用于响应。

要找出服务的类型,请使用以下命令:

ros2 service type <service_name>

我们来看看turtlesim的/clear服务。 在新终端中输入命令:

ros2 service type /clear

将看到如下的结果:

std_srvs/srv/Empty

Empty 类型表示服务调用在发出请求时不发送任何数据,在接收响应时不接收任何数据。

查看所有服务类型

要同时查看所有活动服务的类型,您可以将 –show-types 选项(缩写为 -t)附加到 list 命令:

ros2 service list -t

将看到如下的结果:

/clear [std_srvs/srv/Empty]
/kill [turtlesim/srv/Kill]
/reset [std_srvs/srv/Empty]
/spawn [turtlesim/srv/Spawn]
...
/turtle1/set_pen [turtlesim/srv/SetPen]
/turtle1/teleport_absolute [turtlesim/srv/TeleportAbsolute]
/turtle1/teleport_relative [turtlesim/srv/TeleportRelative]
...

寻找服务

如果要查找特定类型的所有服务,可以使用以下命令:

ros2 service find <type_name>

例如,您可以像这样找到所有 Empty 类型服务:

ros2 service find std_srvs/srv/Empty

将看到如下的结果:

/clear
/reset

查看服务接口参数

您可以从命令行调用服务,但首先您需要了解输入参数的结构。

ros2 interface show <type_name>.srv

在 /clear 服务的 Empty 类型上尝试此操作:

ros2 interface show std_srvs/srv/Empty.srv

将看到如下的结果:

---

— 将请求结构与响应结构分开。 但是空类型不会发送或接收任何数据。 所以它的结构是空白的。

让我们检查一下具有发送和接收数据类型的服务,例如 /spawn。 从 ros2 service list -t 的结果我们知道/spawn的类型是turtlesim/srv/Spawn。

要查看 /spawn 服务的请求和响应参数,请运行以下命令:

ros2 interface show turtlesim/srv/Spawn

将得到如下返回结果:

float32 x
float32 y
float32 theta
string name # Optional.  A unique name will be created and returned if this is empty
---
string name

— 行上方的信息告诉我们调用 /spawn 所需的参数。 x、y 和 theta 确定生成的Turtle的 2D 姿势,并且名称显然是可选的。

在这种情况下,您不需要了解该行下方的信息,但它可以帮助您了解从调用中获得的响应的数据类型。

调用ROS 2服务

现在您已经知道什么是服务类型、如何查找服务类型以及如何查找该类型参数的结构,您可以使用以下方式调用服务:

ros2 service call <service_name> <service_type> <arguments>

部分是可选的。 例如,空类型服务没有任何参数:

ros2 service call /clear std_srvs/srv/Empty

此命令将清除turtlesim 窗口中海龟绘制的任何线条。

现在我们通过调用 /spawn 并设置参数来生成新的 turtle。 从命令行进行的服务调用中的输入需要采用 YAML 语法。

ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"

您将获得正在发生的情况的方法风格视图,然后是服务响应:

requester: making request: turtlesim.srv.Spawn_Request(x=2.0, y=2.0, theta=0.2, name='')response:
turtlesim.srv.Spawn_Response(name='turtle2')

你的turtlesim窗口将立即更新为新生成的 turtle:

总结

节点可以使用 ROS 2 中的服务进行通信。与主题(一种单向通信模式,其中节点发布可供一个或多个订阅者使用的信息)不同,服务是一种请求/响应模式,其中客户端向节点发出请求 提供服务,服务处理请求并生成响应。

一般不要在服务中使用连续通话的服务;这种情况下使用主题(topic)或者动作(action)会更合适。

作者ROS 2学习笔记系列文章:ROS 2学习笔记 归档 - HY's Blog

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

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

相关文章

UE4升级UE5 蓝图节点变更汇总(4.26/27-5.2/5.3)

一、删除部分 Ploygon Editing删除 Polygon Editing这个在4.26、4.27中的插件&#xff0c;在5.1后彻底失效。 相关的蓝图&#xff0c;如编辑器蓝图 Generate mapping UVs等&#xff0c;均失效。 如需相关功能&#xff0c;请改成Dynamic Mesh下的方法。 GetSupportedClass删…

微服务超大Excel文件导出方案优化

1、在导出Excel时经常会碰到文件过大&#xff0c;导出特别慢 2、微服务限制了请求超时时间&#xff0c;文件过大情况必然超时 优化思路&#xff1a; 1、文件过大时通过文件拆分、打包压缩zip&#xff0c;然后上传到oss,并设置有效期&#xff08;30天过期&#xff09; 2、把…

便捷在线导入:完整Axure元件库集合,让你的设计更高效!

Axure元件库包含基本的工具组件&#xff0c;可以使原型绘制节省大量的重复工作&#xff0c;保持整个设计页面的一致性和标准化&#xff0c;同时显得专业。Axure元件库就像我们日常生活中的门把手、自行车踏板和桌子上的螺丝钉&#xff0c;需要组装才能使用。作为一名成熟的产品…

搜索引擎都没流量啦,官网建设还有啥意义?

百度等搜索引擎都没啥流量了&#xff0c;再建设官网还有啥用&#xff1f;如果你把官网定位于获客&#xff0c;那真的没啥太大用处&#xff0c;但是官网不仅仅是用来获客的。 一、搜索引擎的流量被稀释了 搜索引擎流量减少的原因有多个&#xff0c; 1. 社交媒体的崛起&#xf…

数据库原理实验课(1)

目录 实验内容 安装头歌中的相关内容 具体过程 完结撒花~ 我也是第一次接触oracle的相关软件和操作&#xff0c;所以是一次傻瓜式教学记录 实验内容 安装头歌中的相关内容 具体过程 这是我在百度网盘中下载解压出来的oracle文件夹内的全部内容&#xff08;可能有因为安装完…

可编程线性霍尔传感器 IC

一、产品概述 CC6521/2 是一款高性能的可编程线性霍尔传感器 IC&#xff0c;采用先进的 BiCMOS 制程生产&#xff0c;具有霍尔系数高的优点&#xff0c;芯片内部包含了高灵敏度 霍尔传感器&#xff0c;霍尔信号预放大器&#xff0c;高精度的霍尔温度补偿单元&#xff0c;振荡…

EOCR电动机保护器在冶金行业的应用具有显著的意义和优势

冶金行业是一个对电动机保护和控制设备需求非常迫切的行业&#xff0c;因为电动机是拖动机械的基础&#xff0c;广泛应用于各种动力机械中。 冶金厂中的电动机需要承受高温、高湿、高粉尘等恶劣环境&#xff0c;同时还需要应对频繁的启动和停止&#xff0c;以及电压不稳定等问…

Java中的优先队列PriorityQueue如何排序

目录 一、基本数据类型的排序 &#xff08;1&#xff09;升序 &#xff08;2&#xff09;降序 二、自定义类型如何排序 &#xff08;1&#xff09;升序 &#xff08;2&#xff09;降序 既然大家想要了解优先队列的排序&#xff0c;那么说明已经知道什么事优先队列了&…

HNU-算法设计与分析-甘晴void学习感悟

前言 算法设计与分析&#xff0c;仅就课程而言&#xff0c;似乎是数据结构与算法分析的延续 教材使用&#xff1a; 课程 关于课程&#xff0c;橙学长讲的非常清晰&#xff0c;我深以为然。 HNUCS-大三课程概览-CSDN博客文章浏览阅读1.3k次&#xff0c;点赞5次&#xff0c;收…

CMake笔记

CMake笔记 文章目录 CMake笔记1 工程项目一般形式2 常见命令2.1 project2.2 set2.3 message2.4 add_executable()2.5 语法原则2.6 add_subdirectory2.7 add_library2.8 list 3 安装3.1 安装.h文件/文本文件3.2 安装工程脚本3.3 安装目录/目录下内容3.4 安装库文件3.5安装过程 4…

探索数据结构:单链表的实战指南

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty‘s blog 前言 在上一章节中我们讲解了数据结构中的顺序表&#xff0c;知道了顺序…

【工具】Raycast – Mac提效工具

引入 以前看到同事们锁屏的时候&#xff0c;不知按了什么键&#xff0c;直接调出这个框&#xff0c;然后输入lock屏幕就锁了。 跟我习惯的按Mac开机键不大一样。个人觉得还是蛮炫酷的&#xff5e; 调研 但是由于之前比较繁忙&#xff0c;这件事其实都忘的差不多了&#xff0…