PID Controller Introduction

© 2018 Anton Lebedevich

Anton Lebedevich

  • data science engineer
  • loves time series and anomalies
  • switched to NLP and marketing campaign optimization
  • blogs at mabrek.github.io

Motivation

It Could Happen to You

wikipedia.org/wiki/Self-oscillation

  • load balancers
  • autoscaling
  • flow control (e.g. Spark Streaming)
  • load testing

Mash Tun

Ibrew-50-Auto

Mash Tun Specs

  • 50l
  • 3000W
  • 100W step regulation
  • digital thermometer

Simplified Physical Model


temperature_derivative = (
    power
    - heat_transfer_coefficient * surface
      * (temperature - external_temperature)
) / heat_capacity
                    

wikipedia.org/wiki/Newton's_law_of_cooling

Relay Controller


if temperature[i] < setpoint[i]:
    next_power = max_power
else:
    next_power = 0
                    

Meet P from PID


error[i] = temperature[i] - setpoint[i]
next_power = - proportional * error[i]
                    

Clip Power Range


error[i] = temperature[i] - setpoint[i]
next_power = - proportional * error[i]
if next_power > max_power:
    next_power = max_power
elif next_power < 0:
    next_power = 0
                    

Add Integral Part (I from PID)


error[i] = temperature[i] - setpoint[i]
time_diff = time[i + 1] - time[i]
integral_error[i] = integral_error[i-1] + error[i] * time_diff
next_power = - proportional * error[i]
             - integral * integral_error[i]
if next_power > max_power:
    next_power = max_power
elif next_power < 0:
    next_power = 0
                    

Integral Windup Protection


error[i] = temperature[i] - setpoint[i]
time_diff = time[i + 1] - time[i]
integral_error[i] = integral_error[i-1] + error[i] * time_diff
next_power = - proportional * error[i]
             - integral * integral_error[i]
if next_power > max_power:
    next_power = max_power
    integral_error[i] = integral_error[i-1]
elif next_power < 0:
    next_power = 0
    integral_error[i] = integral_error[i-1]
                    

Derivative (D from PID)


error[i] = temperature[i] - setpoint[i]
time_diff = time[i + 1] - time[i]
integral_error[i] = integral_error[i-1] + error[i] * time_diff
derivative_error[i] = (error[i] - error[i - 1]) / time_diff
next_power = - proportional * error[i] \
             - integral * integral_error[i] \
             - derivative * derivative_error[i]
                    

Process Variable Derivative


error[i] = temperature[i] - setpoint[i]
time_diff = time[i + 1] - time[i]
integral_error[i] = integral_error[i-1] + error[i] * time_diff
derivative_error[i] = (
    temperature[i] - temperature[i - 1]
) / time_diff
next_power = - proportional * error[i] \
             - integral * integral_error[i] \
             - derivative * derivative_error[i]
                    

Complete PID


error[i] = temperature[i] - setpoint[i]
time_diff = time[i + 1] - time[i]
integral_error[i] = integral_error[i-1] + error[i] * time_diff
derivative_error[i] = (
    temperature[i] - temperature[i - 1]
) / time_diff
next_power = - proportional * error[i] \
             - integral * integral_error[i] \
             - derivative * derivative_error[i]
if next_power > max_power:
    next_power = max_power
    integral_error[i] = integral_error[i-1]
elif next_power < 0:
    next_power = 0
    integral_error[i] = integral_error[i-1]
                    

wikipedia.org/wiki/PID_controller

Books to read

Q&A

Anton Lebedevich

mabrek@gmail.com

@widdoc

mabrek.github.io/controllers-2018/

github.com/mabrek/controllers-2018/blob/master/controllers.ipynb