コード例 #1
0
def plot_loops(name, G_ol, G_cl):
    # type: (str, control.tf, control.tf) -> None
    """
    Plot loops
    :param name: Name of axis
    :param G_ol: open loop transfer function
    :param G_cl: closed loop transfer function
    """
    plt.figure()
    plt.plot(*control.step_response(G_cl, np.linspace(0, 1, 1000)))
    plt.title(name + ' step response')
    plt.grid()

    plt.figure()
    control.bode(G_ol)
    print('margins', control.margin(G_ol))
    plt.subplot(211)
    plt.title(name + ' open loop bode plot')

    plt.figure()
    control.rlocus(G_ol, np.logspace(-2, 0, 1000))
    for pole in G_cl.pole():
        plt.plot(np.real(pole), np.imag(pole), 'rs')
    plt.title(name + ' root locus')
    plt.grid()
コード例 #2
0
ファイル: logsysid.py プロジェクト: mzahana/px4tools
def plot_attitude_rate_design(name, G_ol, G_cl):
    import matplotlib.pyplot as plt
    plt.figure()
    plt.plot(*control.step_response(G_cl, np.linspace(0, 1, 1000)))
    plt.title(name + ' rate step resposne')

    plt.figure()
    control.bode(G_ol)
    print(control.margin(G_ol))

    plt.figure()
    control.rlocus(G_ol, np.logspace(-2, 0, 1000))
    for pole in G_cl.pole():
        plt.plot(np.real(pole), np.imag(pole), 'rs')
    plt.title(name + ' rate step root locus')
コード例 #3
0
def PDrootlocusPlot():
    G = control.TransferFunction(L, (L, K2, -9.8 + K1))

    rlist, klist = control.rlocus(G, grid=False)
    plt.title("Root Locus diagram, K1=" + str(K1) + " and K2= " + str(K2))

    plt.show()
コード例 #4
0
ファイル: analysis.py プロジェクト: AzizFS/aae497-f19
def rlocus(name, sys, kvect, k=None):
    if k is None:
        k = kvect[-1]
    sysc = control.feedback(sys * k, 1)
    closed_loop_poles = control.pole(sysc)

    res = control.rlocus(sys, kvect, Plot=False)
    for locus in res[0].T:
        plt.plot(np.real(locus), np.imag(locus))
    p = control.pole(sys)
    z = control.zero(sys)
    marker_props = {
        'markeredgecolor': 'r',
        'markerfacecolor': 'none',
        'markeredgewidth': 2,
        'markersize': 10,
        'linestyle': 'none'
    }
    plt.plot(np.real(p), np.imag(p), marker='x', label='pole', **marker_props)
    plt.plot(np.real(z), np.imag(z), marker='o', label='zero', **marker_props)
    plt.plot(np.real(closed_loop_poles),
             np.imag(closed_loop_poles),
             marker='s',
             label='closed loop pole',
             **marker_props)

    plt.legend(loc='best')
    plt.xlabel('real')
    plt.ylabel('imag')
    plt.grid(True)
    plt.title(name + ' root locus')
コード例 #5
0
def rootlocus(sys, kvect=None):
    if kvect is None:
        kvect = np.logspace(-3, 0, 1000)
    rlist, klist = control.rlocus(sys, plot=False, kvect=kvect)
    for root in rlist.T:
        plt.plot(np.real(root), np.imag(root))
        plt.plot(np.real(root[-1]), np.imag(root[-1]), 'bs')
    for pole in control.pole(sys):
        plt.plot(np.real(pole), np.imag(pole), 'rx')
    for zero in control.zero(sys):
        plt.plot(np.real(zero), np.imag(zero), 'go')
    plt.grid()
    plt.xlabel('real')
    plt.ylabel('imag')
