Skip to content

Commit 0f23a6a

Browse files
committed
fix typo
1 parent 327c37d commit 0f23a6a

File tree

7 files changed

+115
-29
lines changed

7 files changed

+115
-29
lines changed

source/isaaclab/docs/CHANGELOG.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Added
1616

1717
* Added optional random prototype selection during environment cloning in
1818
:class:`~isaaclab.scene.interactive_scene.InteractiveScene` via
19-
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogenous_cloning`.
19+
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogeneous_cloning`.
2020
Defaults to ``True``; round-robin (modulo) mapping remains available by setting it to ``False``.
2121

2222
* Added flexible per-object cloning path in
@@ -30,7 +30,7 @@ Deprecated
3030

3131
* Deprecated :attr:`~isaaclab.sim.spawners.wrappers.MultiAssetSpawnerCfg.random_choice` and
3232
:attr:`~isaaclab.sim.spawners.wrappers.MultiUsdFileCfg.random_choice`. Use
33-
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogenous_cloning` to control whether
33+
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogeneous_cloning` to control whether
3434
assets are selected randomly (``True``) or via round-robin (``False``) across environments.
3535

3636

source/isaaclab/isaaclab/scene/cloner.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class TemplateCloneCfg:
2828
1. Discover prototypes under :attr:`template_root` whose base name starts with
2929
:attr:`template_prototype_identifier` (for example, ``proto_asset_0``, ``proto_asset_1``).
3030
2. Build a per-prototype mapping to environments according to
31-
:attr:`random_heterogenous_cloning` (random) or modulo assignment (deterministic).
31+
:attr:`random_heterogeneous_cloning` (random) or modulo assignment (deterministic).
3232
3. Stamp the selected prototypes to destinations derived from :attr:`clone_regex`.
3333
4. Optionally perform PhysX replication for the same mapping.
3434
@@ -48,7 +48,7 @@ class TemplateCloneCfg:
4848
clone_regex="/World/envs/env_.*",
4949
clone_usd=True,
5050
clone_physx=True,
51-
random_heterogenous_cloning=False, # use round-robin mapping
51+
random_heterogeneous_cloning=False, # use round-robin mapping
5252
device="cpu",
5353
)
5454
@@ -74,7 +74,7 @@ class TemplateCloneCfg:
7474
clone_physx: bool = True
7575
"""Enable PhysX replication for the same mapping to speed up physics setup."""
7676

77-
random_heterogenous_cloning: bool = True
77+
random_heterogeneous_cloning: bool = True
7878
"""Randomly assign prototypes to environments. Default is True.
7979
8080
When enabled, each environment selects a prototype at random from the available prototypes
@@ -119,7 +119,7 @@ def clone_from_template(stage: Usd.Stage, num_clones: int, template_clone_cfg: T
119119
protos = [proto for proto in protos if proto.split("/")[-1].startswith(prototype_id)]
120120
m = torch.zeros((len(protos), num_clones), dtype=torch.bool, device=cfg.device)
121121
# Optionally select prototypes randomly per environment; else round-robin by modulo
122-
if cfg.random_heterogenous_cloning:
122+
if cfg.random_heterogeneous_cloning:
123123
rand_idx = torch.randint(len(protos), (num_clones,), device=cfg.device)
124124
m[rand_idx, world_indices] = True
125125
else:

source/isaaclab/isaaclab/scene/interactive_scene.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def __init__(self, cfg: InteractiveSceneCfg):
138138

139139
self.cloner_cfg = cloner.TemplateCloneCfg(
140140
clone_regex=self.env_regex_ns,
141-
random_heterogenous_cloning=self.cfg.random_heterogenous_cloning,
141+
random_heterogeneous_cloning=self.cfg.random_heterogeneous_cloning,
142142
clone_in_fabric=self.cfg.clone_in_fabric,
143143
device=self.device,
144144
)

source/isaaclab/isaaclab/scene/interactive_scene_cfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class MySceneCfg(InteractiveSceneCfg):
125125
126126
"""
127127

