Skip to content

Commit d02be42

Browse files
committed
Rename stand_scale to stand_height and lift robot base to match
Signed-off-by: Xinjie Yao <xyao@nvidia.com>
1 parent cfdcc94 commit d02be42

3 files changed

Lines changed: 67 additions & 26 deletions

File tree

isaaclab_arena/embodiments/droid/droid.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,16 @@
4343
from isaaclab_arena.utils.pose import Pose
4444
from isaaclab_arena.variations.camera_extrinsics_variation import CameraExtrinsicsVariation
4545

46-
# Default per-axis scale for the base stand.
47-
_DEFAULT_STAND_SCALE: tuple[float, float, float] = (1.2, 1.2, 1.7)
46+
# The base stand's x/y footprint is fixed; only its height (the z-axis scale factor) is
47+
# configurable, so the stand can be made taller or shorter without changing its footprint.
48+
_STAND_FOOTPRINT_SCALE_XY: tuple[float, float] = (1.2, 1.2)
49+
_DEFAULT_STAND_HEIGHT_SCALE: float = 1.7
50+
51+
# The stand's top is pinned at the robot base and it extends downward to the floor, so scaling its
52+
# height moves the floor contact, not the mount. Measured native (scale=1.0) stand height in meters;
53+
# used to lift the robot base by the same amount the stand grows, keeping the stand's bottom on the
54+
# floor while the robot rides higher.
55+
_STAND_UNIT_HEIGHT_M: float = 0.795
4856

4957

