关于ROS 2接口 [待校准@10102]
目录
1. 背景 [Alyssa@10103]
ROS应用程序通常通过三种类型之一的接口进行通信: 消息(messages)、服务(services)和动作(actions)。ROS 2使用简化的描述语言,即接口定义语言 (IDL) 来描述这些接口。这种描述使ROS工具可以轻松地以多种目标语言自动的生成接口类型的源文件。 [Alyssa@10104]
在本文档中,我们将描述ROS2支持的类型。 [Alyssa@10105]
msg(消息):
.msg
文件是描述ROS消息字段的简单文本文件。它们用于为不同语言的消息生成源文件代码。 [Alyssa@10106]srv(服务):
.srv
文件描述了一项服务。它们由两部分组成: 请求和响应。请求和响应是消息声明。 [Alyssa@10107]动作(action):
.action
文件描述动作。它们由三部分组成: 目标、结果和反馈。每个部分本身都是一个消息声明。 [Alyssa@10108]
2. 消息描述规范 [Alyssa@10109]
消息是在ROS包的 msg/
目录下的 .msg
文件中描述和定义的。 .msg
文件由两部分组成: 字段和常量。 [Alyssa@10110]
2.1 字段 [Alyssa@10111]
每个字段由一个类型和一个名称组成,用一个空格分隔,即:
fieldtype1 fieldname1
fieldtype2 fieldname2
fieldtype3 fieldname3
例如:
int32 my_int
string my_string
2.1.1 字段类型 [Alyssa@10114]
字段类型可以是:
内置类型
ROS2自己定义的消息描述的名称,如 "geometry_msgs/PoseStamped" [Alyssa@10117]
目前支持的内置类型: [Alyssa@10118]
类型名称 |
|||
---|---|---|---|
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 |
每个内置类型都可以用来定义数组: [Alyssa@10164]
类型名称 |
|||
---|---|---|---|
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约束 [待校准@10177]
使用数组和有界类型的消息定义示例: [Alyssa@10178]
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_string_up_to_ten_characters each
string<=10[<=5] up_to_five_strings_up_to_ten_characters_each
2.1.2 字段名称 [Alyssa@10179]
字段名必须是小写字母和数字字符,用下划线分隔单词。它们必须以字母字符开头,不能以下划线结尾,也不能有两个连续的下划线。 [Alyssa@10180]
2.1.3 字段默认值 [Alyssa@10181]
可以为消息类型中的任何字段设置默认值。目前,string数组和复杂类型(即上述内置类型表中不存在的类型,适用于所有嵌套消息)不支持设置默认值 [Alyssa@10182]
定义默认值是通过向字段定义行添加第三个元素来完成的,即: [待校准@10183]
fieldtype fieldname fielddefaultvalue
例如:
uint8 x 42
int16 y -2000
string full_name "John Doe"
int32[] samples [-200, -100, 0, 100, 200]
注意:
string值必须定义在单引号 ”' ”或双引号 “ "“中 [Alyssa@10185]
目前string值未转义 [待校准@10186]
2.2 常数 [Alyssa@10187]
每个常量定义都类似于具有默认值的字段描述,不同之处在于该值永远无法通过程序更改。该值通过使用等号 “=” 来赋值,例如 [Alyssa@10188]
constanttype CONSTANTNAME=constantvalue
例如:
int32 X=123
int32 Y=-123
string FOO="foo"
string EXAMPLE='bar'
注解
常量名称必须为大写 [待校准@10189]
3. 服务描述规范 [Alyssa@10190]
服务消息在ROS包的 srv/
目录下的 .srv
文件中描述和定义。 [Alyssa@10191]
服务描述文件由一个请求和一个响应msg类型组成,以“---”分隔。任何两个用“---” 连接的 .msg
文件都是合法的服务描述。 [Alyssa@10192]
这是一个非常简单的服务示例,该服务接受一个字符串(string)并返回一个字符串(string): [Alyssa@10193]
string str
---
string str
我们当然可以使服务消息变得更加复杂 (如果您想引用来自同一包的消息,您不能提及包名称): [Alyssa@10194]
#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
您不能在服务中嵌入其他服务。 [待校准@10195]
4. ROS 2接口的新功能 [Alyssa@10196]
ROS 2 IDL与 ROS 1 IDL 密切相关。大多数现有的ROS 1 .msg
和 .srv
文件在ROS 2上应该一样可用。在ROS 1现有的特征集上,ROS 2 IDL引入了一些新的特征,即: [Alyssa@10197]
有界数组: 鉴于ROS 1IDL允许无界数组 (例如,
int32[] foo
) 和固定大小数组 (例如,int32[5] bar
),ROS 2 IDL进一步允许有界数组 (例如,int32[<=5] bat
)。在某些用例中,重要的是能够在数组大小上设置上限,而不必总是使用太多空间 (例如,在实时系统中,您需要预分配将在执行期间使用的所有内存)。 [Alyssa@10198]有界字符串: 鉴于ROS 1IDL允许无界字符串 (例如,
string foo
),ROS 2 IDL进一步允许有界字符串 (例如,string<=5 bar
)。 [Alyssa@10199]默认值: 鉴于ROS 1IDL允许常量字段 (例如,
int32 X=123
),ROS 2 IDL进一步允许指定默认值 (例如,int32 X 123
)。在构造消息/服务对象时使用默认值,随后可以通过给字段赋值来覆盖默认值。您也可以为动作部分指定默认值。 [Alyssa@10200]