コード例 #6
0
if __name__ == "__main__":
    #open loop transfer function
    num = [
        1,
    ]
    denum = [1, 3.50, 8]
    k = 516.666
    GH = k * transfer_function(num, denum)

    #create a list of evenly spaced gains
    gains = np.linspace(-0.5, 10.0, num=2000)

    roots = compute_roots(GH, gains)
    fig, ax = plot_root_locus(gains, roots)
    #   plot.show()
    """  This is the end of the first code and beginning of the second
2nd code requires installation of control library. Must run Anaconda command 
promt and enter this command:
    conda install -c conda-forge control
Root locus function discription here
https://python-control.readthedocs.io/en/0.8.2
/generated/control.matlab.rlocus.html#control.matlab.rlocus

To set the 
    
    """
    G = k * cnt.tf(num, denum)
    y = 5
    x = -5, 2
    cnt.rlocus(G, kvect=gains, xlim=x, ylim=[-y, y], grid=True)
コード例 #7
0
t_inicial = 0
t_final = 10
passo_T = 0.001
T = 0.1

time_array = np.arange(t_inicial, t_final, passo_T)
tfs = control.TransferFunction([1500, 16000], [750, 1500, 16000])
time_array_disc = np.arange(t_inicial, t_final, T)
tfz = control.c2d(tfs, T)
print(tfz)
print('polos:', tfz.pole())
print()

roots, gains = control.rlocus(tfz,
                              xlim=[-20, 2],
                              kvect=np.arange(0, 20, 0.001),
                              ylim=[-5, 5],
                              Plot=False)
last_gain = None
for i in range(len(roots)):
    gain = gains[i]
    root1 = roots[i][0]
    root2 = roots[i][1]
    radius1 = getRootRadius(root1)
    radius2 = getRootRadius(root2)
    if radius1 <= 1 and radius2 <= 1:
        last_gain = gain
    else:
        break

print('Hard tunning - last gain:', last_gain)
コード例 #8
0
import control as co
import matplotlib.pyplot as plt

s = co.tf('s')
g1 = (s + 4) / ((s + 2) * (s + 1))
g2 = (s**2 + 3 * s + 4) / ((s + 2) * (s**2 + 1))
g3 = (2 * s + 1) / (s**2 + 4 * s + 8)

plt.figure(1)
g1_rlocus = co.rlocus(g1)
plt.xlim([-8, 0])

plt.figure(2)
g2_rlocus = co.rlocus(g2)
plt.xlim([-2, 1])

plt.figure(3)
g3_rlocus = co.rlocus(g3)
plt.xlim([-4, 0])

plt.show()
コード例 #9
0
import numpy
import matplotlib
import control
from pylab import *
from numpy import *
from scipy import signal

G = control.TransferFunction([6], [1, 7, 6])
C1 = control.TransferFunction([1, 10], [1, 30.31])
K = 54.67
H1 = control.feedback(G * C1 * K)
C2 = control.TransferFunction([1, 0.13583], [1, 0.05])
H2 = control.feedback(G * C1 * C2 * K)
[rlist, klist] = control.rlocus(
    H1, kvect=None, xlim=None, ylim=None, plotstr='-', Plot=True, PrintGain=True, grid=False)
# plt.show()
[rlist2, klist2] = control.rlocus(
    H2, kvect=None, xlim=None, ylim=None, plotstr='-', Plot=True, PrintGain=True, grid=False)
# plt.show()
# Parte 2: Respuesta ante escalon
t = arange(0, 25, 0.01)
T1, yout1 = control.step_response(H1, t)
T2, yout2 = control.step_response(H2, t)
plot(T1, yout1, label='Sistema realimentado con C1')
plot(T2, yout2, label='Sistema realimentado con C1 y C2')
xlabel('Tiempo [s]')
ylabel('Salida')
title('Respuesta en el tiempo de una senal tipo escalon')

# plt.show()
# Tiempo establecimiento
コード例 #10
0
    return ca.Function('ss', [x, u, p], [A, B, C, D],
            ['x', 'u', 'p'], ['A', 'B', 'C', 'D'])


