Space and body Jacobians: map joint rates to rigid motion

Build space and body Jacobians from joint screw axes, recover the physical tool velocity, and compare their ranks with a position-only task. Explore a planar two-link arm and verify its derivatives in Python.

By 14 min read

What you will learn

  • Construct Jacobian columns by transforming joint screw axes into the required frame.
  • Convert joint rates into space and body twists with an explicit angular-first convention.
  • Recover the tool point's physical velocity from either twist representation.
  • Explain why a position singularity can coexist with full column rank in a pose Jacobian.

Before you start

Two joint motors set the motion of a robot arm, but the tool has both a position and an orientation. A Jacobian tells us which instantaneous tool motions those joint rates produce.

Space and body Jacobians describe the same rigid motion in different frames. Their linear twist coordinates need careful interpretation: a spatial linear coordinate generally differs from the physical velocity of the tool point. This lesson calculates both representations and shows how the choice of task changes the meaning of a singularity.

Map joint rates to a twist

Let T = T_sb describe the tool frame b in a fixed space frame s. It maps body-coordinate column points into space coordinates. A serial robot has joint coordinates θ = (θ₁, …, θₙ) and current rates θ̇.

Use angular-first twists V = (ω, v). In three dimensions this gives six rows; a planar model keeps (ω_z, vₓ, vᵧ). The two Jacobians satisfy:

V_s = J_s(θ)θ̇
V_b = J_b(θ)θ̇
V̂_s = ṪT⁻¹,   V̂_b = T⁻¹Ṫ

Each column answers one question: what twist results when that joint moves at unit rate and the others stop? Multiplying each column by its rate and adding gives the complete twist. Modern Robotics introduces the space Jacobian through these joint contributions.

The arm below has two revolute joints. Its joint rates and angular twist coordinate use rad/s; linear twist coordinates use m/s. The planar twist Jacobians are 3 × 2. Their angular row converts angular rates, while their linear rows carry length per radian.

Build space columns from home screw axes

Let Sᵢ be joint i's screw axis in the space frame at the home configuration. The product-of-exponentials formula is:

T(θ) = exp(Ŝ₁θ₁) ⋯ exp(Ŝₙθₙ) M

Earlier joints move joint i's axis relative to space. Define Pᵢ as the product of their exponentials, in the same order. Then the corresponding Jacobian column is:

Pᵢ = exp(Ŝ₁θ₁) ⋯ exp(Ŝᵢ₋₁θᵢ₋₁)
J_s,i = Ad_(Pᵢ) Sᵢ
J_s,1 = S₁

The adjoint transforms the screw's angular and linear parts together. The first column stays fixed because no joint precedes it. Column i depends on preceding joint coordinates, not on later ones.

For our planar arm, link lengths are L₁ = 2 m and L₂ = 1 m. Both positive joint rotations point along +z. At home, both links lie along +x, so the planar home screws are S₁ = (1, 0, 0) and S₂ = (1, 0, −2).

At shoulder angle θ₁, the elbow axis passes through (2 cos θ₁, 2 sin θ₁). Its normalized linear coordinates are (2 sin θ₁, −2 cos θ₁). Thus:

J_s =
[ 1, 1 ]
[ 0, 2 sin θ₁ ]
[ 0, −2 cos θ₁ ]

This matrix does not depend on the elbow angle θ₂. The physical tip velocity still does, because the tip's location changes with θ₂.

Build body columns and change frames

Let Bᵢ describe each home screw in the home tool frame. The body form of forward kinematics is T = M exp(B̂₁θ₁) ⋯ exp(B̂ₙθₙ). To build body column i, express Bᵢ in the current tool frame using the inverse of the later joint motions:

Qᵢ = exp(−B̂ₙθₙ) ⋯ exp(−B̂ᵢ₊₁θᵢ₊₁)
J_b,i = Ad_(Qᵢ) Bᵢ
J_b,n = Bₙ

The negative signs and reversed order come from inverting that later product. The last column stays fixed because the final joint's relationship to the tool frame does not depend on preceding joints. Modern Robotics derives this body-column construction.

For the same tool origin and axes, every column obeys the twist frame-change rule:

