接口

背景

ROS 应用程序通常通过以下三种类型的接口进行通信: topics, services, or actions. ROS 2 使用一种简化的描述语言,即接口定义语言 (IDL) 来描述这些接口。 此描述使 ROS 工具可以轻松地自动生成多种目标语言的接口类型源代码。

在本文档中,我们将描述支持的类型:

  • msg:“.msg”文件是描述 ROS 消息字段的简单文本文件。它们用于生成不同语言的消息源代码。

  • srv:“.srv”文件描述服务。它们由两部分组成:请求和响应。请求和响应是消息声明。

  • action:“.action”文件描述操作。它们由三部分组成:目标、结果和反馈。

每个部分本身都是一个消息声明。

消息

消息是 ROS 2 节点通过网络向其他 ROS 节点发送数据的一种方式,无需响应。 例如,如果 ROS 2 节点从传感器读取温度数据,则它可以使用“温度”消息在 ROS 2 网络上发布该数据。 ROS 2 网络上的其他节点可以订阅该数据并接收“温度”消息。

消息在 ROS 包的“msg/”目录中的“.msg”文件中描述和定义。 “.msg”文件由两部分组成:字段和常量。

字段

每个字段由一个类型和一个名称组成,以空格分隔,即:

fieldtype1 fieldname1
fieldtype2 fieldname2
fieldtype3 fieldname3

例如:

int32 my_int
string my_string

字段类型

字段类型可以是:

  • 内置类型

  • 自行定义的消息描述名称,例如“geometry_msgs/PoseStamped”

当前支持的内置类型:

Type name

C++

Python

DDS type

bool

bool

builtins.bool

boolean

byte

uint8_t

builtins.bytes*

octet

char

char

builtins.int*

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

每个内置类型都可以用来定义数组:

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 在范围和长度方面的限制。

使用数组和有界类型的消息定义示例:

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

字段名称

字段名称必须是小写字母数字字符,并用下划线分隔单词。 它们必须以字母开头,并且不能以下划线结尾或有两个连续的下划线。

字段默认值

默认值可以设置为消息类型中的任何字段。 目前,字符串数组和复杂类型(即上述内置类型表中不存在的类型;适用于所有嵌套消息)不支持默认值。

定义默认值是通过向字段定义行添加第三个元素来完成的,即:

fieldtype fieldname fielddefaultvalue

例如:

uint8 x 42
int16 y -2000
string full_name "John Doe"
int32[] samples [-200, -100, 0, 100, 200]

Note

  • string values must be defined in single ' or double " quotes

  • currently string values are not escaped

常量

每个常量定义都类似于具有默认值的字段描述,但该值永远无法通过编程更改。 此值分配通过使用等号“=”来表示,例如

constanttype CONSTANTNAME=constantvalue

例如:

int32 X=123
int32 Y=-123
string FOO="foo"
string EXAMPLE='bar'

Note

Constants names have to be UPPERCASE

服务

服务是一种请求/响应通信,其中客户端(请求者)等待服务器(响应者)进行简短计算并返回结果。

服务在 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

您不能将另一个服务嵌入到服务中。

操作

操作是一种长时间运行的请求/响应通信,其中操作客户端(请求者)正在等待操作服务器(响应者)采取某些操作并返回结果。 与服务相比,操作可以长时间运行(数秒或数分钟),在发生时提供反馈,并且可以中断。

操作定义具有以下形式:

<request_type> <request_fieldname>
---
<response_type> <response_fieldname>
---
<feedback_type> <feedback_fieldname>

与服务一样,请求字段位于第一个三连字符(“—”)之前,而响应字段位于其之后。

在第二个三连字符之后还有第三组字段,这是发送反馈时要发送的字段。

请求字段数量可以是任意数量(包括零个)、响应字段数量可以是任意数量(包括零个),反馈字段数量也可以是任意数量(包括零个)。

<request_type><response_type><feedback_type> 遵循与消息的 <type> 相同的所有规则。 <request_fieldname><response_fieldname><feedback_fieldname> 遵循与消息的 <fieldname> 相同的所有规则。

例如,“Fibonacci”操作定义包含以下内容:

int32 order
---
int32[] sequence
---
int32[] sequence

这是一个动作定义,其中动作客户端发送一个“int32”字段,表示要采取的斐波那契步骤数,并期望动作服务器生成一个包含完整步骤的“int32”数组。 在此过程中,动作服务器还可以提供一个中间“int32”数组,其中包含在某个点之前完成的步骤。