if __name__ == "__main__":
    run()
    code_generation()

    x0, u0, p0 = do_trim(vt=100, gamma_deg=90, m_fuel=0.8)
    lin = linearize()
    import control
    sys1 = control.ss(*lin(x0, u0, p0))

    # get pitch rate from elevator
    G = control.ss2tf(sys1[1, 2])
    control.rlocus(G)
    plt.show()

    # next steps
    # pitch rate pid design, use this to control pitch angle
    # use flight path angle to control altitude

    #print(x0, u0, p0)
    #print(sys1)
    # sys2 = do_trim(vt=50, gamma_deg=90, m_fuel=0.0)
    
    # pid design to get gains, manually for now using root locus

    # schedule gains
    # gains = gain_schedule(gains1, gains2, t)
コード例 #11
0
ファイル: tarea5.py プロジェクト: Aldunate5/Diego_Aldunate
import numpy as np
import matplotlib.pyplot as plt
import control

#### Caso C1 #####
G = control.TransferFunction([3], [1, 7, 6])
C1 = control.TransferFunction([1, 10], [1, 30.31])
K = 109.34
H1 = control.feedback(G * C1 * K)
[rlist, klist] = control.rlocus(H1,
                                plotstr='-',
                                Plot=True,
                                PrintGain=True,
                                grid=False)
plt.show()

t = np.arange(0, 30, 0.05)
T1, yout1 = control.step_response(H1, t)
plt.plot(T1, yout1)
plt.xlabel('Tiempo [s]'), plt.ylabel('Salida')
plt.title('Respuesta a entrada en escalon - Compensador 1')
plt.show()

C2 = control.TransferFunction([1, 0.136], [1, 0.05])
H2 = control.feedback(G * C1 * C2 * K)
#[rlist2, klist2] = control.rlocus(
#    H2, plotstr='-', Plot=True, PrintGain=True, grid=False)
#plt.show()
t = np.arange(0, 30, 0.05)
T2, yout2 = control.step_response(H2, t)
plt.plot(T2, yout2)
コード例 #12
0
def rlocus(tf_list=[],
           kvect=np.logspace(-2, 1.2, 1000),
           xlim=None,
           ylim=None,
           show_grid=None):
    """Root locus plot
        
        Calculate the root locus by finding the roots of 1+k*TF(s) where TF is self.num(s)/self.den(s) and each k is an element of kvect.
    """

    xlabel = "Real Axis"
    ylabel = "Imag Axis"
    ylabel = "Magnitude (dB)"
    hovertemplate = "<b>K</b>: %{text:.3f}<br><b>imag</b>: %{y:.3f}<br><b>real</b>: %{x:.3f}<br>m: %{customdata[0]:.3f}<br>wn: %{customdata[1]:.3f} rad/s"

    data = []
    xlim = []
    ylim = []
    for index, tf in enumerate(tf_list):

        r_list, k_list = ctl.rlocus(tf,
                                    kvect,
                                    xlim=xlim,
                                    ylim=ylim,
                                    Plot=False)

        #get ylim and xlim
        xlim_max = np.max(np.real(np.ravel(r_list)))
        xlim_min = np.min(np.real(np.ravel(r_list)))
        ylim_max = np.max(np.imag(np.ravel(r_list)))
        ylim_min = np.min(np.imag(np.ravel(r_list)))
        xlim = 1.2 * np.array([xlim_min, xlim_max])
        ylim = 1.2 * np.array([ylim_min, ylim_max])

        tf_name = "tf {}".format(index + 1)
        r_list = np.transpose(r_list)

        first_point = dict(color='#555', width=1, dash="dot")

        for index_r in range(len(r_list)):
            r_temp = r_list[index_r]
            #compute equivalent continuous m, wn
            r_list_comp = r_list.astype(
                complex
            )  # WTF: the python control "damp" function is buggy due to this missing cast !
            r_list_continuous = np.log(r_list_comp) / tf.dt
            wn_vect = np.abs(r_list_continuous)
            m_vect = -np.real(r_list_continuous) / wn_vect
            custom_data = np.dstack((m_vect, wn_vect))[0]

            data.append({
                "x": np.real(r_temp),
                "y": np.imag(r_temp),
                "name": tf_name,
                "customdata": custom_data,
                "hovertemplate": hovertemplate,
                "text": k_list,
                "showlegend": False
            })
            data.append({
                "x": [np.real(r_temp[0])],
                "y": [np.imag(r_temp[0])],
                "line": first_point,
                "mode": "markers",
                "marker": {
                    "symbol": "x",
                    "size": 8
                },
                "showlegend": False
            })

    layout = default_layout("Real Axis", "Imag Axis", name=None)
    fig = go.Figure(data, layout=layout)
    return fig
