def graficado(valor_ajustado_de_la_deslizadera_del_tiempo, tamaño_impulso,
              tamaño_escalon, tamaño_rampa, boton_pulsado, G0):

    fig.clf()

    retardo = eval(input_del_retardo_en_la_ventana.get())

    if boton_pulsado == 'Impulso':
        t, y = control.impulse_response(
            G0 * tamaño_impulso,
            T=(valor_ajustado_de_la_deslizadera_del_tiempo))
    if boton_pulsado == 'Escalon':
        t, y = control.step_response(
            G0 * tamaño_escalon,
            T=(valor_ajustado_de_la_deslizadera_del_tiempo))
    if boton_pulsado == 'Rampa':
        t, y = control.step_response(
            G0 * tamaño_rampa / s,
            T=(valor_ajustado_de_la_deslizadera_del_tiempo))
    if boton_pulsado == 'Arbitraria':
        t, y, xout = control.forced_response(G0,
                                             T=(t_experimental),
                                             U=(u_experimental))

    t_a_dibujar, y_a_dibujar = ajusta_el_retardo_segun_el_input_de_la_ventana(
        t, y, retardo)

    fig.add_subplot(111).plot(t_a_dibujar, y_a_dibujar)
    canvas.draw()
Пример #2
0
def pidplot1(num, den, kp, ki, kd):
    G = control.tf(num, den)
    if ki != 0:
        g2 = control.tf([kd, kp, ki], [1, 0])
    else:
        g2 = control.tf([kd, kp], [1])
    k = control.series(G, g2)
    v = control.feedback(k, 1)
    t1, y1 = control.step_response(G)
    t2, y2 = control.step_response(v)
    plt.plot(t2, y2, 'r', linewidth=1, label='G(s) with PID control')
    plt.grid(True)
    s = '(Kp=' + str(kp) + ',Ki=' + str(ki) + ',Kd=' + str(kd) + ')'
    plt.title('Time response of G(s) with PID control' + s)
    plt.xlabel('Time(sec)')
    plt.ylabel('Amplitude')
    if not os.path.isdir('static'):
        os.mkdir('static')
    else:
        # Remove old plot files
        for filename in glob.glob(
                os.path.join('static', 'pidcontrol', 'pidc1.png')):
            os.remove(filename)

    pidc1 = os.path.join('static', 'pidcontrol', 'pidc1.png')
    plt.savefig(pidc1)
    plt.clf()
    plt.cla()
    plt.close()
    return pidc1
Пример #3
0
def Controlador(X):

    #Atribuição dos paramentros Kp, Ki e Kd
    Kp = Kpi + X[0] / 100
    Ki = Kii + X[1] / 100
    Kd = Kdi + X[2] / 100

    #Função Transferência dos termos do controlador
    P = Kp
    I = tf(Ki, [1, 0])
    D = tf([Kd, 0], [0.1 * Kd, 1])
    #União dos blocos PID
    C = parallel(P, I, D)

    # Função Transferência com o Controlador
    F = series(C, G)

    # Penalidade para o valor do sinal de Entrada na planta
    # ou seja penalidade para o sinal de Controle alto
    tc = feedback(C, G)
    _, yc = step_response(tc, time)
    if max(yc) > maxcontrolador:
        #SE1 = np.square(np.subtract(1,yc))
        ISE = tdiv + max(yc)
    else:
        # Realizando a Integral do erro quadrado
        t1 = feedback(F, 1)
        _, y1 = step_response(t1, time)
        SE = np.square(np.subtract(1, y1))
        ISE = np.sum(SE)

    return (ISE)