128-
random_heterogenous_cloning: bool = True
128+
random_heterogeneous_cloning: bool = True
129129
"""Randomly assign prototypes to environments. Default is True.
130130
131131
When enabled, each environment selects a prototype at random from the available

source/isaaclab/isaaclab/sim/simulation_context.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def __init__(self, cfg: SimulationCfg | None = None):
246246
)
247247
else:
248248
self._app_control_on_stop_handle = None
249-
self._disable_app_control_on_stop_handle = False
249+
self._disable_app_control_on_stop_handle = True
250250

251251
# flatten out the simulation dictionary
252252
sim_params = self.cfg.to_dict()
@@ -1124,6 +1124,7 @@ def build_simulation_context(
11241124
sim.logger.error(traceback.format_exc())
11251125
raise
11261126
finally:
1127+
sim._disable_app_control_on_stop_handle = True
11271128
if not sim.has_gui():
11281129
# Stop simulation only if we aren't rendering otherwise the app will hang indefinitely
11291130
sim.stop()

source/isaaclab/isaaclab/sim/spawners/wrappers/wrappers_cfg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class MultiAssetSpawnerCfg(RigidObjectSpawnerCfg, DeformableObjectSpawnerCfg):
4343
.. warning::
4444
4545
This attribute is deprecated. Use
46-
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogenous_cloning` instead.
46+
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogeneous_cloning` instead.
4747
"""
4848

4949