5058
class DroidEmbodimentBase(EmbodimentBase, ABC):
@@ -64,11 +72,15 @@ def __init__(
6472
initial_joint_pose: list[float] | None = None,
6573
concatenate_observation_terms: bool = False,
6674
arm_mode: ArmMode | None = None,
67-
stand_scale: tuple[float, float, float] = _DEFAULT_STAND_SCALE,
75+
stand_height: float = _DEFAULT_STAND_HEIGHT_SCALE,
6876
):
6977
super().__init__(enable_cameras, initial_pose, concatenate_observation_terms, arm_mode)
7078
self.scene_config = DroidSceneCfg()
71-
self.scene_config.stand.spawn.scale = stand_scale
79+
self.scene_config.stand.spawn.scale = (*_STAND_FOOTPRINT_SCALE_XY, stand_height)
80+
# Lift the robot base (and stand) so a taller/shorter stand keeps its bottom on the floor.
81+
self._robot_base_z_offset = _STAND_UNIT_HEIGHT_M * (stand_height - _DEFAULT_STAND_HEIGHT_SCALE)
82+
self.scene_config.robot.init_state.pos = self._lift_z(self.scene_config.robot.init_state.pos)
83+
self.scene_config.stand.init_state.pos = self._lift_z(self.scene_config.stand.init_state.pos)
7284
self.action_config = None
7385
self.camera_config = DroidCameraCfg()
7486
self.observation_config = DroidObservationsCfg()
@@ -79,13 +91,19 @@ def __init__(
7991
self.mimic_env = None
8092
self.add_variation(CameraExtrinsicsVariation(camera_name="wrist_camera"))
8193

94+
def _lift_z(self, pos: tuple[float, float, float]) -> tuple[float, float, float]:
95+
"""Return ``pos`` shifted up by the stand-height-driven robot base offset."""
96+
return (pos[0], pos[1], pos[2] + self._robot_base_z_offset)
97+
8298
def _update_scene_cfg_with_robot_initial_pose(self, scene_config: Any, pose: Pose) -> Any:
83-
# We override the default initial pose setting function in order to also set
84-
# the initial pose of the stand.
99+
# We override the default initial pose setting function in order to also set the initial pose
100+
# of the stand, and to re-apply the stand-height lift on top of the requested pose (the base
101+
# implementation overwrites init_state.pos with the raw pose).
85102
scene_config = super()._update_scene_cfg_with_robot_initial_pose(scene_config, pose)
86103
if scene_config is None or not hasattr(scene_config, "robot"):
87104
raise RuntimeError("scene_config must be populated with a `robot` before calling `set_robot_initial_pose`.")
88-
scene_config.stand.init_state.pos = pose.position_xyz
105+
scene_config.robot.init_state.pos = self._lift_z(pose.position_xyz)
106+
scene_config.stand.init_state.pos = self._lift_z(pose.position_xyz)
89107
scene_config.stand.init_state.rot = pose.rotation_xyzw
90108

91109
return scene_config
@@ -114,15 +132,15 @@ def __init__(
114132
initial_joint_pose: list[float] | None = None,
115133
concatenate_observation_terms: bool = False,
116134
arm_mode: ArmMode | None = None,
117-
stand_scale: tuple[float, float, float] = _DEFAULT_STAND_SCALE,
135+
stand_height: float = _DEFAULT_STAND_HEIGHT_SCALE,
118136
):
119137
super().__init__(
120138
enable_cameras,
121139
initial_pose,
122140
initial_joint_pose,
123141
concatenate_observation_terms,
124142
arm_mode,
125-
stand_scale,
143+
stand_height,
126144
)
127145
self.action_config = DroidDifferentialIKActionsCfg()
128146

@@ -141,15 +159,15 @@ def __init__(
141159
initial_joint_pose: list[float] | None = None,
142160
concatenate_observation_terms: bool = False,
143161
arm_mode: ArmMode | None = None,
144-
stand_scale: tuple[float, float, float] = _DEFAULT_STAND_SCALE,
162+
stand_height: float = _DEFAULT_STAND_HEIGHT_SCALE,
145163
):
146164
super().__init__(
147165
enable_cameras,
148166
initial_pose,
149167
initial_joint_pose,
150168
concatenate_observation_terms,
151169
arm_mode,
152-
stand_scale,
170+
stand_height,
153171
)
154172
self.action_config = DroidRelativeJointPositionActionsCfg()
155173

@@ -169,15 +187,15 @@ def __init__(
169187
initial_joint_pose: list[float] | None = None,
170188
concatenate_observation_terms: bool = False,
171189
arm_mode: ArmMode | None = None,
172-
stand_scale: tuple[float, float, float] = _DEFAULT_STAND_SCALE,
190+
stand_height: float = _DEFAULT_STAND_HEIGHT_SCALE,
173191
):
174192
super().__init__(
175193
enable_cameras,
176194
initial_pose,
177195
initial_joint_pose,
178196
concatenate_observation_terms,
179197
arm_mode,
180-
stand_scale,
198+
stand_height,
181199
)
182200
self.action_config = DroidAbsoluteJointPositionActionsCfg()
183201

@@ -252,7 +270,7 @@ class DroidSceneCfg:
252270
usd_path=(
253271
f"{ISAACLAB_NUCLEUS_DIR}/Arena/assets/object_library/srl_robolab_assets/robots/franka_stand_grey.usda"
254272
),
255-
scale=_DEFAULT_STAND_SCALE,
273+
scale=(*_STAND_FOOTPRINT_SCALE_XY, _DEFAULT_STAND_HEIGHT_SCALE),
256274
activate_contact_sensors=False,
257275
),
258276
)

isaaclab_arena/tests/test_droid_stand_scale.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,50 @@
88
from isaaclab_arena.tests.utils.subprocess import run_simulation_app_function
99

1010
_DEFAULT_STAND_SCALE = (1.2, 1.2, 1.7)
11-
_CUSTOM_STAND_SCALE = (1.5, 1.5, 2.0)
11+
_CUSTOM_STAND_HEIGHT = 2.0
12+
_EXPECTED_CUSTOM_SCALE = (1.2, 1.2, 2.0)
1213

1314

1415
def _test_droid_stand_scale(simulation_app) -> bool:
15-
"""Check that ``stand_scale`` threads through to the stand spawn without touching the robot."""
16+
"""Check ``stand_height`` sets only the stand z-scale and lifts the robot base to match."""
1617

1718
from isaaclab_arena.assets.registries import AssetRegistry
18-
from isaaclab_arena.embodiments.droid.droid import DroidAbsoluteJointPositionEmbodiment
19+
from isaaclab_arena.embodiments.droid.droid import (
20+
_DEFAULT_STAND_HEIGHT_SCALE,
21+
_STAND_UNIT_HEIGHT_M,
22+
DroidAbsoluteJointPositionEmbodiment,
23+
)
24+
from isaaclab_arena.utils.pose import Pose
25+
26+
expected_offset = _STAND_UNIT_HEIGHT_M * (_CUSTOM_STAND_HEIGHT - _DEFAULT_STAND_HEIGHT_SCALE)
1927

