D.HOSKIA
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:

ParameterSymbolMeaning
Link lengtha_iDistance along x_i from z_{i-1} to z_i
Link twistα_iAngle about x_i from z_{i-1} to z_i
Link offsetd_iDistance along z_{i-1} from x_{i-1} to x_i
Joint angleθ_iVariable 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):

Jointa (m)α (rad)d (m)θ (variable)
HAA (hip abduction)0.06π/20θ₁
HFE (hip flex/ext)0.1200θ₂
KFE (knee)0.1200θ₃

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}")