← all notes

Unit 3 · Forward Kinematics

DH parameters - reading the table off an arm

Denavit-Hartenberg is a bookkeeping trick. A general transform between two frames needs six numbers; DH gets it down to four by refusing to place frames arbitrarily. You give up freedom in where the axes go, and in exchange every joint is described by one row of a table.

Each row turns into one homogeneous transform, and the chain multiplies out:

T0,n=T0,1 T1,2⋯Tn−1,nT_{0,n} = T_{0,1}\, T_{1,2} \cdots T_{n-1,n}

The four parameters

Every parameter is measured between two consecutive frames, which is why each carries a double index i, i+1i,\,i+1:

zizi+1αxi+1axiθd

Notice the pattern: the two length parameters and the two angle parameters pair up on the two axes. aa and α\alpha are both measured on xi+1x_{i+1}; dd and θ\theta are both measured on ziz_i. If you can remember which axis a parameter lives on, you can reconstruct its definition.

Some course material writes the offset along ziz_i as si,i+1s_{i,i+1}. It is the same quantity as dd here, and dd is the letter used in the transform matrix.

Reading the parameters off a figure

The definitions are geometric, so most entries are read, not computed. Four shortcuts cover almost every exam figure:

You seeParameterValue
ziz_i and zi+1z_{i+1} intersectai,i+1a_{i,i+1}00
ziz_i and zi+1z_{i+1} are parallelαi,i+1\alpha_{i,i+1}00
ziz_i and zi+1z_{i+1} are perpendicularαi,i+1\alpha_{i,i+1}±90∘\pm 90^\circ
the axes are not offset sidewaysdi,i+1d_{i,i+1}00

The sign of α\alpha comes from the right-hand rule about xi+1x_{i+1}: point your right thumb along xi+1x_{i+1} and the fingers curl from ziz_i towards zi+1z_{i+1} for a positive angle. Half the lost marks in this section are a correct magnitude with the wrong sign.

The other half are a wrong variable. For a revolute joint, θ\theta is the joint variable and aa, α\alpha, dd are fixed by the geometry. For a prismatic joint it swaps: dd is the variable and θ\theta is fixed. Exactly one entry per row moves.

Worked example: a three-joint arm

A waist that rotates about the vertical, a shoulder, and an elbow - three revolute joints, so three rows and three variables θ1,θ2,θ3\theta_1, \theta_2, \theta_3.

A three-joint arm on a cylindrical base, with frames 0 to 3 drawn at each joint: z0 vertical up the base, z1 and z2 horizontal and parallel at the shoulder and elbow, z3 along the final link to the tool point P. The base height d1, the lateral offset d2, and the link length l2 are marked.

The arm the table below describes. Note the figure labels the fourth parameter s, which is the one written d here. Source: irobotkits.blogspot.com, via the course slides.

Work the frames left to right in the figure: z0z_0 up the base, z1z_1 and z2z_2 across the shoulder and elbow, z3z_3 out along the last link.

Frame assignment. z0z_0 points up the base column. The waist turns about it, so z0z_0 is the first joint axis. The shoulder axis z1z_1 is horizontal, perpendicular to z0z_0. The elbow axis z2z_2 is parallel to z1z_1, because the shoulder and elbow both swing the arm in the same vertical plane. z3z_3 runs along the last link.

Two constants come out of the figure: d1d_1 is the height of the base column, d2d_2 is the sideways offset from the base centre to the plane the arm swings in, and l2l_2 is the link length between shoulder and elbow.

Joint iiai,i+1a_{i,i+1}αi,i+1\alpha_{i,i+1}θi,i+1\theta_{i,i+1}di,i+1d_{i,i+1}
0000−90∘-90^\circθ1\theta_1d1d_1
11l2l_20∘0^\circθ2\theta_2d2d_2
2200+90∘+90^\circθ3\theta_300

Row by row, the reasoning is the shortcut table above:

