这是一个用于控制ZDT闭环驱动板的Python SDK,支持通过SLCAN接口进行CAN通信。
注意:获取全部状态的接口可能存在问题
- 🚀 简单易用的API - 提供直观的高级接口
- 🔧 完整的功能支持 - 支持所有ZDT驱动板功能
- 🔄 多种控制模式 - 力矩模式、速度模式、位置模式
- 📡 SLCAN通信 - 通过串口发送CAN帧,支持CANable等设备
- 🎯 精确控制 - 支持梯形曲线运动规划
- 🏠 回零功能 - 完整的原点回零支持
- 🔗 多机同步控制 - 支持真正的多电机同步运动,基于官方上位机同步机制
- 🛡️ 错误处理 - 完善的异常处理机制
- 📊 实时监控 - 实时状态和参数监控
- 🧪 交互式测试 - 内置多种测试工具
- 闭环驱动板
- CANable、CANtact或其他SLCAN兼容的USB转CAN设备
- CAN总线速率设置为500K
pip install pyserial将Control_Core文件夹复制到您的项目目录中。
from Control_Core import ZDTMotorController
# 创建电机控制器 (默认COM18, 500000波特率, 电机ID=1)
with ZDTMotorController() as motor:
# 使能电机
motor.enable()
# 位置控制
motor.move_to_position(90.0, speed=200)
motor.wait_for_position()
# 速度控制
motor.set_speed(100)
# 获取状态
position = motor.get_position()
speed = motor.get_speed()
print(f"位置: {position:.2f}度, 速度: {speed:.2f}RPM")from Control_Core import ZDTMotorController
# 广播控制器(统一触发或统一控制)
broadcast = ZDTMotorController(motor_id=0, port='COM18')
# 多电机
a = ZDTMotorController(motor_id=1, port='COM18')
b = ZDTMotorController(motor_id=2, port='COM18')
broadcast.connect()
a.can_interface = broadcast.can_interface
b.can_interface = broadcast.can_interface
a.control_actions.enable()
b.control_actions.enable()
# 使用同步标志:先缓存不执行
a.control_actions.move_to_position(position=-3600, speed=1000, multi_sync=True)
b.control_actions.move_to_position_trapezoid(position=7200, max_speed=1000, acceleration=2000, deceleration=2000, multi_sync=True)
# 统一触发同时开始
broadcast.control_actions.sync_motion()python test_interactive.py功能包括:
- 📡 连接管理(自动或手动配置)
- 🔋 基础控制(使能、失能、停止)
- 📊 状态读取(位置、速度、温度等)
- 🏃 运动控制(速度、位置、力矩模式)
- 🏠 回零功能(触发回零、参数设置)
- 🔧 工具功能(位置清零、解除堵转保护)
- 📝 日志级别设置
python test_multi_motor_sync.py核心特性:
- 🔄 真正的多机同步控制 - 基于官方上位机同步机制
- 📡 CAN总线共享 - 多个电机共享一个CAN接口
- 🎯 同步运动配置 - 支持直通位置、梯形位置、速度模式同步
- 📊 实时监控 - 串行状态读取,避免通信冲突
- 🔍 诊断工具 - 基础CAN诊断、分步连接测试
- 🚀 快速测试 - 一键执行示例同步运动
主要功能:
- 连接管理(配置电机、CAN诊断、分步测试)
- 状态监控(显示状态、实时监控、简化检查)
- 基础控制(单电机控制、批量使能/失能)
- 多机同步控制(配置同步运动、执行同步运动)
- 广播控制(广播命令测试)
- 回零功能(多电机回零)
- 工具功能(日志设置、报告导出)
主要的电机控制器类,提供所有控制功能。
motor = ZDTMotorController(
motor_id=1, # 电机ID (0=广播, 1-255=单机)
interface_type="slcan", # 接口类型(默认slcan)
port="COM18", # 串口号
baudrate=500000 # 串口波特率
)连接/控制器
| 方法 | 说明 |
|---|---|
connect(motor_id=None) |
连接 CAN 接口并绑定电机 ID(未在构造中提供时需在此指定) |
disconnect() |
断开连接并释放共享/私有接口资源 |
set_motor_id(motor_id) |
动态切换当前控制的电机地址(0=广播,1-255=单机) |
send_broadcast_command(command_data) |
以广播地址(0)下发命令,不等待响应 |
multi_motor_command(per_motor_commands, expected_ack_motor_id=1, timeout=1.0, wait_ack=True, mode=None) |
Y 板专用 Y42 聚合多机命令;单次调用仅允许控制类(F5/F6/FB/FD)或读取类(0x36)之一,禁止混合 |
control_actions.sync_motion() |
触发多机同步运动(X 板用于带同步标志命令的统一启动) |
基础控制(ControlActionsModule / TriggerActionsModule)
| 方法 | 说明 |
|---|---|
enable(multi_sync=False) |
使能电机(可带多机同步标志) |
disable(multi_sync=False) |
失能电机(可带多机同步标志) |
stop(multi_sync=False) |
立即停止(可带多机同步标志) |
emergency_stop() |
紧急停止(先停再失能,确保安全) |
clear_position() |
将当前机械角度清零为 0° |
release_stall_protection() |
解除堵转保护状态 |
trigger_encoder_calibration() |
触发编码器校准流程 |
运动控制(ControlActionsModule)
| 方法 | 说明 |
|---|---|
set_torque(current, current_slope=DEFAULT_CURRENT_SLOPE, multi_sync=False) |
力矩模式,单位 mA,支持正负方向;current_slope 为电流斜率 |
set_speed(speed, acceleration=DEFAULT_ACCELERATION, multi_sync=False) |
速度模式,速度单位 RPM(可正负),加速度单位 RPM/s |
move_to_position(position, speed=DEFAULT_SPEED, is_absolute=False, multi_sync=False, timeout=1.0) |
直通限速位置模式,位置单位度;is_absolute=True 为绝对位置,默认相对 |
move_to_position_trapezoid(position, max_speed=DEFAULT_SPEED, acceleration=DEFAULT_ACCELERATION, deceleration=DEFAULT_ACCELERATION, is_absolute=False, multi_sync=False, timeout=1.0) |
梯形曲线位置模式,含独立加减速度限制 |
回零(HomingCommandsModule / ControlActionsModule)
| 方法 | 说明 |
|---|---|
start_homing(homing_mode=None, multi_sync=False) |
开始回零;不指定则就近回零(见 Parameters.HOMING_MODE_*) |
force_stop_homing() / stop_homing() |
强制停止回零流程 |
set_zero_position(save_to_chip=True) |
将当前位置设为零点,可选择保存至芯片 |
modify_homing_parameters(...) |
修改回零参数(模式、方向、速度、超时、碰撞检测、是否自启等) |
get_homing_status() -> HomingStatus |
获取回零状态标志(编码器就绪、是否在回零、是否失败等) |
wait_for_homing_complete(timeout=30.0, check_interval=0.5) -> bool |
阻塞等待回零完成/失败 |
is_homing_in_progress() -> bool / is_homing_failed() -> bool / is_encoder_ready() -> bool |
回零便利查询 |
读取与监控(ReadParametersModule)
| 方法 | 说明 |
|---|---|
get_motor_status() -> MotorStatus |
基本状态(使能/到位/堵转/堵转保护) |
get_position() -> float |
实时位置(度) |
get_speed() -> float |
实时转速(RPM) |
get_position_error() -> float |
位置误差(度) |
get_temperature() -> float |
驱动器温度(°C) |
get_bus_voltage() -> float |
总线电压(V) |
get_current() -> float |
相电流(A) |
get_bus_current() -> float |
总线平均电流(A) |
get_version() -> Dict |
固件/硬件版本(解析成人类可读) |
get_resistance_inductance() -> Dict |
相电阻/相电感(含原始单位与换算) |
get_target_position() -> float |
目标位置(度) |
get_realtime_target_position() -> float |
实时设定目标位置(度) |
get_encoder_raw() -> float |
编码器原始度数(0-16383→0-360°) |
get_encoder_calibrated() -> float |
线性化后编码器度数(0-65535→0-360°) |
get_pulse_count() -> int |
实时脉冲数 |
get_input_pulse() -> int |
输入脉冲数 |
get_status_info() -> Dict |
汇总常用状态信息(容错聚合) |
get_drive_parameters() -> DriveParameters |
驱动配置全集(新增) |
get_system_status() -> SystemStatus |
系统状态全集(含标志位展开,新增) |
参数修改(ModifyParametersModule)
| 方法 | 说明 |
|---|---|
modify_drive_parameters(params, save_to_chip=True) / set_drive_parameters(params, save_to_chip=True) |
应用驱动参数(可选择保存至芯片) |
modify_drive_parameters_with_validation(params, save_to_chip=True) |
带参数校验的驱动参数应用 |
create_default_drive_parameters() / create_open_loop_drive_parameters() / create_high_precision_drive_parameters() |
提供常用预设,返回 DriveParameters |
modify_control_mode(control_mode, save_to_chip=True) |
修改控制模式(0=开环,1=闭环FOC) |
modify_current_limits(open_loop_current=None, closed_loop_max_current=None, save_to_chip=True) |
修改开环/闭环电流限制(mA) |
modify_speed_limit(max_speed_limit, save_to_chip=True) |
修改最大转速限制(RPM) |
modify_stall_protection(enabled, speed_threshold=None, current_threshold=None, time_threshold=None, save_to_chip=True) |
修改堵转保护启用与阈值 |
modify_communication_settings(uart_baudrate=None, can_baudrate=None, save_to_chip=True) |
修改 UART/CAN 速率选项 |
validate_drive_parameters(params) |
对 DriveParameters 进行范围/一致性检查 |
get_baudrate_options() -> dict |
UART/CAN 速率选项映射表 |
set_pid_parameters(...) |
设置 PID(占位;当前以日志提示为主) |
set_baudrate(baudrate) / set_acceleration_limits(max_acceleration) / set_speed_limits(max_speed) / set_current_limits(max_current) / set_homing_parameters(...) / set_encoder_parameters(...) |
兼容占位接口(日志提示为主,协议按后续实现) |
板型提示:X 板不支持
multi_motor_command,应使用各命令multi_sync=True并最终以sync_motion()同步启动;Y 板支持multi_motor_command聚合,但控制类与读取类命令不得混在同一调用中。
| 方法 | 说明 |
|---|---|
get_position() |
获取当前位置(度) |
get_speed() |
获取当前转速(RPM) |
get_temperature() |
获取驱动器温度(°C) |
get_bus_voltage() |
获取总线电压(V) |
get_current() |
获取相电流(A) |
get_motor_status() |
获取电机状态 |
get_status_info() |
获取完整状态信息 |
get_drive_parameters() |
获取驱动参数(新增) |
get_system_status() |
获取完整系统状态(新增) |
| 方法 | 说明 |
|---|---|
set_zero_position() |
设置当前位置为零点 |
start_homing() |
开始回零 |
stop_homing() |
停止回零 |
wait_for_homing_complete() |
等待回零完成 |
- 新增模式(API 传参):
homing_mode=4回到绝对位置坐标零点homing_mode=5回到上次掉电位置角度
- 同步控制(API 传参):
multi_sync=False立即执行该命令multi_sync=True先缓存,待调用control_actions.sync_motion()统一触发后同时开始
- 注意:使用
start_homing(homing_mode: int, multi_sync: bool)即可,接线/参数需符合各回零模式要求,请按“原点回零”章节操作。
# 紧急停止(立即停止电机并进入安全状态)
motor.trigger_actions.emergency_stop()
# 编码器校准
after_ok = motor.trigger_actions.trigger_encoder_calibration()
# 清零位置
motor.trigger_actions.clear_position()
# 解除堵转保护
motor.trigger_actions.release_stall_protection()
# 恢复出厂设置(谨慎执行)
motor.trigger_actions.factory_reset()| 方法 | 说明 |
|---|---|
is_enabled() |
检查电机是否使能 |
is_in_position() |
检查电机是否到位 |
is_stalled() |
检查电机是否堵转 |
wait_for_position() |
等待电机到位 |
- 广播(X/Y):用
motor_id=0控制器直接调用控制方法,所有电机同时执行相同命令。 - 同步标志(X/Y):各电机调用控制方法时设置
multi_sync=True先缓存,最后调用control_actions.sync_motion()统一触发。 - 多机聚合(Y 板):用
multi_motor_command(..., mode='control'|'read')聚合不同电机的指令一次下发;控制类与读取类需分两次调用。
# 1. 创建控制器并连接
broadcast = ZDTMotorController(motor_id=0, port='COM18')
motor1 = ZDTMotorController(motor_id=1, port='COM18')
motor2 = ZDTMotorController(motor_id=2, port='COM18')
broadcast.connect()
motor1.can_interface = broadcast.can_interface
motor2.can_interface = broadcast.can_interface
# 2. 使能电机
motor1.control_actions.enable()
motor2.control_actions.enable()
# 3. 发送带同步标志的命令
motor1.control_actions.move_to_position(position=-3600, speed=1000, sync_flag=0x01)
motor2.control_actions.move_to_position_trapezoid(
position=7200, max_speed=1000, acceleration=2000,
deceleration=2000, sync_flag=0x01
)
# 4. 触发同步运动
broadcast.can_interface.send_command_and_receive_response(
motor_id=0, command=[0x00, 0xFF, 0x66, 0x6B]
)- 直通位置模式同步:所有电机同时开始位置运动
- 梯形位置模式同步:所有电机同时开始梯形曲线运动
- 速度模式同步:所有电机同时开始速度运动
- 混合模式同步:不同电机可以使用不同的运动模式
// 本文面向应用层开发者,底层协议细节省略。若需协议/字节级细节,请参考底层README。
- CANable (推荐)
- CANtact
- 其他支持SLCAN协议的USB转CAN设备
- P_Serial设置: 必须设置为
CAN1_MAP - CAN速率: 设置为500K
- 电机ID: 设置为1-255之间的唯一值(多机时每个电机ID必须不同)
- 接线: 确保CAN_H和CAN_L正确连接
电脑(COM18) ←→ CANable ←→ CAN总线 ←→ ZDT驱动板1(ID=1)
├→ ZDT驱动板2(ID=2)
└→ ZDT驱动板N(ID=N)
SDK提供了完善的异常处理机制:
from Control_Core import (
MotorNotEnabledException,
StallProtectionException,
TimeoutException,
CANInterfaceException
)
try:
motor.move_to_position(180)
except MotorNotEnabledException:
print("电机未使能,请先使能电机")
motor.enable()
except StallProtectionException:
print("电机堵转,解除保护")
motor.release_stall_protection()
except TimeoutException:
print("通信超时")
except CANInterfaceException as e:
print(f"CAN接口错误: {e}")A: 检查以下项目:
- 串口号是否正确(通过设备管理器确认)
- 是否有其他程序占用串口(如CANgaroo)
- ZDT驱动板是否正确上电
- P_Serial是否设置为CAN1_MAP
A: 检查以下项目:
- 电机ID是否正确
- CAN总线连接是否正常
- 驱动板CAN速率是否为500K
- 是否先使能了电机
A: 检查以下项目:
- 每个电机的ID是否唯一且正确
- 是否正确发送了带同步标志(0x01)的命令
- 是否发送了广播同步命令(00 FF 66 6B)
- 所有电机是否都已使能
- CAN总线连接是否稳定
A:
- 使用多机测试工具的"基础CAN诊断"功能
- 使用"分步连接测试"逐个检查电机
- 设置DEBUG日志级别:
from Control_Core import setup_logging
import logging
setup_logging(logging.DEBUG)A:
- 使用"简化状态检查"功能,只读取最基本信息
- 检查是否有多个程序同时访问CAN总线
- 确认电机通信正常(使用单电机测试)
from Control_Core import ZDTMotorController, setup_logging
import logging
import time
# 启用详细日志
setup_logging(logging.INFO)
def multi_motor_sync_demo():
"""多机同步控制演示"""
# 创建控制器
broadcast = ZDTMotorController(motor_id=0, port='COM18')
motor1 = ZDTMotorController(motor_id=1, port='COM18')
motor2 = ZDTMotorController(motor_id=2, port='COM18')
try:
# 连接CAN总线
print("连接CAN总线...")
broadcast.connect()
# 共享CAN接口
motor1.can_interface = broadcast.can_interface
motor2.can_interface = broadcast.can_interface
# 使能电机
print("使能电机...")
motor1.control_actions.enable()
motor2.control_actions.enable()
time.sleep(1)
# 读取初始位置
pos1 = motor1.read_parameters.get_position()
pos2 = motor2.read_parameters.get_position()
print(f"初始位置 - 电机1: {pos1:.2f}°, 电机2: {pos2:.2f}°")
# 配置同步运动
print("配置同步运动...")
print(" 电机1: 直通位置模式 -3600°")
print(" 电机2: 梯形位置模式 7200°")
# 发送带同步标志的命令
motor1.control_actions.move_to_position(
position=-3600, speed=1000, sync_flag=0x01
)
motor2.control_actions.move_to_position_trapezoid(
position=7200, max_speed=1000, acceleration=2000,
deceleration=2000, sync_flag=0x01
)
# 触发同步运动
print("触发同步运动...")
broadcast.can_interface.send_command_and_receive_response(
motor_id=0, command=[0x00, 0xFF, 0x66, 0x6B]
)
# 监控运动过程
print("监控运动过程...")
start_time = time.time()
while time.time() - start_time < 30: # 最多监控30秒
try:
# 读取状态
status1 = motor1.read_parameters.get_motor_status()
status2 = motor2.read_parameters.get_motor_status()
pos1 = motor1.read_parameters.get_position()
pos2 = motor2.read_parameters.get_position()
speed1 = motor1.read_parameters.get_speed()
speed2 = motor2.read_parameters.get_speed()
# 显示状态
elapsed = time.time() - start_time
print(f"[{elapsed:.1f}s] 电机1: {pos1:.1f}° {speed1:.0f}RPM {'到位' if status1.in_position else '运动中'}")
print(f"[{elapsed:.1f}s] 电机2: {pos2:.1f}° {speed2:.0f}RPM {'到位' if status2.in_position else '运动中'}")
# 检查是否都到位
if status1.in_position and status2.in_position:
print("✅ 所有电机已到位,同步运动完成!")
break
time.sleep(2) # 2秒更新一次
except Exception as e:
print(f"状态读取错误: {e}")
time.sleep(1)
# 显示最终位置
final_pos1 = motor1.read_parameters.get_position()
final_pos2 = motor2.read_parameters.get_position()
print(f"最终位置 - 电机1: {final_pos1:.2f}°, 电机2: {final_pos2:.2f}°")
except Exception as e:
print(f"错误: {e}")
finally:
# 断开连接
broadcast.disconnect()
print("✓ 已断开连接")
if __name__ == "__main__":
multi_motor_sync_demo()- v1.0.0 - 初始版本,支持SLCAN通信协议
- v1.1.0 - 添加多机同步控制功能
- 真正的多机同步控制,基于官方上位机同步机制
- 多机同步测试工具 (
test_multi_motor_sync.py) - 串行状态读取,避免CAN通信冲突
- CAN总线诊断和分步连接测试功能
- 完善的错误处理和日志系统
- v1.2.0(新增)
- 模块化架构完善(控制/读取/修改/回零/触发)
- 新增驱动参数读写(
DriveParameters) - 新增系统状态读取(
SystemStatus) - 新增触发动作(
emergency_stop等)
本项目采用MIT许可证。
如有问题或建议,请联系技术支持。