ROS专题 · 2024年2月28日 0

ROS 2基础概念#4:消息(Message)| ROS 2学习笔记

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 nameC++PythonDDS type
boolboolbuiltins.boolboolean
byteuint8_tbuiltins.bytes*octet
charcharbuiltins.str*char
float32floatbuiltins.float*float
float64doublebuiltins.float*double
int8int8_tbuiltins.int*octet
uint8uint8_tbuiltins.int*octet
int16int16_tbuiltins.int*short
uint16uint16_tbuiltins.int*unsigned short
int32int32_tbuiltins.int*long
uint32uint32_tbuiltins.int*unsigned long
int64int64_tbuiltins.int*long long
uint64uint64_tbuiltins.int*unsigned long long
stringstd::stringbuiltins.strstring
wstringstd::u16stringbuiltins.strwstring

所有的内置支持类型都能用于定义数组(array):

Type nameC++PythonDDS type
static arraystd::array<T, N>builtins.list*T[N]
unbounded dynamic arraystd::vectorbuiltins.listsequence
bounded dynamic arraycustom_class<T, N>builtins.list*sequence<T, N>
bounded stringstd::stringbuiltins.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