RobotForge
Published·~13 min

The Jacobian and velocity kinematics

The matrix that connects joint speeds to end-effector velocities — and joint torques to end-effector forces. Master it once and most arm-control intuition follows.

by RobotForge
#kinematics#jacobian#math

If forward kinematics asks "where is the hand?", velocity kinematics asks "how fast does the hand move when I move the joints?" The Jacobian is the linear map that answers it. Once you see it, you have one tool for IK, force mapping, manipulability, and singularity analysis.

The definition

Given forward kinematics (end-effector pose as a function of joints), the Jacobian is the matrix of partial derivatives:

For an arm with n joints producing a 6-DOF pose, is 6×n. Three rows for translational velocity, three for angular.

The relationship that matters:

Push joint velocities through , get end-effector velocity .

Geometric Jacobian for a serial arm

For an arm where each joint axis is (in world frame, after the joint) and each joint origin is , the i-th column of the geometric Jacobian is:

  • For a revolute joint: where is the end-effector position.
  • For a prismatic joint: .

The cross product is the linear velocity at the end-effector when joint i rotates at unit angular velocity. alone is the angular velocity contribution. Stack the columns to build .

Compute this every iteration of an IK solver, every control tick.

Two facts that follow

1. Inverse velocity kinematics

Given a desired end-effector velocity , find joint velocities:

That's the iterative IK building block. is the pseudoinverse.

2. Force mapping

Forces at the end-effector map to joint torques via the transpose:

If you push the gripper with 10 N, this tells you the torque each joint experiences. Conversely, if your joint torque controller commands , the end-effector applies (when is square; pseudoinverse otherwise).

This is the duality: motion goes through , force goes through . A single matrix runs both directions of every arm interaction.

Singular values of J — the manipulability story

Take the SVD: . The singular values encode how easily the arm moves in each Cartesian direction.

  • : a Cartesian direction in which the arm cannot move infinitesimally. That's a singularity.
  • : tiny joint motion produces big end-effector motion. Sensitive, jittery.
  • Manipulability index : a single number measuring "how dexterous is the arm here?" Maximize it as a secondary IK objective.
  • Condition number : ratio of biggest to smallest. Bigger = closer to singular = numerically dangerous.

Common singularities

  • Boundary singularity: arm fully extended. The end-effector can't move further along the radial direction.
  • Wrist singularity: two wrist joint axes align. End-effector can't rotate around an axis perpendicular to both.
  • Internal singularity: specific joint configurations within the workspace. Rare, but they exist.

Real arms detect singularities in software and refuse motions that drive into them. Pseudoinverse + damping (covered in iterative IK lesson) is one path; explicit singularity avoidance via the manipulability gradient is another.

Computing the Jacobian numerically

def numerical_jacobian(forward_kin, q, eps=1e-6):
    n = len(q)
    x0 = forward_kin(q)
    J = np.zeros((len(x0), n))
    for j in range(n):
        q_p = q.copy(); q_p[j] += eps
        J[:, j] = (forward_kin(q_p) - x0) / eps
    return J

For a 6×6 arm, this calls forward kinematics 7 times per Jacobian. Slow but correct. Use it as a sanity check on your analytical Jacobian — they should agree to within a few eps tolerance.

For production, derive the geometric Jacobian analytically. Many libraries (KDL, Pinocchio, Drake) do this for you given a URDF.

Six-DOF Jacobian in code (Pinocchio-style)

import pinocchio as pin
import numpy as np

model = pin.buildModelFromUrdf('panda.urdf')
data = model.createData()

q = pin.neutral(model)
end_effector_id = model.getFrameId('panda_hand')

pin.computeFrameJacobian(model, data, q, end_effector_id, pin.LOCAL)
J = pin.getFrameJacobian(model, data, end_effector_id, pin.LOCAL)
print(J.shape)  # (6, 7) for a 7-DOF Panda

Three lines after model loading. Pinocchio handles the analytical derivation, deals with prismatic vs revolute, manages frame transforms. Beats hand-rolling.

Velocity vs body Jacobian (the gotcha)

Two conventions for "what frame is the angular velocity expressed in":

  • Spatial / world Jacobian: angular velocity in the world frame.
  • Body Jacobian: angular velocity in the end-effector frame.

Different libraries default to different conventions. The math relating them is straightforward, but if you mix them silently, your control law commands the wrong rotations. Read the docs.

The full toolkit

Use J for… Operation
Forward velocity kinematics
Inverse velocity kinematics
Force mapping
Manipulability
Null-space tasks

Exercise

Take a 2-DOF planar arm. Derive the geometric Jacobian analytically (it's 2×2). Compute the determinant. Plot as a function of — you'll see it goes to zero at (arm fully extended) and (folded). Those are the boundary singularities. Now implement the damped pseudoinverse IK from the previous lesson and watch how it behaves near those configurations.

Next

Lagrangian dynamics — turning kinematics into a force-and-torque story. The mass matrix M(q), Coriolis, gravity, and the equation that controls every arm.

Comments

    Sign in to post a comment.