Jacky Baltes
National Taiwan Normal University
Taipei, Taiwan
jacky.baltes@ntnu.edu.tw
Coordinate systems can attach freely to a link
DH-Convention leads to a simplified setup
The transformation matrix is a 4*4 matrix (16 unknowns)
Using the DH-Convention, we only need four numbers to define the transformation matrix
\[ T^i_j = \left[ \begin{array}{cc} R^{i}_j & o^{i}_j \\ 0 & 1 \\ \end{array} \right] \]
Rotation matrices \(R^i_j \) is a 3*3 matrix, but can be completely defined by three Euler angles (Rotation along X, Y, Z)
So we are left with six unknowns
DH Convention only uses four numbers
Possible through clever choice of the position of the coordinate frames to simplify the analysis
Place the coordinate systems so that the Z-axis aligns with the axis of actuation of the joint
The axis of actuation of a revolute joint is the axis that we rotate around (joint variable \(\theta_i\) will rotate along \(Z_{i-1}\) )
The axis of actuation of a prismatic joint is the axis that we translate along (joint variable \( d_i \) will translate along \( Z_{i-1} \) )
The actual shape of the link is not important as far as the kinematics are concerned
Only the relative position between the two joints is important
\[ T^i_j = \left[ \begin{array}{cccc} r_{11} & r_{12} & r_{13} & o_{14} \\ r_{21} & r_{22} & r_{23} & o_{24} \\ r_{31} & r_{32} & r_{33} & o_{34} \\ 0 & 0 & 0 & 1 \\ \end{array} \right] \]
First Assumption: Assume that \( x_{i+1} \) and \( z_i \) are perpendicular (DH1)
If two vectors are perpendicular to each other, then their dot product must be 0.
\[ \begin{eqnarray} x_{i-1} \cdot z_i = 0\\ [r_{11}, r_{21}, r_{31} ] \cdot [0, 0, 1]^T = 0 \end{eqnarray} \]So \( r_{31} = 0 \)
From this equation, we can conclude
\[ r_{31} = 0\\ \]\[ \begin{eqnarray} R^{i-1}_i = R_{z,\theta} R_{x,\alpha} = \\ \left[ \begin{array}{ccc} \cos(\theta) & -\sin(\theta) cos(\alpha) & \sin(\theta) sin(\alpha) \\ \sin(\theta) & \cos(\theta) cos(\alpha) & -\cos(\theta) sin(\alpha) \\ 0 & sin(\alpha) & cos(\alpha) \\ \end{array} \right] \end{eqnarray} \]
#--style="font-size:0.5em"
import sympy
sympy.init_printing(use_unicode=True)
from sympy.printing.mathml import print_mathml
t, a = sympy.symbols( 'θ α')
rxt = sympy.Matrix( [ [ sympy.cos(t), -sympy.sin(t), 0 ], [ sympy.sin(t), sympy.cos(t), 0 ], [ 0, 0, 1 ] ] )
rxa = sympy.Matrix( [ [ 1, 0, 0 ], [ 0, sympy.cos(a), -sympy.sin(a) ], [ 0, sympy.sin(a), sympy.cos(a) ] ] )
r = rxt * rxa
sympy.pprint(r)
⎡cos(θ) -sin(θ)⋅cos(α) sin(α)⋅sin(θ) ⎤ ⎢ ⎥ ⎢sin(θ) cos(α)⋅cos(θ) -sin(α)⋅cos(θ)⎥ ⎢ ⎥ ⎣ 0 sin(α) cos(α) ⎦
Second Assumption: Assume that \( z_{i-1} \) and \( x_i \) intersect (DH2)
Displacement from \( o^{i-1}_{i} \) can be expressed as a linear combination of \( z_{i-1} \) and \( x_i \)
\[ o^{i-1}_{i} = o^{i-1}_{i-1} + d z_{i-1} + a x_{i}\\ o^{i-1}_{i} = \left[ \begin{array}{c} 0 \\ 0 \\ 0 \end{array} \right] + d \left[ \begin{array}{c} 0 \\ 0 \\ 1 \end{array} \right] + a \left[ \begin{array}{c} \cos \theta \\ \sin{\theta} \\ 0 \end{array} \right]\\ o^{i-1}_{i} = \left[ \begin{array}{c} a \cos \theta \\ a \sin \theta \\ d \end{array} \right] \]
Transformation matrix is now defined by four numbers joint angle \( \theta \), link offset \( d \), link length \( a \), link twist \( \alpha \)
\[ A^{i-1}_i = R_{z,\theta} T_{z,d} T_{x,a} R_{x,\alpha} \]#--style="font-size:0.5em"
import sympy
sympy.init_printing(use_unicode=True)
from sympy.printing.mathml import print_mathml
t, a, dd, aa = sympy.symbols( 'θ α d a')
rzt = sympy.Matrix( [ [ sympy.cos(t), -sympy.sin(t), 0, 0 ], [ sympy.sin(t), sympy.cos(t), 0, 0 ], [ 0, 0, 1, 0 ], [0, 0, 0, 1] ] )
tzd = sympy.Matrix( [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, dd ], [0, 0, 0, 1] ] )
txa = sympy.Matrix( [ [ 1, 0, 0, aa ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [0, 0, 0, 1] ] )
rxa = sympy.Matrix( [ [ 1, 0, 0, 0 ], [ 0, sympy.cos(a), -sympy.sin(a), 0 ], [ 0, sympy.sin(a), sympy.cos(a), 0 ], [ 0, 0, 0, 1 ] ] )
r = rzt * tzd * txa * rxa
sympy.pprint(r)
⎡cos(θ) -sin(θ)⋅cos(α) sin(α)⋅sin(θ) a⋅cos(θ)⎤ ⎢ ⎥ ⎢sin(θ) cos(α)⋅cos(θ) -sin(α)⋅cos(θ) a⋅sin(θ)⎥ ⎢ ⎥ ⎢ 0 sin(α) cos(α) d ⎥ ⎢ ⎥ ⎣ 0 0 0 1 ⎦
Joint angle θ is the angle between \( x_{i-1} \) and \( x_{i} \)
Link offset d is the distance from the origin of \( o_{i-1} \) to the intersection point between \(z_{i-1}\) and \( x_{i} \), measured along \( z_{i-1} \)
Link length a is the distance between \( z_{i-1} \) and \( z_i \) measured along \( x_i \)
Link twist α is the angle between \( z_{i-1}\) and \( z_i\) measured in a plane normal to \( x_i \)
Start with the inertial frame (Frame 0) and then iterate to 1, ... n
Axis \( z_0 \cdots z_{n-1} \) can be assigned arbitrarily since \( α_i \) and \( θ_i \) can compensate. Select intuitive directions for \( z_0 \cdots z_{n-1} \)
\( z_{i-1} \) is the axis of actuation for joint \( i \)
Once Z axis have been assigned, set up the world frame/inertial frame/frame 0
Origin of inertial frame must lie somewhere along \( z_0 \)
Set up axis \( x_0 \) and \( y_0 \) in such a way that it makes sense and is a right handed coordinate system.
Three cases to consider
\( x_i \) must be the shortest line between \( z_{i-1} \) and \( z_i \). Origin \(o_i\) will be at intersection of \(x_i\) and \(z_i\). Assign \( y_i\) to make it a right-handed coordinate system
\(x_i\) must be the normal passing through the plane spanned by \(z_{i-1} \) and \( z_i \) and going through the point of intersection of \(z_{i-1} \) and \( z_i \). Origin of \( o_i\) is at the intersection. Assign \(y_i\) to make it a right-handed coordinate system.
Choose \( x_i \) anywhere along \(z_i\). Align \( x_i\) so that \( d_i\) is 0. \( \alpha_i \) will be 0, since \(z_{i-1} \) and \( z_i \) are parallel
Assign Z-axis as axis of actuation
Assign frames based position of x-axis. Assign y axis to make it a right-handed coordinate system.
Create a table of parameters (DH-table) Joint angle, link offset, link length, link twist
Calculate the homogeneous transformation matrices
To solve forward kinematics: calculate the compound transformations \( T^0_n = A_1(\theta_1) A_2(\theta_2) \cdots A_n(\theta_n) \)