Two entries in this table are worth pausing on. First, only one row carries a link length; it is normal for most of the aa column to be zero when joint axes intersect. Second, the length of the last link never appears. The table stops at frame 3, and the tool point PP is described by a further fixed transform from frame 3 - it is not a joint, so it gets no row.

Assembling the result

Each row goes into the standard DH transform:

Ti,i+1=[cθ−sθcαsθsαa cθsθcθcα−cθsαa sθ0sαcαd0001]T_{i,i+1} = \begin{bmatrix} c_{\theta} & -s_{\theta} c_{\alpha} & s_{\theta} s_{\alpha} & a\, c_{\theta} \\ s_{\theta} & c_{\theta} c_{\alpha} & -c_{\theta} s_{\alpha} & a\, s_{\theta} \\ 0 & s_{\alpha} & c_{\alpha} & d \\ 0 & 0 & 0 & 1 \end{bmatrix}

That matrix is not something to memorise. It is what you get when you apply the four parameters as four moves, in this order:

Ti,i+1=Rotz(θ) Transz(d) Transx(a) Rotx(α)T_{i,i+1} = \mathrm{Rot}_z(\theta)\,\mathrm{Trans}_z(d)\,\mathrm{Trans}_x(a)\,\mathrm{Rot}_x(\alpha) frame iframe i+1Rotz(θ)Transz(d)Transx(a)Rotx(α)both measured on ziboth measured on xi+1

The order is not arbitrary. The two moves measured on ziz_i come first, then the two measured on xi+1x_{i+1} - the same pairing as the parameters themselves. Within a pair the order does not matter, because a rotation about an axis and a translation along that same axis commute. Between the pairs it matters a great deal.

The four elementary matrices

Every homogeneous transform is a rotation block with a translation column bolted on:

T=[Rr03T1]T = \begin{bmatrix} R & r \\ 0_3^{T} & 1 \end{bmatrix}

A pure rotation has r=03r = 0_3; a pure translation has R=IR = I. The four DH moves are the simplest possible cases of each:

Rotz(θ)=[cθ−sθ00sθcθ0000100001]Transz(d)=[10000100001d0001]\mathrm{Rot}_z(\theta) = \begin{bmatrix} c_{\theta} & -s_{\theta} & 0 & 0 \\ s_{\theta} & c_{\theta} & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \qquad \mathrm{Trans}_z(d) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & d \\ 0 & 0 & 0 & 1 \end{bmatrix} Transx(a)=[100a010000100001]Rotx(α)=[10000cα−sα00sαcα00001]\mathrm{Trans}_x(a) = \begin{bmatrix} 1 & 0 & 0 & a \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \qquad \mathrm{Rot}_x(\alpha) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & c_{\alpha} & -s_{\alpha} & 0 \\ 0 & s_{\alpha} & c_{\alpha} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}

You can write any of these from scratch in a few seconds with two rules:

How the multiplication goes

One rule does all the work. For two homogeneous transforms:

[R1r103T1][R2r203T1]=[R1R2R1r2+r103T1]\begin{bmatrix} R_1 & r_1 \\ 0_3^{T} & 1 \end{bmatrix} \begin{bmatrix} R_2 & r_2 \\ 0_3^{T} & 1 \end{bmatrix} = \begin{bmatrix} R_1 R_2 & R_1 r_2 + r_1 \\ 0_3^{T} & 1 \end{bmatrix}

Rotations just multiply. The second translation gets rotated by the first rotation before it is added on. Take the pairs one at a time:

Rotz(θ) Transz(d)=[Rz(θ)(0, 0, d)T03T1]Transx(a) Rotx(α)=[Rx(α)(a, 0, 0)T03T1]\mathrm{Rot}_z(\theta)\,\mathrm{Trans}_z(d) = \begin{bmatrix} R_z(\theta) & (0,\,0,\,d)^{T} \\ 0_3^{T} & 1 \end{bmatrix} \qquad \mathrm{Trans}_x(a)\,\mathrm{Rot}_x(\alpha) = \begin{bmatrix} R_x(\alpha) & (a,\,0,\,0)^{T} \\ 0_3^{T} & 1 \end{bmatrix}

