Kiru Lab / Embodied Control: Kinematics and the Inverse Jacobian / The Jacobian
Singularities and Conditioning
When the Jacobian loses rank, an entire direction of motion becomes unreachable and naive inversion explodes.
Concept · about 30 minutes
A singularity is a configuration where the Jacobian loses rank — a direction of desired end-effector motion that no combination of joint velocities can produce. The classic case is a fully extended arm: at full stretch, no joint motion moves the hand further outward along the arm's axis.
import numpy as np
def singularity_report(J, tol=1e-4):
U, S, Vt = np.linalg.svd(J)
manipulability = float(np.prod(S)) # volume of the achievable velocity ellipsoid
condition = float(S[0] / S[-1]) if S[-1] > 0 else np.inf
lost = [Vt[i] for i, s in enumerate(S) if s < tol]
return {"singular_values": S, "manipulability": manipulability,
"condition_number": condition, "degenerate_directions": lost}Near a singularity the smallest singular value approaches zero, so the condition number blows up. Since the inverse scales by one over the singular values, the naive inverse demands enormous joint velocities to produce a tiny end-effector motion. On a physical robot that means violent, unsafe commands. This is precisely the ill-conditioning you saw in track two — same mathematics, physical consequences.
A singularity is a fact about the arm's geometry at that pose, not about the controller. No control algorithm can produce a motion the structure forbids. The structural fix is to design the workspace and the arm so that operations stay away from these configurations — which is a design decision, made long before any code is written.
Hold on to
- A singularity is lost Jacobian rank: a direction that cannot be produced
- Manipulability and condition number quantify how close you are
- No controller can overcome a structural limitation of the geometry
Work through
Try each one before opening the solution. Getting it wrong first is most of where the learning happens.
-
Plot the smallest singular value across the workspace of a two-link arm and locate the singular set.
Hint
Sweep a grid of joint angles, compute the SVD at each, and plot the smallest singular value.
Solution
For a two-link arm the singular set is where the arm is fully extended (q2 = 0) or fully folded (q2 = pi). At those configurations the two columns of the Jacobian become parallel, rank drops to 1, and the smallest singular value hits zero — a whole direction of hand motion becomes unreachable. Note that this depends only on q2: the singularity is a property of the arm's shape, not its orientation in the world.
import numpy as np, matplotlib.pyplot as plt lengths = np.array([1.0, 1.0]) q1 = np.linspace(-np.pi, np.pi, 200) q2 = np.linspace(-np.pi, np.pi, 200) smallest = np.zeros((200, 200)) for i, a in enumerate(q1): for j, b in enumerate(q2): smallest[i, j] = np.linalg.svd(jacobian_analytic(np.array([a, b]), lengths), compute_uv=False)[-1] plt.imshow(smallest, extent=[-np.pi, np.pi, -np.pi, np.pi], origin="lower") plt.colorbar(label="smallest singular value"); plt.xlabel("q2"); plt.show() -
Command a straight-line motion through a singularity with a naive inverse and record the peak joint velocity.
Hint
Use the raw pseudoinverse with no damping and record max(abs(qdot)) at each step.
Solution
Peak joint velocity spikes by orders of magnitude as the path passes near the singular configuration — values of 1e3 to 1e6 are routine, depending on how close you pass. On real hardware that is a violent, potentially destructive command. This single measurement is why damped least squares is the production default rather than an optimization.
import numpy as np lengths = np.array([1.0, 1.0]) q = np.array([0.1, 0.2]) peak = 0.0 for target in np.linspace(1.5, 1.99, 200): # march toward full extension error = np.array([target, 0.0]) - forward_kinematics(q, lengths) J = jacobian_analytic(q, lengths) qdot = np.linalg.pinv(J) @ error # no damping peak = max(peak, float(np.abs(qdot).max())) q = q + 0.1 * qdot print("peak joint velocity:", peak)
Sign in to track your progress through the lab.