Unverified Commit eac029db authored by Mayank Mittal's avatar Mayank Mittal Committed by GitHub

Fixes interval event resets and deprecation of `attach_yaw_only` flag (#2958)

# Description

Just a friendly cleanup. Noticed some issues that crept up in some
previous MR. Still digging through some of the other MRs and
understanding why certain things changed.

## Type of change

- Bug fix (non-breaking change which fixes an issue)

## Checklist

- [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
- [ ] 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: 's avatarMayank Mittal <12863862+Mayankm96@users.noreply.github.com>
Co-authored-by: 's avatarKelly Guo <kellyg@nvidia.com>
Co-authored-by: 's avatarKelly Guo <kellyguo123@hotmail.com>
Co-authored-by: 's avatarooctipus <zhengyuz@nvidia.com>
parent fca3c9ea
......@@ -101,7 +101,7 @@ For this tutorial, the ray-cast based height scanner is attached to the base fra
The pattern of rays is specified using the :attr:`~sensors.RayCasterCfg.pattern` attribute. For
a uniform grid pattern, we specify the pattern using :class:`~sensors.patterns.GridPatternCfg`.
Since we only care about the height information, we do not need to consider the roll and pitch
of the robot. Hence, we set the :attr:`~sensors.RayCasterCfg.attach_yaw_only` to true.
of the robot. Hence, we set the :attr:`~sensors.RayCasterCfg.ray_alignment` to "yaw".
For the height-scanner, you can visualize the points where the rays hit the mesh. This is done
by setting the :attr:`~sensors.SensorBaseCfg.debug_vis` attribute to true.
......
......@@ -63,7 +63,7 @@ class RaycasterSensorSceneCfg(InteractiveSceneCfg):
update_period=1 / 60,
offset=RayCasterCfg.OffsetCfg(pos=(0, 0, 0.5)),
mesh_prim_paths=["/World/Ground"],
attach_yaw_only=True,
ray_alignment="yaw",
pattern_cfg=patterns.LidarPatternCfg(
channels=100, vertical_fov_range=[-90, 90], horizontal_fov_range=[-90, 90], horizontal_res=1.0
),
......
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.41.2"
version = "0.41.3"
# Description
title = "Isaac Lab framework for Robot Learning"
......
This diff is collapsed.
......@@ -39,9 +39,15 @@ class ArticulationCfg(AssetBaseCfg):
class_type: type = Articulation
articulation_root_prim_path: str | None = None
"""Path to the articulation root prim in the USD file.
"""Path to the articulation root prim under the :attr:`prim_path`. Defaults to None, in which case the class
will search for a prim with the USD ArticulationRootAPI on it.
If not provided will search for a prim with the ArticulationRootAPI. Should start with a slash.
This path should be relative to the :attr:`prim_path` of the asset. If the asset is loaded from a USD file,
this path should be relative to the root of the USD stage. For instance, if the loaded USD file at :attr:`prim_path`
contains two articulations, one at `/robot1` and another at `/robot2`, and you want to use `robot2`,
then you should set this to `/robot2`.
The path must start with a slash (`/`).
"""
init_state: InitialStateCfg = InitialStateCfg()
......
......@@ -1144,8 +1144,14 @@ def reset_nodal_state_uniform(
asset.write_nodal_state_to_sim(nodal_state, env_ids=env_ids)
def reset_scene_to_default(env: ManagerBasedEnv, env_ids: torch.Tensor):
"""Reset the scene to the default state specified in the scene configuration."""
def reset_scene_to_default(env: ManagerBasedEnv, env_ids: torch.Tensor, reset_joint_targets: bool = False):
"""Reset the scene to the default state specified in the scene configuration.
If :attr:`reset_joint_targets` is True, the joint position and velocity targets of the articulations are
also reset to their default values. This might be useful for some cases to clear out any previously set targets.
However, this is not the default behavior as based on our experience, it is not always desired to reset
targets to default values, especially when the targets should be handled by action terms and not event terms.
"""
# rigid bodies
for rigid_object in env.scene.rigid_objects.values():
# obtain default and deal with the offset for env origins
......@@ -1166,9 +1172,11 @@ def reset_scene_to_default(env: ManagerBasedEnv, env_ids: torch.Tensor):
default_joint_pos = articulation_asset.data.default_joint_pos[env_ids].clone()
default_joint_vel = articulation_asset.data.default_joint_vel[env_ids].clone()
# set into the physics simulation
articulation_asset.set_joint_position_target(default_joint_pos, env_ids=env_ids)
articulation_asset.set_joint_velocity_target(default_joint_vel, env_ids=env_ids)
articulation_asset.write_joint_state_to_sim(default_joint_pos, default_joint_vel, env_ids=env_ids)
# reset joint targets if required
if reset_joint_targets:
articulation_asset.set_joint_position_target(default_joint_pos, env_ids=env_ids)
articulation_asset.set_joint_velocity_target(default_joint_vel, env_ids=env_ids)
# deformable objects
for deformable_object in env.scene.deformable_objects.values():
# obtain default and set into the physics simulation
......
......@@ -114,12 +114,14 @@ def body_pose_w(
asset_cfg: The SceneEntity associated with this observation.
Returns:
The poses of bodies in articulation [num_env, 7*num_bodies]. Pose order is [x,y,z,qw,qx,qy,qz]. Output is
stacked horizontally per body.
The poses of bodies in articulation [num_env, 7 * num_bodies]. Pose order is [x,y,z,qw,qx,qy,qz].
Output is stacked horizontally per body.
"""
# extract the used quantities (to enable type-hinting)
asset: Articulation = env.scene[asset_cfg.name]
pose = asset.data.body_state_w[:, asset_cfg.body_ids, :7]
# access the body poses in world frame
pose = asset.data.body_pose_w[:, asset_cfg.body_ids, :7]
pose[..., :3] = pose[..., :3] - env.scene.env_origins.unsqueeze(1)
return pose.reshape(env.num_envs, -1)
......@@ -138,7 +140,7 @@ def body_projected_gravity_b(
Returns:
The unit vector direction of gravity projected onto body_name's frame. Gravity projection vector order is
[x,y,z]. Output is stacked horizontally per body.
[x,y,z]. Output is stacked horizontally per body.
"""
# extract the used quantities (to enable type-hinting)
asset: Articulation = env.scene[asset_cfg.name]
......
......@@ -135,7 +135,7 @@ class EventManager(ManagerBase):
# when the episode starts. otherwise the counter will start from the last time
# for that environment
if "interval" in self._mode_term_cfgs:
for index, term_cfg in enumerate(self._mode_class_term_cfgs["interval"]):
for index, term_cfg in enumerate(self._mode_term_cfgs["interval"]):
# sample a new interval and set that as time left
# note: global time events are based on simulation time and not episode time
# so we do not reset them
......
......@@ -19,6 +19,7 @@ from isaacsim.core.simulation_manager import SimulationManager
from pxr import UsdGeom, UsdPhysics
import isaaclab.sim as sim_utils
import isaaclab.utils.math as math_utils
from isaaclab.markers import VisualizationMarkers
from isaaclab.terrains.trimesh.utils import make_plane
from isaaclab.utils.math import convert_quat, quat_apply, quat_apply_yaw
......@@ -117,10 +118,11 @@ class RayCaster(SensorBase):
r = torch.empty(num_envs_ids, 3, device=self.device)
self.drift[env_ids] = r.uniform_(*self.cfg.drift_range)
# resample the height drift
r = torch.empty(num_envs_ids, device=self.device)
self.ray_cast_drift[env_ids, 0] = r.uniform_(*self.cfg.ray_cast_drift_range["x"])
self.ray_cast_drift[env_ids, 1] = r.uniform_(*self.cfg.ray_cast_drift_range["y"])
self.ray_cast_drift[env_ids, 2] = r.uniform_(*self.cfg.ray_cast_drift_range["z"])
range_list = [self.cfg.ray_cast_drift_range.get(key, (0.0, 0.0)) for key in ["x", "y", "z"]]
ranges = torch.tensor(range_list, device=self.device)
self.ray_cast_drift[env_ids] = math_utils.sample_uniform(
ranges[:, 0], ranges[:, 1], (num_envs_ids, 3), device=self.device
)
"""
Implementation.
......@@ -249,6 +251,21 @@ class RayCaster(SensorBase):
self._data.pos_w[env_ids] = pos_w
self._data.quat_w[env_ids] = quat_w
# check if user provided attach_yaw_only flag
if self.cfg.attach_yaw_only is not None:
msg = (
"Raycaster attribute 'attach_yaw_only' property will be deprecated in a future release."
" Please use the parameter 'ray_alignment' instead."
)
# set ray alignment to yaw
if self.cfg.attach_yaw_only:
self.cfg.ray_alignment = "yaw"
msg += " Setting ray_alignment to 'yaw'."
else:
self.cfg.ray_alignment = "base"
msg += " Setting ray_alignment to 'base'."
# log the warning
omni.log.warn(msg)
# ray cast based on the sensor poses
if self.cfg.ray_alignment == "world":
# apply horizontal drift to ray starting position in ray caster frame
......@@ -257,14 +274,7 @@ class RayCaster(SensorBase):
ray_starts_w = self.ray_starts[env_ids]
ray_starts_w += pos_w.unsqueeze(1)
ray_directions_w = self.ray_directions[env_ids]
elif self.cfg.ray_alignment == "yaw" or self.cfg.attach_yaw_only:
if self.cfg.attach_yaw_only:
self.cfg.ray_alignment = "yaw"
omni.log.warn(
"The `attach_yaw_only` property will be deprecated in a future release. Please use"
" `ray_alignment='yaw'` instead."
)
elif self.cfg.ray_alignment == "yaw":
# apply horizontal drift to ray starting position in ray caster frame
pos_w[:, 0:2] += quat_apply_yaw(quat_w, self.ray_cast_drift[env_ids])[:, 0:2]
# only yaw orientation is considered and directions are not rotated
......
......@@ -44,22 +44,32 @@ class RayCasterCfg(SensorBaseCfg):
offset: OffsetCfg = OffsetCfg()
"""The offset pose of the sensor's frame from the sensor's parent frame. Defaults to identity."""
attach_yaw_only: bool = False
attach_yaw_only: bool | None = None
"""Whether the rays' starting positions and directions only track the yaw orientation.
Defaults to None, which doesn't raise a warning of deprecated usage.
This is useful for ray-casting height maps, where only yaw rotation is needed.
.. warning::
.. deprecated:: 2.1.1
This attribute is deprecated and will be removed in the future. Please use
:attr:`ray_alignment` instead.
To get the same behavior as setting this parameter to ``True`` or ``False``, set
:attr:`ray_alignment` to ``"yaw"`` or "base" respectively.
This attribute is deprecated. Use :attr:`~isaaclab.sensors.ray_caster.ray_caster_cfg.ray_alignment` instead.
To get the same behavior, set `ray_alignment` to `"yaw"`.
"""
ray_alignment: Literal["base", "yaw", "world"] = "yaw"
"""Specify in what frame the rays are projected onto the ground. Default is `world`.
* `base` if the rays' starting positions and directions track the full root position and orientation.
* `yaw` if the rays' starting positions and directions track root position and only yaw component of orientation. This is useful for ray-casting height maps.
* `world` if rays' starting positions and directions are always fixed. This is useful in combination with the grid map package.
ray_alignment: Literal["base", "yaw", "world"] = "base"
"""Specify in what frame the rays are projected onto the ground. Default is "base".
The options are:
* ``base`` if the rays' starting positions and directions track the full root position and orientation.
* ``yaw`` if the rays' starting positions and directions track root position and only yaw component of orientation.
This is useful for ray-casting height maps.
* ``world`` if rays' starting positions and directions are always fixed. This is useful in combination with a mapping
package on the robot and querying ray-casts in a global frame.
"""
pattern_cfg: PatternBaseCfg = MISSING
......@@ -75,7 +85,8 @@ class RayCasterCfg(SensorBaseCfg):
"""
ray_cast_drift_range: dict[str, tuple[float, float]] = {"x": (0.0, 0.0), "y": (0.0, 0.0), "z": (0.0, 0.0)}
"""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.
"""The range of drift (in meters) to add to the projected ray points in local projection frame. Defaults to
a dictionary with zero drift for each x, y and z axis.
For floating base robots, this is useful for simulating drift in the robot's pose estimation.
"""
......
......@@ -138,7 +138,7 @@ class AnymalCRoughEnvCfg(AnymalCFlatEnvCfg):
height_scanner = RayCasterCfg(
prim_path="/World/envs/env_.*/Robot/base",
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
attach_yaw_only=True,
ray_alignment="yaw",
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
debug_vis=False,
mesh_prim_paths=["/World/ground"],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment