Skip to content

ROSBag and MCAP Time Provenance Contract

Last updated: 2026-05-09

Why It Matters

Incident replay is only as good as its time provenance. For SLAM and fusion, a bag must answer: when was the physical sample valid, when did the publisher send it, when did the recorder receive it, which clock source was active, and whether TF/static calibration state was present at the same time. Without those answers, replay can reproduce message bytes while losing the timing fault that caused the vehicle behavior.

MCAP and modern rosbag2 can preserve both receive/log time and publish/send time. The application Header.stamp remains inside the serialized message and must be interpreted with the run's time-source manifest.

Provenance Contract

ArtifactRequired contentPurpose
Bag storageMCAP for production incident and regression logs unless a project-specific exception is documented.Indexed, schema-carrying, chunked recording with publish/log time fields.
Time base manifestuse_sim_time, /clock source, host clock sync source, RMW vendor/version, recorder host ID.Makes timestamp interpretation reproducible.
Message metadataBag receive/log timestamp and send/publish timestamp when available.Separates recording time from publisher time.
Application stampsOriginal Header.stamp preserved without restamping.Preserves acquisition and estimator-validity time.
Frame state/tf, /tf_static, static calibration artifact IDs, map/version IDs.Allows correct projection and localization replay.
QoS snapshotOffered/requested QoS for recorded topics or launch manifest hash.Explains missing transient-local, reliability, or lifespan behavior.
Recorder stateSplit/snapshot events, pause/resume mode, dropped cache counts, disk pressure.Identifies recorder-induced gaps.

Timestamp Semantics

FieldMeaning
MCAP log_timeTime at which the message was recorded.
MCAP publish_timeTime at which the message was published; if unavailable it is set to log_time.
rosbag2 recv_timestampNanosecond timestamp when the recorder received the message.
rosbag2 send_timestampNanosecond timestamp when the message was published; if unavailable it is set to receive time.
ROS message Header.stampApplication-defined acquisition or validity timestamp inside the message.

Do not assume these are equal. For sensor fusion, Header.stamp usually drives alignment. For recorder and middleware analysis, use send/publish and receive/log timestamps. For fleet incident timelines, map all three to the documented clock source and host clock offset.

Recording Profile

Recommended production profile for SLAM/fusion evidence:

bash
ros2 bag record -s mcap \
  --all \
  --include-hidden-topics \
  --repeat-all-transient-local 1 \
  --storage-config-file mcap_storage.yaml

For simulation or deterministic replay capture:

bash
ros2 bag record -s mcap --use-sim-time --all

Minimum topic set when selective recording is required:

GroupTopics
Time/clock, recorder diagnostics, host time sync status.
Frames/tf, /tf_static, calibration metadata topic or manifest.
LocalizationRaw/preprocessed LiDAR, IMU, GNSS, vehicle twist, NDT pose, EKF pose/twist, localization diagnostics.
FusionCamera/LiDAR/radar inputs, synchronized outputs, message-filter diagnostics.
Runtime/diagnostics, /statistics, node lifecycle events, QoS manifest, map/config/model versions.

MCAP Writer Options

Option classGuidance
ChunkingKeep chunking enabled for indexed access unless an emergency fast-write profile requires otherwise.
CompressionPrefer MCAP chunk compression (Lz4 or Zstd) over rosbag2 file/message compression when indexed reads matter.
Summary/indexDo not ship validation bags without summary/index unless a post-process step repairs them.
CRCDisable CRC only when write bandwidth is the limiting factor and storage health is covered elsewhere.
Split policySplit by time and size so incident windows are bounded and uploadable. Preserve transient-local data on splits.

Failure Modes

Failure modeSymptomControl
Missing /clockReplay uses wall time or starts with zero-time ambiguity.Record /clock and manifest use_sim_time; fail replay launch if absent.
Restamped bagHeader stamps no longer match original acquisition time.Preserve serialized messages; use sidecar metadata for alternate time views.
Missing /tf_static after trimFirst replay samples cannot transform or use wrong extrinsics.Repeat transient-local topics on split and include TF warmup in clips.
Receive-time-only evidenceCannot distinguish network backlog from sensor delay.Use rosbag2/MCAP path that preserves send/publish time where available.
Unindexed fast-write fileScenario mining and random-access replay are slow or incomplete.Post-process fast-write bags before upload and validation.
Snapshot too smallTriggered event lacks pre-roll needed for TF and message filters.Size snapshot cache by sensor rate, TF cache, and fusion queue budgets.
QoS override mismatchRecorder misses best-effort or transient-local topics.Version recorder QoS overrides and verify topic discovery before motion.

Replay Contract

Replay modeRule
Timing regressionRun at 1x with --clock; compare age, skew, and drop histograms.
Algorithm stressAccelerated replay allowed, but results cannot replace 1x acceptance.
Bag seekBackward seek must reset filters, TF caches, EKF history, and scan accumulators.
Trimmed incident clipInclude pre-roll for /tf, /tf_static, maps, and slow topic warmup.
Cross-version replayPreserve schema definitions, message package versions, map/config/model IDs, and RMW metadata.

Acceptance Checks

  • A recorded incident can answer all three timing questions for critical topics: header/acquisition time, publish/send time, and receive/log time.
  • ros2 bag info -s mcap <bag> succeeds and shows expected topic coverage.
  • /tf_static and map/calibration metadata are available to a late-joining replay node before localization output is evaluated.
  • Replay with use_sim_time=true does not publish trusted localization output before /clock is non-zero.
  • Bag split and snapshot tests preserve transient-local state and recorder metadata.
  • A post-processed MCAP is indexed and supports timestamp-bounded reads for scenario mining.

Sources

Public research notes collected from public sources.