feat: add option to read LiDAR data from rosbag#277
Draft
hakuturu583 wants to merge 24 commits into
Draft
Conversation
Add `use_rosbag` option to T4Devkit that reads LiDAR point cloud data directly from rosbag2 (db3/mcap) files in `input_bag/` instead of processed `.pcd.bin` files. Uses the `rosbags` library (pure Python, no ROS2 required) as an optional dependency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
☂️ Python Coverage
Overall Coverage
New Files
Modified Files
|
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a rosbag2-backed LiDAR loading path to T4Devkit, enabling visualization and downstream consumers to transparently read PointCloud2 data from input_bag/ instead of preprocessed .pcd.bin files.
Changes:
- Introduces
use_rosbagandtopic_mappingoptions inT4Devkit, plus aget_lidar_pointcloud()API used by the rendering pipeline. - Adds a
t4_devkit.rosbagmodule (Rosbag2Reader,TopicMapping, PointCloud2→LidarPointCloudconversion) and corresponding test coverage. - Extends
t4vizCLI commands with--use-rosbagand--topic-mapping, and documents rosbag usage; addsrosbagsas a dependency.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/rosbag/init.py | Adds package marker for rosbag-related tests. |
| tests/rosbag/test_pointcloud2.py | Unit tests for PointCloud2 → LidarPointCloud conversion behavior. |
| tests/rosbag/test_reader.py | Integration tests for Rosbag2Reader against a synthetic rosbag. |
| tests/rosbag/test_topic_mapping.py | Validation and conversion tests for TopicMapping. |
| t4_devkit/tier4.py | Adds rosbag initialization and get_lidar_pointcloud() fallback logic. |
| t4_devkit/rosbag/init.py | Exposes rosbag reader and mapping types. |
| t4_devkit/rosbag/reader.py | Implements Rosbag2Reader with timestamp indexing and message retrieval. |
| t4_devkit/rosbag/pointcloud2.py | Implements PointCloud2 parsing into the devkit point cloud format. |
| t4_devkit/rosbag/topic_mapping.py | Adds validated channel↔topic mapping datatype utilities. |
| t4_devkit/helper/rendering.py | Switches rendering to use T4Devkit.get_lidar_pointcloud(). |
| t4_devkit/cli/visualize.py | Adds --use-rosbag / --topic-mapping and parsing helper. |
| pyproject.toml | Adds required dependency on rosbags. |
| docs/tutorials/render.md | Documents rosbag LiDAR reading and CLI usage. |
| docs/tutorials/initialize.md | Documents optional input_bag/ dataset layout. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Support reading pandar_msgs/msg/PandarScan topics in addition to PointCloud2, enabling LiDAR point cloud extraction from rosbags that contain raw Hesai UDP packets (e.g. XT32, XT32M2X). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ktro2828
reviewed
Jun 2, 2026
| PointCloudColorMode.SEGMENTATION | ||
| if self._has_lidarseg() | ||
| else PointCloudColorMode.DISTANCE | ||
| ) |
Collaborator
There was a problem hiding this comment.
Note that LiDAR point clouds are never loaded from rosbag in t4viz scene/instance command because they force to set pointcloud_color_mode=PointCloudColorMode.Segmentation if the dataset contains lidarseg data.
…d add OT128 support Replace AT128/AT128P sensor models with OT128 using official Hesai elevation angles from the Angle Correction CSV. Fix 90° yaw rotation by converting from Hesai native coordinates (x=right, y=forward) to ROS sensor frame (x=forward, y=left, z=up). Also update PandarPacket definition to use fixed uint8[1500] buffer with size field, add sensor_type validation in Rosbag2Reader, improve reader performance with O(1) topic connection lookup, and update rerun API calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rsion The Hesai sensor frame uses native coordinates and the /tf_static tree includes the full rotation from sensor frame to base_link. Revert the incorrect Hesai-to-ROS axis swap in the decoder and instead read /tf_static from the rosbag to compute the composed transform. Add frame_id parameter to TopicMapping so users can specify the sensor's TF frame (e.g. "hesai_top") for automatic coordinate transformation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add per-channel azimuth offset from the OT128 Angle Correction CSV. Channels 25-88 have offsets up to ±4.6° which caused visible projection misalignment without correction. XT32 azimuth offsets are all 0 per the official CSV. Also verified XT32 elevation angles match the CSV exactly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace (R, t) tuple representation with 4x4 homogeneous matrices throughout TF handling. Add get_sensor2ego() public method for resolving /tf_static chain from any sensor frame to target frame. Extract _DEFAULT_TARGET_FRAME constant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merged
3 tasks
… chunk-filter off-by-one (#279) * fix(rosbag): widen Reader.messages start by 1ns to dodge rosbags MCAP chunk-filter off-by-one Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(pre-commit): autofix --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: hakuturu583 <10348912+hakuturu583@users.noreply.github.com>
…tion Use the UDP Sequence field (u32 LE) defined in Hesai specs to detect dropped packets within a PandarScan message. XT32 stores the sequence in the last 4 bytes; OT128 at 30 bytes from the end (per their respective User Manuals, Section 3.1.2 Tail / Additional information). By default (min_completeness=1.0), any scan with missing packets is rejected with ValueError. Callers can lower the threshold or disable the check with min_completeness=0.0. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
use_rosbagoption toT4Devkitthat reads LiDAR point cloud data directly from rosbag2 files (input_bag/) instead of processed.pcd.binfilesrosbagslibrary (pure Python, no ROS2 installation required)--use-rosbagand--topic-mappingCLI flags tot4vizcommands (scene,instance,pointcloud)LidarPointCloudformat (4×N float32 array) as file-based loading, fully transparent to downstream codeTopicMappingdataclass (attrs-based) with input validation for channel-to-topic mappingpandar_msgs/msg/PandarScan(Hesai raw packet) decoding support withsensor_typeparameterset_time_seconds→set_time,ImageEncoded→EncodedImage)Key design decisions
rosbagsas required dependency: Added to[project.dependencies]so it is always available.TopicMappingdataclass: Validates that channel names are non-empty strings and topic names start with/. Accepts bothlist[TopicMapping]anddict[str, str](auto-converted) for ergonomics. Optionalsensor_typefield for PandarScan topics.sensor_typefor PandarScan: Instead of auto-detecting the sensor model from factory bytes or channel count, the user must specify the Hesai model name (e.g."OT128","XT32") viaTopicMapping.sensor_type. This avoids ambiguity and validates channel count at init time.rosbagsReader.messages()API to build the timestamp index. The underlying cursor lazily evaluates rows so payloads are not loaded into memory all at once.get_pointcloud()uses a lock to support concurrent access fromThreadPoolExecutorin the rendering pipeline.Usage
topic_mappingkeys must match T4sample_data.channelnames, values must be ROS topic names in the rosbag. If omitted, PointCloud2 topics are auto-detected. PandarScan topics always require explicittopic_mappingwithsensor_type.Supported Hesai sensor models
Test plan
use_rosbag=False)ruff checkpasses🤖 Generated with Claude Code