Skip to content
AI360Xpert
Beta

Forward and Inverse Kinematics

Forward kinematics maps joint settings to end-effector position through rigid geometry; inverse kinematics solves the reverse, finding the joint angles that place the hand at a target pose. While forward kinematics is unique and closed-form, inverse kinematics can have multiple solution branches, singularities, or no solution at all.

Forward kinematics maps joint angles to hand pose, while inverse kinematics yields elbow-up and elbow-down solution branches
Forward kinematics maps joint angles to hand pose, while inverse kinematics yields elbow-up and elbow-down solution branches

Why Does This Exist?

When commanding a robotic arm, the goal is expressed in operational task coordinates: "place the suction gripper at coordinate (x=0.6,y=0.4)(x=0.6, y=0.4) on the conveyor belt." But motors do not accept Cartesian (x,y)(x, y) coordinates. Motors rotate joints through individual angles (θ1,θ2,…,θn)(\theta_1, \theta_2, \ldots, \theta_n).

Mapping between these two representations is the domain of kinematics:

  • Forward Kinematics (FK): Given joint angles q\mathbf{q}, where is the hand? This is a forward geometric evaluation: every joint angle yields exactly one unique end-effector pose.
  • Inverse Kinematics (IK): Given a desired hand pose x\mathbf{x}, what joint angles q\mathbf{q} reach it? This is fundamentally difficult: non-linear trigonometric equations yield multiple solution branches (e.g. elbow-up versus elbow-down), boundary singularities where joints lock up, or no solution if the target lies outside the arm's reach.

Solving inverse kinematics reliably is the bridge that allows high-level trajectory planners to command low-level joint motor drives.

Basics first: the configuration space and workspace geometry of robotic limbs live in robot-degrees-of-freedom. Transforming between base and tool frames lives in robot-coordinate-frames. Generating collision-free paths between joint configurations lives in robot-motion-planning.

Think of It Like This

Touching your laptop keyboard with your elbow up versus down

Place your index finger firmly on the spacebar of your keyboard. Keep your fingertip glued to that exact spot. Now, notice what your arm can do: you can swing your elbow outward and upward into the air, or you can drop your elbow downward close to your ribs.

Your fingertip is at the exact same (x,y,z)(x, y, z) position, but your shoulder and elbow joints occupy two completely different mathematical configurations. These are distinct inverse kinematic branches: "elbow-up" and "elbow-down."

Where it stops: your human brain chooses an elbow posture based on muscle comfort and natural tendon tension. A robot arm controller must explicitly calculate both mathematical branches and evaluate whether the elbow-down posture collides with the tabletop, or whether the elbow-up posture hits an overhead ceiling beam.

How It Actually Works

For a planar 2-link arm with link lengths l1l_1 and l2l_2, and joint angles θ1\theta_1 and θ2\theta_2, the end-effector position (x,y)(x, y) is given by simple trigonometry:

x=l1cos⁡(θ1)+l2cos⁡(θ1+θ2)x = l_1 \cos(\theta_1) + l_2 \cos(\theta_1 + \theta_2) y=l1sin⁡(θ1)+l2sin⁡(θ1+θ2)y = l_1 \sin(\theta_1) + l_2 \sin(\theta_1 + \theta_2)

This forward mapping is unique, continuous, and straightforward to evaluate.

Inverse kinematics via the Law of Cosines

Given a target position (x,y)(x, y), we first compute the squared distance from the base origin:

r2=x2+y2r^2 = x^2 + y^2

If r>l1+l2r > l_1 + l_2 or r<∣l1−l2∣r < |l_1 - l_2|, the target is outside the reachable workspace and no physical solution exists.

Inside the workspace, applying the Law of Cosines to the triangle formed by l1l_1, l2l_2, and rr gives:

r2=l12+l22−2l1l2cos⁡(π−θ2)=l12+l22+2l1l2cos⁡(θ2)r^2 = l_1^2 + l_2^2 - 2 l_1 l_2 \cos(\pi - \theta_2) = l_1^2 + l_2^2 + 2 l_1 l_2 \cos(\theta_2)

Solving for cos⁡(θ2)\cos(\theta_2):

cos⁡(θ2)=x2+y2−l12−l222l1l2\cos(\theta_2) = \frac{x^2 + y^2 - l_1^2 - l_2^2}{2 l_1 l_2}

