PID Autotuning
The PID controller is a classical control method that is widely used due to its simplicity and ability to control many practically occurring systems. The parameters of a PID controller can be tuned in multiple different ways:
- Trial and error, in simulation or on the real system
- Loop shaping
- Automatic tuning
This page details the automatic tuning features offered by JuliaSimControl. Automatic tuning offers the possibility of achieving an optimal response, subject to constraints on closed-loop robustness with respect to uncertainty and noise amplification. While this page refers to the automatic tuning of PID controllers in isolation, we refer the reader to Automatic tuning of structured controllers for tuning of more general structured controllers.
The PID autotuning in JuliaSimControl is based on disturbance step-response optimization, subject to robustness constraints on closed-loop sensitivity functions. We currently implement two methods, one that optimizes a PID controller on the form
\[K(s) = (k_p + k_i/s + k_d s)\]
by solving
\[\operatorname{minimize}_K \int e(t) dt\]
\[\text{subject to} \\ ||S(s)||_\infty \leq M_S \\ ||T(s)||_\infty \leq M_T \\ ||KS(s)||_\infty \leq M_{KS}\]
where $e(t) = r(t) - y(t)$ is the control error.
The second method performs joint optimization of a PID controller and a measurement filter on the form
\[K(s) = C(s) F(s) = (k_p + k_i/s + k_d s) \dfrac{1}{(sT)^2 + 2ζTs + 1}, ζ = 1/√2\]
by solving
\[\operatorname{minimize}_{C, F} \int |e(t)| dt\]
\[\text{subject to} \\ ||S(s)||_\infty \leq M_S \\ ||T(s)||_\infty \leq M_T\\ ||KS(s)||_\infty \leq M_{KS}\]
The autotuning functions operate on SISOLTISystem
s from ControlSystems.jl. If you have a ModelingToolkit model, you may obtain a linear system model using linearization. The general workflow for autotuning is
- Define a plant model, $P$
- Define desired constraints on the maximum magnitudes $M_S, M_T, M_{KS}$ of the sensitivity functions $S = \dfrac{1}{1+ PK}$, $T = \dfrac{PK}{1+ PK}$ and $KS = \dfrac{K}{1+ PK}$.
- Choose problem and solver parameters and create an
AutoTuningProblem
. - Call
solve
. - Plot the result.
If you want to use the optimized controller in a ModelingToolkit simulation, see OptimizedPID
.
Examples of this are shown below.
Functions:
solve
: solve an autotuning problem.AutoTuningProblem
: define an autotuning problem.OptimizedPID
: obtain anODESystem
representing the tuned PID controller.
Getting started
JuliaSimControl contains a Pluto-based graphical app (GUI) for PID-controller tuning using the two methods below, usage of this app is documented under PID autotuning GUI. This example demonstrates the non-graphical interface.
Integrated absolute error (IAE)
The following example optimizes a PID controller with a low-pass filter using the method from
K. Soltesz, C. Grimholt, S. Skogestad. Simultaneous design of proportional–integral–derivative controller and measurement filter by optimisation. Control Theory and Applications. 11(3), pp. 341-348. IET. 2017.
using JuliaSimControl, Plots
# Process model (continuous time LTI SISO system).
T = 4 # Time constant
L = 1 # Delay
K = 1 # Gain
P = tf(K, [T, 1.0])*delay(L) # process dynamics
Ts = 0.1 # Discretization time
Tf = 25 # Simulation time
# Robustness constraints
Ms = 1.2 # Maximum allowed sensitivity function magnitude
Mt = Ms # Maximum allowed complementary sensitivity function magnitude
Mks = 10.0 # Maximum allowed magnitude of transfer function from process output to control signal, sometimes referred to as noise sensitivity.
w = 2π .* exp10.(LinRange(-2, 2, 200)) # frequency grid
prob = AutoTuningProblem(; P, Ms, Mt, Mks, w, Ts, Tf, metric = :IAE)
# p0 = Float64[1, 1, 0, 0.001] # Initial parameter guess can be optionally supplied, kp, ki, kd, T_filter
res = solve(prob)
plot(res)
The figure shows the Nyquist curve of the loop-transfer function $P(s)K(s)$ using the optimized controller, as well as circles corresponding to the chosen constraints. The top figures show Bode plots of the closed-loop sensitivity functions together with the constrains, and the lower left figure shows the response to a unit load-disturbance step as well as a reference-step response. Note, the response to a reference step is not part of the optimization criterion, and optimized suppression of load disturbances often leads to a suboptimal response to reference steps. If steps are expected in the reference signal, reference shaping using a pre-filter is recommended (called a 2-DOF design, realized, for example, by the introduction of $W_r$ in the diagram of the following design example).
Integrated error (IE)
The following example optimizes a PID controller using the method from
M. Hast, K. J. Astrom, B. Bernhardsson, S. Boyd. PID design by convex-concave optimization. European Control Conference. IEEE. Zurich, Switzerland. 2013.
This method optimizes integrated error (not integrated absolute error). This problem is relatively easy to solve and corresponds well to IAE if the system is well damped. If convergence of the above method (IAE) appears difficult, this method can be used as initialization by choosing metric = :IEIAE
.
using JuliaSimControl, Plots
T = 4 # Time constant
K = 1 # Gain
P = tf(K, [T, 1.0]) # process dynamics
## Robustness constraints
Ms = 1.2 # Maximum allowed sensitivity function magnitude
Mt = Ms # Maximum allowed complementary sensitivity function magnitude
Mks = 10.0 # Maximum allowed magnitude of transfer function from process output to control signal, sometimes referred to as noise sensitivity.
w = 2π .* exp10.(LinRange(-2, 2, 50)) # frequency vector
p0 = Float64[1, 1, 0.1] # Initial guess. Use only two parameters to tune a PI instead of PID controller
prob = AutoTuningProblem(; P, Ms, Mt, Mks, w, Ts=0.1, Tf=25.0, metric = :IE) # Set the metric here
res = solve(prob, p0)
plot(res)
Choosing metric
The metric = :IE
problem optimizes integrated error $\int e(t) dt$ (not integrated absolute error). This problem is relatively easy and fast to solve and corresponds well to IAE if the system is well damped. If this metric is chosen, a PI or PID controller is tuned, determined by the number of parameters in the initial guess. The method requires a stabilizing controller as an initial guess. If the plant is stable, the zero controller is okay. If the initial guess is not stabilizing, an attempt at automatically finding a feasible initial guess is made.
If the response is oscillatory, the metric = :IE
metric is expected to perform poorly and metric = :IAE
is recommended. If metric = :IAE
is chosen, a PID controller with a low-pass filter is tuned by minimizing $\int |e(t)| dt$. This problem is nonconvex and can be difficult to solve. This method can be initialized with the IE
method by selecting metric = :IEIAE
.
Index
JuliaSimControl.AutoTuningProblem
JuliaSimControl.AutoTuningResult
CommonSolve.solve
JuliaSimControl.OptimizedPID
JuliaSimControl.AutoTuningProblem
— TypeAutoTuningProblem{S, W}
Optimizes a controller on the form
K(s) = C(s) * F(s) = (kp + ki/s + kd*s) * 1/((s*T)^2+2*ζ*T*s+1), ζ = 1/√2
\[K(s) = C(s) F(s) = (k_p + k_i/s + k_d s) \dfrac{1}{(sT)^2 + 2ζTs + 1}, ζ = 1/√2\]
Can be plotted after optimization by using Plots; plot(prob, C)
where C
is obtained from the optimization.
See also OptimizedPID
Keyword arguments:
P::LTISystem
: Plant modelw::AbstractVector
: Frequency grid vectorTs::Float64
: Discretization time (sample time, arbitrary time unit)Tf::Float64
: Simulation duration in the same time unit asTs
.Ms::Float64
: Maximum allowed sensitivityMt::Float64
: Maximum allowed complimentary sensitivityMks::Float64
: Maximum allowed noise sensitivity (controller times sensitivity)pmax::Vector{Float64}
: An optional vector of the same length as the number of estimated parameters that contains upper bounds on parameters, the default isfill(Inf, 4)
(no bounds).metric = :IAE
: The metric to optimize. Choices are:IAE, :IE, :IEIAE
.disc
: The discretization method to use when optimizinfmetric = :IAE
. Choices are:zoh, :foh, :tustin
(delay systems only support :zoh).
CommonSolve.solve
— Methodres = solve(prob::AutoTuningProblem, p0; kwargs...)
res = solve(prob::AutoTuningProblem; kwargs...)
Computes PID parameters, that minimize load step IAE, and filter for noise attenuation.
\[K(s) = C(s) F(s) = (k_p + k_i/s + k_d s) \dfrac{1}{(sT)^2 + 2 ζ Ts + 1}\]
p0
Parameter vector guess:[kp; ki; kd; T]
. Ifp0
is not provied, attempts will be made to find one automatically.
See AutoTuningProblem
for arguments. res
is of type AutoTuningResult
and can be plotted plot(res)
. It contains the optimized parameters as well as an ODESystem
representing an optimized controller.
Based on K. Soltesz, C. Grimholt, S. Skogestad. Simultaneous design of proportional–integral–derivative controller and measurement filter by optimisation. Control Theory and Applications. 11(3), pp. 341-348. IET. 2017.
Solver options for metric :IAE
include
maxeval = 500
maxtime = 20
xtol_rel = 1e-3
alg
An optimizer supported by Optimization.jl. The default is IPOPT.random_start = 0
A positive integer indicates a number of random starts to try in order to find a good soluiton. Ifrandom_start = 0
, only the provided initial guess is used.
Solver options for metric :IE
include
maxiter = 15
: Maximum number of convex-concave optimization iterations.tol = 1e-3
: Tolerance for the convex-concave procedure.solver = Hypatia.Optimizer
: Any MOI compatible solver.verbose = false
:
Extended help
The autotuner optimizes the reponse to load disturbances appearing on the process input. This typically leads to good regulation performance, but may result in a controller that produces large overshoots for step changes in the reference. If step changes in the reference are expected, we advice using one of the following strategies
- Prefilter the reference using aditional lowpass filters.
- If the system is a force/torque controlled servo system, generate a feasible reference trajectory with a continuous acceleration profile and make use of computed force/torque feedforward.
- Let the proportional and derivative terms of the PID controller act on the measurement only. This can be achieved by setting the
wp
andwd
keyword arguments toModelingToolkitStandardLibrary.Blocks.LimPID
(and similar toOptimizedPID
).
JuliaSimControl.OptimizedPID
— MethodOptimizedPID(popt; name, kwargs...)
OptimizedPID(res::AutoTuningResult; name, kwargs...)
Takes optimized parameters popt
and returns the following system
┌───┐
────►│ F ├───────┐ ┌─────┐
reference └───┘ └►│ │ ctr_output
│ PID ├─────►
┌───┐ ┌►│ │
┌─►│ F ├───────┘ └─────┘
│ └───┘
│
└───── measurement
Arguments:
popt
: Obtained by solving anAutoTuningProblem
kwargs
: Are passed toModelingToolkitStandardLibrary.Blocks.LimPID
JuliaSimControl.AutoTuningResult
— TypeAutoTuningResult
A structure containing the results of performing PID autotuning.
This structure can be plotted plot(res; stepsize = 1)
, where stepsize
controls the size of the reference step to show (turn off by setting to 0). See also OptimizedPID
.
Fields:
prob::AutoTuningProblem
p::Vector
: The optimal parameter vector.K::ControlSystemsBase.StateSpace
: The optimal controller.