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