Source code for isaaclab.envs.mdp.actions.surface_gripper_actions

# 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

from __future__ import annotations

import logging
from collections.abc import Sequence
from typing import TYPE_CHECKING

import torch

from isaaclab.managers.action_manager import ActionTerm

if TYPE_CHECKING:
    from isaaclab_physx.assets import SurfaceGripper

    from isaaclab.envs import ManagerBasedEnv

    from . import actions_cfg

# import logger
logger = logging.getLogger(__name__)


[docs] class SurfaceGripperBinaryAction(ActionTerm): """Surface gripper binary action. This action term maps a binary action to the *open* or *close* surface gripper configurations. The surface gripper behavior is as follows: - [-1, -0.3] --> Gripper is Opening - [-0.3, 0.3] --> Gripper is Idle (do nothing) - [0.3, 1] --> Gripper is Closing Based on above, we follow the following convention for the binary action: 1. Open action: 1 (bool) or positive values (float). 2. Close action: 0 (bool) or negative values (float). The action term is specifically designed for surface grippers, which use a different interface than joint-based grippers. """ cfg: actions_cfg.SurfaceGripperBinaryActionCfg """The configuration of the action term.""" _asset: SurfaceGripper """The surface gripper asset on which the action term is applied."""
[docs] def __init__(self, cfg: actions_cfg.SurfaceGripperBinaryActionCfg, env: ManagerBasedEnv) -> None: # initialize the action term super().__init__(cfg, env) # log the resolved asset name for debugging logger.info( f"Resolved surface gripper asset for the action term {self.__class__.__name__}: {self.cfg.asset_name}" ) # create tensors for raw and processed actions self._raw_actions = torch.zeros(self.num_envs, 1, device=self.device) self._processed_actions = torch.zeros(self.num_envs, 1, device=self.device) # parse open command self._open_command = torch.tensor(self.cfg.open_command, device=self.device) # parse close command self._close_command = torch.tensor(self.cfg.close_command, device=self.device)
""" Properties. """ @property def action_dim(self) -> int: return 1 @property def raw_actions(self) -> torch.Tensor: return self._raw_actions @property def processed_actions(self) -> torch.Tensor: return self._processed_actions """ Operations. """ def process_actions(self, actions: torch.Tensor): # store the raw actions self._raw_actions[:] = actions # compute the binary mask if actions.dtype == torch.bool: # true: close, false: open binary_mask = actions == 0 else: # true: close, false: open binary_mask = actions < 0 # compute the command self._processed_actions = torch.where(binary_mask, self._close_command, self._open_command) def apply_actions(self): """Apply the processed actions to the surface gripper.""" self._asset.set_grippers_command(self._processed_actions.view(-1)) self._asset.write_data_to_sim() def reset(self, env_ids: Sequence[int] | None = None) -> None: if env_ids is None: self._raw_actions[:] = 0.0 else: self._raw_actions[env_ids] = 0.0