Ejemplo n.º 1
0
    def test_zero(self, fun, args):
        sys = fun(*args)
        np.testing.assert_allclose(sys.zeros(), 42)
        np.testing.assert_allclose(zeros(sys), 42)

        with pytest.warns(PendingDeprecationWarning):
            sys.zero()

        with pytest.warns(PendingDeprecationWarning):
            ct.zero(sys)
Ejemplo n.º 2
0
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')
Ejemplo n.º 3
0
 def test_full_order_compensator(self):
     with warnings.catch_warnings():
         warnings.simplefilter("ignore")
         A = np.array([[0., 1., 0., 0.], [0., -25., -0.98, 0.],
                       [0., 0., 0., 1.], [0., 25., 10.78,
                                          0.]]).astype('float')
         B = np.array([[0.], [0.5], [0.], [-0.5]]).astype('float')
         C = np.array([[1., 0., 0., 0.]]).astype('float')
         D = np.zeros((1, 1)).astype('float')
         desiredPolesCtrl = np.array([
             -25., -4.,
             np.complex(-2., 2. * np.sqrt(3)),
             np.complex(-2., -2. * np.sqrt(3))
         ])
         w0 = 5.
         desiredPolesObsv = np.roots(
             np.array([
                 1.0, 2.613 * w0, (2. + np.sqrt(2)) * w0**2, 2.613 * w0**3,
                 w0**4
             ]))
         compensatorTF = fullOrderCompensator(A, B, C, D, desiredPolesCtrl,
                                              desiredPolesObsv)
         openLoopTF = control.ss2tf(control.StateSpace(A, B, C, D))
         # poles are zeros of return difference
         poles = control.zero(1. + compensatorTF * openLoopTF)
         for p in poles:
             polePresent = any([
                 np.isclose(np.complex(p), np.complex(pt))
                 for pt in np.hstack([desiredPolesCtrl, desiredPolesObsv])
             ])
             self.assertTrue(polePresent)
Ejemplo n.º 4
0
def locate_poles():
    """
        Finds location of a system's zeros and poles
    """
    n1 = np.array([1, 1])
    n2 = np.array([1, 2])

    d1 = np.array([1, 2j])
    d2 = np.array([1, -2j])
    d3 = np.array([1, 3])

    numerator_g, denominator_g = np.array([6, 0, 1]), np.array([1, 3, 3, 1])
    sys_g = ct.tf(numerator_g, denominator_g)

    zeros_g = ct.zero(sys_g)
    pole_g = ct.pole(sys_g)

    numerator_h = np.convolve(n1, n2)
    denominator_h = np.convolve(d1, np.convolve(d2, d3))
    sys_h = ct.tf(numerator_h, denominator_h)

    sys_tf = sys_g / sys_h

    pzmap_sys = ct.pzmap(sys_tf)

    print(AsciiTable([['Poles and Zeros']]).table)
    data = [['Function', 'Result Ouput'], ['G(s)', sys_g],
            ['Zeros(g)', zeros_g], ['Pole(g)', pole_g], ['H(s)', sys_h],
            ['T(s)', sys_tf], ['Pzmap(s)', pzmap_sys]]
    print(AsciiTable(data).table)