Пример #4
0
def test_response_copy():
    # Generate some initial data to use
    sys_siso = ct.rss(4, 1, 1)
    response_siso = ct.step_response(sys_siso)
    siso_ntimes = response_siso.time.size

    sys_mimo = ct.rss(4, 2, 1)
    response_mimo = ct.step_response(sys_mimo)
    mimo_ntimes = response_mimo.time.size

    # Transpose
    response_mimo_transpose = response_mimo(transpose=True)
    assert response_mimo.outputs.shape == (2, 1, mimo_ntimes)
    assert response_mimo_transpose.outputs.shape == (mimo_ntimes, 2, 1)
    assert response_mimo.states.shape == (4, 1, mimo_ntimes)
    assert response_mimo_transpose.states.shape == (mimo_ntimes, 4, 1)

    # Squeeze
    response_siso_as_mimo = response_siso(squeeze=False)
    assert response_siso_as_mimo.outputs.shape == (1, 1, siso_ntimes)
    assert response_siso_as_mimo.states.shape == (4, 1, siso_ntimes)
    assert response_siso_as_mimo._legacy_states.shape == (4, siso_ntimes)

    response_mimo_squeezed = response_mimo(squeeze=True)
    assert response_mimo_squeezed.outputs.shape == (2, mimo_ntimes)
    assert response_mimo_squeezed.states.shape == (4, mimo_ntimes)
    assert response_mimo_squeezed._legacy_states.shape == (4, 1, mimo_ntimes)

    # Squeeze and transpose
    response_mimo_sqtr = response_mimo(squeeze=True, transpose=True)
    assert response_mimo_sqtr.outputs.shape == (mimo_ntimes, 2)
    assert response_mimo_sqtr.states.shape == (mimo_ntimes, 4)
    assert response_mimo_sqtr._legacy_states.shape == (mimo_ntimes, 4, 1)

    # Return_x
    t, y = response_mimo
    t, y = response_mimo()
    t, y, x = response_mimo(return_x=True)
    with pytest.raises(ValueError, match="too many"):
        t, y = response_mimo(return_x=True)
    with pytest.raises(ValueError, match="not enough"):
        t, y, x = response_mimo

    # Labels
    assert response_mimo.output_labels is None
    assert response_mimo.state_labels is None
    assert response_mimo.input_labels is None
    response = response_mimo(
        output_labels=['y1', 'y2'], input_labels='u',
        state_labels=["x[%d]" % i for i in range(4)])
    assert response.output_labels == ['y1', 'y2']
    assert response.state_labels == ['x[0]', 'x[1]', 'x[2]', 'x[3]']
    assert response.input_labels == ['u']

    # Unknown keyword
    with pytest.raises(ValueError, match="Unknown parameter(s)*"):
        response_bad_kw = response_mimo(input=0)
Пример #5
0
    def testSimulation(self):
        T = range(100)
        U = np.sin(T)

        # For now, just check calling syntax
        # TODO: add checks on output of simulations
        tout, yout = step_response(self.siso_ss1d)
        tout, yout = step_response(self.siso_ss1d, T)
        tout, yout = impulse_response(self.siso_ss1d, T)
        tout, yout = impulse_response(self.siso_ss1d)
        tout, yout, xout = forced_response(self.siso_ss1d, T, U, 0)
        tout, yout, xout = forced_response(self.siso_ss2d, T, U, 0)
        tout, yout, xout = forced_response(self.siso_ss3d, T, U, 0)
Пример #6
0
    def test_div(self):

        fb_sys = self.sys1 / (1 + self.sys1 * self.sys2)
        fb_m = self.m1 / self.m2
        t, y2 = ps.step_response(fb_m)
        _, y1 = ctrl.step_response(fb_sys, t)
        self.assertTrue(np.allclose(y1, y2, rtol=1e-2), "feedback is broken")
        fb_sys = ctrl.feedback(self.sys1, 1)
        fb_m = self.m1 / 1
        t, y2 = ps.step_response(fb_m)
        _, y1 = ctrl.step_response(fb_sys, t)
        self.assertTrue(np.allclose(y1, y2, rtol=1e1), "scalar feedback is"
                        "broken")
def analyze_sys(sys,H):
    Go = sys*H
    Gc = control.feedback(Go)
    control.root_locus(Go)
    
    plt.figure()
    plt.title('system')
    t1,x1 = control.step_response(sys)
    plt.plot(t1,x1)
    
    plt.figure()
    plt.title('controlled system w/ step response')
    t2,x2 = control.step_response(Gc)
    print(x2)
    plt.plot(t2,x2)
Пример #8
0
def pt1(smooth, time):
    smoothed_df     = pd.concat([pd.DataFrame(smooth, columns = ['smoothed']), \
                                 pd.DataFrame(time, columns   = ['time'])], axis = 1)
    steady_state = smooth[-1]
    #last element of the smoothed data is passed as steady state value
    standard_output = steady_state * (1 - np.exp(-1))
    #case when t = time_constant in the eqn.
    #############################################################################
    #       standard_output = steady_state * (1 - e ^ (−t / time_constant))     #
    #############################################################################
    delay = smoothed_df.time[smoothed_df.smoothed < 0.02].values[-1]
    #returns the time at which the step change occurs i.e a transition from 0 to some value.
    #Values lesser than 0.02 were treatred as zero.
    time_constant = smoothed_df.time[smoothed_df.index == abs(smoothed_df.smoothed - standard_output)\
                                     .sort_values().index[0]].values[0]
    #derived from the equation of standard_output
    tf_pt1 = con.tf(steady_state, [time_constant, 1])
    numerator, denominator = con.pade(delay, 1)
    delay_tf_pt1 = con.tf(numerator, denominator)
    t_pt1, yout_pt1 = con.step_response(tf_pt1 * delay_tf_pt1)
    #first order transfer function is given by
    ###############################################################################
    #                                  steady_state * (e ^ - (delay * s))         #
    #    transfer_function(s) =       ------------------------------------        #
    #                                       (time_constant * s + 1 )              #
    ###############################################################################
    return tf_pt1 * delay_tf_pt1, yout_pt1, t_pt1, delay, time_constant, steady_state, tf_pt1
