Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Facultad de Ingeniería
Escuela de Ingeniería Eléctrica
IDENTIFICACIÓN DE PROCESOS Y
SINTONIZACIÓN DE CONTROLADORES PID
EN MATLAB ® 7.0
Por:
Por:
Miguel Aguilera Chaves, A20102
_________________________________
Ing. Víctor Manuel Alfaro
Profesor Guía
_________________________________ _________________________________
Ing. Rodolfo Espinoza Ing. Jorge Badilla
Profesor lector Profesor lector
ii
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
DEDICATORIA
iii
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
RECONOCIMIENTOS
hace las cosas bien. Desde este punto de vista, quiero felicitar al profesor Víctor Alfaro
quien durante todo el semestre estuvo disponible para cualquier consulta, aportó
información, brindó sus puntos de vista y allanó el terreno para completar el proyecto. Si el
presente es un buen trabajo, en mucho se debe al papel que desempeñó el profesor guía.
iv
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
ÍNDICE GENERAL
ÍNDICE DE FIGURAS..................................................................................vii
ÍNDICE DE TABLAS......................................................................................x
NOMENCLATURA........................................................................................xi
RESUMEN.................................................................................................... xiii
CAPÍTULO 1: Introducción ...........................................................................1
1.1 Antecedentes ...........................................................................................................1
1.2 Objetivos.................................................................................................................3
1.1.1 Objetivo general..............................................................................................3
1.1.2 Objetivos específicos ......................................................................................3
1.3 Desarrollo................................................................................................................5
CAPÍTULO 2: Desarrollo teórico ..................................................................7
2.1 Programas de identificación y sintonización comerciales ......................................7
2.1.1 BESTune (BESTune.com) (15) ........................................................................7
2.2.2 Control Loop Assistant (Lambda Controls) (17) ..............................................8
2.2.3 ExperTune (ExperTune Inc.) (16) ...................................................................10
2.2.4 EZYtune (Matrikon Inc.) (18) .........................................................................12
2.2.5 PID Controller Laboratory (PIDLab.com) (20) ..............................................12
2.2.6 TRA (Instituto de Tecnología de Lund, Suecia)...........................................13
2.2.7 Resumen de características ...........................................................................15
2.2 Características particulares de MATLAB® 7 para el desarrollo de una interfaz
gráfica 16
2.2.1 Introducción a los controles ActiveX ...........................................................16
2.2.2 Controles ActiveX en MATLAB® 7............................................................19
2.2.3 Controles Panel y Grupo de Botones ............................................................27
2.2.4 Intérprete de TEX y LaTEX en MATLAB®................................................30
CAPÍTULO 3: Desarrollo del programa .....................................................35
3.1 Módulos básicos ...................................................................................................35
3.1.1 Adquisición (adquisicion).............................................................................35
3.1.2 Filtrado (filtrado) ..........................................................................................42
3.1.3 Identificación de Lazo Abierto (identif_la) ..................................................49
v
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
vi
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
ÍNDICE DE FIGURAS
Figura 2.1 Selección del área de trabajo para la identificación de un modelo de la planta,
en el programa Control Loop Assistant ..............................................................................9
Figura 2.2 Ajuste manual de los parámetros del modelo de identificación del proceso, a
través del programa Control Loop Assistant ....................................................................10
Figura 2.3 Diagrama de Robustez en ExperTune (fuente Expertune Inc.).......................11
Figura 2.4 Ajuste manual del modelo de identificación del proceso en TRA ..................14
Figura 2.5 Ejemplo de un control ActiveX: Calendar Control 11.0 ................................19
Figura 2.6 Herramienta de creación de interfaces gráficas en MATLAB, GUIDE..........20
Figura 2.7 Ventana para la selección del tipo de control ActiveX, en MATLAB®.........21
Figura 2.8 Editor de propiedades de los controles en GUIDE..........................................22
Figura 2.9 Interfaz gráfica para el ejemplo de uso de un control ActiveX en MATLAB®
..........................................................................................................................................23
Figura 2.10 Funcionamiento de un control ActiveX en tiempo de ejecución ..................25
Figura 2.11 Lista de métodos para el control ActiveX del ejemplo .................................26
Figura 2.12 Empleo del control “Panel” en programas GUI desarrollados en MATLAB®
7 ........................................................................................................................................29
Figura 2.13 Creación de objetos “texto” mediante código de MATLAB® .....................31
Figura 2.14 Ejemplo del uso de intérprete de TEX en MATLAB®.................................33
Figura 2.15 Ejemplo del uso de intérprete de LaTEX en MATLAB® ............................34
Figura 3.1 Diagrama de bloques para las Funciones Básicas (parte 1) ............................37
Figura 3.2 Ejemplo de señales de entrada y salida (prueba de lazo abierto) antes de
aplicar la corrección del nivel DC ....................................................................................39
Figura 3.3 Ejemplo de señales de entrada y salida (prueba de lazo abierto) después de
aplicar la corrección del nivel DC ....................................................................................40
Figura 3.4 Especificaciones de diseño para un filtro Paso Bajo .......................................43
Figura 3.5 Parámetros de la respuesta del sistema necesarios para determinar modelos de
identificación de lazo cerrado ...........................................................................................60
Figura 3.6 Diagrama de bloques para las Funciones Básicas (parte 2) ............................63
vii
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
Figura 3.7 Diagrama de Nyquist obtenido por medio de la función nyquist ....................78
Figura 3.8 Diagrama de Nyquist obtenido mediante la función nyqlog ...........................78
Figura 3.9 Gráfico de robustez producido por la función graficorubus ...........................79
Figura 3.10 Curva de reacción filtrada (ejemplo).............................................................85
Figura 3.11 Curva de reacción de los modelos identificados (ejemplo)...........................86
Figura 3.12 Respuesta de lazo cerrado del sistema (ejemplo) ..........................................89
Figura 3.13 Gráfico de robustez (Ejemplo) ......................................................................91
Figura 3.14 Diagrama de Nyquist (Ejemplo)....................................................................91
Figura 3.15 Diagrama de flujo del programa....................................................................92
Figura 3.16 Objetos estándar utilizados en el programa.................................................111
Figura 3.17. Ejemplo del control ActiveX “OpcionCtl” ................................................119
Figura 4.1 Ventana de introducción del programa (ejemplo 1) ......................................133
Figura 4.2 Cuadro de diálogo de selección de archivo (ejemplo 1) ...............................134
Figura 4.3 Ventana de selección de archivo de datos (ejemplo 1) .................................135
Figura 4.4 Error por archivo no válido (ejemplo 1)........................................................135
Figura 4.5 Cuadro de diálogo de interrogación por ausencia de datos (ejemplo 1) .......136
Figura 4.6 Cuadro de diálogo para insertar el periodo de muestra (ejemplo 1) .............137
Figura 4.7 Ventana de vista previa de los datos de la prueba (ejemplo 1) .....................138
Figura 4.8 Reasignación de los límites para los datos de la prueba (ejemplo 1) ............139
Figura 4.9. Selección de filtro (ejemplo 1). ....................................................................139
Figura 4.10 Cuadro de diálogo de selección de método (ejemplo 1) .............................141
Figura 4.11 Curvas de reacción de los modelos identificados (ejemplo 1) ....................141
Figura 4.12 Parámetros de los modelos identificados (ejemplo 1).................................142
Figura 4.13 Funciones de transferencia de dos modelos (ejemplo 1).............................142
Figura 4.14 Vista con detalle de la curva de reacción asociada al método de “Jután y
Rodríguez” ......................................................................................................................143
Figura 4.15. Archivo imagen creado por el programa para las curvas de reacción
(ejemplo 1) ......................................................................................................................144
Figura 4.16 Gráfico de comparación de métodos de identicación (ejemplo 1) ..............145
Figura 4.17 Deficiencia del método Bogere y Özgen (ejemplo 1) .................................146
viii
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
ix
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
ÍNDICE DE TABLAS
x
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
NOMENCLATURA
ep error permanente.
Mp sobrepaso máximo.
s variable compleja.
ωc frecuencia de corte.
τ constantes de tiempo.
τn periodo natural.
ζ razón de amortiguamiento.
xii
Diciembre del 2005
Identificación de procesos y sintonización de controladores PID en MATLAB 7.0
RESUMEN
MATLAB 7.0, con el propósito de identificar procesos (a partir de pruebas de lazo abierto
otras herramientas similares que se han desarrollado en la Escuela: PILAC, IGS, HISCRO,
pero, a su vez, incluye una serie de mejoras resultantes del análisis de distintos programas
de MATLAB.
determinar el mejor modelo identificado para luego utilizarlo en las simulaciones del lazo
de control.
xiii
Diciembre del 2005
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 1
CAPÍTULO 1: Introducción
1.1 Antecedentes
Costa Rica, ha existido un proyecto para desarrollar programas que faciliten la simulación y
[IGS] (14).
Además, el programa HISCRO provee las gráficas de robustez, algo que aun en los
herramienta.
1.2 Objetivos
7.0.
• Determinar cuáles son las capacidades adicionales que provee la versión 7.0 de
• Establecer una lista de posibles mejoras (en la interfaz gráfica, interacción con el
• Incorporar las facilidades para seleccionar el tipo de filtrado que se aplica a los
datos de entrada.
1.3 Desarrollo
1. Establecer y analizar, en conjunto con el profesor guía, los objetivos del proyecto.
2. Estudiar los programas PILAC, IGS y HISCRO, para conservar sus puntos fuertes,
5. Investigar las funciones que provee la versión 7.0 de MATLAB para producir un
filtrado sobre una señal, cuando se dispone de una colección de puntos (u,y).
determinar cuáles de ellas pueden resultar útiles para el desarrollo del proyecto.
Utiliza una interfaz muy simple, la cual se caracteriza por la estrechez de los objetos
puede provocar que el usuario no mantenga una secuencia correcta en los pasos requeridos
Para la identificación del proceso, se hace uso de un archivo externo que contiene
7
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 8
por el programa con la ayuda del usuario, quien debe digitar el tiempo de muestreo en un
cuadro de texto.
Canadá, lee la información de la entrada y la salida del proceso, desde archivos separados.
muestreo y número de puntos. El archivo que contiene los datos de la entrada tiene
extensión OP, mientras que el archivo que contiene los datos de salida es de extensión PV.
A través del menú Ventana, se puede acceder a una muestra gráfica del contenido
de los archivos, con el propósito de seleccionar la porción de datos que deben ser utilizados
escalón de entrada; esto es, puede pasar de un 0% a un 50%, luego, de un 50% a un 75% y
luego, de un 75% a un 0%. El usuario puede, en el caso anterior, considerar sólo la porción
del 0% al 50%. Para hacerlo, puede emplear dos barras (1 y 2, en la figura 2.1.1) que le
indican al programa el tiempo final y el tiempo inicial de los datos que debe utilizar, o bien,
escribir dichos valores en las casillas que, para ese fin, fueron colocadas en la parte inferior
de la ventana.
Control Loop Assistant, utiliza posteriormente los datos escogidos para identificar
un modelo de primer orden más tiempo muerto, o un modelo de integrador con tiempo
muerto. Para ambos casos, se utiliza un único método (desconocido) para obtener los
parámetros del modelo, pero se brinda al usuario la opción de cambiarlos mediante dos
anclas colocadas sobre la curva de reacción, de manera que ésta se aproxime mejor a la
original.
determinar un conjunto de parámetros, los cuales son debidamente tabulados, para obtener
El parámetro proporcional, puede ser expresado como ganancia del controlador o bien,
como banda proporcional; mientras que, el parámetro integral puede ser dado por medio de
repeticiones/segundo.
Figura 2.2 Ajuste manual de los parámetros del modelo de identificación del proceso,
Basado en el modelo del proceso, el programa sugiere un valor pero, es el usuario quien
PID. Provee una herramienta paso a paso, que inicia con la lectura de información del
proceso a partir de un archivo e incluye la opción de simular los efectos de los parámetros
Para ello, ExperTune maneja una biblioteca de archivos (manejadores) para interactuar con
controladores comerciales.
el proceso para un rendimiento constante cuando se varía el nivel del valor deseado y un
lazo de control.
único criterio.
parámetros de la planta, de acuerdo con un tipo de modelo, el cual debe ser seleccionado de
una lista. Para verificar si el comportamiento de lazo abierto es el esperado, existe una
cerrado (beta) y el tiempo de levantamiento que se espera en la curva de lazo cerrado, para
determinar los parámetros de un controlador Ideal (ISA). Para verificar la utilidad del
controlador PID, por medio de este programa, primero se debe describir la planta mediante
alguno de los siguientes modelos: FOPDT (primer orden más tiempo muerto), SOPDT
(segundo orden más tiempo muerto), coeficientes del numerador y del denominador o,
polos y ceros.
Esta aplicación utiliza módulos Java y muestra una buena distribución de objetos
que le dan a la interfaz gráfica un mejor aprovechamiento del espacio. Los botones se
identifican por medio de dibujos, en lugar de palabras y, cuando se hace necesario una
Respuesta Transiente), una aplicación desarrollada en MATLAB® 5.3, por Wallén del
TRA junto a una lista de parámetros, lo cuales son, en su orden: datos de salida (y), tiempo
(t) y entrada (u). Si se omite u, el programa supone una entrada escalón unitaria que inicia
en cero segundos.
al programa Control Loop Assistant, pues es posible utilizar anclas colocadas sobre la
curva para mejorar el modelo en sí. Sin embargo, esta herramienta despliega el error que se
obtiene al variar los indicadores del tiempo muerto y la constante de tiempo, o toda función
de transferencia.
Figura 2.4 Ajuste manual del modelo de identificación del proceso en TRA
Provee distintos tipos de modelos: primer orden más tiempo muerto, polo múltiple
(hasta orden ocho) más tiempo muerto y procesos integrantes puros o con retardo más
Si se quiere considerar sólo una porción de los datos de la entrada y la salida, existe
una opción denominada "Selección de Área de Trabajo", que permite por medio de un
cuadro en pantalla especificar una región del gráfico. Este último se puede acercar o alejar,
controladores.
Características Características
Programa sobresalientes en el sobresalientes en la
funcionamiento interfaz gráfica
de parámetros de
controladores
de controles ActiveX y objetos contenedores como los paneles y los grupos de botones. A
MATLAB®.
ActiveX consiste un una generalización de los controles OLE que Microsoft utiliza
de código entre aplicaciones. Un ejemplo de objeto OLE lo constituye una ecuación del
Los controles ActiveX forman parte de una clase más general de objetos
denominada COM (Component Object Model), una tecnología ideada por Microsoft con la
software desarrollada por Microsoft, para crear aplicaciones basadas en componentes. Los
objetos COM son de tipo discreto, esto es, cada uno posee una identidad única, la cual
expone una interfaz que permite a las aplicaciones y a otros componentes, acceder
lenguaje de programación, los objetos COM son más versátiles que las bibliotecas
orientadas a objetos. Todos los objetos COM pueden escribirse en cualquier lenguaje (Java,
C++, Pascal, Visual Basic, etc.) e implementarse en sus propios ejecutables o bajo la forma
extensión OCX.
objeto, no intrínseco, pero que mantiene las características de cualquier objeto estándar. Lo
controles de una herramienta para el diseño de GUI, como los botones de comando o los
manera similar.
arquitectura COM, los controles ActiveX pueden ser programados en cualquier lenguaje
orientado a objetos y, sin importar cuál de ellos se utiliza, pueden ser empleados en el
diseño de interfaces gráficas en cualquier otro lenguaje de programación. Así, por ejemplo,
se puede diseñar un control ActiveX en Microsoft Visual Basic, para ser empleado en una
página Web.
dispone de propiedades tales como el color de fondo o el color de texto, y de eventos, como
el “Clic”. Las propiedades de los controles ActiveX pueden, en su mayoría, ser actualizadas
en tiempo de diseño, pero siempre, en tiempo de ejecución. Esto quiere decir que, en la
mayoría de los casos, se puede introducir un valor para la propiedad texto, en el momento
programa. Pero, este valor puede ser variado durante la ejecución del programa, mediante
GUIDE, se puede observar la barra de controles, la cual incluye, además de vínculos para
un botón asociado a los controles ActiveX ( ). Esto se puede observar en la figura 2.6.
Una vez que se introduce un control ActiveX, es necesario especificar qué tipo de
control se desea utilizar. Es por esto que, de forma automática, aparece una ventana de
Figura 2.7 Ventana para la selección del tipo de control ActiveX, en MATLAB®
Esta ventana muestra, a través de una lista, los controles ActiveX que se encuentran
ocasiones, es posible observar una muestra del control, como ocurre en el caso de la figura
anterior, donde se puede apreciar una vista previa del control de Microsoft denominado
Slider. Por medio del botón Create se crea un objeto del tipo seleccionado (Slider, en el
Una vez agregado el objeto sobre la figura, se puede proceder a variar algunas de
sus propiedades. Existen, durante período de diseño, dos maneras distintas para hacerlo. La
primera de ellas consiste en pulsar dos veces sobre el control para forzar la aparición del
cual aparece en la barra de herramientas del GUIDE. Una muestra de dicho editor se
Los valores de las propiedades se cambian de la misma forma que se puede hacer
La segunda forma de variar las propiedades, implica pulsar con el botón derecho del
apuntador sobre el control, para acceder a la opción “Property Editor”. Esta opción es
menos gráfica pero más compacta que la anterior, pues utiliza una ventana con pestañas
necesario conocer los eventos asociados al control con el que se trabaja, pues sólo por
Para desarrollar este tema, se utilizará un ejemplo con el mismo control que se había
Sobre la misma figura se agrega un control ActiveX (tipo Slider) junto a un botón
MATLAB®
botón de acción, se le asigna el valor de “Argentina”. La idea es que al mover la pestaña del
control Slider, el botón haga referencia a otro país hispano y la pestaña señale el número de
(Callback) que contiene todas las instrucciones que deben ejecutarse, en caso que el usuario
presione el botón del ratón. Para acceder a la función de llamado Click de este objeto, se
debe pulsar con el botón derecho del apuntador sobre el control, de forma que se despliegue
un menú con la opción “View Callbacks” (ver llamadas). Esta opción conduce, por medio
Para asociar los países con un número, se define un arreglo de celda llamado txt con
Cuando el usuario presiona el botón del apuntador sobre la pestaña del control
ActiveX, su propiedad Text debe tener, tal y como se ha dicho, una valor de la forma
“Texto #x”, donde x equivale a el valor de la propiedad Value (nivel de selección actual de
Para ello, se utiliza la línea número cinco, donde se asigna a la propiedad String, del botón
de comandos, el texto al que apunta el valor de la propiedad Value del control ActiveX,
Para apreciar el funcionamiento del pequeño programa, se muestran dos casos con
botón del ratón sobre el control ActiveX. Esto quiere decir que se ha utilizado un evento
desplazando con ella el cursor del ratón, por lo cual, el uso del evento MouseMove puede
Al aplicar estos últimos cambios, se podrá apreciar que el programa responde con
éxito. Es importante anotar, con esto, que se debe conocer bien los eventos de cada control
ActiveX.
(handles) del objeto. Si este comando se aplica sobre el control Slider de Microsoft, se
Como se puede apreciar, uno de los métodos disponibles para este control ActiveX,
De esta manera, una vez que el usuario decida presionar el botón, el control
de tipo contenedor, al igual que lo es una figura. Son de suma utilidad si se pretende
MATLAB tiene una propiedad denominada Parent, que indica cierta pertenencia del objeto
(handle) de una figura. Pero, es posible asignar dicha propiedad al identificador de objetos
determinado momento pero, esconderlo en otro. Esto se puede hacer mediante el uso del
pues, supone que todos los que se encuentren contenidos en él, serán mutuamente
otro “panel”. Para mostrar esto, además de la asignación de la jerarquía de objetos (nivel de
Por medio del segmento de código anterior, se ha creado dos paneles con un botón
dentro de cada uno de ellos (identificados como Argentina y Brasil, sus respectivos valores
en la propiedad Value). Ambos paneles se encuentran contenidos sobre otro panel cuyo
identificador es hpp. Para distinguir este último del resto, se ha denotado como “Panel
MATLAB® 7
un formato "agradable". Es en sí, un lenguaje que agrupa comandos y macros, donde los
comandos suelen iniciar con el caracter "\" y sus argumentos se indican mediante llaves ("{
... }").
LaTEX es una variante de TEX que posee una mayor cantidad de macros que,
gráfico “texto” (diferente a la etiqueta). Este tipo de objeto, sólo puede ser contenido por
objetos “Ejes” (“Axes”). Esto quiere decir, que para respetar la jerarquía de objetos
impuesta por MATLAB, primero se debe crear un objetos “Ejes” sobre una figura o un
hf = figure('Color',[1,1,1]); delete(gca);
ha = axes('Units','pixels','Position',[80,60,400,300],...
'Parent',hf,'Color',[0.9,0.9,0.9],'Visible','on');
ht1 = text(0.15,0.8,'Fórmula General:');
En el segmento anterior, la primera línea le indica a MATLAB que se debe crear una
figura, con color de fondo blanco. Se elimina el control “Ejes” que está asociado a dicha
crea un nuevo control “Ejes” para lo cual, se utiliza la instrucción “axes”. Se indica dentro
supone que debe ser contenido por el control “Ejes”, cuyo identificador está contenido en
gca.
La siguiente figura muestra una sección del objeto “Ejes”, donde se observa
En general, la función que permite crear objetos “Texto” posee la siguiente sintaxis:
Este tipo de objetos, tiene propiedades muy similares a las de los “cuadros de texto
utiliza la expresión “Color” (no se puede cambiar el color de fondo). Dos propiedades con
las que sólo cuenta el objeto “texto” son: “Rotation” y “Interpreter”. La primera de ellas
horizontal (en dirección contraria a las manecillas del reloj). Esto es útil si se quiere
mostrar una frase en posición vertical, en este caso se debe asignar dicha propiedad a 90°,
interpretar los caracteres del valor asignado a la propiedad “String” como instrucciones de
TEX o, si debe procesarlos de forma literal. Los valores posibles para la propiedad
propiedad “String” del objeto “texto” el valor: “\alpha, \beta, \gamma”. Es importante no
olvidar el carácter “\” pues, permite distinguir entre comandos y expresiones “literales”. El
carácter “^” siempre implica que el siguiente carácter o conjunto de ellos (entre llaves
“{}”), se hallen en un nivel superior, respecto del resto del texto. Una situación similar
ocurre con el caracter “_” que lleva todo a un nivel inferior. Una lista completa de
Para continuar con el primer ejemplo, se quiere escribir la solución general de una
ecuación cuadrática, justo debajo del texto “Fórmula General”. Para cumplir con este
El comando “\pm” se cambia durante la ejecución de esta línea por un caracter “±”.
Los operadores “_” y “^” llevan el texto seleccionado (mediante llaves), de forma
figura:
posible escribir la “raya fraccionaria” con el numerador arriba y el denominador abajo. Para
ello se requiere un intérprete más sofisticado que sea capaz de analizar el texto (definido
completa se inicia y se termina con la secuencia de caracteres “$$”. Lo anterior quiere decir
que, el valor de la propiedad “String” del objeto “texto”, debe ser de la forma: '$$ expresión
$$'. Para producir una fracción, se hace uso del comando “\over”, bajo la consideración
que, todo lo que se quiere en el numerador o en el denominador debe estar encerrado por
Si se toma en cuenta lo anterior, se puede obtener una forma más “gráfica” de la solución
siguiente figura:
conjunto de funciones que por sí solas permiten realizar las tareas más comunes como el
La segunda etapa implicó el diseño de la interfaz gráfica que permite comunicar las
distintas funciones entre ellas y con una serie de objetos tales como botones o cuadros de
Para facilitar el acceso a las tareas comunes para el programa, se han implementado
alrededor de doce funciones que son capaces de interactuar entre sí aun sin la presencia de
archivo de datos que contenga tres columnas: tiempo, entrada y salida. Si la prueba que se
realizó fue de “lazo abierto”, esta última columna corresponde a la salida del proceso,
35
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 36
La secuencia que tiene esta información dentro de un archivo de datos puede variar;
es decir, cierto archivo puede presentar las columnas en el siguiente orden: “tiempo-salida-
entrada” pero, es probable que se cuente con otro que mantenga la siguiente relación:
“entrada-salida-tiempo”. Es por esto que, para que MATLAB adquiera los datos en el orden
correcto, es necesario hacerle saber cuál es la secuencia que se está siguiendo. La mayor
parte de los programas comerciales solicitan al usuario la posición de al menos dos de las
tres variables de interés. Sin embargo, considerando que los datos dispuestos en la columna
del tiempo son los únicos que se encuentran uniformemente espaciados (algo que se puede
determinar con unas cuantas líneas de código), basta conocer la posición de la columna de
salidas (o la de entradas) para establecer el orden que mantienen los datos dentro del
archivo.
convertir todo el texto en una matriz tal que los elementos son todos numéricos y el
segundo, implica separar las columnas de la matriz, para lo cual se requiere, tal y como se
%Función de Adquisición
function [vt,vu,vy] = adquisicion(arch_dat,posy)
id_arch = fopen(arch_dat); %Abre archivo de datos
mdatos = fscanf(id_arch,'%g %g %g',[3 inf]); mdatos = mdatos';
fclose(id_arch); %Cierra el archivo
%
%///////////////////////////////////////////////////
%PROCEDIMIENTO PARA DETERMINAR LA SECUENCIA DE DATOS
%///////////////////////////////////////////////////
%
%
if esvt(mdatos(:,1))
vt = mdatos(:,1);
if posy == 2
vu = mdatos(:,3);
vy = mdatos(:,2);
else
vu = mdatos(:,2);
vy = mdatos(:,3);
end
elseif esvt(mdatos(:,2))
vt = mdatos(:,2);
if posy == 1
vu = mdatos(:,3);
vy = mdatos(:,1);
else
vu = mdatos(:,1);
vy = mdatos(:,3);
end
else
vt = mdatos(:,3);
if posy == 2
vu = mdatos(:,1);
vy = mdatos(:,2);
else
vu = mdatos(:,2);
vy = mdatos(:,1);
end
end
%
%///////////////////////////////////////////////////
%
[ND,Iu] = max(abs(vu));
[ND,Iy] = max(abs(vy));
%
umax = promemax(vu,Iu);
ymax = promemax(vy,Iy);
%
%Corrección Nivel DC
if abs(vu(1)) > 0.6 * umax;
vu = vu - umax;
vy = vy - ymax;
end
Los bloques condicionales externos, utilizan el valor que retorna la función esvt,
dato, se compara la diferencia de todos los pares de puntos consecutivos con ese paso para
La última sección del segmento de código anterior tiene como propósito lograr una
generalización de las características de las señales de entrada y salida (se quiere que tanto
60
50
Porcentaje de Entrada o
40
Salida (%)
30
20
10
0
0 5 10 15 20 25 30 35
-10
Tiempo (seg)
Figura 3.2 Ejemplo de señales de entrada y salida (prueba de lazo abierto) antes de
10
0
Porcentaje de Entrada o
Salida (%) -10 0 5 10 15 20 25 30 35
-20
-30
-40
-50
-60
Tiempo (seg)
Figura 3.3 Ejemplo de señales de entrada y salida (prueba de lazo abierto) después de
inicial de las curvas a cero, se utiliza la función “promemax” que tiene como parámetros de
entrada, el vector (de entradas o salidas) y el índice (posición del elemento dentro del
función abs al vector). Esta pequeña función (“promemax”) retorna el promedio de los diez
%Función promemax
function val = promemax(vec,I)
val = 0;
long = length(vec);
%
if I < 6
for k=1:10
val = val+vec(k);
end
val = val/10;
elseif I > long-5;
for k=0:9
val = val+vec(end-k);
end
val = val/10;
else
val = vec(I);
for k=1:5
val = val+vec(I-k);
end
for k=1:5
val = val+vec(I+k);
end
val = val/11;
end
Dentro del bloque condicional if, se estudian tres casos para determinar cuáles son
los puntos más cercanos al valor máximo de la versión positiva de la curva. El caso más
general (sección else del bloque condicional) es que se disponga de un punto que cuente
con al menos cinco antecesores y cinco sucesores para establecer el promedio. Los casos
alternativos corresponden a situaciones en las cuales no se pueden tomar cinco puntos antes
de las otras funciones, es la doble misión que puede adoptar el operador end. En MATLAB,
end se utiliza para indicar la finalización de un bloque condicional (if o switch) o un bucle
(for o while) pero además, es sumamente útil para trabajar con vectores pues permite
matemático basado en curvas ideales (no tienen ruido). Por esto, es indispensable utilizar
algún tipo de filtro con el objetivo de “acercar” las curvas originales (de lazo abierto o de
MATLAB provee una colección de funciones que permiten “filtrar” una señal que
se encuentre descrita por un conjunto de puntos. Estas funciones hacen referencia a filtros
clásicos como los son: Chebyshev (en sus dos variantes: tipo I y tipo II), Butterworth,
paso (δp).
(δs).
(tomado de (10))
El ruido que afecta las señales que se obtienen en las pruebas de lazo abierto o
cerrado son de alta frecuencia, por lo cual es necesario aplicar un filtro Paso Bajo. Un filtro
Paso Bajo deja pasar todas las frecuencias que se encuentren debajo de una frecuencia de
corte (representada por fc, si está establecida en Hz o por wc, si está establecida en rad/s), lo
cual implica la atenuación de las frecuencias que se hallen por encima de dicha frecuencia
La frecuencia fc aplica para cualesquiera de los cuatro tipos de filtros detallados líneas
atrás.
En general, los filtros Butterworth se caracterizan por tener una ganancia plana en la
banda de paso, los de Chebyshev por tener una pendiente máxima en la región de
transición, los de Bessel por tener una respuesta de fase lineal en torno a fc, mientras que los
filtros Elípticos permiten obtener una transición más rápida entre la banda de paso y la de
rechazo. Las consideraciones anteriores son relevantes a la hora de elegir el tipo de filtro
MATLAB, para un filtro Butterworth son: el orden y la frecuencia corte ωc; para un filtro
Chebyshev: el orden n, la frecuencia corte ωc y el rizado (en la banda de paso δp, cuando el
filtro es tipo I o en la banda de rechazo δs, cuando el filtro es tipo II) y para un filtro de
Es común que no se disponga inicialmente del orden que se debe utilizar para el
el orden del sistema. En su lugar, se brinda una serie de datos como: la frecuencia límite en
banda de paso fp, la frecuencia límite en banda de rechazo fs, la atenuación mínima en la
n=
[( ) ]
log 100.1 Amin − 1 − 2 log ∈
(3.1)
f
2 log s
fp
muestra a continuación:
∈= 10 Amax / 10 −1 (3.2)
n=
(
log 1 − Amin
2
+ 1 − Amin
2
(
1+ ∈2 / ∈ ⋅ Amin ) ) (3.3)
log (ωs / ω p ) + (ω / ωp ) −1
2
s
MATLAB tiene funciones para calcular, de forma directa, el orden de los filtros que
se quieren diseñar. Los parámetros de entrada siempre son los mismos (en el orden
Para facilitar la implementación de filtros sobre las señales de salida de las pruebas
%Función Filtrado
function vyf = filtrado(varargin);
vy = cell2mat(varargin(1));
%
%Lectura de argumentos de entrada obligatorios
tipo_filtro = cell2mat(varargin(2));
%
if tipo_filtro ~= 0
orden_filtro = cell2mat(varargin(3));
frec_corte = cell2mat(varargin(4));
%
%Lectura de argumentos de entrada opcionales (depende del tipo ...
%de filtro)
if tipo_filtro > 0 & tipo_filtro < 4
if tipo_filtro == 3
delta1_filtro = cell2mat(varargin(5));
delta2_filtro = cell2mat(varargin(6));
else
delta1_filtro = cell2mat(varargin(5));
end
end
%
%Llamada a funciones de filtro:
switch tipo_filtro
case 1 %Filtro Chebyshev Tipo I
[b,a]=cheby1(orden_filtro,delta1_filtro,frec_corte,'low');
case 2 %Filtro Chebyshev Tipo II
[b,a]=cheby2(orden_filtro,delta1_filtro,frec_corte,'low');
case 3 %Filtro Elíptico (De Cauer)
[b,a]=ellip(orden_filtro,delta1_filtro,delta2_filtro,...
frec_corte,'low');
otherwise %Butterworth
[b,a]=butter(orden_filtro,frec_corte);
end
%
%Aplicación del filtro sobre la señal original
vyf=filter(b,a,vy);
else
vyf=vy; %No aplicar filtro
end
no se puede suponer una secuencia fija de argumentos de entrada para la función filtrado.
Es por ello que se utiliza la expresión varargin como única entrada inicial de la función.
Esta variable consiste en un arreglo de celda cuya longitud está determinada por nargin
Puesto que todos los parámetros de entrada son numéricos, es una buena decisión
convertir cada fila del arreglo de celda en un vector (arreglo numérico). Para realizar lo
Los primeros dos parámetros de entrada siempre son los mismos: el vector de
salidas sin filtrar (vy) y el tipo de filtro que se va a utilizar (tipo_filtro), por lo cual, las
que contiene dos bloques condicionales internos: uno if y el otro switch. El bloque
descrita por vy (un valor de cero para el argumento tipo_filtro implica que el valor devuelto
El bloque switch permite relacionar una asignación específica con el tipo de filtro
que se designó como argumento de entrada, para obtener la función de transferencia por
Se fuerza a que todos los filtros sean paso bajo mediante la expresión 'low'.
aplicar el filtro sobre la señal original (vector de salidas vy) se utiliza la función filter. Los
puede variar según el tipo de filtro. Si se utiliza un filtro Chebyshev tipo II, delta1_filtro
representa el mínimo rizado en la banda de rechazo δs mientras que, para el caso de filtros
prueba de lazo abierto estén representados por los vectores vt, vu y yf (vector de salidas
no sólo devuelve la función de transferencia del modelo (gp) sino también los parámetros
del modelo: kpm (ganancia de la planta), tmm (tiempo muerto) y taom (constante o vector
de constantes de tiempo, en caso de modelos POMTM y SOMTM polo doble o, [ζ, τn] =
Jahanmiri y Fallahi).
entrada metodo.
3. Bröida, POMTM
4. Ho et al., POMTM
6. Smith, POMTM
7. Vitecková, POMTM
s = tf('s');
%
yl = y2-y1; ul = u2-u1;
kp = yl / ul; kpm = kp;
%
vu = abs(vu); %Se fuerza un escalón positivo
yf = abs(yf); %Se fuerza una respuesta positiva
%
%//////////////MÉTODOS DE IDENTIFICACIÓN LA////////////////////
%
if metodo == 1 %///////Áreas Características POMTM////////
%
mxvu = max(vu); k = 1;
while vu(k) < 0.6 * mxvu %Inicio del escalón
k = k+1;
end
ti_esc = vt(k); %Tiempo de inicio del escalón
iti_esc = k;
np = length(vt);
%
nvt = vt(iti_esc:np); nyf = yf(iti_esc:np);
ydf = yl-nyf;
Ao = trapz(nvt,ydf);
taot = Ao/yl;
%
vtx = abs(vt-taot); [ND,I] = min(vtx);
nyf2 = nyf(1:I); nvt2 = nvt(1:I);
A1 = trapz(nvt2,nyf2);
sigma = A1/(taot*yl);
%
tao = sigma*exp(1)*taot;
tm = taot-tao;
%
if tm < 0
tm = 0;
end
%
%Modelo obtenido:
taom = tao; tmm = tm;
gp = kp/(tao*s+1); gp.OutputDelay = tm;
%--
elseif metodo > 1 & metodo < 11 %////Métodos de dos puntos////
p1 = mat_dospts1(metodo-1,1);
p2 = mat_dospts1(metodo-1,2);
a = mat_dospts1(metodo-1,3);
b = mat_dospts1(metodo-1,4);
%
t1 = txporce(vt,vu,yf,yl,p1);
t2 = txporce(vt,vu,yf,yl,p2);
%
tao = a*(t2-t1); %Constante de tiempo
tm = b*t1 + (1-b)*t2; %Tiempo muerto
if tm < 0
tm = 0;
end
%
tmm = tm; taom = tao;
if metodo < 8
gp = kp/(tao*s+1); %Si es POMTM
else
gp = kp/(tao*s+1)^2; %Si es SOMTM, polo doble
end
gp.OutputDelay = tm;
%--
elseif metodo == 11 %//// Método de Stark ////
t1 = txporce(vt,vu,yf,yl,0.15);
t2 = txporce(vt,vu,yf,yl,0.45);
t3 = txporce(vt,vu,yf,yl,0.75);
%
x = (t2-t1)/(t3-t1);
chi = (0.0805-5.547*(0.475-x)^2)/(x-0.356);
if chi <= 1
f2 = 0.708*2.811^chi;
else
f2 = 2.6*chi-0.6;
end
wn = f2/(t3-t1); f3 = 0.922*1.66^chi;
tm = t2 - f3/wn;
if tm < 0
tm = 0;
end
%
tmm = tm;
if chi >= 1
tao1 = (chi+sqrt(chi^2-1))/wn;
tao2 = (chi-sqrt(chi^2-1))/wn;
taom = [chi,tao1,tao2];
gp = kp/((tao1*s+1)*(tao2*s+1));
else
gp = kp*wn^2/(s^2+2*chi*wn*s+wn^2);
taom = [chi,wn];
end
gp.OutputDelay = tm;
%--
elseif metodo == 12 %///Método de Jahanmiri y Fallahi///
t1 = txporce(vt,vu,yf,yl,0.02);
t2 = txporce(vt,vu,yf,yl,0.05);
t3 = txporce(vt,vu,yf,yl,0.7);
t4 = txporce(vt,vu,yf,yl,0.9);
%
tm = [t1,t2];
for k=1:2
nx=(t4-t3)/(t4-tm(k));
if nx <= 0.4771
chi(k) = sqrt((0.48446561-0.75323499*nx)/(1-
2.0946464*nx));
else
chi(k) = 13.9352;
end
tao(k) = (t4-tm(k))/(0.424301+4.62533*chi(k)-2.65412*exp(-
chi(k)));
end
%
gp1 = kp/(tao(1)^2*s^2+2*chi(1)*tao(1)*s+1);
gp1.OutputDelay = tm(1);
gp2 = kp/(tao(2)^2*s^2+2*chi(2)*tao(2)*s+1);
gp2.OutputDelay = tm(2);
gpt = [gp1,gp2];
%
for k=1:2
ym2 = lsim(gpt(k),vu,vt);
S2(k) = sum((abs(yf)-abs(ym2)).^2);
end
%
if S2(1) < S2(2) %El mejor modelo, basado en el S2 = ?
tmm = tm(1); taom = [tao(1),chi(1)];
gp = gpt(1);
else
tmm = tm(2); taom = [tao(2),chi(2)];
gp = gpt(2);
end
%--
elseif metodo == 13 %///Método de Áreas Características SOMTM ///
% (polo doble)
mxvu = max(vu); k = 1;
while vu(k) < 0.6 * mxvu %Inicio del escalón
k = k+1;
end
ti_esc = vt(k); %Tiempo de inicio del escalón
iti_esc = k;
np = length(vt);
%
nvt = vt(iti_esc:np); nyf = yf(iti_esc:np);
ydf = yl-nyf;
Ao = trapz(nvt,ydf);
taot = Ao/yl;
%
vtx = abs(vt-taot); [ND,I] = min(vtx);
nyf2 = nyf(1:I); nvt2 = nvt(1:I);
A1 = trapz(nvt2,nyf2);
sigma = A1/(taot*yl);
%
tao=A1*exp(1)^2/(4*yl);
tm=taot-2*tao;
%
if tm < 0
tm = 0;
end
%
%Modelo obtenido:
taom = tao; tmm = tm;
gp = kp/(tao*s+1)^2; gp.OutputDelay = tm;
end
por el modelo debe coincidir con la curva original) y coeficientes a y b los cuales son
código para determinar la ganancia del modelo (común para todos los métodos). Con el fin
la función abs sobre las señales con el fin de simplificar los cálculos posteriores, sin que
entrada metodo, con las asignaciones adecuadas para determinar el modelo respectivo.
requieren la obtención de tiempos necesarios para alcanzar un porcentaje del valor final de
continuación:
conocer el tiempo que conduce al 15, 45 y al 75% del valor final de la respuesta. Para ello,
para el cual se quiere determinar el tiempo tx). Como los resultados pueden variar según el
intervalo de muestreo de los datos de las pruebas, es mejor aplicar una interpolación lineal
para determinar un valor de tiempo más preciso. La función lineal se encuentra a través de
polyfit que devuelve en la variable pol, los coeficientes del polinomio (criterio de la
Cualquier tiempo que se determine por medio de la función txporce debe iniciar con
el escalón en la entrada del proceso, por lo cual, es preciso restar al tiempo obtenido
es el de Stark, entonces taom adopta los valores de dos constantes de tiempo (τ1 y τ2), si la
cerrado: vt, vu (no varían respecto a la función identif_la) y yf que, representa los datos de
1. Yuwana y Seborg
2. Jután y Rodríguez
3. Lee
4. Bogere y Özgen
s = tf('s');
mxvu = max(vu); k = 1;
%
[ND,I] = max(yf);
tp1 = vt(I); yp1 = yf(I); %Primer pico
for k = I:length(yf) %Recorte del vector
va(k-I+1) = vt(k);
vb(k-I+1) = yf(k);
end
%
[ND,I] = min(vb);
tm1 = va(I); ym1 = vb(I); %Primer mínimo
for k = I:length(vb) %Recorte del vector
vc(k-I+1) = va(k);
vd(k-I+1) = vb(k);
end
%
[ND,I] = max(vd);
tp2 = vc(I); yp2 = vd(I); %Segundo pico
yu = 0; du = 0;
for k=0:9 %Promedio de los últimos 10 valores
yu = yu + yf(length(yf)-k);
du = du + vu(length(vu)-k);
end
%
yu = yu/10; du = du/10; %Valor final de la respuesta
tm = 2*deltat*sqrt((1-chip^2)*(K+1))/den3;
if tm < 0
tm = 0;
end
%
%Modelo
kpm = kp; tmm = tm; taom = tao;
gp = kp/(tao*s+1);
gp.OutputDelay = tm;
%--
case 2 %///------Jutan y Rodríguez-------///
%Ecuaciones del método
deltat = fdeltat(vt,yf,tm1,yu);
gam1=-0.61453; gam2=0.1247; cdelta=0.3866;
kprim = yu/(du-yu);
alfa1 = (yu-ym1)/(yp1-yu);
chip = -log(alfa1)/sqrt(pi^2+(log(alfa1))^2);
taop = deltat*sqrt(1-chip^2)/pi;
vbeta = -1/(cdelta+gam1*kprim);
valfa = 2*chip*taop*(1+kprim)*-vbeta;
a = vbeta^2*gam2*kprim+vbeta*cdelta;
b = 2*gam2*kprim*valfa*vbeta+valfa*cdelta;
c = gam2*kprim*valfa^2-taop^2*(1+kprim);
tao = (-b+sqrt(b^2-4*a*c))/(2*a);
tm = valfa+vbeta*tao;
if tm < 0
tm = 0;
end
kp = kprim/kc;
%
%Modelo
kpm = kp; tmm = tm; taom = tao;
gp = kp/(tao*s+1);
gp.OutputDelay = tm;
%--
case 3 %///-------------Lee------------///
%Ecuaciones del método
delta = (yu-ym1)/(yp1-yu);
deltat = fdeltat(vt,yf,tm1,yu);
chi = -log(delta)/sqrt((pi^2+(log(delta))^2));
taop = deltat*sqrt(1-chi^2)/pi;
kprim = yu/du;
kp = kprim/(kc*(1-kprim));
valfa = chi/taop; vbeta = sqrt(1-chi^2)/taop;
v = atan(vbeta/valfa);
tm_in = (v+pi/4)/vbeta; tmkm1 = tm_in;
while 1
den = kc*kp*sqrt(valfa^2+vbeta^2)*cos(vbeta*tmkm1-v);
tmant = tmkm1;
tmkm1 = (v+atan(vbeta*exp(-valfa*tmkm1)/den))/vbeta;
if tmkm1 == tmant
break;
end
end
tm = tmkm1;
if tm < 0
tm = 0;
end
tao = (1+kc*kp*exp(valfa*tm)*cos(vbeta*tm))/valfa;
%
%Modelo
kpm = kp; tmm = tm; taom = tao;
gp = kp/(tao*s+1);
gp.OutputDelay = tm;
%--
case 4 %///------Bogere y Özgen-------///
a = -0.8647; b = 0.2260;
deltat = fdeltat(vt,yf,tm1,yu);
kp = abs(yu-yf(1))/(kc*(du-abs(yu-yf(1)))); K = kc*kp;
tm = tp1 - deltat;
den1 = sqrt(pi^2+(log((yu-ym1)/(yp1-yu)))^2);
den2 = sqrt(4*pi^2+(log((yp2-yu)/(yp1-yu)))^2);
chi1 = -log((yu-ym1)/(yp1-yu))/den1;
chi2 = -log((yp2-yu)/(yp1-yu))/den2;
chi = (chi1+chi2)/2;
alfa = (deltat/pi)*chi*sqrt(1-chi^2)*(1+K)-0.5*a*K*tm;
beta1 = (deltat/pi)^2*(1-chi^2)*(1+K)*(chi^2*(1+K)-1);
beta2 = (deltat/pi)*chi*sqrt(1-chi^2)*(1+K)*-a*K*tm;
beta3 = K*tm^2*(0.25*K*a^2+b);
beta = sqrt(beta1+beta2+beta3);
tao1 = alfa+beta;
tao2 = alfa-beta;
%
if tao2 < 0
tao2 = 0;
end
if tm < 0
tm = 0;
end
%
%Modelo
kpm = kp; tmm = tm; taom = [tao1,tao2];
gp = kp/((tao1*s+1)*(tao2*s+1)); gp.OutputDelay = tm;
end
una serie de datos requeridos por las ecuaciones de los métodos para determinar los
modelos. En la siguiente figura es posible apreciar los datos a los que se hace referencia en
En el código: yp1 (yp1), yp2 (yp2), ym1 (ym1), yu (yu) y deltat (∆t) corresponden, de
forma respectiva, a los valores del primer y segundo pico, el primer mínimo y el valor final
función fdeltat:
vtx(k) = vt(k);
vyx(k) = vy(k);
end
%
[ND,I]=max(vyx);
for k=1:length(vyx)
if k <= I
vtx1(k) = vtx(k);
vyx1(k) = vyx(k);
else
vtx2(k-I) = vtx(k);
vyx2(k-I) = vyx(k);
end
end
%
%Primera Etapa
vaux = abs(vyx1 - yu);
[ND,I] = min(vaux);
pol=0;
if vyx1(I)-yu == 0
ta = vtx1(I);
elseif vyx1(I)-yu < 0
pol = polyfit([vyx1(I),vyx1(I+1)],[vtx1(I),vtx1(I+1)],1);
ta = polyval(pol,yu);
else
pol = polyfit([vyx1(I-1),vyx1(I)],[vtx1(I-1),vtx1(I)],1);
ta = polyval(pol,yu);
end
%
%Segunda Etapa
vaux = abs(vyx2 - yu);
[ND,I] = min(vaux);
pol=0;
if vyx2(I)-yu == 0
tb = vtx2(I);
elseif vyx1(I)-yu < 0
pol = polyfit([vyx2(I),vyx2(I+1)],[vtx2(I),vtx2(I+1)],1);
tb = polyval(pol,yu);
else
pol = polyfit([vyx2(I-1),vyx2(I)],[vtx2(I-1),vtx2(I)],1);
tb = polyval(pol,yu);
end
dt = tb-ta;
La función fdeltat utiliza un pequeño algoritmo para determinar los puntos que, en
la figura 3.5, se encuentran marcados con círculos rojos. La diferencia entre los tiempos a
los que se obtienen dichos puntos (ta y tb) determina el parámetro de salida dt (el
semiperiodo ∆t).
tiempo del modelo (POMTM). Como el modelo que se identifica a través del método de
Bogere y Özgen es SOMTM, taom contiene, luego de la aplicación del método, el valor de
Tal y como ocurre con identif_la, gp, kpm y tmm son utilizados por la función
tiempo muerto del modelo identificado. El método deseado se debe establecer a través del
parámetro de entrada metodo, cuyo valor se puede determinar de la lista de métodos que se
diagrama de bloques que muestra la interconexión entre las distintas funciones básicas. La
Es importante distinguir que el punto de conexión entre los segmentos del diagrama
de bloques que, se muestran en las figura 3.1 y 3.6, es el modelo identificado para la planta
gp.
La función sintoniz consta de cuatro secciones, las cuales están demarcadas con los
la entrada de la función: los valores asignados a los parámetros tpctl (tipo de controlador) y
El valor (numérico) que se debe asignar al parámetro metodo, está determinado por
la siguiente lista:
Reglas de Sintonización:
7. Cohen y Coon
9. López ISE
25. Shinskey
esencial para extraer los parámetros del modelo a partir de la función de transferencia gp, y
continuación:
%Función - Sintonización
function [kc,Td,Ti,gc,tgc] = sintoniz(gp,varargin)
metodo = cell2mat(varargin(2));
%
s = tf('s');
%
%2) Obtención de parámetros a partir de la función de transferencia
% de la planta, gp
%
if metodo<20 | metodo==22 | (metodo>25 & metodo<28)
[z,p,kp] = zpkdata(minreal(gp));
kp = kp/abs(p{1}); tao = 1/abs(p{1});
tm = gp.OutputDelay;
tc = tm/tao;
elseif metodo>19 & metodo<22 | metodo==28
[z,p,kp] = zpkdata(minreal(gp));
[num,den] = tfdata(minreal(gp));
den = den{1};
kp = kp/den(3);
tao = sqrt(1/den(3));
chi = den(2)*tao/2;
tm = gp.OutputDelay;
tc = tm/tao;
elseif metodo == 23
[z,p,kp] = zpkdata(minreal(gp)); p=p{1};
if -1/p(1) > -1/p(2)
tao1 = -1/p(1); tao2 = -1/p(2);
else
tao2 = -1/p(1); tao1 = -1/p(2);
end
kp = kp*tao1*tao2; tm = gp.OutputDelay;
end
%//////////////////////////////////////////////////////%
%///// /////%
%///// REGLAS DE SINTONIZACIÓN /////%
%///// /////%
%//////////////////////////////////////////////////////%
%
%Asignación de parámetros (PID+Ideal):
kc = (a(m)+b(m)*tc^c(m))/kp;
Ti = tao*(d(m)+e(m)*tc^f(m));
%
if tpctl == 1 %Controlador PI
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID (ideal)
Td = tao*g(m)*tc^h(m);
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
%--
elseif metodo > 2 & metodo < 7 %Arrieta IAE, ITAE, R y S
m = 2*(metodo - 2)-1;
%
%Constantes del método:
a = [0.45,0.1050,0.2607,0.1230,0.2438,0.2268,0.1140,0.1749];
b = [0.6494,1.2432,0.6470,1.1891,0.5305,0.8051,0.5131,0.8355];
c = [-1.1251,-0.9946,-1.1055,-1.0191,-1.0299,-0.9597,...
-1.0382,-0.9462];
d = [-0.2551,-0.2512,-1.5926,-
0.3173,0.9377,1.0068,0.9953,0.9581];
e = [1.8205,1.3581,2.9191,1.4489,0.4337,0.3658,0.2073,0.3987];
f = [0.4749,0.4796,0.1789,0.4440,0.8714,1.0092,1.5246,0.6884];
g = [0,-0.0003,0,-0.0053,0,-0.0146,0,-0.0169];
h = [0,0.3838,0,0.3695,0,0.3500,0,0.3126];
I = [0,0.9479,0,0.9286,0,0.8100,0,0.7417];
%
%Asignación de parámetros (PID):
if tpctl == 1 %Controlador PI
kc = (a(m)+b(m)*tc^c(m))/kp;
Ti = tao*(d(m)+e(m)*tc^f(m));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID (ideal)
kc = (a(m+1)+b(m+1)*tc^c(m+1))/kp;
Ti = tao*(d(m+1)+e(m+1)*tc^f(m+1));
Td = tao*(g(m+1)+h(m+1)*tc^I(m+1));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
%--
end
elseif metodo > 8 & metodo < 12 %López ISE, IAE, ITAE, R
m = metodo - 8;
%
%Asignación de parámetros (según tipo de controlador):
switch tpctl
case 1 %Controlador P
a = [1.4110,0.9023,0.4897];
b = [-0.9170,-0.9850,-1.0850];
kc = a(m)/kp*tc^(b(m));
%
%Obtención de la función de transferencia
gc = kc;
tgc = 1;
case 2 %Controlador PI
a = [1.3050,0.9840,0.8590];
b = [-0.9600,-0.9860,-0.9770];
c = [2.0325,1.6447,1.4837];
d = [0.7390,0.7070,0.6800];
kc = a(m)/kp*tc^(b(m));
Ti = c(m)*tao*tc^(d(m));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
case 3 %Controlador PID (ideal)
a = [1.4950,1.4350,1.3570];
b = [-0.9450,-0.9210,-0.9470];
c = [0.9083,1.1390,1.1876];
d = [0.7710,0.7490,0.7380];
e = [0.5600,0.4820,0.3810];
f = [1.0060,1.1370,0.9950];
kc = a(m)/kp*tc^(b(m));
Ti = c(m)*tao*tc^(d(m));
Td = e(m)*tao*tc^(f(m));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
elseif metodo > 11 & metodo < 18 %Kaya y Sheib IAE, ITAE, ISE, R y
S
m = metodo - 11;
%
%Constantes del método:
a = [0.98089,0.77902,1.11907,0.65000,1.12762,0.71959];
b = [-0.76167,-1.06401,-0.89711,-1.04432,-0.80368,-1.03092];
c = [1.09851,0.87481,1.25203,0.98950,0.99783,1.12666];
d = [1.05211,0.70949,0.95480,0.09539,0.02860,-0.18145];
e = [0.59974,0.57137,0.54766,0.50814,0.42844,0.54568];
f = [0.89819,1.03826,0.87798,1.08433,1.00810,0.86411];
%
if metodo == 21 %Servo:
if chi <= 0.9
kc = (-0.04+(0.333+0.949*tc^(-0.983))*chi)/kp;
else
kc = (-0.544+0.308*tc+1.408*chi*tc^(-0.832))/kp;
end
if tc <= 1
Ti = tao*chi*(2.055+0.072*tc);
else
Ti = tao*chi*(1.768+0.329*tc);
end
%
if tpctl == 1 %Controlador PI
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID (ideal)
Td = tao/((1-exp((-chi*tc^1.060)/0.870))* ...
(0.55+1.683*tc^(-1.090)));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
%
else %Regulador:
if tc < 0.9
kc = (-0.67+0.297*tc^(-2.001)+2.189*chi*tc^(-0.766))/kp;
else
kc = (-0.365+0.260*(tc-1.4)^2+2.189*chi*tc^(-0.766))/kp;
end
if tc < 0.4
Ti = tao*(2.212*tc^0.520-0.3);
else
fac1 = 1-exp(-chi/(0.15+0.33*tc));
fac2 = 5.25-0.88*(tc-2.8)^2;
Ti = tao*(-0.975+0.910*(tc-1.845)^2+fac1*fac2);
end
%
if tpctl == 1 %Controlador PI
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else
fac1 = 1-exp(-chi/(-0.15+0.939*tc^(-1.121)));
fac2 = 1.45+0.969*tc^(-1.171);
Td = tao/(-1.9+1.576*tc^(-0.530)+fac1*fac2);
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
end
%
%//////////////////////////////////////////////////////%
%///// /////%
%///// MÉTODOS DE LAZO CERRADO Y /////%
%///// MÉTODOS ANALÍTICOS /////%
%///// /////%
%//////////////////////////////////////////////////////%
%
elseif metodo > 21 & metodo < 24 %Martin, Smith y Corripio (S)
%
%Obtener parámetro lambda:
lambda = cell2mat(varargin(3));
%
if metodo == 22 %Planta POMTM, Controlador PI
Ti = tao; kc = lambda*tao/(kp*(lambda*tm+1));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else
Ti = tao1; Td = tao2;
kc = lambda*tao1/(kp*(lambda*tm+1));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 4; %PID Serie
end
%
elseif metodo == 24 %Ziegler y Nichols de Lazo Cerrado
%
%Obtener parámetros Kcu y Tu:
Kcu = cell2mat(varargin(3));
Tu = cell2mat(varargin(4));
%
if tpctl == 1 %Controlador P
kc = 0.5*Kcu;
%
%Obtención de la función de transferencia
gc = kc;
tgc = 1;
elseif tpctl == 2 %Controlador PI
kc = 0.45*Kcu;
Ti = Tu/1.2;
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID (Ideal)
kc = 0.75*Kcu;
Ti = Tu/1.6;
Td = Tu/10;
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
%
elseif metodo == 25 %Shinskey
%
%Obtener parámetros Kcu y Tu:
Kcu = cell2mat(varargin(3));
Tu = cell2mat(varargin(4));
%
if tpctl == 1 %Controlador PI
kc = 0.43*Kcu;
Ti = 0.5*Tu;
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID (Ideal)
kc = 0.5*Kcu;
Ti = 0.34*Tu;
Td = 0.08*Tu;
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
%
elseif metodo == 26 %Rivera IMC
%
%Obtener parámetro lambda:
lambda = cell2mat(varargin(3));
%
if tpctl == 1 %Controlador PI
kc = 2*(tao/tm)/(2*lambda*kp);
Ti = tao+tm/2;
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID
kc = (2*tao+tm)/(kp*(2*lambda+tm));
Ti = tao+tm/2;
Td = tao*tm/(2*tao+tm);
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
%
elseif metodo == 27 %Brosilow IMC, POMTM
%
%Obtener parámetro lambda:
lambda = cell2mat(varargin(3));
%
Ti = tao+(tm^2)/(2*(lambda+tm));
kc = Ti/(kp*(lambda+tm));
%
if tpctl == 1 %Controlador PI
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID
Td = ((tm^2)/(2*(lambda+tm)))*(1-tm/(3*Ti));
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
%
else %Brosilow IMC, SOMTM
%
%Obtener parámetro lambda:
lambda = cell2mat(varargin(3));
%
Ti = 2*chi*tao+(2*lambda^2-tm^2)/(2*(2*lambda+tm));
kc = Ti/(kp*(2*lambda+tm));
%
if tpctl == 1 %Controlador PI
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s));
tgc = 3;
else %Controlador PID
Td = Ti-2*chi*tao+(tao^2-(tm^3)/(6*(2*lambda+tm)))/Ti;
%
%Obtención de la función de transferencia
gc = kc*(1+1/(Ti*s)+Td*s);
tgc = 5;
end
end
En una tercera sección (dos líneas de código), se produce una asignación inicial de
Por esto es importante anotar que la sintaxis requerida para obtener los parámetros
[kc,Td,Ti,gc,tgc] = sintoniz(0,tpctl,metodo,Kcu,Tu);
[kc,Td,Ti,gc,tgc] = sintoniz(gp,tpctl,metodo);
[kc,Td,Ti,gc,tgc] = sintoniz(gp,tpctl,metodo,lambda);
para especificar si el controlador es P, PI o PID. Los métodos no siempre son útiles para
sintonizar esas tres variantes de controladores por lo cual, no existe una receta definida para
establecer los valores que se deben asignar a tpctl (es ahí donde la interfaz gráfica es
realmente útil). La idea, sin embargo, siempre es la misma: sea el caso en que un método
orden que se debe respetar para asignar los números es siempre el siguiente: P, PI, PID.
En casos de los métodos analíticos (Martin et al, Brosilow IMC y Rivera IMC), es
necesario, además del modelo y el tipo de controlador, especificar una constante lambda
(parámetro lambda) que, en el caso de los métodos IMC, corresponde a la constante del
filtro.
transferencia del controlador) y tgc (tipo de controlador). El principal objetivo del último
parámetro es distinguir entre controladores PID Serie e Ideal pero, en general, toma el valor
PID Ideal.
la magnitud en el diagrama pues, en lugar de utilizar una escala lineal, como era de
esperarse, emplea una escala logarítmica. Por tal motivo, la función se llama: nyqlog.
la función nyqlog, se procede a comparar el diagrama obtenido por medio de ella, respecto
1 .5
lazo abierto de un sistema específico es: L( s) = . El resultado de la comparación
s (3 s + 1)
Nyquist en el mismo eje de coordenadas pero, se debe considerar que estos deben tener
colores distintos. Por tal motivo, se definieron tres parámetros más en la entrada de la
función (col1, col2 y col3) para que, sea posible variar el color rojo del sistema de
coordenadas polares (col1), el color azul de los ejes (col2) y el color azul del diagrama en sí
(col3).
(7)
La función graficorubus fue implementada por Alfaro y, como se ha dicho,
permite dibujar el gráfico de robustez. A continuación se puede observar una muestra del
Para dibujar los gráficos de robustez sobre objetos “Ejes”, se han realizado algunas
sistema de control que bien puede operar como servo o como regulador, se muestra a
continuación:
tv = yfin-pct(m)/100;
end
pol = polyfit([vy(k-1),vy(k)],[vt(k-1),vt(k)],1);
ta(m) = polyval(pol,tv);
end
ta2=ta(1); ta5=ta(2);
función paramresp son: tiempo al pico (tp), sobrepaso máximo o error máximo (mx), error
especificación del modo de funcionamiento del sistema de control se establece a través del
parámetro de entrada fsc. El argumento debe ser “0” si se trata de un regulador ó “1” si es
un servo.
Para determinar los tiempos de asentamiento se utiliza una interpolación lineal para,
iniciales (archivo de datos y posición del vector de salidas) y para conectar los distintos
un archivo de datos. La prueba realizada para producir dicho archivo fue de lazo abierto,
por lo cual, se utiliza un método de identificación de lazo abierto. Pero, como la señal de
salida del proceso (reportada como la tercera columna de datos) tiene un alto porcentaje de
completo:
%Programa de Ejemplo
%Módulo Principal
%Miguel Aguilera
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear;
%Datos de Entrada:
archivo = 'step_open_010m.dat'; posy = 3;
%MODELOS:
clc;
disp('Modelo POMTM (Alfaro):'); gp1
disp(' ');
disp('Modelo SOMTM (Stark):'); gp2
disp(' ');
disp('--------------------------------------------------------');
%CONTROLADORES SINTONIZADOS:
disp('--------------------------------------------------------');
disp(' ');
disp('Controlador PI:');
kc1
Ti1
disp(' ');
disp('Controlador PID:');
kc2
Ti2
Td2
%Curva de Reacción:
y2 = lsim(gp1,vu,vt); y3 = lsim(gp2,vu,vt);
figure(2); set(2,'Color','w');
plot(vt,vu,'y',vt,yf,'b',vt,y2,'r',vt,y3,'m');
title('Curva de Reacción'); xlabel('Tiempo (seg)');
ylabel('Amplitud de la Respuesta'); grid on;
legend('Entrada Escalón','Curva de Reacción Original',...
'Curva - Modelo POMTM (Alfaro)',...
'Curva - Modelo SOMTM (Stark)');
%FTLC
[num,den] = pade(gp2.OutputDelay,4); gtm = tf(num,den);
gp = gp2;
gp.OutputDelay = 0;
gp = gp*gtm;
gc = gc2;
mr = gc*gp/(1+gc*gp);
figure(3); vtp=0:0.01:20; set(3,'Color','w');
step(mr,vtp); grid on;
%Diagrama de Nyquist
figure(4); set(4,'Color','w');
gp3 = gp1; gp3.OutputDelay = 0;
nyqlog(gp*gc,'m-','g-','b-');
title('Diagrama de Nyquist');
disp(' ');
disp('--------------------------------------------------------');
disp('--------------------------------------------------------');
disp(' ');
%Parámetros de la Respuesta
disp('Parámetros de la Respuesta de L.C:');
[tp,mp,ep,ta2,ta5]=paramresp(vt,vu,vy,1)
%Gráfico de Robustez
figure(5); set(5,'Color','w');
graficorobus(gca,gc,gp2,1);
title('Gráfico de Robustez'); xlabel('kp/kpa');
ylabel('tm/tma'); grid on;
Luego de varias pruebas (ejecuciones del programa), se determinó que el filtro que
se debía aplicar a la señal de salida del proceso, para disminuir al máximo el ruido sin
alterar por ello su forma original, era un Chebyshev Tipo I con las siguientes
del proceso con la menor cantidad de ruido: yf. Se determina mediante la función identif_la
utiliza más adelante para sintonizar un control PI y otro PID. Por otra parte, el segundo
modelo (SOMTM) se emplea como “planta” en el análisis de lazo cerrado del sistema de
control.
85
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 86
Es importante señalar que para obtener la respuesta ante una entrada escalón de los
utilizada función “step” pues, permite especificar cualquier tipo de señal como entrada del
sistema. Cuando “step” sólo permite utilizar un escalón que inicie en cero segundos, a
través de “lsim” se puede utilizar como entrada un escalón que inicie en cualquier instante
en la ventana de comandos (las variables gp1 y gp2 se encuentran sin punto y coma):
controlador PID (método de Arrieta, criterio integral ITAE) al hacer uso de la función
sintoniz.
Para analizar las otras “funciones básicas” sin complicar mucho el ejemplo, se
utilizó el controlador PID para determinar la función de transferencia de lazo cerrado del
sistema de control. Como planta se ha hecho uso del modelo SOMTM (Stark).
Para graficar la curva anterior, primero se determinó un vector con los distintos
puntos de la señal realimentada. Ese vector fue empleado por la función paramresp, para
robustez necesita el tiempo muerto del proceso (como propiedad “OutputField” del objeto
forma directa el modelo SOMTM (no se utilizó Padé). Para graficar el diagrama de Nyquist
la siguiente figura:
Las siguientes secciones se dedican a explicar los detalles más sobresalientes sobre
El programa está contenido en un único archivo “.m”, el cual se encarga de crear los
elementos gráficos y manejar las funciones específicas, para las cuales estos fueron
diseñados.
siguientes tareas:
Una vez que se ha conseguido completar las tareas anteriores, el programa entra en
estado de espera (se rompe la secuencia lineal). La siguiente sección de código que se va a
introducción).
Esta situación se repite durante toda la ejecución del programa. Esto es, el programa
presenta durante periodos específicos, una secuencia lineal (procesa el código línea por
línea). Esta lógica se rompe en el momento que se requiera información por parte del
usuario, o que deba utilizarse otras funciones para desempeñar tareas específicas.
En general, una función puede ser invocada a través de un evento (por ejemplo, el
de la sección 3.1.7 y, siempre se utiliza cuando se requiere aplicar las funciones básicas
Todos los identificadores de los objetos son invisibles entre las funciones, por lo
tanto, para transferir esta información y cualquier otro parámetro importante, para la
operación del programa, se hace uso de una estructura global llamada infog.
las distintas funciones del programa. Las funciones que necesiten información de infog,
function principal()
clc; clear;
warning off;
...
infog.tPant = tPant;
ScreenSize) por medio de la función get. Este valor puede ser de gran utilidad para otras
funciones y por ello, se almacena como variable global en la estructura infog (línea:
mediante la instrucción “global infog” y se define una variable local tPant para almacenar
el contenido del elemento tPant de la estructura infog. Aquí, se observa cómo hacer
siguiente:
variable = struct('nombre_elemento_1',valor_elemento_1,
'nombre_elemento_2',valor_elemento_2,...);
pantalla del usuario). Para hacer esto, se debe conocer las dimensiones de la pantalla. En el
ejemplo anterior se pudo apreciar cómo determinar esta información. Ahora, es importante
comentar el porqué del cero como primer argumento de entrada en la función get.
establece una “jerarquía de objetos”. En cualquier caso, dentro de los programas con
interfaz gráfica de MATLAB, el objeto contenedor por excelencia (el del nivel superior) es
la pantalla. Como sólo hay un objeto de este tipo, se le ha establecido un número que no
varía según se use en una computadora u otra. Ese número (identificador) es “0” y al objeto
Como todo objeto gráfico, “root” tiene sus propiedades. Algunas de ellas son:
“CurrentFigure” (figura actual), “Format” (formato que tienen los números en MATLAB:
corto, largo, corto exponencial, largo exponencial, etc.), “PointerLocation” (ubicación del
Ahora bien, una vez conocidas las dimensiones de la Pantalla, se puede “centrar”
PosVentana = [tPant(3)/2-WV/2,tPant(4)/2-HV/2,W,H];
que tiene como elementos, de forma respectiva: la posición en el eje horizontal, la posición
en el eje vertical, el ancho y la altura del objeto (referidos todos al contenedor). De esta
Si se quiere crear una ventana que se ubique en el centro de la pantalla y que tenga
un ancho W y una altura H, se debe establecer su posición X,Y como la mitad del ancho y
Sin importar a qué objeto se haga referencia, las funciones get y set son utilizadas
aplica para set) de un objeto específico, el cual está denotado por un número de
continuación:
set(identificador,'Nombre_Propiedad_1',Valor_Propiedad_1,'Nombre_Pro ...
piedad_2',Valor_Propiedad_2,...);
var = get(identificador,'Nombre_Propiedad');
la variable “var”.
Algo muy importante de conocer durante las distintas fases de ejecución del
programa, es el objeto actual seleccionado. MATLAB tiene cinco funciones, las cuales no
Dichas funciones son las siguientes: gcf (figura actual), gca (objeto “Ejes” actual),
gco (objeto actual), gcbf (figura que contiene el objeto cuya función de llamado se ejecuta
en ese instante) y gcbo (el objeto cuya función de llamado se está ejecutando). Cualquiera
ha concluido la ejecución de cierta instrucción. Para ello, se cuenta con las siguientes
funciones, las cuales detienen la operación del programa: “pause” y “uiwait”. La primera
produce una pausa hasta que transcurran n segundos de tiempo (único parámetro de
entrada). La segunda puede adoptar las formas de: “uiwait(fig)” y/o “uiwait(fig, timeout)”.
En el primer caso, la ejecución del programa se detiene hasta que la figura fig sea eliminada
entrada timeout.
Una función que presenta una cierta relación con las anteriores es: “drawnow”, la
cual “obliga” al programa a actualizar los objetos gráficos contenidos en una figura.
Los segmentos de código que traspasen los 76 caracteres en una misma línea, son
muy mal vistos en MATLAB. Por ello, en el programa, se ha hecho uso frecuente del
operador “…”. Este operador, antecedido por un espacio, permite continuar un fragmento
por comas, la expresión “,…” permite establecer los siguientes elementos del arreglo, en la
línea siguiente.
Ejemplo 1:
Td = tao/((1-exp((-chi*tc^1.060)/0.870))* ...
(0.55+1.683*tc^(-1.090)));
Ejemplo 2:
c = [-1.1251,-0.9946,-1.1055,-1.0191,-1.0299,-0.9597,...
-1.0382,-0.9462];
directorio actual del trabajo. Como este valor se trata de una cadena, se posible producir
mediante dos formas. La primera de ellas es mediante el uso de la función “strcat”, cuyos
argumentos de entrada deben ser las distintas cadenas de texto que se van a unir. La
segunda forma consiste en agrupar las cadenas dentro de paréntesis cuadrados y separadas
por coma: “variable = [ 'cadena 1', 'cadena 2', 'cadena 3', …]”.
cumplir con tales objetivos, se emplea las funciones: str2num y num2str. Esta última tiene
quiere desplegar un número, el cual se sabe es menor que 1000 pero mayor que 0, con sólo
tres decimales, formato debe valer: '%7.3f', donde 7 corresponde a la cantidad de dígitos en
Tanto los arreglos numéricos como los de caracteres, utilizan expresiones similares
Arreglo de Caracteres:
colores = ['L','u','n','e','s'];
número de columna, cuyo valor debe ser el que se encuentra a la derecha de la igualdad.
utiliza la expresión: “valor = vector( n );” mientras que si se quiere obtener el valor de la
m-ésima fila y la n-ésima columna de una matriz, se usa la expresión “valor = matriz (m,
n);”.
un vector de 50 elementos, se quiere tomar los elementos que van del 10 al 20. La
expresión correcta que se debe emplear para cumplir la tarea anterior es: “vector(10:20)”.
Esto es, dentro de los paréntesis debe escribirse el índice del elemento inicial, dos puntos
(prima), el cual debe aplicarse a la derecha de la matriz. Por ejemplo, si se tiene un vector
fila vt, el vector columna correspondiente es vt'. Esto es sumamente importante para
[m,n] = size(A);
En el caso específico del trabajo con vectores, es más cómodo utilizar la función
devuelve el último elemento del vector (vector), una forma más simple conlleva la
último_elemento = vector(end);
“nulo”, para lo cual se emplea una línea semejante a la que se muestra a continuación:
vector = [];
respectivamente, a través de las funciones min y max. Una sintaxis semejante a la que se
muestra un párrafo adelante, es esencialmente útil para determinar no el valor máximo, sino
[valmx,I] = max(vector);
MATLAB (en lugar de paréntesis se usan llaves: “{ - }”). Para definir un arreglo de celda
celda1 = {1,2,3}
celda2 = {'Argentina','Hungría','Portugal','China'}
Los arreglos de celda pueden contener, como se ve del ejemplo anterior, valores
continúa siendo un arreglo de celda (1 x 1). Esto implica un especial cuidado cuando se
trabaja con arreglos de celda: muy útiles pero, algo complejos para manipular.
para cada tipo. En el caso de las ventanas se empleó el prefijo: “hV”, en el caso de los
paneles: “hPanel” y en el caso del grupo de botones: hGB. La “h” se debe al término
expresión que caracteriza la utilidad de las figuras: filtrado (F), simulación (Sim),
Los otros dos tipos de objetos, completan las variables de identificación con un
número entero positivo (el cual fue aumentando de uno en uno, según se creara un nuevo
objeto del mismo tipo). Por ejemplo, los paneles tienen identificadores almacenados en las
A continuación se muestra una lista de los nombres de las variables que contienen
Las figuras, al igual que el resto de los objetos que requiere el programa para su
funcionamiento, se crean por medio de funciones. Por medio de estas funciones se asignan
las propiedades iniciales de cada objeto. Las figuras constituyen el único objeto al cual es
permitido asignar un identificador, pues éstos son siempre, números enteros (tal y como se
figure(n);
Después de haber creado la figura, se asignan las propiedades iniciales que ésta
debe poseer (posición, color, visibilidad, estilo de ventana, etc.) por medio de la función
set.
En general y para efectos del programa, las figuras se crean, pero se vuelven
(WindowStyle). Los valores que puede tomar esta propiedad son: “normal”
“modal” se asigna cuando se quiere una ventana que capture cualquier tecla o pulso del
ratón para que, no se pueda acceder a otra que no sea ella. Finalmente, si se quiere contar
3.2).
Las propiedades más utilizadas de una figura durante el diseño del programa, junto
Propiedad Descripción
CloseRequestFcn Nombre de la función asociada al evento de
menús.
herramientas.
Para cualquier figura del programa, los valores de las propiedades “MenuBar”,
Los paneles son muy utilizados para clasificar objetos en grupos. Por ejemplo, para
la sección de “filtrado”, las etiquetas y los cuadros de texto asociados a la selección de los
parámetros del filtro Chebyshev Tipo I, responden todos a una función similar, por lo tanto,
Las principales propiedades de los paneles (al menos las que se utilizan en el
programa) son: “Position” (posición del objeto en la ventana), “Title” (título del panel),
Para mantener un orden adecuado, se utilizó un prefijo para todos los objetos
anteriores (excepto los para los “Ejes”). Para los botones de comando, las etiquetas, los
cuadros de texto, los botones de asignación, los botones de estado, las listas desplegables y
los botones de opción se hizo uso, de forma respectiva, de los prefijos: “bc”, “et”, “ct”,
“chbx”, “be”, “md” y “bo”. En todos estos objetos, el prefijo está seguido de un número (el
cual aumentó de uno en uno, según se fue creando un nuevo objeto del mismo tipo).
Para crear objetos “Ejes”, se hizo uso de la función “axes” y, más explícitamente de
la expresión:
hEjes = ...
axes('Parent',identificador_del_objeto_contenedor,'Units',...
unidades_utilizadas,'Position', vector_de_posición,'Color',...
vector_del_color,otras_propiedades...);
Propiedad Descripción
ColorOrder Secuencia de colores que debe seguirse cuando se
de escala (“Ticks”).
Además de ser útiles para desplegar curvas, los controles “Ejes” son requisito para
(archivo “tav.dtp”). Para mostrar la imagen, se debe crear un objeto “imagen” (“image”)
Para crear objetos “imagen”, se utiliza la función image y, en el caso del programa,
hIm = image(imread(nombre_del_archivo));
“imread”. Esta función devuelve un mapa de colores a partir del archivo – imagen que se
opcional, es útil para indicar el tipo de imagen que se ha de procesar (mapa de bits, ícono,
El resto de objetos estándar que se han utilizado (botones, cuadros de texto, listas y
“uicontrol”. Los argumentos de entrada de esta función son los n pares “nombre de
empleado en el programa:
Si bien se utiliza una misma función (“uicontrol”) para crear objetos como botones,
etiquetas y cuadros de texto, la diferencia se establece con la propiedad “Style”. Para los
botones de comando, las etiquetas, los cuadros de texto, los botones de asignación, los
botones de estado, las listas desplegables y los botones de opción la propiedad “Style” vale,
“radiobutton”.
Propiedad Descripción
BackgroundColor Color de fondo del objeto (vector).
habilitado.
La propiedad “Value” es muy importante para objetos específicos como los botones
de estado, los botones de asignación, las listas desplegables y los botones de opción. Para el
caso de los botones, el valor de la propiedad “Value” indica el estado del objeto ( 0: no
Para borrar de forma rápida los objetos contenidos en figuras y objetos “Ejes”, se
utilizan las funciones “clf” y “cla”. Pero, para eliminar objetos determinados, se utiliza la
función “delete”, cuyo argumento de entrada corresponde al identificador del elementro por
destruir.
de rojo, cantidad de verde y cantidad de azul). Los elementos, son valores normalizados,
operativo, esto quiere decir que, 0 equivale al 0 de la escala RGB sin normalizar y, 1
equivale a 255.
“unidades” las unidades normalizadas (“normalized”). Estas unidades son muy útiles para
ubicar objetos sin conocer las dimensiones exactas del contenedor (se trabaja con
gracias al uso de la propiedad “CData” (datos de color). Aquí se muestra una expresión
botones de comando:
imagen indexada que se obtiene del archivo, en "X" y, el mapa de colores asociado en
"mapa".
parámetro. Por esto, se emplea la función “ind2rgb” para convertir la estructura indexada
(par X-mapa) en un arreglo de vectores RGB (el valor que ha de pasarse a la propiedad
detalle gracias al uso de los objetos “texto”. La sintaxis de la función utilizada para crear
if length(den) == 2
dent = [num2str(den(1)),'s +',' ',num2str(den(2))];
else
dent = [num2str(den(1)),'s^2 + ',num2str(den(2)),...
's +',' ',num2str(den(3))];
end
texto = ['$$g_p(s)=\frac{',kpt,'}{',dent,'}\ e^{-',tmt,'s}$$'];
trate de un modelo de primer orden o uno de segundo orden más tiempo muerto. La
variable texto contiene el valor que se debe pasar como propiedad “String” al objeto
“texto”. La fracción no encierra todo el texto, su rango de definición se establece por medio
forma sencilla.
fondo).
seleccionar un miembre de un
grupo.
tabla.
Las dos primeras ventanas del programa deben desplegar imágenes animadas
(secuencia de cuadros). Este tipo de imágenes no se pueden mostrar por medio de los
objetos estándar de MATLAB, así que se utilizó un par de controles que únicamente sirven
se puede ver en la tabla anterior, sobre el fondo de la ventana (color gris) se estableció otro
fondo blanco. Este rectángulo blanco no debería aparecer, pues se supone que la figura no
ahí donde apareció el control “PlayGif”, que a diferencia del control “AnimatedGif”,
permite alterar el color del rectángulo blanco para que, no se note la frontera entre la
Cualquiera de los cuatro objetos se puede implementar mediante código por medio
de la línea:
El identificador de programa es una expresión tipo texto, que está asociada al tipo
función “[h, info] = actxcontrolselect” (con sus dos parámetros de salida). Esta función
devuelve en info, un arreglo de celda, del cual se puede obtener (en su segundo elemento,
que se especifica como su segundo parámetro de entrada (el primero es el identificador del
objeto “PlayGif”):
expresión RGB normalizada que adopta MATLAB para describir los colores no puede ser
largo entero.
propiedades se asignan por medio de la función set (sin importar que se trate de controles
ActiveX).
Propiedad Descripción
ElemAct Índice del elemento seleccionado (actual).
Propiedad Descripción
Col Columna de la celda seleccionada.
“negrita”.
“cursiva”.
seleccionada.
Para seleccionar una celda específica en la tabla del control “MS FlexGrid”, se debe
asignar los valores de “Row” y “Col” a los de la fila y la columna a la que la celda
pertenece.
El código del programa se demarcó mediante comentarios, para separar las distintas
Cerca del 60% del código (segmento superior) corresponde a funciones asociadas a
funciones son de la forma bcx_Callback, con “x” un número del 1 al 60, entonces
asociadas al evento de pulsar el botón derecho del apuntador sobre el área de etiquetas. Sin
encuentran asociadas al evento de petición de cierre de ventanas (de hecho, “x” representa
La creación de las ventanas no sólo implica la creación de figuras, sino que conlleva
una serie de instrucciones que permiten mostrar la ventana con todos sus objetos contenidos
(objetos Children). Todas estas rutinas se encuentran clasificadas en el código del programa
secuencia creciente de la forma L.x, donde “L” representa una letra distintiva de la ventana
tantas veces como grupos de rutinas exista. Ejemplos de estos grupos de rutinas son:
%F. Identificación:
hEI1 = axes('Units','pixels','Color',[1,1,1],'Position',...
[45,30,250,150],'Parent',hPanel11,'XColor',...
[1,1,1],'YColor',[1,1,1],'Visible','off');
%
hEI2 = axes('Units','pixels','Color',[1,1,1],'Position',...
[45,30,250,150],'Parent',hPanel12,'XColor',...
[1,1,1],'YColor',[1,1,1],'Visible','off');
%
hEI3 = axes('Units','pixels','Color',[1,1,1],'Position',...
[45,30,250,150],'Parent',hPanel13,'XColor',...
[1,1,1],'YColor',[1,1,1],'Visible','off');
%
hEI4 = axes('Units','pixels','Color',[1,1,1],'Position',...
[45,30,250,150],'Parent',hPanel14,'XColor',...
[1,1,1],'YColor',[1,1,1],'Visible','off');
Las funciones, al igual que los objetos gráficos, mantienen una jerarquía de objetos
que, en el caso de este programa tiene como elemento superior a la función principal. Una
vez que se ingresa (con el cursor) a un área externa a la función principal, se obtiene en la
barra de estado del editor de texto de MATLAB, una indicación similar a la siguiente:
. Este texto hace referencia a que todas las funciones (en este caso
bc8_Callback) están contenidas dentro de la función principal y por tanto, dependen ella.
niveles de jerarquía. Tal es el caso de la función básica “nyqplot” la cual invoca, para
cumplir con su misión, funciones como “circle”, “arrow” y “nlgrid”. Si no fuera por
“@Nombre_de_Función”.
Todos los objetos que requieren tratamiento de eventos, como es el caso de los
botones de comando, deben tener como valor de la propiedad asociada a la función del
botón bc22 sirve para aplicar un método de identificación, conocidos los datos de una
prueba de lazo abierto o cerrado. Las instrucciones necesarias para satisfacer la aplicación
del botón se deben colocar en una función (en este caso, se escogió una función llamada
“bc22_Callback”). Para asociar esta función con el llamado del botón “Callback” (por el
Cerca de un 25% del total del código del programa corresponde a funciones que, si
no se encuentran dentro del grupo de funciones básicas, analizadas en la sección 3.1. A este
llamados Callback de objetos gráficos” e incluye las rutinas que se muestran en la tabla
3.9.
El concepto de funciones “externas” para las funciones básicas, nació del hecho que
“Ejes” específico.
identificación
identificación.
Controlador" y/o
"Criterio Integral".
Controlador" y/o
"Criterio Integral".
o ninguno de ellos.
métodos de Sintonización
función nyqlog.
función graficorobus.
sección de Sintonización.
esencialmente útil cuando el número de variables puede diferir según la aplicación para la
cual la función fue invocada. Ya se estudió como ejemplo, la función básica filtrado.
marcha del programa. En distintos puntos del programa se crean archivos de texto o
imágenes que, tienen como finalidad complementar las distintas tareas específicas.
continuación:
status = fclose(idarc);
acceso al archivo (sólo escritura, sólo lectura, lectura-escritura, etc.) se especifica por
medio de una letra clave como segundo argumento de entrada en la función fopen. Esa letra
puede ser, por ejemplo, 'r', si se quiere abrir el archivo para lectura o 'r+', si se quiere abrirlo
para lectura y escritura. En “status” se devuelve un valor que indica si hubo errores al tratar
de cerrar el archivo.
Para escribir datos bajo formato, en archivos de texto, se utiliza la función fprintf,
cuenta = fprintf(idarc,formato,A,...);
Esta función escribe una líneas en el archivo que tiene como identificador a idarc,
formato. Esta última variable debe contener una expresión con términos de la forma “%x”
tales que especifiquen cómo deben ser interpretados los datos de la matriz. Por ejemplo, el
término “%s” indica que el dato debe ser interpretado como una cadena de texto, mientras
que, el término “%f” indica que el dato se debe interpretar como un número de punto
“%6.2f” (el valor debe ser escrito como un número de cuanto más 6 dígitos y 2 decimales).
extensión). Estos archivos pueden contener cualquier tipo de dato que salga de MATLAB,
por ejemplo: funciones de transferencia. La ventaja de usar esta clase de archivos es que,
MATLAB brinda funciones para leer y escribir de forma directa. Estas funciones son: load
y save. Sea el caso del programa, se quiere escribir una variable llamada “gpt” (la cual
posteriormente, en otra función, leer ese dato. Para ello se escriben las siguientes líneas de
código:
gpt=infog.gp1;
save([ruta,nombre],'gpt','-mat');
load('-mat',[ruta,nombarc]);
gp = gpt;
Como load y save, permiten trabajar con otros archivos además de los “.mat”, es
necesario indicar que, en este caso, se quiere utilizar tal tipo de archivo. La expresión
Para guardar el contenido de una figura como imagen (distintos formatos), se hace
Esa expresión copia todos los objetos de la ventana actual (gcf) sin incluir la barra
El programa, en sus distintas secciones, cuenta con trampas de error. Además de los
probar un conjunto de instrucciones que pueden provocar errores pero, en lugar de llevar al
programa a un estado de pausa o detención, establece otra serie de instrucciones para tratar
el error. La sección de instrucciones por probar va adentro del try (entre el try y el catch) y,
Se efectuó una prueba de lazo cerrado, sobre el proceso de caudal, del módulo de
proporcional de 30%.
datos como: los modos del controlador y las entradas y salidas analógicas no utilizadas para
132
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 133
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 50 100
0.1714082 50 100
3.746258 50 100
10.76899 50 100
primera opción:
datos. Para poder continuar se debe especificar, de forma válida, el tipo de prueba efectuada
(lazo abierto o lazo cerrado), la ganancia del controlador (en caso que la prueba fuese de
• Tipo de Prueba: Lazo Cerrado (se especifica al presionar una vez el botón “Lazo
Abierto”).
Para esto, se presionó el botón “…” y, a través del cuadro de diálogo de selección
numéricos, la primera línea en el archivo (que contiene el título de cada una de las
De paso, se observa que, para efectos de la identificación del modelo, los datos de la
salida del controlador no son necesarios por lo que, se elimina la tercera columna de datos.
De esta manera, el archivo resultante tiene como 15 primeras líneas las siguientes:
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 50
0.1714082 50
3.746258 50
10.76899 50
para incluir una columna de tiempos, a partir del periodo de muestra de datos.
nuevo cuadro de diálogo, esta vez, de entrada (solicitud de datos). Se especifica en este
trabajando sobre una prueba de lazo cerrado, la salida es la variable controlada (señal
realimentada) y, por tanto, el programa la especifica así (en color azul, por tratarse de una
1 2
Los datos pueden delimitarse para eliminar exceso de información. En este caso, se
aprecia que tanto al principio como al final de la prueba se puede recortar un poco los datos
de la prueba. Para hacer esto se arrastra las líneas señaladas, en la figura anterior, como “1”
y “2”, hacia la izquierda o derecha, según corresponda. Como regla general, se debe
considerar que en la definición de los límites, hay que contemplar por lo menos 10
muestras antes que se aplique el escalón en la entrada y 10 muestras al final, una vez
Se realiza, en este caso, una delimitación que considera los puntos que van desde
Figura 4.8 Reasignación de los límites para los datos de la prueba (ejemplo 1)
ejemplo). De esta forma, queda bajo el criterio del usuario la selección de un modelo
específico sobre los demás. De todas maneras, sólo se dispone de cuatro métodos de
identificación de lazo cerrado. Como la ventana de identificación cuenta con espacio para
este ejemplo, se aplican todos los métodos de identificación de lazo cerrado disponibles:
Yuwana y Seborg.
Jután y Rodríguez.
Lee.
Bogere y Özgen.
En las líneas anteriores se muestra, a manera de viñetas, los botones que se deben
presionar para “cargar” cada uno de los cuatro métodos. Estos botones se ubican en la barra
método. Basta como escoger el método pertinente de la lista y, pulsar el botón “OK”.
Una vez cargados los cuatro métodos; se despliegan las curvas de reacción, las
pestaña “Modelo”, que se encuentra justo encima de las curvas. En la siguiente figura, se
muestran las funciones de transferencia de dos de los modelos (tal y como se pueden ver en
el programa):
Para observar cada una de las curvas, con un mayor nivel de detalle, se cuenta con
ejemplo, se obtiene una vista con detalle de la curva de reacción asociada al modelo que se
+ Leyenda
+ Rotulado de Ejes
Figura 4.14 Vista con detalle de la curva de reacción asociada al método de “Jután y
Rodríguez”
Dos tareas adicionales que vale la pena estudiar en este ejemplo son: la posibilidad
Para guardar las curvas como archivos “.emf” se presiona el botón . Como
resultado, se obtienen cuatro archivos en la carpeta donde está instalado el programa. Los
archivos tienen un nombre que se halla caracterizado por el método que derivó cada una de
(Microsoft Word, StarOffice, etc.). Aquí, se tiene una muestra de una de las imágenes
producidas en el ejemplo:
Lee (POMTM)
110
100
90
80
Magnitud de la Señal
70
60
50
40
30
20
Entrada
10
Curva de Reacción, Modelo
0
0 2 4 6 8 10 12 14
Tiempo (seg)
Figura 4.15. Archivo imagen creado por el programa para las curvas de reacción
(ejemplo 1)
Como última fase de esta primera prueba, se quiere comparar las cuatro curvas en el
mismo sistema de ejes. Para hacerlo, se selecciona ( a través de los botones de asignación
ejemplo. El resto de métodos derivaron curvas de reacción, muy similares. El problema del
métodos, pues una de sus dos constantes de tiempo, vale cero; esto es, lo que debía ser un
POMTM
En este ejemplo, se simuló una prueba de lazo abierto efectuada sobre una planta de
tercer orden, con la presencia de ruido. Los datos se utilizan para identificar modelos
controladores PID y, el mejor modelo de todos (incluidos los modelos SOMTM) se usó
como planta en la simulación del sistema de control. A partir de las simulaciones con los
Para construir un modelo de orden alto que simule una planta y para efectuar a
simulación. Esta ventana, solicita los siguientes datos: Inicio del escalón, magnitud del
escalón, período de la muestra, tiempo final, función de transferencia del proceso, tiempo
0.925
• Función de transferencia:
(3.5 s + 1)⋅ (4.7 s + 1)⋅ (5.8 s + 1)
Para obtener una vista preliminar de la curva de reacción simulada, se pulsa el botón
“ejemplo2.mod”:
aún resta generar un archivo que contenga los datos de la prueba de lazo abierto. Para
cumplir con este objetivo, se presiona el botón “Crear Archivo”. El archivo se guarda como
“prueba_lazab.dat”.
Una vez finalizadas las dos tareas anteriores, se presiona el botón “<< Anterior” y,
En la ventana de vista previa de las curvas de la prueba, se establece que los datos
filtro que pueda ser aplicado a la señal de salida del proceso, para reducir el efecto del
ruido.
Para aplicar cada uno de los filtros se pulsa el botón que tiene el signo de
asignación: .
El resultado de aplicar los cuatro tipos de filtro sobre la señal de salida se muestra a
continuación:
Figura 4.22 Aplicación de los cuatro tipos de filtro sobre la señal de salida (ejemplo 2)
eficiencia de cada uno de los filtros; se escogió el filtro Elíptico pues, para este caso,
demostró contar con una mejor atenuación del ruido, sobretodo en las regiones iniciales y
finales de la curva (de suma importancia para la estimación de la ganancia del proceso), sin
alterar su forma.
1.8
1.6
1.4
Magnitud de la Señal
1.2
0.8
0.6
0.4 Entrada
Salida
0.2
Salida Filtrada
0
0 10 20 30 40 50 60 70
Tiempo (seg)
planta. Para acceder a la ventana respectiva basta con presionar el botón “Siguiente >>”.
Con el objetivo de establecer los mejores métodos (POMTM, SOMTM polo doble y
derivó el mejor modelo POMTM (con un error S2 = 0.63802), Ho et al., el mejor modelo
SOMTM polo doble (con un error S2 = 0.11019) y, Stark, el mejor modelo de todos (con un
error S2 = 0.63802).
utiliza para efectos de sintonización, mientras que, el modelo obtenido a partir del método
Dentro del proceso estimación de los mejores modelos, se generó un archivo que
contiene todos los métodos, con el índice de error S2, producto de aplicarlos sobre la curva
se muestran a continuación:
0.92334 − 9.8738 s
G p (s) = e (Alfaro POMTM)
9.4166 s + 1
0.02169
G p ( s) = e −6.1669 s (Stark)
s + 0.2906 s + 0.02349
2
0.925
apenas el 0.18%, respecto al modelo original: e − 4.15 s . La
(3.5 s + 1)⋅ (4.7 s + 1)⋅ (5.8 s + 1)
suma de la constante de tiempo y el tiempo muerto para el modelo POMTM, presenta sólo
un error del 6.28%, respecto a la suma de constantes de tiempo y el tiempo muerto del
presiona el botón “Modelo Elegido” tantas veces como sea necesario, para desplegar en él
el nombre del método que produjo el modelo ( Alfaro ). Como paso siguiente se pulsa el
diagrama de Nyquist, gráfico de robustez y curva de lazo cerrado, así como también, los
parámetros de la respuesta en el tiempo y los valores de las integrales del error. Todo esto
se logra, con sólo asignar un valor del tiempo final (110 segundos) y, posteriormente,
presionar el botón “Graficar”. Pero, antes se tuvo que considerar las siguientes dos
valor “S”.
en las simulaciones de lazo cerrado. Esto se puede confirmar a partir de los parámetros que
Figura 4.25 Modelo empleado como planta en las simulaciones de control (Stark)
tiempo de asentamiento), junto con los valores de las integrales del error: IAE, ITAE e ISE,
controladores.
parámetros de la respuesta y los valores de las integrales del error, en la figura 4.28.
(ejemplo 2)
Figura 4.27 Parámetros de la respuesta de lazo cerrado y valores de las integrales del
error (ejemplo 2)
PID de Kaya y Sheib conduce a respuestas sin sobrepaso máximo, presenta una respuesta
porciento de casi el doble del tiempo de asentamiento al dos porciento de la respuesta del
controlador PID de Alfaro. Esto es, el controlador PI implica una respuesta que tarda más
respuesta de Rovira no produjo un valor del ITAE menor al de las respuestas de los otros
Como era de suponer, el controlador de Alfaro, arroja el menor valor IAE pero,
5.1 Conclusiones
siguiente:
programa, ha sido desarrollado en MATLAB 7.0 y cuenta con una interfaz gráfica
160
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 161
muestran a continuación:
entrada y salida.
(diagrama de Nyquist).
ventana.
lazo abierto). Es posible utilizar este modelo como planta, en las simulaciones del
lazo de control.
Chebyshev Tipo II y Elíptico) sobre los datos de las pruebas (lazo abierto o lazo
cerrado). La ventana que está asociada a la etapa de filtrado de datos, cuenta con las
5.2 Recomendaciones
A continuación se establece una serie de recomendaciones para desarrollar nuevos
programa.
PSIID.
otras.
[1] Aguilera, M., C. Marín, y F. Porras. “Guía para la creación de una interfaz
Ingeniería Eléctrica, Universidad de Costa Rica, San José, Costa Rica, 2002.
de Ingeniería Eléctrica, Universidad de Costa Rica, San José, Costa Rica, 2002.
165
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 166
Páginas web:
msdn.microsoft.com/library/en-us/vbcmn/html/vboripropertiesactivexctls.asp
help/helpdesk.html
www.mathworks.com/matlabcentral/fileexchange
all.htm
168
1
2
3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 %% %%%%%%%% %%%%%%%%%%%%
6 %%% %%%%%%% UNIVERSIDAD DE COSTA RICA %%%%%%%%%%%%
7 %% %%%%%% ESCUELA DE INGENIERÍA ELÉCTRICA %%%%%%%%%%%%
8 % %% %%%%% DEPARTAMENTO DE AUTOMÁTICA %%%%%%%%%%%%
9 %% %% %%%% %%%%%%%%%%%%
10 %% %% %%% ---------- %%%%%%%%%%%%
11 %% %% %% " PSIID " %%%%%%%%%%%%
12 % %% %% % ---------- %%%%%%%%%%%%
13 %% %% %% %%%%%%%%%%%%
14 %%% %% %% PROGRAMADOR: MIGUEL AGUILERA CHAVES %%%%%%%%%%%%
15 %%%% %% %% (A20102) %%%%%%%%%%%%
16 %%%%% %% % %%%%%%%%%%%%
17 %%%%%% %% DICIEMBRE DEL 2005 %%%%%%%%%%%%
18 %%%%%%% %% %%%%%%%%%%%%
19 %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20 %%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21
22
23 function principal()
24 clc; clear;
25 warning off;
26
27 %Preparar archivos:
28 try
29 delete([pwd,'\ext\*.dtp']); delete([pwd,'\ext\*.dai']);
30 delete([pwd,'\ext\*.zip']);
31 copyfile([pwd,'\ext\agaussz.bin'],[pwd,'\ext\agaussz.zip']);
32 unzip([pwd,'\ext\agaussz.zip'],[pwd,'\ext']);
33 copyfile([pwd,'\ext\agaussz.zip'],[pwd,'\ext\agaussz.bin']);
34 delete([pwd,'\ext\*.zip']);
35 catch
36 return;
37 end
38
39 %Dimensiones de la Pantalla (en píxeles)
40 tPant = get(0,'ScreenSize');
41
42 %A. LOGOTIPO DEL PROGRAMA:
43
44 % A.1. Creación de la Figura
45 PosVE = [tPant(3)/2-225 tPant(4)/2-150 450 300];
46 hVE = 2; figure(hVE); delete(gca); clf;
47 set(hVE,'Color',[0.961,0.961,0.961],'MenuBar','none','Resize',...
48 'off','WindowStyle','modal','Position',PosVE,'NumberTitle',...
49 'off','Name',' ','Visible','off');
50
51 % A.2. Creación de un Control Axes para Desplegar Imagen de Fondo
52 hFondo = axes('Units','pixels','Color',[0.961 0.961 0.961] ,...
169
IE-0502 Identificación de procesos y sintonización de controladores PID en MATLAB 7.0 170
53 'Position',[10,40,430,150],'XTick',[],'YTick',[],'XColor',...
54 [0.961 0.961 0.961],'YColor',[0.961 0.961 0.961]);
55 logo = [pwd,'\ext\ram.dtp'];
56 image(imread(logo));
57 set(hFondo,'XTick',[],'YTick',[]);
58
59 % A.3. Creación de una Etiqueta para Desplegar el texto:
60 % "INGENIERÍA ELÉCTRICA"
61 uicontrol('Style','text','Position',[25,190,400,50],'FontName',...
62 'Tahoma','FontSize',15,'FontWeight','bold','String',...
63 {'INGENIERÍA ELÉCTRICA','DEPARTAMENTO DE AUTOMÁTICA'},...
64 'BackgroundColor',[0.961,0.961,0.961],'FontAngle','italic',...
65 'ForegroundColor',[0.2,0.4,0.8]);
66
67 % A.4. Creación de una Etiqueta para Desplegar el texto:
68 % "UNIVERSIDAD DE COSTA RICA"
69 uicontrol('Style','text','Position',[15,240,420,40],'FontName',...
70 'Tahoma','FontSize',20,'FontWeight','bold','String',...
71 'UNIVERSIDAD DE COSTA RICA',...
72 'BackgroundColor',[0.961,0.961,0.961],'FontAngle','italic',...
73 'ForegroundColor',[0.2,0.4,0.8]);
74
75 % A.5. Creación de una Etiqueta para Desplegar el texto: "Versión 1.0"
76 uicontrol('Style','text','Position',[350,0,90,30],'FontSize',11,...
77 'HorizontalAlignment','right','String','Versión 1.0',...
78 'FontWeight','bold','BackgroundColor',[0.961,0.961,0.961]);
79
80 % A.6. Creación de ActiveX para Visualizar Animación GIF (cargando...)
81 gif1 = actxcontrol('ANIMATEDGIF.AnimatedGifCtrl.1',[15,5,70,20],hVE);
82 archivo = [pwd,'\ext\mig.dai'];
83 set(gif1,'AnimatedGif',archivo); gif1.Play;
84 set(hVE,'Visible','on');
85
86 % A.7. Mantener abierta la ventana por 3.5 segundos, después cerrarla
87 pause(3.5); set(hVE,'Visible','off');
88 drawnow; delete(hVE);
89
90 %B. VENTANA DE INTRODUCCIÓN AL PROGRAMA:
91
92 clc;
93 % B.1. Creación de la Figura
94 PosVInt = [tPant(3)/2-300 tPant(4)/2-150 600 300];
95 hVInt = 3; figure(hVInt); delete(gca); clf;
96 set(hVInt,'MenuBar','none','Resize','off','WindowStyle',...
97 'modal','Position',PosVInt,'NumberTitle','off','Name',...
98 'Ventana de Introducción','Color',[0.839,0.914,0.996],'Visible',...
99 'off');
100
101 % B.2. Creación del Grupo de Botones
102 hGB = uibuttongroup('Visible','off','Position',[0.05,0.15,0.9,0.6],...
103 'BackgroundColor',[0.918,0.957,1]);
104
261 set(gif2,'BackgroundColor',15921906);
262 Play(gif2); %reproducir la animación
263
264 % C.9. Mostrar la Figura y Actualizar la Estructura infog
265 set(hVAdq,'Visible','on');
266 infog.bc2 = bc2; infog.ct1 = ct1; infog.et10 = et10;
267 infog.bc3 = bc3; infog.ct2 = ct2; infog.bc4 = bc4;
268 infog.hVAdq = hVAdq;
269 %
270 elseif get(infog.bo2,'Value') == infog.Max %El usuario ha escogido
271 %G. SIMULACIÓN DE UN PROCESO: la 2da opción!
272
273 % G.1. Creación de la Figura
274 PosVSim = [tPant(3)/2-333.5 tPant(4)/2-164 667 328];
275 hVSim = 8; figure(hVSim); delete(gca); clf;
276 set(hVSim,'MenuBar','none','Resize','off','WindowStyle',...
277 'normal','Position',PosVSim,'NumberTitle','off','Name',...
278 'Simulación de la Curva de Reacción de un Proceso',...
279 'Visible','off','Color',[0.949,0.949,0.949],...
280 'CloseRequestFcn',@hVSim_CloseRequestFcn);
281 set(infog.hVInt,'Visible','off'); %Cerrar figura anterior
282
283 % G.2. Creación de Paneles
284 %
285 %Panel 1 (Entrada al Proceso)
286 hPanel24 = uipanel('Position',[0.019,0.598,0.348,0.357],...
287 'BackgroundColor',[0.949,0.949,0.949],'Title',...
288 'Entrada al Proceso:','Parent',hVSim);
289
290 %Panel 2 (Datos del Proceso)
291 hPanel25 = uipanel('Position',[0.022,0.317,0.343,0.274],...
292 'BackgroundColor',[0.949,0.949,0.949],'Title',...
293 'Datos del Proceso:','Parent',hVSim);
294
295 %Panel 3 (Muestra)
296 hPanel26 = uipanel('Position',[0.378,0.104,0.604,0.854],...
297 'BackgroundColor',[0.949,0.949,0.949],'Title',...
298 'Muestra:','Parent',hVSim);
299
300 % G.3. Creación de Etiquetas
301 %
302 %Sección: Entrada al Proceso
303 et52 = uicontrol('Parent',hPanel24,'BackgroundColor',...
304 [0.949,0.949,0.949],'HorizontalAlignment','right',...
305 'Position',[26,81,121,15],'String',['Inicio del Escalón (',...
306 'seg):'],'Style','text');
307 et53 = uicontrol('Parent',hPanel24,'BackgroundColor',...
308 [0.949,0.949,0.949],'HorizontalAlignment','right',...
309 'Position',[26,59,121,15],'String','Magnitud del Escalón:',...
310 'Style','text');
311 et54 = uicontrol('Parent',hPanel24,'BackgroundColor',...
312 [0.949,0.949,0.949],'HorizontalAlignment','right',...
365 %
366 % Botón Vista Previa
367 bc35 = uicontrol('Parent',hVSim,'Callback',@bc35_Callback,...
368 'Position',[141,40,100,22],'String','Vista Previa >>',...
369 'Style','pushbutton');
370 %
371 % Botón <<Anterior
372 bc36 = uicontrol('Parent',hVSim,'Callback',@bc36_Callback,...
373 'Position',[15,7,100,22],'String','<< Anterior',...
374 'Style','pushbutton');
375 %
376 % Botón "Crear Archivo"
377 bc37 = uicontrol('Parent',hVSim,'Callback',@bc37_Callback,...
378 'Position',[551,6,100,22],'String','Crear Archivo',...
379 'Style','pushbutton');
380 %
381 % Botón "Guardar Modelo"
382 bc38 = uicontrol('Parent',hPanel25,'Callback',@bc38_Callback,...
383 'Position',[190,8,26,26],'String',' ',...
384 'Style','pushbutton');
385 %
386 %Cargar información de la imagen
387 [celda,mapa] = imread([pwd,'\ext\jac.dtp'],'gif');
388 %
389 %Convertir de indexado a directo (RGB)...
390 celda = ind2rgb(celda,mapa);
391 %
392 %Colocar imagen en el botón
393 set(bc38,'CData',celda);
394
395 % G.7. Guardar información en la variable global y mostrar la ...
396 % ventana
397 infog.hVSim = hVSim; infog.ct15 = ct15; infog.ct16 = ct16;
398 infog.ct17 = ct17; infog.ct18 = ct18; infog.ct19 = ct19;
399 infog.ct20 = ct20; infog.ct21 = ct21; infog.hESim = hESim;
400 %
401 set(hVSim,'Visible','on');
402 else
403 %Mostrar Ventanas: "Sintonización"
404 infog.svant = 1; infog.sigp = 0;
405 mostrarsinto;
406 end
407
408 %Subrutina de Llamado al Botón bc2 (Lazo Abierto/Cerrado)
409 function bc2_Callback(varargin)
410 global infog;
411 %Si dice 'Lazo Abierto' => cambiar a 'Lazo Cerrado'
412 %y mostrar el cuadro de texto para la ganancia Kc
413 if get(infog.bc2,'String') == 'Lazo Abierto'
414 set(infog.bc2,'String','Lazo Cerrado');
415 set(infog.bc2,'BackgroundColor',[0,0,1]);
416 set(infog.bc2,'ForegroundColor',[0,0,1]);
417 set(infog.et10,'FontAngle','normal','ForegroundColor',...
418 [0,0,0]);
419 set(infog.ct1,'Enable','on');
420 %Si no (entonces dice 'Lazo Cerrado') => cambiar a 'Lazo Abierto'
421 %y ocultar el cuadro de texto para la ganancia Kc
422 else
423 set(infog.bc2,'String','Lazo Abierto');
424 set(infog.bc2,'BackgroundColor',[1,0,0]);
425 set(infog.bc2,'ForegroundColor',[1,0,0]);
426 set(infog.et10,'FontAngle','italic','ForegroundColor',...
427 [0.450,0.450,0.450]);
428 set(infog.ct1,'Enable','off');
429 set(infog.ct1,'String','0');
430 end
431
432 %Subrutina de Llamado al Botón bc3 (...)
433 function bc3_Callback(varargin)
434 global infog;
435 [archivo,ruta,F] = uigetfile({'*.dat','Archivo de Datos (*.dat)';...
436 '*.txt', 'Archivo de Texto (*.txt)';'*.*',['Todos los ar',...
437 'chivos (*.*)']}, 'Seleccione un Archivo');
438 if F ~= 0
439 set(infog.ct2,'String',[ruta,archivo]);
440 end
441
442 %Subrutina de Llamado al Botón bc4 (Siguiente>>)
443 function bc4_Callback(varargin)
444 global infog;
445 tPant = infog.tPant;
446 archivo = get(infog.ct2,'String');
447 %
448 %Cuadro de Diálogo para Especificar Archivo de Datos
449 [id_arc,mensaje] = fopen(archivo, 'r');
450 %
451 %Tratamiento de Errores (basado en el mensaje reportado por la...
452 %función fopen)
453 if length(strtrim(mensaje)) ~= 0
454 switch length(strtrim(mensaje))
455 case 25 %Longitud Efectiva de mensaje = 25
456 if length(strtrim(archivo)) == 0
457 errordlg(['No se especificó un archivo, en el c',...
458 'uadro de texto !'],'Error');
459 else
460 errordlg(['El archivo que se especificó no es v',...
461 'álido !'],'Error');
462 end
463 case 55 %Longitud Efectiva de mensaje = 55
464 if length(strtrim(archivo)) == 0
465 errordlg(['No se especificó un archivo, en el c',...
466 'uadro de texto !'],'Error');
467 else
468 errordlg(['Imposible abrir el archivo especifica',...
573
574 %D. VISTA PREVIA DE LOS DATOS:
575
576 % D.1. Creación de la Figura
577 PosVP = [tPant(3)/2-250 tPant(4)/2-225 500 450];
578 hVVP = 5; figure(hVVP); delete(gca); clf;
579 set(hVVP,'Color',[0.961,0.961,0.961],'MenuBar','none','Resize',...
580 'off','WindowStyle','normal','Position',PosVP,'NumberTitle',...
581 'off','Name','Vista Previa de los Datos de la Prueba','Visible',...
582 'off','CloseRequestFcn',@hVVP_CloseRequestFcn);
583
584 % D.2. Creación del Panel que Contiene al Control Axes
585 hPanel1 = uipanel('Position',[0.15,0.1,0.7,0.62],'BorderType',...
586 'etchedin','BackgroundColor',[1,1,1],'Parent',hVVP);
587
588 % D.3. Creación de un Control Axes para la Vista Previa
589 hEVP = axes('Units','pixels','Color',[0.835 0.929 1] ,...
590 'Position',[30,30,300,200],'Parent',hPanel1,'XColor',...
591 [1,1,1],'YColor',[1,1,1]);
592
593 % D.4. Creación de las Etiquetas
594 %
595 %Etiqueta '3.'
596 et12 = uicontrol('Style','Text','pos',[10,390,50,50],'Parent',...
597 hVVP,'FontName','Arial','FontSize',28,'String','3.',...
598 'FontWeight','bold','ForegroundColor',[0,0,0.510],...
599 'BackgroundColor',[0.961,0.961,0.961]);
600 %
601 %Etiquetas de Información:
602 et13 = uicontrol('Style','Text','pos',[70,400,415,20],'Parent',...
603 hVVP,'FontName','Arial','FontSize',11,'String',['Los d',...
604 'atos se han interpretado con éxito, pero es necesario q',...
605 'ue'],'BackgroundColor',[0.961,0.961,0.961],...
606 'HorizontalAlignment','left');
607 et14 = uicontrol('Style','Text','pos',[40,375,375,20],'Parent',...
608 hVVP,'FontName','Arial','FontSize',11,'String',['especif',...
609 'ique a cuál columna corresponden los datos de la'],...
610 'BackgroundColor',[0.961,0.961,0.961],...
611 'HorizontalAlignment','left');
612 if tipopr == 1
613 txt1 = ' variable'; %si la prueba es de LC
614 txt2 = 'controlada';
615 txt3 = 'referencia';
616 colorf = [0,0,1]; xpos = 112;
617 else
618 txt1 = ' salida'; %si la prueba es de LA
619 txt2 = 'del proceso';
620 txt3 = 'entrada del proceso';
621 colorf = [1,0,0]; xpos = 120;
622 end
623 et15 = uicontrol('Style','Text','pos',[413,375,60,20],'Parent',...
624 hVVP,'FontName','Arial','FontSize',11,'String',txt1,...
625 'ForegroundColor',color,'BackgroundColor',...
626 [0.961,0.961,0.961],'HorizontalAlignment','left',...
627 'FontAngle','italic');
628 et16 = uicontrol('Style','Text','pos',[40,350,80,20],'Parent',...
629 hVVP,'FontName','Arial','FontSize',11,'String',txt2,...
630 'ForegroundColor',color,'BackgroundColor',...
631 [0.961,0.961,0.961],'HorizontalAlignment','left',...
632 'FontAngle','italic');
633 et17 = uicontrol('Style','Text','pos',[xpos,350,75,20],'Parent',...
634 hVVP,'FontName','Arial','FontSize',11,'String',[': _',...
635 ' .'],'BackgroundColor',[0.961,0.961,0.961],...
636 'HorizontalAlignment','left','FontAngle','italic');
637 et18 = uicontrol('Parent',hPanel1,'Style','Text','pos',...
638 [10,247,100,20],'FontName','Arial','FontSize',11,'String',...
639 'Vista Previa:','BackgroundColor',[1,1,1],...
640 'HorizontalAlignment','left','FontWeight','bold');
641 %
642 %Etiquetas para recordar al usuario que la curva naranja ...
643 %corresponde a la entrada
644 et44 = uicontrol('Parent',hPanel1,'Style','Text','pos',...
645 [180,240,150,15],'FontName','Arial','FontSize',8.5,...
646 'HorizontalAlignment','left','FontAngle','italic',...
647 'String',['x:',' ',strtrim(txt1),' ',strtrim(txt2)],...
648 'ForegroundColor',colorf,'BackgroundColor',[1,1,1]);
649 et45 = uicontrol('Parent',hPanel1,'Style','Text','pos',...
650 [180,255,150,15],'FontName','Arial','FontSize',8.5,...
651 'HorizontalAlignment','left','FontAngle','italic',...
652 'String',['x:',' ',txt3],'ForegroundColor',...
653 [0.5,0,0.5],'BackgroundColor',[1,1,1]);
654 %
655 %Etiqueta para Mostrar la Delimitación de los Datos
656 et60 = uicontrol('Parent',hVVP,'Style','Text','pos',...
657 [200,20,100,20],'BackgroundColor',[1,1,1],...
658 'ForegroundColor',[1,0,0],'HorizontalAlignment','center',...
659 'FontSize',8,'FontAngle','italic','String','Delimitación');
660
661 % D.5. Creación del Menú Desplegable (para seleccionar la columna
662 % del vector vy)
663 md1 = uicontrol('Style','popupmenu','Position',[xpos+10,356,40,20],...
664 'Parent',hVVP,'FontName','Arial','FontSize',9,'String',...
665 {'1','2','3'},'BackgroundColor',[1,1,0.8],...
666 'HorizontalAlignment','left','Callback',@md1_Callback);
667
668 % D.6. Creación del Botón de Comandos (Siguiente)
669 bc6 = uicontrol('Style','pushbutton','pos',[425,10,70,25],...
670 'Parent',hVVP,'String','Siguiente >>','Callback',...
671 @bc6_Callback,'Enable','off');
672
673 % D.7. Creación del Botón de Comandos (Anterior)
674 bc7 = uicontrol('Style','pushbutton','pos',[15,10,70,25],...
675 'Parent',hVVP,'String','<< Anterior','Callback',...
676 @bc7_Callback);
677
678 % D.8. Desaparecer figura Anterior y Mostrar la Actual
679 set(infog.hVAdq,'Visible','off');
680 pause(0.5); set(infog.hVAdq,'Visible','off');
681 drawnow;
682 set(hVVP,'Visible','on');
683
684 % D.9. Actualizar la Variable Global infog
685 infog.archivo = archivo; infog.md1 = md1; infog.hEVP = hEVP;
686 infog.bc6 = bc6; infog.vyColor = colorf; infog.hVVP = hVVP;
687 infog.tipopr = tipopr; infog.et60 = et60;
688
689 %Subrutina de Llamado al Botón bc5 (<<Anterior)
690 function bc5_Callback(varargin)
691 global infog;
692 set(infog.hVInt,'Visible','on');
693 pause(0.5); set(infog.hVAdq,'Visible','off');
694 drawnow;
695 delete(infog.hVAdq);
696
697 %Subrutina de Llamado al Botón bc7 (<<Anterior)
698 function bc7_Callback(varargin)
699 global infog;
700 set(infog.hVAdq,'Visible','on');
701 delete(infog.hVVP);
702
703 %Subrutina de Llamado al Menú Desplegable (Columna de vy)
704 function md1_Callback(varargin)
705 global infog;
706 %
707 %Determinar los vectores vt, vu y vy, basado en la posición del
708 %vector vy (que el usuario estableció)
709 posvy = get(infog.md1,'Value');
710 [vt,vu,vy]=adquisicion(infog.archivo,posvy);
711 %
712 gca = infog.hEVP; %Seleccionar el Objeto Ejes
713 vyColor = infog.vyColor; %Color del vector vy: rojo (salida del ...
714 % proceso), azul (variable controlada)
715 set(gca,'NextPlot','replacechildren');
716 set(gca,'ColorOrder',[[0.5,0,0.5];vyColor]);
717 plot(vt,vu,vt,vy); %Mostrar Curvas
718 set(gca,'Color',[0.925,1,0.961],'XColor',[0,0.502,0.251],...
719 'YColor',[0,0.502,0.251]); %Ajustar Propiedades del Control Ejes
720 grid on; %Agregar cuadrícula
721 %
722 dmy = get(gca,'YLim'); hold on;
723 lin1 = line([vt(1),vt(1)],[dmy(1),dmy(2)],'LineWidth',2,'Color',...
724 [1,0,0],'ButtonDownFcn',@moverlinea1);
725 lin2 = line([vt(end),vt(end)],[dmy(1),dmy(2)],'LineWidth',2,...
726 'Color',[0,0,1],'ButtonDownFcn',@moverlinea2);
727 %
728 set(infog.bc6,'Enable','on');
729 %
730 %Información de la Variable Global
731 infog.vto = vt; infog.vuo = vu; infog.vyo = vy; %Guardar valores orig
732 infog.vt = vt; infog.vu = vu; infog.vy = vy;
733 infog.limizq = vt(1); infog.limder = vt(end);
734
735
736 %Subrutina de Llamado al Botón bc6 (Siguiente>>)
737 function bc6_Callback(varargin)
738 global infog;
739 tPant = infog.tPant;
740
741 if infog.limizq >= infog.limder
742 errordlg(['La selección del intervalo de datos que se utiliza',...
743 'rán para las etapas posteriores, es incorrecta !'],'Error');
744 return;
745 end
746 %
747 %Definir los nuevos vectores de tiempo, entrada y salida, con base
748 % en la delimitación propuesta por el usuario
749 [ND,I1]=min(abs(infog.vto-infog.limizq));
750 [ND,I2]=min(abs(infog.vto-infog.limder));
751 tin = infog.vto(I1); tfi = infog.vto(I2);
752 vx = infog.vto(I1:I2); infog.vt = vx-tin;
753 infog.vu = infog.vuo(I1:I2); infog.vy = infog.vyo(I1:I2);
754
755 %E. FILTRADO:
756
757 % E.1. Creación de la Figura
758 PosVF = [tPant(3)/2-400 tPant(4)/2-300 800 600];
759 hVF = 6; figure(hVF); delete(gca); clf;
760 set(hVF,'Color',[0.961,0.961,0.961],'MenuBar','none','Resize',...
761 'off','WindowStyle','normal','Position',PosVF,'NumberTitle',...
762 'off','Name','Selección del Filtro','Visible',...
763 'off','CloseRequestFcn',@hVF_CloseRequestFcn);
764
765 % E.2. Creación de los Paneles que Contienen los Controles Axes,
766 % la Barra y los Parámetros
767 %
768 %Panel 1 (Gráfico - Butterworth)
769 hPanel2 = uipanel('Position',[0.01,0.46,0.4,0.35],'BorderType',...
770 'etchedin','BackgroundColor',[1,0.922,0.843],'Parent',hVF);
771 %
772 %Panel 2 (Gráfico - Chebyshev I)
773 hPanel3 = uipanel('Position',[0.42,0.46,0.4,0.35],'BorderType',...
774 'etchedin','BackgroundColor',[0.988,1,0.824],'Parent',hVF);
775 %
776 %Panel 3 (Gráfico - Chebyshev II)
777 hPanel4 = uipanel('Position',[0.01,0.1,0.4,0.35],'BorderType',...
778 'etchedin','BackgroundColor',[0.851,1,0.851],'Parent',hVF);
779 %
780 %Panel 4 (Gráfico - Elíptico)
937 'HorizontalAlignment','left','Position',...
938 [3 4.92307692307692 5 1.23076923076923],...
939 'String','N =','Style','text');
940 et36 = uicontrol('Parent',hPanel10,'Units','characters',...
941 'BackgroundColor',[0.831 0.8316096 0.860],...
942 'HorizontalAlignment','left','Position',...
943 [3 3.53846153846154 6.4 1.23076923076923],...
944 'String','w =','Style','text','FontName','Arial');
945 et37= uicontrol('Parent',hPanel10,'Units','characters',...
946 'BackgroundColor',[0.831 0.8316096 0.860],...
947 'HorizontalAlignment','left','Position',...
948 [4.6 3.07692307692308 2 1.15384615384615],'FontAngle',...
949 'italic','FontName','Arial','FontSize',7,'String','c',...
950 'Style','text');
951 et38 = uicontrol('Parent',hPanel10,'Units','characters',...
952 'BackgroundColor',[0.831 0.8316096 0.860],...
953 'HorizontalAlignment','left','Position',...
954 [3 2.15384615384615 6.4 1.23076923076923],...
955 'String','R =','Style','text','FontName','Arial');
956 et39 = uicontrol('Parent',hPanel10,'Units','characters',...
957 'BackgroundColor',[0.831 0.8316096 0.860],...
958 'HorizontalAlignment','left','Position',...
959 [4.4 1.76923076923077 2 1.15384615384615],'FontAngle',...
960 'italic','FontName','Arial','FontSize',7,'String','p',...
961 'Style','text');
962 et40 = uicontrol('Parent',hPanel10,'Units','characters',...
963 'BackgroundColor',[0.831 0.8316096 0.860],...
964 'HorizontalAlignment','left','Position',...
965 [3 0.615384615384615 6.4 1.23076923076923],...
966 'String','R =','Style','text','FontName','Arial');
967 et41 = uicontrol('Parent',hPanel10,'Units','characters',...
968 'BackgroundColor',[0.831 0.8316096 0.860],...
969 'HorizontalAlignment','left','Position',...
970 [4.4 0.230769230769231 2 1.15384615384615],'FontAngle',...
971 'italic','FontName','Arial','FontSize',7,'String','s',...
972 'Style','text');
973 %
974 %Etiqueta "Respuesta de la Señal Filtrada"
975 et42 = uicontrol('Parent',hVF,'Units','pixels',...
976 'BackgroundColor',[0.961 0.961 0.961],...
977 'HorizontalAlignment','left','Position',...
978 [15 490 220 20],'FontAngle','italic','FontName','Arial',...
979 'FontSize',10,'String','Respuesta de la Señal Filtrada:',...
980 'FontWeight','bold','ForegroundColor',[0,0,0.502],...
981 'Style','text');
982 %
983 %Etiqueta "Filtro Seleccionado"
984 et43 = uicontrol('Parent',hPanel6,'Units','normalized',...
985 'BackgroundColor',[0.831,0.831,0.831],...
986 'HorizontalAlignment','center','Position',...
987 [0.1 0.075 0.8 0.055],'FontName','Arial','FontSize',7.5,...
988 'String','Filtro Seleccionado','FontWeight','bold',...
989 'Style','text');
990
991 % E.5. Creación de las Cuadros de Texto (Barra)
992 %
993 %Cuadros de Texto Sección Parámetros: Butterworth
994 ct3 = uicontrol('Parent',hPanel7,'Units','characters',...
995 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
996 'Position',[9,2.07692307692308,5,1.15384615384615],...
997 'String','1','Style','edit');
998 ct4 = uicontrol('Parent',hPanel7,'Units','characters',...
999 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1000 'Position',[9,0.692307692307692,6,1.15384615384615],...
1001 'String','0.5','Style','edit');
1002 %
1003 %Cuadros de Texto Sección Parámetros: Chebyshev I
1004 ct5 = uicontrol('Parent',hPanel8,'Units','characters',...
1005 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1006 'Position',[9,3.53846153846154,5,1.15384615384615],...
1007 'String','1','Style','edit');
1008 ct6 = uicontrol('Parent',hPanel8,'Units','characters',...
1009 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1010 'Position',[9,2.15384615384615,6,1.15384615384615],...
1011 'String','0.5','Style','edit');
1012 ct7 = uicontrol('Parent',hPanel8,'Units','characters',...
1013 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1014 'Position',[9,0.692307692307692,6,1.15384615384615],...
1015 'String','0.5','Style','edit');
1016 %
1017 %Cuadros de Texto Sección Parámetros: Chebyshev II
1018 ct8 = uicontrol('Parent',hPanel9,'Units','characters',...
1019 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1020 'Position',[9,3.61538461538462,5,1.15384615384615],...
1021 'String','1','Style','edit');
1022 ct9 = uicontrol('Parent',hPanel9,'Units','characters',...
1023 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1024 'Position',[9,2.15384615384615,6,1.15384615384615],...
1025 'String','0.5','Style','edit');
1026 ct10 = uicontrol('Parent',hPanel9,'Units','characters',...
1027 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1028 'Position',[9,0.692307692307692,6,1.15384615384615],...
1029 'String','20','Style','edit');
1030 %
1031 %Cuadros de Texto Sección Parámetros: Elíptico
1032 ct11 = uicontrol('Parent',hPanel10,'Units','characters',...
1033 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1034 'Position',[9,5.07692307692308,5,1.15384615384615],...
1035 'String','1','Style','edit');
1036 ct12 = uicontrol('Parent',hPanel10,'Units','characters',...
1037 'BackgroundColor',[1 1 1],'FontName','Arial','FontSize',7.5,...
1038 'Position',[9,3.69230769230769,6,1.15384615384615],...
1039 'String','0.5','Style','edit');
1040 ct13 = uicontrol('Parent',hPanel10,'Units','characters',...
1197 return;
1198 end
1199 %
1200 %La frecuencia corte debe cumplir 0 < N < 1
1201 wc = str2num(get(infog.ct4,'String'));
1202 if wc == 0 | wc >= 1
1203 errordlg(['La frecuencia corte del filtro debe cumplir',...
1204 ': 0 < wc < 1 !'],'Error');
1205 set(infog.ct4,'ForegroundColor','r');
1206 return;
1207 end
1208 %
1209 %Aplicar el Filtro y Obtener Señal Filtrada
1210 yf = filtrado(infog.vy,4,N,wc);
1211 %
1212 %Actualizar el Contenido de la Estructura Global
1213 infog.ord1 = N; infog.wc1 = wc;
1214 %
1215 %Desplegar las Curvas
1216 c1 = [0.973,0.8,0.545]; c2 = [0,0,1]; c3 = [1,0,0];
1217 llenarejesf(infog.hEF1,yf,[c1;c2;c3],...
1218 ['Butterworth, N = ',num2str(N),', \omega_{c}=',...
1219 num2str(wc)]);
1220
1221
1222 %Subrutina de Llamado al Botón bc11 (Actualizar, Chebyshev I)
1223 function bc11_Callback(varargin)
1224 global infog;
1225 %
1226 set(infog.ct5,'ForegroundColor','k');
1227 set(infog.ct6,'ForegroundColor','k');
1228 set(infog.ct7,'ForegroundColor','k');
1229 %
1230 [val,error] = validarcampo({'ct5','ct6','ct7'}); %Probar si los
1231 if ~val %datos son numéricos
1232 errordlg(['Al menos uno de los parámetros descritos no es n',...
1233 'umérico !'],'Error');
1234 gco = eval(['infog.',error]);
1235 set(gco,'ForegroundColor','r');
1236 return;
1237 end
1238 %
1239 %Sólo Valores Positivos
1240 set(infog.ct5,'String',num2str(abs(str2num(get(infog.ct5,'String')))));
1241 set(infog.ct6,'String',num2str(abs(str2num(get(infog.ct6,'String')))));
1242 set(infog.ct7,'String',num2str(abs(str2num(get(infog.ct7,'String')))));
1243 %
1244 %El orden del Filtro debe ser entero y cumplir 0 < N < 10
1245 N = str2num(get(infog.ct5,'String'));
1246 if (N-round(N))~=0 | N == 0 | N > 9
1247 errordlg(['El orden del filtro debe ser un número entero qu',...
1248 'e cumpla: 0 < N < 10 !'],'Error');
1249 set(infog.ct5,'String',num2str(round(N)));
1250 set(infog.ct5,'ForegroundColor','r');
1251 return;
1252 end
1253 %
1254 %La frecuencia corte debe cumplir 0 < N < 1
1255 wc = str2num(get(infog.ct6,'String'));
1256 if wc == 0 | wc >= 1
1257 errordlg(['La frecuencia corte del filtro debe cumplir',...
1258 ': 0 < wc < 1 !'],'Error');
1259 set(infog.ct6,'ForegroundColor','r');
1260 return;
1261 end
1262 %
1263 %Rizado en Banda de Paso:
1264 deltap = str2num(get(infog.ct7,'String'));
1265 if deltap == 0
1266 errordlg('El rizado debe ser mayor que cero !','Error');
1267 set(infog.ct7,'ForegroundColor','r');
1268 return;
1269 end
1270 %
1271 %Aplicar el Filtro y Obtener Señal Filtrada
1272 yf = filtrado(infog.vy,1,N,wc,deltap);
1273 %
1274 %Actualizar el Contenido de la Estructura Global
1275 infog.ord2 = N; infog.wc2 = wc; infog.dp2 = deltap;
1276 %
1277 %Desplegar las Curvas
1278 c1 = [0.973,0.8,0.545]; c2 = [0,0,1]; c3 = [1,0,0];
1279 llenarejesf(infog.hEF2,yf,[c1;c2;c3],...
1280 ['Chebyshev Tipo I, N = ',num2str(N),', \omega_{c}=',...
1281 num2str(wc),', \delta_{p}=',num2str(deltap)]);
1282
1283
1284 %Subrutina de Llamado al Botón bc12 (Actualizar, Chebyshev II)
1285 function bc12_Callback(varargin)
1286 global infog;
1287 %
1288 set(infog.ct8,'ForegroundColor','k');
1289 set(infog.ct9,'ForegroundColor','k');
1290 set(infog.ct10,'ForegroundColor','k');
1291 %
1292 [val,error] = validarcampo({'ct8','ct9','ct10'}); %Probar si los
1293 if ~val %datos son numéricos
1294 errordlg(['Al menos uno de los parámetros descritos no es n',...
1295 'umérico !'],'Error');
1296 gco = eval(['infog.',error]);
1297 set(gco,'ForegroundColor','r');
1298 return;
1299 end
1300 %
1353 %
1354 [val,error] = validarcampo({'ct11','ct12','ct13','ct14'}); %Probar si
1355 if ~val %los datos son numéricos
1356 errordlg(['Al menos uno de los parámetros descritos no es n',...
1357 'umérico !'],'Error');
1358 gco = eval(['infog.',error]);
1359 set(gco,'ForegroundColor','r');
1360 return;
1361 end
1362 %
1363 %Sólo Valores Positivos
1364 set(infog.ct11,'String',num2str(abs(str2num(get(infog.ct11,'String')))));
1365 set(infog.ct12,'String',num2str(abs(str2num(get(infog.ct12,'String')))));
1366 set(infog.ct13,'String',num2str(abs(str2num(get(infog.ct13,'String')))));
1367 set(infog.ct14,'String',num2str(abs(str2num(get(infog.ct14,'String')))));
1368 %
1369 %El orden del Filtro debe ser entero y cumplir 0 < N < 10
1370 N = str2num(get(infog.ct11,'String'));
1371 if (N-round(N))~=0 | N == 0 | N > 9
1372 errordlg(['El orden del filtro debe ser un número entero qu',...
1373 'e cumpla: 0 < N < 10 !'],'Error');
1374 set(infog.ct11,'String',num2str(round(N)));
1375 set(infog.ct11,'ForegroundColor','r');
1376 end
1377 %
1378 %La frecuencia corte debe cumplir 0 < N < 1
1379 wc = str2num(get(infog.ct12,'String'));
1380 if wc == 0 | wc >= 1
1381 errordlg(['La frecuencia corte del filtro debe cumplir',...
1382 ': 0 < wc < 1 !'],'Error');
1383 set(infog.ct12,'ForegroundColor','r');
1384 return;
1385 end
1386 %
1387 %Rizados en Banda de Paso y de Rechazo:
1388 deltap = str2num(get(infog.ct13,'String'));
1389 if deltap == 0
1390 errordlg('El rizado debe ser mayor que cero !','Error');
1391 set(infog.ct13,'ForegroundColor','r');
1392 return;
1393 end
1394 deltas = str2num(get(infog.ct14,'String'));
1395 if deltas == 0
1396 errordlg('El rizado debe ser mayor que cero !','Error');
1397 set(infog.ct14,'ForegroundColor','r');
1398 return;
1399 end
1400 %
1401 %Aplicar el Filtro y Obtener Señal Filtrada
1402 yf = filtrado(infog.vy,3,N,wc,deltap,deltas);
1403 %
1404 %Actualizar el Contenido de la Estructura Global
1457 set(infog.bc14,'ForegroundColor',[0,0.502,0]);
1458 set(infog.hPanel4,'BackgroundColor',[0,0.502,0]);
1459 set(infog.hPanel2,'BackgroundColor',infog.colP2);
1460 set(infog.hPanel3,'BackgroundColor',infog.colP3);
1461 set(infog.hPanel5,'BackgroundColor',infog.colP5);
1462 %
1463 %Habilitar el Botón "Siguiente" sólo si el Usuario Especificó
1464 %Datos para el Filtro Seleccionado
1465 if infog.ord3 ~= 0 & infog.wc3 ~= 0
1466 set(infog.bc8,'Enable','on');
1467 else
1468 set(infog.bc8,'Enable','off');
1469 end
1470 elseif strcmp(txt,'Chebyshev II')
1471 set(infog.bc14,'String','Elíptico');
1472 set(infog.bc14,'BackgroundColor','b');
1473 set(infog.bc14,'ForegroundColor','b');
1474 set(infog.hPanel5,'BackgroundColor',[0,0.478,0.957]);
1475 set(infog.hPanel2,'BackgroundColor',infog.colP2);
1476 set(infog.hPanel3,'BackgroundColor',infog.colP3);
1477 set(infog.hPanel4,'BackgroundColor',infog.colP4);
1478 %
1479 %Habilitar el Botón "Siguiente" sólo si el Usuario Especificó
1480 %Datos para el Filtro Seleccionado
1481 if infog.ord4 ~= 0 & infog.wc4 ~= 0
1482 set(infog.bc8,'Enable','on');
1483 else
1484 set(infog.bc8,'Enable','off');
1485 end
1486 else
1487 set(infog.bc14,'String','Ninguno');
1488 set(infog.bc14,'BackgroundColor',infog.predCB);
1489 set(infog.bc14,'ForegroundColor','k');
1490 set(infog.hPanel2,'BackgroundColor',infog.colP2);
1491 set(infog.hPanel3,'BackgroundColor',infog.colP3);
1492 set(infog.hPanel4,'BackgroundColor',infog.colP4);
1493 set(infog.hPanel5,'BackgroundColor',infog.colP5);
1494 %set(infog.bc8,'Enable','off');
1495 end
1496
1497 %Subrutina de Llamado al Botón bc15 (Vista Ampliada, Butterworth)
1498 function bc15_Callback(varargin)
1499 global infog;
1500 %
1501 N = infog.ord1; wc = infog.wc1;
1502 %
1503 if N ~= 0 & wc ~= 0 %El usuario estableció parámetros para el filtro?
1504 %
1505 %Preparar la Figura
1506 prepararfigz('Respuesta de la Señal Filtrada');
1507 %
1508 %Obtener Curva Filtrada
1509 yf = filtrado(infog.vy,4,N,wc);
1510 %
1511 %Desplegar las Curvas
1512 c1 = [0.973,0.8,0.545]; c2 = [0,0,1]; c3 = [1,0,0];
1513 llenarejesf(gca,yf,[c1;c2;c3],...
1514 ['Butterworth, N = ',num2str(N),', \omega_{c}=',...
1515 num2str(wc)]);
1516 legend('Entrada','Salida','Salida Filtrada','Location',...
1517 'SouthEast');
1518 xlabel('Tiempo (seg)'); ylabel('Magnitud de la Señal');
1519 end
1520
1521 %Subrutina de Llamado al Botón bc16 (Vista Ampliada, Chebyshev I)
1522 function bc16_Callback(varargin)
1523 global infog;
1524 %
1525 N = infog.ord2; wc = infog.wc2; deltap = infog.dp2;
1526 %
1527 if N ~= 0 & wc ~= 0 %El usuario estableció parámetros para el filtro?
1528 %
1529 %Preparar la Figura
1530 prepararfigz('Respuesta de la Señal Filtrada');
1531 %
1532 %Obtener Curva Filtrada
1533 yf = filtrado(infog.vy,1,N,wc,deltap);
1534 %
1535 %Desplegar las Curvas
1536 c1 = [0.973,0.8,0.545]; c2 = [0,0,1]; c3 = [1,0,0];
1537 llenarejesf(gca,yf,[c1;c2;c3],...
1538 ['Chebyshev Tipo I, N = ',num2str(N),', \omega_{c}=',...
1539 num2str(wc),', \delta_{p}=',num2str(deltap)]);
1540 legend('Entrada','Salida','Salida Filtrada','Location',...
1541 'SouthEast');
1542 xlabel('Tiempo (seg)'); ylabel('Magnitud de la Señal');
1543 end
1544
1545 %Subrutina de Llamado al Botón bc17 (Vista Ampliada, Chebyshev II)
1546 function bc17_Callback(varargin)
1547 global infog;
1548 %
1549 N = infog.ord3; wc = infog.wc3; deltas = infog.ds3;
1550 %
1551 if N ~= 0 & wc ~= 0 %El usuario estableció parámetros para el filtro?
1552 %
1553 %Preparar la Figura
1554 prepararfigz('Respuesta de la Señal Filtrada');
1555 %
1556 %Obtener Curva Filtrada
1557 yf = filtrado(infog.vy,2,N,wc,deltas);
1558 %
1559 %Desplegar las Curvas
1560 c1 = [0.973,0.8,0.545]; c2 = [0,0,1]; c3 = [1,0,0];
1561 llenarejesf(gca,yf,[c1;c2;c3],...
1562 ['Chebyshev Tipo II, N = ',num2str(N),', \omega_{c}=',...
1563 num2str(wc),', \delta_{s}=',num2str(deltas)]);
1564 legend('Entrada','Salida','Salida Filtrada','Location',...
1565 'SouthEast');
1566 xlabel('Tiempo (seg)'); ylabel('Magnitud de la Señal');
1567 end
1568
1569 %Subrutina de Llamado al Botón bc18 (Vista Ampliada, Elíptico)
1570 function bc18_Callback(varargin)
1571 global infog;
1572 %
1573 N = infog.ord4; wc = infog.wc4; deltap = infog.dp4;
1574 deltas = infog.ds4;
1575 %
1576 if N ~= 0 & wc ~= 0 %El usuario estableció parámetros para el filtro?
1577 %
1578 %Preparar la Figura
1579 prepararfigz('Respuesta de la Señal Filtrada');
1580 %
1581 %Obtener Curva Filtrada
1582 yf = filtrado(infog.vy,3,N,wc,deltap,deltas);
1583 %
1584 %Desplegar las Curvas
1585 c1 = [0.973,0.8,0.545]; c2 = [0,0,1]; c3 = [1,0,0];
1586 llenarejesf(gca,yf,[c1;c2;c3],...
1587 ['Elíptico, N = ',num2str(N),', \omega_{c}=',...
1588 num2str(wc),', \delta_{p}=',num2str(deltap),', \delta_{s}=',...
1589 num2str(deltas)]);
1590 legend('Entrada','Salida','Salida Filtrada','Location',...
1591 'SouthEast');
1592 xlabel('Tiempo (seg)'); ylabel('Magnitud de la Señal');
1593 end
1594
1595 %Subrutina de Llamado al Botón bc19 (Guardar Curvas en Archivos-Imagen)
1596 function bc19_Callback(varargin)
1597 global infog;
1598 %
1599 %Observar si el usuario ha variado parámetros en algún filtro...
1600 if infog.ord1 ~= 0 & infog.wc1 ~= 0
1601 bc15_Callback(1,1,1)
1602 print -dmeta 'fbutter.emf' %Guardar el contenido de la figura
1603 end %en Archivo (Imagen Vectorial)
1604 if infog.ord2 ~= 0 & infog.wc2 ~= 0
1605 bc16_Callback(1,1,1)
1606 print -dmeta 'fchebyt1.emf' %Guardar el contenido de la figura
1607 end %en Archivo (Imagen Vectorial)
1608 if infog.ord3 ~= 0 & infog.wc3 ~= 0
1609 bc17_Callback(1,1,1)
1610 print -dmeta 'fchebyt2.emf' %Guardar el contenido de la figura
1611 end %en Archivo (Imagen Vectorial)
1612 if infog.ord4 ~= 0 & infog.wc4 ~= 0
1613 bc18_Callback(1,1,1)
1614 print -dmeta 'felipt.emf' %Guardar el contenido de la figura
1615 end %en Archivo (Imagen Vectorial)
1616 try
1617 delete(1); %Eliminar la Figura de Vista Ampliada si Existe
1618 end
1619
1620 %Subrutina de Llamado al Botón bc8 (Siguiente>>)
1621 function bc8_Callback(varargin)
1622 global infog;
1623 tPant = infog.tPant;
1624
1625 %Leer el Texto del Botón de Selección de Filtro
1626 txt = get(infog.bc14,'String');
1627 %
1628 %Obtener la Respuesta Filtrada
1629 if strcmp(txt,'Butterworth')
1630 infog.yf = filtrado(infog.vy,4,infog.ord1,infog.wc1);
1631 elseif strcmp(txt,'Chebyshev I')
1632 infog.yf = filtrado(infog.vy,1,infog.ord2,infog.wc2,infog.dp2);
1633 elseif strcmp(txt,'Chebyshev II')
1634 infog.yf = filtrado(infog.vy,2,infog.ord3,infog.wc3,infog.ds3);
1635 elseif strcmp(txt,'Elíptico')
1636 infog.yf = filtrado(infog.vy,3,infog.ord4,infog.wc4,infog.dp4,...
1637 infog.ds4);
1638 else
1639 infog.yf = filtrado(infog.vy,0);
1640 end
1641
1642 %F. Identificación:
1643
1644 % F.1. Creación de la Figura
1645 PosVId = [tPant(3)/2-400 tPant(4)/2-300 800 600];
1646 hVId = 7; figure(hVId); delete(gca); clf;
1647 set(hVId,'Color',[0.961,0.961,0.961],'MenuBar','none','Resize',...
1648 'off','WindowStyle','normal','Position',PosVId,'NumberTitle',...
1649 'off','Name','Identificación de un Modelo para la Planta',...
1650 'Visible','off','CloseRequestFcn',@hVId_CloseRequestFcn);
1651
1652 % F.2. Creación de los Paneles que Contienen los Controles Axes,
1653 % la Barra y los Parámetros
1654 %
1655 %Panel 1 (Gráfico - Método 1)
1656 hPanel11 = uipanel('Position',[0.01,0.46,0.4,0.35],'BorderType',...
1657 'etchedin','BackgroundColor',[1,1,1],'Parent',hVId);
1658 %
1659 %Panel 2 (Gráfico - Método 2)
1660 hPanel12 = uipanel('Position',[0.42,0.46,0.4,0.35],'BorderType',...
1661 'etchedin','BackgroundColor',[0.85,0.85,0.85],'Parent',hVId);
1662 %
1663 %Panel 3 (Gráfico - Método 3)
1664 hPanel13 = uipanel('Position',[0.01,0.1,0.4,0.35],'BorderType',...
1665 'etchedin','BackgroundColor',[0.85,0.85,0.85],'Parent',hVId);
1666 %
1667 %Panel 4 (Gráfico - Método 4)
1668 hPanel14 = uipanel('Position',[0.42,0.1,0.4,0.35],'BorderType',...
1669 'etchedin','BackgroundColor',[1,1,1],'Parent',hVId);
1670 %
1671 %Panel Principal de la Barra
1672 hPanel15 = uipanel('Position',[0.83,0.1,0.16,0.71],'BorderType',...
1673 'etchedin','BackgroundColor',[0.831,0.831,0.831],'Parent',hVId);
1674 %
1675 %Panel del 1er Método
1676 hPanel16 = uipanel('Parent',hPanel15,'Title',...
1677 ' ','BackgroundColor',[0.831,0.831,0.860],...
1678 'Position',[0.03,0.725,0.94,0.19]);
1679 %
1680 %Panel del 2do Método
1681 hPanel17 = uipanel('Parent',hPanel15,'Title',...
1682 ' ','BackgroundColor',[0.831,0.831,0.860],...
1683 'Position',[0.03,0.53,0.94,0.19]);
1684 %
1685 %Panel del 3er Método
1686 hPanel18 = uipanel('Parent',hPanel15,'Title',...
1687 ' ','BackgroundColor',[0.831,0.831,0.860],...
1688 'Position',[0.03,0.335,0.94,0.19]);
1689 %
1690 %Panel del 4to Método
1691 hPanel19 = uipanel('Parent',hPanel15,'Title',...
1692 ' ','BackgroundColor',[0.831,0.831,0.860],...
1693 'Position',[0.03,0.14,0.94,0.19]);
1694 %
1695 set(hPanel16,'TitlePosition','righttop');
1696 set(hPanel17,'TitlePosition','righttop');
1697 set(hPanel18,'TitlePosition','righttop');
1698 set(hPanel19,'TitlePosition','righttop');
1699 %
1700 %Panel: Función de Transferencia de la Planta - Método 1
1701 hPanel20 = uipanel('Position',[0.01,0.46,0.4,0.35],'BorderType',...
1702 'etchedin','BackgroundColor',[1,1,1],'Parent',hVId,'Visible',...
1703 'off');
1704 %
1705 %Panel: Función de Transferencia de la Planta - Método 2
1706 hPanel21 = uipanel('Position',[0.42,0.46,0.4,0.35],'BorderType',...
1707 'etchedin','BackgroundColor',[0.85,0.85,0.85],'Parent',hVId,...
1708 'Visible','off');
1709 %
1710 %Panel: Función de Transferencia de la Planta - Método 3
1711 hPanel22 = uipanel('Position',[0.01,0.1,0.4,0.35],'BorderType',...
1712 'etchedin','BackgroundColor',[0.85,0.85,0.85],'Parent',hVId,...
1713 'Visible','off');
1714 %
1715 %Panel: Función de Transferencia de la Planta - Método 4
1716 hPanel23 = uipanel('Position',[0.42,0.1,0.4,0.35],'BorderType',...
1717 'etchedin','BackgroundColor',[1,1,1],'Parent',hVId,'Visible',...
1718 'off');
1719
1720 % F.3. Creación de Controles Axes para Mostrar la Curva de Reacción
1721 %que se Obtiene a Partir del Modelo de la Planta
1722 %
1723 hEI1 = axes('Units','pixels','Color',[1,1,1],'Position',...
1724 [45,30,250,150],'Parent',hPanel11,'XColor',...
1725 [1,1,1],'YColor',[1,1,1],'Visible','off');
1726 %
1727 hEI2 = axes('Units','pixels','Color',[1,1,1],'Position',...
1728 [45,30,250,150],'Parent',hPanel12,'XColor',...
1729 [1,1,1],'YColor',[1,1,1],'Visible','off');
1730 %
1731 hEI3 = axes('Units','pixels','Color',[1,1,1],'Position',...
1732 [45,30,250,150],'Parent',hPanel13,'XColor',...
1733 [1,1,1],'YColor',[1,1,1],'Visible','off');
1734 %
1735 hEI4 = axes('Units','pixels','Color',[1,1,1],'Position',...
1736 [45,30,250,150],'Parent',hPanel14,'XColor',...
1737 [1,1,1],'YColor',[1,1,1],'Visible','off');
1738 %
1739 % F.4. Creación de Controles Axes para Mostrar los Parámetros de los
1740 %Modelos Identificados (en la barra)
1741 %
1742 hEI5 = axes('Units','normalized','Color',[0.957,0.957,0.969],...
1743 'Position',[0.015,0.04,0.96,0.82],'Parent',hPanel16,'XTick',[],...
1744 'YTick',[],'XColor',[1,1,1],'YColor',[1,1,1]);
1745 hEI6 = axes('Units','normalized','Color',[0.957,0.957,0.969],...
1746 'Position',[0.015,0.04,0.96,0.82],'Parent',hPanel17,'XTick',[],...
1747 'YTick',[],'XColor',[1,1,1],'YColor',[1,1,1]);
1748 hEI7 = axes('Units','normalized','Color',[0.957,0.957,0.969],...
1749 'Position',[0.015,0.04,0.96,0.82],'Parent',hPanel18,'XTick',[],...
1750 'YTick',[],'XColor',[1,1,1],'YColor',[1,1,1]);
1751 hEI8 = axes('Units','normalized','Color',[0.957,0.957,0.969],...
1752 'Position',[0.015,0.04,0.96,0.82],'Parent',hPanel19,'XTick',[],...
1753 'YTick',[],'XColor',[1,1,1],'YColor',[1,1,1]);
1754 %
1755 texto = {'Tipo: ?','\fontsize{7} ','\fontsize{8}k_{p} = ?',...
1756 '\fontsize{11}\tau\fontsize{8}_{1,2}= ?','t_{m} = ?'};
1757 tx1 = text(0.05,0.5,texto,'Parent',hEI5,'FontWeight','bold',...
1758 'FontSize',8);
1759 tx2 = text(0.05,0.5,texto,'Parent',hEI6,'FontWeight','bold',...
1760 'FontSize',8);
1761 tx3 = text(0.05,0.5,texto,'Parent',hEI7,'FontWeight','bold',...
1762 'FontSize',8);
1763 tx4 = text(0.05,0.5,texto,'Parent',hEI8,'FontWeight','bold',...
1764 'FontSize',8);
1765
1766 % F.5. Creación de Controles Axes para Contener Las Funciones de
1767 %Transferencia de la Planta (obtenidos mediante la aplicación de los
1768 %métodos de identificación
1769 %
1770 hEI9 = axes('Units','pixels','Color',[1,1,1],'Position',...
1771 [15,30,250,100],'Parent',hPanel20,'XColor',...
1772 [1,1,1],'YColor',[1,1,1],'XTick',[],'YTick',[]);
1773 %
1774 hEI10 = axes('Units','pixels','Color',[0.85,0.85,0.85],'Position',...
1775 [15,30,250,100],'Parent',hPanel21,'XColor',...
1776 [0.85,0.85,0.85],'YColor',[0.85,0.85,0.85],'XTick',[],'YTick',[]);
1777 %
1778 hEI11 = axes('Units','pixels','Color',[0.85,0.85,0.85],'Position',...
1779 [15,30,250,100],'Parent',hPanel22,'XColor',...
1780 [0.85,0.85,0.85],'YColor',[0.85,0.85,0.85],'XTick',[],'YTick',[]);
1781 %
1782 hEI12 = axes('Units','pixels','Color',[1,1,1],'Position',...
1783 [15,30,250,100],'Parent',hPanel23,'XColor',...
1784 [1,1,1],'YColor',[1,1,1],'XTick',[],'YTick',[]);
1785 %
1786 texto = ' ';
1787 tx5 = text(0.02,0.5,texto,'Parent',hEI9,'FontWeight','bold',...
1788 'FontSize',12,'Interpreter','latex');
1789 tx6 = text(0.02,0.5,texto,'Parent',hEI10,'FontWeight','bold',...
1790 'FontSize',12,'Interpreter','latex');
1791 tx7 = text(0.02,0.5,texto,'Parent',hEI11,'FontWeight','bold',...
1792 'FontSize',12,'Interpreter','latex');
1793 tx8 = text(0.02,0.5,texto,'Parent',hEI12,'FontWeight','bold',...
1794 'FontSize',12,'Interpreter','latex');
1795
1796 % F.6. Creación de las Etiquetas
1797 %
1798 %Etiqueta '5.'
1799 et46 = uicontrol('Style','Text','pos',[10,535,50,50],'Parent',...
1800 hVId,'FontName','Arial','FontSize',28,'String','5.',...
1801 'FontWeight','bold','ForegroundColor',[0,0,0.510],...
1802 'BackgroundColor',[0.961,0.961,0.961]);
1803 %
1804 %Etiqueta "Barra de Selección de Métodos"
1805 et47 = uicontrol('Parent',hPanel15,'Units','normalized',...
1806 'BackgroundColor',[0.502 0.502 0.502],'FontWeight','bold',...
1807 'ForegroundColor',[1,1,1],'Position',...
1808 [0.023,0.92,0.938,0.07],'String',...
1809 {'Barra de Selección';'de Métodos'},'Style','text');
1810 %Etiqueta "Modelo Elegido"
1811 et93 = uicontrol('Parent',hPanel15,'Units','normalized',...
1812 'BackgroundColor',[0.831 0.831 0.831],'FontWeight','bold',...
1813 'ForegroundColor',[0,0,0.5],'Position',...
1814 [0.023,0.03,0.938,0.07],'String','Modelo Elegido',...
1815 'Style','text');
1816 %
1817 %Otras Etiquetas:
1818 textoc = {'Función de Trasferencia de la Planta:',...
1819 ' [ Método (?) ]'};
1820 et48 = uicontrol('Style','Text','pos',[0.05,0.70,0.85,0.15],...
1821 'Parent',hPanel20,'FontName','Arial','FontSize',10,'String',...
1822 textoc,'FontWeight','bold','ForegroundColor',...
1823 [0,0,0.510],'BackgroundColor',[1,1,1],'Units',...
1824 'normalized','HorizontalAlignment','left');
1825 et49 = uicontrol('Style','Text','pos',[0.05,0.70,0.85,0.15],...
1826 'Parent',hPanel21,'FontName','Arial','FontSize',10,'String',...
1827 textoc,'FontWeight','bold','ForegroundColor',...
1828 [0,0,0.510],'BackgroundColor',[0.85,0.85,0.85],'Units',...
1829 'normalized','HorizontalAlignment','left');
1830 et50 = uicontrol('Style','Text','pos',[0.05,0.70,0.85,0.15],...
1831 'Parent',hPanel22,'FontName','Arial','FontSize',10,'String',...
1832 textoc,'FontWeight','bold','ForegroundColor',...
1833 [0,0,0.510],'BackgroundColor',[0.85,0.85,0.85],'Units',...
1834 'normalized','HorizontalAlignment','left');
1835 et51 = uicontrol('Style','Text','pos',[0.05,0.70,0.85,0.15],...
1836 'Parent',hPanel23,'FontName','Arial','FontSize',10,'String',...
1837 textoc,'FontWeight','bold','ForegroundColor',...
1838 [0,0,0.510],'BackgroundColor',[1,1,1],'Units',...
1839 'normalized','HorizontalAlignment','left');
1840 %
1841 %Descripción de la Ventana:
1842 et59 = uicontrol('Style','Text','pos',[70,500,720,80],'Parent',...
1843 hVId,'FontName','Arial','FontSize',10,'String',[' Uti',...
1844 'lice los botones ubicados en las 4 "secciones claras" d',...
1845 'e la barra de selección de métodos, para identificar u',...
1846 'n modelo POMTM o SOMTM a partir de la información de l',...
1847 'a prueba (de lazo abierto o lazo cerrado). Si dicha info',...
1848 'rmación proviene de una prueba de "Lazo Abierto", el b',...
1849 'otón "Mejores Métodos" (caracterizado por una medalla)',...
1850 ', le será útil para obtener los mejores modelos de POMT',...
1851 'M y SOMTM.'],...
1852 'BackgroundColor',[0.961,0.961,0.961],'HorizontalAlignment',...
1853 'left','FontAngle','italic','ForegroundColor',[0,0,0.5]);
1854
1855 % F.7. Creación Botones de Comando
1856 %
1857 %Botones Anterior y Siguiente:
1858 bc20 = uicontrol('Parent',hVId,'Callback',@bc20_Callback,...
1859 'Position',[720,10,70,25],'String','Siguiente >>',...
1860 'Style','pushbutton','Enable','off');
1861 bc21 = uicontrol('Parent',hVId,'Callback',@bc21_Callback,...
1862 'Position',[10,10,70,25],'String','<< Anterior','Style',...
1863 'pushbutton');
1864 %
1865 %Botones de la Barra:
1866 bc22 = uicontrol('Parent',hPanel16,'BackgroundColor',[1 0 0],...
1867 'Callback',@bc22_Callback,'Position',[90,35,26,26],'String',...
1868 ' ','Style','pushbutton'); %Cargar Método #1
1869 bc23 = uicontrol('Parent',hPanel17,'BackgroundColor',[1 1 0],...
1870 'Callback',@bc23_Callback,'Position',[90,35,26,26],'String',...
1871 ' ','Style','pushbutton'); %Cargar Método #2
1872 bc24 = uicontrol('Parent',hPanel18,'BackgroundColor',[0 1 0],...
1873 'Callback',@bc24_Callback,'Position',[90,35,26,26],'String',...
1874 ' ','Style','pushbutton'); %Cargar Método #3
1875 bc25 = uicontrol('Parent',hPanel19,'BackgroundColor',[0 0 1],...
1876 'Callback',@bc25_Callback,'Position',[90,35,26,26],'String',...
1877 ' ','Style','pushbutton'); %Cargar Método #4
1878 %
1879 %Cargar información de la imagen
1880 [celda,mapa] = imread([pwd,'\ext\lgx.dtp'],'gif');
1881 %
1882 %Convertir de indexado a directo...
1883 celda = ind2rgb(celda,mapa);
1884 %
1885 %Colocar imagen en los botones
1886 set(bc22,'CData',celda); set(bc23,'CData',celda);
1887 set(bc24,'CData',celda); set(bc25,'CData',celda);
1888 %
1889 %Botón de Selección del Modelo que se va a Utilizar
1890 bc26 = uicontrol('Parent',hPanel15,'Callback',@bc26_Callback,...
1891 'Position',[30,5,70,25],'String','Ninguno','Style',...
1892 'pushbutton','FontWeight','bold');
1893 %
1894 %Botones de Vista Ampliada (Señales)
1895 bc27 = uicontrol('Parent',hPanel11,'Callback',@bc27_Callback,...
1896 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1897 'BackgroundColor','r');
1898 bc28 = uicontrol('Parent',hPanel12,'Callback',@bc28_Callback,...
1899 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1900 'BackgroundColor','y');
1901 bc29 = uicontrol('Parent',hPanel13,'Callback',@bc29_Callback,...
1902 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1903 'BackgroundColor','g');
1904 bc30 = uicontrol('Parent',hPanel14,'Callback',@bc30_Callback,...
1905 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1906 'BackgroundColor','b');
1907 %
1908 %Cargar información de la imagen
1909 [celda,mapa] = imread([pwd,'\ext\str.dtp'],'gif');
1910 %
1911 %Convertir de indexado a directo...
1912 celda = ind2rgb(celda,mapa);
1913 %
1914 %Colocar imagen en los botones
1915 set(bc27,'CData',celda); set(bc28,'CData',celda);
1916 set(bc29,'CData',celda); set(bc30,'CData',celda);
1917 %
1918 %Botón "Mejores Métodos"
1919 bc32 = uicontrol('Parent',hVId,'Callback',@bc32_Callback,...
1920 'Position',[740,487,25,33],'String',' ','Style',...
1921 'pushbutton','BackgroundColor','y');
1922 %
1923 %Cargar información de la imagen
1924 [celda,mapa] = imread([pwd,'\ext\nee.dai'],'gif');
1925 %
1926 %Convertir de indexado a directo...
1927 celda = ind2rgb(celda,mapa);
1928 %
1929 %Colocar imagen en el botón
1930 set(bc32,'CData',celda);
1931 %
1932 %Botón "Salir"
1933 bc33 = uicontrol('Style','pushbutton','pos',[85,10,70,25],...
1934 'Parent',hVId,'String','Salir','Callback',@bc31_Callback);
1935 %
1936 %Botón para Guardar Curvas como Imágenes
1937 bc34 = uicontrol('Parent',hVId,'Callback',@bc34_Callback,...
1938 'Position',[767,487,25,27],'String',' ','Style',...
1939 'pushbutton','BackgroundColor','g');
1940 %
1941 %Cargar información de la imagen
1942 [celda,mapa] = imread([pwd,'\ext\moo.dtp'],'gif');
1943 %
1944 %Convertir de indexado a directo...
1945 celda = ind2rgb(celda,mapa);
1946 %
1947 %Colocar imagen en el botón
1948 set(bc34,'CData',celda);
1949 %
1950 %Botón para Mostrar Gráfico de Comparación de Métodos
1951 bc39 = uicontrol('Parent',hVId,'Callback',@compararmi,...
1952 'Position',[713,487,25,27],'String',' ','Style',...
1953 'pushbutton','BackgroundColor','c');
1954 %
1955 %Cargar información de la imagen
1956 [celda,mapa] = imread([pwd,'\ext\ony.dai'],'gif');
1957 %
1958 %Convertir de indexado a directo...
1959 celda = ind2rgb(celda,mapa);
1960 %
1961 %Colocar imagen en el botón
1962 set(bc39,'CData',celda);
1963 %
1964 %Botones para Guardar Modelos
1965 bc53 = uicontrol('Parent',hPanel20,'Callback',@bc53_Callback,...
1966 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1967 'BackgroundColor','r');
1968 bc54 = uicontrol('Parent',hPanel21,'Callback',@bc54_Callback,...
1969 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1970 'BackgroundColor','y');
1971 bc55 = uicontrol('Parent',hPanel22,'Callback',@bc55_Callback,...
1972 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1973 'BackgroundColor','g');
1974 bc56 = uicontrol('Parent',hPanel23,'Callback',@bc56_Callback,...
1975 'Position',[5,5,25,27],'String',' ','Style','pushbutton',...
1976 'BackgroundColor','b');
1977 %
1978 %Cargar información de la imagen
1979 [celda,mapa] = imread([pwd,'\ext\jac.dtp'],'gif');
1980 %
1981 %Convertir de indexado a directo...
1982 celda = ind2rgb(celda,mapa);
1983 %
1984 %Colocar imagen en el botón
1985 set(bc53,'CData',celda); set(bc54,'CData',celda);
1986 set(bc55,'CData',celda); set(bc56,'CData',celda);
1987
1988 % F.8. Creación de las Pestañas (Botones ToggleButton)
1989 %
1990 be1 = uicontrol('Parent',hVId,'Callback',@be1_Callback,...
1991 'Position',[8,485,80,20],'String','Curvas','Style','toggle',...
1992 'BackgroundColor',[0.82,0.82,0.82],'Value',1);
1993 be2 = uicontrol('Parent',hVId,'Callback',@be2_Callback,...
1994 'Position',[88,485,80,20],'String','Modelo','Style','toggle',...
1995 'BackgroundColor',[0.82,0.82,0.82],'Value',0);
1996
1997 % F.9. Creación de Botones de Asignación para Producir Varias Curvas
1998 % en un Solo Gráfico (el Usuario Escoge los Modelos)
1999 %
2000 chbx1 = uicontrol('Parent',hPanel11,'Units','normalized',...
2001 'Position',[0.935,0.91,0.045,0.07],'Style','checkbox');
2002 chbx2 = uicontrol('Parent',hPanel12,'Units','normalized',...
2003 'Position',[0.935,0.91,0.045,0.07],'Style','checkbox');
2004 chbx3 = uicontrol('Parent',hPanel13,'Units','normalized',...
2005 'Position',[0.935,0.91,0.045,0.07],'Style','checkbox');
2006 chbx4 = uicontrol('Parent',hPanel14,'Units','normalized',...
2007 'Position',[0.935,0.91,0.045,0.07],'Style','checkbox');
2008
2009 %Esconder figura anterior y mostrar la actual
2010 set(infog.hVF,'Visible','off');
2011 set(hVId,'Visible','on');
2012
2013 %Almacenar Información en la Variable Global
2014 infog.hVId = hVId; infog.tx1 = tx1; infog.tx2 = tx2;
2015 infog.tx3 = tx3; infog.tx4 = tx4; infog.hEI1 = hEI1;
2016 infog.hEI2 = hEI2; infog.hEI3 = hEI3; infog.hEI4 = hEI4;
2017 infog.hPanel11 = hPanel11; infog.hPanel12 = hPanel12;
2018 infog.hPanel13 = hPanel13; infog.hPanel14 = hPanel14;
2019 infog.hPanel20 = hPanel20; infog.hPanel21 = hPanel21;
2020 infog.hPanel22 = hPanel22; infog.hPanel23 = hPanel23;
2021 infog.gp1 = []; infog.nombremi1 = []; infog.tipomi1 = [];
2022 infog.gp2 = []; infog.nombremi2 = []; infog.tipomi2 = [];
2023 infog.gp3 = []; infog.nombremi3 = []; infog.tipomi3 = [];
2024 infog.gp4 = []; infog.nombremi4 = []; infog.tipomi4 = [];
2025 infog.be1 = be1; infog.be2 = be2;
2026 infog.et48 = et48; infog.et49 = et49; infog.et50 = et50;
2027 infog.et51 = et51; infog.tx5 = tx5; infog.tx6 = tx6;
2028 infog.tx7 = tx7; infog.tx8 = tx8;
2185 'ForegroundColor',[0,0.5,0]);
2186 infog.sigp = 3; infog.sgp = infog.gp3;
2187 else
2188 if length(infog.nombremi4)>2
2189 set(infog.bc26,'String',infog.nombremi4,...
2190 'ForegroundColor','b');
2191 infog.sigp = 4; infog.sgp = infog.gp4;
2192 else
2193 set(infog.bc26,'String','Ninguno',...
2194 'ForegroundColor','k');
2195 infog.sigp = 0; infog.sgp = 1;
2196 end
2197 end
2198 end
2199 case 2
2200 if length(infog.nombremi3)>2
2201 set(infog.bc26,'String',infog.nombremi3,...
2202 'ForegroundColor',[0,0.5,0]);
2203 infog.sigp = 3; infog.sgp = infog.gp3;
2204 else
2205 if length(infog.nombremi4)>2
2206 set(infog.bc26,'String',infog.nombremi4,...
2207 'ForegroundColor','b');
2208 infog.sigp = 4; infog.sgp = infog.gp4;
2209 else
2210 set(infog.bc26,'String','Ninguno',...
2211 'ForegroundColor','k');
2212 infog.sigp = 0; infog.sgp = 1;
2213 end
2214 end
2215 case 3
2216 if length(infog.nombremi4)>2
2217 set(infog.bc26,'String',infog.nombremi4,...
2218 'ForegroundColor','b');
2219 infog.sigp = 4; infog.sgp = infog.gp4;
2220 else
2221 set(infog.bc26,'String','Ninguno',...
2222 'ForegroundColor','k');
2223 infog.sigp = 0; infog.sgp = 1;
2224 end
2225 case 4
2226 set(infog.bc26,'String','Ninguno',...
2227 'ForegroundColor','k');
2228 infog.sigp = 0; infog.sgp = 1;
2229 end
2230
2231
2232
2233 %Subrutina de Llamado al Botón bc27 (Vista Ampliada de la Curva 1)
2234 function bc27_Callback(varargin)
2235 global infog;
2236 %
2289 %
2290 %Preparar la Figura
2291 titulo = [infog.nombremi2,' ','(',infog.tipomi2,')'];
2292 %
2293 %Título de la Figura (Propiedad 'Name')
2294 if infog.tipopr == 0 %Prueba LA?
2295 prepararfigz(['Curva de Reacción (a partir de los dato',...
2296 's y del modelo)']);
2297 else %Prueba LC?
2298 prepararfigz('Curva de Reacción (a partir del modelo)');
2299 end
2300 %
2301 llenarejesi(gca,infog.gp2,color,titulo);
2302 %
2303 %Leyenda
2304 if infog.tipopr == 0 %Prueba LA?
2305 legend('Entrada','Curva de Reacción, Prueba',...
2306 'Curva de Reacción, Modelo','Location',...
2307 'SouthEast');
2308 else %Prueba LC?
2309 legend('Entrada','Curva de Reacción, Modelo','Location',...
2310 'SouthEast');
2311 end
2312 xlabel('Tiempo (seg)'); ylabel('Magnitud de la Señal');
2313 end
2314
2315 %Subrutina de Llamado al Botón bc29 (Vista Ampliada de la Curva 3)
2316 function bc29_Callback(varargin)
2317 global infog;
2318 %
2319 if length(infog.nombremi3) > 0
2320 %
2321 %Obtener Información de los Colores Utilizados para Graficar
2322 %Las Curvas Actuales
2323 color = get(infog.hEI3,'ColorOrder');
2324 %
2325 %Arreglar la Matriz de Colores si la prueba es tipo LC
2326 if infog.tipopr == 1
2327 c1 = color(1,:); c3 = color(2,:); c2 = [1,1,1];
2328 color = [c1;c2;c3];
2329 end
2330 %
2331 %Preparar la Figura
2332 titulo = [infog.nombremi3,' ','(',infog.tipomi3,')'];
2333 %
2334 %Título de la Figura (Propiedad 'Name')
2335 if infog.tipopr == 0 %Prueba LA?
2336 prepararfigz(['Curva de Reacción (a partir de los dato',...
2337 's y del modelo)']);
2338 else %Prueba LC?
2339 prepararfigz('Curva de Reacción (a partir del modelo)');
2340 end
2341 %
2342 llenarejesi(gca,infog.gp3,color,titulo);
2343 %
2344 %Leyenda
2345 if infog.tipopr == 0 %Prueba LA?
2346 legend('Entrada','Curva de Reacción, Prueba',...
2347 'Curva de Reacción, Modelo','Location',...
2348 'SouthEast');
2349 else %Prueba LC?
2350 legend('Entrada','Curva de Reacción, Modelo','Location',...
2351 'SouthEast');
2352 end
2353 xlabel('Tiempo (seg)'); ylabel('Magnitud de la Señal');
2354 end
2355
2356 %Subrutina de Llamado al Botón bc30 (Vista Ampliada de la Curva 4)
2357 function bc30_Callback(varargin)
2358 global infog;
2359 %
2360 if length(infog.nombremi4) > 0
2361 %
2362 %Obtener Información de los Colores Utilizados para Graficar
2363 %las Curvas Actuales
2364 color = get(infog.hEI4,'ColorOrder');
2365 %
2366 %Arreglar la Matriz de Colores si la prueba es tipo LC
2367 if infog.tipopr == 1
2368 c1 = color(1,:); c3 = color(2,:); c2 = [1,1,1];
2369 color = [c1;c2;c3];
2370 end
2371 %
2372 %Preparar la Figura
2373 titulo = [infog.nombremi4,' ','(',infog.tipomi4,')'];
2374 %
2375 %Título de la Figura (Propiedad 'Name')
2376 if infog.tipopr == 0 %Prueba LA?
2377 prepararfigz(['Curva de Reacción (a partir de los dato',...
2378 's y del modelo)']);
2379 else %Prueba LC?
2380 prepararfigz('Curva de Reacción (a partir del modelo)');
2381 end
2382 %
2383 llenarejesi(gca,infog.gp4,color,titulo);
2384 %
2385 %Leyenda
2386 if infog.tipopr == 0 %Prueba LA?
2387 legend('Entrada','Curva de Reacción, Prueba',...
2388 'Curva de Reacción, Modelo','Location',...
2389 'SouthEast');
2390 else %Prueba LC?
2391 legend('Entrada','Curva de Reacción, Modelo','Location',...
2392 'SouthEast');
2393 end
2394 xlabel('Tiempo (seg)'); ylabel('Magnitud de la Señal');
2395 end
2396
2397
2398 %
2399 %Subrutina de Llamado al Botón bc31 (Salida)
2400 function bc31_Callback(varargin)
2401 for k=0:11
2402 try
2403 delete(12-k);
2404 end
2405 end
2406 drawnow;
2407 %
2408 try
2409 %Mostrar la ventana de créditos:
2410 %(Java)
2411 %
2412 I = imread([pwd,'\ext\amp.dtp'],'BMP');
2413 tiempo = 3000;
2414 splImagen = im2java(I);
2415 vent = javax.swing.JWindow;
2416 imag = javax.swing.ImageIcon(splImagen);
2417 etiq = javax.swing.JLabel(imag);
2418 vent.getContentPane.add(etiq);
2419 %
2420 %Tamaño de la pantalla:
2421 tPant = vent.getToolkit.getScreenSize;
2422 PantH = tPant.height;
2423 PantW = tPant.width;
2424 %
2425 %Tamaño de la imagen:
2426 imgH = imag.getIconHeight;
2427 imgW = imag.getIconWidth;
2428 %
2429 %Colocar la imagen en el centro de la pantalla:
2430 vent.setLocation((PantW-imgW)/2,(PantH-imgH)/2);
2431 vent.pack
2432 vent.show %Mostrar la ventana
2433 %
2434 %Control del tiempo de duración:
2435 tic;
2436 while toc < tiempo/1000
2437 end
2438 %
2439 vent.dispose() %Cerrar la ventana
2440 end
2441 %
2442 %Borrar archivos...
2443 delete([pwd,'\ext\*.dtp']); delete([pwd,'\ext\*.dai']);
2444
2497 set(infog.hPanel11,'Visible','on');
2498 set(infog.hPanel12,'Visible','on');
2499 set(infog.hPanel13,'Visible','on');
2500 set(infog.hPanel14,'Visible','on');
2501
2502 %Subrutina de Llamado a los Botones be2
2503 function be2_Callback(varargin)
2504 global infog;
2505 %
2506 set(infog.be2,'Value',1);
2507 set(infog.be1,'Value',0);
2508 set(infog.hPanel11,'Visible','off');
2509 set(infog.hPanel12,'Visible','off');
2510 set(infog.hPanel13,'Visible','off');
2511 set(infog.hPanel14,'Visible','off');
2512 set(infog.hPanel20,'Visible','on');
2513 set(infog.hPanel21,'Visible','on');
2514 set(infog.hPanel22,'Visible','on');
2515 set(infog.hPanel23,'Visible','on');
2516
2517 %Subrutina de Llamado al Botón bc53 (Guardar Modelo 1, hVId)
2518 function bc53_Callback(varargin)
2519 global infog;
2520 %
2521 if length(infog.nombremi1)>2
2522 try
2523 s = tf('s');
2524 gpt=infog.gp1;
2525 [nombre,ruta,filtroi] = uiputfile({'*.mod',['Archivo de M',...
2526 'odelo (*.mod)']},'Guardar como');
2527 if ~isequal(nombre,0)
2528 save([ruta,nombre],'gpt','-mAT');
2529 end
2530 end
2531 end
2532
2533 %Subrutina de Llamado al Botón bc54 (Guardar Modelo 2, hVId)
2534 function bc54_Callback(varargin)
2535 global infog;
2536 %
2537 if length(infog.nombremi2)>2
2538 try
2539 s = tf('s');
2540 gpt=infog.gp2;
2541 [nombre,ruta,filtroi] = uiputfile({'*.mod',['Archivo de M',...
2542 'odelo (*.mod)']},'Guardar como');
2543 if ~isequal(nombre,0)
2544 save([ruta,nombre],'gpt','-mAT');
2545 end
2546 end
2547 end
2548
2601 gp = eval(['tf(',get(infog.ct19,'String'),')']);
2602 lim = length(0:dt:te);
2603 [num,den] = pade(tm,2); fttm = tf(num,den);
2604 gp = series(gp,fttm);
2605 for k=1:te/dt
2606 vu(k) = 0;
2607 end
2608 for k=te/dt+1:tu/dt+1
2609 vu(k) = mgu;
2610 end
2611 %
2612 vy = lsim(gp,vu,vt);
2613 for k=1:te/dt
2614 if vy(k) < 0
2615 vy(k) = 0;
2616 end
2617 end
2618 %
2619 vyr = awgn(vy,SNR);
2620 set(infog.hVSim,'CurrentAxes',infog.hESim);
2621 plot(vt,vu,'g',vt,vyr,'r'); grid on;
2622 catch
2623 return;
2624 end
2625 infog.vtsm = vt; infog.vusm = vu; infog.vysm = vyr;
2626
2627 %Subrutina de Llamado al Botón bc36 (<< Anterior, hVSim)
2628 function bc36_Callback(varargin)
2629 global infog;
2630 set(infog.hVInt,'Visible','on');
2631 delete(infog.hVSim);
2632
2633 %Subrutina de Llamado al Botón bc37 (Crear Archivo, hVSim)
2634 function bc37_Callback(varargin)
2635 global infog;
2636 %
2637 try
2638 vt = infog.vtsm; vu = infog.vusm; vy = infog.vysm;
2639 catch
2640 return;
2641 end
2642 %
2643 [nombre,ruta,filtroi] = uiputfile({'*.dat',['Archivo de Datos (',...
2644 '*.dat)']; '*.txt','Archivo de Texto (*.txt)'; '*.xls',['Hoj',...
2645 'a de Cálculo de Microsoft Excel (*.xls)']},'Guardar como');
2646 if ~isequal(nombre,0)
2647 mdatos = [vt',vu',vy];
2648 end
2649 %
2650 if isequal(filtroi,3)
2651 if ~isequal(nombre,0)
2652 xlswrite([ruta,nombre],mdatos);
2653 end
2654 else
2655 if ~isequal(nombre,0)
2656 id_arc = fopen([ruta,nombre],'w');
2657 fprintf(id_arc,'%f\t%f\t%f\n',mdatos(1,:));
2658 fclose(id_arc);
2659 ibe = waitbar(0,'Generando Archivo de Datos...');
2660 for k = 2:length(vt)
2661 id_arc = fopen([ruta,nombre],'a');
2662 fprintf(id_arc,'%f\t%f\t%f\n',mdatos(k,:));
2663 fclose(id_arc);
2664 waitbar(k/length(vt)); %Barra de Espera (% Completado)
2665 end
2666 close(ibe);
2667 end
2668 end
2669
2670 %Subrutina de Llamado al Botón bc38 (Guardar Modelo, hVSim)
2671 function bc38_Callback(varargin)
2672 global infog;
2673 %
2674 try
2675 s = tf('s');
2676 st1 = get(infog.ct19,'String');
2677 st2 = get(infog.ct20,'String');
2678 eval(['gpt=',st1]); eval(['gpt.OutputDelay=',st2]);
2679 [nombre,ruta,filtroi] = uiputfile({'*.mod',['Archivo de Mod',...
2680 'elo (*.mod)']},'Guardar como');
2681 if ~isequal(nombre,0)
2682 save([ruta,nombre],'gpt','-mAT');
2683 end
2684 end
2685
2686 %\\\\\\\\\\\\\\\\\\\\\\\\\
2687 %/////////////////////////
2688 %SUBSECCIÓN: SINTONIZACIÓN
2689 %\\\\\\\\\\\\\\\\\\\\\\\\\
2690 %/////////////////////////
2691
2692 %Subrutina de Llamado por Evento Callback en la Lista "Info Disponible"
2693 function lp01_Callback(varargin)
2694 global infog;
2695 x = str2num(get(infog.lp01,'ElemAct'));
2696 infog.sinfod = x;
2697 %
2698 for k=2:7 %Eliminar listas anteriores
2699 try
2700 eval(['delete(infog.lp0',num2str(k),')']);
2701 end
2702 end
2703 for k=2:5 %Eliminar cuadros anteriores
2704 try
2705 eval(['delete(infog.et6',num2str(k),')']);
2706 end
2707 end
2708 eliminarmds;
2709 %
2710 %Eliminar flechas anteriores
2711 for k=1:5
2712 try
2713 eval(['delete(infog.hESt',num2str(k),')']);
2714 end
2715 end
2716 for k=6:9
2717 try
2718 eval(['delete(infog.et6',num2str(k),')']);
2719 end
2720 end
2721 for k=0:4
2722 try
2723 eval(['delete(infog.et7',num2str(k),')']);
2724 end
2725 end
2726 %
2727 if x == 1 %Caso "Sólo Parámetros Críticos"
2728 %
2729 %Crear Flecha:
2730 hESt5 = axes('Units','pixels','Color',[0.8,0.8,0.8],...
2731 'pos',[212,94,28,55]);
2732 %
2733 img = [pwd,'\ext\unv.dtp'];
2734 image(imread(img));
2735 set(hESt5,'XTick',[],'YTick',[],'XColor',[0.8,0.8,0.8],...
2736 'YColor',[0.8,0.8,0.8]);
2737 %
2738 et72 = uicontrol('Style','Text','BackgroundColor',[0,0,0.5],...
2739 'pos',[40,109,173,25]);
2740 et73 = uicontrol('Style','Text','BackgroundColor',[0,0,0.5],...
2741 'pos',[35,109,25,370]);
2742 et74 = uicontrol('Style','Text','BackgroundColor',[0,0,0.5],...
2743 'pos',[35,462.5,55,25]);
2744 infog.hESt5 = hESt5; infog.et72 = et72; infog.et73 = et73;
2745 infog.et74 = et74;
2746 %
2747 %Crear Cuadro "Lista de Métodos"
2748 et65 = uicontrol('Style','Text','BackgroundColor',[0,0.667,0],...
2749 'pos',[240,92,200,59],'String','Lista de Métodos',...
2750 'FontName','Arial','FontSize',8.5,'ForegroundColor',[1,1,1],...
2751 'FontWeight','bold');
2752 infog.et65 = et65;
2753 %
2754 %Mostrar Lista de Métodos
2755 lp05 = actxcontrol('OpcionCtl.Opciones',...
2756 [250,97,180,35],infog.hVSint1,{'Callback',@lp05_Callback});
2757 set(lp05,'nOpcs',2,'Texto1','Shinskey',...
2758 'Texto2','Ziegler y Nichols','Color',1);
2759 infog.lp05 = lp05;
2760 else
2761 %
2762 %Crear Flecha:
2763 hESt1 = axes('Units','pixels','Color',[0.8,0.8,0.8],...
2764 'pos',[362,448,28,55]);
2765 %
2766 img = [pwd,'\ext\unv.dtp'];
2767 image(imread(img));
2768 set(hESt1,'XTick',[],'YTick',[],'XColor',[0.8,0.8,0.8],...
2769 'YColor',[0,0,0]);
2770 %
2771 et66 = uicontrol('Style','Text','BackgroundColor',[0,0,0.5],...
2772 'pos',[290,463,72,25]);
2773 infog.hESt1 = hESt1; infog.et66 = et66;
2774 %
2775 %Crear Cuadro "Tipo de Modelo de la Planta"
2776 et62 = uicontrol('Style','Text','BackgroundColor',[0,0.35,0],...
2777 'pos',[390,445,200,60],'String',['Tipo de Modelo de l',...
2778 'a Planta:'],...
2779 'FontName','Arial','FontSize',8.5,'ForegroundColor',[1,1,1],...
2780 'FontWeight','bold');
2781 infog.et62 = et62;
2782 %
2783 %Mostrar POMTM / SOMTM
2784 lp02 = actxcontrol('OpcionCtl.Opciones', [400,450,180,35],...
2785 infog.hVSint1,{'Callback',@lp02_Callback});
2786 set(lp02,'nOpcs',2,'Texto1','"POMTM"','Texto2','"SOMTM"',...
2787 'Color',1);
2788 infog.lp02 = lp02;
2789 end
2790
2791 %Subrutina de Llamado por Evento Callback en la Lista "POMTM/SOMTM"
2792 function lp02_Callback(varargin)
2793 global infog;
2794 x = str2num(get(infog.lp02,'ElemAct'));
2795 infog.sordp = x;
2796 %
2797 for k=3:5 %Eliminar listas anteriores
2798 try
2799 eval(['delete(infog.lp0',num2str(k),')']);
2800 end
2801 end
2802 for k=3:5 %Eliminar cuadros anteriores
2803 try
2804 eval(['delete(infog.et6',num2str(k),')']);
2805 end
2806 end
2807 eliminarmds;
2808 %
2913 'Texto2','Servomecanismo','Color',0);
2914 infog.lp04 = lp04; infog.et64 = et64;
2915 infog.hESt3 = hESt3; infog.et70 = et70;
2916 else
2917 %
2918 %Crear Flecha:
2919 hESt4 = axes('Units','pixels','Color',[0.8,0.8,0.8],...
2920 'pos',[312.5,151,55,28]);
2921 %
2922 img = [pwd,'\ext\drw.dtp'];
2923 image(imread(img));
2924 set(hESt4,'XTick',[],'YTick',[],'XColor',[0.8,0.8,0.8],...
2925 'YColor',[0.8,0.8,0.8]);
2926 %
2927 et70 = uicontrol('Style','Text','BackgroundColor',[0,0.4,0.4],...
2928 'pos',[327.5,171,25,130]);
2929 %
2930 %Crear Cuadro "Lista de Métodos"
2931 et65 = uicontrol('Style','Text','BackgroundColor',[0,0.667,0],...
2932 'pos',[240,100,220,60],'String','Lista de Métodos',...
2933 'FontName','Arial','FontSize',8.5,'ForegroundColor',[1,1,1],...
2934 'FontWeight','bold');
2935 %
2936 if infog.sordp == 1
2937 %
2938 %Ajustar Cuadro
2939 set(et65,'pos',[240,74,200,77]); %falta
2940 %
2941 %Mostrar Lista de Métodos
2942 lp05 = actxcontrol('OpcionCtl.Opciones',...
2943 [250,79,180,53],infog.hVSint1,{'Callback',...
2944 @lp05_Callback});
2945 set(lp05,'nOpcs',3,'Texto2',['Martín, Smith y C',...
2946 'orripio'],'Texto1','Brosilow IMC','Texto3',...
2947 'Rivera IMC','Color',1);
2948 else
2949 %
2950 %Ajustar Cuadro
2951 set(et65,'pos',[240,92,200,59]);
2952 %
2953 lp05 = actxcontrol('OpcionCtl.Opciones',...
2954 [250,96,180,36],infog.hVSint1,{'Callback',...
2955 @lp05_Callback});
2956 set(lp05,'nOpcs',2,'Texto2',['Martín, Smith y Co',...
2957 'rripio'],'Texto1','Brosilow IMC','Color',1);
2958 end
2959 infog.hESt4 = hESt4; infog.lp05 = lp05; infog.et65 = et65;
2960 infog.sfunsc = 2; infog.et70 = et70;
2961 end
2962
2963 %Subrutina de Llamado por Evento Callback en la Lista "Funcionamiento del
2964 % Lazo de Control"
3121 {'ISE';'IAE';'ITAE'});
3122 infog.snci = [' ','ISE'];
3123 else
3124 infog.smetodo = 18; %Rovira
3125 infog.snmet = 'Rovira';
3126 mostrarmds(2,{'PI';'PID'},{'IAE';'ITAE'});
3127 infog.snci = [' ','IAE'];
3128 end
3129 elseif x == 5
3130 infog.smetodo = 7; %Cohen y Coon
3131 infog.snmet = 'Cohen y Coon';
3132 mostrarmds(1,{'P';'PI';'PID'},[]);
3133 else
3134 infog.smetodo = 8; %Miller, Smith y Murrill
3135 infog.snmet = 'Miller, Smith y Murrill';
3136 mostrarmds(1,{'P';'PI';'PID'},[]);
3137 end
3138 %
3139 else %///////Métodos Analíticos///////
3140 if x == 1
3141 infog.smetodo = 27; %Brosilow IMC (POMTM)
3142 infog.snmet = 'Brosilow IMC';
3143 mostrarmds(1,{'PI';'PID'},[]);
3144 elseif x == 2
3145 infog.smetodo = 22; %Martín, S y C (POMTM)
3146 infog.snmet = 'Martín, Smith y Corripio';
3147 mostrarmds(1,'PI',[]);
3148 set(infog.md02,'Enable','off');
3149 else
3150 infog.smetodo = 26; %Rivera IMC
3151 infog.snmet = 'Rivera IMC';
3152 mostrarmds(1,{'PI';'PID'},[]);
3153 end
3154 end
3155 %
3156 else %Modelo Planta = SOMTM
3157 if infog.srsoma == 1 %Reglas de Sintonización
3158 if infog.sfunsc == 1
3159 infog.smetodo = 20; %Sung, Regulador
3160 else
3161 infog.smetodo = 21; %Sung, Servo
3162 end
3163 infog.snmet = 'Sung';
3164 mostrarmds(1,{'PI','PID'},[]);
3165 else %Métodos Analíticos
3166 if x == 1
3167 infog.smetodo = 28; %Brosilow IMC
3168 infog.snmet = 'Brosilow IMC';
3169 mostrarmds(1,{'PI','PID'},[]);
3170 else
3171 infog.smetodo = 23; %Martin, S y C (SOMTM)
3172 infog.snmet = 'Martín, Smith y Corripio';
3173 mostrarmds(1,'PID',[]);
3174 set(infog.md02,'Enable','off');
3175 end
3176 end
3177 end
3178 end
3179
3180 %Subrutina de Llamado a la Lista Desplegable md03 ('Criterio Integral')
3181 function md03_Callback(varargin)
3182 global infog;
3183 %
3184 x = get(infog.md03,'Value');
3185 infog.smetdesv = x-1;
3186 txt = get(infog.md03,'String');
3187 infog.snci = [' ',txt{x}];
3188
3189 %Subrutina de Llamado al Botón bc40 (Agregar)
3190 function bc40_Callback(varargin)
3191 global infog;
3192 %
3193 %/////////Métodos de Lazo Cerrado:///////////
3194 %////////////Z y N, Shinskey...//////////////
3195 if infog.smetodo == 24 | infog.smetodo == 25
3196 %
3197 %Solicitar al Usuario los Parámetros Críticos
3198 datos = inputdlg({'Ganancia Crítica (Kcu):',['Período de Osc',...
3199 'ilación (Tu):']},'Información Requerida',1);
3200 try
3201 Kcu = str2num(datos{1});
3202 Tu = str2num(datos{2});
3203 if Kcu<=0 | Tu<=0
3204 errordlg('Alguno de los parámetros no es válido !',...
3205 'Error');
3206 return;
3207 end
3208 catch
3209 return;
3210 end
3211 %
3212 %Calcular los Parámetros del Controlador
3213 tpctl = get(infog.md02,'Value'); %Tipo de Controlador
3214 [kc,Td,Ti,gc,tgc] = sintoniz(0,tpctl,infog.smetodo,Kcu,Tu);
3215 infog.sfunsc = 1;
3216 agregarmts(kc,Ti,Td,gc);
3217 return;
3218 end
3219 %
3220 if infog.sigp ~= 0 %Observar si el usuario había especificado un
3221 opc = 'NV'; % modelo en ventanas anteriores
3222 else
3223 %Cargar Parámetros de la Planta a Partir de un Archivo?
3224 opc = questdlg(['Desea cargar la información de la planta a p',...
3381 try
3382 kp = str2num(datos{1});
3383 tao = str2num(datos{2});
3384 tm = str2num(datos{3});
3385 if kp>0 & tao>0 & tm>=0
3386 s=tf('s'); gp = kp/(tao*s+1); gp.OutputDelay = tm;
3387 else
3388 errordlg(['Alguno de los parámetros especificad',...
3389 'os no es válido !'],'Error');
3390 return;
3391 end
3392 catch
3393 return;
3394 end
3395 %
3396 %Calcular los Parámetros del Controlador
3397 tpctl = get(infog.md02,'Value'); %Tipo de Controlador
3398 [kc,Td,Ti,gc,tgc] = sintoniz(gp,tpctl,metodo);
3399 infog.sia = {num2str(kp);num2str(tao);num2str(tm)};
3400 %
3401 elseif metodo > 19 & metodo < 22 %Sung
3402 %Observar Valores Anteriores (para colocarlos como predetermi-
3403 %nados en las casillas del cuadro de diálogo)
3404 if length(infog.sia)~=4
3405 infog.sia = {'1';'1';'1';'1'};
3406 end
3407 %
3408 %Solicitar al Usuario kp, tao y tm
3409 datos = inputdlg({'Ganancia (kp):';'Período Natural:'; ...
3410 'Razón de Amortiguamiento (chi):';['Tie',...
3411 'mpo Muerto (tm):']},'Información Requerida',1,infog.sia);
3412 try
3413 kp = str2num(datos{1});
3414 tao = str2num(datos{2});
3415 chi = str2num(datos{3});
3416 tm = str2num(datos{4});
3417 if kp>0 & tao>0 & tm>=0 & chi>0
3418 s=tf('s'); gp = kp/(tao^2*s^2+2*chi*tao*s+1);
3419 gp.OutputDelay = tm;
3420 else
3421 errordlg(['Alguno de los parámetros especificad!',...
3422 'os no es válido !'],'Error');
3423 return;
3424 end
3425 catch
3426 return;
3427 end
3428 %
3429 %Calcular los Parámetros del Controlador
3430 tpctl = get(infog.md02,'Value'); %Tipo de Controlador
3431 [kc,Td,Ti,gc,tgc] = sintoniz(gp,tpctl,metodo);
3432 infog.sia = {num2str(kp);num2str(tao);num2str(chi); ...
3433 num2str(tm)};
3434 length(infog.sia)
3435 %
3436 elseif metodo == 22 %Martin, Smith y Corripio POMTM
3437 %Observar Valores Anteriores (para colocarlos como predetermi-
3438 %nados en las casillas del cuadro de diálogo)
3439 if length(infog.sia)~=4
3440 infog.sia = {'1';'1';'1';'1'};
3441 end
3442 %
3443 %Solicitar al Usuario kp, tao, tm y lambda
3444 datos = inputdlg({'Ganancia (kp):';['Constante de Tiemp',...
3445 'o (tao):'];'Tiempo Muerto (tm):';'Lambda:'},['Infor',...
3446 'mación Requerida'],1,infog.sia);
3447 try
3448 kp = str2num(datos{1});
3449 tao = str2num(datos{2});
3450 tm = str2num(datos{3});
3451 lambda = str2num(datos{4});
3452 if kp>0 & tao>0 & tm>=0 & lambda>0
3453 s=tf('s'); gp = kp/(tao*s+1); gp.OutputDelay = tm;
3454 else
3455 errordlg(['Alguno de los parámetros especificad',...
3456 'os no es válido !'],'Error');
3457 return;
3458 end
3459 catch
3460 return;
3461 end
3462 %
3463 %Calcular los Parámetros del Controlador
3464 tpctl = get(infog.md02,'Value'); %Tipo de Controlador
3465 [kc,Td,Ti,gc,tgc] = sintoniz(gp,tpctl,metodo,lambda);
3466 infog.sia = {num2str(kp);num2str(tao);num2str(tm); ...
3467 num2str(lambda)};
3468 %
3469 elseif metodo == 23 %Martin, Smith y Corripio SOMTM
3470 %Observar Valores Anteriores (para colocarlos como predetermi-
3471 %nados en las casillas del cuadro de diálogo)
3472 if length(infog.sia)~=5
3473 infog.sia = {'1';'1';'1';'1';'1'};
3474 end
3475 %
3476 %Solicitar al Usuario kp, tao1, tao2, tm y lambda:
3477 datos = inputdlg({'Ganancia (kp):';['Constante de Tiemp',...
3478 'o 1:'];'Constante de Tiempo 2:';['Tiempo Muerto (t',...
3479 'm):'];'Lambda:'},'Información Requerida',1,infog.sia);
3480 try
3481 kp = str2num(datos{1});
3482 tao1 = str2num(datos{2});
3483 tao2 = str2num(datos{3});
3484 tm = str2num(datos{4});
3537 else
3538 %Observar Valores Anteriores (para colocarlos como predetermi-
3539 %nados en las casillas del cuadro de diálogo)
3540 if length(infog.sia)~=5
3541 infog.sia = {'1';'1';'1';'1';'1'};
3542 end
3543 %
3544 %Solicitar al Usuario kp, tao1, tao2, tm y lambda:
3545 datos = inputdlg({'Ganancia (kp):';['Período Natural (ta',...
3546 'o):'];'Razón de Amortiguamiento (chi):';['Tiempo Mu',...
3547 'erto (tm):'];'Constante de Filtro:'},['Informació',...
3548 'n Requerida'],1,infog.sia);
3549 try
3550 kp = str2num(datos{1});
3551 tao = str2num(datos{2});
3552 chi = str2num(datos{3});
3553 tm = str2num(datos{4});
3554 lambda = str2num(datos{5});
3555 if kp>0 & tao>0 & tm>=0 & chi>0 & lambda>0
3556 s=tf('s'); gp = kp/(tao^2*s^2+2*chi*tao*s+1);
3557 gp.OutputDelay = tm;
3558 else
3559 errordlg(['Alguno de los parámetros especificad',...
3560 'os no es válido !'],'Error');
3561 return;
3562 end
3563 catch
3564 return;
3565 end
3566 %
3567 %Calcular los Parámetros del Controlador
3568 tpctl = get(infog.md02,'Value'); %Tipo de Controlador
3569 [kc,Td,Ti,gc,tgc] = sintoniz(gp,tpctl,metodo,lambda);
3570 infog.sia = {num2str(kp);num2str(tao);num2str(chi); ...
3571 num2str(tm);num2str(lambda)};
3572 end
3573 end
3574 %
3575 %Pasar todos los controladores PID a ideal:
3576 if tgc == 4
3577 [kc,Ti,Td] = serieaideal(kc,Ti,Td);
3578 end
3579 %
3580 try
3581 agregarmts(kc,Ti,Td,gc); %Agregar Métodos a la Lista!
3582 end
3583
3584 %Subrutina de Llamado al Botón bc41 (<<Anterior)
3585 function bc41_Callback(varargin)
3586 global infog;
3587 %
3588 %Borrar Ventanas "Sintonización"
3589 delete(infog.hVSint1);
3590 delete(infog.hVSint2);
3591 delete(infog.hVSint3);
3592 %
3593 %Mostrar Ventana Anterior
3594 if infog.svant == 1
3595 set(infog.hVInt,'Visible','on');
3596 else
3597 set(infog.hVId,'Visible','on');
3598 end
3599
3600 %Subrutina de Llamado al Botón bc42 (Siguiente>>)
3601 function bc42_Callback(varargin)
3602 global infog;
3603 %
3604 %Ocultar los Ejes:
3605 cla(infog.hES1); cla(infog.hES2); cla(infog.hES3);
3606 set(infog.hES1,'Visible','off'); set(infog.hES2,'Visible','off');
3607 set(infog.hES3,'Visible','off');
3608 %
3609 %Ocultar las Etiquetas:
3610 set(infog.et94,'Visible','off'); set(infog.et95,'Visible','off');
3611 set(infog.et96,'Visible','off');
3612 %
3613 set(infog.hVSint1,'Visible','off');
3614 set(infog.hVSint3,'Visible','on');
3615 set(infog.bc59,'Visible','off');
3616
3617
3618 %Subrutina de Llamado al Botón bc43 (Mostrar Tabla)
3619 function bc43_Callback(varargin)
3620 global infog;
3621 %
3622 set(infog.hVSint2,'Visible','on');
3623
3624 %Subrutina de Llamado al Botón bc44 ("1")
3625 function bc44_Callback(varargin)
3626 global infog;
3627 %
3628 if infog.snvt ~= 0
3629 try
3630 fila = get(infog.tb01,'RowSel');
3631 %
3632 %No seleccionar los mismos controladores que ya se han selec-
3633 %cionado
3634 if infog.sics2 == fila | infog.sics3 == fila
3635 return;
3636 end
3637 %
3638 %Quitar la marca "celeste" de la fila anterior
3639 if infog.sics1 ~= 0
3640 x = infog.sics1;
3693 13621758);
3694 end
3695 infog.sics2 = fila;
3696 set(infog.tb01,'Col',0);
3697 tmetod = get(infog.tb01,'Text');
3698 set(infog.et88,'String',['2.',' ',tmetod]);
3699 %
3700 %Pasar como información global, la función de transferencia
3701 %de este controlador:
3702 eval(['infog.gccs2=infog.scgc',num2str(fila),';']);
3703 end
3704 end
3705
3706 %Subrutina de Llamado al Botón bc46 ("3")
3707 function bc46_Callback(varargin)
3708 global infog;
3709 %
3710 if infog.snvt ~= 0 & infog.sics2 ~= 0
3711 try
3712 fila = get(infog.tb01,'RowSel');
3713 %
3714 %No seleccionar los mismos controladores que ya se han selec-
3715 %cionado
3716 if infog.sics1 == fila | infog.sics2 == fila
3717 return;
3718 end
3719 %
3720 %Quitar la marca "verde" de la fila anterior
3721 if infog.sics3 ~= 0
3722 x = infog.sics3;
3723 for k=1:10
3724 set(infog.tb01,'Row',x,'Col',k,'CellBackColor',...
3725 16777215);
3726 end
3727 end
3728 %
3729 %Aplicar la marca "verde" a la fila actual
3730 for k=1:11
3731 set(infog.tb01,'Row',fila,'Col',k,'CellBackColor',...
3732 13434828);
3733 end
3734 infog.sics3 = fila;
3735 set(infog.tb01,'Col',0);
3736 tmetod = get(infog.tb01,'Text');
3737 set(infog.et89,'String',['3.',' ',tmetod]);
3738 %
3739 %Pasar como información global, la función de transferencia
3740 %de este controlador:
3741 eval(['infog.gccs3=infog.scgc',num2str(fila),';']);
3742 end
3743 end
3744
3797 otherwise
3798 nc = 1;
3799 end
3800 %
3801 %Asignar el Nuevo Texto al Botón:
3802 set(infog.bc49,'String',num2str(nc));
3803 %
3804 %Cambiar la Imagen del Botón (si es el caso):
3805 %
3806 switch nc
3807 case 1
3808 arcimg = [pwd,'\ext\rda.dtp'];
3809 case 2
3810 arcimg = [pwd,'\ext\fil.dai'];
3811 otherwise
3812 arcimg = [pwd,'\ext\gun.dtp'];
3813 end
3814 %
3815 %Cargar información de la imagen
3816 [celda,mapa] = imread(arcimg,'gif');
3817 %
3818 %Convertir de indexado a directo...
3819 celda = ind2rgb(celda,mapa);
3820 %
3821 %Colocar imagen en el botón
3822 set(infog.bc49,'CData',celda);
3823
3824 %Subrutina de Llamado al Botón bc50 ("Funcionamiento del Lazo de C.")
3825 function bc50_Callback(varargin)
3826 global infog;
3827 %
3828 if strcmp(get(infog.bc50,'String'),'R')
3829 set(infog.bc50,'String','S');
3830 set(infog.et95,'String','Respuesta del Servomecanismo');
3831 else
3832 set(infog.bc50,'String','R');
3833 set(infog.et95,'String','Respuesta del Regulador');
3834 end
3835 cla(infog.hES3); set(infog.hES3,'Visible','off');
3836 infog.svtx = 0;
3837
3838 %Subrutina de Llamado al Botón bc51 ("Graficar")
3839 function bc51_Callback(varargin)
3840 global infog;
3841 %
3842 set(infog.hPanel34,'Visible','on');
3843 set(infog.et98,'Visible','on');
3844 barraprogreso(infog.barrae,1); %Actualizar Progreso
3845 drawnow; uiwait(gcf,0.5);
3846 tfin = str2num(get(infog.cts1,'String'));
3847 if length(tfin) ~= 0 %Es numérico?
3848 if tfin > 15
3849 dt = tfin/1001;
3850 %
3851 %-------------------------------------------------
3852 %Probar si dt > Td/20 para todos los controladores:
3853 ncurvas = str2num(get(infog.bc49,'String'));
3854 %
3855 switch ncurvas
3856 case 1
3857 set(infog.tb01,'Row',infog.sics1,'Col',4);
3858 vx = str2num(get(infog.tb01,'Text'));
3859 if length(vx) == 0
3860 Td = 0;
3861 else
3862 Td = vx;
3863 end
3864 case 2
3865 for k=1:2
3866 indi = [infog.sics1,infog.sics2];
3867 set(infog.tb01,'Row',indi(k),'Col',4);
3868 vx = str2num(get(infog.tb01,'Text'));
3869 if length(vx) == 0
3870 Td(k) = 0;
3871 else
3872 Td(k) = vx;
3873 end
3874 end
3875 case 3
3876 for k=1:2
3877 indi = [infog.sics1,infog.sics2,infog.sics3];
3878 set(infog.tb01,'Row',indi(k),'Col',4);
3879 vx = str2num(get(infog.tb01,'Text'));
3880 if length(vx) == 0
3881 Td(k) = 0;
3882 else
3883 Td(k) = vx;
3884 end
3885 end
3886 end
3887 %
3888 for k=1:length(Td)
3889 if Td(k)~= 0 & Td(k)/20 < dt
3890 dt = ceil(Td(k)/20);
3891 end
3892 end
3893 %
3894 %Generar Vector de Tiempos y Graficar Curvas:
3895 vt = linspace(0,tfin,ceil(tfin/dt));
3896 infog.svtx = vt;
3897 cla(infog.hES3); %Limpiar Objeto Ejes
3898 cla(infog.hES2);
3899 barraprogreso(infog.barrae,10); %Actualizar Progreso 10%
3900 drawnow; uiwait(gcf,0.5);
3901 %
3902 graficarclc(infog.hES3,vt,1);
3903 barraprogreso(infog.barrae,25); %Actualizar Progreso 25%
3904 drawnow; uiwait(gcf,0.5);
3905 graficarnyq;
3906 graficarrobustez;
3907 set(infog.et94,'Visible','on'); set(infog.et95,'Visible','on');
3908 set(infog.bc59,'Visible','on');
3909 uiwait(gcf,0.5);
3910 barraprogreso(infog.barrae,100);
3911 drawnow; uiwait(gcf,0.5);
3912 set(infog.hPanel34,'Visible','off');
3913 set(infog.et98,'Visible','off');
3914 end
3915 end
3916
3917 %Subrutina de Llamado al Botón bc49 ("Controlador Deseado")
3918 function bc52_Callback(varargin)
3919 global infog;
3920 %
3921 %Número de Controladores en la Lista...
3922 if infog.sics2 ~= 0
3923 if infog.sics3 ~= 0
3924 tc = 3;
3925 else
3926 tc = 2;
3927 end
3928 else
3929 tc = 1;
3930 end
3931 %
3932 txt = get(infog.bc52,'String');
3933 txt = strtrim(txt); nc = str2num(txt(3));
3934 %
3935 %Bloque para determinar siguiente valor del botón:
3936 switch nc
3937 case 1
3938 if tc == 1
3939 nc = 1;
3940 else
3941 nc = 2;
3942 end
3943 case 2
3944 if tc == 2
3945 nc = 1;
3946 elseif tc == 3
3947 nc = 3;
3948 end
3949 otherwise
3950 nc = 1;
3951 end
3952 %
4057 text(0.1,0.4,tcfa,'Interpreter','latex');
4058 text(0.1,0.2,cffta,'Interpreter','latex');
4059 else
4060 text(0.15,0.7,tcfp,'Interpreter','latex');
4061 text(0.15,0.3,cfftp,'Interpreter','latex');
4062 Posv = [tPant(3)/2-200,tPant(4)/2-75,400,150];
4063 set(12,'Position',Posv);
4064 end
4065 set(12,'Color',[0.967,0.967,0.967]);
4066
4067
4068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4070 %%%%%%%%%%%% %%%%%%%%%%%%
4071 %%%%%%%%%%%% SECCIÓN DE SUBRUTINAS POR PETICIÓN DE %%%%%%%%%%%%
4072 %%%%%%%%%%%% CIERRE DE FIGURAS (VENTANAS): %%%%%%%%%%%%
4073 %%%%%%%%%%%% "CLOSEREQUESTFCN" %%%%%%%%%%%%
4074 %%%%%%%%%%%% %%%%%%%%%%%%
4075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4077
4078
4079 %
4080 %Subrutina por Petición de Cierre de Ventana hVAdq
4081 function hVAdq_CloseRequestFcn(varargin)
4082 %
4083
4084 %
4085 %Subrutina por Petición de Cierre de Ventana hVSim
4086 function hVSim_CloseRequestFcn(varargin)
4087 %
4088
4089 %Subrutina por Petición de Cierre de Ventana hVVP
4090 function hVVP_CloseRequestFcn(varargin)
4091 %
4092
4093 %Subrutina por Petición de Cierre de Ventana hVF
4094 function hVF_CloseRequestFcn(varargin)
4095 %
4096
4097 %Subrutina por Petición de Cierre de Ventana hVId
4098 function hVId_CloseRequestFcn(varargin)
4099 %
4100
4101 %Subrutina por Petición de Cierre de Ventana: "Sintonización 1"
4102 function hVSint1_CloseRequestFcn(varargin)
4103 global infog;
4104 %
4105
4106 %Subrutina por Petición de Cierre de Ventana: "Sintonización 2"
4107 function hVSint2_CloseRequestFcn(varargin)
4108 global infog;
4109 %
4110 set(infog.hVSint2,'Visible','off');
4111
4112 %Subrutina por Petición de Cierre de Ventana: "Sintonización 3"
4113 function hVSint3_CloseRequestFcn(varargin)
4114 global infog;
4115 %
4116 set(infog.hVSint3,'Visible','off');
4117
4118
4119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121 %%%%%%%%%%%% %%%%%%%%%%%%
4122 %%%%%%%%%%%% SECCIÓN DE FUNCIONES INTERNAS QUE NO COR- %%%%%%%%%%%%
4123 %%%%%%%%%%%% RESPONDEN A LLAMADOS "CALLBACK" DE %%%%%%%%%%%%
4124 %%%%%%%%%%%% OBJETOS GRÁFICOS %%%%%%%%%%%%
4125 %%%%%%%%%%%% %%%%%%%%%%%%
4126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4128
4129
4130 %Función para Comprobar que el Contenido de un Conjunto de Cuadros de...
4131 %Texto es Numérico
4132 function [val,herr] = validarcampo(vid)
4133 global infog;
4134 %
4135 for k = 1:length(vid)
4136 hk = char(vid(k));
4137 instruc = ['length(str2num(get(infog.',hk,',',char(39),...
4138 'String',char(39),')))'];
4139 if eval(instruc) == 0
4140 herr = hk;
4141 val = 0;
4142 return;
4143 end
4144 end
4145 herr = 'nada';
4146 val = 1;
4147 return;
4148
4149 %Subrutina para Desplegar Respuesta de la Señal Filtrada en un Control
4150 %Axes Específico
4151 function llenarejesf(iEje,vf,color,titulo)
4152 global infog;
4153 %
4154 %Obtener vector de tiempo, escalón de entrada y salida
4155 vt = infog.vt; vy = abs(infog.vy); vu = abs(infog.vu);
4156 vf = abs(vf);
4157 gca = iEje;
4158 %
4159 %Leer el Parámetro color
4160 c1 = color(1,:); c2 = color(2,:); c3 = color(3,:);
4161 %
4162 %Aplicar Propiedades Necesarias Sobre el Control Axes
4163 set(gca,'NextPlot','replacechildren');
4164 set(gca,'ColorOrder',[c1;c2;c3]);
4165 set(gca,'XColor',[0,0,0],'YColor',[0,0,0]);
4166 set(gca,'Visible','on');
4167 %
4168 %Mostrar las Curvas
4169 plot(gca,vt,vu,vt,vy,vt,vf);
4170 set(gca,'XGrid','on','YGrid','on');
4171 %
4172 %Colocar el Título a las Curvas
4173 yl = get(gca,'YLim'); ypos = 1.05*yl(2);
4174 tx = text(0,ypos,titulo,'Parent',gca,'FontWeight','bold',...
4175 'FontSize',8.5);
4176
4177 %Subrutina para Desplegar Respuesta de la Señal de Respuesta de Lazo
4178 % Abierto en un Control Axes Específico
4179 function llenarejesi(iEje,gp,color,titulo)
4180 global infog;
4181 %
4182 %Obtener vector de tiempo, escalón de entrada y salida
4183 vt = infog.vt; vf = abs(infog.yf); vu = abs(infog.vu);
4184 vf = abs(vf);
4185 gca = iEje;
4186 %
4187 %Obtener la curva de reacción que proviene del modelo identificado
4188 ym = lsim(gp,vu,vt);
4189 %
4190 if infog.tipopr == 0 %La prueba es de LA?
4191 %Obtención del Error S^2
4192 S2 = sum((abs(vf)-abs(ym)).^2);
4193 end
4194 %
4195 %Normalización de las Curvas
4196 umax = max(abs(vu)); y1max = max(abs(vf)); y2max = max(abs(ym));
4197 vu = 100 * 1/umax * abs(vu);
4198 vf = 100 * 1/y1max * abs(vf);
4199 ym = 100 * 1/y2max * abs(ym);
4200 %
4201 %Leer el Parámetro color
4202 c1 = color(1,:); c2 = color(2,:); c3 = color(3,:);
4203 %
4204 %Aplicar Propiedades Necesarias Sobre el Control Axes
4205 set(gca,'NextPlot','replacechildren');
4206 %
4207 if infog.tipopr == 0 %La prueba es de LA?
4208 set(gca,'ColorOrder',[c1;c2;c3]);
4209 else
4210 set(gca,'ColorOrder',[c1;c3]);
4211 end
4212 set(gca,'XColor',[0,0,0],'YColor',[0,0,0]);
4213 set(gca,'Visible','on');
4214 %
4215 %Mostrar las Curvas
4216 if infog.tipopr == 0 %La prueba es de LA?
4217 plot(gca,vt,vu,vt,vf,vt,ym);
4218 else
4219 plot(gca,vt,vu,vt,ym);
4220 end
4221 set(gca,'XGrid','on','YGrid','on');
4222 axis(gca,[vt(1) vt(end) 0 110]);
4223 %
4224 %Colocar el Título a las Curvas
4225 %
4226 if infog.tipopr == 0
4227 titulo = [titulo,',',' ','S^2 =',' ',num2str(S2)];
4228 end
4229 tx = text(1/5*vt(end),115,titulo,'Parent',gca,'FontWeight','bold',...
4230 'FontSize',8.5);
4231
4232 %Función para Mostrar la Lista de Selección de Métodos de Identificación
4233 function [ind,nomb,tipo,color,ok] = listametodos(tipopr)
4234 if tipopr == 0
4235 opcs = {'Áreas, POMTM','Alfaro, POMTM','Bröida, POMTM',...
4236 'Ho et al, POMTM','Chen y Yang, POMTM','Smith, POMTM',...
4237 'Vitecková, POMTM','Alfaro, SOMTM','Ho et al, SOMTM',...
4238 'Vitecková, SOMTM','Stark, SOMTM','Jahanmiri y F., SOMTM',...
4239 'Áreas, SOMTM'};
4240 else
4241 opcs = {'Yuwana y Seborg, POMTM','Jután y Rodríguez, POMTM',...
4242 'Lee, POMTM','Bogere y Özgen, SOMTM'};
4243 end
4244 %Matriz de Colores:
4245 mcols = [[1,137,182];[5,209,31];[128,0,0];[255,128,0];[128,0,...
4246 255];[128,0,128];[0,155,155];[0,128,0];[0,0,255];[0,0,...
4247 160];[255,0,255];[0,120,240];[179,0,0];[62,63,98]]/255;
4248 %
4249 %Desplegar un cuadro de diálogo con la lista
4250 [sel,ok] = listdlg('PromptString','Elija un Método:','SelectionMode',...
4251 'single','ListString',opcs,'ListSize',[200,40],'Name',...
4252 'Selección del Método');
4253 if ok == 0
4254 ind = []; nomb = []; tipo = []; color = [];
4255 else
4256 tmp1 = char(opcs(sel));
4257 ind = sel; nomb = tmp1(1:end-7); tipo = tmp1(end-4:end);
4258 color = mcols(sel,:);
4259 end
4260
4261 %Subrutina para Mostrar los Parámetros del Modelo Identificado (en la
4262 %Barra) y la Función de Transferencia de la Planta (en los Paneles)
4263 function actualizarlistaid(it,gp,kp,tm,tao,nombre,tipo)
4264 global infog;
4265 %
4266 %Lista Vectores que Contienen los Identificadores de los Objetos
4267 %Texto que Despliegan la Información en la Barra o en los Paneles
4268 itxta = [infog.tx1,infog.tx2,infog.tx3,infog.tx4];
4269 itxtb = [infog.tx5,infog.tx6,infog.tx7,infog.tx8];
4270 ietqs = [infog.et48,infog.et49,infog.et50,infog.et51];
4271 %
4272 %Información: Parámetro Constante de Tiempo...
4273 if strcmp(nombre,'Stark') %El método es Stark?
4274 if tao(1) < 1
4275 txtao = ['[\fontsize{11}\zeta\fontsize{8}, \',...
4276 'fontsize{11}\omega\fontsize{8}_{n}] = [',...
4277 num2str(tao(1),'%5.3f'),',',' ',...
4278 num2str(tao(2),'%5.3f'),']'];
4279 else
4280 txtao = ['\fontsize{11}\tau\fontsize{8}_{1,2}= [',...
4281 num2str(tao(2),'%5.3f'),',',' ',...
4282 num2str(tao(3),'%5.3f'),']'];
4283 end
4284 elseif strcmp(nombre,'Bogere y Özgen') %El método es Bogere y Özgen?
4285 txtao = ['\fontsize{11}\tau\fontsize{8}_{1,2}= [',...
4286 num2str(tao(1),'%5.3f'),',',' ',num2str(tao(2),'%5.3f'),']'];
4287 elseif strcmp(nombre,'Jahanmiri y F.') %El método es J y F?
4288 txtao = ['[\fontsize{11}\tau\fontsize{8}, \',...
4289 'fontsize{9}\zeta\fontsize{8}] = [',...
4290 num2str(tao(1),'%5.3f'),',',' ',...
4291 num2str(tao(2),'%5.3f'),']'];
4292 else %Es otro método?
4293 txtao = ['\fontsize{11}\tau\fontsize{8}_{1,2}=',' ',...
4294 num2str(tao),' ','seg'];
4295 end
4296 %
4297 texto = {[' ',nombre],['\fontsize{7}\it',' ',tipo],...
4298 ['\rm\bf\fontsize{8}k_{p} =',' ',num2str(kp)],txtao,['t_{m} =',...
4299 ' ',num2str(tm),' ','seg']};
4300 set(itxta(it),'String',texto);
4301 %
4302 %Desplegar el Nombre del Método en los Paneles
4303 textoc = {'Función de Trasferencia de la Planta:',[' [',' ',...
4304 nombre,' (',tipo,') ]']};
4305 set(ietqs(it),'String',textoc);
4306 %
4307 %Desplegar la Función de Transferencia en los Paneles
4308 [num,den] = tfdata(gp);
4309 num = num{1}; den = den{1}; %Arreglo de Celdas -> Vectores
4310 kpt = num2str(num(end));
4311 tmt = num2str(gp.OutputDelay);
4312 %
4313 if length(den) == 2
4314 dent = [num2str(den(1)),'s +',' ',num2str(den(2))];
4315 else
4316 dent = [num2str(den(1)),'s^2 + ',num2str(den(2)),...
4473 %
4474 a = get(infog.chbx1,'Value'); b = get(infog.chbx2,'Value');
4475 c = get(infog.chbx3,'Value'); d = get(infog.chbx4,'Value');
4476 cont = 0;
4477 %
4478 %Observar cuáles casillas están seleccionadas...
4479 if a & length(infog.nombremi1) > 2
4480 cont=cont+1;
4481 ley{cont}=[infog.nombremi1,' (',infog.tipomi1,')'];
4482 vyt(cont,:)=lsim(infog.gp1,vu,vt);
4483 %
4484 %Índice de Error
4485 if ~infog.tipopr
4486 vx = (vyt(cont,:))';
4487 S2=sum((abs(vf)-abs(vx)).^2);
4488 ley{cont}=[ley{cont},' S^2=',num2str(S2)];
4489 end
4490 %
4491 %Dato para el Nombre de Archivo
4492 dna{cont} = infog.nombremi1;
4493 if strcmp(infog.tipomi1,'POMTM')
4494 dna{cont}=[dna{cont},'1x'];
4495 else
4496 dna{cont}=[dna{cont},'2x'];
4497 end
4498 end
4499 if b & length(infog.nombremi2) > 2
4500 cont=cont+1;
4501 ley{cont}=[infog.nombremi2,' (',infog.tipomi2,')'];
4502 vyt(cont,:)=lsim(infog.gp2,vu,vt);
4503 %
4504 %Índice de Error
4505 if ~infog.tipopr
4506 vx = (vyt(cont,:))';
4507 S2=sum((abs(vf)-abs(vx)).^2);
4508 ley{cont}=[ley{cont},' S^2=',num2str(S2)];
4509 end
4510 %
4511 %Dato para el Nombre de Archivo
4512 dna{cont} = infog.nombremi2;
4513 if strcmp(infog.tipomi2,'POMTM')
4514 dna{cont}=[dna{cont},'1x'];
4515 else
4516 dna{cont}=[dna{cont},'2x'];
4517 end
4518 end
4519 if c & length(infog.nombremi3) > 2
4520 cont=cont+1;
4521 ley{cont}=[infog.nombremi3,' (',infog.tipomi3,')'];
4522 vyt(cont,:)=lsim(infog.gp3,vu,vt);
4523 %
4524 %Índice de Error
4525 if ~infog.tipopr
4526 vx = (vyt(cont,:))';
4527 S2=sum((abs(vf)-abs(vx)).^2);
4528 ley{cont}=[ley{cont},' S^2=',num2str(S2)];
4529 end
4530 %
4531 %Dato para el Nombre de Archivo
4532 dna{cont} = infog.nombremi3;
4533 if strcmp(infog.tipomi3,'POMTM')
4534 dna{cont}=[dna{cont},'1x'];
4535 else
4536 dna{cont}=[dna{cont},'2x'];
4537 end
4538 end
4539 if d & length(infog.nombremi4) > 2
4540 cont=cont+1;
4541 ley{cont}=[infog.nombremi4,' (',infog.tipomi4,')'];
4542 vyt(cont,:)=lsim(infog.gp4,vu,vt);
4543 %
4544 %Índice de Error
4545 if ~infog.tipopr
4546 vx = (vyt(cont,:))';
4547 S2=sum((abs(vf)-abs(vx)).^2);
4548 ley{cont}=[ley{cont},' S^2=',num2str(S2)];
4549 end
4550 %
4551 %Dato para el Nombre de Archivo
4552 dna{cont} = infog.nombremi4;
4553 if strcmp(infog.tipomi4,'POMTM')
4554 dna{cont}=[dna{cont},'1x'];
4555 else
4556 dna{cont}=[dna{cont},'2x'];
4557 end
4558 end
4559 %
4560 if cont ~= 0
4561 %Preparar Figura y Objeto Axes
4562 prepararfigz('Comparación de Métodos');
4563 c1 = [244,199,15]/255; c2 = [1,0,0]; c3 = [0,0,1];
4564 c4 = [0,1,0]; c5 = [0,1,1]; c6 = [1,0,1];
4565 set(gca,'NextPlot','replacechildren');
4566 set(gca,'ColorOrder',[c1;c2;c3;c4;c5;c6]);
4567 end
4568 %
4569 %Normalización de las Curvas
4570 umax = max(abs(vu));
4571 for k=1:cont
4572 ym = vyt(k,:);
4573 y2max = max(abs(ym));
4574 vyt(k,:) = 100 * 1/y2max * abs(ym);
4575 end
4576 vu = 100 * 1/umax * abs(vu);
4577 if ~infog.tipopr
4578 y1max = max(abs(vf));
4579 vf = 100 * 1/y1max * abs(vf);
4580 end
4581
4582 %
4583 %Mostrar Curvas con base en el #total = cont y el tipo de prueba
4584 switch cont
4585 case 1
4586 if ~infog.tipopr
4587 plot(vt,vu,vt,vf,vt,vyt(1,:));
4588 legend('Entrada','Prueba de Lazo Abierto',ley{1},...
4589 'Location','SouthEast');
4590 else
4591 plot(vt,vu,vt,vyt(1,:));
4592 legend('Entrada',ley{1},'Location','SouthEast');
4593 end
4594 case 2
4595 if ~infog.tipopr
4596 plot(vt,vu,vt,vf,vt,vyt(1,:),vt,vyt(2,:));
4597 legend('Entrada','Prueba de Lazo Abierto',ley{1},...
4598 'Location','SouthEast',ley{2});
4599 else
4600 plot(vt,vu,vt,vyt(1,:),vt,vyt(2,:));
4601 legend('Entrada',ley{1},ley{2},'Location','SouthEast');
4602 end
4603 case 3
4604 if ~infog.tipopr
4605 plot(vt,vu,vt,vf,vt,vyt(1,:),vt,vyt(2,:),vt,vyt(3,:));
4606 legend('Entrada','Prueba de Lazo Abierto',ley{1},...
4607 ley{2},ley{3},'Location','SouthEast');
4608 else
4609 plot(vt,vu,vt,vyt(1,:),vt,vyt(2,:),vt,vyt(3,:));
4610 legend('Entrada',ley{1},ley{2},ley{3},'Location',...
4611 'SouthEast');
4612 end
4613 case 4
4614 if ~infog.tipopr
4615 plot(vt,vu,vt,vf,vt,vyt(1,:),vt,vyt(2,:),vt,vyt(3,:),...
4616 vt,vyt(4,:));
4617 legend('Entrada','Prueba de Lazo Abierto',ley{1},...
4618 ley{2},ley{3},ley{4},'Location','SouthEast');
4619 else
4620 plot(vt,vu,vt,vyt(1,:),vt,vyt(2,:),vt,vyt(3,:),vt,...
4621 vyt(4,:));
4622 legend('Entrada',ley{1},ley{2},ley{3},ley{4},...
4623 'Location','SouthEast');
4624 end
4625 otherwise
4626 return;
4627 end
4628 %
4681 if infog.sigp ~= 0
4682 infog.gplanta = infog.sgp;
4683 end
4684 end
4685
4686 %
4687 %H. Sintonización:
4688
4689 % H.1. Creación de la Figura 1: Selección de Métodos
4690 tPant = get(0,'ScreenSize');
4691 PosVSint1 = [tPant(3)/2-340 tPant(4)/2-300 680 600];
4692 hVSint1 = 9; figure(hVSint1); delete(gca); clf;
4693 set(hVSint1,'Color',[0.8,0.8,0.8],'MenuBar','none','Resize',...
4694 'off','WindowStyle','normal','Position',PosVSint1,...
4695 'NumberTitle','off','Name',['Sintonización de Controlad',...
4696 'ores PID'],'Visible','off',...
4697 'CloseRequestFcn',@hVSint1_CloseRequestFcn);
4698
4699 % H.2. Crear Cuadro "Información Disponible"
4700 et61 = uicontrol('Style','Text','BackgroundColor',[0,0,0.5],...
4701 'pos',[90,445,200,60],'String','Información Disponible:',...
4702 'FontName','Arial','FontSize',8.5,'ForegroundColor',[1,1,1],...
4703 'FontWeight','bold');
4704
4705 % H.3. Crear la Lista "Información Disponible"
4706 lp01 = actxcontrol('OpcionCtl.Opciones',[100,450,180,35],...
4707 hVSint1,{'Callback',@lp01_Callback});
4708 set(lp01,'nOpcs',2,'Texto1','Parámetros Críticos',...
4709 'Texto2','Modelo de la Planta');
4710
4711 % H.4. Creación de la Figura 2: Tabla Resumen
4712 PosVSint2 = [tPant(3)/2-350 tPant(4)/2-150 700 300];
4713 hVSint2 = 10; figure(hVSint2); delete(gca); clf;
4714 set(hVSint2,'Color',[0.7255,0.9137,1],'MenuBar','none','Resize',...
4715 'off','WindowStyle','normal','Position',PosVSint2,...
4716 'NumberTitle','off','Name',['Tabla Resumen: Métodos de Sint',...
4717 'onización'],'Visible','off',...
4718 'CloseRequestFcn',@hVSint2_CloseRequestFcn);
4719
4720 % H.5. Creación de la Figura 3: Análisis de la Respuesta del Sistema
4721 PosVSint3 = [tPant(3)/2-400 tPant(4)/2-300 800 600];
4722 hVSint3 = 11; figure(hVSint3); delete(gca); clf;
4723 set(hVSint3,'Color',[0.931,0.931,0.931],'MenuBar','none','Resize',...
4724 'off','WindowStyle','normal','Position',PosVSint3,'NumberTitle',...
4725 'off','Name','Análisis de la Respuesta del Sistema','Visible',...
4726 'off','CloseRequestFcn',@hVSint3_CloseRequestFcn);
4727
4728 % H.6. Creación de los Paneles que Contienen los Controles Axes,
4729 % y la Barra
4730 %
4731 %Panel 1 (Diagrama de Nyquist)
4732 hPanel27 = uipanel('Position',[0.05,0.55,0.35,0.4],'BorderType',...
4733 'etchedin','BackgroundColor',[0.9098,0.9529,1],'Parent',hVSint3);
4734 %
4735 %Panel 2 (Diagrama de Robustez)
4736 hPanel28 = uipanel('Position',[0.42,0.55,0.35,0.4],'BorderType',...
4737 'etchedin','BackgroundColor',[0.9098,0.9529,1],'Parent',hVSint3);
4738 %
4739 %Panel 3 (Respuesta al Escalón)
4740 hPanel29 = uipanel('Position',[0.15,0.1,0.5,0.42],'BorderType',...
4741 'etchedin','BackgroundColor',[0.9098,0.9529,1],'Parent',hVSint3);
4742 %
4743 %Panel Principal de la Barra
4744 hPanel30 = uipanel('Position',[0.785,0.1,0.21,0.75],'BorderType',...
4745 'etchedin','BackgroundColor',[0.831,0.831,0.831],'Parent',hVSint3);
4746 %
4747 %Panel "Información de la Planta"
4748 hPanel31 = uipanel('Position',[0.05,0.48,0.9,0.2],'BorderType',...
4749 'etchedin','BackgroundColor',[0.8353,1,0.8353],'Parent',...
4750 hPanel30);
4751 %
4752 %Panel "Información del Controlador"
4753 hPanel32 = uipanel('Position',[0.05,0.27,0.9,0.2],'BorderType',...
4754 'etchedin','BackgroundColor',[1,0.8431,0.8431],'Parent',...
4755 hPanel30);
4756 %
4757 %Panel "Otros Datos"
4758 hPanel33 = uipanel('Position',[0.05,0.11,0.9,0.15],'BorderType',...
4759 'etchedin','BackgroundColor',[0.961,0.961,0.961],'Parent',...
4760 hPanel30);
4761 %
4762 %Panel para Barra de Progreso:
4763 hPanel34 = uipanel('Position',[0.81,0.87,0.16,0.04],'BorderType',...
4764 'etchedin','BackgroundColor',[0.831,0.831,0.831],'Parent',...
4765 hVSint3,'Visible','off');
4766
4767 % H.7. Creación de Controles "Axes" para Mostrar la Curvas y Para
4768 % Efectos de la Barra
4769 %
4770 %Diagrama de Nyquist
4771 hES1 = axes('Units','pixels','Color',[1,1,1],'Position',...
4772 [20,0,240,220],'Parent',hPanel27,'XColor',...
4773 [1,1,1],'YColor',[1,1,1],'Visible','on','XTick',[],'YTick',[],...
4774 'Visible','off');
4775 %
4776 %Diagrama de Robustez
4777 hES2 = axes('Units','pixels','Color',[1,0.9961,0.8745],'Position',...
4778 [45,45,200,165],'Parent',hPanel28,'XColor',...
4779 [1,1,1],'YColor',[1,1,1],'Visible','off');
4780 %
4781 %Respuesta al Escalón
4782 hES3 = axes('Units','pixels','Color',[1,0.9961,0.8745],'Position',...
4783 [45,30,315,190],'Parent',hPanel29,'XColor',...
4784 [0,0,0.5],'YColor',[0,0,0.5],'Visible','off');
4785 %
4786 %Controles de la Barra:
4787 %
4788 hES4 = axes('Units','pixels','Color',[1,1,1],'Position',...
4789 [16,320,138,56],'Parent',hPanel30);
4790 %
4791 rimagen = [pwd,'\ext\yun.dai'];
4792 im1 = image(imread(rimagen));
4793 set(hES4,'XTick',[],'YTick',[]);
4794 %
4795 hES5 = axes('Units','pixels','Color',[0.8353,1,0.8353],'Position',...
4796 [15,10,125,58],'Parent',hPanel31,'XColor',...
4797 [0.961,0.961,0.961],'YColor',[0.961,0.961,0.961],'XTick',[],...
4798 'YTick',[]);
4799 %
4800 texto = {'\fontsize{8}k_{p} = ?',['\fontsize{11}\tau\fontsi',...
4801 'ze{8}_{x}= ?'],'t_{m} = ?'};
4802 txS1 = text(0.05,0.5,texto,'Parent',hES5,'FontWeight','bold',...
4803 'FontSize',8);
4804
4805 % H.8. Creación de Botones:
4806 %
4807 %Botón "Anterior"
4808 bc41 = uicontrol('Parent',hVSint1,'Style','pushbutton',...
4809 'Position',[8,10,75,25],'String','<< Anterior','Callback',...
4810 @bc41_Callback,'BackgroundColor','b');
4811 %
4812 %Botón "Siguiente"
4813 bc42 = uicontrol('Parent',hVSint1,'Style','pushbutton',...
4814 'Position',[600,10,75,25],'String','Siguiente >>','Callback',...
4815 @bc42_Callback,'BackgroundColor','b','Enable','off');
4816 %
4817 %Botón "Mostrar Tabla"
4818 bc43 = uicontrol('Parent',hVSint1,'Style','pushbutton',...
4819 'Position',[570,10,25,27],'Callback',@bc43_Callback,...
4820 'BackgroundColor','r');
4821 %
4822 %Cargar información de la imagen
4823 [celda,mapa] = imread([pwd,'\ext\kco.dtp'],'gif');
4824 %
4825 %Convertir de indexado a directo...
4826 celda = ind2rgb(celda,mapa);
4827 %
4828 %Colocar imagen en el botón
4829 set(bc43,'CData',celda);
4830 %
4831 %Botones: "1", "2" y "3": Selección de Controladores, Figura 2
4832 bc44 = uicontrol('Parent',hVSint2,'Style','pushbutton',...
4833 'Position',[265,20,25,25],'Callback',@bc44_Callback,...
4834 'ForegroundColor',[1,1,1],'FontWeight','bold','String','1',...
4835 'FontSize',10.5);
4836 bc45 = uicontrol('Parent',hVSint2,'Style','pushbutton',...
4837 'Position',[295,20,25,25],'Callback',@bc45_Callback,...
4838 'ForegroundColor',[1,1,1],'FontWeight','bold','String','2',...
4839 'FontSize',10.5);
4840 bc46 = uicontrol('Parent',hVSint2,'Style','pushbutton',...
4841 'Position',[325,20,25,25],'Callback',@bc46_Callback,...
4842 'ForegroundColor',[1,1,1],'FontWeight','bold','String','3',...
4843 'FontSize',10.5);
4844 %
4845 %Cargar información de la imagen
4846 [celda1,mapa1] = imread([pwd,'\ext\rda.dtp'],'gif');
4847 [celda2,mapa2] = imread([pwd,'\ext\isi.dtp'],'gif');
4848 [celda3,mapa3] = imread([pwd,'\ext\pal.dai'],'gif');
4849 %
4850 %Convertir de indexado a directo...
4851 celda1 = ind2rgb(celda1,mapa1);
4852 celda2 = ind2rgb(celda2,mapa2);
4853 celda3 = ind2rgb(celda3,mapa3);
4854 %
4855 %Colocar imagen en el botón
4856 set(bc44,'CData',celda1);
4857 set(bc45,'CData',celda2);
4858 set(bc46,'CData',celda3);
4859 %
4860 %Botón "Cerrar", Figura 2
4861 bc47 = uicontrol('Parent',hVSint2,'Style','pushbutton',...
4862 'Position',[610,20,75,25],'String','Cerrar','Callback',...
4863 @bc47_Callback,'BackgroundColor','b');
4864 %
4865 %Botones: "Cargar Modelo" y "# de Controladores", Figura 3
4866 bc48 = uicontrol('Parent',hPanel31,'Style','pushbutton',...
4867 'Position',[124,5,25,25],'Callback',@bc48_Callback,...
4868 'ForegroundColor',[1,1,1],'FontWeight','bold',...
4869 'FontSize',10.5);
4870 %
4871 %Cargar información de la imagen
4872 [celda,mapa] = imread([pwd,'\ext\cdr.dtp'],'gif');
4873 %
4874 %Convertir de indexado a directo...
4875 celda = ind2rgb(celda,mapa);
4876 %
4877 %Colocar imagen en el botón
4878 set(bc48,'CData',celda);
4879 %
4880 bc49 = uicontrol('Parent',hPanel32,'Style','pushbutton',...
4881 'Position',[122,63,25,25],'Callback',@bc49_Callback,...
4882 'ForegroundColor',[1,1,1],'FontWeight','bold','String','1',...
4883 'FontSize',10,'FontName','Arial');
4884 %
4885 %Cargar información de la imagen
4886 [celda,mapa] = imread([pwd,'\ext\rda.dtp'],'gif');
4887 %
4888 %Convertir de indexado a directo...
4941 %
4942 %Etiqueta '#?.'
4943 nume = infog.svant+1;
4944 et77 = uicontrol('Style','Text','pos',[10,540,50,50],'Parent',...
4945 hVSint1,'FontName','Arial','FontSize',28,'String',nume,...
4946 'FontWeight','bold','ForegroundColor',[0,0,0.510],...
4947 'BackgroundColor',[0.8,0.8,0.8]);
4948 %
4949 %Descripción, Figura #1:
4950 et78 = uicontrol('Style','Text','pos',[70,510,600,70],'Parent',...
4951 hVSint1,'FontName','Arial','FontSize',10,'String',[' U',...
4952 'tilice las listas que se despliegan en la ventana para e',...
4953 'specificar un método de sintonización. El botón que cont',...
4954 'iene el " signo de suma ", le permitirá incluir el cont',...
4955 'rolador sintonizado en la " Tabla Resumen ".'],...
4956 'BackgroundColor',[0.8,0.8,0.8],'HorizontalAlignment',...
4957 'left','FontAngle','italic','ForegroundColor',[0,0,0.5]);
4958 %
4959 %Descripción, Figura #2:
4960 et79 = uicontrol('Style','Text','pos',[40,230,630,50],'Parent',...
4961 hVSint2,'FontName','Arial','FontSize',10,'String',[' A',...
4962 ' continuación, se muestra una tabla que contiene los mét',...
4963 'odos utilizados para sintonizar un controlador P, PI o P',...
4964 'ID (ideal), junto con los parámetros que se obtienen med',...
4965 'iante su aplicación:'],...
4966 'BackgroundColor',[0.7255,0.9137,1],'HorizontalAlignment',...
4967 'left','FontAngle','italic','ForegroundColor',[0,0,0.5]);
4968 %
4969 %"Selección de Controladores", Figura #2:
4970 et80 = uicontrol('Style','Text','pos',[40,32,200,13],'Parent',...
4971 hVSint2,'FontName','Arial','FontSize',10,'String',['Sele',...
4972 'cción de Controladores:'],'BackgroundColor',...
4973 [0.7255,0.9137,1],'FontAngle','italic','ForegroundColor',...
4974 [0.5,0,0],'FontWeight','bold');
4975 et81 = uicontrol('Style','Text','pos',[25,20,220,10],'Parent',...
4976 hVSint2,'FontName','Arial','FontSize',8,'String',['(Aná',...
4977 'lisis de la Respuesta de Lazo Cerrado)'],'BackgroundColor',...
4978 [0.7255,0.9137,1],'FontAngle','italic','ForegroundColor',...
4979 [0.5,0,0]);
4980 %
4981 %---------------------------------
4982 %Etiquetas de la Barra (figura 3):
4983 %---------------------------------
4984 %
4985 %Etiqueta "Barra de Ajustes"
4986 et82 = uicontrol('Parent',hPanel30,'Units','normalized',...
4987 'BackgroundColor',[0.502 0.502 0.502],'FontWeight','bold',...
4988 'ForegroundColor',[1 1 1],'Position',...
4989 [0.025,0.95,0.95,0.04],'String','Barra de Ajustes',...
4990 'Style','text','FontSize',9);
4991 et83 = uicontrol('Parent',hPanel30,'Units','normalized',...
4992 'BackgroundColor',[0.502 0.502 0.502],'FontWeight','bold',...
5045 'ForegroundColor',[0,0,0.5],'Position',...
5046 [0.025,0.39,0.75,0.18],'String','Tiempo Final (seg):',...
5047 'Style','text','FontSize',7.5,'HorizontalAlignment','left',...
5048 'FontAngle','italic');
5049 %
5050 %Etiqueta: "Controlador Deseado"
5051 et92 = uicontrol('Parent',hPanel30,'Units','normalized',...
5052 'BackgroundColor',[0.831,0.831,0.831],'FontWeight','bold',...
5053 'ForegroundColor',[0.4,0.4,0.4],'Position',...
5054 [0.1,0.065,0.8,0.03],'String','Controlador Deseado',...
5055 'Style','text','FontSize',8);
5056 %
5057 %Etiquetas para Títulos de los Gráficos:
5058 et94 = uicontrol('Parent',hPanel27,'Units','normalized',...
5059 'BackgroundColor',[0.9098,0.9529,1],'FontWeight','bold',...
5060 'ForegroundColor',[0,0,0.5],'Position',...
5061 [0.1,0.9,0.8,0.08],'String','Diagrama de Nyquist',...
5062 'Style','text','FontSize',10,'Visible','off');
5063 et95 = uicontrol('Parent',hPanel29,'Units','normalized',...
5064 'BackgroundColor',[0.9098,0.9529,1],'FontWeight','bold',...
5065 'ForegroundColor',[0,0,0.5],'Position',...
5066 [0.1,0.9,0.8,0.08],'String','Respuesta del Regulador',...
5067 'Style','text','FontSize',10,'Visible','off');
5068 et96 = uicontrol('Parent',hPanel28,'Units','normalized',...
5069 'BackgroundColor',[0.9098,0.9529,1],'FontWeight','bold',...
5070 'ForegroundColor',[0,0,0.5],'Position',...
5071 [0.1,0.9,0.8,0.08],'String','Gráfico de Robustez',...
5072 'Style','text','FontSize',10,'Visible','off');
5073 et98 = uicontrol('Parent',hVSint3,'BackgroundColor',...
5074 [0.931,0.931,0.931],'FontWeight','bold','Position',...
5075 [650,548,75,16],'String','Graficando...','Visible','off',...
5076 'Style','text');
5077 %
5078 %Etiqueta para Simular Barra de Progreso:
5079 barrae = uicontrol('Parent',hPanel34,'Units','normalized',...
5080 'BackgroundColor',[0,0,1],'FontWeight','bold',...
5081 'ForegroundColor',[1,1,1],'Position',...
5082 [0.05,0.2,0.9,0.6],'String',' ',...
5083 'Style','text','FontSize',8);
5084
5085 % H.10. Creación de Cuadro de Texto (Tiempo Final):
5086 cts1 = uicontrol('Style','edit','Parent',hPanel33,'Position',...
5087 [120,23,27,15],'FontSize',7);
5088
5089 % H.11. Creación de la Tabla:
5090 tb01 = actxcontrol('MSFlexGridLib.MSFlexGrid.1',[35,65,630,165],...
5091 hVSint2);
5092
5093 % H.12. Asignación de Propiedades Iniciales para la Tabla:
5094 set(tb01,'BackColorBkg',16774365,'BackColorFixed',15790320,...
5095 'Cols',12);
5096 set(tb01,'ColWidth',0,2000); set(tb01,'ColWidth',1,1600);
5097 set(tb01,'RowHeight',0,350);
5098 set(tb01,'Row',0,'Col',0,'CellForeColor',128);
5099 for k = 2:4
5100 set(tb01,'Row',0,'Col',k,'CellForeColor',8338736);
5101 set(tb01,'Row',0,'Col',k+3,'CellForeColor',32896,...
5102 'CellFontItalic',1,'CellFontName','Arial');
5103 set(tb01,'Row',0,'Col',k+7,'CellForeColor',8421504);
5104 end
5105 set(tb01,'Col',8,'CellForeColor',32896,'CellFontItalic',1,...
5106 'CellFontName','Arial');
5107
5108 % H.13. Nombrar las Columnas:
5109 txt = {'Método';'Funcionamiento';'Kc';'Ti';'Td';'Mx';'ta(5%)'; ...
5110 'ta(2%)';'ep(%)';'IAE';'ITAE';'ISE'};
5111 for k=0:11
5112 set(tb01,'Row',0,'Col',k,'CellFontBold',1,'CellAlignment',3,...
5113 'Text',txt{k+1});
5114 end
5115
5116 % H.14. Mostrar Figura 1 y Guardar Información Global
5117 set(hVSint1,'Visible','on');
5118 %
5119 if infog.svant == 1
5120 set(infog.hVInt,'Visible','off');
5121 end
5122 %
5123 infog.hVSint1 = hVSint1; infog.lp01=lp01; infog.et61 = et61;
5124 infog.sia = []; infog.hVSint2 = hVSint2;
5125 infog.snvt = 0; infog.tb01 = tb01; infog.snci = '';
5126 infog.scfut=[8388608,255,8388736,32768,8421376,359915];
5127 infog.scolfa = 1; infog.sics1 = 0; infog.sics2 = 0;
5128 infog.sics3 = 0; infog.hVSint3 = hVSint3; infog.et87 = et87;
5129 infog.et88 = et88; infog.et89 = et89; infog.bc49 = bc49;
5130 infog.bc42 = bc42; infog.bc50 = bc50; infog.bc52 = bc52;
5131 infog.bc49 = bc49; infog.txS1 = txS1; infog.et85 = et85;
5132 infog.cts1 = cts1; infog.hES1 = hES1; infog.hES2 = hES2;
5133 infog.hES3 = hES3; infog.hES4 = hES4; infog.et94 = et94;
5134 infog.et95 = et95; infog.et96 = et96;
5135 infog.svtx = 0; infog.bc59 = bc59; infog.barrae = barrae;
5136 infog.hPanel34 = hPanel34; infog.et98 = et98;
5137 %
5138 %Si el usuario elegió un modelo en la sección de identificación,
5139 %establecerlo como "predeterminado" en la barra de la ventana #3:
5140 %
5141 if infog.svant == 6 & infog.igppp ~= 0
5142 mostrarpargp(infog.gppp);
5143 else
5144 if infog.svant == 6 & infog.sigp ~= 0
5145 mostrarpargp(infog.sgp);
5146 end
5147 end
5148
5149
5150 %Subrutina para Eliminar Listas Desplegables: "Tipo de Controlador" y/o
5151 %"Criterio Integral"
5152 function eliminarmds()
5153 global infog;
5154 %
5155 try
5156 delete(infog.et75);
5157 end
5158 try
5159 delete(infog.et76);
5160 end
5161 try
5162 delete(infog.md02);
5163 end
5164 try
5165 delete(infog.md03);
5166 end
5167 try
5168 delete(infog.bc40);
5169 end
5170 infog.snci = '';
5171
5172 %Subrutina para Mostrar Listas Desplegables: "Tipo de Controlador" y/o
5173 %"Criterio Integral"
5174 function mostrarmds(nlistas,lconts,lcitgs)
5175 global infog;
5176 %
5177 et75 = uicontrol('Style','text','pos',[490,70,110,20],'String',...
5178 'Tipo de Controlador:','FontName','Arial','FontSize',8,...
5179 'HorizontalAlignment','left','BackgroundColor',[0.8,0.8,0.8]);
5180 md02 = uicontrol('Style','popupmenu','Position',[595,75,40,20],...
5181 'String',lconts,'FontName','Arial','FontSize',7.5,...
5182 'BackgroundColor',[0.875,1,0.937]);
5183 %
5184 %Mostrar Botón: "Agregar"
5185 bc40 = uicontrol('Style','pushbutton','Position',[540,10,25,27],...
5186 'Callback',@bc40_Callback,'BackgroundColor',[0.357,0.875,0.384]);
5187 %
5188 %Cargar información de la imagen
5189 [celda,mapa] = imread([pwd,'\ext\inv.dtp'],'gif');
5190 %
5191 %Convertir de indexado a directo...
5192 celda = ind2rgb(celda,mapa);
5193 %
5194 %Colocar imagen en el botón
5195 set(bc40,'CData',celda);
5196
5197 infog.et75 = et75; infog.md02 = md02; infog.bc40 = bc40;
5198 %
5199 if nlistas > 1
5200 et76 = uicontrol('Style','text','pos',[490,45,100,20],...
5617 %
5618 %///////////////////////////////////////////////////
5619 %PROCEDIMIENTO PARA DETERMINAR LA SECUENCIA DE DATOS
5620 %///////////////////////////////////////////////////
5621 %
5622 if esvt(mdatos(:,1))
5623 vt = mdatos(:,1);
5624 if posy == 2
5625 vu = mdatos(:,3);
5626 vy = mdatos(:,2);
5627 else
5628 vu = mdatos(:,2);
5629 vy = mdatos(:,3);
5630 end
5631 elseif esvt(mdatos(:,2))
5632 vt = mdatos(:,2);
5633 if posy == 1
5634 vu = mdatos(:,3);
5635 vy = mdatos(:,1);
5636 else
5637 vu = mdatos(:,1);
5638 vy = mdatos(:,3);
5639 end
5640 else
5641 vt = mdatos(:,3);
5642 if posy == 2
5643 vu = mdatos(:,1);
5644 vy = mdatos(:,2);
5645 else
5646 vu = mdatos(:,2);
5647 vy = mdatos(:,1);
5648 end
5649 end
5650 %
5651 %///////////////////////////////////////////////////
5652 %
5653 [ND,Iu] = max(abs(vu));
5654 [ND,Iy] = max(abs(vy));
5655 %
5656 umax = promemax(vu,Iu);
5657 ymax = promemax(vy,Iy);
5658 %
5659 %Corrección Nivel DC
5660 if abs(vu(1)) > 0.6 * umax;
5661 vu = vu - umax;
5662 vy = vy - ymax;
5663 end
5664
5665 %Función promemax
5666 function val = promemax(vec,I)
5667 val = 0;
5668 long = length(vec);
5669 %
5670 if I < 6
5671 for k=1:10
5672 val = val+vec(k);
5673 end
5674 val = val/10;
5675 elseif I > long-5;
5676 for k=0:9
5677 val = val+vec(end-k);
5678 end
5679 val = val/10;
5680 else
5681 val = vec(I);
5682 for k=1:5
5683 val = val+vec(I-k);
5684 end
5685 for k=1:5
5686 val = val+vec(I+k);
5687 end
5688 val = val/11;
5689 end
5690
5691 %Función esvt: Verificar si el vector dado es el vector de tiempos
5692 function resp=esvt(vent)
5693 long = length(vent);
5694 %
5695 paso = 0;
5696 for k=0:9
5697 paso = paso+vent(round(long/2)-k)-vent(round(long/2)-k-1);
5698 end
5699 paso = paso/10; %Promedio
5700 %
5701 contador = 0;
5702 for k=0:long-2
5703 if round(10*((vent(long-k)-vent(long-k-1))-paso))==0
5704 contador = contador + 1;
5705 end
5706 end
5707 %
5708 if contador >= 0.9*long & paso~=0
5709 resp=1;
5710 else
5711 resp=0;
5712 end
5713
5714 %Función para Efectuar el Filtrado
5715 function vyf = filtrado(varargin);
5716 %//////////////////////////////////////////////////
5717 %// //
5718 %//FUNCIÓN vyf = filtrado(vy,tipo_filtro,... //
5719 %// orden_filtro,...) //
5720 %// //
5773 %
5774 %Lectura de argumentos de entrada opcionales (depende del tipo ...
5775 %de filtro)
5776 if tipo_filtro > 0 & tipo_filtro < 4
5777 if tipo_filtro == 3
5778 delta1_filtro = cell2mat(varargin(5));
5779 delta2_filtro = cell2mat(varargin(6));
5780 else
5781 delta1_filtro = cell2mat(varargin(5));
5782 end
5783 end
5784 %
5785 %Llamada a funciones de filtro:
5786
5787 switch tipo_filtro
5788 case 1 %Filtro Chebyshev Tipo I
5789 [b,a]=cheby1(orden_filtro,delta1_filtro,frec_corte,'low');
5790 case 2 %Filtro Chebyshev Tipo II
5791 [b,a]=cheby2(orden_filtro,delta1_filtro,frec_corte,'low');
5792 case 3 %Filtro Elíptico (De Cauer)
5793 [b,a]=ellip(orden_filtro,delta1_filtro,delta2_filtro,...
5794 frec_corte,'low');
5795 otherwise %Butterworth
5796 [b,a]=butter(orden_filtro,frec_corte);
5797 end
5798 %
5799 %Aplicación del filtro sobre la señal original
5800 vyf=filter(b,a,vy);
5801 else
5802 vyf=vy; %No aplicar filtro
5803 end
5804
5805 %Función para Identificar Modelos de Lazo Abierto
5806 function [gp,kpm,tmm,taom] = identif_la(vt,vu,yf,metodo)
5807
5808 %//////////////////////////////////////////////////
5809 %// //
5810 %//FUNCIÓN gp = identif_la(vt,vu,yf,metodo) //
5811 %// //
5812 %// + gp: Modelo Identificado //
5813 %// + kpm: Ganancia del Proceso //
5814 %// + tmm: Tiempo Muerto del Proceso //
5815 %// + taom: Constante(s) de Tiempo //
5816 %// + vt: Vector de Tiempos //
5817 %// + vu: Vector de Entrada //
5818 %// + yf: Vector de Salida (Filtrado) //
5819 %// + metodo: Método de Identificación de LA //
5820 %// //
5821 %// ------------------- //
5822 %// MÉTODOS DISPONIBLES: //
5823 %// ------------------- //
5824 %// 1. Áreas Características POMTM //
5877 k = k+1;
5878 end
5879 ti_esc = vt(k); %Tiempo de inicio del escalón
5880 iti_esc = k;
5881 np = length(vt);
5882 %
5883 nvt = vt(iti_esc:np); nyf = yf(iti_esc:np);
5884 ydf = yl-nyf;
5885 Ao = trapz(nvt,ydf);
5886 taot = Ao/yl;
5887 %
5888 vtx = abs(vt-taot); [ND,I] = min(vtx);
5889 nyf2 = nyf(1:I); nvt2 = nvt(1:I);
5890 A1 = trapz(nvt2,nyf2);
5891 sigma = A1/(taot*yl);
5892 %
5893 tao = sigma*exp(1)*taot;
5894 tm = taot-tao;
5895 %
5896 if tm < 0
5897 tm = 0;
5898 end
5899 %
5900 %Modelo obtenido:
5901 taom = tao; tmm = tm;
5902 gp = kp/(tao*s+1); gp.OutputDelay = tm;
5903 %--
5904 elseif metodo > 1 & metodo < 11 %////Métodos de dos puntos////
5905 p1 = mat_dospts1(metodo-1,1);
5906 p2 = mat_dospts1(metodo-1,2);
5907 a = mat_dospts1(metodo-1,3);
5908 b = mat_dospts1(metodo-1,4);
5909 %
5910 t1 = txporce(vt,vu,yf,yl,p1);
5911 t2 = txporce(vt,vu,yf,yl,p2);
5912 %
5913 tao = a*(t2-t1); %Constante de tiempo
5914 tm = b*t1 + (1-b)*t2; %Tiempo muerto
5915 if tm < 0
5916 tm = 0;
5917 end
5918 %
5919 tmm = tm; taom = tao;
5920 if metodo < 8
5921 gp = kp/(tao*s+1); %Si es POMTM
5922 else
5923 gp = kp/(tao*s+1)^2; %Si es SOMTM, polo doble
5924 end
5925 gp.OutputDelay = tm;
5926 %--
5927 elseif metodo == 11 %//// Método de Stark ////
5928 t1 = txporce(vt,vu,yf,yl,0.15);
5929 t2 = txporce(vt,vu,yf,yl,0.45);
5930 t3 = txporce(vt,vu,yf,yl,0.75);
5931 %
5932 x = (t2-t1)/(t3-t1);
5933 chi = (0.0805-5.547*(0.475-x)^2)/(x-0.356);
5934 if chi <= 1
5935 f2 = 0.708*2.811^chi;
5936 else
5937 f2 = 2.6*chi-0.6;
5938 end
5939 wn = f2/(t3-t1); f3 = 0.922*1.66^chi;
5940 tm = t2 - f3/wn;
5941 if tm < 0
5942 tm = 0;
5943 end
5944 %
5945 tmm = tm;
5946 if chi >= 1
5947 tao1 = (chi+sqrt(chi^2-1))/wn;
5948 tao2 = (chi-sqrt(chi^2-1))/wn;
5949 taom = [chi,tao1,tao2];
5950 gp = kp/((tao1*s+1)*(tao2*s+1));
5951 else
5952 gp = kp*wn^2/(s^2+2*chi*wn*s+wn^2);
5953 taom = [chi,wn];
5954 end
5955 gp.OutputDelay = tm;
5956 %--
5957 elseif metodo == 12 %///Método de Jahanmiri y Fallahi///
5958 t1 = txporce(vt,vu,yf,yl,0.02);
5959 t2 = txporce(vt,vu,yf,yl,0.05);
5960 t3 = txporce(vt,vu,yf,yl,0.7);
5961 t4 = txporce(vt,vu,yf,yl,0.9);
5962 %
5963 tm = [t1,t2];
5964 for k=1:2
5965 nx=(t4-t3)/(t4-tm(k));
5966 if nx <= 0.4771
5967 chi(k) = sqrt((0.48446561-0.75323499*nx)/(1-2.0946464*nx));
5968 else
5969 chi(k) = 13.9352;
5970 end
5971 tao(k) = (t4-tm(k))/(0.424301+4.62533*chi(k)-2.65412*exp(-chi(k)));
5972 end
5973 %
5974 if tm(1)<0
5975 tm(1)=0;
5976 end
5977 if tm(2)<0
5978 tm(2)=0;
5979 end
5980 %
6085 s = tf('s');
6086 mxvu = max(vu); k = 1;
6087 %
6088 [ND,I] = max(yf);
6089 tp1 = vt(I); yp1 = yf(I); %Primer pico
6090 for k = I:length(yf) %Recorte del vector
6091 va(k-I+1) = vt(k);
6092 vb(k-I+1) = yf(k);
6093 end
6094 %
6095 [ND,I] = min(vb);
6096 tm1 = va(I); ym1 = vb(I); %Primer mínimo
6097 for k = I:length(vb) %Recorte del vector
6098 vc(k-I+1) = va(k);
6099 vd(k-I+1) = vb(k);
6100 end
6101 %
6102 [ND,I] = max(vd);
6103 tp2 = vc(I); yp2 = vd(I); %Segundo pico
6104 yu = 0; du = 0;
6105 for k=0:9 %Promedio de los últimos 10 valores
6106 yu = yu + yf(length(yf)-k);
6107 du = du + vu(length(vu)-k);
6108 end
6109 %
6110 yu = yu/10; du = du/10; %Valor final de la respuesta
6111
6112
6113 %/////////////// MÉTODOS DE IDENTIFICACIÓN LC ///////////////
6114 switch metodo
6115 case 1 %///------Yuwana y Seborg------///
6116 %Ecuaciones del método
6117 deltat = fdeltat(vt,yf,tm1,yu);
6118 kp = yu/(kc*(du-yu)); K = kc*kp;
6119 den1 = sqrt(pi^2+(log((yu-ym1)/(yp1-yu)))^2);
6120 den2 = sqrt(4*pi^2+(log((yp2-yu)/(yp1-yu)))^2);
6121 chi1 = -log((yu-ym1)/(yp1-yu))/den1;
6122 chi2 = -log((yp2-yu)/(yp1-yu))/den2;
6123 chip = (chi1+chi2)/2;
6124 fact1 = sqrt((1-chip^2)*(K+1))/pi;
6125 tao = deltat*(chip*sqrt(K+1)+sqrt(chip^2*(K+1)+K))*fact1;
6126 den3 = pi*(chip*sqrt(K+1)+sqrt(chip^2*(K+1)+K));
6127 tm = 2*deltat*sqrt((1-chip^2)*(K+1))/den3;
6128 if tm < 0
6129 tm = 0;
6130 end
6131 %
6132 %Modelo
6133 kpm = kp; tmm = tm; taom = tao;
6134 gp = kp/(tao*s+1);
6135 gp.OutputDelay = tm;
6136 %--
6189 gp = kp/(tao*s+1);
6190 gp.OutputDelay = tm;
6191 %--
6192 case 4 %///------Bogere y Özgen-------///
6193 a = -0.8647; b = 0.2260;
6194 deltat = fdeltat(vt,yf,tm1,yu);
6195 kp = abs(yu-yf(1))/(kc*(du-abs(yu-yf(1)))); K = kc*kp;
6196 tm = tp1 - deltat;
6197 den1 = sqrt(pi^2+(log((yu-ym1)/(yp1-yu)))^2);
6198 den2 = sqrt(4*pi^2+(log((yp2-yu)/(yp1-yu)))^2);
6199 chi1 = -log((yu-ym1)/(yp1-yu))/den1;
6200 chi2 = -log((yp2-yu)/(yp1-yu))/den2;
6201 chi = (chi1+chi2)/2;
6202 alfa = (deltat/pi)*chi*sqrt(1-chi^2)*(1+K)-0.5*a*K*tm;
6203 beta1 = (deltat/pi)^2*(1-chi^2)*(1+K)*(chi^2*(1+K)-1);
6204 beta2 = (deltat/pi)*chi*sqrt(1-chi^2)*(1+K)*-a*K*tm;
6205 beta3 = K*tm^2*(0.25*K*a^2+b);
6206 beta = sqrt(beta1+beta2+beta3);
6207 tao1 = alfa+beta;
6208 tao2 = alfa-beta;
6209 %
6210 if tao2 < 0
6211 tao2 = 0;
6212 end
6213 if tm < 0
6214 tm = 0;
6215 end
6216 %
6217 %Modelo
6218 kpm = kp; tmm = tm; taom = [tao1,tao2];
6219 gp = kp/((tao1*s+1)*(tao2*s+1)); gp.OutputDelay = tm;
6220 end
6221
6222 %Función Para el Cálculo de deltat (parámetro necesario para obtener
6223 %modelos de identificación de LC)
6224 function dt = fdeltat(vt,vy,tm1,yu)
6225 %
6226 [ND,I]=min(abs(vt-tm1));
6227 vtx = 0; vyx = 0;
6228 for k=1:I
6229 vtx(k) = vt(k);
6230 vyx(k) = vy(k);
6231 end
6232 %
6233 [ND,I]=max(vyx);
6234 for k=1:length(vyx)
6235 if k <= I
6236 vtx1(k) = vtx(k);
6237 vyx1(k) = vyx(k);
6238 else
6239 vtx2(k-I) = vtx(k);
6240 vyx2(k-I) = vyx(k);
6241 end
6242 end
6243 %
6244 %Primera Etapa
6245 vaux = abs(vyx1 - yu);
6246 [ND,I] = min(vaux);
6247 pol=0;
6248 if vyx1(I)-yu == 0
6249 ta = vtx1(I);
6250 elseif vyx1(I)-yu < 0
6251 pol = polyfit([vyx1(I),vyx1(I+1)],[vtx1(I),vtx1(I+1)],1);
6252 ta = polyval(pol,yu);
6253 else
6254 pol = polyfit([vyx1(I-1),vyx1(I)],[vtx1(I-1),vtx1(I)],1);
6255 ta = polyval(pol,yu);
6256 end
6257 %
6258 %Segunda Etapa
6259 vaux = abs(vyx2 - yu);
6260 [ND,I] = min(vaux);
6261 pol=0;
6262 if vyx2(I)-yu == 0
6263 tb = vtx2(I);
6264 elseif vyx1(I)-yu < 0
6265 pol = polyfit([vyx2(I),vyx2(I+1)],[vtx2(I),vtx2(I+1)],1);
6266 tb = polyval(pol,yu);
6267 else
6268 pol = polyfit([vyx2(I-1),vyx2(I)],[vtx2(I-1),vtx2(I)],1);
6269 tb = polyval(pol,yu);
6270 end
6271 dt = tb-ta;
6272
6273 %Función - Sintonización
6274 function [kc,Td,Ti,gc,tgc] = sintoniz(gp,varargin)
6275
6276 %///////////////////////////////////////////////////////
6277 %// //
6278 %//FUNCIÓN sintoniz(gp,tpctl,metodo,[...]) //
6279 %// //
6280 %// + gp: Modelo Identificado para la planta //
6281 %// + kc=ganancia del controlador //
6282 %// + Td=Tiempo Derivativo //
6283 %// + Ti=Tiempo Integral //
6284 %// + gc=Función de Transferencia del Controlador //
6285 %// + tgc=Clase de PID: PID Ideal, PID Serie, etc... //
6286 %// + yf: Vector de Salida (Filtrado) //
6287 %// + tpctl=Tipo de Controlador (Modos Deseados) //
6288 %// + lambda //
6289 %// //
6290 %//Nota: //
6291 %//---- //
6292 %// tgc = //
6293 %// 1. P //
6294 %// 2. PD //
6295 %// 3. PI //
6296 %// 4. PID Serie //
6297 %// 5. PID Ideal //
6298 %// //
6299 %// a) Para Ziegler y Nichols y Shinskey se debe //
6300 %// usar la siguiente sintaxis: //
6301 %// //
6302 %// ... = sintoniz(0,tpctl,metodo,Kcu,Tu) //
6303 %// donde: //
6304 %// *metodo = 24 (Z y N) ó 25 (Shinskey) //
6305 %// *Kcu = Ganancia Crítica //
6306 %// *Tu = Período Crítico //
6307 %// //
6308 %// b) Para Martin et al. se debe utilizar la si- //
6309 %// guiente sintaxis: //
6310 %// //
6311 %// ... = sintoniz(gp,tpctl,metodo,lambda) //
6312 %// donde: //
6313 %// *metodo = 22 (Modelo POMTM) ó 23 (Modelo ... //
6314 %// SOMTM) //
6315 %// //
6316 %// //
6317 %// c) Para Rivera y Brosilow IMC se debe usar la //
6318 %// siguiente sintaxis: //
6319 %// ... = sintoniz(gp,tpctl,metodo,lambda) //
6320 %// donde: //
6321 %// *metodo = 26 (Rivera IMC POMTM), 27 (Bro- //
6322 %// silow IMC POMTM) ó 28 (Brosilow IMC SOMTM) //
6323 %// *lambda = Constante del Filtro //
6324 %// //
6325 %///////////////////////////////////////////////////////
6326
6327 %1) Lectura de los parámetros obligatorios de entrada
6328 tpctl = cell2mat(varargin(1));
6329 metodo = cell2mat(varargin(2));
6330 %
6331 s = tf('s');
6332 %
6333 %2) Obtención de parámetros a partir de la función de transferencia
6334 % de la planta, gp
6335 %
6336 if metodo<20 | metodo==22 | (metodo>25 & metodo<28)
6337 [z,p,kp] = zpkdata(minreal(gp));
6338 kp = kp/abs(p{1}); tao = 1/abs(p{1});
6339 tm = gp.OutputDelay;
6340 tc = tm/tao;
6341 elseif metodo>19 & metodo<22 | metodo==28
6342 [z,p,kp] = zpkdata(minreal(gp));
6343 [num,den] = tfdata(minreal(gp));
6344 den = den{1};
6345 kp = kp/den(3);
6346 tao = sqrt(1/den(3));
6347 chi = den(2)*tao/2;
6348 tm = gp.OutputDelay;
6349 tc = tm/tao;
6350 elseif metodo == 23
6351 [z,p,kp] = zpkdata(minreal(gp)); p=p{1};
6352 if -1/p(1) > -1/p(2)
6353 tao1 = -1/p(1); tao2 = -1/p(2);
6354 else
6355 tao2 = -1/p(1); tao1 = -1/p(2);
6356 end
6357 kp = kp*tao1*tao2; tm = gp.OutputDelay;
6358 end
6359
6360 %3) Inicialización de parámetros del controlador
6361 kc = 0; Td = 0; Ti = 0;
6362
6363 %4) Asignación del parámetros del controlador según el método
6364 % seleccionado por el usuario
6365 %
6366
6367 %//////////////////////////////////////////////////////%
6368 %///// /////%
6369 %///// REGLAS DE SINTONIZACIÓN /////%
6370 %///// /////%
6371 %//////////////////////////////////////////////////////%
6372
6373 if metodo == 1 | metodo == 2 %Alfaro IAE, S y R
6374 m = metodo;
6375 %
6376 %Constantes del método:
6377 a = [0.3295,0.2068]; b = [0.7182,1.1597];
6378 c = [-0.9971,-1.0158]; d = [0.9781,-0.2228];
6379 e = [0.3723,1.3009]; f = [0.8456,0.5022];
6380 g = [0.3416,0.3953]; h = [0.9414,0.8469];
6381 %
6382 %Asignación de parámetros (PID+Ideal):
6383 kc = (a(m)+b(m)*tc^c(m))/kp;
6384 Ti = tao*(d(m)+e(m)*tc^f(m));
6385 %
6386 if tpctl == 1 %Controlador PI
6387 %
6388 %Obtención de la función de transferencia
6389 gc = kc*(1+1/(Ti*s));
6390 tgc = 3;
6391 else %Controlador PID (ideal)
6392 Td = tao*g(m)*tc^h(m);
6393 %
6394 %Obtención de la función de transferencia
6395 gc = kc*(1+1/(Ti*s)+Td*s);
6396 tgc = 5;
6397 end
6398 %--
6399 elseif metodo > 2 & metodo < 7 %Arrieta IAE, ITAE, R y S
6400 m = 2*(metodo - 2)-1;
6401 %
6402 %Constantes del método:
6403 a = [0.45,0.1050,0.2607,0.1230,0.2438,0.2268,0.1140,0.1749];
6404 b = [0.6494,1.2432,0.6470,1.1891,0.5305,0.8051,0.5131,0.8355];
6405 c = [-1.1251,-0.9946,-1.1055,-1.0191,-1.0299,-0.9597,...
6406 -1.0382,-0.9462];
6407 d = [-0.2551,-0.2512,-1.5926,-0.3173,0.9377,1.0068,0.9953,0.9581];
6408 e = [1.8205,1.3581,2.9191,1.4489,0.4337,0.3658,0.2073,0.3987];
6409 f = [0.4749,0.4796,0.1789,0.4440,0.8714,1.0092,1.5246,0.6884];
6410 g = [0,-0.0003,0,-0.0053,0,-0.0146,0,-0.0169];
6411 h = [0,0.3838,0,0.3695,0,0.3500,0,0.3126];
6412 I = [0,0.9479,0,0.9286,0,0.8100,0,0.7417];
6413 %
6414 %Asignación de parámetros (PID):
6415 if tpctl == 1 %Controlador PI
6416 kc = (a(m)+b(m)*tc^c(m))/kp;
6417 Ti = tao*(d(m)+e(m)*tc^f(m));
6418 %
6419 %Obtención de la función de transferencia
6420 gc = kc*(1+1/(Ti*s));
6421 tgc = 3;
6422 else %Controlador PID (ideal)
6423 kc = (a(m+1)+b(m+1)*tc^c(m+1))/kp;
6424 Ti = tao*(d(m+1)+e(m+1)*tc^f(m+1));
6425 Td = tao*(g(m+1)+h(m+1)*tc^I(m+1));
6426 %
6427 %Obtención de la función de transferencia
6428 gc = kc*(1+1/(Ti*s)+Td*s);
6429 tgc = 5;
6430 end
6431 %--
6432 elseif metodo == 7 %Cohen y Coon, R
6433 %
6434 %Asignación de parámetros (según tipo de controlador):
6435 switch tpctl
6436 case 1 %Controlador P
6437 kc = tao*(1+tm/(3*tao))/(kp*tm);
6438 %
6439 %Obtención de la función de transferencia
6440 gc = kc;
6441 tgc = 1;
6442 case 2 %Controlador PI
6443 kc = tao*(9/10+tm/(12*tao))/(kp*tm);
6444 Ti = tm*((30+3*tm/tao)/(9+20*tm/tao));
6445 %
6446 %Obtención de la función de transferencia
6447 gc = kc*(1+1/(Ti*s));
6448 tgc = 3;
6501 c = [2.0325,1.6447,1.4837];
6502 d = [0.7390,0.7070,0.6800];
6503 kc = a(m)/kp*tc^(b(m));
6504 Ti = c(m)*tao*tc^(d(m));
6505 %
6506 %Obtención de la función de transferencia
6507 gc = kc*(1+1/(Ti*s));
6508 tgc = 3;
6509 case 3 %Controlador PID (ideal)
6510 a = [1.4950,1.4350,1.3570];
6511 b = [-0.9450,-0.9210,-0.9470];
6512 c = [0.9083,1.1390,1.1876];
6513 d = [0.7710,0.7490,0.7380];
6514 e = [0.5600,0.4820,0.3810];
6515 f = [1.0060,1.1370,0.9950];
6516 kc = a(m)/kp*tc^(b(m));
6517 Ti = c(m)*tao*tc^(d(m));
6518 Td = e(m)*tao*tc^(f(m));
6519 %
6520 %Obtención de la función de transferencia
6521 gc = kc*(1+1/(Ti*s)+Td*s);
6522 tgc = 5;
6523 end
6524 elseif metodo > 11 & metodo < 18 %Kaya y Sheib IAE, ITAE, ISE, R y S
6525 m = metodo - 11;
6526 %
6527 %Constantes del método:
6528 a = [0.98089,0.77902,1.11907,0.65000,1.12762,0.71959];
6529 b = [-0.76167,-1.06401,-0.89711,-1.04432,-0.80368,-1.03092];
6530 c = [1.09851,0.87481,1.25203,0.98950,0.99783,1.12666];
6531 d = [1.05211,0.70949,0.95480,0.09539,0.02860,-0.18145];
6532 e = [0.59974,0.57137,0.54766,0.50814,0.42844,0.54568];
6533 f = [0.89819,1.03826,0.87798,1.08433,1.00810,0.86411];
6534 %
6535 %Asignación de parámetros (PID):
6536 kc = a(m)/kp*tc^b(m);
6537 if metodo < 15 %Regulador
6538 Ti = c(m)*tao*tc^d(m);
6539 else %Servomecanismo
6540 Ti = tao/(c(m)+d(m)*tc);
6541 end
6542 %
6543 if tpctl == 1 %Controlador PI
6544 %
6545 %Obtención de la función de transferencia
6546 gc = kc*(1+1/(Ti*s));
6547 tgc = 3;
6548 else %Controlador PID (serie)
6549 Td = e(m)*tao*tc^f(m);
6550 %
6551 %Obtención de la función de transferencia
6552 gc = kc*(1+1/(Ti*s))*(1+Td*s);
6553 tgc = 4;
6554 end
6555 elseif metodo > 17 & metodo < 20 %Rovira IAE, ITAE, S
6556 m = metodo - 17;
6557 %
6558 if tpctl == 1 %Controlador PI
6559 a = [0.7580,0.5860];
6560 b = [-0.8610,-0.9160];
6561 c = [1.0200,1.0300];
6562 d = [-0.3230,-0.1650];
6563 kc = a(m)/kp*tc^b(m);
6564 Ti = tao/(c(m)+d(m)*tc);
6565 %
6566 %Obtención de la función de transferencia
6567 gc = kc*(1+1/(Ti*s));
6568 tgc = 3;
6569 else %Controlador PID (ideal)
6570 a = [1.0860,0.9650];
6571 b = [-0.8690,-0.8500];
6572 c = [0.7400,0.7960];
6573 d = [-0.1300,-0.1465];
6574 e = [0.3480, 0.3080];
6575 f = [0.9140, 0.9290];
6576 kc = a(m)/kp*tc^b(m);
6577 Ti = tao/(c(m)+d(m)*tc);
6578 Td = e(m)*tao*tc^f(m);
6579 %
6580 %Obtención de la función de transferencia
6581 gc = kc*(1+1/(Ti*s)+Td*s);
6582 tgc = 5;
6583 end
6584 elseif metodo > 19 & metodo < 22 %Sung, R y S
6585 tc = tm/tao;
6586 %
6587 if metodo == 21 %Servo:
6588 if chi <= 0.9
6589 kc = (-0.04+(0.333+0.949*tc^(-0.983))*chi)/kp;
6590 else
6591 kc = (-0.544+0.308*tc+1.408*chi*tc^(-0.832))/kp;
6592 end
6593 if tc <= 1
6594 Ti = tao*chi*(2.055+0.072*tc);
6595 else
6596 Ti = tao*chi*(1.768+0.329*tc);
6597 end
6598 %
6599 if tpctl == 1 %Controlador PI
6600 %
6601 %Obtención de la función de transferencia
6602 gc = kc*(1+1/(Ti*s));
6603 tgc = 3;
6604 else %Controlador PID (ideal)
6657 %
6658 %Obtención de la función de transferencia
6659 gc = kc*(1+1/(Ti*s));
6660 tgc = 3;
6661 else
6662 Ti = tao1; Td = tao2;
6663 kc = lambda*tao1/(kp*(lambda*tm+1));
6664 %
6665 %Obtención de la función de transferencia
6666 gc = kc*(1+1/(Ti*s)+Td*s);
6667 tgc = 4; %PID Serie
6668 end
6669 %
6670 elseif metodo == 24 %Ziegler y Nichols de Lazo Cerrado
6671 %
6672 %Obtener parámetros Kcu y Tu:
6673 Kcu = cell2mat(varargin(3));
6674 Tu = cell2mat(varargin(4));
6675 %
6676 if tpctl == 1 %Controlador P
6677 kc = 0.5*Kcu;
6678 %
6679 %Obtención de la función de transferencia
6680 gc = kc;
6681 tgc = 1;
6682 elseif tpctl == 2 %Controlador PI
6683 kc = 0.45*Kcu;
6684 Ti = Tu/1.2;
6685 %
6686 %Obtención de la función de transferencia
6687 gc = kc*(1+1/(Ti*s));
6688 tgc = 3;
6689 else %Controlador PID (Ideal)
6690 kc = 0.75*Kcu;
6691 Ti = Tu/1.6;
6692 Td = Tu/10;
6693 %
6694 %Obtención de la función de transferencia
6695 gc = kc*(1+1/(Ti*s)+Td*s);
6696 tgc = 5;
6697 end
6698 %
6699 elseif metodo == 25 %Shinskey
6700 %
6701 %Obtener parámetros Kcu y Tu:
6702 Kcu = cell2mat(varargin(3));
6703 Tu = cell2mat(varargin(4));
6704 %
6705 if tpctl == 1 %Controlador PI
6706 kc = 0.43*Kcu;
6707 Ti = 0.5*Tu;
6708 %
6761 gc = kc*(1+1/(Ti*s)+Td*s);
6762 tgc = 5;
6763 end
6764 %
6765 else %Brosilow IMC, SOMTM
6766 %
6767 %Obtener parámetro lambda:
6768 lambda = cell2mat(varargin(3));
6769 %
6770 Ti = 2*chi*tao+(2*lambda^2-tm^2)/(2*(2*lambda+tm));
6771 kc = Ti/(kp*(2*lambda+tm));
6772 %
6773 if tpctl == 1 %Controlador PI
6774 %
6775 %Obtención de la función de transferencia
6776 gc = kc*(1+1/(Ti*s));
6777 tgc = 3;
6778 else %Controlador PID
6779 Td = Ti-2*chi*tao+(tao^2-(tm^3)/(6*(2*lambda+tm)))/Ti;
6780 %
6781 %Obtención de la función de transferencia
6782 gc = kc*(1+1/(Ti*s)+Td*s);
6783 tgc = 5;
6784 end
6785 end
6786
6787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6789 %%%%%%%%%%%%%%%%%%%%%%%%%%%% FUNCIÓN NYQLOG %%%%%%%%%%%%%%%%%%%%%%%%%%%%
6790 %%%%%%%%%%%%%%%%%%%%% ELABORADA POR Trond Andresen %%%%%%%%%%%%%%%%%%%%%%
6791 %%%%%%%%%%%%%%%%%%%%% <Trond.Andresen@itk.ntnu.no> %%%%%%%%%%%%%%%%%%%%%%
6792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6793 %%%%%%%%%%%%%%% DEPARTAMENTO DE INGENIERÍA EN CIBERNÉTICA %%%%%%%%%%%%%%%
6794 %%%%%%%%%%%%%% UNIVERSIDAD NORUEGA DE CIENCIA Y TECNOLOGÍA %%%%%%%%%%%%%%
6795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6796 %%%%%%%%%%%%%%%%%%%%%%%%%% Trondheim, NORUEGA %%%%%%%%%%%%%%%%%%%%%%%%%%%
6797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6799
6800
6801 function nyqlog(sys,col1,col2,col3)
6802
6803 % Checking system order:
6804 [hlp,den]=tfdata(sys,'v');
6805 k=1;
6806 while (hlp(k) == 0) k=k+1; end
6807 num=(hlp(k:end));
6808 hlp=size(size(den));
6809 if (hlp(2)> 2)
6810 error('Only monovariable systems allowed in Nyqlog');
6811 end
6812
6917
6918 % Plotting main graph and its mirror image:
6919
6920 s1=s;
6921 spiralfactor=1.5;
6922 spiralfactor=1/spiralfactor;
6923 %set(gcf,'Color',[1 1 1]);
6924 s = scurve(s1,R,spiralfactor, Np_origin, Np_imag,impoles);
6925 %plot(s); hold on;
6926 %break;
6927 %plot([0 1],[R 1]);
6928 s=conj(s);
6929 [zmirr,ncount] = nygraph(sys,s,0,[col3,'-']);
6930 hold on;
6931 spiralfactor=1/spiralfactor;
6932 s = scurve(s1,R,spiralfactor, Np_origin, Np_imag,impoles);
6933 [zmain,ncount] = nygraph(sys,s,1,[col3,'-']);
6934 % Plotting background diagram;
6935 paru1 = col1; paru2 = [col1,'.']; %Agregué esto!
6936 circle(0,0.5,paru1);
6937 circle(0,0.6666666667,paru2);
6938 circle(0,0.833333333,paru2);
6939 circle(0,1,paru1);
6940 circle(0,1.16666667,paru2);
6941 circle(0,1.33333333,paru2);
6942 circle(0,1.5,paru1);
6943 phase_lines(24,0.5,1.5,paru2);
6944 phase_lines(8,0.5,1.5,paru1);
6945 argu3 = [col3(1),'o']; %Agregué esto!
6946 plot(-1,0,argu3,'LineWidth',2.5);
6947 plot([-1.5 1.5],[0 0]); plot([0 0],[-1.5 1.5]);
6948 text(0.03,-0.05,'-120','FontSize',7);
6949 text(0.4141, -0.3331,'-60','FontSize',9);
6950 text(0.8, -0.64,'0 dB','FontSize',8);
6951 text(1.1924, -0.9575,'+60','FontSize',9);
6952
6953 % Plotting directional arrows:
6954 % for xh = [0.8 0.65 0.45 0.25]
6955 for xh = [0.8 0.15]
6956 nmid=round(xh*ncount);
6957 arrow(zmain(nmid+1),zmain(nmid),col2);
6958 end
6959 % for xh = [0.75 0.6 0.4 0.2]
6960 for xh = [0.7 0.1]
6961 nmid=round(xh*ncount);
6962 arrow(zmirr(nmid),zmirr(nmid+1),col3);
6963 end
6964
6965 % Contours for |N|= const. may be plotted:
6966 % for instance [6 3 1 0.5 0.25 0 -0.5 -1 -3 -6]
6967
6968 % nlgrid([6 3]);
6969
6970 scalexy=axis; scalexy(3:4)= 1.01*scalexy(3:4);
6971 axis(scalexy);
6972 axis equal; axis off; hold off;
6973
6974 %******************************************
6975 %****** SUB-FUNCTIONS: ********************
6976
6977 function arrow(z2,z1,col)
6978 % dz=0.12*exp(j*angle(z2-z1));
6979 dz=0.11*exp(j*angle(z2-z1));
6980 z_arrow_end1=z2-dz*exp(j*pi/4);
6981 z_arrow_end2=z2-dz*exp(-j*pi/4);
6982 plot([real(z2) real(z_arrow_end1)],...
6983 [imag(z2) imag(z_arrow_end1)],col,'LineWidth',1.5);
6984 plot([real(z2) real(z_arrow_end2)],...
6985 [imag(z2) imag(z_arrow_end2)],col,'LineWidth',1.5);
6986
6987 %***********************************************
6988 function circle(zcentre,radius,plotdata)
6989 angles=0:pi/72:2*pi;
6990 circ=zcentre+radius.*(cos(angles)+j.*sin(angles));
6991 plot(circ,plotdata);
6992
6993 %***********************************************
6994 function phase_lines(n,rstart,rend,plotdata)
6995 hold on;
6996 angles=0:2*pi/n:2*pi;
6997 lines=ones(n,2);
6998 for k=1:n
6999 zh = cos(angles(k))+j*sin(angles(k));
7000 lines(k,1)= rstart*zh;
7001 lines(k,2)= rend*zh;
7002 plot(real(lines(k,:)),imag(lines(k,:)),plotdata);
7003 end
7004
7005 %***********************************************
7006
7007 function [s]= scurve(s1,R,spiralfactor, Np_origin, Np_imag,impoles)
7008 a=log(spiralfactor)*2/pi;
7009 %R=R/spiralfactor;
7010 % Calculating first arc if pole(s) in the origin:
7011 % If there are one or more pure integrators s is
7012 % made to do a small arc of a log spiral
7013 % into the upper right quadrant from 0 to pi/2.
7014 s=s1;
7015 if Np_origin
7016 fi=0:0.02/Np_origin:1; fi=0.5*pi*fi;
7017 sarc=R*exp((a+j)*fi);
7018 % merging sarc with s:
7019 x1=imag(sarc(end));
7020 k=1;
7073 end
7074
7075 % ************************
7076
7077 function [dist] = mindist(point,vector,initdist)
7078 % Calculates the minimum distance from a given complex number
7079 % to a set of other complex numbers:
7080 mdist = initdist;
7081 kmax=length(vector);
7082 for k=1:kmax
7083 d0=abs(vector(k)-point);
7084 if (d0 ~= 0) mdist = min(d0, mdist); end
7085 end
7086 dist=mdist;
7087
7088 % ************************
7089
7090 function nlgrid(absNdB,arga)
7091 % absNdB = [6 3 1 0.5 0.25 0 -0.5 -1 -3 -6]
7092 absNdB = absNdB';
7093 n=length(absNdB);
7094 absN=10.^(absNdB/20);
7095 radii=1./absN;
7096 nangles=200;
7097 angles=0:pi/nangles:2*pi;
7098 angles=angles';
7099 for k=1:n
7100 circ=-1.+radii(k).*(cos(angles)+j.*sin(angles));
7101 absc = abs(circ)+1e-14;
7102 logabs = 20.*log10(absc);
7103 for p=1:nangles
7104 if (logabs(p) <= -120) logabs(p) = -120; end
7105 end
7106 logabsplot=logabs./120.+1;
7107 cplot=circ.*logabsplot./absc;
7108 plot(cplot,arga,'LineWidth',2);
7109 end
7110
7111 function graficorobus(iEje,Gc,Gp,ci)
7112 %por V.M. Alfaro, 2004
7113 %Revisión: Miguel Aguilera
7114 %
7115 %Cálculo de la Ganancia de la Planta:
7116 [num,den]=tfdata(Gp); den=den{1};
7117 [z,p,k]=zpkdata(Gp,'v');
7118 prod=1;
7119 for m=1:length(p)
7120 prod=prod*abs(p(m));
7121 end
7122 kp=k/prod;
7123 %
7124 gca=iEje;
7125 set(gca,'NextPlot','add');
7126 %
7127 cv=['b','g','r','c','m','y','k'];
7128 tma=Gp.outputdelay;
7129 %
7130 %Se define un numero de 50 muestras:
7131 vt=tma/10:tma/10:4*tma;
7132 n=length(vt);
7133 g=Gp*Gc;
7134 %
7135 %Bucle: Valores de los Elementos del Vector vkp:
7136 for i=1:n
7137 g.outputdelay=vt(i);
7138 y=allmargin(g);
7139 vkp(i)=y.GainMargin(1);
7140 end
7141 %
7142 %Vector de Razón de Tiempos Muertos:
7143 vtm=vt/tma;
7144 %
7145 %%Se grafica la ventana con centro en (1,1):
7146 fplot(gca,'2*x',[0.5,1],'m');
7147 fplot(gca,'0.5*x',[1,2],'m');
7148 axis(gca,[0,4,0,4]);
7149 fplot(gca,'2/x',[1,2],'m');
7150 fplot(gca,'0.5/x',[0.5,1],'m');
7151 axis(gca,[0,4,0,4]);
7152 %
7153 %Se grafica el símbolo "+" en el punto (1,1):
7154 plot(gca,1,1,'+k');
7155 %
7156 %Gráfico de Robustez:
7157 plot(gca,vkp,vtm,cv(ci)); axis(gca,[0,4,0,4]);
7158
7159 %Función para Determinar los Parámetros de la Respuesta a una Entrada
7160 %Escalón
7161 function [tp,mx,ep,ta2,ta5]=paramresp(vt,vu,vy,fsc)
7162 yfin = 0; long = length(vy);
7163 for k = long-9:long
7164 yfin = yfin+vy(k);
7165 end
7166 yfin = yfin/10;
7167 %
7168 %Sobrepaso Máximo y Error Máximo:
7169 %-------------------------------
7170 [vym,I] = max(abs(vy)); tp = vt(I);
7171 if fsc == 0 %Regulador
7172 mx = vym; %Error Máximo
7173 else
7174 mx = (abs(vym)-yfin)/yfin*100; %Sobrepaso Máximo
7175 end
7176 %
7229 'Col',10,'Text',num2str(ITAE),'Col',11,'Text',...
7230 num2str(ISE));
7231 end
7232 end
7233 %
ANEXO A
309
Universidad de Costa Rica
Facultad de Ingeniería
Escuela de Ingeniería Eléctrica
Departamento de Automática
Por:
TABLA DE CONTENIDO
1.0 Introducción
Este manual tiene como objetivo el informar al usuario sobre el funcionamiento del
identificar modelos para procesos y, de sintonizar controladores PID, a través de una gran
El hecho que el programa permita abarcar muchos de los temas de interés del curso
• Simular un proceso, cuya función de transferencia sea descrita por el usuario, para
obtener un archivo de datos, a partir de los resultados de una prueba de lazo abierto.
• Aplicar un filtro sobre los datos de salida de una prueba de lazo abierto o lazo
cerrado.
3. Bröida, POMTM
4. Ho et al., POMTM
2
6. Smith, POMTM
7. Vitecková, POMTM
métodos:
1. Yuwana y Seborg
2. Jután y Rodríguez
3. Lee
4. Bogere y Özgen
continuación:
Reglas de Sintonización
7. Cohen y Coon
9. López ISE
25. Shinskey
• Emplear el mejor modelo como “planta” en la simulación del lazo, a partir de los
controladores sintonizados.
4.0 Instalación
junto con otros archivos del sistema, deben copiarse en la computadora donde se vaya a
correr el programa.
5
Básicamente, se deben seguir todos los pasos que el instalador defina. En una
primera etapa, se instalarán correctamente las librerías de MATLAB (un paquete “libre”
conocido como “MATLAB Component Runtime”). La segunda etapa copia y registra los
Procedimiento de instalación
advertencia que el proceso total de copia de archivos puede tardar hasta 5 minutos.
6
(por medio del botón Change Directory). Para comenzar la instalación se debe
5. Como paso siguiente, se debe definir el nombre del grupo al cual va a pertenecer el
del programa).
despliega un mensaje “El programa de instalacion ha finalizado con exito!”, para informar
8
que el proceso completo, incluyendo la copia de las librerías de MATLAB7®, terminó sin
errores.
Para iniciar el programa, se debe navegar a través del menú inicio, hasta encontrar el
Se debe seleccionar la opción que, en la figura anterior, se marca por medio de una
elipse roja.
9
(archivo de datos).
• Simular un proceso (con ruido), para aplicarle una prueba de lazo abierto.
Una vez escogida, alguna de las tres opciones, se debe oprimir el botón
Siguiente>>.
Durante la ejecución del programa, es posible volver a esta ventana para aplicar una
nueva función.
10
introductoria. En las curvas de muestra, la señal de entrada se representa por medio del
color verde claro, mientras que la señal de salida, se representa con el color rojo.
abierto es la siguiente:
• Inicio del Escalón: Tiempo, en segundos, para de inicio del escalón de entrada. En
segundos.
• Magnitud del Escalón: Valor Final del escalón de entrada. En el ejemplo, esta
propiedad vale “1”, por lo tanto, la curva verde llega a “1” después de pasar los 10
segundos.
11
• Período de Muestra: Espaciamiento (en segundos) que han de tener los puntos en la
prueba. Se recomienda no hacer muy pequeño este período (valores deben ser
mayores de 0.1).
Si, por ejemplo, se tiene un período de muestra de 0.25, el primer punto en la prueba
<numerador>/<denominador>
se definen los polos, ceros y la ganancia de la planta. Cada uno de estos factores
- (s+cero) ó (s+polo)
proceso es de la forma:
ganancia/((tao1*s+1)*(tao2*s+1)*(tao3*s+1))
decibelios. Entre más alta sea la razón menor es la influencia del ruido sobre la
señal de salida.
una muestra de la curva de reacción resultante de dicha prueba. Para se debe presionar el
El archivo de datos se genera al especificar una ruta y un nombre válido para éste,
Para la simulación de un lazo de control, para el proceso establecido en esta fase del
programa (simulación de pruebas de lazo abierto), es posible utilizar como planta el modelo
descrito por la función de transferencia y el tiempo muerto, aquí especificados. Para ello, se
debe almacenar en un archivo aparte (respecto al archivo que contiene los datos de la
prueba), el modelo.
13
visto, llevar una secuencia de pasos que conduzca a la identificación de un proceso, a partir
Estos pasos se enumeran del dos al cinco y, podrían continuar, si así es necesario,
Cada uno de los pasos anteriores implica una ventana distinta. Cada una de estas
pasos.
14
La ventana donde se debe especificar el archivo que contiene los datos, ya sea de
una prueba de lazo abierto, como de lazo cerrado, es similar a la que se muestra a
continuación:
15
• El tipo de prueba: Para ello se debe oprimir el botón, señalado con un rectángulo en
la figura anterior, las veces que sea necesario de forma que despliegue el tipo de la
prueba. En caso que la prueba sea de lazo cerrado, se debe incluir la ganancia del
pero se debe describir la ruta completa. Si no se conoce el nombre del archivo (y/o
figura:
Una vez seleccionado el archivo correcto, se tiene que presionar el botón Abrir.
El archivo de datos debe tener tres columnas (tiempo, entrada, salida; sin importar el
orden) que cuenten sólo con datos numéricos, de lo contrario, será rechazado.
que contiene los datos de salida (salida del proceso o variable controlada, según
corresponda). A partir de esto, el programa determina cuál es la posición de las otras dos
El color rojo, en las curvas, caracteriza la señal de salida del proceso (prueba de lazo
abierto); el color azul, la señal realimentada (prueba de lazo cerrado) y el color morado, la
En la figura, se muestra la lista desplegable (elipse azul) que debe ser empleada
secuencia de colores, que se ha definido dos párrafos atrás, no se sigue. Dicho de otra
primer y el último valor que se toman, para efectos de la identificación del proceso, a partir
del archivo original. Para redefinir la posición de las líneas verticales, se debe pulsar
primero la línea y luego, la nueva ubicación, dentro del área del gráfico.
afectados por la presencia de ruido. Por tal motivo, se hace necesaria la aplicación de un
Antes de aplicar un filtro, hay que diseñarlo. Esto es, se debe dar una serie de
Chebyshev tipo II (asociado al color verde) y Elíptico (o de Cauer, asociado al color azul).
En general, los filtros Butterworth se caracterizan por tener una ganancia plana en la
banda de paso, los de Chebyshev por tener una pendiente máxima en la región de
18
transición, los de Bessel por tener una respuesta de fase lineal en torno a la frecuencia corte,
mientras que los filtros Elípticos permiten obtener una transición más rápida entre la banda
de paso y la de rechazo.
Barra de parámetros
para los filtros
Las especificaciones de diseño para cada uno de los filtros son las siguientes:
• Chebyshev Tipo I: Orden (N), frecuencia corte normalizada (wc) y rizado máximo
Una vez que las especificaciones de diseño son aceptadas, en el área rectangular que
tiene como color de fondo, el color característico del filtro, aparecen las curvas de la señal
de entrada (en naranja), la señal de salida original (en azul) y, la señal resultante de aplicar
el filtro sobre la señal de salida (en rojo). Un ejemplo de esto, se puede apreciar a
Como ocurre en este caso, el efecto del filtro sobre la señal de salida puede no ser
observado con claridad a través de este gráfico. Una opción muy efectiva consiste en
presionar el botón , el cual reproduce las curvas, en un espacio menos limitado (de
20
mayores dimensiones). Esta vista con detalle es similar a la que se aprecia en la siguiente
figura:
1.8
1.6
1.4
Magnitud de la Señal
1.2
0.8
0.6
0.4 Entrada
Salida
0.2
Salida Filtrada
0
0 5 10 15 20 25 30 35 40 45 50
Tiempo (seg)
Las curvas de vistas con detalle, se muestran en ventanas aparte, que cuentan con la
posibilidad de ver alteradas sus dimensiones por parte del usuario (algo que no es posible,
El programa brinda, a través del botón (el cual se ubica en la esquina superior
curvas que se encuentren sobre la ventana de filtrado, en archivos – imagen, que pueden
Estos archivos son almacenados, en el directorio del programa, con los nombres de:
respectiva.
El proceso de filtrado finaliza con la selección de un tipo de filtro, para que, a partir
de ese momento, la señal de salida original se vea reemplazado por su versión filtrada.
Para seleccionar un filtro, se debe oprimir el botón que se ubica en la parte inferior
de la barra de parámetros, tantas veces como sea necesario, hasta que despliegue como
Si la prueba es de lazo cerrado, se cuenta con espacio suficiente para mostrar cada
una de las curvas de reacción resultantes de aplicar los cuatro métodos de identificación:
Yuwana y Seborg, Jután y Rodríguez, Lee y, Bogere y Özgen. Pero, siempre se debe cargar
modelos SOMTM (polo doble) y modelos SOMTM (métodos de tres puntos). No obstante,
22
modelo de su tipo.
identificación. Aquí, se detalla la función que ejerce cada uno de los objetos (botones,
Parámetros
del Modelo
Las funciones de cada uno de los botones, se describe con más detalle en las
siguientes líneas:
Al pulsar este botón, aparece una lista similar a la que se muestra a continuación:
que están destinadas a contener las curvas de reacción de los modelos y, los botones que
permiten cargar los métodos que originan cada uno de los modelos.
constante(s) de tiempo y tiempo muerto), se muestran a la izquierda del botón que se utilizó
El paso que se debe seguir para apreciar la función de transferencia del modelo, se
claras. La alternativa está depositada en el botón anterior, el cual permite crear una réplica
25
de las curvas en una ventana aparte (con capacidad de ser expandida o reducida, según se
Al pulsar este botón, el programa determina el modelo resultante de cada uno de los
métodos disponibles (de lazo abierto) para que, a partir de la curva de reacción de los
modelos y, respecto a la curva de reacción original, sea posible calcular el índice de error
“mejor modelo” SOMTM (polo doble) y el “mejor modelo” SOMTM (métodos de Stark y,
Jahanmiri y Fallahi).
El mejor modelo POMTM ocupa la posición del primer modelo (en la barra de
El mejor modelo SOMTM (polo doble) ocupa la posición del segundo modelo y, su curva
SOMTM (entre los métodos de Stark y, Jahanmiri y Fallahi) ocupa la posición del tercer
♣
♦ Mejor
♣ Mejor Modelo
Modelo
POMTM
SOMTM
(polo doble)
♦
♠
♠ Mejor
Modelo
SOMTM
(otro)
Durante el proceso de cálculo de los índices de error (S2) de cada uno de los
método que origina el modelo y, en su segunda columna el valor del S2. El número de filas
En este ejemplo, es claro apreciar que, el mejor modelo (sin importar el tipo) es el
que se obtiene de aplicar el método de Ho et al (SOMTM). Este modelo (el mejor de todos),
controlador PID).
controladores PID, se debe presionar el botón “Modelo Escogido” (el cual se ubica en la
parte inferior de la barra de selección de métodos), tantas veces como sea necesario para
que, su texto coincida con el nombre del método que originó el modelo de interés.
Para mostrar las curvas de reacción asociadas a dos o más modelos, en el mismo
sistema de ejes, hay que presionar el botón anterior. Pero, antes se debe definir cuáles
curvas deben ir en ese gráfico. Para ello, cada uno de los cuatro rectángulos que contienen
archivo con la imagen equivalente (en formato vectorial). El nombre de este archivo
depende del nombre de los métodos asociados a los modelos, cuyas curvas de reacción
están siendo comparadas. Por ejemplo, si se obtuvo un modelo por el método de Smith y,
80
Magnitud de la Señal
60
40
Entrada
Prueba de Lazo Abierto
20
Smith (POMTM) S 2=0.3181
Ho et al (SOMTM) S2=0.08711
0
0 5 10 15 20 25 30 35 40 45 50
Tiempo (seg)
29
guardar, a la vez, en archivos – imagen (con extensión emf), al pulsar el botón anterior.
El nombre de los archivos, está asociado con el método que origina el modelo de la
curva. Si, por ejemplo, se utiliza el método de Smith, el archivo que contiene la curva de
Todos estos archivos se ubican, una vez construidos, en la carpeta del programa.
• .
reacción que se obtienen para cada uno de los modelos identificados. Pero, si la pestaña
seleccionada es “Modelo”, los rectángulos despliegan, en lugar de las curvas, las funciones
archivo, puede ser utilizado para describir el modelo que se emplea como planta, en la
controladores PID y, la simulación del lazo control, se pueden acceder de dos maneras
distintas:
debe suministrar, de forma manual, los parámetros del modelo: ganancia, tiempo muerto,
del método, es asistida por un diagrama de flujo, que se dibuja sobre la ventana.
32
sintonización (lazo cerrado): Ziegler y Nichols y Shinskey, los cuales son ambos para
ó PID.
• Criterio Integral: Criterio IAE, ITAE o ISE (sólo en caso de métodos de Arrieta,
los parámetros del modelo (pues éste se encuentre en la memoria del programa).
siguiente:
34
sintonización; la segunda columna, el funcionamiento del lazo de control para el cual fue
sintonizado el controlador. Las siguientes tres columnas contienen los valores de los
parámetros del controlador (ganancia, tiempo integral y tiempo derivativo). Por último, el
Para efectos de la simulación del lazo de control, se puede utilizar hasta tres
Antes de presionar cualquiera de estos botones, se debe pulsar cualquier celda (en la
adquiere un tono “celeste” como fondo. Situaciones similares ocurren al pulsar los otros
sintonización (la ventana de selección de métodos). Este botón está desactivado mientras no
anterior).
Barra de
Ajustes
Espacio para
la(s) curva(s) de
lazo cerrado
38
Barra de Ajustes
El botón , se debe presionar una vez, para obtener al mismo tiempo (y en los
seleccionado. Al hacer esto, el botón la cara del botón se transforma en: . Los tonos
azul y rojo, se utilizan para recordar que, las curvas asociadas al primer controlador, son de
color azul, mientras que, las curvas asociadas al segundo controlador, son de color rojo.
39
Para incluir una tercera serie, en los tres distintos grupos de curvas (Nyquist,
Robustez y, Lazo Cerrado), se debe pulsar nuevamente el botón. Como resultado de esta
acción, la cara del botón vuelve a transformarse, esta vez en: . En este caso, las curvas
Las distintas curvas, no pueden ser dibujadas (con el botón Graficar), si antes no se
• Modelo – Planta.
Una vez obtenidas las distintas curvas, la “tabla resumen” se actualiza con los
tantas veces como sea necesario, de manera que despliegue el número (y/o color) del
entre PID ideal y PID serie), se debe oprimir el botón OK. La ventana resultante, es similar
La unidad de tiempo para todas las curvas y parámetros (de tiempo), en todas las
6.0 Bibliografía
PID en MATLAB ® 7.0”. Escuela de Ingeniería Eléctrica, Universidad de Costa Rica, San