Skip to content

Commit ea88ba4

Browse files
Mayankm96pascal-rothrenezurbrueggjtigue-bdaiCopilot
authored andcommitted
Addresses docs related issues from MultiMeshRayCaster (isaac-sim#4222)
# Description This MR adds the remaining comments in isaac-sim#3298 ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there --------- Signed-off-by: renezurbruegg <zrene@ethz.ch> Signed-off-by: Mayank Mittal <12863862+Mayankm96@users.noreply.github.com> Signed-off-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com> Signed-off-by: Pascal Roth <57946385+pascal-roth@users.noreply.github.com> Signed-off-by: Kelly Guo <kellyg@nvidia.com> Co-authored-by: Pascal Roth <57946385+pascal-roth@users.noreply.github.com> Co-authored-by: zrene <zrene@ethz.ch> Co-authored-by: Pascal Roth <roth.pascal@outlook.de> Co-authored-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com> Co-authored-by: zrene <rene.zurbruegg@gmail.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
1 parent 5050f87 commit ea88ba4

File tree

17 files changed

+224
-73
lines changed

17 files changed

+224
-73
lines changed
727 KB
Loading

docs/source/api/lab/isaaclab.sensors.rst

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
RayCasterCfg
3232
RayCasterCamera
3333
RayCasterCameraCfg
34+
MultiMeshRayCaster
35+
MultiMeshRayCasterData
36+
MultiMeshRayCasterCfg
37+
MultiMeshRayCasterCamera
38+
MultiMeshRayCasterCameraCfg
3439
Imu
3540
ImuCfg
3641

@@ -151,7 +156,40 @@ Ray-Cast Camera
151156
:members:
152157
:inherited-members:
153158
:show-inheritance:
154-
:exclude-members: __init__, class_type
159+
:exclude-members: __init__, class_type, OffsetCfg
160+
161+
Multi-Mesh Ray-Cast Sensor
162+
--------------------------
163+
164+
.. autoclass:: MultiMeshRayCaster
165+
:members:
166+
:inherited-members:
167+
:show-inheritance:
168+
169+
.. autoclass:: MultiMeshRayCasterData
170+
:members:
171+
:inherited-members:
172+
:exclude-members: __init__
173+
174+
.. autoclass:: MultiMeshRayCasterCfg
175+
:members:
176+
:inherited-members:
177+
:show-inheritance:
178+
:exclude-members: __init__, class_type, OffsetCfg
179+
180+
Multi-Mesh Ray-Cast Camera
181+
--------------------------
182+
183+
.. autoclass:: MultiMeshRayCasterCamera
184+
:members:
185+
:inherited-members:
186+
:show-inheritance:
187+
188+
.. autoclass:: MultiMeshRayCasterCameraCfg
189+
:members:
190+
:inherited-members:
191+
:show-inheritance:
192+
:exclude-members: __init__, class_type, OffsetCfg, RaycastTargetCfg
155193

156194
Inertia Measurement Unit
157195
------------------------

docs/source/overview/showroom.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,3 +358,27 @@ A few quick showroom scripts to run and checkout:
358358
.. image:: ../_static/demos/quadrupeds.jpg
359359
:width: 100%
360360
:alt: Quadrupeds in Isaac Lab
361+
362+
363+
- Spawn a multi-mesh ray caster that uses Warp kernels for raycasting
364+
365+
.. tab-set::
366+
:sync-group: os
367+
368+
.. tab-item:: :icon:`fa-brands fa-linux` Linux
369+
:sync: linux
370+
371+
.. code:: bash
372+
373+
./isaaclab.sh -p scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type objects
374+
375+
.. tab-item:: :icon:`fa-brands fa-windows` Windows
376+
:sync: windows
377+
378+
.. code:: batch
379+
380+
isaaclab.bat -p scripts\demos\sensors\multi_mesh_raycaster.py --num_envs 16 --asset_type objects
381+
382+
.. image:: ../_static/demos/multi-mesh-raycast.jpg
383+
:width: 100%
384+
:alt: Multi-mesh raycaster in Isaac Lab

scripts/demos/sensors/multi_mesh_raycaster.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,34 @@
44
# SPDX-License-Identifier: BSD-3-Clause
55

66

7-
"""Example on using the MultiMesh Raycaster sensor.
7+
"""Example on using the Multi-Mesh Raycaster sensor.
8+
9+
.. code-block:: bash
10+
11+
# with allegro hand
12+
python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type allegro_hand
13+
14+
# with anymal-D bodies
15+
python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type anymal_d
16+
17+
# with random multiple objects
18+
python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type objects
819
9-
Usage:
10-
`python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type <allegro_hand|anymal_d|multi>`
1120
"""
1221

1322
import argparse
1423

1524
from isaaclab.app import AppLauncher
1625

1726
# add argparse arguments
18-
parser = argparse.ArgumentParser(description="Example on using the raycaster sensor.")
27+
parser = argparse.ArgumentParser(description="Example on using the multi-mesh raycaster sensor.")
1928
parser.add_argument("--num_envs", type=int, default=16, help="Number of environments to spawn.")
2029
parser.add_argument(
2130
"--asset_type",
2231
type=str,
2332
default="allegro_hand",
2433
help="Asset type to use.",
25-
choices=["allegro_hand", "anymal_d", "multi"],
34+
choices=["allegro_hand", "anymal_d", "objects"],
2635
)
2736
# append AppLauncher cli args
2837
AppLauncher.add_app_launcher_args(parser)
@@ -89,7 +98,7 @@
8998
elif args_cli.asset_type == "anymal_d":
9099
asset_cfg = ANYMAL_D_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
91100
ray_caster_cfg = MultiMeshRayCasterCfg(
92-
prim_path="{ENV_REGEX_NS}/Robot",
101+
prim_path="{ENV_REGEX_NS}/Robot/base",
93102
update_period=1 / 60,
94103
offset=MultiMeshRayCasterCfg.OffsetCfg(pos=(0, -0.1, 0.3)),
95104
mesh_prim_paths=[
@@ -106,7 +115,7 @@
106115
visualizer_cfg=RAY_CASTER_MARKER_CFG.replace(prim_path="/Visuals/RayCaster"),
107116
)
108117

109-
elif args_cli.asset_type == "multi":
118+
elif args_cli.asset_type == "objects":
110119
asset_cfg = RigidObjectCfg(
111120
prim_path="{ENV_REGEX_NS}/Object",
112121
spawn=sim_utils.MultiAssetSpawnerCfg(
@@ -276,7 +285,7 @@ def main():
276285
scene_cfg = RaycasterSensorSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0, replicate_physics=False)
277286
scene = InteractiveScene(scene_cfg)
278287

279-
if args_cli.asset_type == "multi":
288+
if args_cli.asset_type == "objects":
280289
randomize_shape_color(scene_cfg.asset.prim_path.format(ENV_REGEX_NS="/World/envs/env_.*"))
281290

282291
# Play the simulator

scripts/demos/sensors/multi_mesh_raycaster_camera.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,34 @@
44
# SPDX-License-Identifier: BSD-3-Clause
55

66

7-
"""Example on using the MultiMesh Raycaster Camera sensor.
7+
"""Example on using the Multi-Mesh Raycaster Camera sensor.
8+
9+
.. code-block:: bash
10+
11+
# with allegro hand
12+
python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type allegro_hand
13+
14+
# with anymal-D bodies
15+
python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type anymal_d
16+
17+
# with random multiple objects
18+
python scripts/demos/sensors/multi_mesh_raycaster.py --num_envs 16 --asset_type objects
819
9-
Usage:
10-
`python scripts/demos/sensors/multi_mesh_raycaster_camera.py --num_envs 16 --asset_type <allegro_hand|anymal_d|multi>`
1120
"""
1221

1322
import argparse
1423

1524
from isaaclab.app import AppLauncher
1625

1726
# add argparse arguments
18-
parser = argparse.ArgumentParser(description="Example on using the raycaster sensor.")
27+
parser = argparse.ArgumentParser(description="Example on using the multi-mesh raycaster sensor.")
1928
parser.add_argument("--num_envs", type=int, default=16, help="Number of environments to spawn.")
2029
parser.add_argument(
2130
"--asset_type",
2231
type=str,
2332
default="allegro_hand",
2433
help="Asset type to use.",
25-
choices=["allegro_hand", "anymal_d", "multi"],
34+
choices=["allegro_hand", "anymal_d", "objects"],
2635
)
2736
# append AppLauncher cli args
2837
AppLauncher.add_app_launcher_args(parser)
@@ -94,7 +103,7 @@
94103
elif args_cli.asset_type == "anymal_d":
95104
asset_cfg = ANYMAL_D_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
96105
ray_caster_cfg = MultiMeshRayCasterCameraCfg(
97-
prim_path="{ENV_REGEX_NS}/Robot",
106+
prim_path="{ENV_REGEX_NS}/Robot/base",
98107
update_period=1 / 60,
99108
offset=MultiMeshRayCasterCameraCfg.OffsetCfg(pos=(0, -0.1, 1.5), rot=(0.0, 1.0, 0.0, 0.0)),
100109
mesh_prim_paths=[
@@ -115,7 +124,7 @@
115124
visualizer_cfg=RAY_CASTER_MARKER_CFG.replace(prim_path="/Visuals/RayCaster"),
116125
)
117126

118-
elif args_cli.asset_type == "multi":
127+
elif args_cli.asset_type == "objects":
119128
asset_cfg = RigidObjectCfg(
120129
prim_path="{ENV_REGEX_NS}/Object",
121130
spawn=sim_utils.MultiAssetSpawnerCfg(
@@ -302,7 +311,7 @@ def main():
302311
scene_cfg = RaycasterSensorSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0, replicate_physics=False)
303312
scene = InteractiveScene(scene_cfg)
304313

305-
if args_cli.asset_type == "multi":
314+
if args_cli.asset_type == "objects":
306315
randomize_shape_color(scene_cfg.asset.prim_path.format(ENV_REGEX_NS="/World/envs/env_.*"))
307316

308317
# Play the simulator

source/isaaclab/config/extension.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
# Note: Semantic Versioning is used: https://semver.org/
4-
version = "0.50.3"
4+
version = "0.50.5"
55

66
# Description
77
title = "Isaac Lab framework for Robot Learning"

source/isaaclab/docs/CHANGELOG.rst

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
Changelog
22
---------
33

4+
0.50.5 (2025-12-15)
5+
~~~~~~~~~~~~~~~~~~~
6+
7+
Added
8+
^^^^^
9+
10+
* Added :class:`~isaaclab.sensors.MultiMeshRayCaster` sensor to support tracking of dynamic meshes for ray-casting.
11+
We keep the previous implementation of :class:`~isaaclab.sensors.RayCaster` for backwards compatibility.
12+
* Added :mod:`isaaclab.utils.mesh` sub-module to perform various Trimesh and USD Mesh related operations.
13+
14+
415
0.50.4 (2025-12-15)
516
~~~~~~~~~~~~~~~~~~~
617

718
Added
819
^^^^^
920

10-
* Added :attr:`~isaaclab.sim.PhysxCfg.enable_external_forces_every_iteration` to enable external forces every position iteration.
11-
This can help improve the accuracy of velocity updates. Consider enabling this flag if the velocities generated by the simulation are noisy.
12-
* Added warning when :attr:`~isaaclab.sim.PhysxCfg.enable_external_forces_every_iteration` is set to False and the solver type is TGS.
21+
* Added :attr:`~isaaclab.sim.PhysxCfg.enable_external_forces_every_iteration` to enable external forces every position
22+
iteration. This can help improve the accuracy of velocity updates. Consider enabling this flag if the velocities
23+
generated by the simulation are noisy.
24+
* Added warning when :attr:`~isaaclab.sim.PhysxCfg.enable_external_forces_every_iteration` is set to False and
25+
the solver type is TGS.
1326

1427

1528
0.50.3 (2025-12-11)

source/isaaclab/isaaclab/sensors/ray_caster/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,17 @@
33
#
44
# SPDX-License-Identifier: BSD-3-Clause
55

6-
"""Sub-module for Warp-based ray-cast sensor."""
6+
"""Sub-module for Warp-based ray-cast sensor.
7+
8+
The sub-module contains two implementations of the ray-cast sensor:
9+
10+
- :class:`isaaclab.sensors.ray_caster.RayCaster`: A basic ray-cast sensor that can be used to ray-cast against a single mesh.
11+
- :class:`isaaclab.sensors.ray_caster.MultiMeshRayCaster`: A multi-mesh ray-cast sensor that can be used to ray-cast against
12+
multiple meshes. For these meshes, it tracks their transformations and updates the warp meshes accordingly.
13+
14+
Corresponding camera implementations are also provided for each of the sensor implementations. Internally, they perform
15+
the same ray-casting operations as the sensor implementations, but return the results as images.
16+
"""
717

818
from . import patterns
919
from .multi_mesh_ray_caster import MultiMeshRayCaster

source/isaaclab/isaaclab/sensors/ray_caster/multi_mesh_ray_caster.py

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55

66
from __future__ import annotations
77

8-
"""Multi-mesh ray casting sensor implementation.
9-
10-
This file adds support for ray casting against multiple (possibly regex-selected) mesh targets.
11-
"""
12-
138
import logging
149
import numpy as np
1510
import re
@@ -53,27 +48,30 @@ class MultiMeshRayCaster(RayCaster):
5348
Compared to the default RayCaster, the MultiMeshRayCaster provides additional functionality and flexibility as
5449
an extension of the default RayCaster with the following enhancements:
5550
56-
- Raycasting against multiple target types : Supports primitive shapes (spheres, cubes, ) as well as arbitrary
57-
meshes.
51+
- Raycasting against multiple target types : Supports primitive shapes (spheres, cubes, etc.) as well as arbitrary
52+
meshes.
5853
- Dynamic mesh tracking : Keeps track of specified meshes, enabling raycasting against moving parts
59-
(e.g., robot links, articulated bodies, or dynamic obstacles).
54+
(e.g., robot links, articulated bodies, or dynamic obstacles).
6055
- Memory-efficient caching : Avoids redundant memory usage by reusing mesh data across environments.
6156
62-
Example usage to raycast against the visual meshes of a robot (e.g. anymal):
63-
.. code-block:: python
64-
ray_caster_cfg = MultiMeshRayCasterCfg(
65-
prim_path="{ENV_REGEX_NS}/Robot",
66-
mesh_prim_paths=[
67-
"/World/Ground",
68-
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/LF_.*/visuals"),
69-
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/RF_.*/visuals"),
70-
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/LH_.*/visuals"),
71-
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/RH_.*/visuals"),
72-
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/base/visuals"),
73-
],
74-
ray_alignment="world",
75-
pattern_cfg=patterns.GridPatternCfg(resolution=0.02, size=(2.5, 2.5), direction=(0, 0, -1)),
76-
)
57+
Example usage to raycast against the visual meshes of a robot (e.g. ANYmal):
58+
59+
.. code-block:: python
60+
61+
ray_caster_cfg = MultiMeshRayCasterCfg(
62+
prim_path="{ENV_REGEX_NS}/Robot",
63+
mesh_prim_paths=[
64+
"/World/Ground",
65+
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/LF_.*/visuals"),
66+
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/RF_.*/visuals"),
67+
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/LH_.*/visuals"),
68+
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/RH_.*/visuals"),
69+
MultiMeshRayCasterCfg.RaycastTargetCfg(prim_expr="{ENV_REGEX_NS}/Robot/base/visuals"),
70+
],
71+
ray_alignment="world",
72+
pattern_cfg=patterns.GridPatternCfg(resolution=0.02, size=(2.5, 2.5), direction=(0, 0, -1)),
73+
)
74+
7775
"""
7876

7977
cfg: MultiMeshRayCasterCfg
@@ -84,7 +82,8 @@ class MultiMeshRayCaster(RayCaster):
8482
mesh_views: ClassVar[dict[str, XFormPrim | physx.ArticulationView | physx.RigidBodyView]] = {}
8583
"""A dictionary to store mesh views for raycasting, shared across all instances.
8684
87-
The keys correspond to the prim path for the mesh views, and values are the corresponding view objects."""
85+
The keys correspond to the prim path for the mesh views, and values are the corresponding view objects.
86+
"""
8887

8988
def __init__(self, cfg: MultiMeshRayCasterCfg):
9089
"""Initializes the ray-caster object.
@@ -148,17 +147,20 @@ def _initialize_warp_meshes(self):
148147
"""Parse mesh prim expressions, build (or reuse) Warp meshes, and cache per-env mesh IDs.
149148
150149
High-level steps (per target expression):
151-
1. Resolve matching prims by regex/path expression.
152-
2. Collect supported mesh child prims; merge into a single mesh if configured.
153-
3. Deduplicate identical vertex buffers (exact match) to avoid uploading duplicates to Warp.
154-
4. Partition mesh IDs per environment or mark as globally shared.
155-
5. Optionally create physics views (articulation / rigid body / fallback XForm) and cache local offsets.
150+
151+
1. Resolve matching prims by regex/path expression.
152+
2. Collect supported mesh child prims; merge into a single mesh if configured.
153+
3. Deduplicate identical vertex buffers (exact match) to avoid uploading duplicates to Warp.
154+
4. Partition mesh IDs per environment or mark as globally shared.
155+
5. Optionally create physics views (articulation / rigid body / fallback XForm) and cache local offsets.
156156
157157
Exceptions:
158158
Raises a RuntimeError if:
159-
- No prims match the provided expression.
160-
- No supported mesh prims are found under a matched prim.
161-
- Multiple mesh prims are found but merging is disabled.
159+
160+
- No prims match the provided expression.
161+
- No supported mesh prims are found under a matched prim.
162+
- Multiple mesh prims are found but merging is disabled.
163+
162164
"""
163165
multi_mesh_ids: dict[str, list[list[int]]] = {}
164166
for target_cfg in self._raycast_targets_cfg:
@@ -292,7 +294,7 @@ def _initialize_warp_meshes(self):
292294

293295
if target_cfg.track_mesh_transforms:
294296
MultiMeshRayCaster.mesh_views[target_prim_path], MultiMeshRayCaster.mesh_offsets[target_prim_path] = (
295-
self._get_trackable_prim_view(target_prim_path)
297+
self._obtain_trackable_prim_view(target_prim_path)
296298
)
297299

298300
# throw an error if no meshes are found

source/isaaclab/isaaclab/sensors/ray_caster/multi_mesh_ray_caster_camera_data.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ class MultiMeshRayCasterCameraData(CameraData, RayCasterData):
1818
"""The mesh ids of the image pixels.
1919
2020
Shape is (N, H, W, 1), where N is the number of sensors, H and W are the height and width of the image,
21-
and 1 is the number of mesh ids per pixel."""
21+
and 1 is the number of mesh ids per pixel.
22+
"""

0 commit comments

Comments
 (0)