Skip to content

Commit 82dfef5

Browse files
jsmith-bdaiooctipus
authored andcommitted
Updates to ray caster
* Adds a new ray_alignment parameter - either world, yaw, or base * Fixes drift height sampling
1 parent 75824e8 commit 82dfef5

File tree

13 files changed

+52
-20
lines changed

13 files changed

+52
-20
lines changed

scripts/tutorials/03_envs/create_quadruped_base_env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class MySceneCfg(InteractiveSceneCfg):
105105
height_scanner = RayCasterCfg(
106106
prim_path="{ENV_REGEX_NS}/Robot/base",
107107
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
108-
attach_yaw_only=True,
108+
ray_alignment="yaw",
109109
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
110110
debug_vis=True,
111111
mesh_prim_paths=["/World/ground"],

scripts/tutorials/04_sensors/add_sensors_on_robot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class SensorsSceneCfg(InteractiveSceneCfg):
8484
prim_path="{ENV_REGEX_NS}/Robot/base",
8585
update_period=0.02,
8686
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
87-
attach_yaw_only=True,
87+
ray_alignment="yaw",
8888
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
8989
debug_vis=True,
9090
mesh_prim_paths=["/World/defaultGroundPlane"],

scripts/tutorials/04_sensors/run_ray_caster.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def define_sensor() -> RayCaster:
4949
prim_path="/World/Origin.*/ball",
5050
mesh_prim_paths=["/World/ground"],
5151
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=(2.0, 2.0)),
52-
attach_yaw_only=True,
52+
ray_alignment="yaw",
5353
debug_vis=not args_cli.headless,
5454
)
5555
ray_caster = RayCaster(cfg=ray_caster_cfg)

