What is PID control?
Proportional-integral-derivative (PID) controllers have been used in manufacturing industry since the 1940s. PID control is similar to proportional control, but with the addition of integral and derivative components. The integral feature eliminates the offset while the derivative element provides a fast response.
Let’s start with a bit of theory. The following equation is used by PID controller to compute the output value u(t):
Kp, Ki and Kd denote the coefficients for the proportional, integral, and derivative gains respectively; e denotes error and t – time.
In this tutorial you will learn how to use Python programming language to implement PID controller.
PID controller – Example of application
Let’s consider a tank used to continuously heat up the liquid stream flowing through this tank with heating jacket shown in the figure. We can use the PID controller to obtain temperature set. We will use a simple mathematical model of this system (check more detailed description in this lecture).
Python code of a system with PID control
Let’s start writing the program with importing necessary python libraries.
import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeint import numpy as np import matplotlib.pyplot as plt
We will need several global variables as the calculations require the history of the object.
time = 0 integral = 0 time_prev = -1e-6 e_prev = 0
The function below calculates the value of the manipulated variable (MV) based on the measured value (in example it is the temperature of the liquid) and setpoint value (temperature we want to obtain). The function also accepts parameters of the controller.
def PID(Kp, Ki, Kd, setpoint, measurement): global time, integral, time_prev, e_prev # Value of offset - when the error is equal zero offset = 320 # PID calculations e = setpoint - measurement P = Kp*e integral = integral + Ki*e*(time - time_prev) D = Kd*(e - e_prev)/(time - time_prev) # calculate manipulated variable - MV MV = offset + P + integral + D # update stored data for next iteration e_prev = e time_prev = time return MV
Next, we create a function defining the system.
def system(t, temp, Tq): epsilon = 1 tau = 4 Tf = 300 Q = 2 dTdt = 1/(tau*(1+epsilon)) * (Tf-temp) + Q/(1+epsilon)*(Tq-temp) return dTdt
Let’s see the results for the system without the automatic control. We obtain them by solving the differential equations shown before.
tspan = np.linspace(0,10,50) Tq = 320, sol = odeint(system,300, tspan, args=Tq, tfirst=True) plt.xlabel('Time') plt.ylabel('Temperature') plt.plot(tspan,sol)
We see that the temperature in the tank is equal 300 K at the initial time and it rises to about 317.5 steadily. Now, we will make a simulation of the tank with automatic control. Let’s say that we want to reach the temperature of 310 K. This is our setpoint. The controller constants are set arbitrarily – they can be adjusted to get a better control. However, it is out of the scope of this tutorial. Temperature of steam was chosen as a manipulated variable (Tq). You can see that its value is calculated in every step of simulation with the use of previously written PID function.
# number of steps n = 250 time_prev = 0 y0 = 300 deltat = 0.1 y_sol = [y0] t_sol = [time_prev] # Tq is chosen as a manipulated variable Tq = 320, q_sol = [Tq] setpoint = 310 integral = 0 for i in range(1, n): time = i * deltat tspan = np.linspace(time_prev, time, 10) Tq = PID(0.6, 0.2, 0.1, setpoint, y_sol[-1]), yi = odeint(system,y_sol[-1], tspan, args = Tq, tfirst=True) t_sol.append(time) y_sol.append(yi[-1]) q_sol.append(Tq) time_prev = time plt.plot(t_sol, y_sol) plt.xlabel('Time') plt.ylabel('Temperature')
You can see that the controller makes the temperature tend to the desired value.
Download Jupiter notebook file with PID implementation
Read related content
We are here to help. Contact us by phone, email or via our social media channels.