Because cos⁡(θ2)=cos⁡(−θ2)\cos(\theta_2) = \cos(-\theta_2), there are two distinct solutions for joint 2:

θ2=±arccos⁡(x2+y2−l12−l222l1l2)\theta_2 = \pm \arccos\left(\frac{x^2 + y^2 - l_1^2 - l_2^2}{2 l_1 l_2}\right)

Once θ2\theta_2 is selected, θ1\theta_1 is found by projecting angles:

θ1=atan2(y,x)−atan2(l2sin⁡θ2,l1+l2cos⁡θ2)\theta_1 = \text{atan2}(y, x) - \text{atan2}(l_2 \sin\theta_2, l_1 + l_2 \cos\theta_2)
  • θ2>0\theta_2 > 0 corresponds to the elbow-down configuration.
  • θ2<0\theta_2 < 0 corresponds to the elbow-up configuration.

Kinematic singularities: losing degrees of freedom

A singularity occurs when the arm loses the ability to move in one or more Cartesian directions. For the 2-link arm, this happens when:

  • θ2=0\theta_2 = 0: The arm is fully outstretched (r=l1+l2r = l_1 + l_2). The arm cannot produce radial velocity outward.
  • θ2=π\theta_2 = \pi: The arm is folded completely onto itself (r=∣l1−l2∣r = |l_1 - l_2|).

At a singularity, the Jacobian matrix drops rank. Attempting to track a Cartesian path through a singularity demands mathematically infinite joint velocities (q˙=J−1x˙\dot{\mathbf{q}} = \mathbf{J}^{-1} \dot{\mathbf{x}}), causing motor drives to trip overcurrent or velocity safety limits.

Worked example: solving IK for target (0.6,0.4) m(0.6, 0.4)\text{ m}

Consider a 2-link arm with equal link lengths l1=0.5 ml_1 = 0.5\text{ m} and l2=0.5 ml_2 = 0.5\text{ m}. We want to reach target (x,y)=(0.6,0.4) m(x, y) = (0.6, 0.4)\text{ m}.

Compute squared distance r2r^2:

r2=0.62+0.42=0.36+0.16=0.52 m2r^2 = 0.6^2 + 0.4^2 = 0.36 + 0.16 = 0.52\text{ m}^2

Distance r=0.52≈0.7211 mr = \sqrt{0.52} \approx 0.7211\text{ m}. Since 0.0≤0.7211≤1.0 m0.0 \le 0.7211 \le 1.0\text{ m}, the target is reachable.

Compute cos⁡(θ2)\cos(\theta_2):

cos⁡(θ2)=0.52−0.52−0.522(0.5)(0.5)=0.52−0.25−0.250.50=0.020.50=0.04\cos(\theta_2) = \frac{0.52 - 0.5^2 - 0.5^2}{2 (0.5)(0.5)} = \frac{0.52 - 0.25 - 0.25}{0.50} = \frac{0.02}{0.50} = 0.04

Compute the two joint 2 branches:

θ2=±arccos⁡(0.04)=±1.5308 rad≈±87.71∘\theta_2 = \pm \arccos(0.04) = \pm 1.5308\text{ rad} \approx \pm 87.71^\circ

Compute base angle β=atan2(y,x)\beta = \text{atan2}(y, x):

β=atan2(0.4,0.6)≈0.5880 rad≈33.69∘\beta = \text{atan2}(0.4, 0.6) \approx 0.5880\text{ rad} \approx 33.69^\circ

For Branch 1 (Elbow-Down, θ2=+1.5308 rad\theta_2 = +1.5308\text{ rad}):

ψ=atan2(0.5sin⁡(1.5308),0.5+0.5cos⁡(1.5308))=atan2(0.4996,0.5200)≈0.7654 rad≈43.85∘\psi = \text{atan2}(0.5 \sin(1.5308), 0.5 + 0.5 \cos(1.5308)) = \text{atan2}(0.4996, 0.5200) \approx 0.7654\text{ rad} \approx 43.85^\circ θ1=β−ψ=0.5880−0.7654=−0.1774 rad≈−10.16∘\theta_1 = \beta - \psi = 0.5880 - 0.7654 = -0.1774\text{ rad} \approx -10.16^\circ

For Branch 2 (Elbow-Up, θ2=−1.5308 rad\theta_2 = -1.5308\text{ rad}):

