Unverified Commit 17f12fdf authored by oahmednv's avatar oahmednv Committed by GitHub

Raises exceptions from initialization callbacks inside SimContext (#2166)

# Description


Handling exceptions when raised inside the initialization callbacks

Fixes #1025 

## 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
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] 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 avatarKelly Guo <kellyguo123@hotmail.com>
Co-authored-by: 's avatarKelly Guo <kellyg@nvidia.com>
parent 104805f2
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.39.6" version = "0.39.7"
# Description # Description
title = "Isaac Lab framework for Robot Learning" title = "Isaac Lab framework for Robot Learning"
......
Changelog Changelog
--------- ---------
0.39.7 (2025-05-19)
~~~~~~~~~~~~~~~~~~~
Fixed
^^^^^^
* Raising exceptions in step, render and reset if they occurred inside the initialization callbacks
of assets and sensors.used from the experience files and the double definition is removed.
0.39.6 (2025-01-30) 0.39.6 (2025-01-30)
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
from __future__ import annotations from __future__ import annotations
import builtins
import inspect import inspect
import re import re
import torch import torch
...@@ -16,7 +17,7 @@ from typing import TYPE_CHECKING, Any ...@@ -16,7 +17,7 @@ from typing import TYPE_CHECKING, Any
import isaacsim.core.utils.prims as prim_utils import isaacsim.core.utils.prims as prim_utils
import omni.kit.app import omni.kit.app
import omni.timeline import omni.timeline
from isaacsim.core.simulation_manager import SimulationManager from isaacsim.core.simulation_manager import IsaacEvents, SimulationManager
import isaaclab.sim as sim_utils import isaaclab.sim as sim_utils
...@@ -102,6 +103,9 @@ class AssetBase(ABC): ...@@ -102,6 +103,9 @@ class AssetBase(ABC):
lambda event, obj=weakref.proxy(self): obj._invalidate_initialize_callback(event), lambda event, obj=weakref.proxy(self): obj._invalidate_initialize_callback(event),
order=10, order=10,
) )
self._prim_deletion_callback_id = SimulationManager.register_callback(
self._on_prim_deletion, event=IsaacEvents.PRIM_DELETION
)
# add handle for debug visualization (this is set to a valid handle inside set_debug_vis) # add handle for debug visualization (this is set to a valid handle inside set_debug_vis)
self._debug_vis_handle = None self._debug_vis_handle = None
# set initial state of debug visualization # set initial state of debug visualization
...@@ -109,17 +113,8 @@ class AssetBase(ABC): ...@@ -109,17 +113,8 @@ class AssetBase(ABC):
def __del__(self): def __del__(self):
"""Unsubscribe from the callbacks.""" """Unsubscribe from the callbacks."""
# clear physics events handles # clear events handles
if self._initialize_handle: self._clear_callbacks()
self._initialize_handle.unsubscribe()
self._initialize_handle = None
if self._invalidate_initialize_handle:
self._invalidate_initialize_handle.unsubscribe()
self._invalidate_initialize_handle = None
# clear debug visualization
if self._debug_vis_handle:
self._debug_vis_handle.unsubscribe()
self._debug_vis_handle = None
""" """
Properties Properties
...@@ -288,10 +283,15 @@ class AssetBase(ABC): ...@@ -288,10 +283,15 @@ class AssetBase(ABC):
called whenever the simulator "plays" from a "stop" state. called whenever the simulator "plays" from a "stop" state.
""" """
if not self._is_initialized: if not self._is_initialized:
# obtain simulation related information
self._backend = SimulationManager.get_backend() self._backend = SimulationManager.get_backend()
self._device = SimulationManager.get_physics_sim_device() self._device = SimulationManager.get_physics_sim_device()
# initialize the asset # initialize the asset
try:
self._initialize_impl() self._initialize_impl()
except Exception as e:
if builtins.ISAACLAB_CALLBACK_EXCEPTION is None:
builtins.ISAACLAB_CALLBACK_EXCEPTION = e
# set flag # set flag
self._is_initialized = True self._is_initialized = True
...@@ -301,3 +301,37 @@ class AssetBase(ABC): ...@@ -301,3 +301,37 @@ class AssetBase(ABC):
if self._debug_vis_handle is not None: if self._debug_vis_handle is not None:
self._debug_vis_handle.unsubscribe() self._debug_vis_handle.unsubscribe()
self._debug_vis_handle = None self._debug_vis_handle = None
def _on_prim_deletion(self, prim_path: str) -> None:
"""Invalidates and deletes the callbacks when the prim is deleted.
Args:
prim_path: The path to the prim that is being deleted.
Note:
This function is called when the prim is deleted.
"""
if prim_path == "/":
self._clear_callbacks()
return
result = re.match(
pattern="^" + "/".join(self.cfg.prim_path.split("/")[: prim_path.count("/") + 1]) + "$", string=prim_path
)
if result:
self._clear_callbacks()
def _clear_callbacks(self) -> None:
"""Clears the callbacks."""
if self._prim_deletion_callback_id:
SimulationManager.deregister_callback(self._prim_deletion_callback_id)
self._prim_deletion_callback_id = None
if self._initialize_handle:
self._initialize_handle.unsubscribe()
self._initialize_handle = None
if self._invalidate_initialize_handle:
self._invalidate_initialize_handle.unsubscribe()
self._invalidate_initialize_handle = None
# clear debug visualization
if self._debug_vis_handle:
self._debug_vis_handle.unsubscribe()
self._debug_vis_handle = None
...@@ -15,7 +15,7 @@ import omni.kit.app ...@@ -15,7 +15,7 @@ import omni.kit.app
import omni.log import omni.log
import omni.physics.tensors.impl.api as physx import omni.physics.tensors.impl.api as physx
import omni.timeline import omni.timeline
from isaacsim.core.simulation_manager import SimulationManager from isaacsim.core.simulation_manager import IsaacEvents, SimulationManager
from pxr import UsdPhysics from pxr import UsdPhysics
import isaaclab.sim as sim_utils import isaaclab.sim as sim_utils
...@@ -67,7 +67,7 @@ class RigidObjectCollection(AssetBase): ...@@ -67,7 +67,7 @@ class RigidObjectCollection(AssetBase):
self.cfg = cfg.copy() self.cfg = cfg.copy()
# flag for whether the asset is initialized # flag for whether the asset is initialized
self._is_initialized = False self._is_initialized = False
self._prim_paths = []
# spawn the rigid objects # spawn the rigid objects
for rigid_object_cfg in self.cfg.rigid_objects.values(): for rigid_object_cfg in self.cfg.rigid_objects.values():
# check if the rigid object path is valid # check if the rigid object path is valid
...@@ -88,7 +88,7 @@ class RigidObjectCollection(AssetBase): ...@@ -88,7 +88,7 @@ class RigidObjectCollection(AssetBase):
matching_prims = sim_utils.find_matching_prims(rigid_object_cfg.prim_path) matching_prims = sim_utils.find_matching_prims(rigid_object_cfg.prim_path)
if len(matching_prims) == 0: if len(matching_prims) == 0:
raise RuntimeError(f"Could not find prim with path {rigid_object_cfg.prim_path}.") raise RuntimeError(f"Could not find prim with path {rigid_object_cfg.prim_path}.")
self._prim_paths.append(rigid_object_cfg.prim_path)
# stores object names # stores object names
self._object_names_list = [] self._object_names_list = []
...@@ -106,7 +106,9 @@ class RigidObjectCollection(AssetBase): ...@@ -106,7 +106,9 @@ class RigidObjectCollection(AssetBase):
lambda event, obj=weakref.proxy(self): obj._invalidate_initialize_callback(event), lambda event, obj=weakref.proxy(self): obj._invalidate_initialize_callback(event),
order=10, order=10,
) )
self._prim_deletion_callback_id = SimulationManager.register_callback(
self._on_prim_deletion, event=IsaacEvents.PRIM_DELETION
)
self._debug_vis_handle = None self._debug_vis_handle = None
""" """
...@@ -688,3 +690,23 @@ class RigidObjectCollection(AssetBase): ...@@ -688,3 +690,23 @@ class RigidObjectCollection(AssetBase):
super()._invalidate_initialize_callback(event) super()._invalidate_initialize_callback(event)
# set all existing views to None to invalidate them # set all existing views to None to invalidate them
self._root_physx_view = None self._root_physx_view = None
def _on_prim_deletion(self, prim_path: str) -> None:
"""Invalidates and deletes the callbacks when the prim is deleted.
Args:
prim_path: The path to the prim that is being deleted.
Note:
This function is called when the prim is deleted.
"""
if prim_path == "/":
self._clear_callbacks()
return
for prim_path_expr in self._prim_paths:
result = re.match(
pattern="^" + "/".join(prim_path_expr.split("/")[: prim_path.count("/") + 1]) + "$", string=prim_path
)
if result:
self._clear_callbacks()
return
...@@ -11,7 +11,9 @@ Each sensor class should inherit from this class and implement the abstract meth ...@@ -11,7 +11,9 @@ Each sensor class should inherit from this class and implement the abstract meth
from __future__ import annotations from __future__ import annotations
import builtins
import inspect import inspect
import re
import torch import torch
import weakref import weakref
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
...@@ -20,6 +22,7 @@ from typing import TYPE_CHECKING, Any ...@@ -20,6 +22,7 @@ from typing import TYPE_CHECKING, Any
import omni.kit.app import omni.kit.app
import omni.timeline import omni.timeline
from isaacsim.core.simulation_manager import IsaacEvents, SimulationManager
import isaaclab.sim as sim_utils import isaaclab.sim as sim_utils
...@@ -71,6 +74,9 @@ class SensorBase(ABC): ...@@ -71,6 +74,9 @@ class SensorBase(ABC):
lambda event, obj=weakref.proxy(self): obj._invalidate_initialize_callback(event), lambda event, obj=weakref.proxy(self): obj._invalidate_initialize_callback(event),
order=10, order=10,
) )
self._prim_deletion_callback_id = SimulationManager.register_callback(
self._on_prim_deletion, event=IsaacEvents.PRIM_DELETION
)
# add handle for debug visualization (this is set to a valid handle inside set_debug_vis) # add handle for debug visualization (this is set to a valid handle inside set_debug_vis)
self._debug_vis_handle = None self._debug_vis_handle = None
# set initial state of debug visualization # set initial state of debug visualization
...@@ -79,16 +85,7 @@ class SensorBase(ABC): ...@@ -79,16 +85,7 @@ class SensorBase(ABC):
def __del__(self): def __del__(self):
"""Unsubscribe from the callbacks.""" """Unsubscribe from the callbacks."""
# clear physics events handles # clear physics events handles
if self._initialize_handle: self._clear_callbacks()
self._initialize_handle.unsubscribe()
self._initialize_handle = None
if self._invalidate_initialize_handle:
self._invalidate_initialize_handle.unsubscribe()
self._invalidate_initialize_handle = None
# clear debug visualization
if self._debug_vis_handle:
self._debug_vis_handle.unsubscribe()
self._debug_vis_handle = None
""" """
Properties Properties
...@@ -270,7 +267,11 @@ class SensorBase(ABC): ...@@ -270,7 +267,11 @@ class SensorBase(ABC):
called whenever the simulator "plays" from a "stop" state. called whenever the simulator "plays" from a "stop" state.
""" """
if not self._is_initialized: if not self._is_initialized:
try:
self._initialize_impl() self._initialize_impl()
except Exception as e:
if builtins.ISAACLAB_CALLBACK_EXCEPTION is None:
builtins.ISAACLAB_CALLBACK_EXCEPTION = e
self._is_initialized = True self._is_initialized = True
def _invalidate_initialize_callback(self, event): def _invalidate_initialize_callback(self, event):
...@@ -280,6 +281,40 @@ class SensorBase(ABC): ...@@ -280,6 +281,40 @@ class SensorBase(ABC):
self._debug_vis_handle.unsubscribe() self._debug_vis_handle.unsubscribe()
self._debug_vis_handle = None self._debug_vis_handle = None
def _on_prim_deletion(self, prim_path: str) -> None:
"""Invalidates and deletes the callbacks when the prim is deleted.
Args:
prim_path: The path to the prim that is being deleted.
Note:
This function is called when the prim is deleted.
"""
if prim_path == "/":
self._clear_callbacks()
return
result = re.match(
pattern="^" + "/".join(self.cfg.prim_path.split("/")[: prim_path.count("/") + 1]) + "$", string=prim_path
)
if result:
self._clear_callbacks()
def _clear_callbacks(self) -> None:
"""Clears the callbacks."""
if self._prim_deletion_callback_id:
SimulationManager.deregister_callback(self._prim_deletion_callback_id)
self._prim_deletion_callback_id = None
if self._initialize_handle:
self._initialize_handle.unsubscribe()
self._initialize_handle = None
if self._invalidate_initialize_handle:
self._invalidate_initialize_handle.unsubscribe()
self._invalidate_initialize_handle = None
# clear debug visualization
if self._debug_vis_handle:
self._debug_vis_handle.unsubscribe()
self._debug_vis_handle = None
""" """
Helper functions. Helper functions.
""" """
......
...@@ -211,7 +211,11 @@ class SimulationContext(_SimulationContext): ...@@ -211,7 +211,11 @@ class SimulationContext(_SimulationContext):
# you can reproduce the issue by commenting out this line and running the test `test_articulation.py`. # you can reproduce the issue by commenting out this line and running the test `test_articulation.py`.
self._gravity_tensor = torch.tensor(self.cfg.gravity, dtype=torch.float32, device=self.cfg.device) self._gravity_tensor = torch.tensor(self.cfg.gravity, dtype=torch.float32, device=self.cfg.device)
# add a callback to keep rendering when a stop is triggered through different GUI commands like (save as) # define a global variable to store the exceptions raised in the callback stack
builtins.ISAACLAB_CALLBACK_EXCEPTION = None
# add callback to deal the simulation app when simulation is stopped.
# this is needed because physics views go invalid once we stop the simulation
if not builtins.ISAAC_LAUNCHED_FROM_TERMINAL: if not builtins.ISAAC_LAUNCHED_FROM_TERMINAL:
timeline_event_stream = omni.timeline.get_timeline_interface().get_timeline_event_stream() timeline_event_stream = omni.timeline.get_timeline_interface().get_timeline_event_stream()
self._app_control_on_stop_handle = timeline_event_stream.create_subscription_to_pop_by_type( self._app_control_on_stop_handle = timeline_event_stream.create_subscription_to_pop_by_type(
...@@ -513,6 +517,11 @@ class SimulationContext(_SimulationContext): ...@@ -513,6 +517,11 @@ class SimulationContext(_SimulationContext):
def reset(self, soft: bool = False): def reset(self, soft: bool = False):
self._disable_app_control_on_stop_handle = True self._disable_app_control_on_stop_handle = True
# check if we need to raise an exception that was raised in a callback
if builtins.ISAACLAB_CALLBACK_EXCEPTION is not None:
exception_to_raise = builtins.ISAACLAB_CALLBACK_EXCEPTION
builtins.ISAACLAB_CALLBACK_EXCEPTION = None
raise exception_to_raise
super().reset(soft=soft) super().reset(soft=soft)
# app.update() may be changing the cuda device in reset, so we force it back to our desired device here # app.update() may be changing the cuda device in reset, so we force it back to our desired device here
if "cuda" in self.device: if "cuda" in self.device:
...@@ -537,6 +546,11 @@ class SimulationContext(_SimulationContext): ...@@ -537,6 +546,11 @@ class SimulationContext(_SimulationContext):
render: Whether to render the scene after stepping the physics simulation. render: Whether to render the scene after stepping the physics simulation.
If set to False, the scene is not rendered and only the physics simulation is stepped. If set to False, the scene is not rendered and only the physics simulation is stepped.
""" """
# check if we need to raise an exception that was raised in a callback
if builtins.ISAACLAB_CALLBACK_EXCEPTION is not None:
exception_to_raise = builtins.ISAACLAB_CALLBACK_EXCEPTION
builtins.ISAACLAB_CALLBACK_EXCEPTION = None
raise exception_to_raise
# check if the simulation timeline is paused. in that case keep stepping until it is playing # check if the simulation timeline is paused. in that case keep stepping until it is playing
if not self.is_playing(): if not self.is_playing():
# step the simulator (but not the physics) to have UI still active # step the simulator (but not the physics) to have UI still active
...@@ -570,6 +584,11 @@ class SimulationContext(_SimulationContext): ...@@ -570,6 +584,11 @@ class SimulationContext(_SimulationContext):
Args: Args:
mode: The rendering mode. Defaults to None, in which case the current rendering mode is used. mode: The rendering mode. Defaults to None, in which case the current rendering mode is used.
""" """
# check if we need to raise an exception that was raised in a callback
if builtins.ISAACLAB_CALLBACK_EXCEPTION is not None:
exception_to_raise = builtins.ISAACLAB_CALLBACK_EXCEPTION
builtins.ISAACLAB_CALLBACK_EXCEPTION = None
raise exception_to_raise
# check if we need to change the render mode # check if we need to change the render mode
if mode is not None: if mode is not None:
self.set_render_mode(mode) self.set_render_mode(mode)
...@@ -840,3 +859,8 @@ def build_simulation_context( ...@@ -840,3 +859,8 @@ def build_simulation_context(
# Clear the stage # Clear the stage
sim.clear_all_callbacks() sim.clear_all_callbacks()
sim.clear_instance() sim.clear_instance()
# check if we need to raise an exception that was raised in a callback
if builtins.ISAACLAB_CALLBACK_EXCEPTION is not None:
exception_to_raise = builtins.ISAACLAB_CALLBACK_EXCEPTION
builtins.ISAACLAB_CALLBACK_EXCEPTION = None
raise exception_to_raise
...@@ -609,9 +609,8 @@ def test_out_of_range_default_joint_pos(sim, num_articulations, device, add_grou ...@@ -609,9 +609,8 @@ def test_out_of_range_default_joint_pos(sim, num_articulations, device, add_grou
assert ctypes.c_long.from_address(id(articulation)).value == 1 assert ctypes.c_long.from_address(id(articulation)).value == 1
# Play sim # Play sim
with pytest.raises(ValueError):
sim.reset() sim.reset()
# Check if articulation is initialized
assert not articulation.is_initialized
@pytest.mark.parametrize("device", ["cuda:0", "cpu"]) @pytest.mark.parametrize("device", ["cuda:0", "cpu"])
...@@ -633,9 +632,8 @@ def test_out_of_range_default_joint_vel(sim, device): ...@@ -633,9 +632,8 @@ def test_out_of_range_default_joint_vel(sim, device):
assert ctypes.c_long.from_address(id(articulation)).value == 1 assert ctypes.c_long.from_address(id(articulation)).value == 1
# Play sim # Play sim
with pytest.raises(ValueError):
sim.reset() sim.reset()
# Check if articulation is initialized
assert not articulation.is_initialized
@pytest.mark.parametrize("num_articulations", [1, 2]) @pytest.mark.parametrize("num_articulations", [1, 2])
...@@ -1062,14 +1060,11 @@ def test_setting_velocity_limit_implicit(sim, num_articulations, device, vel_lim ...@@ -1062,14 +1060,11 @@ def test_setting_velocity_limit_implicit(sim, num_articulations, device, vel_lim
device=device, device=device,
) )
# Play sim # Play sim
sim.reset()
if vel_limit_sim is not None and vel_limit is not None: if vel_limit_sim is not None and vel_limit is not None:
# Case 1: during initialization, the actuator will raise a ValueError and fail to with pytest.raises(ValueError):
# initialize when both these attributes are set. sim.reset()
# note: The Exception is not caught with self.assertRaises or try-except
assert len(articulation.actuators) == 0
return return
sim.reset()
# read the values set into the simulation # read the values set into the simulation
physx_vel_limit = articulation.root_physx_view.get_dof_max_velocities().to(device) physx_vel_limit = articulation.root_physx_view.get_dof_max_velocities().to(device)
...@@ -1170,12 +1165,11 @@ def test_setting_effort_limit_implicit(sim, num_articulations, device, effort_li ...@@ -1170,12 +1165,11 @@ def test_setting_effort_limit_implicit(sim, num_articulations, device, effort_li
device=device, device=device,
) )
# Play sim # Play sim
sim.reset()
if effort_limit_sim is not None and effort_limit is not None: if effort_limit_sim is not None and effort_limit is not None:
# during initialization, the actuator will raise a ValueError and fail to initialize with pytest.raises(ValueError):
assert len(articulation.actuators) == 0 sim.reset()
return return
sim.reset()
# obtain the physx effort limits # obtain the physx effort limits
physx_effort_limit = articulation.root_physx_view.get_dof_max_forces().to(device=device) physx_effort_limit = articulation.root_physx_view.get_dof_max_forces().to(device=device)
...@@ -1610,9 +1604,8 @@ def test_body_incoming_joint_wrench_b_single_joint(sim, num_articulations, devic ...@@ -1610,9 +1604,8 @@ def test_body_incoming_joint_wrench_b_single_joint(sim, num_articulations, devic
self.assertEqual(ctypes.c_long.from_address(id(articulation)).value, 1) self.assertEqual(ctypes.c_long.from_address(id(articulation)).value, 1)
# Play sim # Play sim
with pytest.raises(RuntimeError):
sim.reset() sim.reset()
# Check if articulation is initialized
self.assertFalse(articulation._is_initialized)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -173,11 +173,9 @@ def test_initialization_on_device_cpu(): ...@@ -173,11 +173,9 @@ def test_initialization_on_device_cpu():
assert ctypes.c_long.from_address(id(cube_object)).value == 1 assert ctypes.c_long.from_address(id(cube_object)).value == 1
# Play sim # Play sim
with pytest.raises(RuntimeError):
sim.reset() sim.reset()
# Check if object is initialized
assert not cube_object.is_initialized
@pytest.mark.parametrize("num_cubes", [1, 2]) @pytest.mark.parametrize("num_cubes", [1, 2])
def test_initialization_with_kinematic_enabled(sim, num_cubes): def test_initialization_with_kinematic_enabled(sim, num_cubes):
...@@ -214,11 +212,9 @@ def test_initialization_with_no_deformable_body(sim, num_cubes): ...@@ -214,11 +212,9 @@ def test_initialization_with_no_deformable_body(sim, num_cubes):
assert ctypes.c_long.from_address(id(cube_object)).value == 1 assert ctypes.c_long.from_address(id(cube_object)).value == 1
# Play sim # Play sim
with pytest.raises(RuntimeError):
sim.reset() sim.reset()
# Check if object is initialized
assert not cube_object.is_initialized
@pytest.mark.parametrize("num_cubes", [1, 2]) @pytest.mark.parametrize("num_cubes", [1, 2])
def test_set_nodal_state(sim, num_cubes): def test_set_nodal_state(sim, num_cubes):
......
...@@ -168,11 +168,9 @@ def test_initialization_with_no_rigid_body(num_cubes, device): ...@@ -168,11 +168,9 @@ def test_initialization_with_no_rigid_body(num_cubes, device):
assert ctypes.c_long.from_address(id(cube_object)).value == 1 assert ctypes.c_long.from_address(id(cube_object)).value == 1
# Play sim # Play sim
with pytest.raises(RuntimeError):
sim.reset() sim.reset()
# Check if object is initialized
assert not cube_object.is_initialized
@pytest.mark.parametrize("num_cubes", [1, 2]) @pytest.mark.parametrize("num_cubes", [1, 2])
@pytest.mark.parametrize("device", ["cuda:0", "cpu"]) @pytest.mark.parametrize("device", ["cuda:0", "cpu"])
...@@ -187,11 +185,9 @@ def test_initialization_with_articulation_root(num_cubes, device): ...@@ -187,11 +185,9 @@ def test_initialization_with_articulation_root(num_cubes, device):
assert ctypes.c_long.from_address(id(cube_object)).value == 1 assert ctypes.c_long.from_address(id(cube_object)).value == 1
# Play sim # Play sim
with pytest.raises(RuntimeError):
sim.reset() sim.reset()
# Check if object is initialized
assert not cube_object.is_initialized
@pytest.mark.parametrize("device", ["cuda:0", "cpu"]) @pytest.mark.parametrize("device", ["cuda:0", "cpu"])
def test_external_force_buffer(device): def test_external_force_buffer(device):
......
...@@ -203,11 +203,9 @@ def test_initialization_with_no_rigid_body(sim, num_cubes, device): ...@@ -203,11 +203,9 @@ def test_initialization_with_no_rigid_body(sim, num_cubes, device):
assert ctypes.c_long.from_address(id(object_collection)).value == 1 assert ctypes.c_long.from_address(id(object_collection)).value == 1
# Play sim # Play sim
with pytest.raises(RuntimeError):
sim.reset() sim.reset()
# Check if object is initialized
assert not object_collection.is_initialized
@pytest.mark.parametrize("device", ["cuda:0", "cpu"]) @pytest.mark.parametrize("device", ["cuda:0", "cpu"])
def test_external_force_buffer(sim, device): def test_external_force_buffer(sim, device):
......
...@@ -80,7 +80,7 @@ class FrankaTeddyBearLiftEnvCfg(FrankaCubeLiftEnvCfg): ...@@ -80,7 +80,7 @@ class FrankaTeddyBearLiftEnvCfg(FrankaCubeLiftEnvCfg):
) )
# Make the end effector less stiff to not hurt the poor teddy bear # Make the end effector less stiff to not hurt the poor teddy bear
self.scene.robot.actuators["panda_hand"].effort_limit = 50.0 self.scene.robot.actuators["panda_hand"].effort_limit_sim = 50.0
self.scene.robot.actuators["panda_hand"].stiffness = 40.0 self.scene.robot.actuators["panda_hand"].stiffness = 40.0
self.scene.robot.actuators["panda_hand"].damping = 10.0 self.scene.robot.actuators["panda_hand"].damping = 10.0
......
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