UWLab / _isaaclab /IsaacLab /source /isaaclab /test /assets /test_surface_gripper.py
Xinyi0214's picture
Upload UWLab (code, datasets, checkpoints, eval outputs)
0037d53 verified
Raw
History Blame Contribute Delete
8.05 kB
# 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
# ignore private usage of variables warning
# pyright: reportPrivateUsage=none
"""Launch Isaac Sim Simulator first."""
from isaaclab.app import AppLauncher
# launch omniverse app
simulation_app = AppLauncher(headless=True).app
"""Rest everything follows."""
import pytest
import torch
import isaaclab.sim as sim_utils
from isaaclab.actuators import ImplicitActuatorCfg
from isaaclab.assets import (
Articulation,
ArticulationCfg,
RigidObject,
RigidObjectCfg,
SurfaceGripper,
SurfaceGripperCfg,
)
from isaaclab.sim import build_simulation_context
from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR
from isaaclab.utils.version import get_isaac_sim_version
# from isaacsim.robot.surface_gripper import GripperView
def generate_surface_gripper_cfgs(
kinematic_enabled: bool = False,
max_grip_distance: float = 0.1,
coaxial_force_limit: float = 100.0,
shear_force_limit: float = 100.0,
retry_interval: float = 0.1,
reset_xform_op_properties: bool = False,
) -> tuple[SurfaceGripperCfg, ArticulationCfg]:
"""Generate a surface gripper cfg and an articulation cfg.
Args:
max_grip_distance: The maximum grip distance of the surface gripper.
coaxial_force_limit: The coaxial force limit of the surface gripper.
shear_force_limit: The shear force limit of the surface gripper.
retry_interval: The retry interval of the surface gripper.
reset_xform_op_properties: Whether to reset the xform op properties of the surface gripper.
Returns:
A tuple containing the surface gripper cfg and the articulation cfg.
"""
articulation_cfg = ArticulationCfg(
spawn=sim_utils.UsdFileCfg(
usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Tests/SurfaceGripper/test_gripper.usd",
rigid_props=sim_utils.RigidBodyPropertiesCfg(kinematic_enabled=kinematic_enabled),
),
init_state=ArticulationCfg.InitialStateCfg(
pos=(0.0, 0.0, 0.5),
rot=(1.0, 0.0, 0.0, 0.0),
joint_pos={
".*": 0.0,
},
),
actuators={
"dummy": ImplicitActuatorCfg(
joint_names_expr=[".*"],
stiffness=0.0,
damping=0.0,
),
},
)
surface_gripper_cfg = SurfaceGripperCfg(
max_grip_distance=max_grip_distance,
coaxial_force_limit=coaxial_force_limit,
shear_force_limit=shear_force_limit,
retry_interval=retry_interval,
)
return surface_gripper_cfg, articulation_cfg
def generate_surface_gripper(
surface_gripper_cfg: SurfaceGripperCfg,
articulation_cfg: ArticulationCfg,
num_surface_grippers: int,
device: str,
) -> tuple[SurfaceGripper, Articulation, torch.Tensor]:
"""Generate a surface gripper and an articulation.
Args:
surface_gripper_cfg: The surface gripper cfg.
articulation_cfg: The articulation cfg.
num_surface_grippers: The number of surface grippers to generate.
device: The device to run the test on.
Returns:
A tuple containing the surface gripper, the articulation, and the translations of the surface grippers.
"""
# Generate translations of 2.5 m in x for each articulation
translations = torch.zeros(num_surface_grippers, 3, device=device)
translations[:, 0] = torch.arange(num_surface_grippers) * 2.5
# Create Top-level Xforms, one for each articulation
for i in range(num_surface_grippers):
sim_utils.create_prim(f"/World/Env_{i}", "Xform", translation=translations[i][:3])
articulation = Articulation(articulation_cfg.replace(prim_path="/World/Env_.*/Robot"))
surface_gripper_cfg = surface_gripper_cfg.replace(prim_path="/World/Env_.*/Robot/Gripper/SurfaceGripper")
surface_gripper = SurfaceGripper(surface_gripper_cfg)
return surface_gripper, articulation, translations
def generate_grippable_object(sim, num_grippable_objects: int):
object_cfg = RigidObjectCfg(
prim_path="/World/Env_.*/Object",
spawn=sim_utils.CuboidCfg(
size=(1.0, 1.0, 1.0),
rigid_props=sim_utils.RigidBodyPropertiesCfg(),
mass_props=sim_utils.MassPropertiesCfg(mass=1.0),
collision_props=sim_utils.CollisionPropertiesCfg(),
visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
),
init_state=RigidObjectCfg.InitialStateCfg(pos=(0.0, 0.0, 0.5)),
)
grippable_object = RigidObject(object_cfg)
return grippable_object
@pytest.fixture
def sim(request):
"""Create simulation context with the specified device."""
device = request.getfixturevalue("device")
if "gravity_enabled" in request.fixturenames:
gravity_enabled = request.getfixturevalue("gravity_enabled")
else:
gravity_enabled = True # default to gravity enabled
if "add_ground_plane" in request.fixturenames:
add_ground_plane = request.getfixturevalue("add_ground_plane")
else:
add_ground_plane = False # default to no ground plane
with build_simulation_context(
device=device, auto_add_lighting=True, gravity_enabled=gravity_enabled, add_ground_plane=add_ground_plane
) as sim:
sim._app_control_on_stop_handle = None
yield sim
@pytest.mark.parametrize("num_articulations", [1])
@pytest.mark.parametrize("device", ["cpu"])
@pytest.mark.parametrize("add_ground_plane", [True])
@pytest.mark.isaacsim_ci
def test_initialization(sim, num_articulations, device, add_ground_plane) -> None:
"""Test initialization for articulation with a surface gripper.
This test verifies that:
1. The surface gripper is initialized correctly.
2. The command and state buffers have the correct shapes.
3. The command and state are initialized to the correct values.
Args:
num_articulations: The number of articulations to initialize.
device: The device to run the test on.
add_ground_plane: Whether to add a ground plane to the simulation.
"""
if get_isaac_sim_version().major < 5:
return
surface_gripper_cfg, articulation_cfg = generate_surface_gripper_cfgs(kinematic_enabled=False)
surface_gripper, articulation, _ = generate_surface_gripper(
surface_gripper_cfg, articulation_cfg, num_articulations, device
)
sim.reset()
assert articulation.is_initialized
assert surface_gripper.is_initialized
# Check that the command and state buffers have the correct shapes
assert surface_gripper.command.shape == (num_articulations,)
assert surface_gripper.state.shape == (num_articulations,)
# Check that the command and state are initialized to the correct values
assert surface_gripper.command == 0.0 # Idle command after a reset
assert surface_gripper.state == -1.0 # Open state after a reset
# Simulate physics
for _ in range(10):
# perform rendering
sim.step()
# update articulation
articulation.update(sim.cfg.dt)
surface_gripper.update(sim.cfg.dt)
@pytest.mark.parametrize("device", ["cuda:0"])
@pytest.mark.parametrize("add_ground_plane", [True])
@pytest.mark.isaacsim_ci
def test_raise_error_if_not_cpu(sim, device, add_ground_plane) -> None:
"""Test that the SurfaceGripper raises an error if the device is not CPU."""
if get_isaac_sim_version().major < 5:
return
num_articulations = 1
surface_gripper_cfg, articulation_cfg = generate_surface_gripper_cfgs(kinematic_enabled=False)
surface_gripper, articulation, translations = generate_surface_gripper(
surface_gripper_cfg, articulation_cfg, num_articulations, device
)
with pytest.raises(Exception):
sim.reset()
if __name__ == "__main__":
pytest.main([__file__, "-v", "--maxfail=1"])