Beispiel #1
0
def Pole(W):
    con.pzmap(W)
    plt.plot()
    plt.grid(True)
    plt.show()
    print('Оценка по распределению корней:')
    Pol = con.pole(W)
    # print(Pol)
    P = []
    """ Показатель колебательности характеризует склонность системы к
    колебаниям: чем выше М, тем менее качественна система при прочих
    равных условиях. Считается допустимым, если 1,1 < М < 1,5.    """

    degreeovershoot_M = []
    for i in Pol:
        k = complex(i)
        if k.real != 0:
            P.append(k.real)
            m = k.imag / k.real
            degreeovershoot_M.append(m)
    a_min = max(P)
    t_reg = abs(1 / a_min)
    overshooting = math.exp(math.pi / max(degreeovershoot_M))
    psi = 1 - math.exp((-2) * math.pi / max(degreeovershoot_M))
    print("a_min= ", a_min)
    print("Время пп: ", t_reg, " c")
    print("Степень колебательности: ", max(degreeovershoot_M))
    print("Перерегулирование: ", overshooting)
    print("Степень затухания: ", psi)
Beispiel #2
0
    def full_analyze(self):
        """
        complex research definition
        :return:  keys for handle changing regulator quality
        """

        k = []

        print("\n", "*" * 40, "\n" "STEP RESPONCE:\n")
        k.extend(self.get_trans_func())

        print("\n", "*" * 40, "\n" "POLES ANALYZE:\n")

        poles, zeros = pzmap(self.w)
        if poles != []:
            k.extend(self.get_poles_analyze(poles))
        else:
            print("Корней нет!!!")

        print("\n", "*" * 40, "\n" "BODE FUNCTION:\n")
        k.extend(self.get_bode_func())

        return k
Beispiel #3
0
def pzmap(W):
    con.pzmap(W)
    plt.title("Расположение нулей на комплексной плоскости")
    plt.grid(True)
    plt.show()
 def testPZmap(self, siso, subsys, mplcleanup):
     """Call pzmap()"""
     # pzmap(siso.ss1);         not implemented
     # pzmap(siso.ss2);         not implemented
     pzmap(getattr(siso, subsys))
     pzmap(getattr(siso, subsys), plot=False)
Beispiel #5
0
# teta = 0.0 # np.arccos([eps])
# eps = np.cos(teta)
'''
################################################################################
#  Input - S (ex: s=-2.5 + 2j) para verificar se cruza a LGR
################################################################################
'''
# x_s = -2.5   # real
# y_s = 2   # complexo
# teta = np.arctan(np.abs(y_s)/np.abs(x_s))
# eps = np.cos(teta)

################################################################################
#  polos e zeros plotados
################################################################################
(p, z) = ctl.pzmap(G)
print('polos =', p)
print('zeros =', z)

################################################################################
#  Lugar geometrico das raizes (LGR)
################################################################################
rlist, klist = ctl.rlocus(G)  # rlist - lugar geometrico das raizes
# klist - ganhos correspondentes

# plotar linha baseada no LGR para achar interseção
real = []
im = []
try:
    for j in range(len(rlist)):
        real.append(rlist[j][ramo].real)
# Expansao em fracoes parciais
# caso nao haja multiplos polos:
#       B(s)       R(1)       R(2)             R(n)
#       ----  =  -------- + -------- + ... + -------- + K(s)
#       A(s)     s - P(1)   s - P(2)         s - P(n)
#
print('-------------')
print('EXPANSAO EM FRACOES PARCIAIS')
B = K1 * Km * Kg
A = [1, a + am, a * am, 0]
[R, P, K] = sc.signal.residue(B, A)
print('R =', R)
print('P =', P)
print('K =', K)
# Plot dos polos e zeros PZMAP
co.pzmap(Gtheta, grid=True)
# Resposta Transitoria
S = co.stepinfo(Gtheta)
print('-------------')
print('CARACTERISTICAS DA RESPOSTA TRANSITORIA DO SISTEMA')
print('tempo de subida tr = ', '%.2f' % S['RiseTime'], 'seg')
print('tempo de acomodacao ts = ', '%.2f' % S['SettlingTime'], 'seg')
print('maximo sobresinal Mp = ', S['Overshoot'])
print('valor de pico thetaomax = ', '%.2f' % S['Peak'])
print('instante de pico tp = ', '%.2f' % S['PeakTime'], 'seg')
print('valor de regime estacionario thetaoss = ',
      '%.2f' % S['SteadyStateValue'])
