Calculation of gain margin fails

I have the following code:

using ControlSystemsBase

Ts = 0.01
Ku = 100/5e6
K2 = 5e6
num = [Ku * Ts]
den = [1, -1]
P = tf(num, den, Ts) # plant
C = K2
sys = feedback(P, C)
ol_sys = P*C

margin(ol_sys)

If I create a bode plot of the open loop system, I can see a gain margin of 6dB and a phase margin of 60 degrees.

The margin(ol_sys) command has the following output:

julia> margin(ol_sys)
(wgm = [NaN;;], gm = [Inf;;], wpm = [104.76061896928398;;], pm = [59.98829336940935;;])

In other words, it calculates the phase margin correctly, but it does not find any value
for the gain margin.

Is this a bug in the margin function, or am I using it wrongly?

Notice that the phase curve never crosses -180 degrees, so the margin command is slightly confused. You can evaluate the margin exactly at the Nyquist frequency

julia> margin(ol_sys, [100pi])
(wgm = [314.1592653589793;;], gm = [2.0;;], wpm = [NaN;;], pm = [Inf;;])

Gain and phase margins are primitive measures of robustness, I’d consider using the diskmargin instead

plot(RobustAndOptimalControl.diskmargin(ol_sys))

image


Here’s a PR fixing margin in this case

2 Likes