The Product of Exponentials Formula
The Product of Exponentials Formula
The Forward Kinematics Equation
If a robotic arm has \(n\) joints, the Product of Exponentials formula computes the final Homogeneous Transformation Matrix (\(T(\theta) \in \SE\)) of the end-effector relative to the base as:
\[\begin{equation} T(\bm{\theta}) = e^{[\screw_1]\theta_1} e^{[\screw_2]\theta_2} \dots e^{[\screw_n]\theta_n} M \end{equation}\]
Where: 1. \(M \in \SE\) is the “Home Configuration” matrix perfectly describing where the end-effector sits when all motor angles \(\theta_i = 0\). 2. \(\screw_i \in \se\) is the spatial Screw Axis (the twist parameter) for joint \(i\), expressed in the global Space Frame when the robot is at Home Configuration. 3. \(\theta_i\) is the actual angle (or distance) the motor has moved. 4. \(e^{[\screw_i]\theta_i} \in \SE\) is the Matrix Exponential (developed in Chapter 5) mapping that single joint’s motion into a 4x4 matrix.
This equation guarantees that no matter how complex the geometric chain is, the entire forward kinematics operation is just sequentially multiplying \(4 \times 4\) matrices starting from the base to the tool tip.
Worked Example: PoE for a Planar 2R Arm
Let us calculate the forward kinematics of a simple 2-link robotic arm rotating on a flat table using python. The first link has length \(L_1\), and the second link has length \(L_2\). Both joints are purely rotational (Revolute) turning around the Z-axis coming vertically out of the table.
When both joints are at \(0^\circ\), the arm sticks straight out along the X-axis. Thus, the Home Configuration \(M\) has no rotation, and translates by \(L_1 + L_2\) in X: \[\begin{equation} M = \begin{bmatrix} 1 & 0 & 0 & L_1 + L_2 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \end{equation}\]
Joint 1 spins at the origin \((0,0,0)\). Joint 2 spins at the elbow, located at \((L_1, 0, 0)\). Using Murray’s formula for a pure rotational screw axis \(\screw = (\omega, v) = (\omega, -\omega \times q)\), we find: \[\begin{align} \screw_1 &= (0, 0, 1, 0, 0, 0)^T \\ \screw_2 &= (0, 0, 1, 0, -L_1, 0)^T \end{align}\]
Here is the python code verifying the Forward Kinematics output:
import numpy as np
import scipy.linalg
def create_screw_matrix(w, v):
# Assembles the 4x4 se(3) skew matrix for a screw axis (w, v)
return np.array([
[ 0, -w[2], w[1], v[0] ],
[ w[2], 0, -w[0], v[1] ],
[-w[1], w[0], 0, v[2] ],
[ 0, 0, 0, 0 ]
])
def planar_2R_forward_kinematics(theta1, theta2, L1, L2):
# 1. Define the Home Configuration M
M = np.array([
[1, 0, 0, L1 + L2],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
])
# 2. Define the Screw Axes (w, v) for the two joints
S1 = create_screw_matrix([0, 0, 1], [0, 0, 0])
S2 = create_screw_matrix([0, 0, 1], [0, -L1, 0])
# 3. Compute Matrix Exponentials
T1 = scipy.linalg.expm(S1 * theta1)
T2 = scipy.linalg.expm(S2 * theta2)
# 4. Product of Exponentials Formula T(theta)
T_final = T1 @ T2 @ M
return T_final
# Example: Arm with links L1=2m, L2=1.5m, rotated 90 deg and -45 deg
T_end = planar_2R_forward_kinematics(np.pi/2, -np.pi/4, L1=2.0, L2=1.5)
print("End-Effector Transform [T]:\n", np.round(T_end, 3))
print("Final Tool X,Y Position:", np.round(T_end[0:2, 3], 3))By utilizing the Matrix Exponential and the global Screw Axis structure, the PoE formalism eliminates error-prone geometry tracking and instantly scales up to complex 6-DOF and 15-DOF spatial mechanisms seamlessly.