ROS 2消息简介
ROS程序使用三种不同的接口来进行沟通:消息(message),服务(service)和动作(action)。ROS 2使用一种简化的描述语言:IDL(interface definition language)来描述这届接口。这种描述使得ROS工具自动生成不同编程语言的接口类型源代码变得更加简单。
这三种接口类型简介如下。本文主要介绍有关消息的接口。
- msg:
.msg
文件是描述ROS消息定义的简单文本文件。它们被用于生成关于消息定义的不同编程语言的源代码。 - srv:
.srv
文件描述服务(service)。它们包含两个部分:请求(request)和返回(response)。请求和返回都是消息声明(declaration)。 - action:
.action
文件描述动作(action). 它们包含三个部分:目标(goal),结果(result)和反馈(feedback)。每个部分都是一个消息声明。
消息描述规范
消息在ROS软件包的msg/目录下的.msg文件里定义。.msg文件包含两部分内容:fields和constants。
Fields
每个field都包含类型和名称的定义。类型和名称之间用空格分开:
fieldtype1 fieldname1
fieldtype2 fieldname2
fieldtype3 fieldname3
例如:
int32 my_int
string my_string
Field类型
Field 可以是:
- ROS 2内置支持的类型 (built-in-types)
- 开发者自定义的消息名称和类型,例如 “geometry_msgs/PoseStamped”
目前内置支持的类型:
Type name | C++ | Python | DDS type |
---|---|---|---|
bool | bool | builtins.bool | boolean |
byte | uint8_t | builtins.bytes* | octet |
char | char | builtins.str* | char |
float32 | float | builtins.float* | float |
float64 | double | builtins.float* | double |
int8 | int8_t | builtins.int* | octet |
uint8 | uint8_t | builtins.int* | octet |
int16 | int16_t | builtins.int* | short |
uint16 | uint16_t | builtins.int* | unsigned short |
int32 | int32_t | builtins.int* | long |
uint32 | uint32_t | builtins.int* | unsigned long |
int64 | int64_t | builtins.int* | long long |
uint64 | uint64_t | builtins.int* | unsigned long long |
string | std::string | builtins.str | string |
wstring | std::u16string | builtins.str | wstring |
所有的内置支持类型都能用于定义数组(array):
Type name | C++ | Python | DDS type |
---|---|---|---|
static array | std::array<T, N> | builtins.list* | T[N] |
unbounded dynamic array | std::vector | builtins.list | sequence |
bounded dynamic array | custom_class<T, N> | builtins.list* | sequence<T, N> |
bounded string | std::string | builtins.str* | string |
所有比 ROS 定义更宽松的类型都通过软件强制执行 ROS 范围和长度约束。
使用数组(array)和有界(bounded)类型的消息定义示例:
int32[] unbounded_integer_array
int32[5] five_integers_array
int32[<=5] up_to_five_integers_array
string string_of_unbounded_size
string<=10 up_to_ten_characters_string
string[<=5] up_to_five_unbounded_strings
string<=10[] unbounded_array_of_strings_up_to_ten_characters_each
string<=10[<=5] up_to_five_strings_up_to_ten_characters_each
Field名称
Field名称必须是小写字母数字字符,并用下划线分隔单词。 它们必须以字母字符开头,并且不能以下划线结尾或有两个连续的下划线。
Field缺省值
缺省值可以设置为消息类型中的任何字段。 目前,字符串数组和复杂类型不支持缺省值(即上面的内置类型表中不存在的类型;这适用于所有嵌套消息)。
通过向字段定义行添加第三个元素来定义缺省值,即:
fieldtype fieldname fielddefaultvalue
例如:
uint8 x 42
int16 y -2000
string full_name "John Doe"
int32[] samples [-200, -100, 0, 100, 200]
注意:
- 字符串值必须用单引号或双引号定义
- 当前字符串值未转义
常量
每个常量定义就像一个具有默认值的字段描述,只不过该值永远不能以编程方式更改。 该值分配通过使用等号“=”来指示,即:
constanttype CONSTANTNAME=constantvalue
例如:
int32 X=123
int32 Y=-123
string FOO="foo"
string EXAMPLE='bar'
注意:
常量名必须大写!
ROS 2消息接口的新功能
ROS 2 IDL 与 ROS 1 IDL 密切相关。 大多数现有的 ROS 1 .msg 和 .srv 文件应该可以按原样与 ROS 2 一起使用。在 ROS 1 的现有功能集之上,ROS 2 IDL 引入了一些新功能,即:
- 有界数组(bounded arrays): ROS 1 IDL 允许无界数组(例如 int32[] foo)和固定大小数组(例如 int32[5] bar),而 ROS 2 IDL 进一步允许有界数组(例如 int32[<=5] bat) 。 在某些用例中,能够为数组的大小设置上限,而不必承诺始终使用那么多空间(例如,在实时系统中,您需要预先分配将要使用的所有内存),这一点在执行期间使用很重要)。
- 有界字符串(bounded strings): ROS 1 IDL 允许无界字符串(例如 string foo),而 ROS 2 IDL 进一步允许有界字符串(例如 string<=5 bar)。
- 缺省值(default values): ROS 1 IDL 允许常量字段(例如 int32 X=123),而 ROS 2 IDL 还允许指定默认值(例如 int32 X 123)。 默认值在构造消息/服务对象时使用,随后可以通过分配给字段来覆盖。 您还可以指定操作部分的默认值。
ROS 2消息的命令行工具
列出系统中所有可用消息类型
ros2 msg list
这个命令会显示系统中所有已知的消息类型,包括标准消息和任何已安装的自定义消息。输出示例:
std_msgs/msg/String
geometry_msgs/msg/Twist
sensor_msgs/msg/LaserScan
…
这里,输出包含了多个消息类型,如std_msgs/msg/String
,这是一个标准的字符串消息类型。
显示特定消息类型的详细信息
ros2 msg show std_msgs/msg/String
使用这个命令可以查看特定消息类型的结构,包括它的字段和每个字段的类型。这对于理解和使用消息非常有帮助。
string data
这表明std_msgs/msg/String
消息只有一个名为data
的字段,其类型为string
。
总结
ROS 2消息为ROS 2系统提供了一种统一的数据传输机制,使得不同节点之间能够进行高效的通信。通过消息,开发者可以定义和传递各种类型的数据,并且能够在节点之间实现灵活、可靠的数据交换。消息的使用能够提高ROS 2系统的模块化程度、可扩展性和可维护性,使其更适用于各种不同的机器人和自动化应用场景。
作者ROS 2学习笔记系列文章:ROS 2学习笔记 归档 - HY's Blog