MCAP ROS2BAG import export - #496
Merged
Merged
Conversation
Member
|
It looks good! |
Adds a laz_to_mcap console tool (apps/lidar_odometry_step_1) that reads a
LAZ scan and optional IMU csv and writes a self-contained .mcap file
(embedded ros2msg schemas, no ROS install needed to produce or inspect it)
with /lidar_points (sensor_msgs/PointCloud2), /imu (sensor_msgs/Imu) and
/lidar_sn (std_msgs/String) topics. Reuses load_point_cloud()/load_imu()
from lidar_odometry_utils.cpp rather than load_data(), which additionally
drops the first LAZ file's points as part of the odometry pipeline's own
preprocessing -- wrong for a lossless exporter.
The PointCloud2 field layout is selectable via --lidar-type
(generic|velodyne|ouster|hesai) to match what different downstream LIO
consumers expect, and topic names/frame_id are configurable.
rosbags/McapWriter.{h,cpp} and cdr_serializer.hpp started from files
copied out of the mandeye firmware/recorder project; rewrote them against
plain McapPoint/McapImuSample structs instead of that project's
LidarPoint/LidarIMU/lidars-BaseLidarClient.h types, which don't exist here.
Also fixes 3rdparty/mcap's CMakeLists.txt: the INTERFACE target never
linked liblz4/libzstd, which mcap's reader/writer .inl files need
unconditionally even when compression is never used.
Tests: rosbags/tests/test_mcap_writer.cpp (doctest, wired into
BUILD_TESTING) round-trips PointCloud2 (all four layouts) and IMU
messages through the real mcap::McapReader. Also validated end-to-end
against a real mandeye recording with ros2 bag info/play (ROS2 jazzy).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
laz_to_mcap: support exporting a whole mandeye session directory
The single-file <input.laz> positional arg now also accepts a directory:
laz_to_mcap scans it for lidarNNNN.laz/.las + imuNNNN.csv chunk pairs
(matched by the filename's last 4 digits, same convention load_data()
uses), writes one /lidar_points message per chunk (in filename order),
and merges + sorts every matched chunk's IMU samples into a single
stream. Chunks without a matching csv still get their points exported,
with a warning. --imu stays single-file-only since IMU now comes from
the directory itself.
Sequential, no threading, to keep the loop straightforward.
Also gives McapFileWriter real per-channel sequence numbers instead of
always writing 0 -- previously harmless (one message per channel), but
directory mode now regularly writes many /lidar_points messages per file.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Move laz_to_mcap from lidar_odometry_step_1 into console_tools
It's a standalone LAZ/IMU-csv -> MCAP converter with no GUI and no real
tie to the odometry app beyond reusing its load_point_cloud()/load_imu()
parsing -- apps/console_tools is where every other converter like this
(laz_to_pcd, laz_to_ply, pcd_to_laz, laz_to_txt) already lives, and
matching that pattern means it's now gated by BUILD_WITH_CLI_TOOLS like
its siblings instead of always building.
Renamed mcap_export_main.cpp -> laz_to_mcap.cpp to match every sibling
file in that directory being named after its target. It still pulls
lidar_odometry_step_1/lidar_odometry_utils.{h,cpp} in by relative path
for load_point_cloud()/load_imu() rather than duplicating them.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix macOS-safe text and label formatting
Co-authored-by: michalpelka <3209244+michalpelka@users.noreply.github.com>
laz_to_mcap: add MLvxCalib calibration support, drop single-file mode
Session directories now auto-detect calibration.json/.mjc + .sn (or
accept --calibration/--sn overrides) and apply per-sensor extrinsics
plus the configured IMU serial when exporting, matching the convention
used by lidar_odometry.cpp and concatenate_multi_livox. Single-file
(.laz + --imu) input is removed since multi-lidar calibration only
makes sense for a full session directory.
michalpelka
force-pushed
the
mp/mcap_export
branch
from
August 20, 2026 11:23
74d04e5 to
640402a
Compare
cmake/cpu_optimizations.cmake forces -D_HAS_STD_BYTE=0 for all MSVC targets (a leftover pybind11/Windows SDK workaround), which silently disables std::byte project-wide. mcap's headers are the first thing in this codebase to actually need it, so Windows CI failed with "'byte' is not a member of 'std'" in McapWriter.cpp and test_mcap_writer.cpp. Re-enable std::byte scoped to just those two translation units, ahead of any standard header that would otherwise lock the disabled value in for the rest of the TU, rather than touching the global define.
michalpelka
force-pushed
the
mp/mcap_export
branch
from
August 20, 2026 13:19
576262c to
0f09ebd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Non-ROS, self contained importer/exporter to ROS 2 bag.
Tested imports:
Works with Python tool to convert : rosbags convert.
Data from TIERS imports after step1:


Data from Oxfod Spires (Ouster):
There is no compression available on Windows - we can circle navigate it with rosbags convert.