J_s = Ad_T J_b
J_b = Ad_(T⁻¹) J_s

The adjoint is invertible, so these matrices have the same rank. They also have the same joint-rate null space: a rate vector produces zero full twist in one frame exactly when it does in the other.

Our tool frame sits at the tip, with x along link 2. Its home origin is (3, 0), giving B₁ = (1, 0, 3) and B₂ = (1, 0, 1). The planar body Jacobian becomes:

J_b =
[ 1, 1 ]
[ 2 sin θ₂, 0 ]
[ 2 cos θ₂ + 1, 1 ]

Recover the physical tool velocity

Let p be the tool origin in space coordinates. A spatial twist defines the rigid-motion field u(x) = ω_s × x + v_s. Evaluating it at the tool origin gives:

ṗ = ω_s × p + v_s = Rv_b

The body linear coordinate v_b expresses the tool-origin velocity in body axes. Multiplying by R expresses that physical velocity in space axes. Neither value means that the tool origin changes coordinates within its own attached frame; those body coordinates remain zero.

We can also differentiate the position directly. The elbow angle is relative to link 1, so the tool heading is φ = θ₁ + θ₂ and its position is p = (2 cos θ₁ + cos φ, 2 sin θ₁ + sin φ). Therefore the position-task Jacobian is:

J_p =
[ −2 sin θ₁ − sin φ, −sin φ ]
[ 2 cos θ₁ + cos φ, cos φ ]
ṗ = J_p θ̇

Deleting the angular row of J_s would give v_s, which usually differs from ṗ. The point Jacobian lesson develops this direct derivative and the distinction between instantaneous velocity and a finite step.

Calculate both Jacobians for a two-link arm

Choose θ₁ = 90°, θ₂ = −90°, and θ̇ = (0.5, −0.25) rad/s. The tip is at p = (1, 2) m, and the tool heading is zero. The body and space axes currently align, though their origins differ.

J_s =
[ 1, 1 ]
[ 0, 2 ]
[ 0, 0 ]


J_b =
[ 1, 1 ]
[ −2, 0 ]
[ 1, 1 ]

Multiplying by the joint rates gives V_s = (0.25, −0.5, 0) and V_b = (0.25, −1, 0.25). The first entry in each triple is rad/s; the others are m/s.

Recover the tool velocity from the spatial representation:

ω_s × p = (−0.5, 0.25) m/s
ṗ = (−0.5, 0.25) + (−0.5, 0)
ṗ = (−1, 0.25) m/s

Since R = I here, the last two body-twist entries give the same physical velocity directly. The position matrix J_p = [−2, 0; 1, 1] produces it too. All three calculations agree.

Change the pose and isolate joint contributions

Use Shoulder only and Elbow only to see each column's contribution. Changing the rates changes the output twist, while the Jacobian matrices remain tied to the selected configuration. A stopped arm still has a Jacobian describing the motions it could produce.

One arm, three velocity maps

Map joint rates to space and body twists

Link lengths are 2 m and 1 m. θ₁ is the shoulder angle; θ₂ is relative to the first link. The tool frame sits at the tip, with x along the final link. Positive angles turn counterclockwise.

90
-90
0.50
-0.25
  • Amber solid: physical tool velocity at the tip
  • Blue dashed: spatial linear coordinate vₛ at the space origin
Tool at (1.000, 2.000) meters with space velocity (-1.000, 0.250) meters per secondFixed equal space-coordinate scales in meters. Dark segments show the two rigid links, with the shoulder at the origin, an open elbow marker, and a filled tool marker. Short gray tool axes show x solid and y dashed. Velocity arrows use a half-second display scale. The amber arrow starts at the tool; blue dashes start at the space origin and show the linear part of the spatial twist. Rings mark arrows with zero displayed displacement. This is an instantaneous diagram.-4-40044xy
The arrows end at their starting position plus 0.5 s times the instantaneous velocity. Their lengths share the meter scales of the plot. They do not predict finite-motion endpoints. A stationary tool point can still have a changing tool orientation.
Tool position (m)
(1.000, 2.000)
Tool heading (degrees)
0.000
Space twist (ω, vₓ, vᵧ)
(0.250, -0.500, 0.000)
Body twist (ω, vₓ, vᵧ)
(0.250, -1.000, 0.250)
Tool velocity in space (m/s)
(-1.000, 0.250)
Tool velocity from body (m/s)
(-1.000, 0.250)
Full pose rank (Jₛ and Jᵦ)
2
Position task rank
2
Position determinant (m²/rad²)
-2.000000
Frame-check linear error (m/s)
0.000000

