Basics
Architecture Overview
The SDK uses a modular design. All features are accessed through the main class:
L6
├── hand.angle # Angle control
├── hand.speed # Speed control
├── hand.torque # Torque control
├── hand.current # Current reading
├── hand.temperature # Temperature reading
├── hand.force_sensor # Force sensors
├── hand.fault # Fault handling
└── hand.version # Version information
Calling Convention
All features are called through hand.module.method():
from realhand import L6
with L6(side="left", interface_name="can0") as hand:
hand.angle.set_angles([50, 50, 50, 50, 50, 50])
hand.speed.set_speeds([100, 100, 100, 100, 100, 100])
data = hand.temperature.get_blocking()
Type Safety
The SDK provides typed data classes with IDE autocompletion support:
from realhand import L6
from realhand.hand.l6 import L6Angle
with L6(side="left", interface_name="can0") as hand:
# Use a data class (recommended, with type hints)
angle = L6Angle(thumb_flex=50, thumb_abd=30, index=60, middle=60, ring=60, pinky=60)
hand.angle.set_angles(angle)
# Or use a list (more concise)
hand.angle.set_angles([50, 30, 60, 60, 60, 60])
Data class fields:
| Field | Description |
|---|---|
thumb_flex | Thumb flexion |
thumb_abd | Thumb abduction |
index | Index finger |
middle | Middle finger |
ring | Ring finger |
pinky | Pinky |
Data Reading Modes
Blocking Read
Send a request and wait for a response:
data = hand.angle.get_blocking(timeout_ms=100)
Cached Read
Get the most recently received data without blocking:
data = hand.angle.get_snapshot()
if data is not None:
print(data.angles)
Streaming Read
Continuously receive data from the unified event stream:
from realhand.hand.l6 import SensorSource, AngleEvent
hand.start_polling({SensorSource.ANGLE: 0.1})
for event in hand.stream():
match event:
case AngleEvent(data=data):
print(data.angles)
if should_stop():
break
hand.stop_polling()
hand.stop_stream()
Snapshot
Get the latest cached values from all sensors:
snap = hand.get_snapshot()
print(snap.angle) # AngleData | None
print(snap.temperature) # TemperatureData | None
Resource Management
Use a with statement to manage resources automatically:
with L6(side="left", interface_name="can0") as hand:
# Use the hand
pass
# Resources are released automatically
Or manage the lifecycle manually:
hand = L6(side="left", interface_name="can0")
try:
# Use the hand
pass
finally:
hand.close()
Exception Handling
from realhand import L6
from realhand.exceptions import TimeoutError, ValidationError
with L6(side="left", interface_name="can0") as hand:
try:
data = hand.angle.get_blocking(timeout_ms=100)
except TimeoutError:
print("Read timed out")
except ValidationError as e:
print(f"Invalid parameter: {e}")
| Exception | Description |
|---|---|
TimeoutError | Communication timeout |
ValidationError | Parameter validation failed |
StateError | Invalid state, such as a closed device |
Joint Indexing
All 6-joint modules use the same index order:
| Index | Name | Identifier |
|---|---|---|
| 0 | Thumb flexion | thumb_flex |
| 1 | Thumb abduction | thumb_abd |
| 2 | Index finger | index |
| 3 | Middle finger | middle |
| 4 | Ring finger | ring |
| 5 | Pinky | pinky |