Skip to content

Port to ROS 2 ros_gz_point_cloud - #912

Open
ahcorde wants to merge 2 commits into
ros2from
ahcorde/rolling/ros_gz_point_cloud_ros2
Open

Port to ROS 2 ros_gz_point_cloud#912
ahcorde wants to merge 2 commits into
ros2from
ahcorde/rolling/ros_gz_point_cloud_ros2

Conversation

@ahcorde

@ahcorde ahcorde commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

🎉 New feature

Related with #911

Summary

Update ros_gz_point_cloud to use ROS 2 and newer Gazebo versions

Backport Policy

Checklist

  • Signed all commits for DCO
  • Added a screen capture or video to the PR description that demonstrates the feature
  • Added tests
  • Added example and/or tutorial
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • Consider updating Python bindings (if the library has them)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • Updated Bazel files (if adding new files). Created an issue otherwise.
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers
  • Was GenAI used to generate this PR? If so, make sure to add "Generated-by" to your commits. (See this policy for more info.)

Generated-by: Claude Opus 4.7

Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining Signed-off-by and Generated-by messages.

Backports: If this is a backport, please use Rebase and Merge instead.

Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Comment thread ros_gz_point_cloud/src/point_cloud.cpp Outdated
auto ns = _sdf->Get<std::string>("namespace", scoped_name).first;
std::string node_name = scoped_name;
std::ranges::replace(node_name, '/', '_');
this->dataPtr->rosnode_ = std::make_shared<rclcpp::Node>(node_name, ns);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a try/catch here? I think this could throw if we use names such as 3d_lidar_link_sensor or my-robot_link_sensor not valid in ROS.

msg.header.stamp.nanosec = sec_nsec.second;
msg.width = _width;
msg.height = _height;
msg.is_dense = true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is hardcoded to true. Should we use the same logic you applied in OnNewDepthFrame, where it can be false as well?

@@ -234,33 +255,43 @@
{
this->dataPtr->current_time_ = _info.simTime;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we protect this and the readers in separate threads with a mutex?

Comment thread ros_gz_point_cloud/src/point_cloud.cpp Outdated
}

this->dataPtr->scene_ = engine->SceneByName(this->dataPtr->scene_name_);
this->dataPtr->scene_ = engine->SceneByIndex(0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is hardcoded to scene at index 0. I think we should update the documentation about this parameter in point_cloud.hpp or parse it correctly.

ros::init(argc, argv, "ignition", ros::init_options::NoSigintHandler);
ROS_INFO_NAMED("ros_gz_point_cloud", "Initialized ROS");
if (!rclcpp::ok()) {
rclcpp::init(0, nullptr);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use NodeOptions().start_parameter_services(false) or a shared context/executor? There's no rclcpp::shutdown, executor, or spin in the package.

Comment thread ros_gz_point_cloud/src/point_cloud.cpp Outdated
if (!this->dataPtr->scene_) {
auto loadedEngNames = gz::rendering::loadedEngines();
if (loadedEngNames.empty()) {
RCLCPP_INFO(rclcpp::get_logger("ros_gz_point_cloud"), "No rendering engines loaded yet");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RCLCPP_INFO_ONCE or throttle this message?

}

//////////////////////////////////////////////////
void PointCloudPrivate::LoadRgbCamera(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is almost similar to LoadDepthCamera(). Should we use a helper function with the right parameters?

Comment thread ros_gz_point_cloud/src/point_cloud.cpp Outdated
if (this->type_ == SensorType::RGBD_CAMERA && _channels != 1) {
ROS_WARN_NAMED(
"ros_gz_point_cloud",
if (this->type_ == RGBD_CAMERA && _channels != 1) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this block can never be reached as the callback seems connected with DEPTH_CAMERA and GPU_LIDAR only.

Comment thread ros_gz_point_cloud/src/point_cloud.cpp Outdated
}
if ((this->type_ == SensorType::RGBD_CAMERA ||
this->type_ == SensorType::DEPTH_CAMERA) && _format != "FLOAT32")
if ((this->type_ == RGBD_CAMERA ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I think we can remove the RGBD_CAMERA part.

Comment thread ros_gz_point_cloud/src/point_cloud.cpp Outdated
msg.header.stamp.nanosec = sec_nsec.second;
msg.width = _width;
msg.height = _height;
msg.row_step = msg.point_step * _width;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this line now?

this->rgb_image_ = this->rgb_camera_->CreateImage();
const auto sec_nsec = gz::math::durationToSecNsec(this->current_time_);

sensor_msgs::msg::PointCloud2 msg;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This setup block is almost the same as the one in OnNewDepthFrame. Could we move it to a shared helper so fixes only need to happen in one place?

Also, depth and lidar clouds have no color, but they still get an rgb field that is zeroed per point. Using only "xyz" fields for them would save 4 bytes per point and skip that work.


<exec_depend>message_runtime</exec_depend>
<depend>gz_plugin_vendor</depend>
<depend>gz_rendering_vendor</depend>

@caguero caguero Aug 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code uses gz-math and gz-common directly, but they are only pulled in through the other vendor packages. Could we declare gz_math_vendor and gz_common_vendor here?

{
// Forward declarations.
class PointCloudPrivate;

@caguero caguero Aug 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment mentions RGBD and GPU lidar, but the plugin also supports depth cameras. Same for the line below.

Comment thread ros_gz_point_cloud/src/point_cloud.cpp Outdated

// Get sensor
auto sensor = this->scene_->SensorByName(sensor_name);
auto sensor = this->scene_->SensorByName(sensor_name + "_depth");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doxygen brief for this function (in the class declaration) still says "Get RGB camera from rendering", but it actually looks up the depth camera of the RGBD sensor.

Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Inbox

Development

Successfully merging this pull request may close these issues.

3 participants