From d0ba23165b136c94c596c167acc8d03bfe06d782 Mon Sep 17 00:00:00 2001 From: Fredrik Bagge Carlson Date: Sun, 17 Jan 2021 06:34:56 +0100 Subject: [PATCH] more robust gangoffour and gofplot --- src/analysis.jl | 29 +++++++++++++++++------------ src/plotting.jl | 14 ++++++++------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/analysis.jl b/src/analysis.jl index 8c928e3ee..58fb09672 100644 --- a/src/analysis.jl +++ b/src/analysis.jl @@ -451,28 +451,33 @@ function delaymargin(G::LTISystem) dₘ end +function robust_minreal(G, args...; kwargs...) + try + return minreal(G, args...; kwargs...) + catch + return G + end +end + """ S,D,N,T = gangoffour(P,C; minimal=true) gangoffour(P::AbstractVector,C::AbstractVector; minimal=true) - + Given a transfer function describing the Plant `P` and a transfer function describing the controller `C`, computes the four transfer functions in the Gang-of-Four. -`minimal` determines whether or not to call `minreal` on the computed systems. - -`S = 1/(1+PC)` Sensitivity function - -`D = P/(1+PC)` - -`N = C/(1+PC)` +- `minimal` determines whether or not to call `minreal` on the computed systems. +- `S = 1/(1+PC)` Sensitivity function +- `D = P/(1+PC)` +- `N = C/(1+PC)` +- `T = PC/(1+PC)` Complementary sensitivity function -`T = PC/(1+PC)` Complementary sensitivity function - -Only supports SISO systems""" +Only supports SISO systems +""" function gangoffour(P::LTISystem,C::LTISystem; minimal=true) if P.nu + P.ny + C.nu + C.ny > 4 error("gangoffour only supports SISO systems") end - minfun = minimal ? minreal : identity + minfun = minimal ? robust_minreal : identity S = (1/(1+P*C)) |> minfun D = (P*S) |> minfun N = (C*S) |> minfun diff --git a/src/plotting.jl b/src/plotting.jl index 787cf4be2..2c2c30aab 100644 --- a/src/plotting.jl +++ b/src/plotting.jl @@ -727,18 +727,20 @@ end pzmap(sys::LTISystem; kwargs...) = pzmap([sys]; kwargs...) pzmap!(sys::LTISystem; kwargs...) = pzmap!([sys]; kwargs...) -"""`fig = gangoffourplot(P::LTISystem, C::LTISystem)`, `gangoffourplot(P::Union{Vector, LTISystem}, C::Vector; plotphase=false)` - -Gang-of-Four plot. +""" + fig = gangoffourplot(P::LTISystem, C::LTISystem; minimal=true, plotphase=false, kwargs...) + gangoffourplot(P::Union{Vector, LTISystem}, C::Vector; minimal=true, plotphase=false, kwargs...) -`kwargs` is sent as argument to Plots.plot.""" -function gangoffourplot(P::Union{Vector, LTISystem}, C::Vector, args...; plotphase=false, kwargs...) +Gang-of-Four plot. `kwargs` is sent as argument to Plots.plot. +""" +function gangoffourplot(P::Union{Vector, LTISystem}, C::Vector, args...; minimal=true, plotphase=false, kwargs...) # Array of (S,D,N,T) if P isa LTISystem # Don't broadcast over scalar (with size?) P = [P] end - sys = gangoffour.(P,C) + sys = gangoffour.(P,C; minimal=minimal) fig = bodeplot([[sys[i][1] sys[i][2]; sys[i][3] sys[i][4]] for i = 1:length(C)], args..., plotphase=plotphase; kwargs...) + hline!([1 1 1 1], l=(:black, :dash), primary=false) titles = fill("", 1, plotphase ? 8 : 4) # Empty titles on phase titleIdx = plotphase ? [1,2,5,6] : [1,2,3,4]