Twist triples use (ω_z, vₓ, vᵧ), with rad/s followed by m/s. Both tool-velocity readouts use space axes. The frame check compares Jₛθ̇ with Ad_T(Jᵦθ̇), including the origin shift.

Space Jacobian Jₛ
RowShoulderElbow
ω_z1.0001.000
vₓ0.0002.000
vᵧ0.0000.000
Body Jacobian Jᵦ
RowShoulderElbow
ω_z1.0001.000
vₓ-2.0000.000
vᵧ1.0001.000
Tool-position Jacobian Jₚ, in space axes
RowShoulderElbow
ẋ-2.0000.000
ẏ1.0001.000

Tool velocity: (-1.000, 0.250) m/s. Angular velocity: 0.250 rad/s. The position task has rank 2. The full planar pose Jacobians also have rank 2; two joints cannot command three independent pose velocities.

Rank describes each map, independent of the selected rates. A very small nonzero elbow angle still has position rank 2, although its inverse velocity problem can be poorly conditioned. Calculations keep more precision than the displayed numbers.

The amber arrow shows the physical tool velocity at the tip. The blue dashed arrow shows v_s at the space origin. Both use a half-second display scale to fit velocity arrows on meter axes; their endpoints are not predictions of a finite trajectory.

The Position-null motion preset keeps the tip instantaneously still while changing its orientation. Read the position rank and full-pose rank separately before interpreting that motion.

State the task before naming a singularity

The full planar pose includes orientation and two position coordinates. This arm has only two joints, so its 3 × 2 pose Jacobians can span at most two independent twist directions. They cannot command three arbitrary pose-velocity components at once.

For this arm, J_s and J_b retain rank 2 at every configuration. In J_s, the two angular entries equal one, while the difference between the columns has a linear part of length L₁ = 2. No nonzero combination of the two columns can cancel the complete twist.

The position-only matrix has a different rank condition:

det J_p = L₁L₂ sin θ₂ = 2 sin θ₂

It has rank 2 when sin θ₂ ≠ 0, and rank 1 at the straight or folded configurations. Modern Robotics defines a singularity through a drop from a Jacobian's attainable maximum rank. Here, the position map loses a direction even though the full-pose map keeps its two independent columns.

At the straight pose θ = (0, 0), J_p = [0, 0; 3, 1]. Rates (0.25, −0.75) give ṗ = 0 but angular velocity 0.25 − 0.75 = −0.5 rad/s. These rates belong to the position task's null space, not the full-pose null space.

Near a collinear configuration, the position columns become nearly dependent. Producing some tip velocities can then require large joint rates. A small nonzero elbow angle still gives exact rank 2; rounding a displayed determinant to zero does not turn it into an exact singularity.

The kinematic singularities lesson tests requested tip velocities at these poses. Compare the reachable part of each request with its residual, then see how a nearby pose changes the required joint rates.

Connect velocity maps to control and statics

A velocity controller must specify the output it wants: a complete twist, a position velocity, or another task derivative. It must also specify the frame. Solving for joint rates cannot repair a mismatch between a spatial linear coordinate and a measured tip velocity.

The same checks apply to learned models. If a model predicts joint rates, its predicted tool motion follows through the chosen Jacobian at the current pose. Comparing that prediction with a target requires matching the task, frame, and units; adding more output coordinates does not add physical degrees of freedom.

Force calculations use the dual map. A consistent tool wrench F and twist V pair through power, so the corresponding joint-load coordinates involve τ = JᵀF. Use J_s with a space wrench or J_b with a body wrench, each with the correct moment reference origin. The robot statics lesson derives the load and holding-torque signs with this same arm.

These calculations describe instantaneous kinematics. A constant joint-rate step changes the arm configuration and its Jacobian over time. Joint limits, torque limits, and collision constraints require additional models.

