import time import struct import can def can_id_single_motor(motor_id: int) -> int: """ 单电机命令:标识符 = 0x140 + ID(1~32) """ assert 1 <= motor_id <= 32 return 0x140 + motor_id def send_run(bus: can.Bus, motor_id: int): """ 电机运行命令:DATA[0]=0x88,其余 0 """ arb_id = can_id_single_motor(motor_id) data = bytes([0x88, 0, 0, 0, 0, 0, 0, 0]) msg = can.Message(arbitration_id=arb_id, data=data, is_extended_id=False) bus.send(msg) def send_stop(bus: can.Bus, motor_id: int): """ 电机停止命令:DATA[0]=0x81,其余 0 """ arb_id = can_id_single_motor(motor_id) data = bytes([0x81, 0, 0, 0, 0, 0, 0, 0]) msg = can.Message(arbitration_id=arb_id, data=data, is_extended_id=False) bus.send(msg) def send_speed_cmd_a2(bus: can.Bus, motor_id: int, speed_dps: float): """ 速度闭环控制命令1(0xA2): DATA[0]=0xA2 DATA[4..7]=speedControl(int32, little-endian), 0.01 dps/LSB speed_dps: 目标角速度 (deg/s) """ speed_control = int(round(speed_dps / 0.01)) # 0.01 dps/LSB arb_id = can_id_single_motor(motor_id) data = bytearray(8) data[0] = 0xA2 data[1] = 0x00 data[2] = 0x00 data[3] = 0x00 data[4:8] = struct.pack(" float: # 1 rev = 360 deg; rpm -> deg/s return rpm * 360.0 / 60.0 def main(): # 1) 配置你的 CAN 接口(按你的系统改 channel / bustype) # 常见:socketcan: channel="can0" # bus = can.Bus(interface="socketcan", channel="can0", bitrate=1000000) bus = can.Bus(interface="canalystii", channel=0, bitrate=1000000) motor_id = 2 # 2) 使能运行 send_run(bus, motor_id) time.sleep(0.05) # 3) 恒速:例如 30 rpm target_rpm = 100.0 target_dps = rpm_to_dps(target_rpm) # 推荐:循环周期性刷新速度命令(例如 50~200Hz),更稳 try: last_print = 0.0 while True: # 方案A:纯速度闭环(0xA2) send_speed_cmd_a2(bus, 1, target_dps) send_speed_cmd_a2(bus, 2, target_dps) send_speed_cmd_a2(bus, 3, target_dps) # send_speed_cmd_a2(bus, 4, target_dps) # 方案B:带转矩电流限制(0xAD),例如限制 iq=300 # send_speed_cmd_ad(bus, motor_id, target_dps, iq_limit=300) time.sleep(0.01) # 100 Hz if time.time() - last_print > 0.1: st1 = read_status2(bus, 1) st2 = read_status2(bus, 2) st3 = read_status2(bus, 3) # st4 = read_status2(bus, 4) print("status:", [st1, st2, st3]) last_print = time.time() except KeyboardInterrupt: send_stop(bus, 1) send_stop(bus, 2) send_stop(bus, 3) # send_stop(bus, 4) if __name__ == "__main__": main()