# Resposta a degrau da planta
plt.figure(2)
thetao, t = co.step(Gtheta)
plt.plot(t, thetao)
Beispiel #7
0
                    print(lastElem * 1.05, " ", lastElem * 0.95, " ", y[-k])
                    ind = k
                    break
            ind = len(x) - ind
            #print("Точка пересечения с +-5 % ",x[ind])
            print("время регулирования: ", x[ind])
        else:
            print("система расходится, время регулирования не определить")

    #print("отношение последнего к предпоследнему",y[-1]/y[-2])
    graph("Переходная функция", y, x, "Amplitude", "Time", "b")

    #_______________________________________________________________________________________________________________

    w_den = ml.tf(w.den[0][0], [1])
    crt = ml.pzmap(w_den)
    plt.close()
    #если берем от знаменателя - а от него берём чтобы считать только полюса, нужно [1]
    first_elem = crt[1]
    print("Значения полюсов передаточной функции:")
    minim = []
    for ans in first_elem:
        print("анс ту____________________________________________т")
        print(ans)
        print(re(ans))
        min_ans = re(first_elem[0])
        minim.append(first_elem[0])
        for i in range(1, len(first_elem)):
            if math.fabs(re(first_elem[i])) < math.fabs(min_ans):
                minim = []
                minim.append(first_elem[i])
# Expansao em fracoes parciais
# caso nao haja multiplos polos:
#       B(s)       R(1)       R(2)             R(n)
#       ----  =  -------- + -------- + ... + -------- + K(s)
#       A(s)     s - P(1)   s - P(2)         s - P(n)
#
print('-------------')
print('EXPANSAO EM FRACOES PARCIAIS')
B = K1*Km*Kg;
A = [1, a+am, a*am];
[R,P,K]=sc.signal.residue(B,A)
print('R =',R)
print('P =',P)
print('K =',K)
# Plot dos polos e zeros PZMAP
co.pzmap(Gomega,grid=True)
# Resposta Transitoria
S=co.stepinfo(Gomega)
print('-------------')
print('CARACTERISTICAS DA RESPOSTA TRANSITORIA DO SISTEMA')
print('tempo de subida tr = ','%.2f' % S['RiseTime'],'seg')
print('tempo de acomodacao ts = ','%.2f' % S['SettlingTime'],'seg')
print('maximo sobresinal Mp = ',S['Overshoot'])
print('valor de pico omegaomax = ','%.2f' % S['Peak'])
print('instante de pico tp = ','%.2f' % S['PeakTime'],'seg')
print('valor de regime estacionario omegaoss = ','%.2f' % S['SteadyStateValue'])
# Resposta a degrau da planta
plt.figure(2)
omegao, t = co.step(Gomega)
plt.plot(t,omegao)
plt.title('Resposta a degrau da planta')
Beispiel #9
0
#% Calculo dos polos da funcao de transferencia Gp
print(co.pole(Gp))
#%
#% Expansao em fracoes parciais
#% caso nao haja multiplos polos:
#%       B(s)       R(1)       R(2)             R(n)
#%       ----  =  -------- + -------- + ... + -------- + K(s)
#%       A(s)     s - P(1)   s - P(2)         s - P(n)
#%
B=K1*Km*Kg;
A=[1,a+am,a*am,0]
print(sympy.apart(Gp))
#%
#% Plot dos polos e zeros de Gm
#%

