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(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]
CAN message type identifiers and their base addresses
- CONFIG_COMMAND = 0
- CONFIG_RESPONSE = 128
- ERROR_MESSAGE = 1536
- 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)[source]
Command for a pair of motors
-
control_mode:
ControlMode
-
motor1_pos:
int
-
motor2_pos:
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
]) – 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
- class pyzlg_dexhand.dexhand_protocol.messages.BoardError(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]
Motor error status
- BOTH_MOTORS_ERROR = 3
- MOTOR1_ERROR = 1
- MOTOR2_ERROR = 2
- class pyzlg_dexhand.dexhand_protocol.messages.ErrorCode(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]
Error codes from protocol
- MOTOR1_CURRENT_OVERLOAD = 1
- MOTOR1_HALL_ERROR = 2
- MOTOR1_PARAM_ERROR = 8
- MOTOR1_STALL_ERROR = 4
- MOTOR2_CURRENT_OVERLOAD = 16
- MOTOR2_HALL_ERROR = 32
- MOTOR2_PARAM_ERROR = 128
- MOTOR2_STALL_ERROR = 64
Feedback Classes
- class pyzlg_dexhand.dexhand_protocol.messages.MotorFeedback(current, velocity, position, angle)[source]
Feedback data for a single motor
-
angle:
float
-
current:
int
-
position:
int
-
velocity:
int
-
angle:
- class pyzlg_dexhand.dexhand_protocol.messages.TactileFeedback(normal_force, normal_force_delta, tangential_force, tangential_force_delta, direction, proximity, temperature)[source]
Feedback from tactile 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, tactile=None, encoder1=0, encoder2=0)[source]
Complete feedback from a motor control board
-
encoder1:
int
= 0
-
encoder2:
int
= 0
-
motor1:
MotorFeedback
-
motor2:
MotorFeedback
-
position_sensor1:
float
-
position_sensor2:
float
-
tactile:
Optional
[TactileFeedback
] = None
-
encoder1:
Message Processing
- class pyzlg_dexhand.dexhand_protocol.messages.ProcessedMessage(sender_id, msg_type, feedback=None, error=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