Skip to content

Conversation

@TomasMerva
Copy link

@TomasMerva TomasMerva commented Nov 3, 2025

Addressing #23

@TomasMerva TomasMerva marked this pull request as draft November 3, 2025 15:31
@spurnvoj
Copy link
Member

spurnvoj commented Nov 3, 2025

@TomasMerva not sure if you know about this discussion regarding RGBD sensor frames differences gazebosim/gz-sensors#488 and gazebosim/ros_gz#703

@spurnvoj spurnvoj requested a review from Copilot November 5, 2025 14:20
Copy link

Copilot AI left a comment

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 refactors the UAV sensor framework to improve sensor support and unify naming conventions. The changes focus on better handling of different sensor types (RGB cameras, RGBD cameras, depth cameras, and LiDARs) and establishing consistent frame naming patterns.

Key changes include:

  • Refactored SDF to TF publisher to support optical frames for camera sensors
  • Added support for RGBD and depth camera sensor types
  • Unified sensor data structures using enums for better type safety
  • Renamed variables from "link" to "frame" for consistency with TF conventions

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
spawner_enums.py Defines enums for sensor types and topic categorization
sdf_tf_enums.py Defines enums for sensor link data structure keys
sdf_to_tf_publisher.py Refactored to handle optical frames and multiple sensor types
mrs_drone_spawner.py Updated to use enums and handle RGBD/depth cameras
generic_components.sdf.jinja Added macros for RGBD and depth cameras, split 2D/3D LiDAR macros
camera templates Updated to use new camera macros and add optical frames
lidar templates Renamed links to frames and updated to use split macros
uav_ros_gz_bridge_config.yaml.jinja Simplified topic handling using consolidated lists

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


def _get_transform_from_string_pose(self, pose_rpy_str: str) -> np.ndarray:
T_frame = np.eye(4)
if pose_rpy_str is not None and(pose_rpy_str != ""):
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

Missing space after 'and' keyword before the opening parenthesis. Should be and (pose_rpy_str != \"\") for consistency with Python style conventions.

Suggested change
if pose_rpy_str is not None and(pose_rpy_str != ""):
if pose_rpy_str is not None and (pose_rpy_str != ""):

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

fixed

if link_name is None:
return ""
for link in model_xml.findall('.//link'):
if link.attrib["name"] == link_name:
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

Inconsistent attribute access method. Line 143 uses .get(\"name\") while this line uses .attrib[\"name\"]. The .get() method is safer as it returns None if the attribute doesn't exist, while .attrib[] will raise a KeyError. Use link.get(\"name\") for consistency and error handling.

Suggested change
if link.attrib["name"] == link_name:
if link.get("name") == link_name:

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

unified

attached_sensors['cameras'].append(camera)
basic_topic_name = '/' + topic[0].firstChild.data
camera[SensorTopics.IMAGE] = basic_topic_name
camera[SensorTopics.CAMERA_INFO] = basic_topic_name.replace('image', 'camera_info')
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

The .replace('image', 'camera_info') call may produce unexpected results if 'image' appears multiple times in the topic name. Consider using a more specific replacement or reconstructing the topic path to ensure only the intended part is replaced.

Suggested change
camera[SensorTopics.CAMERA_INFO] = basic_topic_name.replace('image', 'camera_info')
camera[SensorTopics.CAMERA_INFO] = basic_topic_name.rsplit('image', 1)[0] + 'camera_info' if 'image' in basic_topic_name else basic_topic_name + '/camera_info'

Copilot uses AI. Check for mistakes.
basic_topic_name = '/' + topic[0].firstChild.data
camera[SensorTopics.DEPTH_IMAGE] = basic_topic_name
camera[SensorTopics.POINTS] = camera[SensorTopics.DEPTH_IMAGE] + '/points'
camera[SensorTopics.CAMERA_INFO] = basic_topic_name.replace('depth_image', 'camera_info')
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

The .replace('depth_image', 'camera_info') call may produce unexpected results if 'depth_image' appears multiple times in the topic name. Consider using a more specific replacement or reconstructing the topic path to ensure only the intended part is replaced.

Suggested change
camera[SensorTopics.CAMERA_INFO] = basic_topic_name.replace('depth_image', 'camera_info')
# Replace only the last segment if it is 'depth_image'
path_parts = basic_topic_name.rstrip('/').split('/')
if path_parts[-1] == 'depth_image':
path_parts[-1] = 'camera_info'
camera_info_topic = '/'.join(path_parts)
if not camera_info_topic.startswith('/'):
camera_info_topic = '/' + camera_info_topic
camera[SensorTopics.CAMERA_INFO] = camera_info_topic
else:
camera[SensorTopics.CAMERA_INFO] = basic_topic_name + '/camera_info'

Copilot uses AI. Check for mistakes.
roll = math.radians(90),
pitch = 0,
yaw = 0)
}}
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

[nitpick] There's an inconsistent blank line pattern. Line 45 has the closing braces followed immediately by the comment on line 46, while in other locations there's typically a blank line. Consider adding a blank line after line 45 for consistency.

Suggested change
}}
}}

Copilot uses AI. Check for mistakes.
gz_type_name: "gz.msgs.CameraInfo"
direction: GZ_TO_ROS
{%- endfor -%}
{% endfor %}
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

[nitpick] Inconsistent Jinja2 template whitespace control. Lines 7 and 15 use {% endfor %} without the - for whitespace control, while line 23 uses {% endfor %}. However, all opening tags use {%-. For consistency, consider using {%- endfor -%} on all three lines.

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

Do not remove -, because doing so will break the generation of the ros_gz_bridge config file.

@TomasMerva
Copy link
Author

This update includes:

  • Updated RGB and depth camera templates with optical frame support to align CameraInfo with sensor data
  • Refactored sdf_to_tf_publisher.py to support optical frames for cameras

RGB-D camera template (pending bug fix):

Screenshot from 2025-11-05 10-05-45

  • The template is prepared and we are successfully publishing point cloud data to ROS. However, users should be aware that the point cloud data must be manually transformed, which is not included in this PR.

@TomasMerva TomasMerva marked this pull request as ready for review November 5, 2025 14:57
@TomasMerva TomasMerva marked this pull request as draft November 6, 2025 10:00
@TomasMerva
Copy link
Author

Update:

  • modified TF-tree
  • refactored sdf_to_tf_publisher so that there is only one static TF publisher regardless of number of drones
  • unified naming for links, sensor plugins, optical frames
  • added README.md for naming conventions and notes regarding adding more sensors in the future

@TomasMerva TomasMerva marked this pull request as ready for review November 6, 2025 13:57
@spurnvoj
Copy link
Member

spurnvoj commented Nov 6, 2025

@TomasMerva, please resolve the conflicts, and I will then perform the final check with Copilot.

{%- set camera_gz_frame_id = spawner_args['name'] + '/' + camera_name + '/color_optical' -%}
```

The resulting camera-related topics will look like as follows:
Copy link
Member

Choose a reason for hiding this comment

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

This is relevant to the gazebo topic; perhaps we could also discuss how it is implemented on the ROS side.

Copy link
Member

Choose a reason for hiding this comment

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

I meant write it in the README :)

@TomasMerva TomasMerva marked this pull request as draft November 6, 2025 16:01
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.

3 participants