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

Free lesson

A proportional controller and overshoot

After this lesson: I can simulate a proportional controller that reaches a target and measure its overshoot.

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

A proportional controller pushes by the error

A proportional controller is a rule that sets the push on a motor in proportion to the error. The error is the gap between where a joint is and where it should be. It is the simplest way to make a joint reach a target. It also shows the trade-off between speed and overshoot that every controller has.

In this lesson you simulate one joint, watch its step response and measure how far it overshoots.

By the end of this lesson

Note

I can simulate a proportional controller that reaches a target and measure its overshoot.

Key words

WordWhat it means
Sensora device that measures something, such as a joint angle
Errorthe target minus the measured position
Gainhow strongly the controller reacts to the error
Overshoothow far the joint goes past the target
Step responsehow the position changes after the target jumps

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

A controller measures, compares and pushes

A sensor measures the joint angle. The controller subtracts it from the target to get the error, and sets the motor push in proportion: push equals gain times error.

Then the joint moves a little and the sensor measures again. This repeating loop, a few times a second or faster, is the whole of a proportional controller.

The error shrinks by a fixed fraction

Take a joint with no inertia, that moves exactly as the push says. Each second the position moves the gain times the error closer.

With a gain of 0.5 the error halves every second: 10, 5, 2.5 and so on. It gets very near the target but never overshoots.

Print the error each second with NumPy

Command
docker exec jupyter python3 -c "import numpy as np; print(np.round(10 * np.exp(-0.5 * np.arange(0, 5.0)), 2))"

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

A smooth approach has no overshoot

The Run above uses a smooth version of the same idea. The error falls as 10, 6.07, 3.68, 2.23 and 1.35.

It never changes sign, so the joint never passes the target. Real joints have mass, and that changes the picture.

Watch the error shrink

Code: python
target = 10
position = 0
gain = 0.5

for second in range(5):
    error = target - position
    print("second", second, "error", round(error, 2))
    position = position + gain * error * 1
# Change gain to 1.5 and press Run.
# The error now changes sign every second. A gain that is too high overshoots.

A common mistake

Warning

Many people think a bigger gain is always better, because the joint arrives faster. A joint with weight keeps moving after the push has gone, so a high gain makes it go past the target. Too high a gain makes it swing back and forth.

A heavy joint keeps moving, so it overshoots

A real joint has inertia, so the push changes its speed rather than its position. The simulation keeps a speed. Each step adds (gain times error minus damping times speed) times dt to the speed, then adds speed times dt to the position.

The damping, the drag that slows the joint, is what stops it overshooting.

Worked example: one joint, three steps

StepErrorSpeedPosition
Start1000
11040.4
29.67.441.144
38.85610.2382.168

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

Simulate one joint with inertia

Code: python
target = 10
kp = 4
kd = 1
dt = 0.1
position = 0
speed = 0

best = 0
for step in range(1, 61):
    error = target - position
    speed = speed + (kp * error - kd * speed) * dt
    position = position + speed * dt
    if position > best:
        best = position
    if step % 10 == 0:
        print("step", step, "position", round(position, 3))
print("highest position:", round(best, 3))
# Change kd to 5 and press Run.
# The joint now creeps up and never goes past 10.

Overshoot and settling time describe a response

Two numbers summarise a step response. The overshoot is the highest position minus the target, or 0 if it never passes. The settling step is the first step after which the position stays within a small tolerance of the target.

A good controller has a small overshoot and settles quickly. You usually trade one against the other.

Repeat the first three steps of the table

Command
docker exec jupyter python3 -c "exec('p = 0\nv = 0\nfor k in range(3):\n    v += (4 * (10 - p) - v) * 0.1\n    p += v * 0.1\nprint(round(p, 3))')"

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

Going further

In start.ipynb, run the simulation for gains of 1, 4 and 16 with damping fixed at 1. Print the overshoot of each.

Which gain gives the biggest overshoot, and which would you choose for a joint carrying a fragile load?

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.