θ1=β+ψ=0.5880+0.7654=1.3534 rad≈+77.54∘\theta_1 = \beta + \psi = 0.5880 + 0.7654 = 1.3534\text{ rad} \approx +77.54^\circ

Forward kinematics confirms both branches reach (0.6,0.4) m(0.6, 0.4)\text{ m} exactly:

  • Elbow-down: θ1=−10.16∘,θ2=+87.71∘  ⟹  (0.60,0.40) m\theta_1 = -10.16^\circ, \theta_2 = +87.71^\circ \implies (0.60, 0.40)\text{ m}.
  • Elbow-up: θ1=+77.54∘,θ2=−87.71∘  ⟹  (0.60,0.40) m\theta_1 = +77.54^\circ, \theta_2 = -87.71^\circ \implies (0.60, 0.40)\text{ m}.

Code

This Python snippet implements forward and inverse kinematics for the 2-link planar arm, verifies both solution branches, and tests for singularity boundary detection.

import math

def solve_2link_ik(    l1: float,    l2: float,    x: float,    y: float,) -> tuple[tuple[float, float], tuple[float, float]] | None:    """Solve inverse kinematics for 2-link planar arm returning (elbow_down, elbow_up) in degrees."""    r2: float = x ** 2 + y ** 2    cos_th2: float = (r2 - l1 ** 2 - l2 ** 2) / (2.0 * l1 * l2)
    if abs(cos_th2) > 1.0:        return None  # Target unreachable
    th2_down: float = math.acos(cos_th2)    th2_up: float = -th2_down
    beta: float = math.atan2(y, x)    psi: float = math.atan2(l2 * math.sin(th2_down), l1 + l2 * math.cos(th2_down))
    th1_down: float = beta - psi    th1_up: float = beta + psi
    return (        (round(math.degrees(th1_down), 2), round(math.degrees(th2_down), 2)),        (round(math.degrees(th1_up), 2), round(math.degrees(th2_up), 2)),    )

solutions = solve_2link_ik(l1=0.5, l2=0.5, x=0.6, y=0.4)if solutions is not None:    elbow_down, elbow_up = solutions    print(elbow_down)  # -> (-10.16, 87.71)    print(elbow_up)    # -> (77.54, -87.71)

Watch Out For

Branch flipping during smooth Cartesian trajectory tracking

When commanding an arm to draw a straight Cartesian line across a workbench, independent IK queries at each waypoint can suddenly jump between the elbow-up and elbow-down branches.

The symptom is the arm moving smoothly for several waypoints, then violently attempting to flip its elbow 180∘180^\circ within a single 10 ms control cycle, causing a velocity fault. Fix it by seeding numerical or analytical IK solvers with the robot's current joint state qt\mathbf{q}_t, minimizing ∥qt+1−qt∥\|\mathbf{q}_{t+1} - \mathbf{q}_t\| to guarantee configuration continuity.

Commanding Cartesian velocities through kinematic singularities

When the arm reaches full extension (r=l1+l2r = l_1 + l_2), the Jacobian matrix determinant drops to zero: the arm loses a degree of freedom in the radial direction.

The symptom is joint motors whining and shutting down due to excessive commanded speed when tracking a trajectory that grazes the workspace boundary. Fix it by monitoring the Jacobian condition number or manipulability measure (w=det⁡(JJT)w = \sqrt{\det(\mathbf{J} \mathbf{J}^T)}), and using damped least-squares (Levenberg-Marquardt singularity avoidance) when approaching singular configurations.

The Quick Version

  • Forward kinematics uniquely maps joint coordinates q\mathbf{q} to end-effector pose (x,y,z)(x, y, z) using geometric link transformations.
  • Inverse kinematics recovers joint angles from a desired Cartesian target; it is non-linear and produces multiple solution branches.
  • For a 2-link planar arm (l1=l2=0.5 ml_1=l_2=0.5\text{ m}) reaching (0.6,0.4) m(0.6, 0.4)\text{ m}, the Law of Cosines yields two branches: elbow-down (−10.16∘,+87.71∘)(-10.16^\circ, +87.71^\circ) and elbow-up (+77.54∘,−87.71∘)(+77.54^\circ, -87.71^\circ).
  • Singularity configurations occur at workspace boundaries (full extension or folding), where the arm loses an instantaneous degree of freedom.
  • Continuous trajectory tracking must maintain configuration branch consistency to prevent catastrophic joint flips during motion.