Пример #9
0
    def test_import_export(self):

        sys = ctrl.tf([1], [100, 1])
        sim_duration = 2000
        time = np.zeros(sim_duration)
        i = 0
        while (i < sim_duration):
            time[i] = i
            i += 1
        _, output = ctrl.step_response(sys, time)
        m = ps.FsrModel(output, t=time)
        # testing our model with a test signal
        test_sgnl_len = int(2500)
        u = np.zeros(test_sgnl_len)
        for i in range(test_sgnl_len):
            u[i] = 1
        time = np.zeros(test_sgnl_len)
        for i in range(test_sgnl_len):
            time[i] = i
        _, comp, _ = ctrl.forced_response(sys, time, u)
        # 'rb' and 'wb' to avoid problems under Windows!
        with open("temp", "w") as fh:
            ps.export_csv(m, fh)
        with open("temp", "r") as fh:
            m = ps.import_csv(fh)
        os.remove("temp")
        _, y = ps.forced_response(m, time, u)
        self.assertTrue(np.allclose(y, comp, rtol=1e-2), "import/export broke")
Пример #10
0
def pidplot(nlg,dlg,nlh,dlh):
    G = control.tf(nlg,dlg)
    s1="("
    s2="("
    s=str(G)
    s=s.split('\n')
    s[1]=s[1].strip()
    s[3]=s[3].strip()
    s1=s1+s[1]+')'
    s2=s2+s[3]+')'
    t1,y1 =control.step_response(G)
    plt.plot(t1,y1,'b',linewidth=1,label='G(s)')
    plt.grid(True)
    plt.title('Time response of G(s)='+(s1)+'/'+(s2))
    plt.xlabel('Time(sec)')
    plt.ylabel('Amplitude')
    if not os.path.isdir('static'):
        os.mkdir('static')
    else:
        # Remove old plot files
        for filename in glob.glob(os.path.join('static', 'Feedback','pidc.png')):
            os.remove(filename)

    pidc=os.path.join('static', 'Feedback' ,'pidc.png')
    plt.savefig(pidc)
    plt.clf()
    plt.cla()
    plt.close()
    return pidc
Пример #11
0
    def plot_step(self, fig):
        if self.settings.is_step_default():
            t, y = control.step_response(self.tf)
        else:
            tmax = self.settings.get_step_time_max()
            step = self.settings.get_step_step()
            t = np.arange(0, tmax, step)
            _, y = control.step_response(self.tf, t)

        fig.clf()
        ax = fig.add_subplot(1, 1, 1)
        ax.plot(t, y)

        ax.set_xlabel('Time')
        ax.set_ylabel('Amplitude (s)')
        return fig
Пример #12
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()
Пример #13
0
def pidplot1(nlg, dlg, nlh, dlh):
    G = control.tf(nlg, dlg)
    H = control.tf(nlh, dlh)
    s = str(H)
    s1 = "("
    s2 = "("
    s = s.split('\n')
    s[1] = s[1].strip()
    s[3] = s[3].strip()
    s1 = s1 + s[1] + ')'
    s2 = s2 + s[3] + ')'
    v = control.feedback(G, H)
    t2, y2 = control.step_response(v)
    plt.plot(t2, y2, 'r', linewidth=1, label='G(s) with Feedback H(s)')
    plt.grid(True)
    plt.title('Time response of G(s) with feedback H(s)=G(s)/(1+G(s)H(s))')
    plt.xlabel('Time(sec)')
    plt.ylabel('Amplitude')
    if not os.path.isdir('static'):
        os.mkdir('static')
    else:
        # Remove old plot files
        for filename in glob.glob(
                os.path.join('static', 'Feedback', 'pidc1.png')):
            os.remove(filename)

    pidc1 = os.path.join('static', 'Feedback', 'pidc1.png')
    plt.savefig(pidc1)
    plt.clf()
    plt.cla()
    plt.close()
    return pidc1
