Hello, I have been using xm430-w350 motors and I really enjoy using them!
I’d like to ask one question regarding dynamixel SDK.
So to actuate the motors in python, I have been using the following scripts:
def set_command_position(id_position_list):
if connected:
ADDR_PRO_GOAL_POSITION = 116 # Control table address
LEN_PRO_GOAL_POSITION = 4 # Data Byte Length: Note the unit is byte = 8 bits = 2 bits HEX
# Wait until the USB port is released =========================================================================
ttyUSB_data = glob.read_one_data(glob.mem_ttyUSB_data, 'portOccupied')
while ttyUSB_data[0]:
ttyUSB_data = glob.read_one_data(glob.mem_ttyUSB_data, 'portOccupied')
# Occupy the USB port =========================================================================================
data_usb_occupied = {}
data_usb_occupied['portOccupied'] = np.array([1.0])
glob.mem_ttyUSB_data.set(data_usb_occupied)
lock.acquire()
#print("Lock acquired for send command ----------------------------------------------")
# compose sync_write package
groupSyncWrite = GroupSyncWrite(portHandler, packetHandler,
ADDR_PRO_GOAL_POSITION, LEN_PRO_GOAL_POSITION)
num_of_motors = len(id_position_list)
for iter in range(num_of_motors):
DXL_ID = id_position_list[iter][0]
dxl_goal_position = rad2tick(id_position_list[iter][1])
# Allocate goal position value into byte array
# A word = 4 digits HEX number = 16 bits binary number = 0 - 65535, thus 65536 has loword=0 and hiword=1
# LOBYTE and HIBYTE separates low 4 digit HEX into 2 low + 2 high digits and express in DEX
# e.g. 2047 has LOBYTE=255 and HIBYTE=7, since 15 + 15*16 = 255, 255 + 7*16^2 = 2047
param_goal_position = [DXL_LOBYTE(DXL_LOWORD(dxl_goal_position)),
DXL_HIBYTE(DXL_LOWORD(dxl_goal_position)),
DXL_LOBYTE(DXL_HIWORD(dxl_goal_position)),
DXL_HIBYTE(DXL_HIWORD(dxl_goal_position))]
# Add Dynamixel goal position values to the Syncwrite parameter storage
dxl_addparam_result = groupSyncWrite.addParam(DXL_ID, param_goal_position)
if not dxl_addparam_result:
print("[ID:%03d] groupSyncWrite addparam failed" % DXL_ID)
return False
# Syncwrite goal position
dxl_comm_result = groupSyncWrite.txPacket()
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
return False
# Clear syncwrite parameter storage
groupSyncWrite.clearParam()
# Release the USB port =========================================================================================
data_usb_occupied = {}
data_usb_occupied['portOccupied'] = np.array([0.0])
glob.mem_ttyUSB_data.set(data_usb_occupied)
lock.release()
#print("Lock released for send command ----------------------------------------------")
return True
else:
return False
The problem I face so far is that the motors generate different angles although “param_goal_position” in the above code is identical between two different motions.
One thing I noticed was that the issue does not exist anymore if I set the range of the joint angles from 0 to 4096. It seems that when we command the joint angle which is outside the feasible range, sometimes I get the totally random motion even with the same “param_goal_position”.
-
This is what we use as settings in R+ manager:
-
We use 14.1 V as an input voltage to the OpenCM 485 Expansion board.
-
We use Python 3.
I look forward to hearing from you!
Best regards,