Skip to content

simulo.GripperCommand

Command a gripper actuator ACCEPTS — what you want it to do.

The intent half of the gripper vocabulary (GripperState is the observation half). Pass one to set_command() / set_commands() on any gripper actuator instead of a bare magic number: gripper.set_command(simulo.GripperCommand.CLOSE) says what gripper.set_command(0.5) only implies.

Command Interface:

  • OPEN (-1): Open the gripper.
  • IDLE (0): Hold the current state — command nothing new.
  • CLOSE (1): Close the gripper.

Enum for scripted code, float for policy output: Gripper actuators take either a GripperCommand or a raw float, and the float is not legacy — it is the point. A gripper command is a continuous channel with a dead band:

  • command < open_threshold → open
  • open_threshold <= command <= close_threshold → idle
  • command > close_threshold → close

In RL the policy emits a continuous action and you pass it straight through (gripper.set_commands(actions[:, -1])) — that dead band is what lets a policy hold a grasp instead of chattering. In scripted code you know the intent exactly, and the enum is what makes it readable. Use whichever matches what you have; both go down the same code path.

Example:

import simulo
# Scripted: say the intent.
gripper.set_command(simulo.GripperCommand.CLOSE)
# Learned: pass the policy's own continuous action through, one per
# environment. Values inside the dead band mean "hold".
gripper.set_commands(actions[:, -1])

Backend Mapping: None — and that is deliberate. GripperCommand is an IntEnum, so each member is an int: it flows through the existing torch.tensor(commands, dtype=torch.float32) command path and the threshold comparisons unchanged, with no engine-side change and no conversion at the seam. (Verified, not assumed: torch.tensor([GripperCommand.OPEN, GripperCommand.CLOSE, 0.5], dtype=torch.float32) yields tensor([-1., 1., 0.5]) — enum and float mix freely in one batch.)

Note: The values -1 / 0 / 1 land in the right bands for any thresholds satisfying -1 < open_threshold <= 0 <= close_threshold < 1, which every shipped default does (-0.3 / 0.3). That condition is now enforced, not merely advised: ParallelGripperActuator rejects a threshold pair outside it at construction, and SurfaceGripperActuator takes no thresholds at all — its band is the engine’s own fixed ±0.3. So there is no supported configuration in which these three values mean something other than open / idle / close, and no case where you must “pass floats instead” to work around the thresholds.

Warning: GripperCommand.IDLE and GripperState.CLOSING are both 0 with different meanings — see GripperState’s warning.

Say the intent in scripted code; pass the action through in a policy:

# Scripted: the command names what it does.
gripper.set_command(simulo.GripperCommand.CLOSE)
# Learned: one continuous value per environment, straight from the policy.
gripper.set_commands(actions[:, -1])
class GripperCommand(IntEnum)
Member Value Meaning
OPEN -1
IDLE 0
CLOSE 1