コード例 #13
0
num = [25.95]
den = [1,7.25,9.77]
numMpComp = [1,5.46]
denMpComp = [1,2.21]
numErrComp = [1,1]
denErrComp = [1,.00945]
sys = co.tf(num,den)
mpComp = 0.289*co.tf(numMpComp,denMpComp)
errComp = 1.1591*co.tf(numErrComp,denErrComp)
mpSys = mpComp*sys
errMpSys = errComp*mpSys
print('\n\nErro sem compesador:',1/(1+co.dcgain(mpSys)))
print('Erro com compensador:',1/(1+co.dcgain(errMpSys)))

co.rlocus(sys)
plt.title('LGR do sistema original')
plt.grid()
plt.figure(2)
co.rlocus(mpSys)
plt.title('LGR do sistema com overshoot compensado')
plt.grid()
plt.figure(3)
co.rlocus(errMpSys)
plt.title('LGR do sistema com overshoot e erro compensado')
plt.grid()
plt.show()

plt.title('Resposta ao impulso')
T = np.arange(0,50,.1)
Y,t = co.step_response(1,T)
コード例 #14
0
ファイル: cod.py プロジェクト: thiagofigcosta/digital-control

# a
t_inicial=0
t_final=10
passo_T=0.001
T=0.1

time_array = np.arange(t_inicial, t_final,passo_T)
tfs = control.TransferFunction([.5],[.5,1,0])
time_array_disc = np.arange(t_inicial, t_final,T)
tfz = control.c2d(tfs, T)
print(tfz)

# b
roots,gains=control.rlocus(tfz,xlim=[-20,2], ylim=[-5,5])
plt.legend(loc='best')
plt.show()

# c
last_gain=None
for i in range(len(roots)):
    gain=gains[i]
    root1=roots[i][0]
    root2=roots[i][1]
    radius1=getRootRadius(root1)
    radius2=getRootRadius(root2)
    if radius1<=1 and radius2<=1:
        last_gain=gain
    else:
        break
コード例 #15
0
        ABCDs.append([A,B,C,D])
        sys.append(control.ss(A,B,C,D))
    
    return sys


if __name__ == "__main__":
    #run()
    #code_generation()
    plan_traj()

    sys = plan_traj()
    # get pitch rate from elevator
    Gp1 = control.ss2tf(sys[0][1, 2])
    plt.figure()
    control.rlocus(Gp1)
    plt.show()

    Gp2 = control.ss2tf(sys[1][1,2])
    plt.figure()
    control.rlocus(Gp2)
    plt.show()

    # next steps
    # pitch rate pid design, use this to control pitch angle
    # use flight path angle to control altitude

    #print(x0, u0, p0)
    #print(sys1)
    # sys2 = do_trim(vt=50, gamma_deg=90, m_fuel=0.0)
    
コード例 #16
0
print("poles: ", G.pole())
print("zeros: ",G.zero())

number_asymptotes=len(G.pole())-len(G.zero())

print("number of asymptotes: ",number_asymptotes)

centroid=(G.pole().sum()-G.zero().sum())/number_asymptotes

print("centroid: ",centroid)

print("angle(s) of deperture:")

for i in range(number_asymptotes):
    theta=(((2*i)+1)/number_asymptotes)*180
    print(theta)

gm, pm, wg, wp = ctl.margin(G)

print("Gain margin:", gm)
print("Phase margin:", pm)

plt.figure()
ctl.rlocus(G)
plt.figure()
ctl.bode(G,dB=True)
plt.show()
plt.figure()
ctl.nyquist_plot(G)
plt.show()
コード例 #17
0
import control as co
import numpy as np
import matplotlib.pyplot as plt
import sympy as sp

