Where you are. You can build the Jacobian and read its columns as “what each joint buys the hand right now”. This lesson is about the poses where two columns quietly become one, and a whole direction of motion goes missing.
The last two degrees
Stand up and hold a pen out in front of you at arm’s length, elbow almost locked. A couple of degrees of bend left in it, no more.
Sweep the pen sideways, twenty centimetres each way, at a comfortable pace. Easy. Your shoulder does the work and the pen goes exactly where you send it.
Now try the same twenty centimetres straight away from you and back, at the same pace. Two things go wrong at once. You have almost no room left; and the room you do have is strangely expensive. Those last couple of degrees of straightening buy you almost no reach at all, so to move outward at any speed your elbow has to move far faster than your shoulder ever did on the sideways sweep. Then you hit straight, and outward stops existing.
Nothing about your arm changed between the two attempts. Same joints, same muscles, same request for a steady comfortable pace. Sideways was free the whole time. Outward had a price that climbed as you approached straight, and at straight it went to infinity, because at straight there is no more outward.
A robot arm has the same problem in the same place. What it does not have is your instinct to stop asking.
The idea in one paragraph
At most poses the Jacobian’s two columns point in genuinely different directions, so between them the joints can push the hand any way you like. At some poses they line up. When they do, every combination of joint speeds sends the hand along one single line, and a whole direction of motion has dropped out of the arm’s vocabulary. That pose is a singularity, and for the two-link arm one number detects it: , which hits zero exactly when the elbow is straight () or folded back on itself (). At the singularity the missing direction is simply gone, and there is nothing to argue about. The neighbourhood is where the damage happens, because there the direction is technically still available, at an exchange rate that climbs without limit, and a solver that keeps asking for it will keep being told yes.
The columns close like scissors
Put the arm at so it stretches out along the x axis, and start straightening the elbow.
From the previous lesson, both columns are perpendicular to something specific: column one to the base-to-hand line, column two to link two. As the elbow straightens, those two segments swing into line with each other. Two segments in line have parallel perpendiculars. So the columns line up too, and they do it at exactly the rate the elbow closes.
Wider than the screen; scroll it sideways.
The shaded area in that figure is not decoration. The determinant of a 2 by 2 matrix is the area of the parallelogram its columns span, so is a direct measure of how much hand motion two units of joint motion can buy between them. Wide parallelogram, capable arm. Sliver, arm in trouble. Zero, arm has lost a direction.
One number, and it only watches one joint
Work the determinant out of the formula from the previous lesson and almost everything cancels:
Checked against numpy.linalg.det over 10,000 random configurations, the largest disagreement was 4.2e-16, which is floating point noise.
Read the formula and two things jump out. It is zero exactly when is zero, so at and and nowhere else. And does not appear at all: sweeping the shoulder through its whole range at a fixed elbow angle changes by less than 1e-15, which is to say not at all. The shoulder only spins the picture. Every singularity of this arm is decided by the elbow alone.
Which direction goes missing
Straighten the elbow completely, , and print the matrix:
Every entry in the top row is zero, so every hand velocity this arm can produce has zero x component. With the arm laid out along x, that means the hand can still be swung sideways by either joint, at different rates, but nothing either joint can do moves the hand along the arm’s own axis. Two joints, one usable direction of motion. The singular values are 1.8385 and exactly 0, and the rank is 1.
Wider than the screen; scroll it sideways.
That is what “loses a direction” means literally. It is not that the direction becomes hard. It is that the set of achievable hand velocities, which is normally the whole plane, has collapsed to a line.
The neighbourhood is the dangerous part
At the singularity you get a clean refusal. Just before it, you get something worse: a yes, with a bill attached.
Walk the elbow in toward straight and ask, at each pose, for two things. Move the hand outward along the arm at 0.1 m/s, and move it sideways across the arm at 0.1 m/s. Both are perfectly ordinary requests. Here is what each costs in joint speed:
| hand is this far inside the rim | columns apart | outward at 0.1 m/s | sideways at 0.1 m/s | ||
|---|---|---|---|---|---|
| 90° | 479 mm | 55.0° | 0.700 | 0.14 rad/s | 0.100 rad/s |
| 30° | 56.1 mm | 17.7° | 0.350 | 0.46 rad/s | 0.100 rad/s |
| 10° | 6.27 mm | 5.9° | 0.122 | 1.39 rad/s | 0.100 rad/s |
| 5° | 1.57 mm | 2.9° | 0.061 | 2.78 rad/s | 0.100 rad/s |
| 2° | 0.25 mm | 1.2° | 0.024 | 6.96 rad/s | 0.100 rad/s |
| 1° | 0.063 mm | 0.6° | 0.012 | 13.91 rad/s | 0.100 rad/s |
| 0.1° | 0.001 mm | 0.06° | 0.0012 | 139.15 rad/s | 0.100 rad/s |
Two readings, and the second is the one people miss.
The outward column doubles every time halves, and keeps on doubling. That is the exchange rate collapsing, and the mechanism is visible in the arithmetic: solving divides by , so as the determinant shrinks the answer grows, without any ceiling to stop at. Coming at the same fact from the other side, at one degree of elbow buys 9.97 mm of extra reach; at a whole degree of elbow buys 0.063 mm.
The sideways column does not move. Not approximately - 0.100 rad/s in every single row, to three decimals. The largest singular value barely shifts either, from 1.30 to 1.84 across the whole approach. The arm is not getting worse. It is getting worse at exactly one thing, and it stays completely healthy at everything else right up to the moment the one thing disappears.
Both rims, same story
The other zero of is : the elbow folded right back, link two lying along link one, hand pulled in to from the base. Print the matrix there, again with , and it is - rank 1 again, singular values 0.7616 and 0, determinant 8.6e-17. The lost direction is once again along the arm.
Those two elbow angles are exactly the two rims of the reachable ring from the workspace lesson. That is not a coincidence, and it generalises in one direction only: the boundary of a workspace is always singular, because being on a boundary means there is a direction you cannot go. The converse is false. A six-axis industrial arm has singularities sitting in the open middle of its workspace - the notorious one is the wrist singularity, where two wrist axes line up and the arm loses a rotational direction while standing somewhere entirely reachable.
Why inverse kinematics blows up nearby
Everything so far has been forward: joints in, hand out. Inverse kinematics needs the other direction, which means solving for . For a 2 by 2 the inverse carries out front, so as the determinant heads for zero the entries of the inverse head for infinity. The table above is that fraction, in engineering units.
At exactly , numpy.linalg.solve raises LinAlgError: Singular matrix. That is the friendly failure: loud, immediate, and at the one pose you will almost never land on exactly.
What the damping term buys
The standard fix is one line. Instead of inverting , solve a slightly softened system:
In plain words: add a small constant to the quantity you are about to divide by, so a nearly-zero direction produces a bounded step instead of an unbounded one. With this is the raw pseudo-inverse. With around 0.01 the solver gives up a little accuracy in the strong directions in exchange for never demanding an impossible one.
Here is what that costs and what it saves. Same solver, same start at , step scale 0.5, 100 iterations, aimed at a target 50 mm past the outer rim - a target no arm with these links can reach:
| largest single step | 22.42 rad | 2.50 rad |
| where the joints ended | , | , |
| where the hand ended | , behind the base | , stretched at the rim |
| distance to the target | 2.449 m | 0.065 m |
Wider than the screen; scroll it sideways.
The undamped run did not merely move violently. It finished pointing away from the target, on the far side of the base, 2.449 m from a goal that was 50 mm out of reach when it started. The damped run stretched toward the target and stopped, 0.065 m short of something nothing could get closer than 0.050 to. One solver degraded; the other detonated.
What you actually do about it
Four moves, roughly in order of how much they cost you.
Keep the task off the rim. Free, and it solves most of the problem. Plan the working area a comfortable margin inside the boundary, and do not design a task whose motion runs radially out to the edge.
Damp. One line, as above. The largest step the solver can ever ask for becomes times the error, so pick from the joint step you are prepared to command rather than by feel. The next lesson builds the whole solver around it.
Watch a number at runtime. works for square Jacobians; the smallest singular value works generally; the condition number, the ratio of largest to smallest, is the most readable of the three because it is dimensionless. In the table above it runs 2.4 at , 27.6 at 10°, 277 at 1°, and 2767 at a tenth of a degree. A threshold on that ratio is a usable guard: refuse the command, or slow the commanded motion, before the motors do the refusing for you.
Add a joint. A seven-axis arm reaching in three dimensions has one more joint than the task needs, which leaves a whole family of joint motions that move the hand nowhere at all. That family is room to reconfigure the elbow away from a bad pose without disturbing the hand, and it is the reason research arms have seven joints rather than six.
Review
A direction drops out of the arm’s vocabulary
At most poses the Jacobian’s two columns point in genuinely different directions, so between them the joints can push the hand any way you like. At some poses they line up, and then every combination of joint speeds sends the hand along one single line: a whole direction of motion has dropped out of the arm’s vocabulary. That pose is a singularity. For the two-link arm one number detects it, the determinant of the Jacobian, which is the product of the link lengths and the sine of the elbow angle, and it hits zero exactly when the elbow is straight or folded back on itself. The determinant of a two by two matrix is the area of the parallelogram its columns span, so it measures directly how much hand motion two units of joint motion can buy. Wide parallelogram, capable arm. Sliver, arm in trouble.
The neighbourhood is where the damage happens
At the singularity you get a clean refusal. Just before it you get something worse: a yes, with a bill attached. Walk the elbow in toward straight and ask for a tenth of a metre per second outward along the arm. At ninety degrees of elbow that costs fourteen hundredths of a radian per second. At five degrees it costs two point seven eight. At a tenth of a degree it costs one hundred and thirty-nine. The cost doubles every time the elbow angle halves, and keeps doubling, because solving for joint speed divides by the determinant. Now the reading people miss: sideways motion costs exactly one tenth of a radian per second in every single row. The arm is not getting worse. It is getting worse at exactly one thing, and it stays completely healthy at everything else right up to the moment that one thing disappears.
It is invisible from outside, and there are four answers
None of this is visible from outside. Five degrees from straight, the hand sits one and a half millimetres short of the rim and the arm simply looks straight; it tracks sideways motion perfectly while tracking outward motion at nearly twenty times the joint speed the same request cost with the elbow bent. Put a real limit on the motors and the impossibility does not arrive as an exception. It arrives as saturated motors, a growing tracking error, and a log full of nothing. Four answers, in order of what they cost. Keep the task off the rim, which is free and solves most of it. Damp, choosing the damping factor from the largest joint step you are prepared to command. Watch a number at runtime; the condition number is the most readable because it is dimensionless, running from about two at a bent elbow to nearly three thousand near straight. Or add a joint, which is why research arms have seven.
Check yourself
1. Why is being near a singularity operationally worse than being exactly at one?
At the singularity the direction is gone and everything says so: the determinant is zero, the rank drops, numpy.linalg.solve throws. A solver has to handle it. Near the singularity the direction is still technically available, so nothing complains - the arithmetic simply returns an enormous joint velocity and the code passes it along. That is the regime in which real hardware gets whipped, and it is why damping exists for the neighbourhood rather than for the point.
2. does not contain . What does that tell you about where this arm’s singularities live?
That they depend only on the elbow. Sweeping the shoulder through its full range at a fixed elbow angle leaves the determinant unchanged to 1.7e-16, so only rotates the whole picture about the base. The singular configurations are and , and in workspace terms those are two circles: the outer rim at and the inner rim at . Everything between them is non-singular, and the shoulder angle never has an opinion on it.
3. At θ2 = 5° the arm tracks sideways motion perfectly and outward motion twenty times more expensively than before. Why does only one direction degrade?
Because only one direction is losing its supply. The set of hand velocities the joints can produce is an ellipse, and approaching the singularity squashes it along one axis while leaving the other alone: the smallest singular value falls from 0.538 to 0.033 while the largest moves only from 1.30 to 1.84. The squashed axis is the arm’s own axis. So the sideways request keeps costing 0.100 rad/s at every pose in the table, and the outward request goes from 0.14 to 2.78 rad/s over the same span.
4. An IK solver returns a joint configuration with no error, but the hand does not move outward when you command it to. Where would you look?
At , or better the condition number, at the pose you are in. A pseudo-inverse asked for a lost direction returns the minimum-norm best effort, which at a singularity is zero motion, and it reports success while doing it. So “no error and no motion” is the exact signature of a collapsed axis. Confirm by asking for the perpendicular direction: if that works and the radial one does not, you are on a rim. The fix is not in the solver, it is in the plan that put the hand there.
5. What does the λ² term actually change, and what does it cost?
It changes the amplification applied to each direction. Undamped, a direction whose singular value is gets amplified by , which runs away as falls. Damped, it gets , which rises, peaks at when equals , and then falls back toward zero. Measured at : a strong direction with is amplified 0.544 either way, indistinguishable. A weak one with would be amplified 1505 times undamped, and is amplified 6.6 times damped.
So the cost is not spread across the arm; it lands entirely on the directions that were about to hurt you, and it is paid as motion you do not get. is chosen from the largest joint step you are willing to command, because is exactly that cap.
6. Your task needs the hand to travel radially outward to within 1 mm of the workspace rim. Argue against the task, with numbers.
The last millimetre of reach lives inside about , where the exchange rate is roughly 3.5 rad/s of joint speed per 0.1 m/s of outward hand motion, climbing to 13.9 rad/s at and without limit after that. With joints capped at one revolution per second the outer 0.31 mm becomes unreachable at that speed regardless of the controller. And an arm that reaches its target only when fully straight has no margin left: any calibration error, any link flex, any thermal drift pushes the target outside the workspace entirely, at which point the solver stalls on the boundary with residual error. Longer links, or a repositioned base, cost far less than fighting this.
Do this
Open code/ik_2link.py with jacobian_analytic already filled in from the previous lesson.
1. Walk the determinant to zero. Print at and confirm it matches each time. Then print it again at four different values of for each of those elbow angles, and watch it not move.
2. Price the two directions. At each of those poses solve twice, once for and once for , with so the arm lies along x. Print the largest joint speed each requires. You are reproducing the table above; the point is to feel that one column runs away while the other never budges. At exactly, np.linalg.solve will throw - catch it and print what np.linalg.pinv returns instead.
3. Measure the amplification directly. Take the Jacobian at , run its SVD, and feed each left-singular direction through the damped step at . Compare the length of what comes back against and against . The strong direction should come back at 0.544 both ways; the weak one at 6.6 damped against 1505 undamped. Seeing those four numbers next to each other is the fastest way to internalise what damping actually touches.
Then note what you have not done: nothing here made an unreachable target reachable, and nothing warned you when one arrived. That job belongs to a reachability check, and building the solver that needs it is the next lesson.
Solution: solutions/ik_2link.py.
What you can now do
You can compute for a 2-link arm, say which physical direction of motion disappears when it hits zero and why, and locate both singular configurations from the elbow angle alone. You can describe the neighbourhood around a singularity in the terms that matter - one direction degrading without limit while everything else stays healthy - and put numbers on it. You can explain what a damping term changes in a least-squares IK step, what it costs, and what it does not fix.