Module 2·55 min
Denavit-Hartenberg Parameters
Denavit-Hartenberg Parameters
DH parameters provide a systematic way to assign coordinate frames to serial robot links, making forward kinematics algebraically tractable.
The Four Parameters
For each joint i:
| Parameter | Symbol | Meaning |
|---|---|---|
| Link length | a_i | Distance along x_i from z_{i-1} to z_i |
| Link twist | α_i | Angle about x_i from z_{i-1} to z_i |
| Link offset | d_i | Distance along z_{i-1} from x_{i-1} to x_i |
| Joint angle | θ_i | Variable for revolute joints — this is what your motor controls |
The DH Transform
Each joint contributes one 4×4 homogeneous transform:
T_i = Rot_z(θ_i) · Trans_z(d_i) · Trans_x(a_i) · Rot_x(α_i)
CatBot Leg DH Table
For one leg (simplified, with link lengths L1 = 0.06m, L2 = 0.12m, L3 = 0.12m):
| Joint | a (m) | α (rad) | d (m) | θ (variable) |
|---|---|---|---|---|
| HAA (hip abduction) | 0.06 | π/2 | 0 | θ₁ |
| HFE (hip flex/ext) | 0.12 | 0 | 0 | θ₂ |
| KFE (knee) | 0.12 | 0 | 0 | θ₃ |
Computing Forward Kinematics
def dh_transform(a, alpha, d, theta):
"""Compute single DH transform matrix."""
ct, st = np.cos(theta), np.sin(theta)
ca, sa = np.cos(alpha), np.sin(alpha)
return np.array([
[ct, -st*ca, st*sa, a*ct],
[st, ct*ca, -ct*sa, a*st],
[ 0, sa, ca, d],
[ 0, 0, 0, 1],
])
def leg_fk(q):
"""Forward kinematics for one CatBot leg.
q: [theta1, theta2, theta3] in radians
Returns: 4x4 homogeneous transform of foot"""
T = np.eye(4)
params = [
(0.06, np.pi/2, 0, q[0]), # HAA
(0.12, 0, 0, q[1]), # HFE
(0.12, 0, 0, q[2]), # KFE
]
for a, alpha, d, theta in params:
T = T @ dh_transform(a, alpha, d, theta)
return T
# Example
q = np.array([0.0, -np.pi/4, np.pi/2]) # standing pose
T_foot = leg_fk(q)
foot_pos = T_foot[:3, 3] # extract x, y, z position
print(f"Foot position: {foot_pos}")