Edit on Github

About ROS 2 Interfaces

1. Background

ROS applications typically communicate through interfaces of one of two types: messages and services. ROS uses a simplified description language to describe these interfaces. This description makes it easy for ROS tools to automatically generate source code for the interface type in several target languages.

In this document we will describe the supported types and how to create your own msg/srv files.

2. Message Description Specification

Messages description are defined in .msg files in the msg/ directory of a ROS package. .msg files are composed of two parts: fields and constants.

2.1 Fields

Each field consists of a type and a name, separated by a space, i.e:

fieldtype1 fieldname1
fieldtype2 fieldname2
fieldtype3 fieldname3

For example:

int32 my_int
string my_string

2.1.1 Field Types

Field types can be:

  • a built-in-type

  • names of Message descriptions defined on their own, such as “geometry_msgs/PoseStamped”

Built-in-types currently supported:

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

Every built-in-type can be used to define arrays:

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

All types that are more permissive than their ROS definition enforce the ROS constraints in range and length by software

Example of message definition using arrays and bounded types:

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 Field Names

Field names must be lowercase alphanumeric characters with underscores for separating words. They must start with an alphabetic character, they must not end with an underscore and never have two consecutive underscores.

2.1.3 Field Default Value

Default values can be set to any field in the message type. Currently default values are not supported for string arrays and complex types (i.e. types not present in the built-in-types table above, that applies to all nested messages)

Defining a default value is done by adding a third element to the field definition line, i.e:

fieldtype fieldname fielddefaultvalue

For example:

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

2.2 Constants

Each constant definition is like a field description with a default value, except that this value can never be changed programatically. This value assignment is indicated by use of an equal ‘=’ sign, e.g.

constanttype CONSTANTNAME=constantvalue

For example:

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

Note

Constants names have to be UPPERCASE

3. Service Description Specification

Services description are defined in .srv files in the srv/ directory of a ROS package.

A service description file consists of a request and a response msg type, separated by ‘—’. Any two .msg files concatenated together with a ‘—’ are a legal service description.

Here is a very simple example of a service that takes in a string and returns a string:

string str
---
string str

We can of course get much more complicated (if you want to refer to a message from the same package you must not mention the package name):

#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

You cannot embed another service inside of a service.