MCAP Format Registry
This document describes well-known values for MCAP files.
Compression formats
The Chunk compression field may contain the following options:
- lz4: an algorithm that prioritizes compression/decompression speed over compression ratio.
- zstd: an algorithm with a tunable compression ratio/speed tradeoff.
Message encodings
The Channel message_encoding field describes the encoding for all messages within a channel. This field is mandatory.
ros1
message_encoding:ros1
cdr
message_encoding:cdr
Used by ROS 2. Each message is an XCDR1 or XCDR2 stream using the usual (RTPS SerializedPayload) framing.
XCDR1 and XCDR2 are described in Section 7.4 "Data Representation" of DDS-XTypes. Chapter 10 "Serialized Payload Representation" of DDSI-RTPS has some extra information about the frame format. (Note that the framing differs slightly between the specifications, but they are still compatible.)
protobuf
message_encoding:protobuf
flatbuffer
message_encoding:flatbuffer
cbor
message_encoding:cbor
msgpack
message_encoding:msgpack
json
message_encoding:json
Schema encodings
The Schema encoding field describes the encoding of a Channel's schema. Typically, this is related to the Channel's message_encoding, but they are separate concepts (e.g. there are multiple schema languages for json).
This field is required for some message encodings (e.g. protobuf) and optional for others (e.g. json).
(empty string)
Schema encoding may only be omitted for self-describing message encodings such as json.
name: May contain any valueencoding: (empty string)data: Must be empty (0 bytes)
protobuf
name: Fully qualified name to the message within the descriptor set. For example, in a proto file containingpackage foo.bar; message Baz {}the fully qualified message name isfoo.bar.Baz.encoding:protobufdata: A binary FileDescriptorSet as produced byprotoc --include_imports --descriptor_set_out.
flatbuffer
name: Fully qualified name corresponding to a name in the reflection Object table. For example in a schema containingnamespace foo; table Bar {}the fully qualified name isfoo.Bar.encoding:flatbufferdata: A reflection.Schema flatbuffer describing the parsed schema encoded as a binary flatbuffer. This can be generated by runningflatc -b --schemaon the fbs file.
ros1msg
name: A valid ROS1 package resource name, e.g.sensor_msgs/PointCloud2.encoding:ros1msgdata: Delimited concatenated ROS1.msgfiles.
The data field contains the concatenated .msg file content that is sent in the ROS subscription connection header for this message type.
The top-level message definition must appear first, with no delimiter. All following message definitions must be preceded by a two-line delimiter:
- One line consisting of just 80
=characters, then - One line exactly of the form
MSG: <package resource name>, naming the message definition to follow. The space afterMSG:is mandatory. The package resource name does not include a file extension.
This format can be reproduced using gendeps --cat.
No package may have multiple messages with the same name. (This applies even if they have different package resource names.) A definition must be present for each message named anywhere in the schema.
ros2msg
name: A valid package resource name, e.g.sensor_msgs/msg/PointCloud2.encoding:ros2msgdata: Delimited concatenated ROS 2 .msg files
The data field stores the .msg definition alongside its dependencies in the same format as ros1msg.
ros2idl
name: A valid ROS 2 package resource name, e.g.sensor_msgs/msg/PointCloud2.encoding:ros2idldata: Delimited concatenated ROS 2.idlfiles
The data field is a concatenation of .idl files, in any order, where each file (including the first one) is preceded by a two-line delimiter:
- One line consisting of just 80
=characters, then - One line exactly of the form
IDL: <package resource name>, giving the file its package resource name. The space afterIDL:is mandatory. The package resource name must be unique. It does not include a file extension.
The IDL type name of the top-level definition is derived by replacing each / in the name field with ::.
Interpretation
The final IDL for interpretation is obtained by running a limited C++-style preprocessor on the file named in the name field. Each directive of the form #include "X.idl" or #include <X.idl> includes the IDL file whose package resource name is X (as if we had unpacked the contents of this schema). All other preprocessor directives must be ignored.
If more sophisticated preprocessing is required, consider using the omgidl schema encoding instead.
omgidl
The omgidl schema encoding stores OMG IDL definitions for (X)CDR-encoded messages.
name: The globally-scoped name of the message type, eg.top_level_module::my_module::MyTypeencoding:omgidldata: valid OMG IDL definition file contents with a definition for the message type and all referenced types.
Producing schema.data for the omgidl schema encoding
.idl files usually contain only one definition each, and use C++ preprocessor
#include directives when referring to other definitions. However, the data
field must be the text of a single, self-contained OMG IDL source file. That is,
all referenced type definitions must be present, and there must be no
preprocessor directives.
You can produce the required format with a C++ preprocessor. For example, with GCC or Clang:
# -x c++: treat input as C++ to avoid guessing based on the extension.
# -E: run only the preprocessor.
# -P: remove all #-directives from the output.
# Run from the root of your IDL definition tree, or change the `-I` flag to the
# correct directory.
$ cc -x c++ -E -P -I . top_level_module/my_module/MyType.idl > combined.idl
For the following files:
#include "top_level_module/other_module/OtherType.idl"
module top_level_module {
module my_module {
struct MyType {
top_level_module::other_module::OtherType val;
};
};
};
module top_level_module {
module other_module {
struct OtherType {
float val;
};
};
};
This should produce:
module top_level_module {
module other_module {
struct OtherType {
float val;
};
};
};
module top_level_module {
module my_module {
struct MyType {
top_level_module::other_module::OtherType val;
};
};
};
For this example, schema.name should be set to top_level_module::my_module::MyType.
jsonschema
name: May contain any valueencoding:jsonschemadata: JSON Schema
Profiles
ROS1
The ros1 profile describes how to create MCAP files for ROS 1.
Header
profile: MUST beros1
Channel
message_encoding: MUST beros1metadatakeys:callerid(optional, string)latching(optional, bool stringified as "true" or "false")
Schema
encoding: MUST beros1msg
ROS2
The ros2 profile describes how to create MCAP files for ROS 2.
Header
profile: MUST beros2
Channel
message_encoding: MUST becdrmetadata:offered_qos_profiles(required, string) YAML formatted sequence of QoS policy values. See ROS QoS Policies for Recording docs for more details. The policy value may change depending on the ROS distro. Below is an example for a single policy schema value.
history: [keep_all, keep_last]
depth: int
reliability: [system_default, reliable, best_effort, unknown]
durability: [system_default, transient_local, volatile, unknown]
deadline:
sec: int
nsec: int
lifespan:
sec: int
nsec: int
liveliness: [system_default, automatic, manual_by_topic, unknown]
liveliness_lease_duration:
sec: int
nsec: int
avoid_ros_namespace_conventions: [true, false]
Schema
encoding: MUST be eitherros2msgorros2idl