DexHand Protocol
The DexHand protocol implements the CANFD communication layer between host and hand hardware.
Core Protocol
Message Types
- class pyzlg_dexhand.dexhand_protocol.MessageType(*values)[source]
 CAN message type identifiers and their base addresses
- COMMAND_READ = 1
 
- COMMAND_WRITE = 2
 
- CONFIG_COMMAND = 0
 
- CONFIG_RESPONSE = 128
 
- ERROR_MESSAGE = 1536
 
- GLOBAL_COMMAND = 255
 
- INVALID = 4096
 
- MOTION_COMMAND = 256
 
- MOTION_FEEDBACK = 384
 
- UNKNOWN = 4097
 
Board IDs
Commands
Command Types
Control Modes
Feedback Modes
Command Classes
- class pyzlg_dexhand.dexhand_protocol.commands.MotorCommand(control_mode, motor_enable, motor1_pos, motor2_pos, motor1_speed, motor2_speed, motor1_current, motor2_current)[source]
 Command for a pair of motors
- 
control_mode: 
ControlMode 
- 
motor1_current: 
int 
- 
motor1_pos: 
int 
- 
motor1_speed: 
int 
- 
motor2_current: 
int 
- 
motor2_pos: 
int 
- 
motor2_speed: 
int 
- 
motor_enable: 
int 
- 
control_mode: 
 
Command Encoding
- pyzlg_dexhand.dexhand_protocol.commands.encode_command(command)[source]
 Encode a command for transmission
- Parameters:
 command (
Union[MotorCommand,ClearErrorCommand,FeedbackConfigCommand,BroadcastCommand,GlobalCommand]) – Command to encode- Return type:
 tuple[MessageType,bytes]- Returns:
 Tuple of (message_type, encoded_bytes)
- Raises:
 ValueError – If command parameters are invalid
Messages
Error Types
Feedback Classes
- class pyzlg_dexhand.dexhand_protocol.messages.MotorFeedback(current, velocity, position, angle, encoder_value=None, error_code=None, impedance=None)[source]
 Feedback data for a single motor
- 
angle: 
float 
- 
current: 
int 
- 
encoder_value: 
Optional[int] = None 
- 
error_code: 
Optional[int] = None 
- 
impedance: 
Optional[float] = None 
- 
position: 
int 
- 
velocity: 
int 
- 
angle: 
 
- class pyzlg_dexhand.dexhand_protocol.messages.TouchFeedback(normal_force, normal_force_delta, tangential_force, tangential_force_delta, direction, proximity, temperature)[source]
 Feedback from touch sensor
- 
direction: 
int 
- 
normal_force: 
float 
- 
normal_force_delta: 
int 
- 
proximity: 
int 
- 
tangential_force: 
float 
- 
tangential_force_delta: 
int 
- 
temperature: 
int 
- 
direction: 
 
- class pyzlg_dexhand.dexhand_protocol.messages.BoardFeedback(motor1, motor2, position_sensor1, position_sensor2, touch=None)[source]
 Complete feedback from a motor control board
- 
motor1: 
MotorFeedback 
- 
motor2: 
MotorFeedback 
- 
position_sensor1: 
float 
- 
position_sensor2: 
float 
- 
touch: 
Optional[TouchFeedback] = None 
- 
motor1: 
 
Message Processing
- class pyzlg_dexhand.dexhand_protocol.messages.ProcessedMessage(sender_id, msg_type, feedback=None, error_info=None)[source]
 Processed message from board
- 
feedback: 
Optional[BoardFeedback] = None 
- 
msg_type: 
MessageType 
- 
sender_id: 
int 
- 
feedback: 
 
- pyzlg_dexhand.dexhand_protocol.messages.process_message(can_id, data)[source]
 Process a received CAN message
- Parameters:
 can_id (
int) – CAN ID of the messagedata (
bytes) – Raw message bytes
- Return type:
 - Returns:
 ProcessedMessage containing decoded information
- Raises:
 ValueError – If message cannot be decoded
Protocol Specification
Message Structure
The protocol uses standard CANFD frames with extended identifiers. Message IDs are constructed as:
Base message type (e.g., 0x100 for motion commands)
Board ID offset (0x01-0x06 for left hand, 0x07-0x0C for right hand)
Command Format
Motor Command:
Byte 0: Control mode
Byte 1: Motor enable flags (0x01=motor1, 0x02=motor2, 0x03=both)
Byte 2-3: Motor 1 position (little endian)
Byte 4-5: Motor 2 position (little endian)
Clear Error Command:
Byte 0: 0x03 (Command prefix)
Byte 1: 0xA4 (Clear error command)
Feedback Config Command:
Byte 0: 0x03 (Command prefix)
Byte 1: 0x74 (Feedback config command)
Byte 2: Feedback mode
Byte 3: Period (10ms units)
Byte 4: Enable flag
Example Usage
Command Generation
from pyzlg_dexhand.dexhand_protocol.commands import (
    MotorCommand,
    ControlMode,
    encode_command
)
# Create motor command
command = MotorCommand(
    control_mode=ControlMode.CASCADED_PID,
    motor_enable=0x03,  # Both motors enabled
    motor1_pos=1000,
    motor2_pos=-2000
)
# Encode for transmission
msg_type, data = encode_command(command)
Message Processing
from pyzlg_dexhand.dexhand_protocol.messages import process_message
# Process received message
can_id = 0x181  # Example: Board 1 feedback
data = b'...'   # Raw message data
result = process_message(can_id, data)
if result.msg_type == MessageType.MOTION_FEEDBACK:
    print(f"Motor 1 position: {result.feedback.motor1.position}")
    print(f"Motor 2 position: {result.feedback.motor2.position}")
elif result.msg_type == MessageType.ERROR_MESSAGE:
    print(f"Error: {result.error.description}")
Notes
Message Flow
Host sends commands using appropriate message type
Hand processes command and returns feedback/response
Any errors are reported via error messages
Error Handling
Check message type from CAN ID
Process messages according to type
Handle errors by: - Parsing error information - Clearing errors when safe - Resuming normal operation