@@ -519,6 +519,46 @@ function loopshapingPI(P0, ωp; ϕl=0, rl=0, phasemargin=0, form::Symbol=:standa
519519 (; C, kp, ki, fig, CF)
520520end
521521
522+ function loopshapingPD (P0, ωp; ϕl= 0 , rl= 0 , phasemargin= 0 , form:: Symbol = :standard , doplot= false , Tf = nothing , F= nothing )
523+ issiso (P0) || throw (ArgumentError (" P must be SISO" ))
524+ if F === nothing && Tf != = nothing
525+ F = tf (1 , [Tf^ 2 , 2 * Tf/ sqrt (2 ), 1 ])
526+ end
527+ if F != = nothing
528+ P = P0* F
529+ else
530+ P = P0
531+ end
532+ Pw = freqresp (P, ωp)[]
533+ ϕp = angle (Pw)
534+ rp = abs .(Pw)
535+
536+ if phasemargin > 0
537+ ϕl == 0 || @warn " Both phasemargin and ϕl provided, the provided value for ϕl will be ignored."
538+ ϕl = deg2rad (- 180 + phasemargin)
539+ else
540+ ϕl = ϕl == 0 ? ϕp : ϕl
541+ end
542+ rl = rl == 0 ? rp : rl
543+
544+ kp = rl/ rp* cos (ϕp- ϕl)
545+ kd = rl/ (rp* ωp)* sin (ϕl- ϕp)
546+ C = pid (kp, 0 , kd, form= :parallel )
547+ CF = F === nothing ? C : C* F
548+
549+ fig = if doplot
550+ w = exp10 .(LinRange (log10 (ωp)- 2 , log10 (ωp)+ 2 , 500 ))
551+ f1 = gangoffourplot (P0,CF, w)
552+ f2 = nyquistplot ([P0 * CF, P0], w, ylims= (- 4 ,2 ), xlims= (- 4 ,1.2 ), unit_circle= true , show= false , lab= [" PC" " P" ])
553+ RecipesBase. plot! ([rl* cos (ϕl)], [rl* sin (ϕl)], lab= " Specification point" , seriestype= :scatter )
554+ RecipesBase. plot (f1, f2)
555+ else
556+ nothing
557+ end
558+ kp, _, kd = convert_pidparams_from_parallel (kp, 0 , kd, form)
559+ (; C, kp, kd, fig, CF)
560+ end
561+
522562
523563"""
524564 C, kp, ki = placePI(P, ω₀, ζ; form=:standard)
0 commit comments