feathersdk.robot.rh56f1_hand.rh56f1_hand Module

RH56F1 EtherCAT Hand Controller - Python API Real-time per-finger control via C++ wrapper using ctypes

class feathersdk.robot.rh56f1_hand.rh56f1_hand.FingerData(finger_id: int, position: int, angle: int, force: int, current: int, temperature: int, error: int, status: int)

Bases: object

Complete data for a single finger

angle: int
current: int
error: int
finger_id: int
force: int
position: int
status: int
temperature: int
class feathersdk.robot.rh56f1_hand.rh56f1_hand.FingerID(*values)

Bases: IntEnum

Finger ID enumeration for RH56F1 hand

INDEX = 4
LITTLE = 1
MIDDLE = 3
RING = 2
THUMB_BEND = 5
THUMB_SIDESWAY = 6
class feathersdk.robot.rh56f1_hand.rh56f1_hand.HandState(fingers: List[FingerData], tactile_sensors: List[TactileSensor], timestamp: float)

Bases: object

Complete hand state

fingers: List[FingerData]
tactile_sensors: List[TactileSensor]
timestamp: float
class feathersdk.robot.rh56f1_hand.rh56f1_hand.RH56F1Hand(lib_path: str | None = None, master_index: int = 0, slave_position: int = 0)

Bases: object

Python wrapper for RH56F1 EtherCAT hand controller with per-finger data access

This class provides a Pythonic interface to the C++ EtherCAT library, giving you C++ real-time performance with Python convenience.

Finger Numbering (from user manual):

1: Little finger 2: Ring finger 3: Middle finger 4: Index finger 5: Thumb (bend) 6: Thumb (sidesway)

Parameter Ranges:
  • Angle: 0-3600 (0.1 degree units, e.g., 1700 = 170.0°)

  • Force: 0-1000 (device-specific units)

  • Speed: 0-5000 (device-specific units)

ANGLE_MAX = 1800
ANGLE_MIN = 600
FINGER_ANGLE_LIMITS = {FingerID.LITTLE: (900, 1740), FingerID.RING: (900, 1740), FingerID.MIDDLE: (900, 1740), FingerID.INDEX: (900, 1740), FingerID.THUMB_BEND: (1100, 1450), FingerID.THUMB_SIDESWAY: (600, 1800)}
FORCE_MAX = 1000
FORCE_MIN = 0
PDO_MAP = {'angle': (6, 6), 'current': (18, 6), 'error': (24, 6), 'force': (12, 6), 'position': (0, 6), 'status': (30, 6), 'tactile': 42, 'temperature': (36, 6)}
PDO_OUTPUT_MAP = {'angle_cmd': (1, 6), 'enable_set': 0, 'force_cmd': (7, 6), 'speed_cmd': (13, 6)}
SPEED_MAX = 5000
SPEED_MIN = 0
__del__()

Destructor: release master when the hand object is garbage-collected.

__enter__()

Context manager entry

__exit__(exc_type, exc_val, exc_tb)

Context manager exit: release master when leaving the with block.

__init__(lib_path: str | None = None, master_index: int = 0, slave_position: int = 0)

Initialize the hand controller

Parameters:
  • lib_path – Path to librh56f1.so (auto-detected if None)

  • master_index – EtherCAT master index (default: 0)

  • slave_position – EtherCAT slave position (default: 0)

calculate_array_index(finger_id: FingerID, pdo_name: str) int
cleanup()

Stop the control loop and deactivate the master, but keep the reservation so start() can be called again without re-requesting the master (avoids ‘Device or resource busy’ on abort/restart).

clear_all_outputs() bool

Clear all output values and disable motion

This stops all movement by: 1. Setting ENABLE_SET to 0 (disable) 2. Zeroing all angle, force, and speed commands

Use this when you want to stop the hand from moving.

Returns:

True if successful

clear_errors() bool

Clear all device errors (SDO 0x2000:03), returns True if successful, False otherwise.

destroy()

Release the EtherCAT master and free resources. Call when the hand will not be used again (e.g. process exit).

disable_hand() bool

Disable hand motion control. Returns True if successful, False otherwise.

enable_hand() bool

Enable motion control for all fingers. Returns True if successful, False otherwise.

get_all_angles() List[int]

Get angles for all fingers

get_all_currents() List[int]

Get currents for all fingers

get_all_fingers_data() List[FingerData]

Returns a list of FingerData objects for all fingers

get_all_forces() List[int]

Get forces for all fingers

get_all_inputs() List[int] | None

Get all 76 input values (raw)

get_all_tactile_sensors() List[TactileSensor]

Returns a list of TactileSensor objects for all tactile sensors (5 finger sensors + 3 palm sensors)

get_all_temperatures() List[int]

Get temperatures for all fingers

get_error() str | None

Get last error message

get_errors() Dict[int, int]

Get error codes for all fingers (only non-zero errors)

get_finger_angle(finger_id: FingerID) int | None

Returns the angle of actuator for a specific finger (0x6000:07-0C ANGLEACT) in 0.1 degree units (e.g., 1700 = 170.0 degrees)