Пример #14
0
def creation_example():
    """Example for creation of a FSR model with python-control."""

    # creating a step response for our model
    sys = ctrl.tf([1], [100, 1])
    sim_duration = 2000
    time = np.arange(sim_duration)
    _, output = ctrl.step_response(sys, time)
    # creating the model
    model = ps.FsrModel(output, t=time)
    # creating a test input signal
    u = np.ones(sim_duration)
    for i in range(len(u)):
        if i < 500:
            u[i] = 0.001 * i
    # getting response from our model
    t1, y1 = ps.forced_response(model, time, u)
    # simulating a reference with control
    t2, y2, _ = ctrl.forced_response(sys, time, u)
    # show everything
    ax = plt.subplot(111)
    plt.plot(t1, y1, label="Model response")
    plt.plot(t2, y2, label="Reference response")
    plt.plot(t1, u, label="Input signal")
    ax.legend()
    plt.title("pystrem example")
    plt.show()
    def Bode_Margin(sys, omega):
        w = omega
        mag, phaserad, w = ctrl.bode(sys, w)
        magdb = 20 * log(mag)
        phasedeg = phaserad * 180 / pi
        gm, pm, wg, wp = ctrl.margin(sys)

        a1 = f.add_subplot(221)
        a1.set_xscale("log")
        a1.plot(w, magdb)
        a1.plot(wp, 0, '.y')
        a1.text(wp, 0 + 25, "wc=%.2f" % wp)
        # a1.title = "Bode"
        # a1.ylabel = "Magnitude dB "
        # a1.xlabel = "Angular frequency"

        a2 = f.add_subplot(223)
        a2.set_xscale("log")
        a2.plot(w, phasedeg)
        a2.plot(wp, pm - 180, '.y')
        a2.text(wp, pm - 180 + 25, "phase=%.2f" % (pm - 180))
        # a2.ylabel = "Phase (degree) "
        # a2.xlabel = "Angular frequency"

        a3 = f.add_subplot(122)
        sysF = sys / (1 + sys)
        T = np.arange(0, 30, 0.5)
        T, yout = ctrl.step_response(sysF, T)
        a3.plot(T, yout)
        # a3.title = "step response"
        # a3.xlabel = "time"
        # a3.ylabel = "Magnitude"

        return wp, pm
Пример #16
0
    def test_response_transpose(self, nstate, nout, ninp, squeeze, ysh_in,
                                ysh_no, xsh_in):
        sys = ct.rss(nstate, nout, ninp)
        T = np.linspace(0, 1, 8)

        # Step response - input indexed
        t, y, x = ct.step_response(sys,
                                   T,
                                   transpose=True,
                                   return_x=True,
                                   squeeze=squeeze)
        assert t.shape == (T.size, )
        assert y.shape == ysh_in
        assert x.shape == xsh_in

        # Initial response - no input indexing
        t, y, x = ct.initial_response(sys,
                                      T,
                                      1,
                                      transpose=True,
                                      return_x=True,
                                      squeeze=squeeze)
        assert t.shape == (T.size, )
        assert y.shape == ysh_no
        assert x.shape == (T.size, sys.nstates)
Пример #17
0
    def calculating_params(self, populations):
        calculatedParams = []
        for population in populations:
            kp = population[0]
            ti = population[1]
            td = population[2]
            G = kp * control.tf([ti * td, ti, 1], [ti, 0])
            F = control.tf(1, [1, 6, 11, 6, 0])
            system = control.feedback(control.series(G, F), 1)

            t = []
            i = 0
            while i < 100:
                t.append(i)
                i += 0.01

            try:
                systemInfo = control.step_info(system)
            except IndexError:
                calculatedParams.append([10000000, 1, 100, 200])
                continue

            T, output = control.step_response(system, T=t)

            ISE = round(sum((output - 1)**2), 2)
            timeRise = round(systemInfo['RiseTime'], 2)
            timeSettle = round(systemInfo['SettlingTime'], 2)
            overshoot = round(systemInfo['Overshoot'], 2)
            calculatedParams.append([ISE, timeRise, timeSettle, overshoot])

        return calculatedParams
Пример #18
0
    def test_forced_response_legacy(self):
        # Define a system for testing
        sys = ct.rss(2, 1, 1)
        T = np.linspace(0, 10, 10)
        U = np.sin(T)
        """Make sure that legacy version of forced_response works"""
        ct.config.use_legacy_defaults("0.8.4")
        # forced_response returns x by default
        t, y = ct.step_response(sys, T)
        t, y, x = ct.forced_response(sys, T, U)

        ct.config.use_legacy_defaults("0.9.0")
        # forced_response returns input/output by default
        t, y = ct.step_response(sys, T)
        t, y = ct.forced_response(sys, T, U)
        t, y, x = ct.forced_response(sys, T, U, return_x=True)
Пример #19
0
def step(tf_list=[], N=100, T=None, name=None):

    data = []
    T_max = get_T_max(tf_list, T=T, N=N)

    for index, tf in enumerate(tf_list):
        if ctl.isctime(tf):
            T = np.linspace(0, T_max, N)
            line_shape = "linear"
        else:
            T = np.arange(0, T_max, tf.dt)
            line_shape = "hv"

        t, y = ctl.step_response(tf, T=T)
        tf_name = "tf {}".format(index + 1)
        data.append({
            "x": np.ravel(t),
            "y": np.ravel(y),
            "name": tf_name,
            "mode": "lines",
            "showlegend": False,
            "line_shape": line_shape
        })

    layout = default_layout("time (s)", "response", name)
    fig = go.Figure(data, layout=layout)
    return fig
