這是我對ROS官方ROS2教程的翻譯,純個人理解,對於文中的關鍵詞彙或不確定的語句標註了原文,如有錯誤或翻譯問題還請指出。
原文:https://index.ros.org/doc/ros2/Concepts/About-ROS-Interfaces/
日期:2019年1月20日
關於ROS2 接口
1. 背景
ROS應用通過兩種類型的接口來實現通信:消息和服務。ROS使用一種簡單的描述性語言來描述這些接口,通過描述性語言可以很容易的讓ROS工具來自動地生成不同目標語言的接口類型的源碼。
這篇文檔我們將會去說明ROS2支持的接口類型以及如何去創建自己的消息、服務文件。
2. 消息描述說明
消息描述在.msg
文件中定義,.msg
文件位於ROS包中的msg/
路徑下。.msg
文件由兩部分組成:域(fields)和常量(constants)。
2.1 域
每個域包括一個類型和一個名稱,用一個空格分開,格式爲:
fieldtype1 fieldname1
fieldtype2 fieldname2
fieldtype3 fieldname3
例如:
int32 my_int
string my_string
2.1.1 域類型
域類型可以是:
- 一個內建類型
- 自定義的消息描述名稱,如“geometory_msgs/PoseStamped”
內建類型現在支持情況如下:
類型名 | C++ | Python | DDS類型 |
---|---|---|---|
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 |
每一個內建類型都可以用於定義數組:
類型名 | C++ | Python | DDS類型 |
---|---|---|---|
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約束。(All types that are more permissive than their ROS definition enforce the ROS constraints in range and length by software)
一個使用數組和有邊界類型的例子如下:
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 域名
域名必須是由小寫的字母或數字的字符以及下劃線組成。必須以字母字符開頭,不能以下劃線結尾,而且不能有連續的兩個下劃線。
2.1.3 域默認值
消息類型中,默認值可以在任何域中設置。當前的默認值不支持string數組以及複雜的類型(比如不屬於上邊表中指定的內建類型,可以應用於所有嵌套消息(that applies to all nested messages))
通過在域定義行中增加第三個元素項來定義一個默認消息,格式爲:
fieldtype fieldname fielddefaultvalue
比如:
uint8 x 42
int16 y -2000
string full_name "John Doe"
int32[] samples [-200, -100, 0, 100, 200]
注:
- string類型的默認值必須由
'
或"
包含 - 當前string值不會被轉義
2.2 常量
常量的定義就像是帶默認值的域描述,區別在於它的值不會被程序改變。這個值通過等號=
來賦給常量,格式爲:
constanttype CONSTANTNAME=constantvalue
比如:
int32 X=123
int32 Y=-123
string FOO="foo"
string EXAMPLE='bar'
注:
- 常量名稱必須是大寫的
3. 服務描述說明
服務描述在.srv
文件中定義,.srv
文件在ROS包中的srv/
路徑下。
一個服務描述文件包含了請求和響應的消息類型,由---
分隔。任何兩個.msg
文件都可以由---
連接起來而形成合法的服務描述文件。
一個最簡單的服務例子如下,它獲得一個string消息,返回一個string消息:
string str
---
string str
我們當然可以讓服務描述更復雜(如果你需要引用一個相同包裏的消息,則不應當提及包名),例如:
#請求常量
int8 FOO=1
int8 BAR=2
#請求域
int8 foobar
another_pkg/AnotherMessage msg
---
#響應常量
uint32 SECRET=123456
#響應域
another_pkg/YetAnotherMessage val
CustomMessageDefinedInThisPackage value
uint32 an_integer
不可以在一個服務中嵌入其他的服務。