Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

License: CC-BY-NC-SA 4.0

Author: Murilo M. Marinho (murilo.marinho@manchester.ac.uk)

Pre-requisites for the learner

The user of this notebook is expected to have prior knowledge in

  • All the content and pre-requisites of lessons 1 and 2.

I found an issue

Thank you! Please report it at https://github.com/MarinhoLab/OpenExecutableBooksRobotics/issues

Latex Macros

\providecommand{\myvec}[1]{{\mathbf{\boldsymbol{{#1}}}}} \providecommand{\mymatrix}[1]{{\mathbf{\boldsymbol{{#1}}}}}

\providecommand{\myvec}[1]{{\mathbf{\boldsymbol{{#1}}}}}
\providecommand{\mymatrix}[1]{{\mathbf{\boldsymbol{{#1}}}}}

Pre-requisites

%%capture
%pip install numpy
%pip install numpy --break-system-packages

Imports

import numpy as np
from math import pi, sin, cos

Forward Kinematics Model (FKM)

The forward kinematics model of a rigid serial-link manipulator is obtained through a sequence of transformations.

The only real challenge in obtaining the FKM is understanding from a diagram, or a real robot, what transformations represent the robot and in what order they happen.

Anyway, we can start with an example. As always, remember that angles are in radians and lengths are in meters.

Lesson4.png

Consider the 2-DoF planar robot shown in the figure. It is classed as an RR robot, because the two joints are revolute.

Let q0q0(t)Rq_0\triangleq q_0(t) \in \mathbb{R} and q1q1(t)Rq_1\triangleq q_1(t) \in \mathbb{R} compose its configuration space. In addition, let l0Rl_{0} \in \mathbb{R} and l1Rl_{1} \in \mathbb{R} be the geometric parameters, which are quantities that cannot be controlled.

The configuration space is what is used in practice to control the robot. You as the system designer will send configuration space values q0q_0 and q1q_1, or other signals related to those, to command the robot. You will make it move to perform a relevant task and hopefully earn your next month’s salary. The parameters l0l_{0} and l1l_{1} are constant in time and represent time-invariant geometrical aspects of the robot, such as link lengths, that you cannot control.

As a representative task for robotic manipulators, let us use the configuration space and geometric parameters to calculate the pose of the frame of the tip of the robot. This is represented mathematically as follows.

H20(q0,l0,q1,l1)SE(2).\mymatrix{H}^{0}_{2}( q_0, l_{0},q_1,l_{1}) \in SE(2).

The equation for the end-effector (tip) pose is what is called the forward kinematics model (FKM). We need this frequently when using a robotic manipulator because the end effector is likely to be its most useful part. For instance, it could be a gripper that is used to pick and place objects. To pick or place and object, the robot needs to move somewhere.

The first step towards moving somewhere is knowing where you are. Thence, the first step towards controlling a robotic manipulator’s end effector pose in any meaningful way is to obtain its FKM.

Understanding the problem

The FKM is a mathematical description of the robot. Before we attempt any programming, we have to mathematically describe the sequential transformations that represent the robot being modeled.

As shown in the figure, there are four transformations for this robot, taking us from the base, F0\mathcal{F}_0, to the end-effector, F2\mathcal{F}_2. The sequence can be summarised as follows.

  1. A rotation of q0q_0 about the current frame, from F0\mathcal{F}_0 to F0\mathcal{F}_{0'}.

  2. A translation of l0l_0 along the xx-axis of the current frame, from F0\mathcal{F}_{0'} to F1\mathcal{F}_{1}.

  3. A rotation of q1q_1 about the current frame, from F1\mathcal{F}_{1} to F1\mathcal{F}_{1'}.

  4. A translation of l1l_1 along the xx-axis of the current frame, from F1\mathcal{F}_{1'} to F2\mathcal{F}_{2}.

1. From F0\mathcal{F}_0 to F0\mathcal{F}_{0'}

We start with the rotation that can be described by the following homogenous transformation matrix.

H00(q0)=[cos(q0)sin(q0)0sin(q0)cos(q0)0001].\myvec H_{0'}^{0}\left(q_0\right) = \begin{bmatrix} \cos(q_0) & -\sin(q_0) & 0\\ \sin(q_0) & \cos(q_0) & 0\\ 0 & 0 & 1 \end{bmatrix}.

Programmatically, supposing that q0=π4q_0 = \frac{\pi}{4}, we arrive at the following piece of code.

H_0_0p = np.array(
        [[cos(pi/4), -sin(pi/4),  0],
         [sin(pi/4),  cos(pi/4),  0],
         [0,         0,           1]]
)

print(f"The first transformation is\n\n H_0_0p = \n{H_0_0p}")
The first transformation is

 H_0_0p = 
[[ 0.70710678 -0.70710678  0.        ]
 [ 0.70710678  0.70710678  0.        ]
 [ 0.          0.          1.        ]]

2. From F0\mathcal{F}_{0'} to F1\mathcal{F}_{1}

The second step is a translation that can be described by the following homogenous transformation matrix.

H10(l0)=[10l0010001].\myvec H_{1}^{0'}\left(l_0\right) = \begin{bmatrix} 1 & 0 & l_0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}.

Programmatically, supposing that l0=0.3l_0 = 0.3, we arrive at the following piece of code.

H_0p_1 = np.array(
        [[1, 0, 0.3],
         [0, 1, 0],
         [0, 0, 1]]
)

print(f"The second transformation is\n\n H_0p_1 = \n{H_0p_1}")
The second transformation is

 H_0p_1 = 
[[1.  0.  0.3]
 [0.  1.  0. ]
 [0.  0.  1. ]]

3. From F1\mathcal{F}_{1} to F1\mathcal{F}_{1'}

The third step is a rotation that can be described by the following homogenous transformation matrix.

H11(q1)=[cos(q1)sin(q1)0sin(q1)cos(q1)0001].\myvec H_{1'}^{1}\left(q_1\right) = \begin{bmatrix} \cos(q_1) & -\sin(q_1) & 0\\ \sin(q_1) & \cos(q_1) & 0\\ 0 & 0 & 1 \end{bmatrix}.

Programmatically, supposing that q1=π14q_1 = -\frac{\pi}{14}, we arrive at the following piece of code.

H_1_1p = np.array(
        [[cos(-pi/14), -sin(-pi/14),  0],
         [sin(-pi/14),  cos(-pi/14),  0],
         [0,         0,           1]]
)

print(f"The third transformation is\n\n H_1_1p = \n{H_1_1p}")
The third transformation is

 H_1_1p = 
[[ 0.97492791  0.22252093  0.        ]
 [-0.22252093  0.97492791  0.        ]
 [ 0.          0.          1.        ]]

4. From F1\mathcal{F}_{1'} to F2\mathcal{F}_{2}

The last step is a translation that can be described by the following homogenous transformation matrix.

H21(l1)=[10l1010001].\myvec H_{2}^{1'}\left(l_1\right) = \begin{bmatrix} 1 & 0 & l_1 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}.

Programmatically, supposing that l1=0.95l_1 = 0.95, we arrive at the following piece of code.

H_1p_2 = np.array(
        [[1, 0, 0.95],
         [0, 1, 0],
         [0, 0, 1]]
)

print(f"The second transformation is\n\n H_1p_2 = \n{H_1p_2}")
The second transformation is

 H_1p_2 = 
[[1.   0.   0.95]
 [0.   1.   0.  ]
 [0.   0.   1.  ]]

Ok, so where’s the FKM for the RR robot?

As we summarised earlier, the planar RR robot used in this lesson is composed of four sequential transformations. We obtained each of them individually, therefore the final step for the FKM is to compose them in sequence.

H20(q0,l0,q1,l1)=H00(q0)H10(l0)H11(q1)H21(l1).\mymatrix{H}^{0}_{2}( q_0, l_{0},q_1,l_{1}) = \myvec H_{0'}^{0}\left(q_0\right)\myvec H_{1}^{0'}\left(l_0\right)\myvec H_{1'}^{1}\left(q_1\right)\myvec H_{2}^{1'}\left(l_1\right).

The equation above is general and is the FKM for this robot.

Programmatically, we will compute the FKM at a given configuration. Using the configuration and parameters defined previously, we arrive at the following piece of code.

H_0_2 = H_0_0p @ H_0p_1 @ H_1_1p @ H_1p_2

print(f"The FKM for the RR robot at the specified configuration is\n\n H_0_2 = \n{H_0_2}")
The FKM for the RR robot at the specified configuration is

 H_0_2 = 
[[ 0.8467242  -0.53203208  1.01652002]
 [ 0.53203208  0.8467242   0.71756251]
 [ 0.          0.          1.        ]]

Denavit-Hartenberg (DH) Parameters

Despite being the most mistyped concept in my career, DH parameters are ubiquitous and frequently used to describe commercial robots.

The process can be divided into two major parts, with different levels of difficulty.

  1. Obtaining the DH parameters for a given robot.

  2. Using given DH parameters to obtain the robot’s FKM.

Obtaining the DH parameters of a robot usually requires some thought, in particular if the robot has many degrees-of-freedom. This is not the objective of this lesson, because that does not involve programming. It is a pen-and-paper exercise.

After the DH parameters are obtained, calculating the FKM of the robot is trivial.

DH parameter table for an RR robot

Let us start with a sample table, shown below.

Jointθ\thetaddaaα\alpha
0q0(t)q_0(t)0l0l_{0}0
1q1(t)q_1(t)0l1l_{1}0

Each joint transformation is represented by a row. The transformations of each row will be done in the following sequence.

  1. A rotation about the zz-axis of the current frame, related to column θ\theta.

  2. A translation about the zz-axis of the current frame, related to column dd.

  3. A translation about the xx-axis of the current frame, related to column aa.

  4. A rotation about the xx-axis of the current frame, related to column α\alpha.

Note that the sequence of transformations in the table represent the same FKM of our RR robot derived previously. The only difference is that the result will be an element of SE(3).

DH parameter table for a PP robot

Instead of working again on the RR robot, let’s derive the FKM for a PP robot, composed of two prismatic joints. Let its configuration be composed of qB0(t)q_{B0}(t) and qB1(t)q_{B1}(t), with different subscripts to clarify that it is a different robot.

Consider that the FKM is represented by the table below. Note that another benefit of a table is that there’s no need to interpret a robot diagram.

Jointθ\thetaddaaα\alpha
00qB0(t)q_{B0}(t)0π2\frac{\pi}{2}
10qB1(t)q_{B1}(t)00

Given that we can ignore any cells with zeros, this robot will be composed of three transformations.

  1. A translation of qB0(t)q_{B0}(t) along the zz-axis of the current frame, from FB0\mathcal{F}_{B0} to FB0\mathcal{F}_{B0'}.

  2. A rotation of π2\frac{\pi}{2} about the xx-axis of the current frame, from FB0\mathcal{F}_{B0'} to FB1\mathcal{F}_{B1}.

  3. A translation of qB1(t)q_{B1}(t) along the zz-axis of the current frame, from FB1\mathcal{F}_{B1} to FB2\mathcal{F}_{B2}.

FKM for the PP robot

Using elements of SE(3), we obtain each of the three transformations, as follows.

HB0B0(qB0)=[10000100001qB0(t)0001],HB1B0=[10000cosπ2sinπ200sinπ2cosπ200001],HB2B1(qB1)=[10000100001qB1(t)0001].\begin{align} \mymatrix{H}^{B0}_{B0'}(q_{B0})&=\left[\begin{array}{cccc} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & q_{B0}(t) \\ 0 & 0 & 0 & 1 \end{array}\right], \\ \mymatrix{H}^{B0'}_{B1}&=\left[\begin{array}{cccc} 1 & 0 & 0 & 0\\ 0 & \cos{\frac{\pi}{2}} & -\sin{\frac{\pi}{2}} & 0\\ 0 & \sin{\frac{\pi}{2}} & \cos{\frac{\pi}{2}} & 0\\ 0 & 0 & 0 & 1 \end{array}\right], \\ \mymatrix{H}^{B1}_{B2}(q_{B1})&=\left[\begin{array}{cccc} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & q_{B1}(t) \\ 0 & 0 & 0 & 1 \end{array}\right]. \end{align}

Then, we sequentially compose them to obtain the FKM.

HB2B0(qB0,qB1)=HB0B0(qB0)HB1B0HB2B1(qB1).\mymatrix{H}^{B0}_{B2}(q_{B0},q_{B1})=\mymatrix{H}^{B0}_{B0'}(q_{B0})\mymatrix{H}^{B0'}_{B1}\mymatrix{H}^{B1}_{B2}(q_{B1}).

Programmatically, suppose qB0=0.2q_{B0}=0.2 and qB1=0.3q_{B1}=0.3. We obtain the following piece of code.

q_B0 = 0.2
q_B1 = 0.3
theta_B0 = pi/2.0

H_B0_B0p = np.array(
          [[1, 0, 0, 0],
           [0, 1, 0, 0],
           [0, 0, 1, q_B0],
           [0, 0, 0, 1]]
)

H_B0p_B1 = np.array(
          [[1, 0, 0, 0],
           [0, cos(theta_B0), -sin(theta_B0), 0],
           [0, sin(theta_B0),  cos(theta_B0), 0],
           [0, 0, 0, 1]]
)

H_B1_B2 = np.array(
          [[1, 0, 0, 0],
           [0, 1, 0, 0],
           [0, 0, 1, q_B1],
           [0, 0, 0, 1]]
)

# FKM
H_B0_B2 = H_B0_B0p @ H_B0p_B1 @ H_B1_B2

print(f"The FKM for the PP robot at the specified configuration is\n\n H_B0_B2 = \n{H_B0_B2}")
The FKM for the PP robot at the specified configuration is

 H_B0_B2 = 
[[ 1.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00]
 [ 0.000000e+00  6.123234e-17 -1.000000e+00 -3.000000e-01]
 [ 0.000000e+00  1.000000e+00  6.123234e-17  2.000000e-01]
 [ 0.000000e+00  0.000000e+00  0.000000e+00  1.000000e+00]]

Exercises

Consider that the numpy and math modules are already imported as shown earlier in this lesson.

Exercise a

Consider a robotic manipulator that has the following DH-parameter table.

Jointθ\thetaddaaα\alpha
0qA0(t)q_{A0}(t)0.50π2\frac{\pi}{2}
10qA1(t)q_{A1}(t)00

Compute its FKM in SE(3) and store in H_A0_A2 the result of the FKM given qA0(t)=π4q_{A0}(t) = \frac{\pi}{4} and qA1(t)=0.1q_{A1}(t) = -0.1.

q_A0 = pi/4.0 # As given in the exercise
q_A1 = -0.1 # As given in the exercise

H_A0_A2 = None # Replace None with your solution to this exercise.

Exercise c

Consider a robotic manipulator that has the following DH-parameter table.

Jointθ\thetaddaaα\alpha
0qC0(t)q_{C0}(t)lC0l_{C0}00
1qC1(t)q_{C1}(t)lC1l_{C1}00
2qC2(t)q_{C2}(t)lC2l_{C2}00

Compute its FKM in SE(3) and store in H_C0_C3 the result of the FKM given qC0(t)=qC1(t)=qC2(t)=π5q_{C0}(t)=q_{C1}(t)=q_{C2}(t) = \frac{\pi}{5} and lC0=lC1=lC2=0.25l_{C0} = l_{C1} = l_{C2} = 0.25.

H_C0_C3 = None # Replace None with your solution to this exercise.

Extra challenge(s)

  1. What about if it was a planar revolute manipulator with n degrees-of-freedom?