simulo.SurfaceGripperActuator
Surface gripper actuator.
A surface gripper uses physics constraints to attach to nearby objects. The gripper has three states: OPEN, CLOSING, CLOSED.
Command Interface:
command < -0.3: Open the gripper-0.3 ≤ command ≤ 0.3: Idle (hold state)command > 0.3: Close the gripper
Pass a GripperCommand for scripted intent or a raw float
for a policy’s continuous action — see that enum for which to use when.
This command band is fixed and is not configurable here. Unlike
ParallelGripperActuator, which this SDK classifies itself, a
surface gripper uses the fixed ±0.3 bounds. This class therefore takes
no open_threshold / close_threshold arguments. Passing either
raises TypeError rather than being silently ignored.
State Interface:
- OPEN (-1): Gripper is open, not grasping
- CLOSING (0): Gripper is attempting to grasp
- CLOSED (1): Gripper has grasped an object
Example:
import simulo
# Create grippergripper = simulo.SurfaceGripperActuator( max_grip_distance=0.1, shear_force_limit=500.0)
# Add to scene (path is set here, consistent with robots)scene.add(gripper, at="/World/Robot/ee_link/Gripper")
# Control gripper (commands are automatically flushed before world.step())gripper.set_command(simulo.GripperCommand.CLOSE)# No write_to_sim() needed - automatically flushed before physics stepworld.step()gripper.update(dt)states = gripper.get_state()Command delivery: Commands are forwarded without rescaling or reclassification, so the fixed command band above applies directly.
Note:
Path patterns (e.g., /World/Robot.*/gripper) are a special optimization for
batch operations and RL training scenarios. For typical applications with
independent control per robot, create separate actuator instances:
# Typical pattern: one actuator per robotgripper_1 = simulo.SurfaceGripperActuator(...)scene.add(gripper_1, at="/World/Robot1/gripper")
gripper_2 = simulo.SurfaceGripperActuator(...)scene.add(gripper_2, at="/World/Robot2/gripper")Attributes:
path— Scene path where gripper is attached. Supports wildcard patterns (e.g.,.*) for multi-instance batch operations, but typically use one actuator per robot.max_grip_distance— Maximum distance to grasp objects (meters)shear_force_limit— Force limit perpendicular to gripper axis (N)coaxial_force_limit— Force limit along gripper axis (N)retry_interval— Time gripper stays in grasping state (seconds)
simulo.SurfaceGripperActuator( path: Optional[str] = None, max_grip_distance: float = 0.1, shear_force_limit: float = 500.0, coaxial_force_limit: float = 500.0, retry_interval: float = 0.1, enabled: bool = True,)set_command()
Section titled “set_command()”SurfaceGripperActuator.set_command(command: Union[GripperCommand, float]) -> NoneSet gripper command for single instance.
Command behavior (the fixed band, described in the class docstring):
- command < -0.3: Open gripper
- -0.3 ≤ command ≤ 0.3: Idle (maintain state)
- command > 0.3: Close gripper
Args:
command— AGripperCommand(OPEN/IDLE/CLOSE) for scripted intent, or a raw command value in range [-1, 1] — typically a policy’s continuous action, which is why the dead band above exists.GripperCommandis anIntEnum, so it travels the same float path with no conversion.
Raises:
TypeError— If given aGripperState. Both enums areIntEnum, so a state passed where a command belongs would otherwise be accepted and silently mean something else.
set_commands()
Section titled “set_commands()”SurfaceGripperActuator.set_commands(commands: Sequence[Union[GripperCommand, float]]) -> NoneSet commands for multiple gripper instances.
Args:
commands— One command value per instance — each aGripperCommandor a raw float (the two may be mixed).
Raises:
ValueError— If the count does not match the instance count. The check is unconditional: it used to be skipped whenever the count was one, which is also what “not attached yet” reports. An over-long batch would otherwise fail later with a tensor-shape error that does not identify the input.TypeError— If any element is aGripperState.
get_state()
Section titled “get_state()”SurfaceGripperActuator.get_state() -> List[GripperState]Get current gripper state for all instances.
State is valid only for the backend handle used by the last successful
update(). Detaching or replacing that handle, or a failed update,
makes this reader raise instead of letting a policy act on stale state.
Returns:
List of GripperState values, one per instance: - OPEN (-1): Not grasping - CLOSING (0): Attempting to grasp - CLOSED (1): Grasping object Before the first update() the list is the pre-attach placeholder — one OPEN per instance the actuator knows about, which is a single entry until the engine attaches it. Read it after update(dt), not before, if you need one entry per environment.
is_open()
Section titled “is_open()”SurfaceGripperActuator.is_open(instance: int = 0) -> boolCheck if gripper instance is open.
State is valid only for the backend handle used by the last successful
update(). Detaching or replacing that handle, or a failed update,
makes this reader raise instead of letting a policy act on stale state.
Args:
instance— Gripper instance index
Returns:
True if gripper is open
is_closed()
Section titled “is_closed()”SurfaceGripperActuator.is_closed(instance: int = 0) -> boolCheck if gripper instance is closed (grasping).
State is valid only for the backend handle used by the last successful
update(). Detaching or replacing that handle, or a failed update,
makes this reader raise instead of letting a policy act on stale state.
Args:
instance— Gripper instance index
Returns:
True if gripper is closed/grasping
update()
Section titled “update()”SurfaceGripperActuator.update(dt: float) -> NoneUpdate gripper state from simulation.
Args:
dt— Time step in seconds
reset()
Section titled “reset()”SurfaceGripperActuator.reset(env_ids: Optional[Any] = None) -> NoneReset gripper instances to the open state.
Args:
env_ids— Instance indices to reset — a tensor, a sequence of ints, orNonefor all of them. Pass the ids. RL environments reset per-environment (Task.reset_idx(env_ids)), and this actuator is not registered with the scene, so nothing resets it on your behalf; an all-instances reset triggered by one environment terminating physically opens every other gripper mid-grasp. The engine’s ownSurfaceGripper.reset(indices=...)has taken indices all along — this signature is what makes them reachable.