Dynamixel MX64-AT: U2D2 + Matlab library

  1. What model(s) of servo are you using?
    Dynamixel MX64-AT. 2 servos in series.
    Firmware version: 44
    Return Delay Time: 2 (4 microseconds)
    Status Return Level: 1 (return for read)

  2. Describe your control environment. Include the controller or interface, operating system (and version #) of your computer, and how you are powering your robot.

Controler: U2D2, operated via Matlab R2021a. Microsoft Windows 10 Enterprise Version 10.0.19044 Build 19044. Bench Power Supply, 12VDC.

I am using the following Matlab library: 4202eipi/dxl_sdk_win64_v1_02 at master · lucasb24/4202eipi · GitHub

I used to generate a sinusoidal motion at f = 1 [Hz], theta_max = 15 [deg] peak to peak amplitude, using the matlab code below. Originally I was able to set dt = 0.004 [s], meaning that I only had to wait 4 miliseconds to send a new pulse to muve the servo to the next GOAL_POSITION, which would give me a very smooth motion (high time resolution). Now when using this code I get a very poor behavior, with the servo only moving correctly if I define a dt = 0.068 [s], and the servo vibrates a lot, creating a very noisy motion due to sudden start-stop accelerations throughout the motion.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
loadlibrary(‘dynamixel’,‘dynamixel.h’);

DEFAULT_PORTNUM = 3;
DEFAULT_BAUDNUM = 1;

% Call library
calllib(‘dynamixel’, ‘dxl_initialize’, DEFAULT_PORTNUM, DEFAULT_BAUDNUM);

P_GOAL_POSITION = 30;
P_PRESENT_POSITION = 36;
% BROADCAST_ID = 254;
INST_SYNC_WRITE = 131;
NUM_ACTUATOR = 2;
id = zeros;
for i = 1:NUM_ACTUATOR
id(1, i) = i;
end

% ----- Initial positions for Leader and Follower -----
InitPos_L = 1160;

InitPos_F = 2878;

% Call libraries
calllib(‘dynamixel’,‘dxl_write_word’,id(1),P_GOAL_POSITION,InitPos_L); %leader
calllib(‘dynamixel’,‘dxl_write_word’,id(2),P_GOAL_POSITION,InitPos_F); %follower

%%

frequency = 1.3;
amplitude = 20;
tempPhase = 0;
cycleNumber = 30;

endTime = round((cycleNumber+2*ramp)/frequency);
RampUpEnd = ramp/frequency;
RampDownBegin = endTime-RampUpEnd;

%dt = 0.004; %for one 0.002; two 0.004
dt = 0.034;

countData = round(endTime/dt)+1;
t = 0:dt:endTime;
% t = linspace(0,endTime,countData);
countData=length(t);

Pos1 = zeros;
Pos2 = zeros;
GoalPos1 = zeros;
GoalPos2 = zeros;

for i=1:countData
if t(i)<RampUpEnd
Pos1(i) = (t(i)/RampUpEnd)…
(sin(2pifrequencyt(i)))(amplitude/2);
Pos2(i) = (t(i)/RampUpEnd)…
(sin(2pi
frequencyt(i)+(tempPhasepi/180)))(amplitude/2);
elseif t(i)<=RampDownBegin && t(i)>=RampUpEnd
Pos1(i) = (sin(2
pifrequencyt(i)))(amplitude/2);
Pos2(i) = (sin(2
pifrequencyt(i)+(tempPhasepi/180)))(amplitude/2);
else
Pos1(i) = ((endTime-t(i))/(endTime-RampDownBegin))…
(sin(2pifrequencyt(i)))(amplitude/2);
Pos2(i) = ((endTime-t(i))/(endTime-RampDownBegin))…
(sin(2pi
frequencyt(i)+(tempPhasepi/180)))(amplitude/2);
end
GoalPos1(i) = round(Pos1(i)
(512/45))+ InitPos_L; % leader
GoalPos2(i) = round(Pos2(i)*(512/45))+ InitPos_F; %follower
end

%%
index = 1;
runTime = 0;
PresentPos1 = zeros();
PresentPos2 = zeros();

disp(‘Start’);

while runTime<=endTime
calllib(‘dynamixel’,‘dxl_write_word’,id(1),P_GOAL_POSITION,GoalPos1(index));
calllib(‘dynamixel’,‘dxl_write_word’,id(2),P_GOAL_POSITION,GoalPos2(index));

PresentPos1(index) = (int32(calllib('dynamixel','dxl_read_word',id(1),P_PRESENT_POSITION)));
PresentPos2(index) = (int32(calllib('dynamixel','dxl_read_word',id(2),P_PRESENT_POSITION)));

runTime = runTime+dt;
index = index+1;

end

%%
calllib(‘dynamixel’,‘dxl_terminate’);
unloadlibrary(‘dynamixel’);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Could you please help me with this issue? Maybe suggesting a different library/code example would be useful.

Thank you!