From 6ddc3d4dc72aac52f568f1d5a9758d5d05e687c8 Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Sun, 2 Aug 2026 17:41:13 -0700 Subject: [PATCH 1/4] Fix PhysX collision filtering in direct tasks Apply per-environment collision groups for manual direct-workflow cloning on every PhysX simulation device. Without these groups, CUDA replicas collide across environments and joint efforts become ineffective. Add a Cartpole regression that verifies every cloned articulation accelerates consistently under a constant effort. Fixes #5302 --- .../fix-direct-physx-collision-filtering.rst | 5 ++ .../contrib/anymal_c_direct/anymal_c_env.py | 4 +- .../contrib/factory/factory_env.py | 4 +- .../contrib/humanoid_amp/humanoid_amp_env.py | 4 +- .../core/cabinet/cabinet_direct_env.py | 4 +- .../cartpole/cartpole_direct_camera_env.py | 4 +- .../core/cartpole/cartpole_direct_env.py | 4 +- .../core/handover/handover_env.py | 3 ++ .../core/locomotion/locomotion_direct_env.py | 4 +- .../core/pendulum/pendulum_env.py | 4 +- .../shadow_hand_direct_camera_env.py | 3 ++ .../core/reorient/reorient_direct_env.py | 3 ++ .../test_cartpole_direct_physx_actuation.py | 49 +++++++++++++++++++ 13 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 source/isaaclab_tasks/changelog.d/fix-direct-physx-collision-filtering.rst create mode 100644 source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py diff --git a/source/isaaclab_tasks/changelog.d/fix-direct-physx-collision-filtering.rst b/source/isaaclab_tasks/changelog.d/fix-direct-physx-collision-filtering.rst new file mode 100644 index 000000000000..6cd2b7c57354 --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/fix-direct-physx-collision-filtering.rst @@ -0,0 +1,5 @@ +Fixed +^^^^^ + +* Fixed ineffective joint actuation in direct-workflow PhysX environments by filtering collisions between + replicas on all simulation devices. diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/anymal_c_direct/anymal_c_env.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/anymal_c_direct/anymal_c_env.py index c0a5fac0edc8..5d25326c2923 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/anymal_c_direct/anymal_c_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/anymal_c_direct/anymal_c_env.py @@ -77,8 +77,8 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - # we need to explicitly filter collisions for CPU simulation - if self.device == "cpu": + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=[self.cfg.terrain.prim_path]) # add lights light_cfg = sim_utils.DomeLightCfg(intensity=2000.0, color=(0.75, 0.75, 0.75)) diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/factory/factory_env.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/factory/factory_env.py index 27a7d9e9ac9c..e85b6835292f 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/factory/factory_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/factory/factory_env.py @@ -103,8 +103,8 @@ def _setup_scene(self): plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - if self.device == "cpu": - # we need to explicitly filter collisions for CPU simulation + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions() self.scene.articulations["robot"] = self._robot diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/humanoid_amp/humanoid_amp_env.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/humanoid_amp/humanoid_amp_env.py index 0e9fc3a40c85..fccda95dc46a 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/humanoid_amp/humanoid_amp_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/humanoid_amp/humanoid_amp_env.py @@ -69,8 +69,8 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - # we need to explicitly filter collisions for CPU simulation - if self.device == "cpu": + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=["/World/ground"]) # add articulation to scene diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/cabinet_direct_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/cabinet_direct_env.py index db83f6bacf32..167c40dbda55 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/cabinet_direct_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/cabinet_direct_env.py @@ -143,8 +143,8 @@ def _setup_scene(self): plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - # we need to explicitly filter collisions for CPU simulation - if self.device == "cpu": + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=[self.cfg.terrain.prim_path]) # add lights diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_camera_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_camera_env.py index e6623a444170..0585fa8b3c85 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_camera_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_camera_env.py @@ -56,8 +56,8 @@ def _setup_scene(self): plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - if self.device == "cpu": - # we need to explicitly filter collisions for CPU simulation + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=[]) # add articulation and sensors to scene diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_env.py index ed125929b4dc..2378183bcf21 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/cartpole/cartpole_direct_env.py @@ -43,8 +43,8 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - # we need to explicitly filter collisions for CPU simulation - if self.device == "cpu": + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=[]) # add articulation to scene diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/handover/handover_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/handover/handover_env.py index a0a8630fedf6..ce78692d54fa 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/handover/handover_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/handover/handover_env.py @@ -96,6 +96,9 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: + self.scene.filter_collisions(global_prim_paths=["/World/ground"]) # add articulation to scene - we must register to scene to randomize with EventManager self.scene.articulations["right_robot"] = self.right_hand self.scene.articulations["left_robot"] = self.left_hand diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/locomotion/locomotion_direct_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/locomotion/locomotion_direct_env.py index 5ff7a076707a..d988356171c3 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/locomotion/locomotion_direct_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/locomotion/locomotion_direct_env.py @@ -122,8 +122,8 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - # we need to explicitly filter collisions for CPU simulation - if self.device == "cpu": + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=[self.cfg.terrain.prim_path]) # add articulation to scene self.scene.articulations["robot"] = self.robot diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/pendulum/pendulum_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/pendulum/pendulum_env.py index 7577eae85504..f0e97fded0c9 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/pendulum/pendulum_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/pendulum/pendulum_env.py @@ -47,8 +47,8 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - # we need to explicitly filter collisions for CPU simulation - if self.device == "cpu": + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=[]) # add articulation to scene self.scene.articulations["robot"] = self.robot diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/reorient/config/shadow_hand/shadow_hand_direct_camera_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/reorient/config/shadow_hand/shadow_hand_direct_camera_env.py index d424b46400e5..025a5c692b3b 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/reorient/config/shadow_hand/shadow_hand_direct_camera_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/reorient/config/shadow_hand/shadow_hand_direct_camera_env.py @@ -57,6 +57,9 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: + self.scene.filter_collisions(global_prim_paths=[]) # add articulation to scene - we must register to scene to randomize with EventManager self.scene.articulations["robot"] = self.hand self.scene.rigid_objects["object"] = self.object diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/reorient/reorient_direct_env.py b/source/isaaclab_tasks/isaaclab_tasks/core/reorient/reorient_direct_env.py index a2ada7e457a1..c2c47e66491b 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/reorient/reorient_direct_env.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/reorient/reorient_direct_env.py @@ -106,6 +106,9 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: + self.scene.filter_collisions(global_prim_paths=["/World/ground"]) # add articulation to scene - we must register to scene to randomize with EventManager self.scene.articulations["robot"] = self.hand self.scene.rigid_objects["object"] = self.object diff --git a/source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py b/source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py new file mode 100644 index 000000000000..4d69fa850979 --- /dev/null +++ b/source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py @@ -0,0 +1,49 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Test PhysX actuation in the direct-workflow Cartpole environment.""" + +from isaaclab.app import AppLauncher + +# launch the simulator +simulation_app = AppLauncher(headless=True).app + +"""Rest everything follows.""" + +import gymnasium as gym +import pytest +import torch + +import isaaclab_tasks # noqa: F401 +from isaaclab_tasks.core.cartpole.cartpole_direct_env_cfg import CartpoleEnvCfg +from isaaclab_tasks.utils.hydra import resolve_presets + + +@pytest.mark.isaacsim_ci +def test_cartpole_direct_physx_actuation_is_consistent_across_environments(): + """Verify that cloned PhysX carts respond consistently to a constant effort.""" + cfg = resolve_presets(CartpoleEnvCfg(), ("physx",)) + cfg.scene.num_envs = 4 + cfg.sim.device = "cuda:0" + cfg.seed = 0 + cfg.initial_cart_position_range = (0.0, 0.0) + cfg.initial_cart_velocity_range = (0.0, 0.0) + cfg.initial_pole_angle_range = (0.0, 0.0) + cfg.initial_pole_velocity_range = (0.0, 0.0) + + env = gym.make("Isaac-Cartpole-Direct", cfg=cfg) + try: + env.reset() + actions = torch.ones(env.action_space.shape, device=env.unwrapped.device) + with torch.inference_mode(): + for _ in range(20): + env.step(actions) + + cart_idx = env.unwrapped._cart_dof_idx[0] + cart_vel = env.unwrapped.cartpole.data.joint_vel.torch[:, cart_idx] + assert torch.all(cart_vel > 1.0), f"Expected every cart to accelerate, got velocities {cart_vel.tolist()}." + torch.testing.assert_close(cart_vel, cart_vel[0].expand_as(cart_vel)) + finally: + env.close() From 2c990c0de94353b1e27a6f45ae6c2c783776c556 Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Sun, 2 Aug 2026 20:05:06 -0700 Subject: [PATCH 2/4] Update PhysX rendering stage goldens Record the per-environment collision groups introduced by the direct-task filtering fix so rendering correctness tests validate the intended stage. --- .../cartpole/physx-isaacsim_rtx_renderer-rgb.usda | 4 ++-- .../golden_stages/cartpole/physx-newton_renderer-rgb.usda | 4 ++-- .../default_physics-default_renderer-stage.usda | 4 ++-- .../default_physics-default_renderer-stage.usda | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/isaaclab_tasks/test/golden_stages/cartpole/physx-isaacsim_rtx_renderer-rgb.usda b/source/isaaclab_tasks/test/golden_stages/cartpole/physx-isaacsim_rtx_renderer-rgb.usda index c25f11f6c268..b7702cae095e 100644 --- a/source/isaaclab_tasks/test/golden_stages/cartpole/physx-isaacsim_rtx_renderer-rgb.usda +++ b/source/isaaclab_tasks/test/golden_stages/cartpole/physx-isaacsim_rtx_renderer-rgb.usda @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b33d1c95f90499e865145095fa0ddd4a2c82f724307d3bc7baca3d5d0e0be70c -size 53021 +oid sha256:0601d2f4e78386786babf320601d44c0a44f58c200429fdf1cf41542dc81e2ba +size 54479 diff --git a/source/isaaclab_tasks/test/golden_stages/cartpole/physx-newton_renderer-rgb.usda b/source/isaaclab_tasks/test/golden_stages/cartpole/physx-newton_renderer-rgb.usda index c8999b3cb6ac..025bf12b256c 100644 --- a/source/isaaclab_tasks/test/golden_stages/cartpole/physx-newton_renderer-rgb.usda +++ b/source/isaaclab_tasks/test/golden_stages/cartpole/physx-newton_renderer-rgb.usda @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa2d25fb0ade1c6b763c736444963d4f42f3780c22e7019fb9631e550397c14a -size 48868 +oid sha256:9b990b3eb24d3eda2383f3ec7c64a9baabb42f342d32c37d6076b633b36d386b +size 50326 diff --git a/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Cartpole-Camera-Direct/default_physics-default_renderer-stage.usda b/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Cartpole-Camera-Direct/default_physics-default_renderer-stage.usda index 12046e937f2b..c931c6c1b35b 100644 --- a/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Cartpole-Camera-Direct/default_physics-default_renderer-stage.usda +++ b/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Cartpole-Camera-Direct/default_physics-default_renderer-stage.usda @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f149773e10ec7c172b4b13388cb7ba5e151ac96675edc7138a2ecbc5c2f8dfcd -size 53471 +oid sha256:a258c00cb0e8a5b72a4c83f327310f08a847267379b7f3c3f0618f25e99ea34d +size 54929 diff --git a/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Reorient-Cube-Shadow-Camera-Direct/default_physics-default_renderer-stage.usda b/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Reorient-Cube-Shadow-Camera-Direct/default_physics-default_renderer-stage.usda index 45e89f6bd878..a20fb62b3e41 100644 --- a/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Reorient-Cube-Shadow-Camera-Direct/default_physics-default_renderer-stage.usda +++ b/source/isaaclab_tasks/test/golden_stages/registered_tasks_Isaac-Reorient-Cube-Shadow-Camera-Direct/default_physics-default_renderer-stage.usda @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41c70aed3a5e6f53a27e9210ffe6d5fd6dde2ada543fe8e76805a46f4df500c3 -size 10647919 +oid sha256:191bcbccbff3085afe9b4bbc93e55dd57638b4fa94d4c89356e66cd35970d5fd +size 10649377 From 8a8621beb0d54c6118099e03ca37e2b7b01db5c7 Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Mon, 3 Aug 2026 11:32:47 -0700 Subject: [PATCH 3/4] Remove redundant Cartpole PhysX test Existing environment tests already cover this path, so remove the dedicated regression requested during review. --- .../test_cartpole_direct_physx_actuation.py | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py diff --git a/source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py b/source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py deleted file mode 100644 index 4d69fa850979..000000000000 --- a/source/isaaclab_tasks/test/core/test_cartpole_direct_physx_actuation.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -"""Test PhysX actuation in the direct-workflow Cartpole environment.""" - -from isaaclab.app import AppLauncher - -# launch the simulator -simulation_app = AppLauncher(headless=True).app - -"""Rest everything follows.""" - -import gymnasium as gym -import pytest -import torch - -import isaaclab_tasks # noqa: F401 -from isaaclab_tasks.core.cartpole.cartpole_direct_env_cfg import CartpoleEnvCfg -from isaaclab_tasks.utils.hydra import resolve_presets - - -@pytest.mark.isaacsim_ci -def test_cartpole_direct_physx_actuation_is_consistent_across_environments(): - """Verify that cloned PhysX carts respond consistently to a constant effort.""" - cfg = resolve_presets(CartpoleEnvCfg(), ("physx",)) - cfg.scene.num_envs = 4 - cfg.sim.device = "cuda:0" - cfg.seed = 0 - cfg.initial_cart_position_range = (0.0, 0.0) - cfg.initial_cart_velocity_range = (0.0, 0.0) - cfg.initial_pole_angle_range = (0.0, 0.0) - cfg.initial_pole_velocity_range = (0.0, 0.0) - - env = gym.make("Isaac-Cartpole-Direct", cfg=cfg) - try: - env.reset() - actions = torch.ones(env.action_space.shape, device=env.unwrapped.device) - with torch.inference_mode(): - for _ in range(20): - env.step(actions) - - cart_idx = env.unwrapped._cart_dof_idx[0] - cart_vel = env.unwrapped.cartpole.data.joint_vel.torch[:, cart_idx] - assert torch.all(cart_vel > 1.0), f"Expected every cart to accelerate, got velocities {cart_vel.tolist()}." - torch.testing.assert_close(cart_vel, cart_vel[0].expand_as(cart_vel)) - finally: - env.close() From c350ee4abfed6ebed2e1815f82522d4356c516e2 Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Mon, 3 Aug 2026 12:01:37 -0700 Subject: [PATCH 4/4] Filter collisions in standalone PhysX scripts Ensure the ANYmal deployment tutorial and pick-and-place demo isolate manually cloned PhysX environments on every simulation device. --- scripts/demos/pick_and_place.py | 3 +++ scripts/tutorials/06_deploy/anymal_c_env.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/demos/pick_and_place.py b/scripts/demos/pick_and_place.py index 7e9cd198e773..e23ee1a2450c 100644 --- a/scripts/demos/pick_and_place.py +++ b/scripts/demos/pick_and_place.py @@ -230,6 +230,9 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: + self.scene.filter_collisions(global_prim_paths=["/World/ground"]) # add articulation to scene self.scene.articulations["pick_and_place"] = self.pick_and_place self.scene.rigid_objects["cube"] = self.cube diff --git a/scripts/tutorials/06_deploy/anymal_c_env.py b/scripts/tutorials/06_deploy/anymal_c_env.py index 3c5d865e646e..c3999cb5b8b5 100644 --- a/scripts/tutorials/06_deploy/anymal_c_env.py +++ b/scripts/tutorials/06_deploy/anymal_c_env.py @@ -68,7 +68,8 @@ def _setup_scene(self): pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0] plan = cloner.clone_plan_from_env_0(src, dest, self.scene.num_envs, self.device, pos) cloner.replicate(plan, stage=self.scene.stage) - if self.device == "cpu": + # PhysX replication requires explicit collision filtering between environments. + if "physx" in self.scene.physics_backend: self.scene.filter_collisions(global_prim_paths=[self.cfg.terrain.prim_path]) light_cfg = sim_utils.DomeLightCfg(intensity=2000.0, color=(0.75, 0.75, 0.75)) light_cfg.func("/World/Light", light_cfg)