Skip to main content
This page builds a converter in Python with the official MCAP libraries. The same structure works in C++, Rust, Go or TypeScript with their MCAP and protobuf libraries: register each channel with a protobuf schema, write messages in time order, and add the overlay as a metadata record.

Setup

Save nomadic_signal.proto and nomadic_skeleton.proto next to your converter and generate their Python classes:

The converter

The script has three parts:
  1. NomadicMcapWriter opens the file, writes the nomadic_spec metadata record, registers each channel with its protobuf schema on first use, and writes every message with the same log_time and publish_time.
  2. Message helpers, one per message type the format uses: images, intrinsics, transforms, poses, signals of every type and keypoints.
  3. An end-to-end example: three seconds of a Franka arm with an external and a wrist camera, its joint angles, end-effector pose and gripper. Replace the synthetic data with reads from your own logs.
convert_example.py
Run it, and it writes franka-demo-0001.mcap:

Converter checklist

  • One file per recording (scene, episode), with a stable recording.id.
  • One clock across every channel; t0_ns is the earliest timestamp, in absolute epoch nanoseconds.
  • Messages written in time order, with log_time = publish_time = the message timestamp.
  • Every declared channel exists and carries the declared message schema, protobuf-encoded.
  • Positions in metres, angles in radians, orientation as x, y, z, w quaternions, z up.
  • Point clouds in the vehicle frame (ground at z = 0), or in their sensor frame with a FrameTransform to vehicle.
  • Every signal declares its unit, or omits it with a note when the source has none.
  • Compressed video has no B-frames.
  • Vectors declare components; joints declare names in vector order.
  • The overlay passes preflight with no errors.

Checking the file

  1. Preflight the overlay before uploading: see Validation.
  2. Open the file in Foxglove. Cameras play in the Image panel, signals plot by message path (e.g. /sig/arm_joints.vector.values[0]), and transforms and point clouds appear in the 3D panel. If a sensor is upside down or below the ground there, it is wrong in your file.
  3. Inspect the structure with the mcap CLI: mcap info recording.mcap lists channels and schemas, and mcap list metadata recording.mcap shows the nomadic_spec record.
Then upload with the SDK; see Uploading local files.