control design
In this tutorial, we will design a controller for a DC-servo (electrical motor).
The servo takes a torque command as input and we are interested in controlling the angle of the output shaft. An approximate model for a DC servo, valid for low frequencies, is
where is the torque and is the angle. The parameter denotes the inertia of the motor and load, is a viscous friction parameter and is a torque constant (gain).
This is a simple SISO example with a pole in the origin. Poles on the stability boundary are problematic for several numerical routines, and this tutorial demonstrates a common trick applied in these situations.
We start by defining the process model. We will use the parameter values which yields the transfer function
using DyadControlSystems, Plots
Gtrue = tf([11.2], [1, 0.12, 0])
When designing a controller using synthesis, we formally specify an optimization problem where the cost function is the norm of a suitably chosen transfer function, and the optimization variable is the controller. In this example we will optimize
where is the controller and is the sensitivity function . The transfer functions and are weight functions that emphasize different frequency ranges, for example, if is large for a particular frequency , then is forced to be small at in order for the norm to be small.
# Sensitivity weight function
WS = makeweight(1e5, 0.05, 0.5) |> tf
# Output sensitivity weight function. Increase this value to penalize controller effort more
WU = ss(1.0)
# Complementary sensitivity weight function
WT = [] # We do not put any weight on T in this example
To solve this problem, we partition the system in a two-input, two output configuration such that forms the system we want to minimize the of. To help with this partitioning, we have the function hinfpartition
:
P = hinfpartition(Gtrue, WS, WU, WT)
Before solving, we may check if the synthesis problem is feasible
hinfassumptions(P, verbose=true)
false
The problem is not feasible, in this case due to the integrator pole on the stability margin. We thus modify the plant description by moving the integrator pole in the origin slightly ($\vareplsilon$) into the stable region
ε = 1e-4
G = tf([11.2], [1, 0.12]) * tf([1], [1, ε])
If we now perform the assumption check again, it passes
P = hinfpartition(G, WS, WU, WT)
hinfassumptions(P)
true
Synthesize the H-infinity optimal controller
With the problem properly defined, we may call hinfsyn_lmi
to solve it. The result is a controller K
and a performance index :
K, γ = hinfsyn_lmi(P, γrel=1.05, ftype=BigFloat)
γ
3.146036497316298
The achieved performance level is indicated by , this number is the norm we are optimizing and it should be as low as possible.
For verification purposes, we may extract some transfer functions defining common sensitivity functions:
Pcl, S, KS, T = hinfsignals(P, G, K)
We may also verify that the closed-loop system has norm
Pcl == lft(P, K)
isapprox(hinfnorm2(Pcl)[1], γ, rtol=1e-5)
true
Plot the specifications
The resulting sensitivity functions can be plotted together with the inverse weighting functions multiplied by to get a feeling for where the constraints are active.
specificationplot([S, KS, T], [WS, WU, WT], γ)
In this case, the noise amplification constraint is active between about rad/s and the sensitivity function is pushed down for lower frequencies. In this case, the complimentary sensitivity function has desireable properties without us specifying and penalizing this function in the optimization problem. If we would like to push this function down at certain frequencies, we may specify a non-empty weight as well.