num = [-25.95]
den = [1, 7.25, 9.77]
sys = co.tf(num, den)
co.rlocus(sys)
plt.title('K->+inf')
plt.figure(2)
sys = co.tf(num, den)
co.rlocus(-sys)
plt.title('K->-inf')
plt.grid()
plt.show()
コード例 #18
0
import numpy as np
from matplotlib import pyplot as plt
import control
from matplotlib.pyplot import style

# style.use('seaborn')

G = control.TransferFunction((25.05, 100.2), (1, 8, 16.05, 28.2))

rlist, klist = control.rlocus(G)

plt.annotate("Pole, P1", (-6.13, -2))
plt.annotate("Pole, P2", (-1, 3))
plt.annotate("Pole, P3", (-1, -3))
plt.annotate("Zero, Z1", (-4, 1))
plt.legend()
plt.show()
コード例 #19
0
#import numpy as np
import matplotlib.pyplot as plt
import control as cnt

G1 = cnt.tf([1], [1, 4, 3, 0])
cnt.rlocus(G1, xlim=(-4, 1), ylim=(-3, 3))
plt.xlabel('real part of s')
plt.ylabel('imaginary part of s')
plt.grid()
plt.savefig('ee18btech11050.pdf')
plt.savefig('ee18btech11050.eps')
plt.show()
コード例 #20
0
import numpy as np
import matplotlib.pyplot as plt
import control

#if using termux
import subprocess
import shlex
#end if

num = [6, 0]  # Coefficients of Numerator of Tranfer Function
den = [1, 2, 5]  # Coefficients of Denominator of Tranfer Function
G = control.TransferFunction(num, den)  # Transfer Function

rlist, klist = control.rlocus(G)  # Root Locus of Transfer Function

ans1 = np.roots(num)  # Zeros of Transfer Fuunction
ans2 = np.roots(den)  # Poles of Transfer Function

X1 = [x.real for x in ans1]
Y1 = [x.imag for x in ans1]
plt.scatter(X1, Y1, color='orange',
            label='Zeros')  # Plotting zeros of Transfer Function
X2 = [x.real for x in ans2]
Y2 = [x.imag for x in ans2]
plt.scatter(X2, Y2, marker='x', color='blue',
            label='Poles')  # Plotting poles of Transfer Function
plt.scatter(-np.sqrt(5), 0, color='red',
            label='Breakaway Point')  #Breakaway point
plt.xlabel('Real axis')
plt.ylabel('Imaginary axis')
plt.title('Root Locus Plot')
コード例 #21
0
ファイル: test.py プロジェクト: AboSalaa7/Root-Locus
from matplotlib import pyplot as plt


def fEquation(roots):
    x = symbols('x')
    whole = 1
    if len(roots) == 0:
        return 0
    for root in roots:
        whole *= (x - root)
    return whole.expand()


pole1 = complex(0, 0)
pole2 = complex(-25, 0)
pole3 = complex(-50, 10)
pole4 = complex(-50, -10)
print(pole3.real)
roots = [pole1, pole2, pole3, pole4]
denominator = fEquation(roots)
k = symbols('k')
equation = 1 / denominator

diffEquation = diff(equation)
breakAwayPoints = solve(diffEquation)
alist = Poly(denominator).all_coeffs()

G = co.TransferFunction(1, (1, 125, 5100, 65000, 0))
rlist, klist = co.rlocus(G)
plt.show()
コード例 #22
0
ファイル: prob_1.py プロジェクト: Blendoit/UCLA_MAE_171A
import numpy as np
import control
import matplotlib.pyplot as plt

# L = control.TransferFunction((1), (1, 6, 5, 0, 0))
# L = control.TransferFunction((1, 2), (1, 10, 0, 0))
L = control.TransferFunction((1, 1), (1, -3, 0))

rlist, klist = control.rlocus(L, kvect=np.linspace(100, -100, num=1000))