Ejemplo n.º 5
0
    def testMinrealBrute(self):

        # depending on the seed and minreal performance, a number of
        # reductions is produced. If random gen or minreal change, this
        # will be likely to fail
        nreductions = 0

        for n, m, p in permutations(range(1, 6), 3):
            s = rss(n, p, m)
            sr = s.minreal()
            if s.states > sr.states:
                nreductions += 1
            else:
                # Check to make sure that poles and zeros match

                # For poles, just look at eigenvalues of A
                np.testing.assert_array_almost_equal(np.sort(eigvals(s.A)),
                                                     np.sort(eigvals(sr.A)))

                # For zeros, need to extract SISO systems
                for i in range(m):
                    for j in range(p):
                        # Extract SISO dynamixs from input i to output j
                        s1 = ss(s.A, s.B[:, i], s.C[j, :], s.D[j, i])
                        s2 = ss(sr.A, sr.B[:, i], sr.C[j, :], sr.D[j, i])

                        # Check that the zeros match
                        # Note: sorting doesn't work => have to do the hard way
                        z1 = zero(s1)
                        z2 = zero(s2)

                        # Start by making sure we have the same # of zeros
                        assert len(z1) == len(z2)

                        # Make sure all zeros in s1 are in s2
                        for z in z1:
                            # Find the closest zero TODO: find proper bounds
                            assert min(abs(z2 - z)) <= 1e-7

                        # Make sure all zeros in s2 are in s1
                        for z in z2:
                            # Find the closest zero
                            assert min(abs(z1 - z)) <= 1e-7

        # Make sure that the number of systems reduced is as expected
        # (Need to update this number if you change the seed at top of file)
        assert nreductions == 2
Ejemplo n.º 6
0
    def plot_rlocus(self, fig):
        tf = self.tf if self.loop_type == 'ol' else self.tf_plant * self.tf_comp

        fig.clf()
        ax = fig.add_subplot(1, 1, 1)

        klist = np.linspace(500.0, 0, num=1000)
        rlist, _ = control.root_locus(tf, kvect=klist, Plot=False)

        rlist = np.vstack(rlist)

        poles = np.array(control.pole(tf))
        ax.plot(np.real(poles), np.imag(poles), 'x')

        zeros = np.array(control.zero(tf))
        if zeros.size > 0:
            ax.plot(np.real(zeros), np.imag(zeros), 'o')

        ax.plot(np.real(rlist), np.imag(rlist))

        ax.axhline(0., linestyle=':', color='k', zorder=-20)
        ax.axvline(0., linestyle=':', color='k')

        ax.set_xlabel('Real axis')
        ax.set_ylabel('Imaginary axis')

        if not self.settings.is_rlocus_default():
            zeta = self.settings.get_rlocus_zeta()
            wn = self.settings.get_rlocus_omega()

            x0 = -np.arccos(zeta) * wn if wn else ax.get_xlim()[0]
            xt = np.arange(x0, 0, 0.01)
            ax.plot(xt,
                    -np.arccos(zeta) * xt,
                    '--',
                    linewidth=0.5,
                    color='black')
            ax.plot(xt,
                    np.arccos(zeta) * xt,
                    '--',
                    linewidth=0.5,
                    color='black')

            x = np.arange(0, wn + 0.01, 0.01)
            y = np.sqrt(wn**2 - x**2)
            x = -np.concatenate([x, x[::-1]])
            y = np.concatenate([y, -y[::-1]])
            ax.plot(x, y, '--', linewidth=0.5, color='black')

            xmin = self.settings.get_rlocus_xmin()
            xmax = self.settings.get_rlocus_xmax()
            ymin = self.settings.get_rlocus_ymin()
            ymax = self.settings.get_rlocus_ymax()
            ax.set_xlim(xmin, xmax)
            ax.set_ylim(ymin, ymax)

        return fig
Ejemplo n.º 7
0
 def TF_properties(self, window, key, entry1, entry2):
     transfer_function = self.get_TF(entry1, entry2)
     if key == "dcgain":
         dc_gain = co.dcgain(transfer_function)
         self.print_TF_props(window, dc_gain, "DC Gain:")
     elif key == "poles":
         poles = co.pole(transfer_function)
         self.print_TF_props(window, poles, "Poles:")
     elif key == "zeros":
         zeros = co.zero(transfer_function)
         self.print_TF_props(window, str(zeros), "Zeros:")
Ejemplo n.º 8
0
 def time(tf):
     print "Poles:   ", ctrl.pole(tf)
     print "Zeros:   ", ctrl.zero(tf)
     dc = ctrl.dcgain(tf)
     print "DC gain: ", dc
     t, y = ctrl.step_response(tf)
     ys = filter(lambda l: l >= 0.98 * dc, y)
     i = np.ndarray.tolist(y).index(min(ys))
     print "Ts: ", t[i]
     print "Overshoot: ", (max(y) / dc) - 1
     i = np.ndarray.tolist(y).index(max(y))
     print "Tr: ", t[i]
