Skip to content

Adds RTXLidar #2308

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

Conversation

jtigue-bdai
Copy link
Collaborator

Description

This PR creates a sensor based on the RTX Lidar:

Fixes ##865

Type of change

  • New feature (non-breaking change which adds functionality)

Screenshots

Please attach before and after screenshots of the change if applicable.

Checklist

  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@jtigue-bdai jtigue-bdai self-assigned this Apr 14, 2025
@jtigue-bdai jtigue-bdai mentioned this pull request Apr 14, 2025
6 tasks
@samirchowd
Copy link

Hi @jtigue-bdai, thanks for the great work on this!

I pulled in your branch to work on adding MDP support for the RTX Lidar. Had two questions:

  1. Is there a better name for the data field in rtx_lidar_data.py? The comment was useful but was not initially intuitive. I assume it's referencing this annotator documentation. Maybe it should be called point_cloud?
  2. I can add this this PR or wait until this is merged, am new to open source so not sure what best practice is here haha

Thanks!

@jtigue-bdai
Copy link
Collaborator Author

Hey @samirchowd thanks for that suggestion. "sensor.data.output['data']" is gonna look pretty weird. Yeah I think point_cloud is a good choice.

I can make the point cloud change. As for the mdp terms I'm not sure you can make a pr to this branch since I moved it out of the IsaacSim/isaaclab into a private fork. If you can go for it.

Depending on how much you were thinking of adding, one thing I could do is make an empty diff in the mdp files you were planning to work on and then you can add them to this as a suggestion and I can add you to the contributors list.

If there are a lot of additions then it would be easier as a PR separately.

@samirchowd
Copy link

To limit the scope of the PR, I can raise it in a separate PR once this is merged in that case. I think it'll keep your development and testing simpler.

@jtigue-bdai jtigue-bdai marked this pull request as ready for review April 17, 2025 20:33
@samirchowd
Copy link

Hey @jtigue-bdai, any chance of this getting reviewed soon? Would be more than happy to help out any way 😄 Thanks!

Copy link
Collaborator

@pascal-roth pascal-roth left a comment

Choose a reason for hiding this comment

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

Some high-level comments, generally looks good.

Comment on lines +165 to +169
if not carb_settings_iface.get("/isaaclab/cameras_enabled"):
raise RuntimeError(
"A camera was spawned without the --enable_cameras flag. Please use --enable_cameras to enable"
" rendering."
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't that not be RTXLiDAR in this case?

lidar_prim = stage.GetPrimAtPath(lidar_prim_path)
# Check if prim is a camera
if not lidar_prim.IsA(UsdGeom.Camera):
raise RuntimeError(f"Prim at path '{lidar_prim_path}' is not a Camera.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

That error might be hard to interpret, maybe we add something extra for the LiDAR?

Suggested change
raise RuntimeError(f"Prim at path '{lidar_prim_path}' is not a Camera.")
raise RuntimeError(f"Prim at path '{lidar_prim_path}' is not a Camera which is the base prim class for the RTXLiDAR")

Comment on lines +223 to +239
for name in self.cfg.optional_data_types:
if name == "azimuth":
init_params["outputAzimuth"] = True
elif name == "elevation":
init_params["outputElevation"] = True
elif name == "normal":
init_params["outputNormal"] = True
elif name == "velocity":
init_params["outputVelocity"] = True
elif name == "beamId":
init_params["outputBeamId"] = True
elif name == "emitterId":
init_params["outputEmitterId"] = True
elif name == "materialId":
init_params["outputMaterialId"] = True
elif name == "objectId":
init_params["outputObjectId"] = True
Copy link
Collaborator

Choose a reason for hiding this comment

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

codewise this feels a bit ugly, could we not directly have the config param as a dict:

cfg.optional_data_types = {"outputAzimuth": False, "outputElevation": False, ...}

and then in the notes link to the description which are available. In that way, we are more robust against code changes on the RTX implementation side

Comment on lines +207 to +217
init_params = {
"outputAzimuth": False,
"outputElevation": False,
"outputNormal": False,
"outputVelocity": False,
"outputBeamId": False,
"outputEmitterId": False,
"outputMaterialId": False,
"outputObjectId": False,
"outputTimestamp": True, # always turn on timestamp field
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

then this would be the default of the config (see the comment below)

Comment on lines +327 to +329
# process data for different segmentation types
# Note: Replicator returns raw buffers of dtype int32 for segmentation types
# so we need to convert them to uint8 4 channel images for colorized types
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is that comment here?

def _process_annotator_output(self, name: str, output: Any) -> tuple[torch.tensor, dict | None]:
"""Process the annotator output.

This function is called after the data has been collected from all the cameras.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
This function is called after the data has been collected from all the cameras.
This function is called after the data has been collected from all the RTXLiDARs.

Please refer to the :class:'RtxLidar' and :class:'RtxLidarData' for a list and description of available data types.
"""
data_frame: Literal["world", "sensor"] = "world"
"""The frame to represent the output.data.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"""The frame to represent the output.data.
"""The frame to represent the :attr:`RtxLidar.data` in.

Can we use this parameters for sphinx indexing? Please check again

Copy link
Collaborator

Choose a reason for hiding this comment

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

or even RtxLidarData

Comment on lines +52 to +57
spawn: LidarCfg = MISSING
"""Spawn configuration for the asset.

If None, then the prim is not spawned by the asset. Instead, it is assumed that the
asset is already present in the scene.
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

given the docstring, it would be allowed to be set it to None, so the default should be None, otherwise the configclass check errors out

Suggested change
spawn: LidarCfg = MISSING
"""Spawn configuration for the asset.
If None, then the prim is not spawned by the asset. Instead, it is assumed that the
asset is already present in the scene.
"""
spawn: LidarCfg | None = None
"""Spawn configuration for the asset.
If None, then the prim is not spawned by the asset. Instead, it is assumed that the
asset is already present in the scene.
"""

Comment on lines +12 to +19
RTX_LIDAR_INFO_FIELDS = {
"numChannels": int,
"numEchos": int,
"numReturnsPerScan": int,
"renderProductPath": str,
"ticksPerScan": int,
"transform": torch.Tensor,
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

brainstorming here but would it make sense to have this directly as the default value for the info param below?

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