Skip to content

Commit 21dbb17

Browse files
committed
Apply dexterous lump review updates to the Direct layer
Fold the reviewed lump changes that belong to this part's content: - Share per-family sim settings through task-cfg base mixins. - Deduplicate backend scene presets via inner-class defaults and nest single-consumer helper cfgs in the shadow-hand Direct cfg. - Compute the orientation error through isaaclab.utils.math.quat_error_magnitude and delete the local direct_reorient_rotation_distance primitive. - Rename direct_reorient_reward to reorient_reward: shared symbols carry no paradigm prefix. Source commits on the lump branch: 2c22af0, 792e400, 42675b6, c6140f9, 173e9dc.
1 parent 6e8a63e commit 21dbb17

7 files changed

Lines changed: 61 additions & 66 deletions

File tree

source/isaaclab_tasks/changelog.d/task-cleanup-dex-part03.minor.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ Fixed
88
^^^^^
99

1010
* Fixed dexterous hand resets that could initialize joints below their lower
11-
position limits.
11+
position limits. Reset joint positions now sample uniformly across the full
12+
joint range; previously the distribution was biased toward the lower half of
13+
the range.

source/isaaclab_tasks/isaaclab_tasks/core/reorient/config/allegro_hand/allegro_hand_direct_env_cfg.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,26 @@ class PhysicsCfg(PresetCfg):
119119
)
120120
},
121121
)
122+
123+
122124
# Simulation settings shared by the Direct and manager variants (configclass
123125
# deep-copies these defaults per cfg instance). The solver-common base material
124126
# is sufficient: only friction values are set, so no PhysX-specific
125127
# ``physxMaterial`` attributes are authored.
126-
ALLEGRO_SIM_CFG = SimulationCfg(
127-
dt=1 / 120,
128-
render_interval=4,
129-
physics_material=RigidBodyMaterialBaseCfg(static_friction=1.0, dynamic_friction=1.0),
130-
physics=PhysicsCfg(),
131-
)
128+
@configclass
129+
class AllegroHandTaskCfgBase:
130+
"""Shared Allegro task settings inherited by both the Direct and the manager configurations."""
131+
132+
sim: SimulationCfg = SimulationCfg(
133+
dt=1 / 120,
134+
render_interval=4,
135+
physics_material=RigidBodyMaterialBaseCfg(static_friction=1.0, dynamic_friction=1.0),
136+
physics=PhysicsCfg(),
137+
)
132138

133139

134140
@configclass
135-
class AllegroHandEnvCfg(DirectRLEnvCfg):
141+
class AllegroHandEnvCfg(AllegroHandTaskCfgBase, DirectRLEnvCfg):
136142
# env
137143
decimation = 4
138144
episode_length_s = 10.0
@@ -141,8 +147,6 @@ class AllegroHandEnvCfg(DirectRLEnvCfg):
141147
state_space = 0
142148
asymmetric_obs = False
143149
obs_type = "full"
144-
# simulation
145-
sim: SimulationCfg = ALLEGRO_SIM_CFG
146150
# robot
147151
robot_cfg: ArticulationCfg = ROBOT_CFG
148152