Пример #20
0
def tr2(numG, denG, numH, denH):
    G = control.tf(numG, denG)
    H = control.tf(numH, denH)
    k = control.parallel(G, H)
    s1 = "("
    s2 = "("
    s = str(k)
    s = s.split('\n')
    s[1] = s[1].strip()
    s[3] = s[3].strip()
    s1 = s1 + s[1] + ')'
    s2 = s2 + s[3] + ')'
    t1, y1 = control.step_response(k)
    plt.plot(t1, y1, 'b', linewidth=1, label='G(s)')
    plt.grid(True)
    plt.title('Time response of Parallel Operation\n' + (s1) + '/' + (s2))
    plt.xlabel('Time(sec)')
    plt.ylabel('Amplitude')
    if not os.path.isdir('static'):
        os.mkdir('static')
    else:
        # Remove old plot files
        for filename in glob.glob(
                os.path.join('static', 'SeriesParallel', 'sp2.png')):
            os.remove(filename)

    sp2 = os.path.join('static', 'SeriesParallel', 'sp2.png')
    plt.savefig(sp2)
    plt.clf()
    plt.cla()
    plt.close()
    return sp2
Пример #21
0
def grstep(sys, T=None):
    """get step response graphically

    Usage
    =====
    grstep(sys)

    Inputs
    ------

    sys: system
    """
    if np.isscalar(T):
        if sys.isctime():
            T = np.linspace(0, T)
        else:
            T = np.arange(0, T, sys.dt)

    t, y = ct.step_response(sys, T)

    if len(y.shape) == 2:
        N = y.shape[0]
        for n in range(0, N):
            plt.plot(t, y[n])
    else:
        plt.plot(t, y)
    plt.grid()
    plt.show()
Пример #22
0
def classic():
    # PI controller
    Kp = 1.5
    Ki = 30.
    
    P = tf([Kp], [1])
    I = tf([Ki], [1, 0])
    
    Gc = parallel(P, I)
    
    # Power convertor
    Gpc = synthesize_2pole_filter(50, 0.707)
    
    # Plant
    Gp = tf([50], [1, 0])
    
    # Sensor
    # если выбросить из петли становится лучше
    # "remove sensor lag"
    Gs = synthesize_1pole_filter(20)
    
    # Openloop
    Gol = series(series(Gc, Gpc), Gp)
    
    # Closed loop
    Gcl = feedback(Gol)
    
    ts, xs = step_response( Gcl )
    
    grid()
    plot(ts, xs)
Пример #23
0
    def execute(self):

        # Realimentando a malha
        sysFechada = con.feedback(self.sys, 1)

        # Resposta ao degrau
        [self.xout, self.yout] = con.step_response(sysFechada,
                                                   const.TEMPO_CALCULO)

        # "Alterando" amplitude do degrau
        self.yout = self.yout * const.SP

        # Pegando as informações sobre o sistema
        info = con.step_info(sysFechada, self.xout)

        # Pegando o valor de estado estacionário
        self.valorEstacionario = info['SteadyStateValue'] * const.SP

        # Ponto de acomodação
        self.tempo_acomodacao = info['SettlingTime']
        self.valor_acomodacao = accommodationPoint(self.yout,
                                                   self.valorEstacionario)

        # Overshoot
        self.overshootX = info['PeakTime']
        self.overshootY = info['Peak'] * const.SP
        self.overshoot = info['Overshoot']

        # Erro em regime permanente
        self.erroRegimePermanente = errorCalculate(const.SP,
                                                   self.valorEstacionario)
def f(X):  #F(Kp, Ki, Kd)
    #Obtendo as constantes a partir da entrada
    Kp = X[0]
    Ki = X[1]
    Kd = X[2]

    #Definindo as constantes do processo
    K = 2
    CT = 4

    s = ct.TransferFunction.s

    #Equação do sistema de Controle
    C = Kp + Ki / s + Kd * s

    #Equação do processo a ser controlado
    P = K / (CT * s + 1)

    #Fazendo a retroalimentação
    T = ct.TransferFunction.feedback(C * P, 1)

    tempo, resposta = ct.step_response(T)

    erro = [TARGET_VALUE - resp for resp in resposta]

    #Cálculo da integral de erro quadratico multiplicado pelo tempo
    # print(tempo)
    # print(erro)
    itse = np.sum(tempo * np.power(erro, 2))

    return itse
Пример #25
0
def assignment2(Kc=Kc, Ki=Ki):  #Kc has to be a list; Ki has to be a float

    # Defining the transfer functions
    sysgp = control.tf(4, [500, 2])  #Process
    sysgv = control.tf(2, [1, 10, 1])  #Valve
    sysgt = control.tf(2, 1)  # Sensor

    syspi_list = []
    # Loop to iterate among the different values of Kc
    for i in Kc:
        syspi = control.tf([i, i * Ki], [1, 0])
        syspi_list.append(syspi)

    # Plotting the figures with the different values of Kc
    plt.figure()
    for i in range(len(syspi_list)):
        #Defining the closed loop
        syslc = control.feedback(syspi_list[i] * sysgv * sysgp, sysgt)
        consig = 1 / 2  # The setpoint is 0.5, because the sensor
        # transfer function is equal to 2
        t, y = control.step_response(syslc, 200)
        error = np.abs(y - consig)  # The error while achieving the setpoint
        plt.plot(t, y, label=f'Kc= {Kc[i]:.2f}')
        # plt.plot(t, error, label=f'Error para Kc={Kc[i]:.2f}')
        plt.title(f'Ki= {Ki:.4f}')

    plt.legend()
    plt.xlabel('Time (s)')
    plt.ylabel('Value')
    plt.show()
    return syspi_list