source/isaaclab/isaaclab/scene/interactive_scene_cfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class MySceneCfg(InteractiveSceneCfg):
5252
height_scanner = RayCasterCfg(
5353
prim_path="{ENV_REGEX_NS}/Robot_1/base",
5454
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
55-
attach_yaw_only=True,
55+
ray_alignment="yaw",
5656
pattern_cfg=GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
5757
debug_vis=True,
5858
mesh_prim_paths=["/World/ground"],

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,13 @@ def reset(self, env_ids: Sequence[int] | None = None):
111111
if env_ids is None:
112112
env_ids = slice(None)
113113
# resample the drift
114-
self.drift[env_ids] = self.drift[env_ids].uniform_(*self.cfg.drift_range)
114+
r = torch.empty(len(env_ids), 3, device=self.device)
115+
self.drift[env_ids] = r.uniform_(*self.cfg.drift_range)
116+
# resample the height drift
117+
r = torch.empty(len(env_ids), device=self.device)
118+
self.ray_cast_drift[env_ids, 0] = r.uniform_(*self.cfg.ray_cast_drift_range["x"])
119+
self.ray_cast_drift[env_ids, 1] = r.uniform_(*self.cfg.ray_cast_drift_range["y"])
120+
self.ray_cast_drift[env_ids, 2] = r.uniform_(*self.cfg.ray_cast_drift_range["z"])
115121

116122
"""
117123
Implementation.
@@ -212,6 +218,7 @@ def _initialize_rays_impl(self):
212218
self.ray_directions = self.ray_directions.repeat(self._view.count, 1, 1)
213219
# prepare drift
214220
self.drift = torch.zeros(self._view.count, 3, device=self.device)
221+
self.ray_cast_drift = torch.zeros(self._view.count, 3, device=self.device)
215222
# fill the data buffer
216223
self._data.pos_w = torch.zeros(self._view.count, 3, device=self._device)
217224
self._data.quat_w = torch.zeros(self._view.count, 4, device=self._device)
@@ -233,23 +240,37 @@ def _update_buffers_impl(self, env_ids: Sequence[int]):
233240
# note: we clone here because we are read-only operations
234241
pos_w = pos_w.clone()
235242
quat_w = quat_w.clone()
236-
# apply drift
243+
# apply drift to ray starting position in world frame
237244
pos_w += self.drift[env_ids]
238245
# store the poses
239246
self._data.pos_w[env_ids] = pos_w
240247
self._data.quat_w[env_ids] = quat_w
241248

242249
# ray cast based on the sensor poses
243-
if self.cfg.attach_yaw_only:
250+
if self.cfg.ray_alignment == "world":
251+
# apply horizontal drift to ray starting position in ray caster frame
252+
pos_w[:, 0:2] += self.ray_cast_drift[env_ids, 0:2]
253+
# no rotation is considered and directions are not rotated
254+
ray_starts_w = self.ray_starts[env_ids]
255+
ray_starts_w += pos_w.unsqueeze(1)
256+
ray_directions_w = self.ray_directions[env_ids]
257+
elif self.cfg.ray_alignment == "yaw":
258+
# apply horizontal drift to ray starting position in ray caster frame
259+
pos_w[:, 0:2] += quat_apply_yaw(quat_w, self.ray_cast_drift[env_ids])[:, 0:2]
244260
# only yaw orientation is considered and directions are not rotated
245261
ray_starts_w = quat_apply_yaw(quat_w.repeat(1, self.num_rays), self.ray_starts[env_ids])
246262
ray_starts_w += pos_w.unsqueeze(1)
247263
ray_directions_w = self.ray_directions[env_ids]
248-
else:
264+
elif self.cfg.ray_alignment == "base":
265+
# apply horizontal drift to ray starting position in ray caster frame
266+
pos_w[:, 0:2] += quat_apply(quat_w, self.ray_cast_drift[env_ids])[:, 0:2]
249267
# full orientation is considered
250268
ray_starts_w = quat_apply(quat_w.repeat(1, self.num_rays), self.ray_starts[env_ids])
251269
ray_starts_w += pos_w.unsqueeze(1)
252270
ray_directions_w = quat_apply(quat_w.repeat(1, self.num_rays), self.ray_directions[env_ids])
271+
else:
272+
raise RuntimeError(f"Unsupported ray_alignment type: {self.cfg.ray_alignment}.")
273+
253274
# ray cast and store the hits
254275
# TODO: Make this work for multiple meshes?
255276
self._data.ray_hits_w[env_ids] = raycast_mesh(
@@ -259,6 +280,9 @@ def _update_buffers_impl(self, env_ids: Sequence[int]):
259280
mesh=self.meshes[self.cfg.mesh_prim_paths[0]],
260281
)[0]
261282

283+
# apply vertical drift to ray starting position in ray caster frame
284+
self._data.ray_hits_w[env_ids, :, 2] += self.ray_cast_drift[env_ids, 2].unsqueeze(-1)
285+
262286
def _set_debug_vis_impl(self, debug_vis: bool):
263287
# set visibility of markers
264288
# note: parent only deals with callbacks. not their visibility

source/isaaclab/isaaclab/sensors/ray_caster/ray_caster_camera_cfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,4 @@ class OffsetCfg:
6060

6161
def __post_init__(self):
6262
# for cameras, this quantity should be False always.
63-
self.attach_yaw_only = False
63+
self.ray_alignment = "base"

source/isaaclab/isaaclab/sensors/ray_caster/ray_caster_cfg.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88

99
from dataclasses import MISSING
10+
from typing import Literal
1011

1112
from isaaclab.markers import VisualizationMarkersCfg
1213
from isaaclab.markers.config import RAY_CASTER_MARKER_CFG
@@ -43,10 +44,11 @@ class OffsetCfg:
4344
offset: OffsetCfg = OffsetCfg()
4445
"""The offset pose of the sensor's frame from the sensor's parent frame. Defaults to identity."""
4546

46-
attach_yaw_only: bool = MISSING
47-
"""Whether the rays' starting positions and directions only track the yaw orientation.
48-
49-
This is useful for ray-casting height maps, where only yaw rotation is needed.
47+
ray_alignment: Literal["base", "yaw", "world"] = "yaw"
48+
"""Specify in what frame the rays are projected onto the ground. Default is `world`.
49+
* `base` if the rays' starting positions and directions track the full root orientation.
50+
* `yaw` if the rays' starting positions and directions only track yaw orientation. This is useful for ray-casting height maps, where only yaw rotation is needed.
51+
* `world` if rays' starting positions and directions are not rotated. This is useful in combination with the grid map package.
5052
"""
5153

5254
pattern_cfg: PatternBaseCfg = MISSING
@@ -56,7 +58,13 @@ class OffsetCfg:
5658
"""Maximum distance (in meters) from the sensor to ray cast to. Defaults to 1e6."""
5759

5860
drift_range: tuple[float, float] = (0.0, 0.0)
59-
"""The range of drift (in meters) to add to the ray starting positions (xyz). Defaults to (0.0, 0.0).
61+
"""The range of drift (in meters) to add to the ray starting positions (xyz) in world frame. Defaults to (0.0, 0.0).
62+
63+
For floating base robots, this is useful for simulating drift in the robot's pose estimation.
64+
"""
65+
66+
ray_cast_drift_range: dict[str, tuple[float, float]] = {"x": (0.0, 0.0), "y": (0.0, 0.0), "z": (0.0, 0.0)}
67+
"""The range of drift (in meters) to add to the projected ray points in local projection frame. Defaults to (0.0, 0.0) for x, y, and z drift.
6068
6169
For floating base robots, this is useful for simulating drift in the robot's pose estimation.
6270
"""

source/isaaclab/test/envs/check_manager_based_env_anymal_locomotion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class MySceneCfg(InteractiveSceneCfg):
9292
height_scanner = RayCasterCfg(
9393
prim_path="{ENV_REGEX_NS}/Robot/base",
9494
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
95-
attach_yaw_only=True,
95+
ray_alignment="yaw",
9696
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
9797
debug_vis=True,
9898
mesh_prim_paths=["/World/ground"],

source/isaaclab/test/markers/check_markers_visibility.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class SensorsSceneCfg(InteractiveSceneCfg):
7070
prim_path="{ENV_REGEX_NS}/Robot/base",
7171
update_period=0.02,
7272
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
73-
attach_yaw_only=True,
73+
ray_alignment="yaw",
7474
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
7575
debug_vis=True,
7676
mesh_prim_paths=["/World/defaultGroundPlane"],

source/isaaclab/test/scene/check_interactive_scene.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class MySceneCfg(InteractiveSceneCfg):
6262
height_scanner = RayCasterCfg(
6363
prim_path="{ENV_REGEX_NS}/Robot_1/base",
6464
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
65-
attach_yaw_only=True,
65+
ray_alignment="yaw",
6666
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
6767
debug_vis=True,
6868
mesh_prim_paths=["/World/ground"],

0 commit comments

Comments
 (0)