This article specifies the file format coming from ROS 1 describing the data structures exchanged by ROS components to interact with each other.
Authors: Dirk Thomas
Date Written: 2019-03
Last Modified: 2021-02
This article specifies the file format coming from ROS 1 describing the data structures which are being used to exchange information between components.
The data structures are defined in a programming language agnostic way.
The format is based on the .msg
format definition from ROS 1.
Below only the mapping to IDL types is described. Please see the Interface Definition and Language Mapping article for the mappings to programming language specific types and API.
A data structure is defined by a set of fields. The order of the fields is irrelevant. Each field is described by a type and a name.
A single data structure is called message. Each message has a name. Together with the name of the package a message can be uniquely identified.
For request / reply style communication the two exchanged data structures are related. These pairs of data structures are called services. A service is identified by its name and the package it is in. Each service describes two messages, one for the request data structure, one for the reply data structure.
For longer running request / reply style communication with feedback about the progress the exchanged data structures are related. These triplets of data structures are called actions. An action is identified by its name and the package it is in. Each action describes three messages, one for the goal data structure, one for the result data structure, and one for the feedback data structure.
The type of a field can be either a primitive type or another data structure. Each of these can optionally be a dynamically or statically sized array.
The following primitive types are defined:
bool
byte
char
float32
, float64
int8
, uint8
int16
, uint16
int32
, uint32
int64
, uint64
string
While byte
and char
are deprecated in ROS 1 they are still part of this definition to ease migration.
In ROS 1 string
does not specify any encoding and the transport is agnostic to it.
This means commonly it can only contain ASCII.
For explicit support of wide character strings please consider migrating to .idl files which defines explicit types for that.
Beside the primitive types other messages can be referenced to describe the type of a “complex” field. A complex field type is identified by a package and a message name.
A static array has exactly N
elements of the specified type.
N
must be greater than 0
.
A dynamic array can have between 0
and N
elements of the specified type.
N
might not have an upper bound and may only be limited by the memory or other system specific limitations.
This feature is not available in ROS 1.
The size of strings as well as dynamic arrays can be limited with an upper boundary. This enables the preallocation of memory for data structures which use dynamically sized data.
This feature is not available in ROS 1.
A field can optionally specify a default value. If no default value is specified a common default value is used:
bool
it is false
0
valuestring
it is an empty string[]
A field of type array
can optionally specify a default value.
[
) and end with a closing square bracket (]
),
),
before the first value of the arrayAdditional rule for string
arrays:
string
s respecting the following rules:
'
) or double quotes ("
)"
) string (respectively single-quoted ('
)) should have any inner double quotes (respectively single quotes) escapedTODO: default values are currently not supported for complex fields
Constants are defined by a primitive type, a name, and a fixed value. If the primitive type is an integer type, the fixed value can be specified in one of the following ways:
Each file contains a single message or service.
Message files use the extension .msg
, service files use the extension .srv
.
Both file names must use an upper camel case name and only consist of alphanumeric characters.
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.
Constant names must be uppercase 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.
The message and service definitions are text files.
The character #
starts a comment, which terminates at the end of the line on which it occurs.
A line can either contain a field definition or a constant definition. While a single space is mandatory to separate tokens additional spaces can be inserted optionally between tokens.
A field definition has the following structure:
<type> <name> <optional_default_value>
A constant definition has the following structure:
<type> <name>=<value>
A <type>
is defined by its base type and optional array specifier.
The base type can be one of the following:
a primitive type from the list above: e.g. int32
a string with an upper boundary: string<=N
to limit the length of the string to N
characters
a complex type referencing another message:
some_package/SomeMessage
OtherMessage
The array specifier can be one of the following:
[N]
where N
is the fixed size of the array[]
[<=N]
where N
is the maximum size of the arrayDepending on the type the following values are valid:
bool
:
true
, 1
false
, 0
byte
:
[0, 255]
char
:
[0, 255]
float32
and float64
:
.
) as the separator between the integer-part and fractional-part.int8
, int16
, int32
and int64
:
[- 2 ^ (N - 1), 2 ^ (N - 1) - 1]
where N
is the number of bits behind int
uint8
, uint16
, uint32
and uint64
:
[0, 2 ^ N - 1]
where N
is the number of bits behind uint
string
:
a string value which can optionally be quoted with either single quotes ('
) or double quotes ("
)
a double-quoted ("
) string (respectively single-quoted ('
)) should have any inner double quotes (respectively single quotes) escaped:
string my_string "I heard \"Hello\""
is validstring my_string "I heard "Hello""
is not validstring my_string "I heard 'Hello'"
is validstring my_string 'I heard \'Hello\''
is validstring my_string 'I heard 'Hello''
is not validstring my_string 'I heard "Hello"'
is validA service file contains two message definitions which are separated by a line which only contains three dashes:
---
Code is generated for defined interfaces to be usable by different client libraries. Interfaces described using the above format are first converted to IDL. Code generation uses the generated file.
A structure defined in the above format can be empty / contain no members.
In that case the generated .idl
structure will have a dummy member
(uint8 structure_needs_at_least_one_member
) to satisfy the requirement from
IDL of not being empty.
ROS type | IDL type |
---|---|
bool | boolean |
byte | octet |
char | uint8 |
float32 | float |
float64 | double |
int8 | int8 |
uint8 | uint8 |
int16 | short |
uint16 | unsigned short |
int32 | long |
uint32 | unsigned long |
int64 | long long |
uint64 | unsigned long long |
string | string |
The mapping of byte
uses a different type than in ROS 1 while still remaining an opaque 8-bit quantity.
Definition in ROS 1: deprecated alias for int8
.
Definition in IDL (7.4.1.4.4.2.6): an opaque 8-bit quantity.
While the mapping of char
is unintuitive it preserves compatibility with the definition in ROS 1:
“deprecated alias for uint8
”.
ROS type | IDL type |
---|---|
static array | array |
unbounded dynamic array | sequence |
bounded dynamic array | bounded sequence |
bounded string | bounded string |