Пример #26
0
    def execute(self):

        # Resposta ao degrau
        [self.xout, self.yout] = con.step_response(self.sys, const.TEMPO)

        # Pegando as informações do sistema
        info = con.step_info(self.sys, self.xout)

        # "Alterando" amplitude do degrau
        self.yout = self.yout * self.VALOR_ENTRADA

        # Pegando o valor de estado estacionário
        self.valorEstacionario = info['SteadyStateValue'] * self.VALOR_ENTRADA

        # Ponto de acomodação
        self.tempo_acomodacao = info['SettlingTime']
        self.valor_acomodacao = accommodationPoint(self.yout,
                                                   self.valorEstacionario)

        # Overshoot
        self.overshootX = info['PeakTime']
        self.overshootY = info['Peak'] * self.VALOR_ENTRADA
        self.overshoot = info['Overshoot']

        # Erro em regime permanente
        self.erroRegimePermanente = errorCalculate(self.VALOR_ENTRADA,
                                                   self.valorEstacionario)
Пример #27
0
def KpKi(sys):

    # Pegando os valores do OVERSHOOT e Tempo de acomodação desejados
    mp = const.OVERSHOOT
    ts = const.TS

    # Resposta ao degrau
    [xout, yout] = con.step_response(sys, const.TEMPO)

    # "Alterando" amplitude do degrau
    yout = yout * const.SP

    # Pegando as informações sobre o sistema
    info = con.step_info(sys, xout)

    # Pegando o valor de estado estacionário
    valorEstacionario = info['SteadyStateValue'] * const.SP

    # Calculando valor de K e tall
    k = K(const.SP, valorEstacionario)
    tal = tall(yout, valorEstacionario, const.TEMPO_AMOSTRAGEM)

    # Calculando valores de Kp e Ki
    kp, ki = calculateKpKi(mp, ts, k, tal)

    return kp, ki
Пример #28
0
def exercise_2():
    # get unknown step response
    t, y = sr1.unknown_step()

    # plot unknown step response
    plt.figure()
    plt.grid(True)
    plt.xlabel("$t$ in s")
    plt.ylabel("$y(t)$")
    plt.plot(t, y)

    # create system
    k_s = 1.38
    T = 1.1
    T_t = 2.2
    sys_2 = system_2(k_s, T, T_t)

    # plot system step response
    t = np.linspace(0, 50, 100)
    t, y = ctl.step_response(sys_2, t)
    plt.plot(t, y)

    # plot PID controlled system step response
    K_P = 1.2 * T / (k_s * T_t)
    K_I = 0.6 * T / (k_s * T_t**2)
    K_D = 0.6 * T / k_s
    t, y = sr1.unknown_step(K_P, K_I, K_D)
    plt.plot(t, y)

    # save plot
    plt.savefig("plots/step_response.png")
    plt.clf()
