exoskeleton/code/test/torque_control.py

81 lines
2.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
import struct
import can
def arb_id_single(motor_id: int) -> int:
# 单电机命令0x140 + ID(1~32)
return 0x140 + motor_id
def send_cmd(bus, motor_id: int, data8: bytes):
msg = can.Message(
arbitration_id=arb_id_single(motor_id),
data=data8,
is_extended_id=False,
)
bus.send(msg)
def motor_run(bus, motor_id: int):
# 电机运行命令DATA[0]=0x88其余 0
send_cmd(bus, motor_id, bytes([0x88, 0, 0, 0, 0, 0, 0, 0]))
def motor_stop(bus, motor_id: int):
# 电机停止命令DATA[0]=0x81其余 0
send_cmd(bus, motor_id, bytes([0x81, 0, 0, 0, 0, 0, 0, 0]))
def torque_iq_cmd_a1(bus, motor_id: int, iq_control: int):
"""
转矩闭环控制命令 0xA1
DATA[0] = 0xA1
DATA[4..5] = iqControl (int16, little-endian), 范围 -2048~2048
其余字节 0
【协议0xA1iqControl:int16DATA[4]=低字节DATA[5]=高字节】
"""
if not (-2048 <= iq_control <= 2048):
raise ValueError("iq_control must be in [-2048, 2048]")
data = bytearray(8)
data[0] = 0xA1
data[4:6] = struct.pack("<h", int(iq_control)) # little-endian int16
send_cmd(bus, motor_id, bytes(data))
if __name__ == "__main__":
# 前提:你已在系统里把 can0 配置并拉起,例如:
# sudo ip link set can0 type can bitrate 1000000 restart-ms 100
# sudo ip link set can0 up
bus = can.Bus(interface="canalystii", channel=0, bitrate=1000000)
motor_id = 2
iq = 40 # 示例:给一个正向转矩电流指令(注意范围 -2048~2048
try:
motor_run(bus, motor_id)
time.sleep(0.05)
# 建议周期性刷新(例如 100~500 Hz并在“零力矩”时及时归零
dt = 0.01 # 100 Hz
while True:
torque_iq_cmd_a1(bus, 1, iq)
torque_iq_cmd_a1(bus, 2, iq)
torque_iq_cmd_a1(bus, 3, iq)
# torque_iq_cmd_a1(bus, 4, iq)
time.sleep(dt)
except KeyboardInterrupt:
# 松手/退出时,建议先发 0 力矩,再 stop
try:
torque_iq_cmd_a1(bus, 1, 0)
torque_iq_cmd_a1(bus, 2, 0)
torque_iq_cmd_a1(bus, 3, 0)
# torque_iq_cmd_a1(bus, 4, 0)
time.sleep(0.05)
except Exception:
pass
motor_stop(bus, motor_id)
bus.shutdown()