plt.show()
コード例 #23
0
def main():
    # construct gain scheduler object
    gs = GainScheduler()

    Kp_guess = 3
    Ki_guess = 8

    # Vars
    gs.m.tf = Param(initialize=30)
    gs.m.Kp = Var(initialize=Kp_guess, bounds=(1, 10))
    gs.m.Ki = Var(initialize=Ki_guess, bounds=(0, 10))
    gs.m.y1 = Var(gs.m.tau)
    gs.m.y2 = Var(gs.m.tau)
    gs.m.y3 = Var(gs.m.tau)
    gs.m.u = Var(gs.m.tau)
    gs.m.r = Var(gs.m.tau)
    gs.m.J = Var(gs.m.tau)

    gs.m.w180cross = Var(initialize=1, bounds=(0, 10))
    gs.m.w0dBcross = Var(initialize=1.2, bounds=(0, 10))

    # Derivative Vars
    gs.m.dy1dt = DerivativeVar(gs.m.y1, wrt=gs.m.tau)
    gs.m.dy2dt = DerivativeVar(gs.m.y2, wrt=gs.m.tau)
    gs.m.dy3dt = DerivativeVar(gs.m.y3, wrt=gs.m.tau)
    gs.m.dudt = DerivativeVar(gs.m.u, wrt=gs.m.tau)
    gs.m.drdt = DerivativeVar(gs.m.r, wrt=gs.m.tau)
    gs.m.dJdt = DerivativeVar(gs.m.J, wrt=gs.m.tau)

    ### Discretize problem (after m.tau and all variables are defined, before constraint defs defined)
    discretizer = TransformationFactory('dae.collocation')
    discretizer.apply_to(gs.m,
                         wrt=gs.m.tau,
                         nfe=75,
                         ncp=10,
                         scheme='LAGRANGE-RADAU')

    #% Build model

    # Phase and Gain crossing constraints
    gs.m.w180crossConstraint = Constraint(rule=gs._w180cross)
    gs.m.w0dBcrossConstraint = Constraint(rule=gs._w0dBcross)

    # Standard constraints
    gs.m.bcConstraint = ConstraintList(rule=gs.BCs)
    gs.m.y1dotConstraint = Constraint(gs.m.tau, rule=gs._y1dot)
    gs.m.y2dotConstraint = Constraint(gs.m.tau, rule=gs._y2dot)
    gs.m.y3dotConstraint = Constraint(gs.m.tau, rule=gs._y3dot)
    gs.m.udotConstraint = Constraint(gs.m.tau, rule=gs._udot)
    gs.m.rdotConstraint = Constraint(gs.m.tau, rule=gs._rdot)

    # Margin constraints
    gs.m.gainMargindBConstraint = Constraint(rule=gs._gainMargindB)
    gs.m.phaseMarginConstraint = Constraint(rule=gs._phaseMargin)

    gs.m.JdotConstraint = Constraint(gs.m.tau, rule=gs._Jdot)

    gs.m.obj = Objective(expr=gs.m.J[1], sense=minimize)

    solver = SolverFactory('ipopt')
    solver.options["halt_on_ampl_error"] = "yes"
    solver.options["tol"] = 1e-6
    solver.options["max_iter"] = 2000
    solver.options["linear_solver"] = "ma27"
    solver.options["ma27_pivtol"] = 1e-6
    #solver.options["ma27_liw_init_factor"] = 5
    solver.options["linear_scaling_on_demand"] = "yes"
    solver.options["mu_init"] = 1
    solver.solve(gs.m, tee=True)

    results_dict = {}
    var_list = [gs.m.Kp, gs.m.Ki]
    for var in var_list:
        print("Saving Variable: ", var)  # doctest: +SKIP
        results_dict[var.name] = [value(var[index]) for index in var]

    #%% Plotting
    mpl.rcParams['font.size'] = 14
    mpl.rcParams['legend.fontsize'] = 14
    mpl.rcParams["font.family"] = "Times New Roman"
    csfont = {'fontname': 'Times New Roman'}
    plt.rc('text', usetex=True)
    plt.rc('font', family='serif')

    #plt.close('all')

    blue = '#1f77b4ff'
    orange = '#ff7f0eff'
    green = '#2ca02cff'

    time = np.dot(gs.m.tau, gs.m.tf())
    y1 = [gs.m.y1[t]() for t in gs.m.tau]
    r = [gs.m.r[t]() for t in gs.m.tau]
    plt.figure(1)
    plt.plot(time, y1, '.-')
    plt.plot(time, r, 'k')
    plt.xlabel('t [s]')
    plt.ylabel('y')
    plt.grid()
    plt.title([
        'Kp:%6.2f' % gs.m.Kp(),
        'Ki:%6.2f' % gs.m.Ki(),
        'J = %6.2f' % gs.m.J[1]()
    ])

    print('Kp = ', gs.m.Kp())
    print('Ki = ', gs.m.Ki())

    sysC = control.tf([gs.m.Kp(), gs.m.Ki()], [1, 0])
    sysG = control.tf([1], [1, 4, 8, 8])
    sys = sysC * sysG
    rlist, klist = control.rlocus(sys, kvect=np.logspace(-10, 1, 500))

    sysC = control.tf([gs.m.Kp(), gs.m.Ki()], [1, 0])
    sysG = control.tf([1], [1, 4, 8, 8])
    sys = sysC * sysG
    r, k = control.rlocus(sys, [1])
    plt.close()
    #fig,ax = plt.subplots()
    plt.scatter(r.real, r.imag, color='k')

    sysC = control.tf([gs.m.Kp(), gs.m.Ki()], [1, 0])
    sysG = control.tf([1], [1, 4, 8, 8])
    sys = sysC * sysG
    plt.figure()
    mag, phase, omega = control.bode(sys, dB=True, margins=True)

    #%% Check gain/phase

    #K  = m.K()
    #s  = complex(real=0, imag=m.w180cross())
    #CG = (s+1)/(s*(s+2)*(s**2+2*s+4))
    #L  = K*CG
    #magL = sqrt(L.real**2+L.imag**2)
    #angleL = -180/pi*np.arctan2(L.imag,L.real)

    w = sympy.Symbol('w', real=True)
    s = sympy.I * w
    C = gs.m.Kp() + gs.m.Ki() / s
    G = 1 / ((s + 2) * (s**2 + 2 * s + 4))
    L = C * G
    real, imag = L.as_real_imag()
    phase = -180 / pi * sympy.atan2(imag, real)
    mag = sympy.sqrt(real**2 + imag**2)

    _phase = sympy.lambdify((w), phase)
    _mag = sympy.lambdify((w), mag)

    print('w180cross = ', gs.m.w180cross(), 'rad/s')
    print('w0dBcross = ', gs.m.w0dBcross(), 'rad/s')
    print('magLdB at w0dBcross = ', 20 * log10(_mag(gs.m.w0dBcross())))
    print('angleL at w180cross = ', _phase(gs.m.w180cross()))

    return