source/isaaclab_tasks/isaaclab_tasks/core/reorient/config/shadow_hand/shadow_hand_env_cfg.py

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -274,18 +274,16 @@ class ShadowHandSceneCfg(PresetCfg):
274274
Newton does not support Fabric cloning, so ``clone_in_fabric`` must be ``False``.
275275
"""
276276

277-
physx: InteractiveSceneCfg = InteractiveSceneCfg(
278-
num_envs=8192,
279-
env_spacing=0.75,
280-
replicate_physics=True,
281-
clone_in_fabric=True,
282-
)
283-
newton_mjwarp: InteractiveSceneCfg = InteractiveSceneCfg(
284-
num_envs=8192,
285-
env_spacing=0.75,
286-
replicate_physics=True,
287-
clone_in_fabric=False,
288-
)
277+
@configclass
278+
class SceneCfg(InteractiveSceneCfg):
279+
"""Shadow Direct scene defaults; backend presets only set ``clone_in_fabric``."""
280+
281+
num_envs = 8192
282+
env_spacing = 0.75
283+
replicate_physics = True
284+
285+
physx: InteractiveSceneCfg = SceneCfg(clone_in_fabric=True)
286+
newton_mjwarp: InteractiveSceneCfg = SceneCfg(clone_in_fabric=False)
289287
default: InteractiveSceneCfg = physx
290288
newton_kamino = newton_mjwarp
291289

@@ -328,26 +326,38 @@ class PhysicsCfg(PresetCfg):
328326
)
329327
},
330328
)
329+
330+
331331
# Simulation settings shared by the Direct and manager variants (configclass
332332
# deep-copies these defaults per cfg instance). The solver-common base material
333333
# is sufficient: only friction values are set, so no PhysX-specific
334334
# ``physxMaterial`` attributes are authored.
335-
SHADOW_SIM_CFG = SimulationCfg(
336-
dt=1 / 120,
337-
render_interval=2,
338-
physics_material=RigidBodyMaterialBaseCfg(static_friction=1.0, dynamic_friction=1.0),
339-
physics=PhysicsCfg(),
340-
)
341-
OPENAI_SIM_CFG = SimulationCfg(
342-
dt=1 / 60,
343-
render_interval=3,
344-
physics_material=RigidBodyMaterialBaseCfg(static_friction=1.0, dynamic_friction=1.0),
345-
physics=PhysicsCfg(),
346-
)
335+
@configclass
336+
class ShadowHandTaskCfgBase:
337+
"""Shared Shadow task settings inherited by both the Direct and the manager configurations."""
338+
339+
sim: SimulationCfg = SimulationCfg(
340+
dt=1 / 120,
341+
render_interval=2,
342+
physics_material=RigidBodyMaterialBaseCfg(static_friction=1.0, dynamic_friction=1.0),
343+
physics=PhysicsCfg(),
344+
)
345+
346+
347+
@configclass
348+
class ShadowHandOpenAITaskCfgBase(ShadowHandTaskCfgBase):
349+
"""Shared OpenAI-variant task settings (60 Hz stepping) for both paradigms."""
350+
351+
sim: SimulationCfg = SimulationCfg(
352+
dt=1 / 60,
353+
render_interval=3,
354+
physics_material=RigidBodyMaterialBaseCfg(static_friction=1.0, dynamic_friction=1.0),
355+
physics=PhysicsCfg(),
356+
)
347357

348358

349359
@configclass
350-
class ShadowHandEnvCfg(DirectRLEnvCfg):
360+
class ShadowHandEnvCfg(ShadowHandTaskCfgBase, DirectRLEnvCfg):
351361
# env
352362
decimation = 2
353363
episode_length_s = 10.0
@@ -357,8 +367,6 @@ class ShadowHandEnvCfg(DirectRLEnvCfg):
357367
asymmetric_obs = False
358368
obs_type = "full"
359369

360-
# simulation
361-
sim: SimulationCfg = SHADOW_SIM_CFG
362370
# robot
363371
robot_cfg: ShadowHandRobotCfg = ROBOT_CFG
364372
actuated_joint_names = SHADOW_ACTUATED_JOINT_NAMES
@@ -405,7 +413,7 @@ class ShadowHandEnvCfg(DirectRLEnvCfg):
405413

406414

407415
@configclass
408-
class ShadowHandOpenAIEnvCfg(ShadowHandEnvCfg):
416+
class ShadowHandOpenAIEnvCfg(ShadowHandOpenAITaskCfgBase, ShadowHandEnvCfg):
409417
# env
410418
decimation = 3
411419
episode_length_s = 8.0
@@ -414,8 +422,6 @@ class ShadowHandOpenAIEnvCfg(ShadowHandEnvCfg):
414422
state_space = 187
415423
asymmetric_obs = True
416424
obs_type = "openai"
417-
# simulation
418-
sim: SimulationCfg = OPENAI_SIM_CFG
419425
# reset
420426
reset_position_noise = 0.01 # range of position at reset
421427
reset_dof_pos_noise = 0.2 # range of dof pos at reset

source/isaaclab_tasks/isaaclab_tasks/core/reorient/mdp/__init__.pyi

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ __all__ = [
1010
"success_bonus",
1111
"track_orientation_inv_l2",
1212
"track_pos_l2",
13-
"direct_reorient_rotation_distance",
1413
"evaluate_reorient_success",
15-
"direct_reorient_reward",
14+
"reorient_reward",
1615
"max_consecutive_success",
1716
"object_away_from_goal",
1817
"object_away_from_robot",
@@ -21,8 +20,7 @@ __all__ = [
2120
from .commands import ReorientCommand, ReorientCommandCfg
2221
from .observations import goal_quat_diff
2322
from .rewards import (
24-
direct_reorient_reward,
25-
direct_reorient_rotation_distance,
23+
reorient_reward,
2624
evaluate_reorient_success,
2725
success_bonus,
2826
track_orientation_inv_l2,

source/isaaclab_tasks/isaaclab_tasks/core/reorient/mdp/rewards.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,6 @@ def track_orientation_inv_l2(
100100
return 1.0 / (dtheta + rot_eps)
101101

102102

103-
@torch.jit.script
104-
def direct_reorient_rotation_distance(object_quat: torch.Tensor, target_quat: torch.Tensor) -> torch.Tensor:
105-
"""Compute the Direct reorientation orientation distance [rad].
106-
107-
Args:
108-
object_quat: Object ``(x, y, z, w)`` orientations.
109-
target_quat: Target ``(x, y, z, w)`` orientations.
110-
111-
Returns:
112-
Per-environment orientation distances [rad], in ``[0, pi]``.
113-
"""
114-
quat_diff = math_utils.quat_mul(object_quat, math_utils.quat_conjugate(target_quat))
115-
return 2.0 * torch.asin(torch.clamp(torch.linalg.norm(quat_diff[:, 0:3], ord=2, dim=-1), max=1.0))
116-
117-
118103
@torch.jit.script
119104
def evaluate_reorient_success(
120105
object_quat: torch.Tensor, target_quat: torch.Tensor, success_tolerance: float
@@ -133,12 +118,12 @@ def evaluate_reorient_success(
133118
Returns:
134119
Per-environment success flags and orientation errors [rad].
135120
"""
136-
orientation_error = direct_reorient_rotation_distance(object_quat, target_quat)
121+
orientation_error = math_utils.quat_error_magnitude(object_quat, target_quat)
137122
return orientation_error <= success_tolerance, orientation_error
138123