@@ -73,5 +73,5 @@ class MultiUsdFileCfg(UsdFileCfg):
7373
.. warning::
7474
7575
This attribute is deprecated. Use
76-
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogenous_cloning` instead.
76+
:attr:`~isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogeneous_cloning` instead.
7777
"""

source/isaaclab/test/sim/test_cloner.py

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,19 @@
1818

1919
import isaacsim.core.utils.prims as prim_utils
2020
import isaacsim.core.utils.stage as stage_utils
21+
from isaacsim.core.simulation_manager import SimulationManager
2122
import pytest
22-
from isaacsim.core.api.simulation_context import SimulationContext
23+
from isaaclab.sim import build_simulation_context
2324
from pxr import UsdGeom
24-
2525
import isaaclab.sim as sim_utils
2626
from isaaclab.scene.cloner import TemplateCloneCfg, clone_from_template, physx_replicate, usd_replicate
2727

2828

29-
@pytest.fixture
30-
def sim():
31-
"""Create a fresh simulation context and stage for each test."""
32-
stage_utils.create_new_stage()
33-
dt = 0.01
34-
sim = SimulationContext(physics_dt=dt, rendering_dt=dt, backend="numpy")
35-
stage_utils.update_stage()
36-
yield sim
37-
sim.stop()
38-
sim.clear()
39-
sim.clear_all_callbacks()
40-
sim.clear_instance()
29+
@pytest.fixture(params=["cpu", "cuda"])
30+
def sim(request):
31+
"""Provide a fresh simulation context for each test on CPU and CUDA."""
32+
with build_simulation_context(device=request.param, dt=0.01, add_lighting=False) as sim:
33+
yield sim
4134

4235

4336
def test_usd_replicate_with_positions_and_mask(sim):
@@ -137,13 +130,11 @@ def test_clone_from_template(sim):
137130
Steps:
138131
- Create /World/template and /World/envs/env_0..env_31
139132
- Spawn three prototypes under /World/template/Object/proto_asset_.*
140-
- Clone using TemplateCloneCfg with random_heterogenous_cloning=False (modulo mapping)
133+
- Clone using TemplateCloneCfg with random_heterogeneous_cloning=False (modulo mapping)
141134
- Verify modulo placement exists; then call sim.reset(), and create PhysX view
142135
"""
143-
from isaacsim.core.simulation_manager import SimulationManager
144-
145136
num_clones = 32
146-
clone_cfg = TemplateCloneCfg(random_heterogenous_cloning=False, device="cpu")
137+
clone_cfg = TemplateCloneCfg(random_heterogeneous_cloning=False, device=sim.cfg.device)
147138
prim_utils.create_prim(clone_cfg.template_root, "Xform")
148139
prim_utils.create_prim("/World/envs", "Xform")
149140
for i in range(num_clones):
@@ -197,3 +188,97 @@ def test_clone_from_template(sim):
197188
object_view_regex = f"{clone_cfg.clone_regex}/Object".replace(".*", "*")
198189
physx_view = SimulationManager.get_physics_sim_view().create_rigid_body_view(object_view_regex)
199190
assert physx_view._backend is not None
191+
192+
193+
def _run_colocation_collision_filter(sim, asset_cfg, expected_types, assert_count=False):
194+
"""Shared harness for colocated collision filter checks across devices."""
195+
num_clones = 32
196+
clone_cfg = TemplateCloneCfg(random_heterogeneous_cloning=False, device=sim.cfg.device)
197+
prim_utils.create_prim(clone_cfg.template_root, "Xform")
198+
prim_utils.create_prim("/World/envs", "Xform")
199+
for i in range(num_clones):
200+
prim_utils.create_prim(f"/World/envs/env_{i}", "Xform", translation=(0, 0, 0))
201+
202+
prim = asset_cfg.func(f"{clone_cfg.template_root}/Object/{clone_cfg.template_prototype_identifier}_.*", asset_cfg)
203+
assert prim.IsValid()
204+
205+
stage = stage_utils.get_current_stage()
206+
clone_from_template(stage, num_clones=num_clones, template_clone_cfg=clone_cfg)
207+
208+
primitive_prims = sim_utils.get_all_matching_child_prims(
209+
"/World/envs", predicate=lambda prim: prim.GetTypeName() in expected_types
210+
)
211+
212+
if assert_count:
213+
assert len(primitive_prims) == num_clones
214+
215+
for i, primitive_prim in enumerate(primitive_prims):
216+
assert primitive_prim.GetTypeName() == expected_types[i % len(expected_types)]
217+
218+
sim.reset()
219+
object_view_regex = f"{clone_cfg.clone_regex}/Object".replace(".*", "*")
220+
physx_view = SimulationManager.get_physics_sim_view().create_rigid_body_view(object_view_regex)
221+
for _ in range(100):
222+
sim.step()
223+
distance_from_origin = torch.norm(physx_view.get_transforms()[:, :2], dim=-1)
224+
assert torch.all(distance_from_origin < 0.1)
225+
226+
227+
def test_colocation_collision_filter_homogeneous(sim):
228+
"""Verify colocated clones of a single prototype stay stable after PhysX cloning.
229+
230+
All clones are spawned at exactly the same pose; if the collision filter is wrong the pile
231+
explodes on reset. This asserts the filter keeps the colocated objects stable while stepping
232+
across CPU and CUDA backends.
233+
"""
234+
_run_colocation_collision_filter(
235+
sim,
236+
sim_utils.ConeCfg(
237+
radius=0.3,
238+
height=0.6,
239+
visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0), metallic=0.2),
240+
mass_props=sim_utils.MassPropertiesCfg(mass=100.0),
241+
rigid_props=sim_utils.RigidBodyPropertiesCfg(
242+
solver_position_iteration_count=4, solver_velocity_iteration_count=0
243+
),
244+
collision_props=sim_utils.CollisionPropertiesCfg(),
245+
),
246+
expected_types=["Cone"],
247+
assert_count=True,
248+
)
249+
250+
251+
def test_colocation_collision_filter_heterogeneous(sim):
252+
"""Verify colocated clones of multiple prototypes retain modulo ordering and remain stable.
253+
254+
The cone, cube, and sphere are all spawned in the identical pose for every clone; an incorrect
255+
collision filter would blow up the simulation on reset. This guards both modulo ordering and
256+
that the colocated set stays stable through PhysX steps across CPU and CUDA.
257+
"""
258+
_run_colocation_collision_filter(
259+
sim,
260+
sim_utils.MultiAssetSpawnerCfg(
261+
assets_cfg=[
262+
sim_utils.ConeCfg(
263+
radius=0.3,
264+
height=0.6,
265+
visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0), metallic=0.2),
266+
mass_props=sim_utils.MassPropertiesCfg(mass=100.0),
267+
),
268+
sim_utils.CuboidCfg(
269+
size=(0.3, 0.3, 0.3),
270+
visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 0.0, 0.0), metallic=0.2),
271+
),
272+
sim_utils.SphereCfg(
273+
radius=0.3,
274+
visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 0.0, 1.0), metallic=0.2),
275+
),
276+
],
277+
rigid_props=sim_utils.RigidBodyPropertiesCfg(
278+
solver_position_iteration_count=4, solver_velocity_iteration_count=0
279+
),
280+
mass_props=sim_utils.MassPropertiesCfg(mass=1.0),
281+
collision_props=sim_utils.CollisionPropertiesCfg(),
282+
),
283+
expected_types=["Cone", "Cube", "Sphere"],
284+
)

0 commit comments

Comments
 (0)