[Documentation] [TitleIndex] [WordIndex

Note: This is a legacy, rosbuild based, version of the ROS Filesystem Concepts

ROS uses a simplified messages description language for describing the data values (aka messages) that ROS nodes publish. This description makes it easy for ROS tools to automatically generate source code for the message type in several target languages. Message descriptions are stored in .msg files in the msg/ subdirectory of a ROS package.

There are two parts to a .msg file: fields and constants. Fields are the data that is sent inside of the message. Constants define useful values that can be used to interpret those fields (e.g. enum-like constants for an integer value).

Message types are referred to using package resource names. For example, the file geometry_msgs/msg/Twist.msg is commonly referred to as geometry_msgs/Twist.

Command-line Tools

rosmsg prints out message definition information and can find source files that use a message type.

Message Description Specification

The format of this language is simple: a message description is a list of data field descriptions and constant definitions on separate lines.

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 x
int32 y

Field Types

Field types can be:

  1. a built-in type, such as "float32 pan" or "string name"
  2. names of Message descriptions defined on their own, such as "geometry_msgs/PoseStamped"
  3. fixed- or variable-length arrays (lists) of the above, such as "float32[] ranges" or "Point32[10] points"
  4. the special Header type, which maps to std_msgs/Header

When embedding other Message descriptions, the type name may be relative (e.g. "Point32") if it is in the same package; otherwise it must be the full Message type (e.g. "std_msgs/String"). The only exception to this rule is Header.

NOTE: you must not use the names of built-in types or Header when constructing your own message types.

Built-in types:

Primitive Type

Serialization

C++

Python

bool (1)

unsigned 8-bit int

uint8_t (2)

bool

int8

signed 8-bit int

int8_t

int

uint8

unsigned 8-bit int

uint8_t

int (3)

int16

signed 16-bit int

int16_t

int

uint16

unsigned 16-bit int

uint16_t

int

int32

signed 32-bit int

int32_t

int

uint32

unsigned 32-bit int

uint32_t

int

int64

signed 64-bit int

int64_t

long

uint64

unsigned 64-bit int

uint64_t

long

float32

32-bit IEEE float

float

float

float64

64-bit IEEE float

double

float

string

ascii string (4)

std::string

string

time

secs/nsecs signed 32-bit ints

ros::Time

rospy.Time

duration

secs/nsecs signed 32-bit ints

ros::Duration

rospy.Duration

  1. bool was introduced in ROS 0.9
  2. bool in C++ is aliased to uint8_t because of array types: std::vector<bool> is in fact a specialized form of vector that is not a container. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2160.html for more information.

  3. uint8 has special meaning in Python. uint8[] is treated as a Python str so that it is compatible with other byte-oriented APIs in Python.

  4. unicode strings are currently not supported as a ROS data type. utf-8 should be used to be compatible with ROS string serialization.

Deprecated:

Array handling

Array Type

Serialization

C++

Python

fixed-length

no extra serialization

0.11+: boost::array, otherwise: std::vector

tuple (1)

variable-length

uint32 length prefix

std::vector

tuple (1)

uint8[]

see above

as above

string (2)

bool[]

see above

std::vector<uint8_t>

list(bool)

  1. In rospy, arrays are deserialized as tuples for performance reasons, but you can set fields to tuples and lists interchangeably.

  2. rospy treats uint8[] data as a string, which is the Python representation for byte data.

rospy can also deserialize arrays into numpy data structures. Please consult the rospy documentation for more information.

Field Names

The field name determines how a data value is referenced in the target language. For example, a field called 'pan' would be referenced as 'obj.pan' in Python, assuming that 'obj' is the variable storing the message.

Field names must be translated by message generators to several target languages, so we restrict field names to be an alphabetical character followed by any mixture of alphanumeric and underscores, i.e. [a-zA-Z][a-zA-Z1-9_]*. It is recommended that you avoid using field names that correspond to keywords in common languages -- although those names are legal, they create confusion as to how a field name is translated.

ROS provides the special Header type to provide a general mechanism for setting frame IDs for libraries like tf. While Header is not a built-in type (it's defined in std_msgs/msg/Header.msg), it is commonly used and has special semantics. If the first field of your .msg is:

Header header

It will be resolved as std_msgs/Header.

Header.msg:

#Standard metadata for higher-level flow data types
#sequence ID: consecutively increasing ID 
uint32 seq
#Two-integer timestamp that is expressed as:
# * stamp.secs: seconds (stamp_secs) since epoch
# * stamp.nsecs: nanoseconds since stamp_secs
# time-handling sugar is provided by the client library
time stamp
#Frame this data is associated with
string frame_id

The special nature of Header is mainly for historical reasons, such as preserving recorded data.

Constants

Each constant definition is like a field description, except that it also assigns a value. This value assignment is indicated by use of an equal '=' sign, e.g.

constanttype1 CONSTANTNAME1=constantvalue1
constanttype2 CONSTANTNAME2=constantvalue2

For example:

int32 X=123
int32 Y=-123
string FOO=foo
string EXAMPLE="#comments" are ignored, and leading and trailing whitespace removed

Notes:

Building .msg Files

The ROS Client Libraries implement message generators that translate .msg files into source code. These message generators must be invoked from your build script, though most of the gory details are taken care of by including some common build rules. By convention, all .msg files are stored in a directory within your package called "msg," and you can build all of them by adding the line genmsg() to your CMakeLists.txt file. Here is an example:

include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
rosbuild_init()
rosbuild_genmsg()

Client Library Support

In Python, the generated Python message file (e.g. std_msgs.msg.String) provides nearly all the information you might want about a .msg file. You can examine the __slots__ and _slot_types and other fields to introspect information about messages.


2024-11-09 17:34