Tuning a PID controller

In this notebook we'll try out PID tuning according to the method presented by ABB here. You should watch this video first.

The idea of PID tuning is that you can find parameters for your controller from simple experiments on the plant. The dynamics of the plant is described by a few (typically 2 or 3) parameters only, and from these few parameters the PID parameters are determined from a look-up table. We will do it by hand, but many commercial controllers have functions that will perform tuning automatically by the press of a button.

The disadvantage of these simple PID tuning rules is that with such a simplified model of the plant dynamics, performance may not be optimal.

Blockdiagram

We consider the problem of velocity control of a car (cruise control). The plant model describes how the velocity of the car responds to the position of the accelerator (the gas pedal). In addition to the signal from the accelerator, there are also unknown and varying forces acting on the car such as wind resistance and gravity when the car is going uphill or downhill. These forces are represented by a disturbance signal entering at the input to the system.

The PID controller

The PID-controller is on the standard form \begin{equation} F(s) = K_c \left( 1 + \frac{1}{T_i s} + T_d s \right). \end{equation}


In [ ]:
# If you are missing some of the required packages, then, in Juliabox go to the Console-tab and do the following:
#  1. Start a julia session: 
#      user@juliabox:~$ julia 
#  2. Add the packages by running the package manager:
#      julia> Pkg.add("ControlSystems") 
#      julia> Pkg.add("Interact") 
#      julia> Pkg.add("Gadfly") 
#      julia> Pkg.update()

In [2]:
using Interact
using ControlSystems
using Gadfly

Step response of the plant

Below is a step-response of the plant to a unit step input in $\theta$. The actual transfer function of the car can be read from the code below, but assume for now that you know nothing more about the plant dynamics than what the step response is telling you.

In the plot you need to identify

  1. The process gain $K_p$. You get this from the steady state value of the output signal.
  2. The time constant $\tau_p$ which can be approximated by the settling time divided by four

There is some noise added to the input to the system to make the task a bit harder :-)


In [3]:
# Define the plant
G1 = tf([1.], [1, 1.]);

# Create time vector
N = 600;
t = collect(linspace(0, 10, N)); # 60 values per second 

# Create the step input signal 
θ = ones(N);

# Simulate disturbance (white noise)
d = 0.6*randn(N);

# Simulate step response
y, t_out, x = lsim(G1, θ+d, t); # Note the noise added to the input


# Simulated 
plot(x=t, y=y, Geom.line, Guide.xticks(ticks=collect(linspace(0,10,11))), Guide.xlabel("time [s]"), Guide.ylabel("Speed"))


Out[3]:
time [s] 0 1 2 3 4 5 6 7 8 9 10 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 -2.5 -2.4 -2.3 -2.2 -2.1 -2.0 -1.9 -1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 -4 -2 0 2 4 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 Speed

The PID parameters

There is a user-chosen parameter in this particular tuning rule: The so-called $\tau_{ratio}$. The purpose of this parameter is to set the "aggressiveness" of the controller, i.e. how fast the closed-loop system should be with respect to how fast the plant is. Its definition is the ratio between the time constant of the closed-loop and and the time constant of the plant. $$ \tau_{ratio} = \frac{\tau_c}{\tau_p}. $$

The suggested guide line from the video is

$\tau_{ratio}$ Closed loop response
1 Faster
2 Fast
3 Safe
4 Slow

The chosen value for the ratio does not have to be integer-valued of course.

Once a value for the $\tau_{ratio}$ has been decided, the other parameters can then be determined as $$ K_c = \frac{1}{K_p \tau_{ratio}} $$ $$ T_i = \tau_p $$ $$ T_d = 0. $$

Tune your PID controller

  1. Determine the parameters $K_p$ and $\tau_p$ from the step response of the plant.
  2. Decide a value for $\tau_{ratio}$.
  3. Determine the PID parameters from the tuning rule above.

Step response of the closed-loop system

In the below plot you can test your tuned parameters.


In [4]:
G = tf([1.], [1, 1.]);

N = 600;
t = collect(linspace(0, 10, N)); # 60 values per second 

# The reference signal
r = zeros(N);
r[round(Int,N/10):end] = 1.0;

# The disturbance signal
d = zeros(N);
d[round(Int,N/10)*5:end] = -1.0;

@manipulate for Kc in 0:0.1:10, Ti in 0:0.1:5, Td in 0:0.1:5
    F = minreal(Kc*tf([Td, 1, 1/Ti], [1.0, 0]));
    Gr = minreal(feedback(G*F));
    Gd = minreal(feedback(G*F)/F);
    yr, t_out, x = lsim(Gr, r, t);
    yd, t_out, x = lsim(Gd, d, t);
    stp = plot(x=t, y=(yr+yd), Geom.line)
end


Out[4]:
x -15 -10 -5 0 5 10 15 20 25 -10.0 -9.5 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5 15.0 15.5 16.0 16.5 17.0 17.5 18.0 18.5 19.0 19.5 20.0 -10 0 10 20 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 -1.00 -0.95 -0.90 -0.85 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 -1 0 1 2 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 y

In [ ]: