def rutina_step_plot(self, system, T, kp, ki, kd): """ Función para obtener la respuesta escalón del sistema en lazo cerrado en combinación con un controlador PID y su respectiva graficacion. :param system: Representacion del sistema :type system: LTI :param T: Vector de tiempo :type T: numpyArray :param kp: Ganancia proporcional :type kp: float :param ki: Ganancia integral :type ki: float :param kd: Ganancia derivativa :type kd: float :return: Respuesta escalón separada en vector de tiempo y vector de salida :rtype: tuple(numpyArray, numpyArray) """ U = np.ones_like(T) # Discriminación entre continue y discreto, con delay o sin delay, delay realizado con pade if ctrl.isdtime(system, strict=True): t, y, _ = ctrl.forced_response(system, T, U) elif (self.main.tfdelaycheckBox2.isChecked() and self.main.PIDstackedWidget.currentIndex() == 0): pade = ctrl.TransferFunction( *ctrl.pade(json.loads(self.main.tfdelayEdit2.text()), 10)) N = self.main.pidNSlider.value() pid = ctrl.TransferFunction([N * kd + kp, N * kp + ki, N * ki], [1, N, 0]) system = ctrl.feedback(pid * system * pade) t, y, _ = ctrl.forced_response(system, T, U) elif (self.main.ssdelaycheckBox2.isChecked() and self.main.PIDstackedWidget.currentIndex() == 1): pade = ctrl.TransferFunction( *ctrl.pade(json.loads(self.main.ssdelayEdit2.text()), 10)) N = self.main.pidNSlider.value() pid = ctrl.TransferFunction([N * kd + kp, N * kp + ki, N * ki], [1, N, 0]) system = ctrl.feedback(pid * system * pade) t, y, _ = ctrl.forced_response(system, T, U) else: N = self.main.pidNSlider.value() pid = ctrl.TransferFunction([N * kd + kp, N * kp + ki, N * ki], [1, N, 0]) system = ctrl.feedback(pid * system) t, y, _ = ctrl.forced_response(system, T, U) if ctrl.isdtime(system, strict=True): y = y[0] y = np.clip(y, -1e12, 1e12) self.main.stepGraphicsView2.curva.setData(t, y[:-1], stepMode=True) else: y = np.clip(y, -1e12, 1e12) self.main.stepGraphicsView2.curva.setData(t, y, stepMode=False) return t, y
def system_creator_ss(self, A, B, C, D): """ Función para la creación del sistema a partir de la matriz de estado, matriz de entrada, matriz de salida y la matriz de transmisión directa. :param A: Matriz de estados :type A: list :param B: Matriz de entrada :type B: list :param C: Matriz de salida :type C: list :param D: Matriz de transmisión directa :type D: list :return: El sistema, el vector de tiempo, el sistema con delay, el sistema en el espacio de estados y las ganancias kp, ki y kd. Si el sistema no tiene delay, ambos son iguales :rtype: tuple(LTI, numpyArray, LTI, LTI, float, float, float) """ if not self.main.ssdiscretocheckBox2.isChecked( ) and self.main.ssdelaycheckBox2.isChecked(): delay = json.loads(self.main.ssdelayEdit2.text()) else: delay = 0 system = ctrl.StateSpace(A, B, C, D, delay=delay) if self.main.kpCheckBox2.isChecked(): kp = self.main.kpHSlider2.value() / self.ssSliderValue else: kp = 0 if self.main.kiCheckBox2.isChecked(): ki = self.main.kiHSlider2.value() / self.ssSliderValue else: ki = 0 if self.main.kdCheckBox2.isChecked(): kd = self.main.kdHSlider2.value() / self.ssSliderValue else: kd = 0 t = self.main.pidTiempoSlider.value() # En caso de que el sistema sea discreto if self.main.ssdiscretocheckBox2.isChecked(): pid = ctrl.TransferFunction([ 2 * kd + 2 * self.dt * kp + ki * self.dt**2, -2 * self.dt * kp - 4 * kd + ki * self.dt**2, 2 * kd ], [2 * self.dt, -2 * self.dt, 0], self.dt) system = ctrl.sample_system(system, self.dt, self.main.sscomboBox2.currentText()) system_ss = system system = ctrl.ss2tf(system) if self.main.ssdelaycheckBox2.isChecked(): delayV = [0] * ( int(json.loads(self.main.ssdelayEdit2.text()) / self.dt) + 1) delayV[0] = 1 system_delay = system * ctrl.TransferFunction([1], delayV, self.dt) system_delay = ctrl.feedback(pid * system_delay) else: system_delay = None system = ctrl.feedback(pid * system) else: system_ss = system system = ctrl.ss2tf(system) system_delay = None try: if ctrl.isdtime(system, strict=True): T = np.arange(0, t + self.dt, self.dt) else: T = np.arange(0, t + 0.05, 0.05) except ValueError: T = np.arange(0, 100, 0.05) return system, T, system_delay, system_ss, kp, ki, kd
def system_creator_ss_tuning(self, A, B, C, D): """ Función para la creación del sistema a partir de la matriz de estado, matriz de entrada, matriz de salida y la matriz de transmisión directa, adicionalmente se realiza el auto tuning utilizando el método escogido por el usuario. :param A: Matriz de estados :type A: list :param B: Matriz de entrada :type B: list :param C: Matriz de salida :type C: list :param D: Matriz de transmisión directa :type D: list :return: El sistema, el vector de tiempo, el sistema con delay, el sistema en el espacio de estados y las ganancias kp, ki y kd. Si el sistema no tiene delay, ambos son iguales :rtype: tuple(LTI, numpyArray, LTI, LTI, float, float, float) """ if not self.main.ssdiscretocheckBox2.isChecked( ) and self.main.ssdelaycheckBox2.isChecked(): delay = json.loads(self.main.ssdelayEdit2.text()) else: delay = 0 system = ctrl.StateSpace(A, B, C, D, delay=delay) t = self.main.pidTiempoSlider.value() T = np.arange(0, t, 0.05) U = np.ones_like(T) t_temp, y, _ = ctrl.forced_response(system, T, U) dc_gain = ctrl.dcgain(system) # Parametros del modelo K_proceso, tau, alpha = model_method(self, t_temp, y, dc_gain) # Auto tunning try: kp, ki, kd = auto_tuning_method( self, K_proceso, tau, alpha, self.main.ssAutoTuningcomboBox2.currentText()) except TypeError: raise TypeError('Alfa es muy pequeño') # En caso de que el sistema sea discreto if self.main.ssdiscretocheckBox2.isChecked(): pid = ctrl.TransferFunction([ 2 * kd + 2 * self.dt * kp + ki * self.dt**2, -2 * self.dt * kp - 4 * kd + ki * self.dt**2, 2 * kd ], [2 * self.dt, -2 * self.dt, 0], self.dt) system = ctrl.sample_system(system, self.dt, self.main.sscomboBox2.currentText()) if self.main.ssdelaycheckBox2.isChecked(): delayV = [0] * ( int(json.loads(self.main.ssdelayEdit2.text()) / self.dt) + 1) delayV[0] = 1 system_delay = system * ctrl.TransferFunction([1], delayV, self.dt) system_delay = ctrl.feedback(pid * system_delay) else: system_delay = None system_ss = system system = ctrl.feedback(pid * system) else: system_ss = system system_delay = system try: if ctrl.isdtime(system, strict=True): T = np.arange(0, t + self.dt, self.dt) else: T = np.arange(0, t + 0.05, 0.05) except ValueError: T = np.arange(0, 100, 0.05) return system, T, system_delay, system_ss, kp, ki, kd
def system_creator_tf(self, numerador, denominador): """ Función para la creación del sistema a partir de los coeficientes del numerador y del denominador de la función de transferencia. :param numerador: Coeficientes del numerador :type numerador: list :param denominador: Coeficientes del denominador :type denominador: list :return: El sistema, el vector de tiempo, el sistema con delay y las ganancias kp, ki y kd. Si el sistema no tiene delay, ambos son iguales :rtype: tuple(LTI, numpyArray, LTI, float, float, float) """ if not self.main.tfdiscretocheckBox2.isChecked( ) and self.main.tfdelaycheckBox2.isChecked(): delay = json.loads(self.main.tfdelayEdit2.text()) else: delay = 0 system = ctrl.TransferFunction(numerador, denominador, delay=delay) if self.main.kpCheckBox2.isChecked(): kp = self.main.kpHSlider2.value() / self.tfSliderValue else: kp = 0 if self.main.kiCheckBox2.isChecked(): ki = self.main.kiHSlider2.value() / self.tfSliderValue else: ki = 0 if self.main.kdCheckBox2.isChecked(): kd = self.main.kdHSlider2.value() / self.tfSliderValue else: kd = 0 t = self.main.pidTiempoSlider.value() # En caso de que el sistema sea discreto if self.main.tfdiscretocheckBox2.isChecked(): pid = ctrl.TransferFunction([ 2 * kd + 2 * self.dt * kp + ki * self.dt**2, -2 * self.dt * kp - 4 * kd + ki * self.dt**2, 2 * kd ], [2 * self.dt, -2 * self.dt, 0], self.dt) system = ctrl.sample_system(system, self.dt, self.main.tfcomboBox2.currentText()) if self.main.tfdelaycheckBox2.isChecked(): delayV = [0] * ( int(json.loads(self.main.tfdelayEdit2.text()) / self.dt) + 1) delayV[0] = 1 system_delay = system * ctrl.TransferFunction([1], delayV, self.dt) system_delay = ctrl.feedback(pid * system_delay) else: system_delay = None system = ctrl.feedback(pid * system) else: system_delay = system try: if ctrl.isdtime(system, strict=True): T = np.arange(0, t + self.dt, self.dt) else: T = np.arange(0, t + 0.05, 0.05) except ValueError: T = np.arange(0, 100, 0.05) return system, T, system_delay, kp, ki, kd