Skip to content

Ft: Gazebo lidar template for ROS2#22

Merged
stibipet merged 30 commits into
ctu-mrs:ros2from
TomasMerva:ft_lidar_ros2
Nov 3, 2025
Merged

Ft: Gazebo lidar template for ROS2#22
stibipet merged 30 commits into
ctu-mrs:ros2from
TomasMerva:ft_lidar_ros2

Conversation

@TomasMerva

@TomasMerva TomasMerva commented Oct 21, 2025

Copy link
Copy Markdown
Contributor

Hi,
I added a general template for the LIDAR using the default Gazebo plugin and separated the individual sensors into their own folders.

Things that still need to be done:

  1. There is currently no TF information being published from Gazebo to ROS/RViz, so a tf2 static publisher is required. Therefore, a custom plugin wrapper for Gazebo::Lidar should be implemented as you do in ROS1.
  2. Many sensors are still defined in component_snippets.sdf.jinja and generic_components.sdf.jinja. These should each be moved into separate folders or removed since none of them has been implemented yet.
  3. Camera::Image::Raw and Camera::Info are currently loaded in different ways. It would be good to unify this and load everything through uav_ros_gz_bridge_config.jinja.yaml.
  4. Create a template for 3D lidar -> a different msg type has to be used

@TomasMerva

Copy link
Copy Markdown
Contributor Author

#21 This one should be merged first to avoid potential conflicts.

@spurnvoj

Copy link
Copy Markdown
Member

Points for discussion:

  1. Take frames and their transformation for plugins from the generated sdf and generate a launch file with tf_static_publishers
  2. Please continue with this. I've wanted to do it for a long time, but never found the time.
  3. You can use the standard bridge for Camera::Image::Raw, but in that case, you will not use image_transport to have a compressed image. So the ros_gz_image package is needed https://index.ros.org/p/ros_gz_image/

@matemat13

Copy link
Copy Markdown
Member

We also need something like this for the depth cameras since we no longer only use Realsense... For now, I've created an issue. Maybe I'll find some time sometime to actually solve it :D

@klaxalk

klaxalk commented Oct 23, 2025

Copy link
Copy Markdown
Member

Yep, having parametric depth cameras would be great! So please, work on this :-).

For now, I am dealing with the static tfs by a custom tf publisher..

@TomasMerva

TomasMerva commented Oct 24, 2025

Copy link
Copy Markdown
Contributor Author

Just small update on this PR:
Tf publishers

  • I created the SdfTfPublisher , which reads the generated SDF files and publishes TF static transformations based on the detected sensor links.
  • I added tf_static_publisher parameters in the config/spawner_params.yaml file to specify the sensors for which we do not want to create TF transformations, as well as basic_link to define the parent link for the static publisher.

ToDo list

  1. I need to check the basic_link frame you are using (it is probably fcu frame) Moreover, I have to verify whether inverting the transformation matrices is necessary before publishing these TF transformations.
  2. I will rewrite the Scance and Rplidar (2D lidars that are specified in the jinja files) so that they use the newly created gazebo_twoD_lidar_macro and copy their original parameters. The same applies to the Ouster and Velodyne lidars, however, I will need to create a new gazebo_threeD_lidar_macro.
  3. I might be wrong, but I believe there is currently some potential for confusion, since we use two methods to define sensor poses: either through the <link/pose> tag, or, when using mount points, through joints. I suggest using only the <joint/origin> tag to specify these poses, and adapting the SdfTfPublisher class to obtain poses from joints instead of links. Since this is a new repository in terms of supported sensors, it would be easier to standardize it now.

Therefore, please do not merge this PR yet.

@spurnvoj

spurnvoj commented Oct 26, 2025

Copy link
Copy Markdown
Member

@TomasMerva As we discussed, please also include the namespace in the frame names. You can check to have the TF structured similarly to the ROS1 version.

Anyway, Good work!

PS: If the PR is not in the ready state, you can switch it to draft at the bottom of this page
image

@TomasMerva TomasMerva marked this pull request as draft October 27, 2025 12:10
@TomasMerva TomasMerva marked this pull request as ready for review October 31, 2025 09:14
@TomasMerva

TomasMerva commented Oct 31, 2025

Copy link
Copy Markdown
Contributor Author