コード例 #24
-5
ファイル: logsysid.py プロジェクト: dronecrew/px4tools
def plot_loops(name, G_ol, G_cl):
    """
    Plot loops
    :param name: Name of axis
    :param G_ol: open loop transfer function
    :param G_cl: closed loop transfer function
    """
    plt.figure()
    plt.plot(*control.step_response(G_cl, np.linspace(0, 1, 1000)))
    plt.title(name + ' step resposne')
    plt.grid()

    plt.figure()
    control.bode(G_ol)
    print('margins', control.margin(G_ol))
    plt.subplot(211)
    plt.title(name + ' open loop bode plot')

    plt.figure()
    control.rlocus(G_ol, np.logspace(-2, 0, 1000))
    for pole in G_cl.pole():
        plt.plot(np.real(pole), np.imag(pole), 'rs')
    plt.title(name + ' root locus')
    plt.grid()
コード例 #25
-22
def rlocusfind(system_or_tf, *args, **kwargs):
    kwargs["Plot"] = False
    initial_pick = None
    if "initial_pick" in kwargs:
        initial_pick = kwargs["initial_pick"]
        del kwargs["initial_pick"]
    
    plot_str = kwargs["plotstr"] if "plotstr" in kwargs else "-"
    rl, gains = control.rlocus(system_or_tf, *args, **kwargs)
    
    x = numpy.concatenate(numpy.real(rl.T))
    y = numpy.concatenate(numpy.imag(rl.T))
    #loci_points = numpy.squeeze(numpy.dstack( (x, y) ))
    #lu_tree = scipy.spatial.KDTree(loci_points, 5)

    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)

    def rlocus_result_at(pole_x, pole_y):
        pole = complex(pole_x, pole_y)
        
        gain = gain_at(system_or_tf, pole)
        damping_coefficient = damping_coefficient_at(pole)
        overshoot = overshoot_from_damping_coefficient(damping_coefficient)
        natural_frequency = undamped_natural_frequency_at(pole)

        return RootLocusResult(
            pole, gain, damping_coefficient, overshoot, natural_frequency
        )

        
    def pick_handler(event):
        try:
            mouse_event = event.mouseevent
            locus_line = event.artist
            #dist, point_index = lu_tree.query(
            #    (mouse_event.xdata, mouse_event.ydata)
            #)
            
            pole_x = mouse_event.xdata #x[point_index]
            pole_y = mouse_event.ydata #y[point_index]
            marker.set_xdata([pole_x])
            marker.set_ydata([pole_y])
            fig.canvas.draw()

            res = rlocus_result_at(pole_x, pole_y)
            
            print "-"*25
            print "System:\n{0!s}".format(system_or_tf)
            print "Gain:", res.gain
            print "Pole: {0!s}".format(res.pole)
            print "Damping:", res.damping_coefficient 
            print "Overshoot (%):", res.overshoot
            print "Frequency (rad/s):", res.frequency
            print "-"*25
        except Exception as e:
            print "Error: {0!s}".format(e)
        sys.stdout.flush()

    if not initial_pick:
        rlocus_result = None
        marker, = ax.plot([x[0]], [y[0]], "ko")
    else:
        initial_x, initial_y = initial_pick
        rlocus_result = rlocus_result_at(initial_x, initial_y)
        marker, = ax.plot([initial_x], [initial_y], "ko")
        SynthesizedEvent = collections.namedtuple(
            "SynthesizedEvent", ["mouseevent", "artist"]
        )
        artificial_pick_event = SynthesizedEvent( initial_pick, None )
        
    for col in rl.T:
        ax.plot(numpy.real(col), numpy.imag(col), plot_str, picker=3)

    ax.grid(True)    
    ax.set_xlabel('Real')
    ax.set_ylabel('Imaginary')
    
    fig.canvas.mpl_connect("pick_event", pick_handler)
    return (fig, rlocus_result)