co.pzmap(Gp)
#% Resposta a entrada degrau do sistema
tspan = np.linspace(0,10,int(10//0.02))
print(tspan)
tspan = tspan.reshape(-1,1)
y,t = co.step(Gp,tspan)
plt.figure(2)
plt.plot(t,y)
plt.title("Step response")
plt.xlabel("Tempo[s]")
plt.ylabel("Amplitude")
plt.grid()
#
##% Caracteristicas da resposta a degrau
#print(co.stepinfo(Gp))
Beispiel #10
0
def ZN_Method():
    """
    Функция исполнения метода Зиглера-Николса для подбора параметров регулятора
    :return:
    """
    def is_on_border(poles):
        """
        функция выявляет, есть ли во входящем массиве полюсов такие, которые находятся
        на границе устойчивости
        :param poles: полюса
        :return: true/false
        """

        a = True
        counter = 1

        print("Полюса плоскости: ")
        for pole in poles:
            if -0.001 < pole.real < 0:  # корень в левой полуплоскости
                a = False
            print("Полюс ", counter, " : ", pole)
            counter += 1

        print("Система на границе устойчивости"
              if not a else "По критерию полюсов система устойчива")

        return a

    def second_var():
        """
        Второй способ релизации метода Зиглера-Никольса
        :return: время западнывания tet, постоянную времени T и коэффициент передачи k
        """
        # получает передаточную функцию объекта управления
        w = SchemeBody().get_scheme_solving()

        t = np.linspace(0, stop=100, num=2000)

        y1, t1 = step(w, t)

        y1 = list(y1)
        max_dif = 0
        # номер элемента в списке, имеющего максимальную разницу с предыдущим
        nmd = 0

        for num, yy in enumerate(y1[1:]):
            if (yy - y1[num]) > max_dif:
                max_dif, nmd = (yy - y1[num]), (num + 1)
                if y1[num - 1] < y1[num] > y1[
                        num + 1]:  # дошли до первого максимума, отбой
                    break

        # находим время запаздывания и постоянную времени через уравенение прямой
        tet = -y1[nmd] / (y1[nmd] - y1[nmd - 1]) * (t[nmd] -
                                                    t[nmd - 1]) + t[nmd]
        T = (y1[-1] - y1[nmd]) / (y1[nmd] -
                                  y1[nmd - 1]) * (t[nmd] - t[nmd - 1]) + t[nmd]

        return tet, T, y1[num]

    Kk = 0
    flag = True
    # создаем объект пропорционального регулятора с начальными параметрами
    regulator = ProportionalRegulator()

    # калибровка регулятора, поиск критического состояния САУ
    while flag:
        regulator.set_regulator_coefficients(k=Kk)
        # объект класса САУ
        grand_gear_function = SchemeBody(
            regs_w=regulator.get_TrFunc_proportional_regulator())
        # передаточная функция САУ с регулятором
        w = grand_gear_function.get_scheme_solving()

        poles, zeros = pzmap(w, Plot=False)
        if size(poles) > 0:
            # есть ли корень на границе устойчивости
            flag = is_on_border(poles)
        if not flag: break
        Kk += 0.1

    print("Кп: ", round(Kk, 3))
    # находим период переходной характеристики
    Tt = plot_trans_func(w, toPlotTrans=True, toFindT=True)
    print("Период колебательной переходной характеристики: ", round(Tt, 6))

    # создаем новый объект ПИД-регулятора
    regulator = PIDRegulator()
    # устанавливаем параметры по методу Зиглера-Николса
    regulator.set_regulator_coefficients(k=0.6 * Kk,
                                         Td=3 / 40 * Tt * Kk,
                                         Tu=1.2 * Kk / Tt)
    grand_gear_function = SchemeBody(
        regs_w=regulator.get_TrFunc_pid_regulator())
    # передаточная функция САУ с регулятором
    w = grand_gear_function.get_scheme_solving()

    poles, zeros = pzmap(w, Plot=False)
    if is_sustainable(poles):
        plot_trans_func(w, toPlotTrans=True)
        print("Оценка регулирования составляет: ", sum(do_direct_method(w)))
        return
    else:
        print("Система неустойчива! применим другой метод")
    """ переходим к оценке по второму методу Зиглера-Никольса"""
    tet, Tt, Kk = second_var()

    # создаем новый объект ПИД-регулятора
    regulator2 = PIDRegulator()
    # устанавливаем параметры по методу Зиглера-Николса
    regulator2.set_regulator_coefficients(k=1.2 * Tt / (Kk * tet),
                                          Td=1.2 * Tt / Kk,
                                          Tu=0.6 * Tt / (Kk * tet**2))
    grand_gear_function = SchemeBody(
        regs_w=regulator2.get_TrFunc_pid_regulator())
    # передаточная функция САУ с регулятором
    w = grand_gear_function.get_scheme_solving()

    poles, zeros = pzmap(w, Plot=False)
    if is_sustainable(poles) and (0.15 < tet / Tt < 0.6):
        plot_trans_func(w, toPlotTrans=True)
        print("Оценка регулирования составляет: ", sum(do_direct_method(w)))
    else:
        print("Опять неудача!")
#% Polos e zeros de malha aberta
#%
print('Polos e zeros - GHw1')
print(co.pole(GHw1))
print(co.zero(GHw1))
print('\nPolos e zeros - GHw2')
print(co.pole(GHw2))
print(co.zero(GHw2))
print('\nPolos e zeros - GHw3')
print(co.pole(GHw3))
print(co.zero(GHw3))
#%
#% Plot com os polos e zeros de malha aberta
#%

co.pzmap(GHw1, title="GHw1")
co.pzmap(GHw2, title="GHw2")
co.pzmap(GHw3, title="GHw3")

#plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.45)
#
#
#plt.subplot(3,1,1)
#co.pzmap(GHw1)
#plt.title('m. aberta GHw1')
##axis equal
#
#plt.subplot(3,1,2)
#co.pzmap(GHw2)
#plt.title('m. aberta GHw2')
##axis equal
Beispiel #12
0
#% Calculo dos polos da funcao de transferencia Gm
print(co.pole(Gomega))
#%
#% Expansao em fracoes parciais
#% caso nao haja multiplos polos:
#%       B(s)       R(1)       R(2)             R(n)
#%       ----  =  -------- + -------- + ... + -------- + K(s)
#%       A(s)     s - P(1)   s - P(2)         s - P(n)
#%
B = K1 * Km * Kg
A = [1, a + am, a * am]
print(sympy.apart(Gomega))

#%
#% Plot dos polos e zeros de Gm
#%
co.pzmap(Gomega)
#% Resposta a entrada degrau do sistema
tspan = np.linspace(0, 10, int(10 // 0.02))
print(tspan)
tspan = tspan.reshape(-1, 1)
y, t = co.step(Gomega, tspan)
plt.figure(2)
plt.plot(t, y)
plt.title("Step response")
plt.xlabel("Tempo[s]")
plt.ylabel("Amplitude")
plt.grid()
##% Caracteristicas da resposta a degrau
print(co.stepinfo(Gomega))
Beispiel #13
0
#% Polos e zeros de maplha aberta
#%
print('Polos e zeros - GHp1')
print(co.pole(GHp1))
print(co.zero(GHp1))
print('\nPolos e zeros - GHp2')
print(co.pole(GHp2))
print(co.zero(GHp2))
print('\nPolos e zeros - GHp3')
print(co.pole(GHp3))
print(co.zero(GHp3))
#%
#% Plot com os polos e zeros de malha aberta
#%

co.pzmap(GHp1, title = "GHp1")
co.pzmap(GHp2,title = "GHp2")
co.pzmap(GHp3, title = "GHp3")

#figure(1);
#subplot(1,3,1);
#pzplot(GHp1);
#title('m. aberta GHp1');
#axis equal;
#subplot(1,3,2);
#pzplot(GHp2);
#title('m. aberta GHp2');
#axis equal;
#subplot(1,3,3);
#pzplot(GHp3);
#title('m. aberta GHp3');