139124

140125
@torch.jit.script
141-
def direct_reorient_reward(
126+
def reorient_reward(
142127
reset_buf: torch.Tensor,
143128
reset_goal_buf: torch.Tensor,
144129
successes: torch.Tensor,

source/isaaclab_tasks/isaaclab_tasks/core/reorient/reorient_direct_env.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from isaaclab.sim.spawners.from_files import GroundPlaneCfg, spawn_ground_plane
2121
from isaaclab.utils.math import quat_conjugate, quat_mul, sample_uniform, saturate, scale_transform, unscale_transform
2222

23-
from isaaclab_tasks.core.reorient.mdp.rewards import direct_reorient_reward, evaluate_reorient_success
23+
from isaaclab_tasks.core.reorient.mdp.rewards import evaluate_reorient_success, reorient_reward
2424
from isaaclab_tasks.core.reorient.reorient_task_base import GOAL_MARKER_POSITION, IN_HAND_POS_OFFSET
2525
from isaaclab_tasks.core.utils import EpisodeErrorRecorder, randomize_rotation, sample_joint_positions_within_limits
2626

@@ -185,7 +185,7 @@ def _get_rewards(self) -> torch.Tensor:
185185
# the success flags and orientation errors were computed this step by
186186
# :meth:`_get_dones`; the recorder and the reward reuse them
187187
self._orientation_error.update(self._orientation_error_buf)
188-
total_reward, goal_resets, successes, consecutive_successes = direct_reorient_reward(
188+
total_reward, goal_resets, successes, consecutive_successes = reorient_reward(
189189
self.reset_buf,
190190
self.reset_goal_buf,
191191
self.successes,

source/isaaclab_tasks/test/core/test_dexterous_task_math.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import isaaclab.utils.math as math_utils
1919

20-
from isaaclab_tasks.core.reorient.mdp.rewards import direct_reorient_rotation_distance, evaluate_reorient_success
20+
from isaaclab_tasks.core.reorient.mdp.rewards import evaluate_reorient_success
2121

2222
_DEVICES = ["cpu"] + (["cuda:0"] if torch.cuda.is_available() else [])
2323

@@ -35,8 +35,8 @@ def _quats(device, *quats):
3535

3636
@pytest.mark.parametrize("device", _DEVICES)
3737
def test_rotation_distance_recovers_known_angles(device):
38-
distance = direct_reorient_rotation_distance(
39-
_quats(device, _IDENTITY, _ROT90_X, _ROT180_Z), _quats(device, _IDENTITY, _IDENTITY, _IDENTITY)
38+
_, distance = evaluate_reorient_success(
39+
_quats(device, _IDENTITY, _ROT90_X, _ROT180_Z), _quats(device, _IDENTITY, _IDENTITY, _IDENTITY), 0.4
4040
)
4141
torch.testing.assert_close(distance, torch.tensor([0.0, math.pi / 2, math.pi], device=device), atol=1e-5, rtol=0.0)
4242

0 commit comments

Comments
 (0)