Week 03 | SKILL-018

Analytical Inverse Kinematics: Solving IK the Elegant Way

Published: April 8, 2026 | Author: Smartotics Learning Journey | Reading Time: 10 min

When we want a robot arm to reach a specific point, we need to figure out what joint angles will get the end-effector there. That’s inverse kinematics (IK). Today we explore the most beautiful approach: analytical (closed-form) solutions.

Why Analytical Solutions Matter

In the previous article, we saw that IK can have zero, one, or many solutions. Analytical methods give us exact, closed-form answers — no iteration, no approximation, no convergence worries. When they exist, they’re fast and deterministic.

The catch? They only work for robots with specific geometries. A general 6-DOF arm doesn’t have a closed-form solution. But many practical robots do — and understanding how to derive these solutions is fundamental.

The 2-DOF Planar Arm

Let’s start with the simplest case: a two-link planar arm.

        Link 2 (L₂)
       /        |
      /         |
  θ₂ /          |
    /           |
   *------------*----------  x
  Shoulder    Elbow       (px, py)
   θ₁
   |
   O

Forward Kinematics (known from Week 1):

$$p_x = L_1 \cos\theta_1 + L_2 \cos(\theta_1 + \theta_2)$$

$$p_y = L_1 \sin\theta_1 + L_2 \sin(\theta_1 + \theta_2)$$

Inverse Kinematics — The Algebraic Approach:

Square and add both equations:

$$p_x^2 + p_y^2 = L_1^2 + L_2^2 + 2L_1 L_2 \cos\theta_2$$

Solving for θ₂:

$$\theta_2 = \pm \arccos\left(\frac{p_x^2 + p_y^2 - L_1^2 - L_2^2}{2 L_1 L_2}\right)$$

The ± sign gives us the elbow-up and elbow-down configurations — two distinct solutions!

For θ₁, we can use the geometric relationship:

$$\theta_1 = \text{atan2}(p_y, p_x) - \text{atan2}(L_2 \sin\theta_2, L_1 + L_2 \cos\theta_2)$$

The Reachability Condition

Not every target is reachable. The end-effector must lie within the arm’s workspace:

$$|L_1 - L_2| \leq \sqrt{p_x^2 + p_y^2} \leq L_1 + L_2$$

Python Implementation

import numpy as np

def ik_2dof(px, py, L1, L2, elbow='up'):
    """
    Analytical IK for a 2-DOF planar arm.
    
    Args:
        px, py: Target end-effector position
        L1, L2: Link lengths
        elbow: 'up' for positive θ₂, 'down' for negative θ₂
    
    Returns:
        (theta1, theta2) in radians, or None if unreachable
    """
    d_sq = px**2 + py**2
    
    # Reachability check
    if d_sq > (L1 + L2)**2 or d_sq < (L1 - L2)**2:
        return None  # Target unreachable
    
    # Solve for θ₂ using law of cosines
    cos_theta2 = (d_sq - L1**2 - L2**2) / (2 * L1 * L2)
    cos_theta2 = np.clip(cos_theta2, -1, 1)  # Numerical safety
    
    if elbow == 'up':
        theta2 = np.arccos(cos_theta2)
    else:
        theta2 = -np.arccos(cos_theta2)
    
    # Solve for θ₁
    theta1 = np.arctan2(py, px) - np.arctan2(
        L2 * np.sin(theta2), L1 + L2 * np.cos(theta2)
    )
    
    return theta1, theta2

# Example: reach for (3, 2) with link lengths 2 and 2.5
for config in ['up', 'down']:
    result = ik_2dof(3.0, 2.0, 2.0, 2.5, elbow=config)
    if result:
        t1, t2 = result
        print(f"Elbow-{config}: θ₁={np.degrees(t1):.1f}°, θ₂={np.degrees(t2):.1f}°")

Output:

Elbow-up: θ₁=30.5°, θ₂=70.5°
Elbow-down: θ₁=-16.8°, θ₂=-70.5°

Extending to 3-DOF: Adding a Wrist

A 3-DOF planar arm adds a third joint. The strategy is to decouple the problem:

  1. Wrist position: The third link’s orientation determines where the wrist must be
  2. Reduced 2-DOF problem: Solve for the first two joints to place the wrist
  3. Wrist angle: Compute the third joint from the desired orientation
def ik_3dof(px, py, phi, L1, L2, L3, elbow='up'):
    """
    Analytical IK for a 3-DOF planar arm.
    
    Args:
        px, py: Target position
        phi: Desired end-effector orientation (radians)
        L1, L2, L3: Link lengths
        elbow: 'up' or 'down'
    
    Returns:
        (theta1, theta2, theta3) or None
    """
    # Wrist position
    wx = px - L3 * np.cos(phi)
    wy = py - L3 * np.sin(phi)
    
    # Solve 2-DOF for first two links to reach wrist
    result = ik_2dof(wx, wy, L1, L2, elbow=elbow)
    if result is None:
        return None
    
    theta1, theta2 = result
    theta3 = phi - theta1 - theta2
    
    return theta1, theta2, theta3

This decoupling technique is incredibly powerful and forms the basis for solving 6-DOF industrial robots (which we’ll see use spherical wrists to decompose the problem into position and orientation).

Singularities

When the argument of arccos equals exactly ±1, we hit a singularity:

Near singularities, small changes in position require huge changes in joint angles. In practice, robot controllers add joint limits to stay away from these configurations.

When Analytical Solutions Exist

Analytical IK is possible when the robot has:

For general robots, we need numerical methods — which we’ll cover in the next two articles.

Key Takeaways

Next Steps

Tomorrow we’ll explore the Jacobian method — a completely different approach that uses the relationship between joint velocities and end-effector velocities to iteratively solve IK. It’s the bridge between analytical elegance and numerical flexibility.