Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Velocity and the Jacobian of a robot arm

After this lesson: I can say how fast the hand moves when the joints turn, using a Jacobian estimated from a small step.

70 min lesson2 commandsJupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

The Jacobian turns joint speeds into hand speed

The Jacobian is a small table of numbers that says how fast a robot hand moves when each joint turns at a given speed. A controller needs it to move the hand smoothly. For that it must know how every joint affects the hand.

In this lesson you estimate the Jacobian of the simulated two-joint arm by a small nudge, and use it to find the hand speed.

By the end of this lesson

Note

I can say how fast the hand moves when the joints turn, using a Jacobian estimated from a small step.

Key words

WordWhat it means
Jacobiana table that links joint speeds to hand speed
Numerical estimatean answer found by a small step instead of a formula
Step sizehow small the nudge to a joint is
Singularityan arm pose where the hand cannot move in some direction
Determinantone number that is zero when a table cannot be reversed

The cells students fill in are left blank in this preview.

Hand speed depends on the pose

Turn joint 1 at 10 degrees a second. How fast does the hand move? It depends on where the arm is. A stretched arm swings its hand fast, and a folded arm swings it slowly.

So there is no single number. For every pose there is a small table, the Jacobian, that turns joint speeds into hand speed.

Nudge one joint and watch the hand

You do not need a formula. Turn joint 1 a tiny bit forward, then a tiny bit back, and compare the two hand positions with forward kinematics.

The difference divided by the size of the whole change is how far the hand moves per degree of joint 1. This is a numerical estimate: a step instead of algebra.

Worked example: a 0.01 degree nudge

Joint 1Hand xHand y
29.992.598693.49955
30.012.597473.50045
Difference-0.001220.00091
Divided by 0.02-0.06110.0453

The cells students fill in are left blank in this preview.

Estimate one column of the Jacobian with NumPy

Command
docker exec jupyter python3 -c "import numpy as np; f = lambda a, b: np.array([3 * np.cos(np.radians(a)) + 2 * np.cos(np.radians(a + b)), 3 * np.sin(np.radians(a)) + 2 * np.sin(np.radians(a + b))]); print(np.round((f(30.01, 60) - f(29.99, 60)) / 0.02, 4))"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Each joint gives one column of the table

The Run above prints two numbers, -0.0611 and 0.0453. They say that one degree of joint 1 moves the hand 0.0611 to the left and 0.0453 up.

Do the same for joint 2 and you have a second column. Together the two columns make a table with two rows, across and up, and two columns, joint 1 and joint 2.

Estimate a column in plain Python

Code: python
import math

def hand(a1, a2):
    t1 = math.radians(a1)
    t2 = math.radians(a1 + a2)
    return [3 * math.cos(t1) + 2 * math.cos(t2), 3 * math.sin(t1) + 2 * math.sin(t2)]

step = 0.01
before = hand(30 - step, 60)
after = hand(30 + step, 60)
dx = (after[0] - before[0]) / (2 * step)
dy = (after[1] - before[1]) / (2 * step)
print("hand moves per degree of joint 1:", round(dx, 4), round(dy, 4))
# Change step to 1 and press Run.
# The answer shifts a little. A bigger step is a rougher estimate.

A common mistake

Warning

Many people think a smaller step is always better. A step that is too large is a rough guess, but one that is far too small lets rounding errors drown the answer. A step of 0.01 degrees, taken on both sides, is a good choice for this arm.

Multiply the table by the joint speeds

With the Jacobian for the pose, the hand speed across is the first row times the joint speeds, added up. The hand speed up is the second row times the same speeds.

Take joint speeds of 10 and 20 degrees a second. The hand speed is then -1.309 across and 0.453 up, in length units a second.

Find hand speed from joint speeds

Command
docker exec jupyter python3 -c "import numpy as np; f = lambda a, b: np.array([3 * np.cos(np.radians(a)) + 2 * np.cos(np.radians(a + b)), 3 * np.sin(np.radians(a)) + 2 * np.sin(np.radians(a + b))]); j = np.array([(f(30.01, 60) - f(29.99, 60)) / 0.02, (f(30, 60.01) - f(30, 59.99)) / 0.02]).T; print(np.round(j @ np.array([10, 20]), 3))"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Hand speed from a table and joint speeds

Code: python
jacobian = [[-0.0611, -0.0349], [0.0453, 0.0]]
speeds = [10, 20]

vx = jacobian[0][0] * speeds[0] + jacobian[0][1] * speeds[1]
vy = jacobian[1][0] * speeds[0] + jacobian[1][1] * speeds[1]
print("hand speed across:", round(vx, 3))
print("hand speed up:", round(vy, 3))
# Set both joint speeds to 0. What is the hand speed?

A stretched arm cannot move along itself

When the arm is fully straight, turning either joint moves the hand sideways only. No joint speed can move the hand along the arm. This is a singularity.

The determinant of the table, the top left times the bottom right minus the top right times the bottom left, is then 0. A controller watches it and slows down as it nears 0.

Going further

In start.ipynb, estimate the Jacobian at a1 = 0 and a2 = 0, then at a1 = 0 and a2 = 90. Print the determinant of each.

Which pose is a singularity, and what does the first row of its table show?

About this lab and its source: JupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.