2028
try:
21-
# The default is applied when the caller does not set stand_scale.
29+
# The default leaves the stand at its nominal scale and the robot base at z=0.
2230
default_emb = DroidAbsoluteJointPositionEmbodiment()
2331
assert tuple(default_emb.scene_config.stand.spawn.scale) == _DEFAULT_STAND_SCALE
32+
assert default_emb.scene_config.robot.init_state.pos[2] == 0.0
2433

25-
# An override reaches the stand spawn config, leaving the robot articulation at native scale.
26-
custom_emb = DroidAbsoluteJointPositionEmbodiment(stand_scale=_CUSTOM_STAND_SCALE)
27-
assert tuple(custom_emb.scene_config.stand.spawn.scale) == _CUSTOM_STAND_SCALE
34+
# An override changes only the z-scale (x/y footprint and robot mesh untouched)...
35+
custom_emb = DroidAbsoluteJointPositionEmbodiment(stand_height=_CUSTOM_STAND_HEIGHT)
36+
assert tuple(custom_emb.scene_config.stand.spawn.scale) == _EXPECTED_CUSTOM_SCALE
2837
assert custom_emb.scene_config.robot.spawn.scale in (None, (1.0, 1.0, 1.0))
2938

30-
# The YAML-spec path instantiates the embodiment via asset_class(**params); stand_scale
31-
# arriving as a list (as it would from YAML) applies just the same.
32-
registry_emb = AssetRegistry().get_asset_by_name("droid_abs_joint_pos")(stand_scale=list(_CUSTOM_STAND_SCALE))
33-
assert tuple(registry_emb.scene_config.stand.spawn.scale) == _CUSTOM_STAND_SCALE
39+
# ...and lifts the robot base and stand together so the stand's floor contact is preserved.
40+
assert abs(custom_emb.scene_config.robot.init_state.pos[2] - expected_offset) < 1e-6
41+
assert abs(custom_emb.scene_config.stand.init_state.pos[2] - expected_offset) < 1e-6
42+
43+
# The lift is re-applied on top of an explicit initial_pose (which the base class would
44+
# otherwise overwrite): the requested z plus the stand-height offset.
45+
posed_emb = DroidAbsoluteJointPositionEmbodiment(stand_height=_CUSTOM_STAND_HEIGHT)
46+
posed_emb.set_initial_pose(Pose(position_xyz=(0.3, 0.0, 0.5), rotation_xyzw=(0.0, 0.0, 0.0, 1.0)))
47+
scene_cfg = posed_emb.get_scene_cfg()
48+
assert abs(scene_cfg.robot.init_state.pos[2] - (0.5 + expected_offset)) < 1e-6
49+
assert abs(scene_cfg.stand.init_state.pos[2] - (0.5 + expected_offset)) < 1e-6
50+
51+
# The YAML-spec path instantiates the embodiment via asset_class(**params); a scalar
52+
# stand_height from YAML applies just the same.
53+
registry_emb = AssetRegistry().get_asset_by_name("droid_abs_joint_pos")(stand_height=_CUSTOM_STAND_HEIGHT)
54+
assert tuple(registry_emb.scene_config.stand.spawn.scale) == _EXPECTED_CUSTOM_SCALE
3455

3556
except Exception as e:
3657
print(f"Error: {e}")

isaaclab_arena_environments/robolab/bagel_plate_banana_bowl_linked.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ embodiment:
88
id: droid
99
registry_name: droid_abs_joint_pos
1010
params:
11-
stand_scale: [1.2, 1.2, 1.7]
11+
# Height (z-axis scale factor) of the robot base stand. The robot base is lifted to match so the
12+
# stand stays on the floor; footprint and robot size are unaffected.
13+
stand_height: 1.7
1214
background:
1315
id: maple_table_robolab
1416
registry_name: maple_table_robolab

0 commit comments

Comments
 (0)