Пример #29
0
def pt2(smooth, time):
    def fourpoint(z):
        f1_zeta = 0.451465 + (0.066696 * z) + (0.013639 * z**2)
        f3_zeta = 0.800879 + (0.194550 * z) + (0.101784 * z**2)
        f6_zeta = 1.202664 + (0.288331 * z) + (0.530572 * z**2)
        f9_zeta = 1.941112 - (1.237235 * z) + (3.182373 * z**2)
        return f1_zeta, f3_zeta, f6_zeta, f9_zeta

    def method():
        #the second method from the article is adopted, as the response/data handled strictly follows this method.
        zeta = np.sqrt(
            (np.log(overshoot)**2) / ((np.pi**2) + (np.log(overshoot)**2)))

        f1_zeta, f3_zeta, f6_zeta, f9_zeta = fourpoint(zeta)

        time_constant = (t9 - t1) / (f9_zeta - f1_zeta)
        #delay        = t1 - time_constant*f1_zeta              #based on article.
        delay = smoothed_df.time[smoothed_df.smoothed < 0.02].values[-1]
        return zeta, time_constant, delay

    smoothed_df  = pd.concat([pd.DataFrame(smooth, columns = ['smoothed']), \
                              pd.DataFrame(time, columns = ['time'])], axis = 1)
    steady_state = smooth[-1]

    #ssn = steady state at n/10th instant of time
    ss1 = steady_state * 0.1
    ss3 = steady_state * 0.3
    ss6 = steady_state * 0.6
    ss9 = steady_state * 0.9

    #tn = time at n/10th instant
    t1 = smoothed_df.time[smoothed_df.index == abs(
        smoothed_df.smoothed - ss1).sort_values().index[0]].values[0]
    t3 = smoothed_df.time[smoothed_df.index == abs(
        smoothed_df.smoothed - ss3).sort_values().index[0]].values[0]
    t6 = smoothed_df.time[smoothed_df.index == abs(
        smoothed_df.smoothed - ss6).sort_values().index[0]].values[0]
    t9 = smoothed_df.time[smoothed_df.index == abs(
        smoothed_df.smoothed - ss9).sort_values().index[0]].values[0]

    peak = smoothed_df.smoothed.max()
    #returns the highest output in the response
    overshoot = (peak - steady_state) / steady_state
    #represented as Mp in article

    zeta, time_constant, delay = method()

    tf_pt2 = con.tf(steady_state,
                    [time_constant**2, 2 * zeta * time_constant, 1])
    n_2, d_2 = con.pade(delay, 1)
    delay_tf_pt2 = con.tf(n_2, d_2)
    t_pt2, yout_pt2 = con.step_response(tf_pt2 * delay_tf_pt2)
    #second order transfer function is given by
    ########################################################################################################
    #                                           steady_state * (e ^ - (delay * s))                         #
    #    transfer_function(s) =  ----------------------------------------------------------------------    #
    #                            ((time_constant ^ 2) * (s ^ 2)) + (2 * zeta * time_constant * s) + 1 )    #
    ########################################################################################################
    return tf_pt2 * delay_tf_pt2, yout_pt2, t_pt2, delay, time_constant, steady_state, zeta, tf_pt2
Пример #30
0
def plot_response(sys, T=None, U=0.0, impulse=True, step=True) -> None:
    if impulse:
        t, yout = control.impulse_response(sys, T=T, X0=U)
        plot_params(t, yout)
    if step:
        t, yout = control.step_response(sys, T=T, X0=U)
        plot_params(t, yout)
    return
Пример #31
0
def Q2_perfFCN(Kp, Ti, Td):
  G = Kp * tf([Ti * Td, Ti, 1.0], [Ti, 0])

  sys = feedback(series(G,F),1)
  res = step_response(sys, t)

  ISE = sum((val - 1)**2 for val in res[1])
  return (ISE,) + stepinfo(res)
Пример #32
0
    def test_IT2_forced_response(self):

        sys = ctrl.tf([100], [50, 1000, 150, 0])  # IT2
        _, o = ctrl.step_response(sys, self.time)
        m = ps.FsrModel(o, t=self.time, optimize=False)
        _, y = ps.forced_response(m, self.t, self.u)
        _, o, _ = ctrl.forced_response(sys, self.t, self.u)
        self.assertTrue(np.allclose(y, o, rtol=1e-2), "it2 response broke")
Пример #33
0
def analysis():
    """Plot open-loop responses for various inputs"""
    g = plant()

    t = np.linspace(0, 10, 101)
    _, yu1 = step_response(g, t, input=0)
    _, yu2 = step_response(g, t, input=1)

    yu1 = yu1
    yu2 = yu2

    # linear system, so scale and sum previous results to get the
    # [1,-1] response
    yuz = yu1 - yu2

    plt.figure(1)
    plt.subplot(1, 3, 1)
    plt.plot(t, yu1[0], label='$y_1$')
    plt.plot(t, yu1[1], label='$y_2$')
    plt.xlabel('time')
    plt.ylabel('output')
    plt.ylim([-1.1, 2.1])
    plt.legend()
    plt.title('o/l response\nto input [1,0]')

    plt.subplot(1, 3, 2)
    plt.plot(t, yu2[0], label='$y_1$')
    plt.plot(t, yu2[1], label='$y_2$')
    plt.xlabel('time')
    plt.ylabel('output')
    plt.ylim([-1.1, 2.1])
    plt.legend()
    plt.title('o/l response\nto input [0,1]')

    plt.subplot(1, 3, 3)
    plt.plot(t, yuz[0], label='$y_1$')
    plt.plot(t, yuz[1], label='$y_2$')
    plt.xlabel('time')
    plt.ylabel('output')
    plt.ylim([-1.1, 2.1])
    plt.legend()
    plt.title('o/l response\nto input [1,-1]')
Пример #34
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
Пример #35
0
def step_opposite(g, t):
    """reponse to step of [-1,1]"""
    _, yu1 = step_response(g, t, input=0)
    _, yu2 = step_response(g, t, input=1)
    return yu1 - yu2
Пример #36
0
    cls()

    Kt = 1.0
    Jt = 1.0  # [?]

    u1 = tf([Kt], [1])
    u2 = tf([1 / Jt], [1])

    # fixme: как добавить сигнал шума?
    u12 = series(u1, u2)
    u3 = tf([1], [1, 0])
    u4 = copy.deepcopy(u3)
    u34 = series(u3, u4)

    # похоже нельзя соединить аналоговую и дискретную
    u34_d0 = c2d(u3, Ts=0.5)
    u34_d = c2d(u3, Ts=0.5)
    print series(u34_d0, u34_d)

    u14 = series(u12, u34)

    print u14

    ts, xs = step_response(u14)

    # print (c2d(u14, Ts=0.5))

    plot(ts, xs)
    grid()
    show()
