Two-link robot: traveling in shortest path between two configurations (no obstacle)
clear all
fig_samples=figure;
n_samples=100; %specify this value
W={[-pi pi],[-pi pi]}; %specify this value
samples(:,1) = W{1}(1,1) +
(W{1}(1,2)-W{1}(1,1))*rand(n_samples,1); % theta_1
componenet
samples(:,2) = W{2}(1,1) +
(W{2}(1,2)-W{2}(1,1))*rand(n_samples,1); % theta_2
componenet
plot(samples(:,1),samples(:,2),'o')
xlim([W{1}(1,1),W{1}(1,2)])
ylim([W{2}(1,1),W{2}(1,2)])
axis square
Some background information
Circular distance between two angles
and
:
Circular distance between two configurations of a two
link robot
and
:
Back to our problem
Let's consider the case that there is no obstacles in the
space.
The code below finds the distance between the samples and
remembers the rotation directions for each angle in going from one configuration to
another.
The cc rotation is noted by 1 and clockwise rotation is
0.
%cc 1
%c 0
sample_set=(1:1:n_samples);
for i=1:n_samples
for
j=setdiff(sample_set,i)
d_cc_theta_1(i,j)=mod((samples(j,1)-samples(i,1)),2*pi);%cc
distance
d_c_theta_1(i,j)=mod((samples(i,1)-samples(j,1)),2*pi); %c
distance
d_circular_theta_1(i,j)=min(d_cc_theta_1(i,j),d_cc_theta_1(i,j));
if d_cc_theta_1(i,j)<=d_c_theta_1(i,j)
rotation_theta_1(i,j)=1; %cc
else
rotation_theta_1(i,j)=0; %c
end
d_cc_theta_2(i,j)=mod((samples(j,2)-samples(i,2)),2*pi); %cc
distance
d_c_theta_2(i,j)=mod((samples(i,2)-samples(j,2)),2*pi); %c
distance
d_circular_theta_2(i,j)=min(d_cc_theta_2(i,j),d_cc_theta_2(i,j));
if d_cc_theta_2(i,j)<=d_c_theta_2(i,j)
rotation_theta_2(i,j)=1; %cc
else
rotation_theta_2(i,j)=0; %c
end
end
end
Now let's pick any two samples and based on the distance
and rotation directions plot the motion for going from one sample to the other.
%the samples we choose
s=10;
g=4;
We set minimum stepsize of angular movement between two
consecutive displacement by `step_size'.
%stepsize of the angular
distance
step_size=10*pi/180;
%here I am using a large angle so you can
see how the motion is taking place from a static plot.
%in you project I want everyone to use
step_size=2.5*pi/180;
if d_circular_theta_1(s,g)>=d_circular_theta_2(s,g)
N_angluar_steps=floor(d_circular_theta_1(s,g)/step_size);
else
N_angluar_steps=floor(d_circular_theta_2(s,g)/step_size);
end
Now we get that angular location as we travel from
configuration s to configuration g (s and g are the chosen samples). Notice that here we are
calling our information encoder matrix rotation_theta_1 and rotation_theta_2 to figure out the
rotation direction between the two configuration for each arm, so we can travel from s to g in
shortest path.
if rotation_theta_1(s,g)==0 %clockwise
theta1_profile=c_motion(samples(s,1),samples(g,1),d_circular_theta_1(s,g)/N_angluar_steps,N_angluar_steps+1);
else
theta1_profile=cc_motion(samples(s,1),samples(g,1),d_circular_theta_1(s,g)/N_angluar_steps,N_angluar_steps+1);
end
if rotation_theta_2(s,g)==0 %clockwise
theta2_profile=c_motion(samples(s,2),samples(g,2),d_circular_theta_2(s,g)/N_angluar_steps,N_angluar_steps+1);
else
theta2_profile=cc_motion(samples(s,2),samples(g,2),d_circular_theta_2(s,g)/N_angluar_steps,N_angluar_steps+1);
end
Now let us plot the motion (this is the part that you
should animate)
l1=1; %length of
arm 1
l2=0.5; %length
of arm 2
figure
for i=1:length(theta1_profile)
plot_robot_config(theta1_profile(i),theta2_profile(i),l1,l2,'c',num2str(i))
hold on
end
%plot_robot_config(theta1(1),theta2(1),l1,l2,'b','start')
%plot_robot_config(theta1(2),theta2(2),l1,l2,'g','goal')
axis square
xlim([-(l1+l2),(l1+l2)])
ylim([-(l1+l2),(l1+l2)])
The followings are functions we use in this demo (comes
from the two_links_motion.mlx). These functions can come handy in your project.
Forward Kinematics to plot a configuration
function plot_robot_config(theta1,theta2,l1,l2,robot_color,config_label)
x_m=l1*cos(theta1);
y_m=l1*sin(theta1);
x_e=x_m+l2*cos(theta1+theta2);
y_e=y_m+l2*sin(theta1+theta2);
line([0,x_m],[0,y_m],'LineWidth',3,'Color',robot_color);
hold on
plot(x_m,y_m,'o','MarkerSize',8,'Color',robot_color);
line([x_m,x_e],[y_m,y_e],'LineWidth',3,'Color',robot_color);
plot(x_e,y_e,'o','MarkerSize',8,'Color',robot_color);
if isempty(config_label)==0
text(0.9*x_e,0.9*y_e,config_label);
end
end
Function for counterclockwise motion
function theta=cc_motion(theta_s,theta_g,step_theta,N)
theta_s_360=mod(theta_s,2*pi);
theta_g_360=mod(theta_g,2*pi);
delta_theta=abs(theta_g_360-theta_s_360);
%counter clockwise motion
if theta_s_360>=theta_g_360
for
t=1:N
theta(t)=theta_s_360+step_theta*(t-1);
if theta(t)>2*pi
theta(t)=mod(theta(t),2*pi);
end
end
else
for
t=1:N
theta(t)=theta_s_360+step_theta*(t-1);
if theta(t)>2*pi
theta(t)=mod(theta(t),2*pi);
end
end
end
end
Function for clockwise motion
%clockwise motion
function theta=c_motion(theta_s,theta_g,step_theta,N)
theta_s_360=mod(theta_s,2*pi);
theta_g_360=mod(theta_g,2*pi);
delta_theta=abs(theta_g_360-theta_s_360);
if theta_s_360>=theta_g_360
for
t=1:N
theta(t)=theta_s_360-step_theta*(t-1);
if theta(t)>2*pi
theta(t)=mod(theta(t),2*pi);
end
end
else
for
t=1:N
theta(t)=theta_s_360-step_theta*(t-1);
if theta(t)>2*pi
theta(t)=mod(theta(t),2*pi);
end
end
end
end