What has changed:

  1. All lidars (Rplidar, Scanse Sweep, Ouster, Velodyne) now use the default Gazebo plugin. The mrs_drone_spawner automatically sets the appropriate message type based on the number of vertical samples read from the generated SDF files
  2. The pose of each sensor link must be specified in the <link> tag, since <joint/pose> in SDF does not define the transform between parent and child, unlike in URDF where the joint origin sets the child link’s pose.
  3. Manual setup of static tfs is no longer required, sdf_to_tf_publisher.py handles this automatically. Certain links listed in config/spawner_params.yaml are intentionally ignored, including the Garmin rangefinder named lidar. Since PX4 expects specific link names, it is best not to modify anything related to naming within the Garmin rangefinder or it will not be loaded correctly by PX4 Gazebo plugin
  4. sdf_to_tf_publisher.py reads the pose defined in the <link> tag as well as any optional <pose> offset specified inside a <sensor plugin ...> tag. It combines both poses and publishes the resulting static transformation with respect to namespace/fcu. This currently works for other sensor types as well, including cameras.

image

Things to keep in mind or suggestions

  1. The <gz_frame_id> will be deprecated in future versions of Gazebo and replaced with <frame_id>, check Conform to ros format for header field frame_id of sensor msgs gazebosim/gz-sensors#195
    Using gz_frame_id emits a warning; should be part of the SDFormat spec gazebosim/gz-sensors#306
    However, since <frame_id> is not yet supported in Gazebo Harmonic, omitting <gz_frame_id> will cause the frame in the message header to default to namespace::sensor_link::sensor_plugin_name. For now, I think it is best to keep <gz_frame_id> as it is. When transitioning to a newer Gazebo version, we can simply rename the tag <gz_frame_id> to <frame_id>.
  2. The Ouster lidar includes an IMU, but since IMU integration has not yet been added to the MRS stack, I will create a separate Issue/PR for that to avoid mixing changes, Rewrite IMU plugin for ROS2 #24

@TomasMerva TomasMerva marked this pull request as draft October 31, 2025 10:36
@TomasMerva TomasMerva marked this pull request as ready for review October 31, 2025 12:31
@stibipet

stibipet commented Oct 31, 2025

Copy link
Copy Markdown
Member

Re-enabled lidars for all supported platforms:

  • f330 (no lidars)
  • f450
  • f550
  • m690
  • robofly (no lidars)
  • t650
  • x500
  • naki (will be discontinued)

@spurnvoj spurnvoj requested a review from Copilot November 3, 2025 10:50

Copilot AI left a comment

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.

Pull Request Overview

This PR adds a general LIDAR template for ROS2 using the default Gazebo plugin and reorganizes sensor components into separate folders. The main changes include:

  • Implementation of a new SdfTfPublisher utility to generate static TF transforms from SDF files
  • Reorganization of sensor templates into dedicated folders (rangefinder/, lidar/, camera/)
  • Addition of LIDAR sensor templates (RPLidar, Scanse Sweep, Velodyne, Ouster) with support for both 2D and 3D LIDARs
  • Updates to the bridge configuration to handle LIDAR topics
  • Refactoring of the camera macro to remove link/joint creation and use pose offsets instead

Reviewed Changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
mrs_uav_gazebo_simulator/utils/sdf_to_tf_publisher.py New utility class for parsing SDF files and publishing static TF transforms for sensors
mrs_uav_gazebo_simulator/mrs_drone_spawner.py Updated to support LIDAR sensors, integrate TF publisher, and reorganize sensor detection logic
models/mrs_robots_description/sdf/components/lidar/*.sdf.jinja New LIDAR sensor templates (ouster, rplidar, scanse_sweep, velodyne)
models/mrs_robots_description/sdf/components/rangefinder/*.sdf.jinja Reorganized rangefinder templates (garmin, teraranger)
models/mrs_robots_description/sdf/components/camera/*.sdf.jinja Reorganized camera templates (bluefox, mobius)
models/mrs_robots_description/sdf/components/component_snippets.sdf.jinja Updated to import from reorganized component folders
models/mrs_robots_description/sdf/generic_components.sdf.jinja Added new LIDAR plugin macro, refactored camera macro
config/uav_ros_gz_bridge_config.yaml.jinja New bridge configuration template supporting cameras and LIDARs
models/mrs_robots_description/sdf/*.sdf.jinja Updated drone models to use new component organization and add LIDAR sensors
launch/*.launch.py Minor formatting and parameter name changes
config/spawner_params.yaml Added TF static publisher configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mrs_uav_gazebo_simulator/mrs_drone_spawner.py
stibipet and others added 3 commits November 3, 2025 12:03
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@stibipet stibipet self-assigned this Nov 3, 2025
@stibipet stibipet merged commit 2c806a0 into ctu-mrs:ros2 Nov 3, 2025
4 of 12 checks passed
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.

6 participants