Ejemplo n.º 9
0
    def test_reduced_order_compensator(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            A = np.array([[0., 1., 0., 0.], [0., -25., -0.98, 0.],
                          [0., 0., 0., 1.], [0., 25., 10.78,
                                             0.]]).astype('float')
            B = np.array([[0.], [0.5], [0.], [-0.5]]).reshape(
                (4, 1)).astype('float')
            C = np.array([[1., 0., 0., 0.]]).reshape((1, 4)).astype('float')
            D = np.zeros((1, 1)).astype('float')

            ### Controller ###
            desiredPolesCtrl = np.array([
                -25., -4.,
                np.complex(-2., 2. * np.sqrt(3)),
                np.complex(-2., -2. * np.sqrt(3))
            ])
            G = ch6_utils.bassGura(A, B, desiredPolesCtrl)
            G1 = G[0, 0].reshape((1, 1))
            G2 = G[0, 1:].reshape((1, 3))

            ### Observer ###
            desiredPolesObsv = np.roots(
                np.array([1.0, 2. * 5., 2. * 5.**2, 5.**3]))
            Aaa = np.array(A[0, 0]).reshape((1, 1))
            Aau = np.array(A[0, 1:]).reshape((1, 3))
            Aua = np.array(A[1:, 0]).reshape((3, 1))
            Auu = np.array(A[1:, 1:]).reshape((3, 3))
            Ba = np.array(B[0]).reshape((1, 1))
            Bu = np.array(B[1:]).reshape((3, 1))
            Ca = np.array([[1]]).reshape((1, 1)).astype('float')
            L, Gbb, H = ch7_utils.reducedOrderObserver(Aaa, Aau, Aua, Auu, Ba,
                                                       Bu, Ca,
                                                       desiredPolesObsv)

            ### Compensator ###
            F = Auu - L @ Aau
            Ar = F - H @ G2
            Br = Ar @ L + Gbb - H @ G1
            Cr = G2
            Dr = G1 + G2 @ L
            sysD = control.StateSpace(Ar, Br, Cr, Dr)
            compensatorTF = control.ss2tf(sysD)
            sysplant = control.StateSpace(A, B, C, D)
            openLoopTF = control.ss2tf(sysplant)
            # poles are zeros of return difference
            poles = control.zero(1. + compensatorTF * openLoopTF)
            for p in poles:
                polePresent = any([
                    np.isclose(np.complex(p), np.complex(pt))
                    for pt in np.hstack([desiredPolesCtrl, desiredPolesObsv])
                ])
                self.assertTrue(polePresent)
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')
Ejemplo n.º 11
0
def question1(Gpr, plot=True):
    print(spacer + "Question 1" + spacer)
    # 1. POLES AND ZEROS
    poles = ct.pole(Gpr)
    zeros = ct.zero(Gpr)
    print("\t Poles of the system are {}, and zeroes are {}".format(
        poles, zeros))

    # 2. PZ MAP
    H = 1
    OLTF = Gpr * H

    plt.figure("Q1 - PZ map")
    ct.pzmap(OLTF)

    if plot: plt.show
    # 3. STABILITY
    stable = True
    for pole in poles:
        if (pole > 0): stable = False

    temp = "unstable"
    if (stable): temp = "stable"
    print("\t Since {} are the poles, the system is {}".format(poles, temp))

    # 4. STEP RESPONSE
    t, c = ct.step_response(OLTF)
    end_value = c[c.size - 1]

    print("\t The end value of the OL step_response is {}".format(end_value))

    plt.figure("Q1 - Step response")
    plt.plot(t, c)

    # plot asymptote
    x_coordinates = [t[0], t[t.size - 1]]
    y_coordinates = [end_value, end_value]
    plt.plot(x_coordinates, y_coordinates)

    if plot: plt.show()

    return OLTF
Ejemplo n.º 12
0
def stabilityRange(tfD, tfPlant, gain):
    """
    numerically evaluate a range of gains, k, to see if the closed-loop system (k*tfD*tfPlant) / (1 + k*tfD*tfPlant)

    Inputs:
        tfD (control.TransferFunction) - compensator transfer function
        tfPlant (control.TransferFunction) - open loop system transfer function
        gain (numpy matrix/array, type=real) - range of gains to check

    Returns:
        tuple(min gain, max gain) defining stability interval if such an interval could be found, `None` otherwise

    Raises:
    """
    stable = np.zeros_like(gain)
    for i, _k in enumerate(gain):
        rz = np.real(control.zero(1. + (_k * tfD) * tfPlant))
        #print(rz.size)
        if rz.size > 0 and np.max(rz) < 0:
            stable[i] = 1.
    if len(gain[stable > 0]) > 1:
        return (gain[stable > 0][0], gain[stable > 0][-1])
    return None
Ejemplo n.º 13
0
	def time (tf, method = 'step', plot = False):
	    print "==================================================================";
	    print "Poles:   ", ctrl.pole (tf);
            print "Zeros:   ", ctrl.zero (tf);
	    dc = ctrl.dcgain (tf);

	    print "DC gain: ", dc;
	    if (method == 'step'):
	       t, y = ctrl.step_response (tf);
	    if (method == 'impulse'):
	       t, y = ctrl.impulse_response (tf);
 
	    ys = filter (lambda l: l >= 0.98 * dc, y);
            i = np.ndarray.tolist(y).index (min (ys));
            print "Ts: ", t[i];
	    print "Overshoot: ", (max (y) / dc) - 1;	
	    i = np.ndarray.tolist(y).index (max (y));
	    print "Tr: ", t[i];
	
	    if (plot == True):
		p = Plotter ({'grid' : True});
		p.plot ([(t, y)]);

            return t, y
Ejemplo n.º 14
0
P2 = 100e3
P3 = 500e3
A0 = 1e3
G = A0/((s/P1+1)*(s/P2+1)*(s/P3+1))


k =1
# Sistema realimentado
H = G/(1+k*G)
# Muestro ganancia lazo cerrado para comprobar resultado
print(H)
#Separo en parte real e imaginaria de los polos y ceros a lazo cerrado para hacer diagrama de polos y ceros
x_polos = ctl.pole(H).real
y_polos = ctl.pole(H).imag

x_zeros = ctl.zero(H).real
y_zeros = ctl.zero(H).imag

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_polos,y_polos,marker="x")
# ax.scatter(x_zeros, y_zeros, marker="o")
ax.set_xlabel('sigma')
ax.set_ylabel('jw')
ax.set_title("Polos de la transferencia a lazo cerrado")

