Skip to content

Conversation

@Ikhyeon-Cho
Copy link

@Ikhyeon-Cho Ikhyeon-Cho commented Jan 25, 2026

Hi @koide3,

Based on our discussion in Issue #129, I've implemented the following optional ROS bridge utilities.

Summary

This PR adds header-only conversion utilities between ROS messages (sensor_msgs::PointCloud2/sensor_msgs::msg::PointCloud2) and small_gicp::PointCloud.

  • Files:
    • include/small_gicp/ros/ros1.hpp (ROS 1)
    • include/small_gicp/ros/ros2.hpp (ROS 2)
    • include/small_gicp/ros/ros_impl.hpp (Common template implementation)
  • Minimal Dependency:
    • No changes to CMakeLists.txt.
    • Users only need to include the header files with standard ROS headers.

Features

  • Unified Support: Identical API for both ROS 1 and ROS 2.
  • Safety:
    • Automatically filters NaN / Inf points from ROS message
    • Resizes the cloud to fit valid points only
  • Performance:
    • Optimized using reserve() + emplace_back() to avoid unnecessary initialization (Tried to align with
      small_gicp's policy of leaving normals/covariances uninitialized until estimation. )

Usage Example

 // ROS 1
 #include <small_gicp/ros/ros1.hpp>
 
 void callback(const sensor_msgs::PointCloud2& msg) {
  
   // XYZ only, NaNs filtered
   auto points = small_gicp::from_ros_msg(msg);
 
   // To estimate normals (required for registration):
   small_gicp::estimate_normals_covariances(*points, *tree);
 
  // Convert back
   auto result_msg = small_gicp::to_ros_msg(*points, "frame_id");
 }

Verification

I verified functional correctness, memory safety, and precision. You can easily test the reproduction code and Dockerfiles in the test/ros-bridge branch of my fork.

Test Status Note
ROS 1 Build ✅ Passed Noetic / g++
ROS 2 Build ✅ Passed Humble / g++
NaN Filtering ✅ Passed Invalid points from message filtered out correctly
Round Trip ✅ Passed Data integrity preserved
Precision ✅ Passed Float-Double conversion check

@Ikhyeon-Cho
Copy link
Author

I ran some performance benchmarks to verify the bridge implementation.

Test Environment

  • CPU: AMD Ryzen 9 5900X (12-Core)
  • Build: Release (-DCMAKE_BUILD_TYPE=Release)
  • Noetic: Ubuntu 20.04 (native)
  • Humble: Docker (ros:humble)

Results (~22k points, averaged over 100 samples)

ROS Version from_ros_msg to_ros_msg Total
Noetic ~0.10 ms ~0.04 ms ~0.14 ms
Humble ~0.12 ms ~0.05 ms ~0.15 ms

Notes

  • Tested with Velodyne VLP-16 point cloud data
  • Sufficient for real-time processing: 10Hz sensor → 100ms budget, bridge uses only ~0.15%
  • NaN/Inf filtering included in timing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant