Message in ROS
Messages are spread across the whole system of a ROS instance, which are the essence and physical base of communication and coordination in ROS system. The message is a serializable and platform agnostic (in the perspective of OS, programming language, etc) specification of structured data.
Most of information in this post is refer to msg page in ROS wiki and source code for ROS core module.
A directly connected concept in ROS is Topic, which is named bus for message exchange, which will be covered in later post. The Service is also based on the infrastructure of message, which will be illustrated in next post.
Message format and definition
Message are defined in msg
files, which list the detailed component of a
message. Each message of an component can be one of the following types:
Primitive types
Currently supported primitive types:
int*
: integer of various size, includingint8
,int16
,int32
,int64
;uint*
: unsigned integer of various size, includinguint8
,uint16
,uint32
,uint64
;bool
: boolean value;float*
: floating point number of various size, includingfloat32
,float64
(corresponding todouble
type);string
: ASCII string;time
: sec & nsec (nanosecond), two unsigned 32-bit integersduration
: sec & nsec, two signed 32-bit integers The last two item can be treated as composite data type since they are actually defined as the following (reference):1234## time as msg spec. time is unsignedTIME_MSG = "uint32 secs\nuint32 nsecs"## duration as msg spec. duration is just like time except signedDURATION_MSG = "int32 secs\nint32 nsecs"Besides, there are some deprecated types which may occur in old packages:
char
: aliased touint8
byte
: aliased toint8
- Arrays
- fixed length(
type[size]
): direct serialization; - variable length(
type[]
): serialized as length prefixed listing (length inuint32
).
- fixed length(
Composite type as defined in other message file
Message definition itself can be used as a type for other message definition, which just worked as a composite of several primitive types.
Some composite message are defined in ROS core packages anc commonly used as convention. The common standard message are defined in std_msgs which can be used for quick prototyping. Notable item are:
Header
: header type is an standard type to provide standard metadata for a message, which is consisted of an sequence number(uint32
), timestamp (time
) and an id of frame (string
). For some historical reason, this field is wide used just as an primitive type.Empty
: empty type is just as it is named, which contains no content (defined in an empty file) and can be used as an signal.- Multi-dimension array: define multi-dimension array, with the layout specified as MultiArrayLayout
ColorRGBA
: 32bit floating point number describe color format (in the order of red, green, blue, alpha)However, most of the wrapper types are simply use
data
field for its payload, which lacks of sufficient semantic for maintains. Thus out of consideration of maintenance, a dedicated message definition is required. Since most of other message types Some common used message types are defined in common message
Constant
Message definition can also contain constant definition, in the form of assignment of value to primitive value. (As denoted before, the
time
andduration
are special primitive value with extra structure, these types cannot be assigned as constant directly)
Message file
Message definition are stored in message file (.msg) and located in msg
directory inside of src
of a ROS package.
The directory structure of a simple package with an message definition is illustrated as follows:
|
|
Utilize messages
To utilize messages, the definition of the message in language specific form ought to be generated and the message handling and processing are also required to be supported. These can be done by including message_generation
and message_runtime
package in package.xml
(or un-comment the illustration generated by default):
Then in build file (the CMakeLists.txt
at the root of of an package in src package), register defined message and enable message findings, including the following configuration items:
Add message generation package to required component
(this step affect the process of the whole project from this point, thus latter pcakage can be processed correctly without proper configuration of this item, while which is not encouraged)
123456find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation)expose message in current package
1234add_message_files(FILESNum.msg)import messages from packages
1234generate_messages(DEPENDENCIESstd_msgs)declare dependencies to build tool
123catkin_package(CATKIN_DEPENDS roscpp rospy std_msgs message_runtime)
The content of the package is a listing of the entries in the this message.
Each entry is specified in separated line, while blank line and hash started
lines are ignored. Each entry is declared by type
and name
separated by whitespace. For the constant, a value
filed led by =
is attached to the
end of entry declaration.
The following is a simple message file:
|
|
Make and list
After all messages configuration setup, rebuild ros package to check potential
errors and generate language specific headers/sources in devel
directory.
Generated files including headers for C (in devel/include
), python lib (in devel/lib/python2.7/dist-packages/
), CMake configurations (in devel/share/<package-name>/
), LISP code (in devel/share/common-lisp
), Node.js code (in devel/share/gennodejs
)
These generated files can be used to leverage IDE supports to messages (as well as services, actions, etc) and support other conventional tools to
support ros package development. These introspection information can also be used to assist package shell complement, for example, rosmsg show <package-name>/<message-name>
. (For shell complement feature, an sync of
package information is required before these actions, which is using source devel/setup.zsh
command).