# Hago la respuesta al escalón
Tau_dominante = 1/min(abs(x_polos))
#El tau dominante es la inversa del polo más cerca del eje imaginario
t_resp = 4* Tau_dominante
tvec = np.linspace(0,t_resp,5000) #Vector de tiempos de 5k puntos de 0 a 4 veces el tau dominante
Ejemplo n.º 15
0
import control as co
import numpy as np
import matplotlib.pyplot as plt

G1 = co.tf(
    [2, 5],
    [1, 2, 3])  # 2s + 5 / s^2 + 2s + 3 --- Provided only the coeficients

G2 = 5 * co.tf(np.poly([-2, -5]), np.poly(
    [-4, -5, -9]))  # Provided the 'zeros' and the 'poles' of the function

# Algebrism is supported
G3 = G1 + G2
G4 = G1 * G2
G5 = G1 / G2
G6 = G1 - G2
G7 = co.feedback(G1, G2)

# Minimum Realization (Pole-Zero Cancellation)
co.minreal(G2)

# TF Properties
print(co.dcgain(G6))  # DC Gain
print(co.pole(G6))  # Pole for G6
print(co.zero(G6))  # Zero for G6
Ejemplo n.º 16
0
def _nq_serial_decomposition(system: "IdealSystem",
                             q: StaticQuantizer,
                             verbose: bool) -> Tuple["DynamicQuantizer", float]:
    """
    Finds the stable and optimal dynamic quantizer for `system`
    using serial decomposition[1]_.

    Parameters
    ----------
    system : IdealSystem
    q : StaticQuantizer
    T : int
    gain_wv : float
    verbose : bool
    dim : int

    Returns
    -------
    (Q, E) : Tuple[DynamicQuantizer, float]
    """
    if verbose:
        print("Trying to calculate quantizer using serial system decomposition...")
    tf = system.P.tf1
    zeros_ = _ctrl.zero(tf)
    poles = _ctrl.pole(tf)

    unstable_zeros = [zero for zero in zeros_ if abs(zero) > 1]

    z = _ctrl.TransferFunction.z
    z.dt = tf.dt

    if len(unstable_zeros) == 0:
        n_time_delay = len([p for p in poles if p == 0])  # count pole-zero
        G = 1 / z**n_time_delay
        F = tf / G
        F_ss = _ctrl.tf2ss(F)
        B_F = matrix(F_ss.B)
        C_F = matrix(F_ss.C)

        E = abs(C_F @ B_F)[0, 0] * q.delta
    elif len(unstable_zeros) == 1:
        i = len(poles) - len(zeros_)  # relative order
        if i < 1:
            return None, inf
        a = unstable_zeros[0]
        G = (z - a) / z**i
        F = _ctrl.minreal(tf / G, verbose=False)
        F_ss = _ctrl.tf2ss(F)
        B_F = matrix(F_ss.B)
        C_F = matrix(F_ss.C)

        E = (1 + abs(a)) * abs(C_F @ B_F)[0, 0] * q.delta
    else:
        return None, inf

    A_F = matrix(F_ss.A)
    D_F = matrix(F_ss.D)

    # check
    if (C_F @ B_F)[0, 0] == 0:
        if verbose:
            print("CF @ BF == 0 became true. Couldn't calculate by using serial system decomposition.")
        return None, inf
    if D_F[0, 0] != 0:
        if verbose:
            print("DF == 0 became true. Couldn't calculate by using serial system decomposition.")
        return None, inf
    Q = DynamicQuantizer(
        A=A_F,
        B=B_F,
        C=- 1 / (C_F @ B_F)[0, 0] * C_F @ A_F,
        q=q
    )
    if verbose:
        print("Success!")
    return Q, E
