URDF to DH Frame Conversions

Overview

Each link in a URDF is connected by joint elements. The joint element describes a homogeneous transformation that will take coordinates in the child link’s coordinate frame and transform them into the parent link’s coordinate frame. The joint elements also give the axis of the joint with respect to the origin of the child link’s coordinate frame.

Starting with the assumption that the root frame of the URDF and the root frame of the DH parameterization are equivalent, our problem becomes determining the DH parameterization that also describes the child link.

_images/urdf_to_dh_frame.png

As we create the new DH frames, it becomes clear that each new joint is solved in a similar manner to the first joint. As we add DH frames, we use our knowledge of the previous frame to solve for the next DH frame in the tree.

_images/next_urdf_to_dh_frame.png

Cases

Using the framework above, there are four different cases to evaluate. The URDF joint axis with respect to the DH parent frame’s z-axis can be:

  1. Collinear
  2. Parallel
  3. Intersecting
  4. Skew

Collinear

The simplest case, take the z-axis (remember the parent frame is assumed to already be DH parameterized frame) and test if it is collinear given the origin of the child frame and a vector describing the joint axis.

def are_collinear(point1, vec1, point2, vec2):
    """Determine if vectors are collinear."""

    # To be collinear, vectors must be parallel
    if not are_parallel(vec1, vec2):
        return False

    # If parallel and point1 is coincident with point2, vectors are collinear
    if all(np.isclose(point1, point2)):
        return True

    # If vectors are parallel, point2 can be defined as p2 = p1 + t * v1
    t = np.zeros(3)
    for idx in range(0, 3):
        if vec1[idx] != 0:
            t[idx] = (point2[idx] - point1[idx]) / vec1[idx]
    p2 = point1 + t * vec1

    return np.allclose(p2, point2)
_images/collinear_case.png

The DH Parameters for this frame are then:

Parameter Value
d Distance to child origin
\(\theta\) Free parameter [1]
a 0
\(\alpha\) 0 or \(\pi\)
[1]Typically left as 0

Parallel

Intersecting

Skew