Check the matrices and a numerical derivative in Python

This standard-library example calculates both twist representations and the tool velocity. It then compares the analytic velocity with a central difference over a finite time interval. The difference is an approximation with a visible error.

from math import cos, hypot, pi, sin


def position(q):
    a, b = q
    return 2*cos(a)+cos(a+b), 2*sin(a)+sin(a+b)


def jacobians(q):
    a, b = q
    js = ((1, 1), (0, 2*sin(a)), (0, -2*cos(a)))
    jb = ((1, 1), (2*sin(b), 0), (2*cos(b)+1, 1))
    return js, jb


def apply(matrix, rates):
    return tuple(row[0]*rates[0]+row[1]*rates[1]
                 for row in matrix)


def show(values):
    parts = [f"{value:.6f}" for value in values]
    return "(" + ", ".join("0.000000" if float(part) == 0
                            else part for part in parts) + ")"


q, rates = (pi/2, -pi/2), (0.5, -0.25)
js, jb = jacobians(q)
vs, vb = apply(js, rates), apply(jb, rates)
p = position(q)
tip = (vs[1]-vs[0]*p[1], vs[2]+vs[0]*p[0])
phi = sum(q)
from_body = (cos(phi)*vb[1]-sin(phi)*vb[2],
             sin(phi)*vb[1]+cos(phi)*vb[2])
assert hypot(tip[0]-from_body[0], tip[1]-from_body[1]) < 1e-12

h = 0.1  # seconds on each side of the current time
before = position(tuple(a-h*r for a, r in zip(q, rates)))
after = position(tuple(a+h*r for a, r in zip(q, rates)))
difference = tuple((b-a)/(2*h) for a, b in zip(before, after))
error = hypot(difference[0]-tip[0], difference[1]-tip[1])
print("Space twist:", show(vs))
print("Body twist:", show(vb))
print("Tool velocity:", show(tip))
print("Velocity from body:", show(from_body))
print("Central difference:", show(difference))
print(f"Difference error: {error:.9f} m/s")

Expected output:

Space twist: (0.250000, -0.500000, 0.000000)
Body twist: (0.250000, -1.000000, 0.250000)
Tool velocity: (-1.000000, 0.250000)
Velocity from body: (-1.000000, 0.250000)
Central difference: (-0.999583, 0.249974)
Difference error: 0.000417428 m/s

For this smooth trajectory, the central-difference truncation error decreases quadratically with h near zero. Extremely small h can expose floating-point cancellation. Neither a finite difference nor the displayed decimal precision replaces the analytic derivative.

Try it yourself

Exercise 1. Keep the worked configuration θ = (90°, −90°), but set the rates to (0, 0.5) rad/s. Calculate V_s, V_b, and the physical tip velocity. Why is the spatial linear pair different from the tip velocity?

Show solution: use the elbow column

Half of the second space column gives V_s = (0.5, 1, 0). Half of the second body column gives V_b = (0.5, 0, 0.5). Since the body axes align with space at this pose, the physical tip velocity is (0, 0.5) m/s.

From the spatial twist, ω_s × p = (−1, 0.5) m/s. Adding v_s = (1, 0) gives (0, 0.5). The spatial linear pair describes the motion field at the space origin, while the tip sits at (1, 2).

Exercise 2. At the straight pose θ = (0, 0), verify that rates (0.25, −0.75) leave the tip position instantaneously unchanged. Find the angular velocity and explain whether those fixed rates keep the tip at (3, 0) for a whole second.

Show solution: distinguish the position task from the full pose

The position Jacobian gives ṗ = (0, 3 × 0.25 − 0.75) = (0, 0). The angular velocity is −0.5 rad/s, so the full twist is nonzero. This matches position rank 1 and full-pose rank 2.

Holding those rates gives θ₁(t) = 0.25t and tool heading φ(t) = −0.5t. The exact position is (2 cos(0.25t) + cos(0.5t), 2 sin(0.25t) − sin(0.5t)). At one second it is approximately (2.815407, 0.015382) m. A zero instantaneous position derivative did not guarantee a fixed position over a finite interval.

Sources and further study