get_finger_current(finger_id: FingerID) int | None

Returns the current for a specific finger (0x6000:13-18 CURACT)

get_finger_data(finger_id: FingerID) FingerData | None

Returns FingerData object for a specific finger

get_finger_error(finger_id: FingerID) int | None

Returns the error code for a specific finger (0x6000:19-1E ERROR), 0 = no error

get_finger_force(finger_id: FingerID) int | None

Returns the force value for a specific finger (0x6000:0D-12 FORCEACT)

get_finger_position(finger_id: FingerID) int | None

Returns the actuator position for a specific finger (0x6000:01-06 POSACT)

get_finger_status(finger_id: FingerID) int | None

Returns the status for a specific finger (0x6000:1F-24 STATUS)

get_finger_temperature(finger_id: FingerID) int | None

Returns the temperature in °C for a specific finger (0x6000:25-2A TEMP)

get_hand_state() HandState

Returns a HandState object with all finger and sensor data

get_input(index: int) int | None

Get specific input value by index (0-75)

get_output(index: int) int

Get cached output value by index (0-18)

get_tactile_sensor(sensor_id: TactileSensorID) TactileSensor | None

Get tactile sensor data (0x6000:2B-4C)

Based on PDO table: - Finger sensors (1-5): 5 values each (Normal, Tangential, Direction, ProximityL, ProximityH) - Palm sensors (6-8): 3 values each (Normal, Tangential, Direction) - NO proximity values

Parameters:

sensor_id – Sensor ID (1-5 for finger sensors, 6-8 for palm sensors)

Returns:

TactileSensor object with NormalForce, TangentialForce, Direction, ProximityValue or None

initialize() bool

Initialize the EtherCAT controller. Retries once after 2.5s if master is busy (e.g. after previous Robot aborted).

property is_initialized: bool

True if the controller has been initialized and not yet cleaned up.

is_running() bool

Check if controller is running

move(open_percent: List[float], force: int | List[int] | None = None, speed: int | List[int] | None = None, enable: bool = True) bool

Control all 6 fingers by open percentage (0 = fully closed, 1 = fully open).

Parameters:
  • open_percent – List of 6 values in [0, 1] for [little, ring, middle, index, thumb_bend, thumb_sidesway].

  • force – Force limit(s). Single int (0-1000) for all fingers, or list of 6 ints. Default: FORCE_MAX.

  • speed – Speed limit(s). Single int (0-5000) for all fingers, or list of 6 ints. Default: SPEED_MAX.

  • enable – Enable all motors (default: True).

Returns:

True if all successful, False otherwise.

print_hand_state()

Print a formatted view of the complete hand state

print_output_state()

Print current output values being sent to the device

read_sdo(index: int, subindex: int) int | None

Read an SDO (Service Data Object) from the device

set_all_fingers_control(angles: List[int], forces: List[int], speeds: List[int], enable: bool = True) bool

Control all 6 fingers at once

Parameters:
  • angles – List of 6 target angles [little, ring, middle, index, thumb_bend, thumb_sidesway]

  • forces – List of 6 force limits (one per finger)

  • speeds – List of 6 speed limits (one per finger)

  • enable – Enable all motors (default: True)

Returns:

True if all successful, False otherwise

set_finger_control(finger_id: FingerID, angle: int, force: int, speed: int, enable: bool = True) bool

Control a specific finger

Parameters:
  • finger_id – FingerID (1-6)

  • angle – Target angle (0-3600 = 0-360 degrees in 0.1 degree units)

  • force – Force/torque limit (0-1000)

  • speed – Speed limit (0-5000)

  • enable – Enable motor (default: True)

Returns:

True if successful, False otherwise

set_output(index: int, value: int) bool

Set specific output value by index (0-18)

start() bool

Start the real-time control loop

stop() bool

Stop the real-time control loop and clear all outputs

wait_for_operational(timeout: float = 5.0, check_interval: float = 0.1) bool

Wait for the device to enter operational state and start providing data

Parameters:
  • timeout – Maximum time to wait in seconds (default: 5.0)

  • check_interval – How often to check for data in seconds (default: 0.1)

Returns:

True if device is operational (providing non-zero data), False if timeout

Note

The EtherCAT device typically takes 2-3 seconds to transition through INIT → PREOP → SAFEOP → OPERATIONAL states after starting.

write_sdo(index: int, subindex: int, value: int) bool

Write an SDO (Service Data Object) to the device

class feathersdk.robot.rh56f1_hand.rh56f1_hand.TactileSensor(normal_force: int, tangential_force: int, direction: int, proximity_low: int, proximity_high: int)

Bases: object

Tactile sensor data for one sensor

direction: int
normal_force: int
proximity_high: int
proximity_low: int
tangential_force: int
class feathersdk.robot.rh56f1_hand.rh56f1_hand.TactileSensorID(*values)

Bases: IntEnum

Sensor ID enumeration for RH56F1 hand

INDEX = 4
LITTLE = 1
MIDDLE = 3
PALM_LEFT = 6
PALM_MIDDLE = 7
PALM_RIGHT = 8
RING = 2
THUMB = 5