TUTORIAL T3: Robot modelling, kinematics and differential kinematics

Based on chapter 2 and chapter 7 of Robotics, Vision and Control by Peter Corke.

Based on chapter 7 of Robotics, Vision and Control by Peter Corke.

Based on chapter 8 of Robotics, Vision and Control by Peter Corke.

It uses the The robotics toolbox for MATLAB.

Basic commands for representing position and orientation

Rotation matrices

>> R = rotx(pi/2)
>> trplot(R)
>> tranimate(R)
>> R = rotx(pi/2) * roty(pi/2)
>> trplot(R)

Euler angles ZYZ

Euler angles ZYZ ([\phi,\theta,\psi]) correspond to rotations about moved axes. The equivalent rotation matrix is R = R_z(\phi)R_{y'}(\theta)R_{z''}(\psi):

>> R = rotz(0.1)*roty(0.2)*rotz(0.3)
>> R = eul2r(0.1,0.2,0.3)
>> gamma = tr2eul(R)
>>> EXERCISE
Repeat with theta=-0.2. Note that a different set of Euler angles is returned, i.e. different sets of Euler angles give the same rotation matrix.

The expression of the rotation matrix as a function of the ZYZ-Euler angles is:

../../_images/R-ZYZ.png

And the inverse problem is:

../../_images/ZYZ-R_a.png ../../_images/ZYZ-R_b.png ../../_images/ZYZ-R_c.png

Euler angles RPY

Euler angles RPY ([\theta_r,\theta_p,\theta_y]) correspond to rotations about fixed axes: first \theta_y about x^W, then \theta_p about y^W, finally \theta_r about z^W,. The equivalent rotation matrix is R = R_z(\theta_r)R_y(\theta_p)R_x(\theta_y)

>> R = rotz(0.3)*roty(0.2)*rotx(0.1)
>> R = rpy2r(0.1,0.2,0.3,'zyx')
>> gamma = tr2rpy(R, 'zyx')

Since from version 10 of the Toolbox the ‘zyx’ is the default option, it could be omitted. If, instead, the parameter ‘xyz’ is passed to the rpy2r function then it considers a different definition of the RPY angles where the roll is about the x axis and the yaw about the y axis, i.e. R = R_x(\theta_r)R_y(\theta_p)R_z(\theta_y).

The expression of the rotation matrix as a function of the RPY-Euler angles is:

../../_images/R-RPY.png

And the inverse problem is:

../../_images/ZYZ-R_a.png ../../_images/RPY-R_b.png ../../_images/RPY-R_c.png

Axis-angle

>> R = angvec2r(pi/2,[1 0 0])
>> [theta,v] = tr2angvec(R)

The expression of the rotation matrix as a function of the angle and axis is:

../../_images/R-AngleAxis.png

And the inverse problem is:

../../_images/ZYZ-R_a.png ../../_images/AngleAxis-R.png

Quaternion

>> help UnitQuaternion
>> q1 = UnitQuaternion(R)
>> q1.R
>> q2 = q1.inv
>> q=q1*q2
>> q.R

The expression of the rotation matrix as a function of the quaternion is:

../../_images/R-Q.png

And the inverse problem is:

../../_images/ZYZ-R_a.png ../../_images/Q-R.png

Conversion functions

The following figure shows the conversion between all rotational representations offered by the Robotics Toolbox.

../../_images/rotational_reps.png

Homogeneous Transformations

The following functions create (4x4) matrices that represent homogeneous transformations:

>> T1 = transl(1, 0 ,0)
>> T2 = trotx(pi/2)
>> T = T1*T2
>> trplot(T)
>> R=t2r(T)
>> p=transl(T)

SE3

A class named SE3 is also provided to represent homogeneous transformations. It has many constructor methods, operators and also many operation, conversion, information methods:

>> TT1 = SE3(1,0,0)
>> TT2 = SE3.Rx(pi/2)
>> TTa = SE3(T)
>> about(T)
>> about(TTa)
>> TTb = TT1*TT2
>> res = TTa*TTb.inv
>> res.isidentity
>> help SE3

Robot modelling using DH parameters

The following video summarizes the reference frames used for the definition of the DH parameters used to model robotic manipulators:

The modelling of robotic manipulators is done as follows using the Robotics Toolbox:

Procedure to determine the DH parameters

../../_images/DH-params.png ../../_images/DH-procedure.png

DH parameters convention:

DH parameters for an anthropomorphic arm:

Forward kinematics

The PUMA 560 robot

Use the script provided by the toolbox to load the PUMA 560 robot and the frequently used configurations qz, qr, qs and qn:

>> mdl_puma560
>> p560
>> p560.plot(qz)
>> p560.plot(qr)
>> p560.plot(qs)
>> p560.plot(qn)

Compute the forward kinematics at qz using the fkine method that returns an SE3 element. Clone the robot and repeat after defining a Tool and a Base for the new robot. Verify the differences in the homogeneous transforms.

>> T1 = p560.fkine(qz)
>> p560b = SerialLink(p560, 'name', 'Puma 560b');
>> p560b.tool = transl(0,0,0.2)
>> T2 = p560b.fkine(qz)
>> p560b.base = transl(0,0,1)
>> T3 = p560b.fkine(qz)
>> p560.plot(qz)
>> figure
>> p560b.plot(qz, 'workspace', [-1,1,-1,1,-1,2])

Inverse kinematics

Closed form using the Toolbox

The ikine6s function of the SerialLink class gives a closed form solution of the inverse kinematics for six DOF manipulators with spherical wrist like the Puma 560:

>> qn
>> T = p560.fkine(qn)
>> q1 = p560.ikine6s(T)

Note that q1 is different from qn.

The eight different inverse kinematic solutions can be obtained by specifying:

  • r/l: right arm / left arm.
  • u/d: elbow up / elbow down.
  • f/n: flipped wrist / not flipped wrist.

The default values are: l, u and n.

>> q2 = p560.ikine6s(T, 'ru')
>>> EXERCISE
    Check the other solutions solutions and plot them.

Numerical solution

The ikine function of the SerialLink class gives a numerical solution using differential kinematics, and therefore is useful for any kind of manipulators.

>> qn
>> T = p560.fkine(qn)
>> q1 = p560.ikine(T)

Note that the solution q1 is different from qn. In this case the solution found has the elbow down. With this numerical solution, the solution found depends on the initial configuration (which is defaulted to zero), and can not be explicitly controlled although different solutions can be found by changing the initial configuration:

>> q2 = p560.ikine(T, 'q0', [0 0 3 0 0 0])
>>> EXERCISE
    Check the forward and inverse kinematics for the Universal Robot's UR3.

Geometric Jacobian

The anthropomorphic arm

../../_images/anthropomorphic_arm.png ../../_images/FK_anthropomorphic_arm.png

The Jacobian for three revolute joints is:

J(\mathbf{q}) = \left[ {\begin{array}{c} J_p(\mathbf{q}) \\ J_{\Theta}(\mathbf{q}) \\ \end{array} } \right] = \left[ {\begin{array}{ccc} \mathbf{z}_0 \times (\mathbf{p}_e - \mathbf{p}_0) & \mathbf{z}_1 \times (\mathbf{p}_e - \mathbf{p}_1) & \mathbf{z}_2 \times (\mathbf{p}_e - \mathbf{p}_2) \\ \mathbf{z}_0 & \mathbf{z}_1 & \mathbf{z}_2 \\ \end{array} } \right]

The homogeneous transformations between links are:

A_1^{0}(q_1) = \left[ {\begin{array}{cccc} c_1 & 0 & s_1 & 0 \\ s_1 & 0 & -c_1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ \end{array} } \right],\;\;\;\;\; A_i^{i-1}(q_i) = \left[ {\begin{array}{cccc} c_i & -s_i & 0 & a_i c_i \\ s_i & c_i & 0 & a_i s_i \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ \end{array} } \right] \;\;\; i=2,3.

The origin \mathbf{\tilde{p}}^i_i=[0\; 0\; 0\; 1]^T of the reference frame of link i\in \{0..3\} is represented in the base frame as:

\mathbf{\tilde{p}}_0 = \left[ {\begin{array}{c} 0 \\ 0 \\ 0 \\ 1 \\ \end{array} } \right],\;\;\; \mathbf{\tilde{p}}_1 = A_1^{0}(q_1)\mathbf{\tilde{p}}^1_1 = \left[ {\begin{array}{c} 0 \\ 0 \\ 0 \\ 1 \\ \end{array} } \right],\;\;\; \mathbf{\tilde{p}}_2 = A_1^{0}(q_1)A_2^{1}(q_2)\mathbf{\tilde{p}}^2_2 = \left[ {\begin{array}{c} a_2 c_1 c_2 \\ a_2 s_1 c_2 \\ a_2 s_2 \\ 1 \\ \end{array} } \right],\;\;\; \mathbf{\tilde{p}}_e =\mathbf{\tilde{p}}_3 = A_1^{0}(q_1)A_2^{1}(q_2)A_3^{2}(q_3)\mathbf{\tilde{p}}^3_3 = \left[ {\begin{array}{c} c_1 (a_2 c_2 + a_3 c_{23}) \\ s_1 (a_2 c_2 + a_3 c_{23}) \\ a_2 s_2 + a_3 s_{23} \\ 1 \\ \end{array} } \right].

The z-axes of the link reference frames are:

\mathbf{z}_0 = \left[ {\begin{array}{c} 0 \\ 0 \\ 1 \\ \end{array} } \right],\;\;\; \mathbf{z}_1 = R_1^{0}(q_1)\mathbf{z}_0 = \left[ {\begin{array}{c} s_1 \\ -c_1 \\ 0 \\ \end{array} } \right],\;\;\; \mathbf{z}_2 = R_1^{0}(q_1)R_2^{0}(q_2)\mathbf{z}_0 = \left[ {\begin{array}{c} s_1 \\ -c_1 \\ 0 \\ \end{array} } \right].

Then, the Jacobian results:

J(\mathbf{q}) = \left[ {\begin{array}{ccc} -s_1 (a_2 c_2 + a_3 c_{23}) & -c_1 (a_2 s_2 + a_3 s_{23}) & -a_3 c_1 s_{23}\\ c_1 (a_2 c_2 + a_3 c_{23}) & -s_1 (a_2 s_2 + a_3 s_{23}) & -a_3 s_1 s_{23} \\ 0 & a_2 c_2 + a_3 c_{23} & a_3 c_{23}\\ 0 & s_1 & s_1 \\ 0 & -c_1 & -c_1 \\ 1 & 0 & 0 \\ \end{array} } \right]

Using the robotics toolbox

The Robotics Toolbox provides a method in the SerialLink class that allows to compute the Geometric Jacobian at a given configuration:

>> mdl_puma560
>> J = p560.jacob0(qn)

The Geometric Jacobian J(\mathbf{q}) relates the joint velocities \dot{\mathbf{q}} with the end-effector linear and angular velocities \mathbf{v}=(\dot{x},\dot{y},\dot{z},\omega_x,\omega_y,\omega_z)^T. The function jacbo0 gives the Cartesian velocities of the end-effector measured from the base frame (hence the 0 in the name of the function)

The rows of J are the Cartesian degrees of freedom and the columns the joints, therefore for the 6 degree of freedom Puma 560 manipulator the Jacobian is a (6x6) square matrix.

The (3x3) zero block indicates that the joint velocities of the wrist joints do not have any effect on the linear motion of the end-effector.

The joint velocities required to move along a small velocity in the z-direction are:

>> qd = inv(J)*[0 0 0.1 0 0 0]'

As an example, the robot can be moved along a given velocity v_base defined w.r.t. the base using the Jacobian as follows:

>> v_base = [1,0,0,0,0,0]'
>> Delta = 0.007;
>> qcurrent=qn;
>> qpath=[qcurrent];
>> for i=1:20
>>  qdot=inv(p560.jacob0(qcurrent))*v_base;
>>  qnext = qcurrent + Delta*qdot';
>>  qpath=[qpath; qnext];
>>  qcurrent = qnext;
>> end
>> p560.plot(qpath)
>>> EXERCISE
  Write a Matlab function called qdot that has as input a serial link, a configuration and a desired operational space velocity and returns the joint velocities.

Analytic Jacobian

The anthropomorphic arm

The Analytical Jacobian is:

J_A(\mathbf{q}) = \left[ {\begin{array}{c} J_p(\mathbf{q}) \\ J_{\Phi}(\mathbf{q}) \\ \end{array} } \right] = \left[ {\begin{array}{c} \frac{\partial \mathbf{p}_e}{\partial \mathbf{q}} \\ \frac{\partial \mathbf{\Phi}_e}{\partial \mathbf{q}} \\ \end{array} } \right]

The position of the end effector is:

\mathbf{p}_e = \left[ {\begin{array}{c} c_1 (a_2 c_2 + a_3 c_{23}) \\ s_1 (a_2 c_2 + a_3 c_{23}) \\ a_2 s_2 + a_3 s_{23} \end{array} } \right]

Then, the linear part of the analytical Jacobian becomes:

J_p(\mathbf{q}) = \left[ {\begin{array}{ccc} \frac{\partial x}{\partial q_1} & \frac{\partial x}{\partial q_2} & \frac{\partial x}{\partial q_3} \\ \frac{\partial y}{\partial q_1} & \frac{\partial y}{\partial q_2} & \frac{\partial y}{\partial q_3} \\ \frac{\partial z}{\partial q_1} & \frac{\partial z}{\partial q_2} & \frac{\partial z}{\partial q_3} \\ \end{array} } \right] = \left[ {\begin{array}{ccc} -s_1 (a_2 c_2 + a_3 c_{23}) & -c_1 (a_2 s_2 + a_3 s_{23}) & -c_1 a_3 s_{23}\\ c_1 (a_2 c_2 + a_3 c_{23}) & -s_1 (a_2 s_2 + a_3 s_{23}) & -s_1 a_3 s_{23}\\ 0 & a_2 c_2 + a_3 c_{23} & a_3 c_{23} \end{array} } \right]

The orientation of the end effector is:

\mathbf{\Phi}_e = \left[ \begin{array}{ccc} c_1 c_{23} & -c_1 s_{23} & s_1 \\ s_1 c_{23} & -s_1 s_{23} & -c_1 \\ s_{23} & c_{23} & 0 \end{array} \right] = \left[ \begin{array}{ccc} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \\ \end{array} \right]

The corresponding ZYZ Euler angles are:

\begin{array}{rcl} \phi & = & \textrm{atan2}(r_{23},r_{13}) = \textrm{atan2}(-c_1,s_1) = q_1 - \frac{\pi}{2}\\ \theta & = & \textrm{atan2}(\sqrt{r_{13}^2 + r_{23}^2}, r_{33}) = \textrm{atan2}(1,0) = \frac{\pi}{2}\\ \psi & = & \textrm{atan2}(r_{32},-r_{31}) = \textrm{atan2}(c_{23},-s_{23}) = q_2+q_3+\frac{\pi}{2}\\ \end{array}

Then, the angular part of the analytical Jacobian becomes:

J_\Phi(\mathbf{q}) = \left[ {\begin{array}{ccc} \frac{\partial \phi}{\partial q_1} & \frac{\partial \phi}{\partial q_2} & \frac{\partial \phi}{\partial q_3} \\ \frac{\partial \theta}{\partial q_1} & \frac{\partial \theta}{\partial q_2} & \frac{\partial \theta}{\partial q_3} \\ \frac{\partial \psi}{\partial q_1} & \frac{\partial \psi}{\partial q_2} & \frac{\partial \psi}{\partial q_3} \\ \end{array} } \right] = \left[ {\begin{array}{ccc} 1 & 0 & 0\\ 0 & 0 & 0\\ 0 & 1 & 1\\ \end{array} } \right]

It can be verified that it corresponds to the angular part of the Geometric Jacobian computed above, which are related through matrix T_A(\Phi).

J_\Theta(\mathbf{q}) = T(\Phi) J_\Phi(\mathbf{q}) = \left[ {\begin{array}{ccc} 0 & -s_\phi & c_\phi s_\theta \\ 0 & c_\phi & s_\phi s_\theta \\ 1 & 0 & c_\theta \\ \end{array} } \right] \left[ {\begin{array}{ccc} 1 & 0 & 0\\ 0 & 0 & 0\\ 0 & 1 & 1\\ \end{array} } \right] = \left[ {\begin{array}{ccc} 0 & c_\phi s_\theta & c_\phi s_\theta \\ 0 & -s_\phi s_\theta & -s_\phi s_\theta \\ 1 & c_\theta & c_\theta \\ \end{array} } \right]

Since \phi=q_1-\frac{\pi}{2} and \theta=\frac{\pi}{2}, then c_\phi=s_1, s_\phi=-c_1, c_\theta=0, and s_\theta=1. Therefore, as expected:

J_\Theta(\mathbf{q}) = \left[ {\begin{array}{ccc} 0 & s_1 & s_1 \\ 0 & -c_1 & -c_1 \\ 1 & 0 & 0 \\ \end{array} } \right]

Using the robotics toolbox

The jacob0 method introduced before, gives us the Analytical Jacobian if the parameter `eul` is added:

>> JA = p560.jacob0(qn,'eul')

The relation between the Geometric Jacobian and the Analytic Jacobian is:

J = T_A(\Phi_e) J_A = \left[ {\begin{array}{cc} \mathbf{I}_3 & \mathbf{0}_3 \\ \mathbf{0}_3 & T(\Phi_e) \\ \end{array} } \right] J_A

The Toolbox provides the function eul2jac(phi,theta,psi) that implements the matrix T(\Phi_e), with \Phi_e being the ZYZ Euler angles \Phi_e = [\phi,\theta,\psi]^T.

>> Tn = p560.fkine(qn)
>> Phi_e = Tn.toeul
>> TA = J*inv(JA)
>> T = TA(4:6,4:6)
>> T = eul2jac(Phi_e)

Alternatively to the use of ZYZ Euler angles, RPY angles can be used, and then the expression of the analytical Jacobian and that of matrix T(\Phi_e) vary. Matrix T(\Phi_e) is implemented in the robotics toolbox by the function rpy2jac.

Transforming Velocities between Coordinate Frames

The Jacobian

Consider two frames {A} and {B} related by:

^A T_B = \left[ {\begin{array}{cc} \mathbf{R} & \mathbf{t} \\ 0 & 1 \\ \end{array} } \right]

Then a spatial velocity (or twist) with respect to frame {A} can be expressed relative to frame {B} by:

^B v = \; ^B J_A(\;^A T_B) \;\; ^A v = \left[ {\begin{array}{cc} \mathbf{R}^T & (\mathbf{S}(\mathbf{t})\mathbf{R})^T \\ \mathbf{0}_3 & \mathbf{R}^T \\ \end{array} } \right] \;\; ^A v

where

\mathbf{S}(\mathbf{t}) = \left[ {\begin{array}{ccc} 0 & -t_z & t_y \\ t_z & 0 & -t_x \\ -t_y & t_x & 0 \\ \end{array} } \right]

See pages 174 and 175 of Robotics, Vision and Control by Peter Corke, and pages 149-151 of Robotics: Modelling, planning and control by B. Siciliano et al.

Spacial velocities (or twists) can be composed if they are expressed in the same reference frame. Therefore, this is a useful tool to convert all of them to the same reference frame.

Using the robotics toolbox

The robotics toolbox includes the function tr2jac that computes the above Jacobian. It has as parameter the transform between frame {A} and {B}:

>> T_AB = transl(1, 0, 0)*troty(pi/2);
>> J_BA = tr2jac(T_AB)
>> vA = [1 0 0 0 0 0]';
>> vB = J_BA*vA;
>>> EXERCISE
      Check that effectively  tr2jac implements the matrix shown above.

As an example consider the Base frame of the robot as frame {B} and the Tool frame as frame {A}. A velocity defined in the Tool reference frame can then be expressed in the Base frame:

>> clear;
>> mdl_puma560;
>> q=[0,pi/2,-pi/4,0,pi/4,0]
>> p560.plot(q)
>> v_tool=[0,0,1,0,0,0]'
>> T=p560.fkine(q)
>> Jv=tr2jac(inv(T))
>> v_base=Jv*v_tool

Then, using the Jacobian of the robot, it can be moved along the velocity v_base:

>> Delta = 0.007;
>> qcurrent=q;
>> qpath=[q];
>> for i=1:10
>>  qdot=inv(p560.jacob0(qcurrent))*v_base;
>>  qnext = qcurrent + Delta*qdot';
>>  qpath=[qpath; qnext];
>>  qcurrent = qnext;
>> end
>> p560.plot(qpath)
>>> EXERCISE
    1) Test for other velocities.
    2) Try to move the robot along a velocity composed of a velocity along the z-axis of the tool and another along the z-axis of the base.