EXAMPLE_FORWARD_KINEMATICS
EXAMPLE_FORWARD_KINEMATICS describes the forward kinematics for 2 or
3-link arms. For both types, the user can choose to use
rotations and translation dual quaternions, or to use screw
motion dual quaternions. For the two-link arm, only the
end-effector position fporward kinematics is computed, while
for the 3-link arm, the end-effector orientation and position
forward kinematics are computed.
The user must specify the arm parameters at the beginning of
this file. Two parameters are important:
- CHOICE_ARM: scalar value equal to:
--> 2 : the two-link arm is chosen
--> 3 : the three-link arm is chosen
- CHOICE_REPRESENTATION: scalar value equal to:
--> 1 : only rotations and translations are considered
--> 2 : screw mùotions are considered
Depending on the option you choose, the end-effector point
(and orientation) position and velocity is displayed.
Contents
parameters to be specified by the user
clear all;
close all;
clc;
choice_arm = 3;
choice_representation = 1;
a = 10;
b = 8;
c = 2;
theta_UB = 0;
axis_UB = [0 0 1]';
Omega_speed_UB = 0;
Omega_axis_UB = [0 0 -1]';
theta_LU = 90;
axis_LU = [0 0 1]';
Omega_speed_LU = 20;
Omega_axis_LU = [0 0 -1]';
if choice_arm == 3
theta_HL = 90;
axis_HL = [0 0 1]';
Omega_speed_HL = 0;
Omega_axis_HL = [0 0 -1]';
end
Forward kinematics of the end-effector of a two-link arm (point transformation)
Using rotations and translations
if choice_representation == 1
R_UB = rot2dquat(theta_UB,axis_UB);
R_LU = rot2dquat(theta_LU,axis_LU);
T_ES = trans2dquat([1 0 0]',a);
Omega_UB = rotvel2dquat(Omega_speed_UB,Omega_axis_UB);
Omega_LU = rotvel2dquat(Omega_speed_LU,Omega_axis_LU);
P_LE = [b 0 0]';
P_LE_dq = pos2dquat(P_LE);
S_tot = DQmult(R_LU,T_ES,R_UB);
P_BS_dq = DQmult(DQconj(S_tot),P_LE_dq,S_tot);
P_BS = dquat2pos(P_BS_dq);
P_UE_dq = DQmult(DQconj(R_LU),P_LE_dq,R_LU);
antisym_LU = 0.5*(DQmult(P_UE_dq,Omega_LU)-DQmult(Omega_LU,P_UE_dq));
antisym_UB = 0.5*(DQmult(P_BS_dq,Omega_UB)-DQmult(Omega_UB,P_BS_dq));
vel_P_BS_dq = antisym_UB + DQmult(DQconj(R_UB),antisym_LU,R_UB);
vel_P_BS = dquat2vel(vel_P_BS_dq);
Using screw motions
elseif choice_representation == 2
d_LU = 0;
axispoint_LU = [a 0 0]';
S_LU = screw2dquat(theta_LU,d_LU,axis_LU,axispoint_LU);
S_LU_dot = screwvel2dquat(Omega_speed_LU,Omega_axis_LU,0,[0 0 0],S_LU);
d_UB = 0;
axispoint_UB = [0 0 0]';
S_UB = screw2dquat(theta_UB,d_UB,axis_UB,axispoint_UB);
S_UB_dot = screwvel2dquat(Omega_speed_UB,Omega_axis_UB,0,[0 0 0],S_UB);
P_BS_0 = [a+b 0 0]';
P_BS_0_dq = pos2dquat(P_BS_0);
S_tot = DQmult(S_LU,S_UB);
P_BS_dq = DQmult(DQconj(S_tot),P_BS_0_dq,S_tot);
P_BS = dquat2pos(P_BS_dq);
P_elbow_dq = DQmult(DQconj(S_LU),P_BS_0_dq,S_LU);
comp_UB_dot = DQmult(DQconj(S_UB_dot),P_elbow_dq,S_UB)+DQmult(DQconj(S_UB),P_elbow_dq,S_UB_dot);
comp_LU_dot = DQmult(DQconj(S_LU_dot),P_BS_0_dq,S_LU)+DQmult(DQconj(S_LU),P_BS_0_dq,S_LU_dot);
vel_P_BS_dq = comp_UB_dot+DQmult(DQconj(S_UB),comp_LU_dot,S_UB);
vel_P_BS = dquat2vel(vel_P_BS_dq);
end
disp('The two-link arm end-effector position (in body-fixed shoulder-centered coordinates) is :');
disp(P_BS);
disp('The two-link arm end-effector velocity (in body-fixed shoulder-centered coordinates) is :');
disp(vel_P_BS);
Forward kinematics of the end-effector of a three-link arm (point and line transformations)
Using rotations and translations
if choice_representation == 1
R_UB = rot2dquat(theta_UB,axis_UB);
R_LU = rot2dquat(theta_LU,axis_LU);
R_HL = rot2dquat(theta_HL,axis_HL);
T_ES = trans2dquat([1 0 0]',a);
T_WE = trans2dquat([1 0 0]',b);
Omega_UB = rotvel2dquat(Omega_speed_UB,Omega_axis_UB);
Omega_LU = rotvel2dquat(Omega_speed_LU,Omega_axis_LU);
Omega_HL = rotvel2dquat(Omega_speed_HL,Omega_axis_HL);
orientation_tool_H = [0 1 0]';
position_tool_HW = [c 0 0]';
L_HW_dq = line2dquat(orientation_tool_H,position_tool_HW);
P_HW_dq = pos2dquat(position_tool_HW);
S_tot = DQmult(R_HL,T_WE,R_LU,T_ES,R_UB);
L_BS_dq = DQmult(DQconj(S_tot,'line'),L_HW_dq,S_tot);
P_BS_dq = DQmult(DQconj(S_tot),P_HW_dq,S_tot);
[orientation_tool_B,r] = dquat2line(L_BS_dq);
P_BS = dquat2pos(P_BS_dq);
orientation_tool_H_dot = [0 0 0]';
position_tool_H_dot = [0 0 0]';
L_HW_dot = linevel2dquat(orientation_tool_H,position_tool_HW,orientation_tool_H_dot,position_tool_H_dot);
P_HW_dot_dq = vel2dquat(position_tool_H_dot);
T_WE_R_LU = DQmult(T_WE,R_LU);
L_LW = DQmult(DQconj(R_HL),L_HW_dq,R_HL);
L_UE = DQmult(DQconj(T_WE_R_LU,'line'),L_LW,T_WE_R_LU);
antisym_UB = 0.5*(DQmult(L_BS_dq,Omega_UB)-DQmult(Omega_UB,L_BS_dq));
antisym_LU = 0.5*(DQmult(L_UE,Omega_LU)-DQmult(Omega_LU,L_UE));
antisym_HL = 0.5*(DQmult(L_LW,Omega_HL)-DQmult(Omega_HL,L_LW));
R_LU_R_UB = DQmult(R_LU,R_UB);
R_tot = DQmult(R_HL,R_LU,R_UB);
L_BS_dot = antisym_UB+...
DQmult(conjDQ(R_UB),antisym_LU,R_UB)+...
DQmult(conjDQ(R_LU_R_UB),antisym_HL,R_LU_R_UB)+...
DQmult(conjDQ(R_tot),L_HW_dot,R_tot);
[orientation_tool_B_dot,MP] = dquat2linevel(L_BS_dot) ;
P_LW = DQmult(DQconj(R_HL),P_HW_dq,R_HL);
P_UE = DQmult(DQconj(T_WE_R_LU),P_LW,T_WE_R_LU);
antisym_P_UB = 0.5*(DQmult(P_BS_dq,Omega_UB)-DQmult(Omega_UB,P_BS_dq));
antisym_P_LU = 0.5*(DQmult(P_UE,Omega_LU)-DQmult(Omega_LU,P_UE));
antisym_P_HL = 0.5*(DQmult(P_LW,Omega_HL)-DQmult(Omega_HL,P_LW));
P_BS_dot_dq = antisym_P_UB+...
DQmult(conjDQ(R_UB),antisym_P_LU,R_UB)+...
DQmult(conjDQ(R_LU_R_UB),antisym_P_HL,R_LU_R_UB)+...
DQmult(conjDQ(R_tot),P_HW_dot_dq,R_tot);
P_BS_dot = dquat2vel(P_BS_dot_dq);
The three-link arm end-effector position (in body-fixed shoulder-centered coordinates) is :
8.0000
8.0000
0
The three-link arm end-effector velocity (in body-fixed shoulder-centered coordinates) is :
2.7925
0.6981
0
The three-link arm end-effector orientation (in body-fixed coordinates) is :
0.0000
-1.0000
0
The three-link arm end-effector orientation rate of change (in body-fixed coordinates) is :
-0.3491
-0.0000
0
Using screw motions
elseif choice_representation == 2
d_HL = 0;
axispoint_HL = [a+b 0 0]';
S_HL = screw2dquat(theta_HL,d_HL,axis_HL,axispoint_HL);
S_HL_dot = screwvel2dquat(Omega_speed_HL,Omega_axis_HL,0,[0 0 0],S_HL);
d_LU = 0;
axispoint_LU = [a 0 0]';
S_LU = screw2dquat(theta_LU,d_LU,axis_LU,axispoint_LU);
S_LU_dot = screwvel2dquat(Omega_speed_LU,Omega_axis_LU,0,[0 0 0],S_LU);
d_UB = 0;
axispoint_UB = [0 0 0]';
S_UB = screw2dquat(theta_UB,d_UB,axis_UB,axispoint_UB);
S_UB_dot = screwvel2dquat(Omega_speed_UB,Omega_axis_UB,0,[0 0 0],S_UB);
orientation_tool_0 = [0 1 0]';
position_tool_0 = [a+b+c 0 0]';
P_BS_0_dq = pos2dquat(position_tool_0);
L_BS_0 = line2dquat(orientation_tool_0,position_tool_0);
S_tot = DQmult(S_HL,S_LU,S_UB);
L_BS = DQmult(DQconj(S_tot,'line'),L_BS_0,S_tot);
P_BS_dq = DQmult(DQconj(S_tot),P_BS_0_dq,S_tot);
[orientation_tool_B,r] = dquat2line(L_BS);
P_BS = dquat2pos(P_BS_dq);
orientation_tool_0_dot = [0 0 0]';
position_tool_0_dot = [0 0 0]';
L_BS_0_dot = linevel2dquat(orientation_tool_0,position_tool_0,orientation_tool_0_dot,position_tool_0_dot);
L_w = DQmult(DQconj(S_HL,'line'),L_BS_0,S_HL);
L_e = DQmult(DQconj(S_LU,'line'),L_w,S_LU);
comp_HL_dot = DQmult(DQconj(S_HL_dot,'line'),L_BS_0,S_HL)+DQmult(DQconj(S_HL,'line'),L_BS_0,S_HL_dot);
comp_LU_dot = DQmult(DQconj(S_LU_dot,'line'),L_w,S_LU)+DQmult(DQconj(S_LU,'line'),L_w,S_LU_dot);
comp_UB_dot = DQmult(DQconj(S_UB_dot,'line'),L_e,S_UB)+DQmult(DQconj(S_UB,'line'),L_e,S_UB_dot);
S_LU_S_UB = DQmult(S_LU,S_UB);
L_BS_dot = DQmult(DQconj(S_tot,'line'),L_BS_0_dot,S_tot)+...
DQmult(DQconj(S_LU_S_UB,'line'),comp_HL_dot,S_LU_S_UB)+...
DQmult(DQconj(S_UB,'line'),comp_LU_dot,S_LU_S_UB)+...
comp_UB_dot;
[orientation_tool_B_dot,MP] = dquat2linevel(L_BS_dot);
P_BS_0_dot_dq = vel2dquat(position_tool_0_dot);
P_w = DQmult(DQconj(S_HL),P_BS_0_dq,S_HL);
P_e = DQmult(DQconj(S_LU),P_w,S_LU);
comp_P_HL_dot = DQmult(DQconj(S_HL_dot),P_BS_0_dq,S_HL)+DQmult(DQconj(S_HL),P_BS_0_dq,S_HL_dot);
comp_P_LU_dot = DQmult(DQconj(S_LU_dot),P_w,S_LU)+DQmult(DQconj(S_LU),P_w,S_LU_dot);
comp_P_UB_dot = DQmult(DQconj(S_UB_dot),P_e,S_UB)+DQmult(DQconj(S_UB),P_e,S_UB_dot);
P_BS_dot_dq = DQmult(DQconj(S_tot),P_BS_0_dot_dq,S_tot)+...
DQmult(DQconj(S_LU_S_UB),comp_P_HL_dot,S_LU_S_UB)+...
DQmult(DQconj(S_UB),comp_P_LU_dot,S_LU_S_UB)+...
comp_P_UB_dot;
P_BS_dot = dquat2vel(P_BS_dot_dq);
end
disp('The three-link arm end-effector position (in body-fixed shoulder-centered coordinates) is :');
disp(P_BS);
disp('The three-link arm end-effector velocity (in body-fixed shoulder-centered coordinates) is :');
disp(P_BS_dot);
disp('The three-link arm end-effector orientation (in body-fixed coordinates) is :');
disp(orientation_tool_B);
disp('The three-link arm end-effector orientation rate of change (in body-fixed coordinates) is :');
disp(orientation_tool_B_dot);