# #### additional code for comparision

A, B, C, D = get_linear_ct_model(theStateAdmin, sys_output)

# create a control system with the python-control-toolbox, see
# https://github.com/python-control/python-control
import control
cs = control.StateSpace(A, B, C, D)

# use default method (zero oder hold (zoh))
cs_dt = control.sample_system(cs, 0.05)


# calculate step-response for first input
__, yy_dt = control.step_response(cs_dt, T=tt, input=0)

# in the time-discrete case the result is shortened by one value. -> repeat the last one.
yy_dt = np.column_stack((yy_dt, yy_dt[:, -1]))


# __, yy_dt = control.step_response(cs,T=tt, input=0)


# #### end of additional code


if __name__ == "__main__":
    pl.plot(tt, bo[SUM1], "b-", lw=3, label="$y_1$ (pyblocksim)")
    pl.plot(tt, bo[SUM2], "r-", lw=3, label="$y_2$ (pyblocksim)")
    # +1 because the step_response starts the step at t=0

# Define the system to use in simulation - in transfer function form here
num = [2.*z*wn,wn**2];
den = [1,2.*z*wn,wn**2];

sys = control.tf(num,den);
       

# Set up simulation parameters
t = np.linspace(0,5,500)            # time for simulation, 0-5s with 500 points in-between



# run the simulation - utilize the built-in initial condition response function
[T,yout] = control.step_response(sys,t)

# Make the figure pretty, then plot the results
#   "pretty" parameters selected based on pdf output, not screen output
#   Many of these setting could also be made default by the .matplotlibrc file
fig = figure(figsize=(6,4))
ax = gca()
subplots_adjust(bottom=0.17,left=0.17,top=0.96,right=0.96)
setp(ax.get_ymajorticklabels(),family='CMU Serif',fontsize=18)
setp(ax.get_xmajorticklabels(),family='CMU Serif',fontsize=18)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.grid(True,linestyle=':',color='0.75')
ax.set_axisbelow(True)
    # 超调量
    print("Mp (%): ", (yout.max() / yout[-1] - 1) * 100)
    # 峰值时间
    print("Tp: ", t[numpy.argmax(yout)])
    # 上升时间
    print("Tr: ", t[next(i for i in range(0, len(yout) - 1) if yout[i] > yout[-1])])
    # 调整时间
    offset = 0.05 # 最大误差容许范围
    print("Ts: ", t[next(len(yout) - i for i in range(2, len(yout) - 1) if abs(yout[-i] / yout[-1] - 1) > offset)])

# 化简分母
S = sympy.symbols('S')
denominator = (S**2 + 0.6*S + 1) * (S**2 + 3*S + 9) * (S + 5)
denominator = denominator.expand() # 化简表达式
denominator = sympy.poly(denominator, S).all_coeffs() # 转成多项式 list
denominator = list(map(float, denominator)) # convert sympy.core.numbers.Float to float

numerator = [45.]
sys = control.matlab.tf(numerator, denominator)

# 阶跃
T, yout = control.step_response(sys)
step_info(T, yout)

# 绘图
plot(T, yout)
title("System Step Response")
xlabel("time / sec")
ylabel("response / value")
show()
Пример #40
0
plt.semilogx(omega, 20 * np.log10(s1mag.flat), label='$S_1$')
plt.semilogx(omega, 20 * np.log10(s2mag.flat), label='$S_2$')
# -1 in logspace is inverse
plt.semilogx(omega, -20 * np.log10(ws1mag.flat), label='$1/w_{P1}$')
plt.semilogx(omega, -20 * np.log10(ws2mag.flat), label='$1/w_{P2}$')

plt.ylim([-80, 10])
plt.xlim([1e-2, 1e2])
plt.xlabel('freq [rad/s]')
plt.ylabel('mag [dB]')
plt.legend()
plt.title('Sensitivity and sensitivity weighting frequency responses')

# time response
time = np.linspace(0, 3, 201)
_, y1 = step_response(t1, time)
_, y2 = step_response(t2, time)

# gd injects into the output (that is, g and gd are summed), and the
# closed loop mapping from output disturbance->output is S.
_, y1d = step_response(s1 * gd, time)
_, y2d = step_response(s2 * gd, time)

plt.figure(2)
plt.subplot(1, 2, 1)
plt.plot(time, y1, label='$y_1(t)$')
plt.plot(time, y2, label='$y_2(t)$')

plt.ylim([-0.1, 1.5])
plt.xlim([0, 3])
plt.xlabel('time [s]')
Пример #41
-5
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()