Kinova gen 3 motion issues

11 views (last 30 days)
Quoc Dao
Quoc Dao on 5 Jul 2022
Commented: Quoc Dao on 8 Jul 2022
Currently I have programmed 13 motions for my robotic arm for a project. I want them all to move quickly so I am decreasing the time until I can find a limit for it. However, for some motions, one work while the other doesn't and I can't understand why. Does anyone have a clue why motion 13, 12, 10 and 8 don't work while 11 does? I checked the velocity and inffered acceleration from it, and I can't see any breach of limit based on what I got from kinova gen 3 user guide (should be around page 80 to 90).
count = 0;
year = zeros(10000,1);
month = zeros(10000,1);
day = zeros(10000,1);
hour = zeros(10000,1);
minute = zeros(10000,1);
seconds = zeros(10000,1);
motiontype = zeros(10000,1);
trialnumber = zeros(10000,1);
status = cell(10000,1);
commandprompt = cell(10000,1);
gen3 = loadrobot("kinovaGen3"); %Type 'rigidBodyTree'
gen3.DataFormat = 'column';
q_home = [0 60 180 -90 360 -30 180]'*pi/180;
% q_home = [0 15 180 -130 0 55 90]'*pi/180;
eeName = 'EndEffector_Link'; %Type 'char'
T_home = getTransform(gen3, q_home, eeName); %For more info use...
%https://www.mathworks.com/help/robotics/ref/rigidbodytree.html#:~:text=all%20in%20page-,Description,to%20import%20your%20robot%20model.
% show(gen3,q_home);
% axis auto;
% view([60,10]);
ik = inverseKinematics('RigidBodyTree', gen3);
ik.SolverParameters.AllowRandomRestart = false;
weights = [1, 1, 1, 1, 1, 1];
q_init = q_home;
%Mind the relation between trajectory and time for there are vel limit
center = [0.53 0 0.2]; %[x y z]
% center = [0.5 0 0.4]; %[x y z]
radius = 0.1; %Do not put radius to or above 0.9 with a duration of 10 seconds
dt = 0.25;
t = (0:dt:5)';
theta = t*(2*pi/t(end))-(pi/2);
repeat = true;
n = input(['Which protocol is being used?', '\n(1): Up to down (2): Left to right (3): Front to back', ...
'\n(4): Upper right to lower left (5): Upper left to lower right (6):upper right front to lower left back', ...
'\n(7): Upper left back to lower right front (8): Horizontal circle (9): Vertial circle movement on y/z place (back and forth)', ...
'\n(10): Upper right to lower left circle (11): Upper left to lower right circle (12): Upper front to Lower back circle', ...
'\n(13): Upper back to Lower front circle', '\n ']);
%NOTE: Tilting a trajectory may just mean adding a z coordinate that have
%an appropiate relation to x or y
clock_direction = 0;
while clock_direction ~=-1 && clock_direction ~=1
clock_direction = input(['Clock direction', '\n(1): CW', '\n(-1): CCW', '\n']);
end
while repeat
switch n
case 1
points = center + clock_direction*radius*[0*ones(size(theta)) 0*sin(theta) -sin(theta)];
%Points for up to down movement
repeat = false;
case 2
points = center + clock_direction*radius*[-sin(theta) 0*cos(theta) 0*ones(size(theta))];
%Points for left to right movement
% points = center + radius*[sin(theta)*sin(pi/4) 0*ones(size(theta)) sin(theta)*sin(pi/4)];
%Titled side to side movement
repeat = false;
case 3
points = center + clock_direction*radius*[0*ones(size(theta)) sin(theta) 0*sin(theta)];
%Points for front to back movement
repeat = false;
case 4
points = center + clock_direction*radius*[sin(theta) 0*cos(theta) -sin(theta)];
%Points for upper right to lower left movement
repeat = false;
case 5
points = center + clock_direction*radius*[-sin(theta) 0*cos(theta) -sin(theta)];
%Points for upper left to lower right movement
repeat = false;
case 6
points = center + clock_direction*radius*[sin(theta) sin(theta) -sin(theta)];
%Points for upper right front to lower left back movement
repeat = false;
case 7
points = center + clock_direction*radius*[-sin(theta) -sin(theta) -sin(theta)];
%Points for upper left back to lower right front movement
repeat = false;
case 8
points = center + radius*[sin(theta) clock_direction*cos(theta) 0.5*ones(size(theta))];
% horizontal circle movement
repeat = false;
case 9
% points = center + radius*[sin(theta) 0.5*ones(size(theta)) clock_direction*cos(theta)];
% vertial circle movement on x/z plane
points = center + radius*[0.5*ones(size(theta)) sin(theta) -clock_direction*cos(theta)];
% vertial circle movement on y/z place
repeat = false;
case 10
points = center + radius*[sin(theta)*cos(pi/4) clock_direction*cos(theta) -sin(theta)*sin(pi/4)];
%Upper right to lower left ( 45 degrees, require more review)
repeat = false;
case 11
points = center + radius*[-sin(theta)*cos(pi/4) -clock_direction*cos(theta) -sin(theta)*sin(pi/4)];
%Upper left to lower right( 45 degrees, require more review)
repeat = false;
case 12
points = center + radius*[-clock_direction*cos(theta) sin(theta)*cos(pi/4) -sin(theta)*sin(pi/4)];
%Upper front to Lower back. Tilted circle side to side( 45 degrees, require more review)
repeat = false;
case 13
points = center + radius*[clock_direction*cos(theta) -sin(theta)*cos(pi/4) -sin(theta)*sin(pi/4)];
%Upper back to Lower front. Tilted circle side to side( 45 degrees, require more review)
% points = center + radius*[sin(theta) clock_direction*cos(theta) cos(theta)*tan(pi/3)];
%Tilted circle(elispe?. require more review). Not running for unknown reasons (speed)?
% points = center + radius*[sin(theta) -clock_direction*sin(theta)*sin(pi/4) clock_direction*cos(theta)*cos(pi/4)];
%Interesting application
repeat = false;
otherwise
disp('invalid input, shutting down')
clear;
return
end
end
% hold on;
% plot3(points(:,1),points(:,2),points(:,3),'-*g', 'LineWidth', 1.5);
% xlabel('x');
% ylabel('y');
% zlabel('z');
% axis auto;
% % view([60,10]);
% view([0,60]);
% grid('minor');
numJoints = size(q_home,1);
numWaypoints = size(points,1);
qs = zeros(numWaypoints,numJoints);
for i = 1:numWaypoints
T_des = T_home;
T_des(1:3,4) = points(i,:)'; %Desired position, unknown why only row 1-3 of column 4 is changed
[q_sol, q_info] = ik(eeName, T_des, weights, q_init);
%Solution information related to execution of the algorithm, q_info, is returned with the joint configuration solution, q_sol.
%eeName: End-effector name, specified as a character vector
%T_des: End-effector desired pose
%weights: Weights for pose tolerance The first three elements correspond to the weights on the error in orientation for the desired pose...
%the last three elements correspond to the weights on the error in xyz position for the desired pose.
%q_init: Initial guess of robot configuration, specified as a structure array or vector.
% Display status of ik result
%disp(q_info.Status);
% Store the configuration
qs(i,:) = q_sol(1:numJoints);
% Start from prior solution
q_init = q_sol;
end
% % Visualize the Animation of the Solution
% figure; set(gcf,'Visible','on');
% ax = show(gen3,qs(1,:)');
% ax.CameraPositionMode='manual';
% hold on;
%
% % Plot waypoints
% plot3(points(:,1),points(:,2),points(:,3),'-g','LineWidth',2);
% % axis auto;
% axis ([-1 1 -0.4 0.4 -0.4 0.6]);
% view([60,10]);
% grid('minor');
% hold on;
%
% title('Simulated Movement of the Robot');
% % Animate
% framesPerSecond = 30;
% r = robotics.Rate(framesPerSecond);
% for i = 1:numWaypoints
% show(gen3, qs(i,:)','PreservePlot',false);
% drawnow;
% waitfor(r);
% end
prompt = 'Do you want to send same trajectory to the hardware? y/n [n]: ';
str = input(prompt,'s');
if isempty(str)
str = 'n';
end
if str == 'n'
disp('Operation halted')
clear;
return;
end
cycle = input('Number of cycles?');
%Calculate joint velocity and acceleration at each waypoint with differentiation
qs_deg = qs*180/pi;
vel = diff(qs_deg)/dt;
vel(1,:) = 0;
vel(end+1,:) = 0;
acc = diff(vel)/dt;
acc(1,:) = 0;
acc(end+1,:) = 0;
%Interpolate the joint position, velocity and acceleration to ensure the 0.001 seconds time step between two trajectory points
timestamp = 0:0.001:t(end);
qs_deg = interp1(t,qs_deg,timestamp);
vel = interp1(t,vel,timestamp);
acc = interp1(t,acc,timestamp);
%Connect to the robot
Simulink.importExternalCTypes(which('kortex_wrapper_data.h'));
gen3Kinova = kortex;
gen3Kinova.ip_address = '192.168.1.10';
isOk = gen3Kinova.CreateRobotApisWrapper();
if isOk
disp('You are connected to the robot!');
else
error('Failed to establish a valid connection!');
end
f = figure;
i = 0;
global a
a = 0;
while a < cycle
a = a+1
i = i+1;
set(f,'WindowKeyPressFcn',@keyPressCallback);
pause(3)
if a >= cycle + 1
disp('end of cycle')
clear;
return;
end
% %Verify if user wants to stop each loop
% prompt = 'Do you want to pause? y/n [n]:';
% str = input(prompt,'s');
% if isempty(str)
% str = 'n';
% end
%
% if str == 'y'
% pause
% end
%
%Send Robot to Starting Point of the Trajectory
jointCmd = wrapTo360(qs_deg(1,:));
constraintType = int32(0); % no_constraint: 0; duration: 1; joint_velocity: 2;
speed = 0; %max 25 degrees/s
duration = 9; %min 8 seconds
isOk = gen3Kinova.SendJointAngles(jointCmd, constraintType, speed, duration);
if isOk
disp('success');
else
disp('SendJointAngles cmd error');
return;
end
%Check if the robot has reached the starting position
while 1
[isOk,~, actuatorFb, ~] = gen3Kinova.SendRefreshFeedback();
% show(gen3, ((actuatorFb.position)*pi/180)','PreservePlot',false);
% drawnow;
if isOk
if max(abs(wrapTo360(qs_deg(1,:))-actuatorFb.position)) < 0.1
disp('Starting point reached.')
break;
end
else
error('SendRefreshFeedback error')
end
end
%Send Pre-Computed Trajectory
isOk = gen3Kinova.SendPreComputedTrajectory(qs_deg.', vel.', acc.', timestamp, size(timestamp,2));
if isOk
disp('SendPreComputedTrajectory success');
else
disp('SendPreComputedTrajectory command error');
end
count = count + 1;
time = clock;
year(count,1) = time(1);
month(count,1) = time(2);
day(count,1) = time(3);
hour(count,1) = time(4);
minute(count,1) = time(5);
seconds(count,1) = round(time(6),1);
motiontype(count,1) = n;
trialnumber(count,1) = i;
status(count,1) = {' S'};
commandprompt(count,1) = {' motion start'};
pause(2)
while 1
[isOk,~, actuatorFb, ~] = gen3Kinova.SendRefreshFeedback();
% show(gen3, ((actuatorFb.position)*pi/180)','PreservePlot',false);
% drawnow;
if isOk
if max(abs(wrapTo360(qs_deg(end,:))-actuatorFb.position)) < 0.1
disp('End Point reached.')
break;
end
else
error('SendRefreshFeedback error')
end
end
count = count + 1;
time = clock;
year(count,1) = time(1);
month(count,1) = time(2);
day(count,1) = time(3);
hour(count,1) = time(4);
minute(count,1) = time(5);
seconds(count,1) = round(time(6),1);
motiontype(count,1) = n;
trialnumber(count,1) = i;
status(count,1) = {' E'};
commandprompt(count,1) = {' motion end'};
if a == cycle
disp('protocol finished, shutting down')
end
end
year = year(1:count,1);
month = month(1:count,1);
day = day(1:count,1);
hour = hour(1:count,1);
minute = minute(1:count,1);
seconds = seconds(1:count,1);
motiontype = motiontype(1:count,1);
trialnumber = trialnumber(1:count,1);
status = status(1:count,1);
commandprompt = commandprompt(1:count,1);
T = table(year,month,day,hour,minute, seconds, motiontype, trialnumber, status,commandprompt);
file_time = clock;
file_year = num2str(file_time(1));
file_month = num2str(file_time(2));
file_day = num2str(file_time(3));
file_hour = num2str(file_time(4));
file_minute = num2str(file_time(5));
file_seconds = num2str(round(file_time(6),1));
motion = num2str(n);
filename = append(file_year,'_',file_month,'_',file_day,'_',file_hour,'_',file_minute,'_',file_seconds,'_','Normal_motion','motiontype_',motion,'.xls');
%Colons are not allow in excel name. DO NOT DO IT
writetable(T,filename)
%Immediately skip to another cycle.
%For example, if currently on cycle 4, calling function will cause current
%cycle to be the input value
function keyPressCallback(source,eventdata)
global a
keyPressed = eventdata.Key;
prompt = 'Do you want to skip to a specific cycle? y/n [n]: ';
str = input(prompt,'s');
if isempty(str)
str = 'n';
end
if str == 'n'
return;
end
x = input('Skip to cycle:');
a = x;
end

Accepted Answer

Deep Parikh
Deep Parikh on 8 Jul 2022
Hello,
Based on the Kinova Gen3 manual, the joint velocity and acceleration limits for the cartesian control modes are as following
  • Joint Speed Limit : 50 deg / s
  • Joint Acceleration Limit : For Joint (1-4) 57.3 deg / s^2 , For Joint (5-7) 572.95 deg / s^2
From the analysis of the cases you mentioned, it is evident that cases 13, 12, 10 and 8 violate the joint acceleration limit of 57.3 deg / s^2 while case 11 does not.
A couple of solutions you can try.
  • Increase the time allocated to complete the motion (5 seconds in the current implementation)
  • Increase the joint velocity and acceleration limits of the Kinova Gen3 via the web app (You can set them to maximum, but the robot will move significantly faster)
An Enhancement
  • You can use the cubic interpolation method while using interp1 command to make the robot motion relatively jerk-free.
  1 Comment
Quoc Dao
Quoc Dao on 8 Jul 2022
Hello, thank you so much for your help. It's working to its full capacity now.

Sign in to comment.

More Answers (0)

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!