Ejemplo n.º 17
0
import control as co
import numpy as np
import matplotlib.pyplot as plt

G1 = co.tf([2,5],[1,2,3]) # 2s + 5 / s^2 + 2s + 3 --- Provided only the coeficients

G2 = 5*co.tf(np.poly([-2,-5]), np.poly([-4,-5,-9])) # Provided the 'zeros' and the 'poles' of the function

# Algebrism is supported
G3 = G1+G2
G4 = G1*G2
G5 = G1/G2
G6 = G1-G2
G7 = co.feedback(G1,G2)

# Minimum Realization (Pole-Zero Cancellation)
co.minreal(G2)

# TF Properties
print(G1)
print('DC Gain: '+ str(co.dcgain(G1)))      # DC Gain
print('Pole: ' + str(co.pole(G1)))          # Pole for G6
print('Zero: ' + str(co.zero(G1)))          # Zero for G6

Ejemplo n.º 18
0
def pid_with_root_placing(g: Union[sp.Expr, ct.TransferFunction],
                          po: float,
                          ts: float,
                          report: bool = False) -> ct.TransferFunction:
    """
    Function to create a PID controller based on root locus method,
    the controller is the form: Kc*(s+b)^2/s equivalent to Kp + Ki/s + Kd*s
    ---
    design params example
    ts = 11.5  # 11.5 seg
    po = 0.5  # 0.5%
    :param g: Your plant transfer function
    :param po: Percentage Overshoot
    :param ts: Time Settling
    :param report: If you want to print a report step by step
    :return: a TransferFunction controller
    """
    s = sp.var("s")

    if isinstance(g, ct.TransferFunction):
        sys = g
    else:
        sys = core.symbolic_transfer_function(g)

    psi, wn = core.from_quality_to_psi_wn(po, ts)
    if report:
        print("psi=%.2f | wn=%.2f\n" % (psi, wn))

    pds = core.construct_poles(psi, wn)

    pd = pds[0]  # util pole in the (Re-, Im+) plane
    if report:
        print("desired pole: %.2f + %.2fi" % (pd.real, pd.imag))

    # finding b with the angle condition
    poles_angles = []
    for pole in [
            *ct.pole(sys), 0
    ]:  # for each pole and added the pole generated for the PID integrator
        angle = np.angle(pd - pole) * 180 / np.pi
        if angle < 0:
            angle = 360 + angle
        poles_angles.append(angle)

    zeros_angles = []
    for zero in ct.zero(sys):  # for each pole
        angle = np.angle(pd - zero) * 180 / np.pi
        if angle < 0:
            angle = 360 + angle
        zeros_angles.append(angle)

    b_angle = -180 - (sum(zeros_angles) - sum(poles_angles))
    b_angle = b_angle / 2  # because a == b in the PID controller form

    if report:
        print("positioned pole angle: %.2f" % b_angle)

    dist = pd.imag / np.tan(b_angle * np.pi / 180)
    b = pd.real - dist  # finally, we have b

    if report:
        print("found 'b' constant = %.2f" % b)
        print("a = b, then a = %.2f too" % b)

    # finding Kc with module condition
    poles_dists = []
    for pole in [
            *ct.pole(sys), 0
    ]:  # for each pole and added the pole generated for the PID integrator
        poles_dists.append(np.abs(pd - pole))

    zeros_dists = []
    for zero in [
            *ct.zero(sys), b, b
    ]:  # for each pole added with our new zeros (from PID) calculated before
        zeros_dists.append(np.abs(pd - zero))

    k = sys.num[0][0][-1]  # assuming the basic form of a SISO system
    kc = np.prod(poles_dists) / k / np.prod(zeros_dists)

    if report:
        print("found 'kc' constant = %.2f" % kc)

    # defining PID constants
    kp = -2 * kc * b
    ki = kc * b**2
    kd = kc

    if report:
        print("controller = %.2f * (s+%.2f)^2 / s" % (kc, b))
        print("pid form = %.2f + %.2f/s + %.2f*s" % (kp, ki, kd))

    c = kp + ki / s + kd * s
    pid = core.symbolic_transfer_function(c)

    return pid
