Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

L20 Dexterous Hand

Quick Start

from realhand import L20

with L20(side="left", interface_name="can0") as hand:
    # Set angles
    hand.angle.set_angles([50.0] * 16)

    # Read angles
    data = hand.angle.get_blocking(timeout_ms=500)
    print(data.angles)

Constructor parameters

ParameterTypeDescription
side"left" | "right"Left hand or right hand
interface_namestrCAN interface name, such as "can0"
interface_typestrCAN interface type, default "socketcan". See CAN Bus for Windows usage

Joint Definition

L20 has 16 degrees of freedom distributed across 5 fingers.

IndexNameIdentifier
0Thumb abductionthumb_abd
1Thumb rotationthumb_yaw
2Thumb rootthumb_root1
3Thumb tipthumb_tip
4Index abductionindex_abd
5Index rootindex_root1
6Index tipindex_tip
7Middle abductionmiddle_abd
8Middle rootmiddle_root1
9Middle tipmiddle_tip
10Ring abductionring_abd
11Ring rootring_root1
12Ring tipring_tip
13Pinky abductionpinky_abd
14Pinky rootpinky_root1
15Pinky tippinky_tip

Functional Modules

ModuleDescription
hand.angleJoint angle control and read
hand.speedSpeed control and read
hand.torqueTorque control and read
hand.temperatureTemperature reading
hand.force_sensorForce sensor data
hand.faultFault reading and clearing
hand.versionDevice version information

Unified Streaming Reads

L20 provides a unified event stream interface. Use hand.stream() and hand.start_polling() to retrieve data from all sensors. Polling starts automatically at initialization using default intervals (angles at 60 Hz, force sensors at 30 Hz), so you do not need to call start_polling() manually.

from realhand import L20
from realhand.hand.l20 import SensorSource, AngleEvent, TemperatureEvent

with L20(side="left", interface_name="can0") as hand:
    # You can set multiple sensors and polling intervals (seconds)
    # Calling start_polling() again overrides the previous settings
    hand.start_polling({SensorSource.ANGLE: 0.05, SensorSource.TEMPERATURE: 1.0})

    for event in hand.stream():
        match event:
            case AngleEvent(data=ad):
                print(f"Angles: {ad.angles.to_list()}")
            case TemperatureEvent(data=td):
                print(f"Temperature: {td.temperatures.to_list()}")

    hand.stop_polling()
    hand.stop_stream()

start_polling parameter

ParameterTypeDefaultDescription
intervalsdict[SensorSource, float]All defaultsPolling interval in seconds per sensor

Available SensorSource values and default rates

ValueDescriptionDefault rate
SensorSource.ANGLEAngles60 Hz
SensorSource.SPEEDSpeedNot polled by default
SensorSource.TORQUETorqueNot polled by default
SensorSource.TEMPERATURETemperatureNot polled by default
SensorSource.FAULTFaultNot polled by default
SensorSource.FORCE_SENSORForce sensors30 Hz

Snapshot

Get the latest cached data from all sensors:

snap = hand.get_snapshot()
print(snap.angle)  # AngleData | None
print(snap.speed)  # SpeedData | None
print(snap.torque)  # TorqueData | None
print(snap.temperature)  # TemperatureData | None
print(snap.fault)  # FaultData | None
print(snap.force_sensor)  # AllFingersData | None