コード例 #26
-23
xe2 = v
ue = n

A11 = np.sin(xe1) * xe2 / g  # Upper left
A12 = (-np.cos(xe1) / g) - (ue * g / np.power(xe2, 2))  # Upper right
A21 = -np.cos(xe1) / g  # Lower left
A22 = (2 * k1 * np.power(ue, 2) * g / np.power(xe2, 3)) - (2 * k2 * xe2 * g)

B1 = g / xe2
B2 = -2 * k1 * ue * g / np.power(xe2, 2)


X1_over_U_numerator = [B1, (A12 * B2 - A22 * B1)]
X1_over_U_denominator = [1, -(A22 + A11), A22 * A11 - A12 * A21]
H1 = cnt.tf(X1_over_U_numerator, X1_over_U_denominator)

X2_over_U_numerator = [B2, (A21 * B1 - A11 * B2)]
X2_over_U_denominator = [1, -(A22 + A11), A22 * A11 - A12 * A21]
H2 = cnt.tf(X2_over_U_numerator, X2_over_U_denominator)

A = 1
B = -(A22 + A11)
C = A22 * A11 - A12 * A21
print((-B + np.sqrt(B**2 - 4*A*C)) / 2*A)
print((-B - np.sqrt(B**2 - 4*A*C)) / 2*A)

cnt.rlocus(H1 / (1 + H1));
plt.show()

cnt.rlocus(H2 / (1 + H2));
plt.show()