Ejemplo n.º 19
0
import control as co
import matplotlib.pyplot as plt

s = co.tf('s')
g = (s + 4) / (7 * s**2 + 3 * s - 1)

g_poles = co.pole(g)
g_zeros = co.zero(g)

print('poles')
for elem in g_poles:  # print poles as a column vector for convenience
    print(f'{elem: .2f}')  # Two floating points per print

print('zeros')
for elem in g_zeros:
    print(f'{elem: .2f}')

g_map = co.pzmap(g, plot=True)
plt.show()
Ejemplo n.º 20
0
# Função de transferência do sistema 
numG = np.array([25])
denG = np.array([1, 5, 0])
Ls = ctl.tf(numG, denG)
print("L(s) = ", Ls)

# malha de realimentação
numH = np.array([1])
denH = np.array([1])
Hs = ctl.tf(numH, denH)
print("H(s) = ", Hs)

# Função de transferência de malha fechada
Ts = ctl.feedback(ctl.series(Ls, 1), Hs, sign=-1)
print("Função de transferência do sistema em malha fechada", Ts)
print("Zeros: ", ctl.zero(Ts))
print("Polos: ", ctl.pole(Ts))

# Calculo da Resposta ao degrau
Tsim = 3 
T, yout = ctl.step_response(Ts, Tsim)
infomation = ctl.step_info(Ts)
print("Informações: ", infomation)