Multiply those two and the rotation block is Rz(θ)Rx(α)R_z(\theta) R_x(\alpha), which is the top-left 3×33 \times 3 of the DH matrix. The translation column is

r=Rz(θ) (a, 0, 0)T+(0, 0, d)T=(a cθ, a sθ, d)Tr = R_z(\theta)\,(a,\,0,\,0)^{T} + (0,\,0,\,d)^{T} = (a\,c_{\theta},\ a\,s_{\theta},\ d)^{T}

which is the last column. That is the whole derivation.

Why only aa picks up the trig

Both aa and dd are plain distances in the table, so it is worth asking why the column comes out as (a cθ, a sθ, d)(a\,c_{\theta},\ a\,s_{\theta},\ d) and not (a, 0, d)(a,\,0,\,d).

Because the aa step happens after the θ\theta rotation. By the time you step aa along xx, that xx axis has already been turned by θ\theta, so the step lands at (acos⁡θ, asin⁡θ, 0)(a\cos\theta,\ a\sin\theta,\ 0). The dd step is along zz, and a rotation about zz does not move zz - so dd passes through untouched.

The general version: anything measured on ziz_i survives the θ\theta rotation unchanged, and anything measured on xi+1x_{i+1} arrives already rotated by it.

Why the moves multiply on the right

Each matrix is post-multiplied, which means every move is expressed in the frame the previous move just produced - not in the base frame. So you read the product left to right as a frame walking into place: start at frame ii, spin about its zz by θ\theta, slide along that zz by dd, slide along the new xx by aa, spin about that xx by α\alpha, and you have arrived at frame i+1i+1.

This is also why the chain telescopes:

T0,3=T0,1 T1,2 T2,3T_{0,3} = T_{0,1}\, T_{1,2}\, T_{2,3}

Each factor is written in the frame the one before it produced, so the indices cancel through the middle and the last column of T0,3T_{0,3} is the position of frame 3 in base coordinates. Had you pre-multiplied instead, every move would be measured in the fixed base frame and the product would not compose like this.

In practice

Substitute the numbers from the table before multiplying, never after. With α=±90∘\alpha = \pm 90^\circ the cos⁡α\cos\alpha terms vanish and a whole column of the rotation block goes to zero; with α=0\alpha = 0 the matrix drops to the planar case

T=[cθ−sθ0a cθsθcθ0a sθ001d0001]T = \begin{bmatrix} c_{\theta} & -s_{\theta} & 0 & a\, c_{\theta} \\ s_{\theta} & c_{\theta} & 0 & a\, s_{\theta} \\ 0 & 0 & 1 & d \\ 0 & 0 & 0 & 1 \end{bmatrix}

and row 1 of the example arm, with α=−90∘\alpha = -90^\circ, collapses just as hard. Multiplying three general symbolic matrices and substituting at the end is how these questions turn into an hour of algebra.

To invert one, never actually invert it - use the structure from 2.3: T−1=[RT−RTr03T1]T^{-1} = \begin{bmatrix} R^{T} & -R^{T} r \\ 0_3^{T} & 1 \end{bmatrix}.

Sanity checks

The alternative

The product of exponentials does the same job without frame assignment - one screw axis ξi\xi_i per joint and its magnitude ϕi\phi_i, with only a home configuration MM to fix:

T(ϕ)=e[ξ1]ϕ1 e[ξ2]ϕ2⋯e[ξn]ϕn MT(\phi) = e^{[\xi_1]\phi_1}\, e^{[\xi_2]\phi_2} \cdots e^{[\xi_n]\phi_n}\, M

DH is more compact once the table exists; PoE skips the intermediate frames, which is where DH errors come from. Exams ask for both, so the useful skill is recognising which description a question has handed you.