Skip to content

Latest commit

 

History

History
 
 

cpp

C++ implementation of the MCAP file format

Example writer

#define MCAP_IMPLEMENTATION  // Define this in exactly one .cpp file
#include <mcap/writer.hpp>

#include <chrono>
#include <cstring>
#include <iostream>

// Returns the system time in nanoseconds. std::chrono is used here, but any
// high resolution clock API (such as clock_gettime) can be used.
mcap::Timestamp now() {
  return mcap::Timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(
                           std::chrono::system_clock::now().time_since_epoch())
                           .count());
}

int main() {
  // Initialize an MCAP writer with the "ros1" profile and write the file header
  mcap::McapWriter writer;
  auto status = writer.open("output.mcap", mcap::McapWriterOptions("ros1"));
  if (!status.ok()) {
    std::cerr << "Failed to open MCAP file for writing: " << status.message << "\n";
    return 1;
  }

  // Register a Schema
  mcap::Schema stdMsgsString("std_msgs/String", "ros1msg", "string data");
  writer.addSchema(stdMsgsString);

  // Register a Channel
  mcap::Channel chatterPublisher("/chatter", "ros1", stdMsgsString.id);
  writer.addChannel(chatterPublisher);

  // Create a message payload. This would typically be done by your own
  // serialiation library. In this example, we manually create ROS1 binary data
  std::array<std::byte, 4 + 13> payload;
  const uint32_t length = 13;
  std::memcpy(payload.data(), &length, 4);
  std::memcpy(payload.data() + 4, "Hello, world!", 13);

  // Write our message
  mcap::Message msg;
  msg.channelId = chatterPublisher.id;
  msg.sequence = 1; // Optional
  msg.logTime = now(); // Required nanosecond timestamp
  msg.publishTime = msg.logTime; // Set to logTime if not available
  msg.data = payload.data();
  msg.dataSize = payload.size();
  writer.write(msg);

  // Finish writing the file
  writer.close();
}

Building

Run make to build the library using a Docker container. This requires Docker to be installed, and will produce Linux (ELF) binaries compiled in an Ubuntu container with the clang compiler. If you want to build binaries for another platform or using your own compiler, run make build-host. This requires a working C++ compiler toolchain and Conan to be installed.

Output binaries can be found in:

  • cpp/bench/build/Release/bin/,
  • cpp/examples/build/Release/bin/
  • cpp/test/build/Debug/bin/.

Including in your project

The C++ implementation of MCAP is maintained as a header-only library with the following dependencies:

To simplify installation of dependencies, the Conan package manager can be used with the included conanfile.py. If you use an alternative approach, such as CMake's FetchContent or directly vendoring the dependencies, make sure you use versions equal or greater than the versions listed above.

Usage

Refer to the API documentation in mcap/mcap.hpp for full details. The high-level interfaces for reading and writing are McapReader and McapWriter.