# Calcular o degrau unitário
T2 = np.linspace(-1, Tsim, 1000)
degrau = np.ones_like(T2)
degrau[T2 < 0] = 0

#plotar os resultados
plt.plot(T, yout, 'k-')
Ejemplo n.º 21
0
PI = co.tf(np.poly(pid_zeros), np.poly(pid_poles))
print(G)
print(PI)

Gcl = co.feedback(0.0001 * G * PI)
co.root_locus(Gcl, Plot=True, grid=False)
Gcl = Gcl.minreal(tol=0.01)
print(Gcl)
#co.root_locus(Gcl, Plot=True, grid=False)

PI = kC * PI
Gcl = co.feedback(G * PI)
Gcl = Gcl.minreal(tol=0.01)
print(Gcl)
print(co.pole(Gcl))
print(co.zero(Gcl))

poles_and_zeros = np.append(np.append(np.append(zeros, poles), s), np.conj(s))
ymin = np.min(np.imag(poles_and_zeros)) - 2
ymax = np.max(np.imag(poles_and_zeros)) + 2
xmin = np.min(np.real(poles_and_zeros)) - 2
xmax = np.max(np.real(poles_and_zeros)) + 2
plt.ylim(ymin, ymax)
plt.xlim(xmin, xmax)

for root in co.pole(Gcl):
    plt.plot(np.real(root), np.imag(root), color='red', marker='*')
    plt.text(np.real(root) + 0.1,
             np.imag(root) + (ymax - ymin) / 20 *
             (1 if np.imag(root) > 0 else -1),
             f'{root:.2f}',
Ejemplo n.º 22
0
def Controller(k):
    global alfa,beta
    N = [k,k*alfa,k*beta]
    D = [1,0]
    C = ctl.tf(N,D)
    zeros = np.roots(N)
    poles = np.roots(D)
    return C,zeros,poles

##DEFINE THE PLANT
G = ctl.tf([1],[L*((M+m)-m),0,-(M+m)*g])

##PLOT POLES AND ZEROS OF PLANT AND CONTROLLER
open_poles = ctl.pole(G)
open_zeros = ctl.zero(G)
plt.plot(np.real(open_poles),np.imag(open_poles),'gx',label='Plant Open Loop Poles',markersize=15)
plt.plot(np.real(open_zeros),np.imag(open_zeros),'go',label='Plant Zeros',markersize=10)
C,zeros,poles = Controller(1)
plt.plot(np.real(zeros),np.imag(zeros),'ro',label='Control Zeros',markersize=10)
plt.plot(np.real(poles),np.imag(poles),'rx',label='Control Poles',markersize=15)

###LOOP ON K TO MAKE LOCUS
k_vec = np.linspace(0,1000,1000)
for k in k_vec:
    #print(k)
    C,zeros,poles = Controller(k)
    GCL = C*G/(1+C*G)
    poles = ctl.pole(GCL)
    plt.plot(np.real(poles),np.imag(poles),'b*')
plt.legend()
Ejemplo n.º 23
0
import control
import matplotlib.pyplot as plt
import numpy as np


num = [24]
den = [1 , 17 , 32 , 30]

sys = control.TransferFunction(num,den)



# You can quickly control this by typing built-in magic commands in Spyder's IPython console, which I find faster than picking these from the preferences menu. Changes take immediate effect, without needing to restart Spyder or the kernel.
# To switch to "automatic" (i.e. interactive) plots, type:
# Escribir en la consola!         %matplotlib auto
# Escribir en la consola!         %matplotlib inline    para escribir en la consola

control.bode_plot(sys)
print(control.pole(sys))
print(control.zero(sys))
control.pzmap(sys)

t, y = control.step_response(sys)
plt.figure(3)
plt.plot(t, y, 'r')
plt.ylabel('Xp(t)')
plt.xlabel('Xin(t)')

print(control.tf2ss(sys))
Ejemplo n.º 24
0
    plt.axvline(-4 / TS, color='r', linestyle='--')


s = co.tf('s')

g = (s + 1) / ((s - 1) * (s - 4))
h1 = 1
h2 = 1 / (s - 1)

#b)
k = 60
gf = co.feedback(
    k * pd_comp(-4.4) * g, h2, -1
)  # υπολογίζω τους πόλου και τα μηδενικά του κλειστού συστήματος με Κ = 60 και feedback=h2
poles = co.pole(gf)
zeros = co.zero(gf)
print(f"poles: {poles}")
print(f"zeros: {zeros}")

plt.figure(1)
co.root_locus(
    pd_comp(-4.4) * g * h2,
    grid=False)  # σχεδιάζω την γραφική παράστασή μου με pd_compensator
plot_ts(2)
plt.xlim(-15, 5)

plt.plot(poles.real, poles.imag, 'rx')

t = np.linspace(0, 3, 1000)
t1, yout = co.step_response(gf, t)
step_info(t1, yout)
Ejemplo n.º 25
0
num = [2.5]
den = [1, 2, 0.5]

G = cl.TransferFunction(num, den)  # create Transfer Function
H = cl.TransferFunction(1, 1)
PI = cl.TransferFunction([Kp, Ki], [1, 0])
print(PID)

F = cl.series(PI, G)
sys = cl.feedback(F, H)
# I = cl.feedback(G, H)
# F = cl.series(PI, I)

print(cl.pole(G))  #print pole
print(cl.zero(G))  #print zero

T = np.arange(0, 40, 0.05)
# create bode plot
# mag, phase, w = cl.bode(sys)

# plot step response
#T, yout = cl.step_response(I)
#T, yout, xout = cl.forced_response(I, T, None, 1)
#plt.plot(T, yout)

# sine wave & square wave for generating reference signals

amplitude = np.sin(T)
u = signal.square(0.1 * np.pi * T)
plt.plot(T, u)
Ejemplo n.º 26
0
c = (s + 3) / (s + 4)
e = 1 / (s * ((s**2) + 1))

acp = co.parallel(c, a)
bap = co.parallel(b, a)
acbas = co.series(acp, bap)
acbaef = co.feedback(acbas, e, +1)

print(acbaef)

g_poles = co.pole(acbaef)
print("G poles")
for elem in g_poles:
    print(f'{elem: .2f}')

g_zeros = co.zero(acbaef)
print("G zeros")
for elem in g_zeros:
    print(f'{elem: .2f}')

g1_map = co.pzmap(acbaef, plot=True)

t = np.linspace(0, 25, 100)
t1, stp = co.step_response(acbaef, t)
t2, imp = co.impulse_response(acbaef, t)  # Warning for infinite impulse at t=0

plt.figure(2)
plt.plot(t1, stp)
plt.title("Step Response")
plt.ylabel("Amplitude")
plt.xlabel("Time")
Ejemplo n.º 27
0
s = co.tf('s')
g1 = (s + 2) / (5 * s**3 + 7 * s - 3)
g2 = 1 / ((s**2 - 3 * s + 4) * (s + 8))

g12s = co.series(g1, g2)
g12p = co.parallel(g1, g2)
g12f = co.feedback(g1, g2, -1)
print(g12s, g12p, g12f)

# G1(s)
g1_poles = co.pole(g1)
print("g1 poles")
for elem in g1_poles:
    print(f'{elem: .2f}')

g1_zeros = co.zero(g1)
print("g1 zero")
for elem in g1_zeros:
    print(f'{elem: .2f}')

# G2(s)
g2_poles = co.pole(g2)
print("g2 poles")
for elem in g2_poles:
    print(f'{elem: .2f}')

g2_zeros = co.zero(g2)
print("g2 zero")
for elem in g2_zeros:
    print(f'{elem: .2f}')