The math that translates "reach to that point" into the joint angles that actually get you there.
You tell a robot arm: "Reach to position (0.5, 0.3, 0.7)." The robot stares at you blankly. It doesn't know what "positions" are. All it has are six motors, each capable of rotating to some angle. You want the hand at a specific position and orientation in space, but the robot only speaks the language of joint angles.
This is the inverse kinematics (IK) problem: given where you want the end-effector to be, figure out what every joint angle should be. It's the translation layer between human intention ("put the hand there") and robot execution ("set motor 1 to 42.3°, motor 2 to −15.7°, ...").
The forward direction is easy. If I tell you joint 1 is at 30° and joint 2 is at 45°, you can compute the end-effector position with basic trigonometry. That's forward kinematics (FK) — just plug angles into sine and cosine equations. Going backwards? That's where all the pain lives.
Think about your own arm. Reach for a cup on the table. Now reach for the same cup but with your elbow pointed up instead of down. Same hand position, completely different arm configuration. That's multiple IK solutions in action. Now try to touch the ceiling while sitting — you can't. That's the workspace boundary. IK must handle all three cases.
A 2-link arm is frozen in place. The orange target is where we want the hand to go. The arm doesn't know which joint angles would achieve that. That's the IK problem.
Every robot motion you've ever seen — a welding robot tracing a seam, a surgical arm inserting a needle, a Mars rover extending its instrument arm — requires solving IK. The motion planner says "move to this pose," and IK converts that into the motor commands that actually move the arm.
The stakes are high. A bad IK solver means the robot can't reach valid targets. A slow IK solver means the robot hesitates. An IK solver that misses solutions means the robot takes inefficient paths or collides with obstacles. Industrial robots solve IK millions of times per day.
| Property | Forward Kinematics | Inverse Kinematics |
|---|---|---|
| Input | Joint angles (θ1, ..., θn) | Desired pose (position + orientation) |
| Output | End-effector pose | Joint angles |
| Uniqueness | Always unique (one set of angles → one pose) | Often multiple solutions (0, 2, 4, 8, or 16) |
| Existence | Always exists | May not exist (target unreachable) |
| Complexity | Linear chain of matrix multiplications | Nonlinear system of trigonometric equations |
| Computation | Trivial (<1 μs) | Hard (1 μs to 10 ms depending on method) |
Before we can invert kinematics, we need to thoroughly understand the forward direction. Forward kinematics (FK) computes the end-effector position given all joint angles. For a planar 2-link arm, it's pure trigonometry — and it's the foundation everything else builds on.
Picture two rigid links connected by revolute joints (joints that rotate). The first link of length L1 attaches to a fixed base at the origin. It rotates by angle θ1 measured counter-clockwise from the positive x-axis. The second link of length L2 attaches to the end of the first link, rotating by θ2 relative to the first link's direction.
Where is the elbow (the point where the two links meet)?
This is just polar-to-Cartesian conversion. The first link starts at the origin and extends at angle θ1 for length L1.
Where is the end-effector (the tip of the second link)? The second link starts at the elbow and extends at the absolute angle θ1 + θ2. Why the sum? Because θ2 is measured relative to link 1, so the total angle from horizontal is θ1 + θ2.
That's it. Two equations mapping two joint angles to one 2D point. Forward kinematics is just a chain of rotations — each joint rotates everything downstream of it.
Drag the sliders to change joint angles. Watch the arm move and see the FK equations compute in real-time. The gray trail shows where the end-effector has been.
Let's compute FK with concrete numbers. Set L1 = 1.0, L2 = 0.7, θ1 = 45°, θ2 = 30°.
Step 1: Convert degrees to radians (since cos/sin expect radians in most programming languages):
Step 2: Compute the absolute angle of link 2:
Step 3: Compute the elbow position:
Step 4: Compute the end-effector position:
Verify: The arm points upward and slightly to the right. At 75° total angle, the hand is nearly vertical. The numbers match our geometric intuition. Set the sliders in the widget above to θ1=45, θ2=30 and confirm!
In 3D, the same principle applies but with rotation matrices instead of single angles. Each joint has a rotation axis (not just "counter-clockwise"), and the FK chain becomes a product of 4×4 homogeneous transformation matrices. We'll build up to that in Chapters 5 and 6.
python import numpy as np def fk_2r(theta1, theta2, L1=1.0, L2=0.7): """Forward kinematics for a 2-link planar arm.""" x = L1 * np.cos(theta1) + L2 * np.cos(theta1 + theta2) y = L1 * np.sin(theta1) + L2 * np.sin(theta1 + theta2) return x, y # Example: theta1=45°, theta2=30° x, y = fk_2r(np.radians(45), np.radians(30)) print(f"End-effector: ({x:.3f}, {y:.3f})") # Output: End-effector: (0.888, 1.383)
Now we flip the problem. Given a target position (x, y), find the joint angles θ1, θ2 that place the end-effector there. This is the simplest possible inverse kinematics problem — only two unknowns — and it already reveals the core challenges: multiple solutions, workspace limits, and the power of geometric thinking.
Instead of staring at the FK equations and trying to algebraically invert them, let's think geometrically. We have a triangle.
The three sides are:
By the law of cosines, we can relate the interior angle at the elbow to these three sides:
Why π − θ2? Because the interior angle of the triangle at the elbow is the supplement of θ2. When θ2 = 0, the arm is fully extended and the interior angle is π (180°). When θ2 = π, the arm folds back on itself and the interior angle is 0.
Since cos(π − θ2) = −cos(θ2), we can rearrange:
Call this value c2. This is a single number computed directly from the target position and the link lengths. Three things can happen:
A naive approach would be θ2 = arccos(c2), giving two solutions ±arccos(c2). But never use arccos for IK. Here's why:
At the workspace boundary (c2 = ±1), the derivative of arccos is infinite. A tiny numerical error in c2 (say, 1.0000001 instead of 1.0) produces a NaN. The robust approach computes both sin(θ2) and cos(θ2) separately:
The positive square root gives elbow-up. The negative gives elbow-down. Two physically different arm configurations that reach the same target.
Once we know θ2 (and therefore c2 and s2), the FK equations become linear in sin(θ1) and cos(θ1). Let's see why.
Expand the FK equations using angle addition formulas:
Group the sinθ1 and cosθ1 terms:
Let k1 = L1 + L2 c2 and k2 = L2 s2. Then:
This elegant formula has a geometric interpretation: atan2(y, x) is the angle from the base to the target, and atan2(k2, k1) is the offset angle caused by the elbow bend.
Target: (1.2, 0.8), L1 = 1.0, L2 = 0.8.
Step 1 — Compute c2:
Step 2 — Compute s2 and θ2:
Elbow-up: θ2 = atan2(0.9614, 0.275) = 74.0°
Elbow-down: θ2 = atan2(−0.9614, 0.275) = −74.0°
Step 3 — Compute θ1 (for elbow-up):
Step 4 — Verify with FK:
The FK output matches the target exactly. Always verify IK solutions with FK — it's the cheapest debugging step in robotics.
The set of reachable points forms an annular ring (donut shape). The outer boundary is rmax = L1 + L2 (arm fully extended, θ2 = 0). The inner boundary is rmin = |L1 − L2| (arm folded back, θ2 = π). Any target inside this ring has exactly two IK solutions. Any target outside has zero.
python import numpy as np def ik_2r(x, y, L1=1.0, L2=0.8): """Inverse kinematics for 2R planar arm. Returns list of (th1, th2) pairs.""" d2 = x**2 + y**2 c2 = (d2 - L1**2 - L2**2) / (2 * L1 * L2) if abs(c2) > 1: return [] # unreachable solutions = [] for sign in [1, -1]: s2 = sign * np.sqrt(max(0, 1 - c2**2)) th2 = np.arctan2(s2, c2) k1 = L1 + L2 * c2 k2 = L2 * s2 th1 = np.arctan2(y, x) - np.arctan2(k2, k1) solutions.append((th1, th2)) return solutions # Verify: for th1, th2 in ik_2r(1.2, 0.8): x, y = fk_2r(th1, th2, 1.0, 0.8) print(f"th1={np.degrees(th1):.1f}° th2={np.degrees(th2):.1f}° -> ({x:.3f}, {y:.3f})")
Drag the orange target anywhere on the canvas. Both IK solutions are shown simultaneously: teal = elbow-up, orange = elbow-down. The gray ring shows the workspace boundary. Move the target outside the ring to see what happens when IK has no solution.
In Chapter 2, we solved 2R IK with the law of cosines. That worked beautifully for two joints in a plane. But real robots have six joints in 3D space, with arbitrary axis orientations. How do we scale up?
The IK-Geo framework (Elias & Wen, 2022) provides an elegant answer. The key insight is deceptively simple, and once you see it, you can't unsee it.
When you rotate a point p around an axis k by angle θ, the point traces out a circle. This is true in any number of dimensions, but it's easiest to visualize in 3D.
The circle lies on a plane perpendicular to k, centered at the point where k passes closest to p. The radius of the circle is the perpendicular distance from p to the axis k.
In 2D, this is obvious — rotating a point around the origin sweeps a circular arc. In 3D, the same thing happens, but the circle lives on a cone around the rotation axis. Think of a spinning top: a point on the rim traces a circle around the spin axis.
The simplest geometric IK subproblem: given a rotation axis k and a point p1, find the angle θ that rotates p1 as close as possible to a target point p2.
Geometrically: the set of all points R(k, θ)p1 as θ varies is a circle. We need the point on this circle closest to p2.
The solution is elegant: project both p1 and p2 onto the plane perpendicular to k. The angle between their projections is θ. If p2 lies exactly on the circle, we get an exact match. Otherwise, we get the closest point. At most one solution.
Now the case that connects directly to 2R IK: two joints, two unknowns. Rotating p1 around axis k1 traces one circle. Rotating p2 around axis k2 traces another circle. The IK solution requires both rotations to produce the same intermediate point — so we need the two circles to intersect.
Two circles in 3D can intersect at 0, 1, or 2 points. Each intersection gives a pair (θ1, θ2). This is exactly the elbow-up / elbow-down duality from Chapter 2 — but stated in pure geometry instead of trigonometric algebra.
The power of this perspective is that it generalizes effortlessly to 3D. The law of cosines only works for planar arms. The circle-intersection approach works for any pair of revolute joints, regardless of axis orientation.
Drag the θ slider to rotate the point p around the axis k. The point traces a circle. The target is fixed. Click Solve SP1 to find the closest approach.
Here's why this geometric perspective is so powerful. Consider a 6R robot. Each joint traces a circle. The FK chain says: rotate point through circle 1, then circle 2, then circle 3, and so on. IK asks: for which specific angles on each circle does the composition reach the target?
IK-Geo decomposes this into subproblems. Sometimes you can solve two consecutive joints by intersecting their circles (SP2). Sometimes you need to intersect a circle with a sphere defined by a distance constraint (SP3). Sometimes with a plane (SP4). Each subproblem has a closed-form solution.
IK-Geo identifies six canonical subproblems. Every IK problem for a serial robot with revolute joints can be decomposed into combinations of these six building blocks. Each subproblem has a closed-form solution using atan2 — no numerical iteration, no arccos, no tangent half-angle substitution.
Let's meet all six.
| SP | Name | Geometry | Unknowns | Max Solutions |
|---|---|---|---|---|
| 1 | Circle ∩ Point | Rotate p around k to reach q | 1 angle | 1 |
| 2 | Two Circles | Two rotations compose: R1p = R2q | 2 angles | 2 |
| 3 | Circle ∩ Sphere | Rotate p to land on a sphere | 1 angle | 2 |
| 4 | Circle ∩ Plane | Rotate p to land on a plane | 1 angle | 2 |
| 5 | Three Circles | Three rotations compose, middle direction known | 3 angles | 4 |
| 6 | Four Circles | Two pairs of rotations match a distance | 4 angles | 4 |
Problem: Given axis k, find θ such that R(k, θ)p = q.
Method: Project p and q onto the plane perpendicular to k. The angle between the projections is θ. Compute via atan2 of the cross product and dot product of the projections.
Exact solution exists when: ‖p − (k·p)k‖ = ‖q − (k·q)k‖ and k·p = k·q. In words: both points must be the same distance from the axis and at the same height along the axis.
Problem: Given axes k1, k2, find θ1, θ2 such that R(k1, θ1)p1 = R(k2, θ2)p2.
Method: Each rotation traces a circle. Find where the two circles intersect. The intersection reduces to a 1D equation solvable with atan2.
Connection to 2R IK: This is exactly the elbow-up/down problem! SP2 is the generalization of 2R IK to arbitrary 3D axis orientations.
Problem: Find θ such that ‖R(k, θ)p − c‖ = r.
Method: The rotated point must land on a sphere of radius r centered at c. A circle and a sphere in 3D intersect at up to 2 points (think of a hula hoop passing through a basketball).
Why it matters: When solving for an arm's reach to a target, the constraint "joint 3's position is at distance d from joint 5's position" is naturally a sphere constraint. SP3 is the 3D generalization of our 2R law-of-cosines approach.
Problem: Find θ such that nT · R(k, θ)p = d.
Method: The rotated point must land on a plane defined by normal n and offset d. A circle intersects a plane at up to 2 points.
Use case: When a joint axis is parallel to a constraint direction, the problem reduces to a plane intersection.
SP5: Three consecutive rotations with a known intermediate direction. Reduces to intersecting two circles derived from the outer rotations, with the middle rotation determined afterwards. Up to 4 solutions.
SP6: Four rotations split into two pairs, constrained by a distance equality. Also up to 4 solutions.
Click a subproblem to see its geometric construction. The blue circle is the rotation path. Solutions appear as green dots.
SP1: Rotate point p (teal) around axis k to reach target q (yellow). One solution.
The maximum number of IK solutions for a 6R robot is determined by how the subproblems chain together. For a robot with a spherical wrist:
We've solved 2D IK. Real robots live in 3D. To handle 3D, we need the mathematical language of rotation matrices — 3×3 matrices that rotate vectors without stretching, shrinking, or reflecting them.
A 3×3 matrix R is a rotation matrix if and only if:
These two properties guarantee that rotation preserves distances and handedness. The set of all 3×3 rotation matrices forms a mathematical group called SO(3) — the Special Orthogonal group in 3 dimensions.
Any 3D rotation can be described by two things: an axis (which direction to rotate around) and an angle (how far to rotate). This is the axis-angle representation: rotate by angle θ around unit vector k = [kx, ky, kz].
The standard rotation matrices around the three coordinate axes are:
Notice the pattern: the row and column corresponding to the rotation axis are "identity-like" (1 on diagonal, 0 elsewhere). The other four entries form a 2D rotation.
For rotation around an arbitrary axis k by angle θ, we use Rodrigues' rotation formula:
Where [k]× is the skew-symmetric matrix that computes the cross product:
This means [k]× v = k × v (cross product) for any vector v.
Let's unpack the three terms of Rodrigues' formula:
Rotate v = [1, 0, 0] by 90° around k = [0, 0, 1] (the z-axis).
cos(90°) = 0, sin(90°) = 1.
Term 1: I · 0 = [[0,0,0],[0,0,0],[0,0,0]]
Term 2: (1 − 0) · kkT = [[0,0,0],[0,0,0],[0,0,1]] (only the zz entry survives because k=[0,0,1])
Term 3: 1 · [k]× = [[0,−1,0],[1,0,0],[0,0,0]]
Sum: R = [[0,−1,0],[1,0,0],[0,0,1]]
Apply: R · [1,0,0]T = [0,1,0] ✓
The x-axis unit vector rotated 90° around z becomes the y-axis unit vector. This matches our geometric intuition: looking down at the xy-plane, a 90° counter-clockwise rotation sends x to y.
python import numpy as np def rodrigues(k, theta): """Rotation matrix from axis k (unit vector) and angle theta.""" k = np.array(k, dtype=float) K = np.array([[0, -k[2], k[1]], [k[2], 0, -k[0]], [-k[1], k[0], 0]]) I = np.eye(3) return I * np.cos(theta) + (1 - np.cos(theta)) * np.outer(k, k) + np.sin(theta) * K # Verify: rotate [1,0,0] by 90° around z R = rodrigues([0, 0, 1], np.pi/2) v = R @ np.array([1, 0, 0]) print(v) # [0, 1, 0]
Choose a rotation axis and drag the angle slider. Watch the vector v = [1,0,0] rotate, and see the rotation matrix values update in real-time. The arc shows the rotation path.
R = [[1.00, 0.00, 0.00], [0.00, 1.00, 0.00], [0.00, 0.00, 1.00]]
Now we leave the plane and enter the real world: a 6-DOF robot arm with six revolute joints. Each joint rotates around its own axis. The forward kinematics is a chain of six rotations and translations, expressed as a product of homogeneous transformation matrices.
This is the robot arm that builds your car, fills your Amazon orders, and performs surgery. Let's understand it.
In 3D, each link doesn't just rotate — it also translates. We need to handle both. A 4×4 homogeneous transformation matrix packs a rotation R and a translation d into a single matrix:
The beauty: composing two transforms (first transform by T1, then by T2) is just matrix multiplication:
This is the power of homogeneous coordinates. Rotation and translation, which are normally different operations, become a single matrix multiply.
Each joint i has a rotation axis hi and a reference position. The transform for joint i at angle qi is a rotation of qi around axis hi, plus the fixed offset between joints.
The full FK from base (frame 0) to end-effector (frame 6) is:
This gives us a 4×4 matrix encoding both the position (where the hand is — the translation column) and orientation (which way it's pointing — the rotation block) of the end-effector. Six numbers in (the joint angles), twelve numbers out (3×3 rotation + 3×1 position). But the rotation has only 3 independent degrees of freedom (it's constrained to be orthogonal), so the output is truly 6-dimensional: 3 for position, 3 for orientation. This matches our 6 joint inputs.
Our visualization models a simplified UR5-like robot (Universal Robots UR5, one of the most common collaborative robots). The joint axes alternate between vertical (Y-axis) and horizontal (Z-axis) rotations, creating the familiar "elbow" shape:
| Joint | Axis | Role | Typical Range |
|---|---|---|---|
| q1 | Y (vertical) | Base rotation (turntable) | ±360° |
| q2 | Z (horizontal) | Shoulder (lift) | ±360° |
| q3 | Z (horizontal) | Elbow (reach) | ±360° |
| q4 | Y (vertical) | Wrist 1 (rotate) | ±360° |
| q5 | Z (horizontal) | Wrist 2 (tilt) | ±360° |
| q6 | Y (vertical) | Wrist 3 (spin) | ±360° |
Drag sliders to change joint angles q1–q6. Drag on the canvas to orbit the camera. Colored segments show different links: shoulder/elbow, forearm, wrist. The orange tip is the end-effector.
End-effector: (0.00, 0.00, 0.00)
Solving IK for six joints simultaneously sounds daunting. Six nonlinear equations in six unknowns, with trigonometric terms everywhere. But most industrial robots have a geometric trick up their sleeve that cuts the problem in half.
If the last three joint axes all intersect at a single point, the robot has a spherical wrist. The point where they intersect is called the wrist center.
Why does this help? Because the wrist center's position depends only on joints 1, 2, 3 (the "shoulder" and "elbow"). Joints 4, 5, 6 rotate the hand around the wrist center without moving it. This means we can split the 6-joint IK into two independent 3-joint problems:
This is the Pieper criterion (1968): a 6R robot has closed-form IK if and only if three consecutive axes intersect at a point (or are parallel).
The wrist center is offset from the end-effector by the tool length d6 along the approach direction (the z-axis of the desired frame). If the desired end-effector pose is position ptarget with rotation Rtarget, then:
In words: start at the desired hand position, walk backwards along the hand's z-axis by the wrist-to-tip distance. That's the wrist center. This is computable immediately from the desired pose — no joint angles needed yet.
With the wrist center known, we need q1, q2, q3 such that FK of joints 1-3 places the wrist center at pwrist. For a typical industrial robot (UR5, KUKA, ABB, Fanuc):
q1 (base rotation): This is usually the simplest. The base rotates around the vertical axis, so q1 = atan2(pwrist,y, pwrist,x). But wait — there's an ambiguity. The arm can reach the same wrist center from the "front" or the "back" (shoulder left/right). That gives 2 solutions for q1.
q2, q3 (shoulder + elbow): Once q1 is fixed, the remaining problem is planar — exactly the 2R IK from Chapter 2! We project the wrist center into the plane of links 2 and 3, then use the law of cosines / circle-sphere intersection. 2 solutions (elbow up/down).
Total for position: 2 × 2 = 4 configurations.
Once joints 1-3 are known, the rotation R03 (from base to frame 3) is determined. The wrist must achieve the remaining rotation:
This is a known rotation matrix that must be decomposed into three rotations around the wrist axes. For a ZYZ wrist configuration (common in industrial robots), this is Euler angle extraction:
Extracting q4, q5, q6 from R36 is a well-known trigonometric exercise. The key: q5 = atan2(√(r31² + r32²), r33), and there are 2 solutions (wrist flip / no flip, corresponding to ±q5).
For each of the 4 position solutions, there are 2 orientation solutions, giving 4 × 2 = 8 total IK solutions.
Toggle between position mode (only joints 1-3 move) and orientation mode (only joints 4-6 move). The yellow dot marks the wrist center. Watch how position joints move the wrist center while orientation joints rotate around it.
This is the payoff chapter. Everything we've built — FK chains, the law of cosines, geometric subproblems, rotation matrices, position-orientation decoupling — comes together here. We build a complete IK solver for a 6R robot with a spherical wrist. Given a desired end-effector pose, we find all valid joint configurations.
Each binary choice doubles the solution count:
Each solution is a physically distinct robot configuration that reaches the same end-effector pose. They look completely different — the elbow points a different direction, the shoulder reaches around a different way — but the hand ends up in exactly the same place and orientation.
With up to 8 solutions, which one should the robot use? Common criteria:
python def ik_6r_spherical_wrist(p_target, R_target, robot): """Full IK for 6R robot with spherical wrist. Returns list of joint angle tuples (q1...q6).""" solutions = [] # Step 1: Wrist center p_wrist = p_target - robot.d6 * R_target @ np.array([0,0,1]) # Step 2: Solve q1 (2 solutions) for q1 in solve_base_angle(p_wrist): # shoulder L/R # Step 3: Solve q2, q3 (2 solutions each) for q2, q3 in solve_elbow(p_wrist, q1, robot): # elbow up/down # Step 4: Solve q4, q5, q6 (2 solutions) R03 = fk_rotation(q1, q2, q3, robot) R36 = R03.T @ R_target for q4, q5, q6 in euler_zyz(R36): # wrist flip # Step 5: Check joint limits q = [q1, q2, q3, q4, q5, q6] if robot.within_limits(q): solutions.append(q) return solutions # up to 8 solutions
Use the slider to adjust the target height. Use Prev/Next to cycle through all IK solutions. The solid arm is the selected solution; ghost arms show alternatives. Drag on the canvas to orbit the camera.
Computing solutions...
Not every robot configuration is created equal. At certain configurations called singularities, the robot loses a degree of freedom — it can't move in some direction no matter what it does. Understanding singularities is essential because they cause real-world catastrophes: infinite joint velocities, controller instability, and dangerous vibrations.
The Jacobian J is a matrix that maps joint velocities to end-effector velocities:
For a 2R planar arm, J is 2×2:
Where s1 = sinθ1, c1 = cosθ1, s12 = sin(θ1+θ2), c12 = cos(θ1+θ2).
The determinant is:
This is zero when θ2 = 0 or π — exactly when the arm is fully extended or fully folded.
When det(J) = 0, the Jacobian is not invertible. The equation q̇ = J−1 vee breaks down. Physically, this means:
Workspace boundary singularity: The arm is fully extended (θ2 = 0) or fully folded (θ2 = π). At this configuration, the arm can only move tangentially — it physically cannot reach further outward or fold further inward. The two IK solutions (elbow-up and elbow-down) merge into one.
Internal singularity: Two joint axes align, creating redundancy in one direction and a dead zone in another. For example, when a robot's shoulder and elbow axes become coplanar, the arm can spin freely around one axis but can't generate velocity perpendicular to it.
Wrist singularity: When q5 = 0 in a ZYZ wrist, axes 4 and 6 become collinear. The robot can spin joints 4 and 6 freely (only their sum q4 + q6 matters), but it's lost the ability to rotate about one axis. This is the most common singularity in industrial robots and must be carefully avoided during path planning.
Drag the target toward the workspace boundary. Watch the Jacobian determinant drop toward zero. The velocity ellipse shows which directions the arm can move easily (long axis) vs barely at all (short axis). At the boundary, the ellipse collapses.
det(J) = 1.000 — Full mobility
As the target approaches a singularity, the IK solutions become numerically ill-conditioned. Small changes in the target produce large jumps in joint angles. This is a fundamental mathematical property, not a bug in the solver. IK-Geo handles this gracefully because it uses atan2 (which is well-defined everywhere), but the solutions themselves become sensitive near singularities.
Everything so far assumes the robot has three consecutive axes that intersect (spherical wrist) or are parallel. But what about robots where no such structure exists? General 6R robots — where no three consecutive axes have special geometric relationships — have no closed-form IK solution. The system of equations is a polynomial of degree up to 16.
This is where IK-Geo's approach truly shines. Even for general robots, it doesn't abandon geometric reasoning for brute-force gradient descent. Instead, it reduces the problem to a 1D search over a single joint angle.
The idea is beautiful in its simplicity. Pick one joint, say q4. For any fixed value of q4, the remaining five joints can be solved in closed form using subproblems. This is because fixing one angle creates enough geometric structure for the subproblems to apply.
So we define an error function:
Where q1, q2, q3, q5, q6 are all determined (via subproblems) as functions of the fixed q4. The zeros of e(q4) are the IK solutions.
The algorithm:
A general 6R robot can have up to 16 IK solutions (proven by algebraic geometry — the system is a degree-16 polynomial). In practice, most configurations have 2-8 real solutions. IK-Geo's 1D search finds them all by sampling densely enough to catch every zero crossing.
For robots with 2D search (two free parameters), the problem becomes finding the zero contour of a 2D error function. This is more expensive but still vastly better than 6D gradient descent.
| Robot Type | Search Dim | Max Solutions | Example |
|---|---|---|---|
| 3 intersecting axes | 0 (closed form) | 8 | UR5, KUKA KR |
| 3 parallel axes | 0 (closed form) | 8 | SCARA-type |
| 2 intersecting + 1 special | 1 | 16 | Some custom arms |
| General 6R | 1-2 | 16 | Custom/exotic arms |
The error function e(q4) is plotted over [−π, π]. Zeros (where the curve crosses the horizontal axis) are IK solutions, marked with green dots. Drag the teal cursor to explore different q4 values. The arm below shows the resulting configuration.
e(q4) = 0.000 — Scanning...
Inverse kinematics is the bridge between intention and motion. Every time a robot arm reaches for an object, welds a seam, inserts a peg, catches a ball, or sutures a wound — IK is the silent translator converting desired end-effector poses into motor commands. You now understand the mathematics behind all of it.
| Method | Type | Speed | All Solutions? | Singularity-Safe? |
|---|---|---|---|---|
| IK-Geo | Geometric | <5 μs | Yes | Yes (atan2 only) |
| IKFast | Symbolic | ~200 μs | Yes | Mostly |
| TRAC-IK | Numerical | ~1 ms | No (one at a time) | No |
| Jacobian pseudoinverse | Iterative | Variable | No | No (blows up) |
| CCD / FABRIK | Heuristic | Fast | No | No |
| Neural network IK | Learned | ~100 μs | No | Depends on training |
Redundant robots (7+ DOF): The Franka Panda has 7 joints — one more than needed for 6-DOF tasks. The extra joint gives a continuous family of IK solutions parameterized by a redundancy angle. GeoFIK (Elias & Wen, 2025) solves this geometrically, finding all solutions along the redundancy manifold with analytical Jacobians as a byproduct.
Cuspidal robots: Some robots can change between IK solution branches without passing through a singularity. These cuspidal configurations create topological traps for path planners — a motion that looks smooth in Cartesian space may require a discontinuous jump in joint space. Elias & Wen (2025) developed specialized path planning algorithms that detect and handle cusp crossings.
Learning-based IK: Neural networks can approximate IK, especially for complex kinematic chains (humanoid hands, snake robots, soft robots). But they sacrifice guaranteed accuracy, completeness, and interpretability. Geometric methods remain the gold standard for precision applications where you need all solutions and need to know when IK is infeasible.