Smith predictor
This example designs a controller for a plant with a time delay using the internal-model principle, which in this case implies the use of a Smith predictor. The plant is given by:
and the control architecture looks like this
┌──────┐ ┌─────────────┐ r │ │ u │ │ ───+──+────────►│ C0 ├───────────┬─►│ P0*exp(-st) ├─┐y ▲ ▲ │ │ │ │ │ │ -│ │- └──────┘ │ └─────────────┘ │ │ │ │ │ │ │ ┌──────────┐ ┌──────┐ │ │ │ │ │ │ │ │ │ │ │ └─┤1-exp(-st)│◄───┤ P0 │◄──┘ │ │ │ │ │ │ │ │ └──────────┘ └──────┘ │ │ │ └──────────────────────────────────────────────────┘
The benefit of this approach is that the controller can be designed for the nominal plant without time delay, and still behave well in the presence of the delay. We also see why we refer to such a controller as using an "internal model", due to the presence of a model of in the inner feedback path.
We now set up the nominal system and PI controller
using ControlSystemsBase, Plots
P0 = ss(-1, 1, 1, 0) # Nominal system
StateSpace{Continuous, Int64}
A =
-1
B =
1
C =
1
D =
0
Continuous-time state-space model
We design a PI controller for nominal system using placePI
. To verify the pole placement, use, e.g., dampreport(feedback(P0, C0))
ω0 = 2
ζ = 0.7
C0, _ = placePI(P0, ω0, ζ)
(TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}
1.7999999999999998s + 4.0
-------------------------
1.0s
Continuous-time transfer function model, 1.7999999999999998, 0.44999999999999996)
We then setup delayed plant + Smith predictor-based controller
τ = 8
P = delay(τ) * P0
C = feedback(C0, (1.0 - delay(τ))*P0) # form the inner feedback connection in the diagram above
DelayLtiSystem{Float64, Float64}
P: StateSpace{Continuous, Float64}
A =
0.0 -2.0
2.0 -2.8
B =
2.0 -2.0
1.7999999999999998 -1.7999999999999998
C =
2.0 -1.7999999999999998
0.0 -1.0
D =
1.7999999999999998 -1.7999999999999998
0.0 0.0
Continuous-time state-space model
Delays: [8.0]
We now plot the closed loop responses. The transfer function from to is given by = feedback(P*C,1)
, and from a load disturbance entering at the transfer function is = feedback(P, C)
using ControlSystems # Load full ControlSystems for delay-system simulation
G = [feedback(P*C, 1) feedback(P, C)] # Reference step at t = 0 and load disturbance step at t = 15
fig_timeresp = plot(lsim(G, (_,t) -> [1; t >= 15], 0:0.1:40), title="τ = $τ")
Plot the frequency response of the predictor part and compare to a negative delay, which would be an ideal controller that can (typically) not be realized in practice (a negative delay implies foresight).
C_pred = feedback(1, C0*(ss(1.0) - delay(τ))*P0)
fig_bode = bodeplot([C_pred, delay(-τ)], exp10.(-1:0.002:0.4), ls=[:solid :solid :dash :dash], title="", lab=["Smith predictor" "" "Ideal predictor" ""])
plot!(yticks=[0.1, 1, 10], sp=1)
plot!(yticks=0:180:1080, sp=2)
Check the Nyquist plot. Note that the Nyquist curve encircles -1 for τ > 2.99
fig_nyquist = nyquistplot(C * P, exp10.(-1:1e-4:2), title="τ = $τ")
A video tutorial on delay systems is available here:
Additional design methods for delay systems
Many standard control-design methods fail for delay systems, or any system not represented as a rational function. In addition to using the Smith predictor outlined above, there are however several common tricks that can be applied to make use of these methods.
-
Approximate the delay using a
pade
approximation, this will result in a standard rational model. The drawbacks include zeros in the right half plane and a failure to capture the extreme phase loss of the delay for high frequencies. -
Discretize the system with a sample time that fits an integer multiple in the delay time. A delay can be represented exactly in discrete time, but if the sample time is chosen small in relation to the delay time, a large number of extra states will be introduced.
-
Neglect the delay and design the controller with large phase and delay margins. This is perhaps not a terribly sophisticated method, but nevertheless useful in practice.
-
Neglect the delay, but model it as uncertainty. See Modeling uncertain time delays in the RobustAndOptimalControl.jl extension package. This can help you get a feeling for the margin with which you must design your controller when you have neglected to model the delay.
-
Frequency-domain methods such as manual loop shaping, and some forms of optimization-based tuning, handle time delays natively.
Whatever method is used to design in the presence of delays, the robustness and performance of the design should preferably be verified using a model of the plant where the delay is included, uncertain or not.