【ROS2】Concept(Basic)
基本概念
ROS 2 是一种基于强类型、匿名发布/订阅机制的中间件,能够实现不同进程间的消息传递。
任何 ROS 2 系统的核心都在于 ROS graph。ROS graph 指的是 ROS 系统中的节点网络,以及节点之间用于通信的连接。
以下这些概念将助力你初步理解 ROS 2 的基础知识。
一、Nodes(节点)
节点是 ROS 2 graph 中的参与者,它通过 client library 与其他节点通信。节点可以与同一进程、不同进程或不同机器上的其他节点进行通信。节点通常是 ROS graph 中的计算单元;每个节点应负责一项逻辑功能。
节点可以向命名的 topics 发布消息,以向其他节点传递数据,或者订阅命名的 topics,以从其他节点获取数据。它们还可以作为 service client,让其他节点代为执行计算,或者作为 service server,为其他节点提供功能。对于长时间运行的计算,节点可以作为 action client,让其他节点代为执行,或者作为 action server,为其他节点提供功能。节点可以提供可配置的 parameters,以在运行时改变行为。
节点通常是发布者、订阅者、service server、service client、action server 和 action client 的复杂组合。
节点之间的连接通过分布式发现过程建立。
二、Discovery(发现)
节点的发现通过 ROS 2 的底层中间件自动完成。其过程可总结如下:
-
当节点启动时,会向同一 ROS 域(由 ROS_DOMAIN_ID 环境变量设置)网络中的其他节点宣告自身存在。其他节点会对这一宣告做出回应,提供自身信息,以便建立适当的连接,实现节点间的通信。
-
节点会定期宣告自身存在,这样即使在初始发现阶段之后,也能与新发现的实体建立连接。
-
节点离线时会向其他节点宣告。
只有当节点具有兼容的 Quality of Service 设置时,它们才会建立连接。
以 talker-listener 演示为例:在一个终端中运行 C++ talker 节点,它会在某个 topic 上发布消息,而在另一个终端中运行的 Python listener 节点会订阅同一 topic 上的消息。你会看到这些节点会自动发现彼此,并开始交换消息。
三、Interfaces(接口)
1. 背景
ROS 应用通常通过三种类型的接口进行通信:topics(话题)、services(服务)或 actions(动作)。ROS 2 使用一种简化的描述语言,即接口定义语言(IDL)来描述这些接口。这种描述便于 ROS 工具自动为多种目标语言生成接口类型的源代码。
本文档将介绍以下支持的类型:
- msg:.msg 文件是用于描述 ROS 消息字段的简单文本文件。它们用于为不同语言生成消息的源代码。
- srv:.srv 文件用于描述服务。它们由两部分组成:请求(request)和响应(response)。请求和响应都是消息声明。
- action:.action 文件用于描述动作。它们由三部分组成:目标(goal)、结果(result)和反馈(feedback)。每一部分本身都是一个消息声明。
2. Messages
消息是 ROS 2 节点在网络上向其他 ROS 节点发送数据的一种方式,不期望收到响应。例如,如果一个 ROS 2 节点从传感器读取温度数据,它可以使用 Temperature 消息在 ROS 2 网络上发布该数据。ROS 2 网络上的其他节点可以订阅该数据并接收 Temperature 消息。
消息在 ROS 包的 msg/ 目录下的 .msg 文件中进行描述和定义。.msg 文件由字段(fields)和常量(constants)两部分组成。
Fileds
int32 my_int
string my_string
(1)Field types
字段类型可以是:
- 内置类型
- 自行定义的消息描述名称,如 “geometry_msgs/PoseStamped”
目前支持的内置类型:
每个内置类型都可以用来定义数组:
所有比其 ROS 定义更宽松的类型都会通过软件来强制实施 ROS 在范围和长度方面的约束。
使用数组和有界类型的消息定义示例:
(2)Field names
字段名称必须是小写字母数字字符,单词之间用下划线分隔。名称必须以字母开头,且不能以下划线结尾或包含两个连续的下划线。
(3)Field default value
默认值可以设置为消息类型中的任何字段。目前不支持字符串数组和复杂类型(即上文内置类型表中未列出的类型;这适用于所有嵌套消息)。
定义默认值是通过向字段定义行添加第三个元素来完成的,即:
Constants
每个常量定义就像一个带有默认值的字段描述,只不过这个值永远无法通过编程更改。这种赋值方式用等号“=”表示,例如
常量名称必须大写