Professional Documents
Culture Documents
Grupo
Inicio
Entrega
21/04/16
28/04/16
MSN
Ponce Cristian Marcelo, 6454
Problema 1 (3 ptos.)
Disear y configurar en MATLAB una interfaz grfica de usuario (GUI), para manejar un
Sistema de Inferencia Fuzzy Mamdani (MFIS), de tipo MISO mononivel, que permita:
Definir o aplicar funciones de pertenencia tipo tringulo (trimf), a las variables del sistema
(entradas/salida) con hasta 7 particiones, relacionadas con el operador fuzzy AND.
Cargar las reglas que formarn la base de reglas, con las caractersticas definidas en el
punto anterior.
Defuzzyficar mediante el mtodo de centro de gravedad (existe una funcin de Matlab que
realiza este clculo).
3. Variable de Salida: dem al panel anterior pero para el caso de una variable de salida.
4. Reglas: en ste panel es donde se aade (o elimina) las reglas de nuestro sistema de
inferencia fuzzy. El mecanismo es sencillo, se selecciona, de la lista correspondiente a cada
panel de variables (Entrada 1, Entrada 2 y Salida), una particin. Opcionalmente se puede
operar de modo negado con la particin, marcando el checkbox not. Seleccionada las
particiones se presiona el botn Agregar Regla del panel de reglas, y se visualiza en la lista,
de manera inmediata, la regla agregada. Procediendo de la manera anterior se puede agregar
tantas reglas como se necesite. El mecanismo para eliminar una regla consiste en seleccionar
algn tem de la lista y presionar, luego, el botn Eliminar Regla y automticamente la regla
desaparece de la lista.
5. Solucin: en ste ltimo panel se ingresa, en el campo Valor de Entrada 1, algn valor para
la primera variable de entrada y, en el campo Valor de Entrada 2, algn valor para la
segunda variable de entrada. Si se presiona el botn Calcular se muestra, en el campo
Resultado, el resultado (valga la redundancia) de la inferencia. Tambin se puede visualizar
grficamente el resultado presionando el botn Graficar. Para limpiar todos los campos del
programa se presiona el botn Limpiar.
Es importante mencionar que el programa, como se pidi, aplica funciones de pertenencia tipo
tringulo (trimf) a las variables del sistema, relacionadas con el operador fuzzy AND. Adems, el
programa utiliza el mtodo de centro de gravedad (centroide) para defuzzyficar.
Luego, utilizando los selectores de cada variable, elegimos las particiones para armar las reglas.
En la siguiente captura se muestra como se arm la ltima regla. Elegimos la particin excelente
utilizando el selector del panel Variable de Entrada 1, elegimos la particin deliciosa utilizando el
selector del panel Variable de Entrada 2 y elegimos la particin generosa utilizando el selector
del panel Variable de Salida.
Luego, una vez elegidas las particiones, presionamos el botn Agregar Regla para agregar la
regla.
Por ltimo, nos ubicamos en el panel Solucin para evaluar nuestro sistema de inferencia fuzzy.
En el campo Valor de Entrada 1 introducimos un valor para la primera variable de entrada, y en
el campo Valor de Entrada 2 introducimos un valor para la segunda variable de entrada.
Comparando el resultado anterior con el obtenido utilizando la herramienta Fuzzy Logic Toolbox,
vemos que ambos programas arrojan el mismo resultado.
Funcin agregarParticiones
%funcion que agrega las particiones al sistema de inferencia fuzzy
function agregarParticiones(id, indice, handles)
%trabajamos con la variable global fis
global fis;
%definimos variables necesarias
j = 0;
celda = {};
%obtenemos la lista de particiones de la variable que se este tratando
listaParticiones = eval(strcat('handles.listaParticiones', num2str(id)));
%recorremos los campos (nombre y parametros) de todas las particiones
for i = 1:1:7
%obtenemos el nombre de la particion
campoNombreParticion = get(eval(strcat('handles.campoNombreParticion', num2str(id),
num2str(i))), 'String');
%obtenemos el rango de valores de la particion
campoParametrosParticion =
str2num(get(eval(strcat('handles.campoParametrosParticion', num2str(id),
num2str(i))), 'String'));
%si los campos nombre y parametros no estan vacios, entonces
if(~isempty(campoNombreParticion) && ~isempty(campoParametrosParticion))
%sumamos en una unidad la variable j
j = j + 1;
%aadimos la particion al sistema de inferencia fuzzy
fis{indice}{3}{j} = {campoNombreParticion, campoParametrosParticion};
%aadimos un nuevo elemento a la celda
celda(j) = {campoNombreParticion};
end;
end;
%sumamos en una unidad la variable j
j = j + 1;
Funcin graficarParticiones
%funcion que grafica las particiones de la variable que se este tratando
function graficarParticiones(indice, resultado)
%trabajamos con la variable global fis
global fis;
%trabajamos con la variable global grado de precision
global gradoPrecision;
%guardamos los datos necesarios para poder graficar las particiones
%en otra ventana (grafica.fig)
manejadorVentanaPrincipal = getappdata(0, 'manejadorVentanaPrincipal');
%guardamos el rango de valores de la variable
setappdata(manejadorVentanaPrincipal, 'rango', fis{indice}{2});
%guardamos las particiones de la variable
setappdata(manejadorVentanaPrincipal, 'particiones', fis{indice}{3});
%guardamos el resultado de la inferencia
setappdata(manejadorVentanaPrincipal, 'resultado', resultado);
%abrimos la ventana grafica.fig para graficar las particiones
winopen('grafica.fig');
Funcin actualizarListaReglas
%funcion que actualiza la lista de reglas de la ventana
function actualizarListaReglas(handles)
%trabajamos con la variable global fis
global fis;
%inicializamos una objeto tipo celda para almacenar las reglas
listaReglas = cell(1, size(fis{4}, 2));
%recorremos todas las reglas del sistema de inferencia
for i = 1:1:size(listaReglas, 2)
%definimos una salida (visual) de la regla '. If ...'
salidaRegla = strcat(mat2str(i), '. If', {' '});
%recorremos todas las particiones involucradas en la regla
for j = 1:1:size(fis{4}{i}, 2)
%si es la particion de la variable de salida, entonces
if(j == size(fis{4}{i}, 2))
%la salida es 'then ...'
salidaRegla = strcat(salidaRegla, {' '}, 'then', {' '});
end;
%si la particion es negativa, entonces
if(fis{4}{i}(j) < 0)
%la salida es 'is not...'
salidaRegla = strcat(salidaRegla, '(', fis{j}{1}, {' '}, 'is not', {' '},
fis{j}{3}{abs(fis{4}{i}(j))}{1}, ')');
%si la particion es positiva, entonces
elseif(fis{4}{i}(j) > 0)
la lista de la ventana
'String', listaReglas);
elemento de la lista
'Value', size(listaReglas, 2));
Funcin obtenerGradoPertenencia
%funcion que obtiene el grado de pertenencia dado un x
function gradoPertenencia = obtenerGradoPertenencia(indiceVariable, indiceParticion,
xPedido)
%trabajamos con la variable global fis
global fis;
%trabajamos con la variable global grado de precision
global gradoPrecision;
%obtenemos los parametros de la curva de la particion
parametrosCurva = fis{indiceVariable}{3}{indiceParticion}{2};
%definimos los valores de x
x = fis{indiceVariable}{2}(1):gradoPrecision:fis{indiceVariable}{2}(2);
%definimos los valores de y
y = max(min((x - parametrosCurva(1)) / (parametrosCurva(2) - parametrosCurva(1)),
(parametrosCurva(3) - x) / (parametrosCurva(3) - parametrosCurva(2))), 0);
%inicializamos a cero el grado de pertenencia
yPedido = 0;
%recorremos todos los valores del vector x
for i = 1:1:size(x, 2)
%si el valor del vector x es mayor o igual al valor de la variable
%xPedido, entonces
if(x(i) >= xPedido)
%encontramos el grado de pertenencia
yPedido = y(i);
break;
end;
end;
Funcin calcularInferencia
%funcion que calcula el sistema de inferencia fuzzy
function calcularInferencia(handles)
%trabajamos con la variable global fis
global fis;
%trabajamos con la variable global grado de precision
global gradoPrecision;
%obtenemos el valor de la primera variable de entrada
campoValorEntrada1 = str2num(get(handles.campoValorEntrada1, 'String'));
%obtenemos el valor de la segunda variable de entrada
campoValorEntrada2 = str2num(get(handles.campoValorEntrada2, 'String'));
%si los campos valor de entrada no estan vacios, entonces
if(~isempty(campoValorEntrada1) && ~isempty(campoValorEntrada2))
%ubicamos los valores de entrada en un vector
valorEntradas = [campoValorEntrada1, campoValorEntrada2];
%inicializamos el vector que almacenara el grado de pertenencia de
%cada regla
gradoPertenenciaReglas = zeros(1, size(fis{4}, 2));
%recorremos todas las reglas del sistema de inferencia
for i = 1:1:size(gradoPertenenciaReglas, 2)
%inicializamos un contador k
k = 0;
%inicializamos el vector que almacena el grado de pertenencia de
%cada particion
gradoPertenenciaParticiones = [];
%recorremos todas las particiones de la regla, excepto de la
%variable de salida
for j = 1:1:size(fis{4}{i}, 2) - 1
%si la particion es distinta de cero, entonces
if(fis{4}{i}(j) ~= 0)
%agregamos un nuevo grado de pertenencia
k = k + 1;
%si la particion es negativa, entonces
if(fis{4}{i}(j) < 0)
%el grado de pertenencia es 1 - mu
gradoPertenenciaObtenido = 1 - obtenerGradoPertenencia(j,
abs(fis{4}{i}(j)), valorEntradas(j));
%sino
else
%el grado de pertenencia es mu
gradoPertenenciaObtenido = obtenerGradoPertenencia(j, fis{4}{i}(j),
valorEntradas(j));
end;
%aadimos el grado de pertenencia de la particion
gradoPertenenciaParticiones(k) = gradoPertenenciaObtenido;
end;
end;
end;
%calculamos el area total
areaTotal = sum(y);
%si el area total es distinto de cero, entonces
if(areaTotal ~= 0)
%el resultado final es:
resultadoFinal = sum(y.*x) / areaTotal;
%sino
else
%el resultado final es cero
resultadoFinal = areaTotal;
end;
%mostramos el resultado en el campo resultado de la ventana
set(handles.campoResultado, 'String', resultadoFinal);
end;
Funcin figure1_CreateFcn
% --- Executes during object creation, after setting all properties.
function figure1_CreateFcn(hObject, eventdata, handles)
%llamada a la funcion que inicializa el sistema de inferencia fuzzy
inicializarSistemaInferencia();
%configuramos lo necesario para habilitar la comunicacion entre la ventana
%ejercicio1.fig y grafica.fig
setappdata(0, 'manejadorVentanaPrincipal', gcf);
Funcin botonCargar1_Callback
% --- Executes on button press in botonCargar1.
function botonCargar1_Callback(hObject, eventdata, handles)
%trabajamos con la variable global fis
global fis;
%obtenemos el nombre de la primera variable de entrada
campoNombreEntrada1 = get(handles.campoNombreEntrada1, 'String');
%obtenemos el rango de valores de la primera variable de entrada
campoRangoEntrada1 = str2num(get(handles.campoRangoEntrada1, 'String'));
%aadimos la primera variable de entrada al sistema de inferencia fuzzy
fis{1} = {campoNombreEntrada1, campoRangoEntrada1};
%llamada a la funcion que agrega las particiones
agregarParticiones(1, 1, handles);
%modificamos el texto si ... es
set(handles.texto1, 'String', strcat('si', {' '}, campoNombreEntrada1, {' '}, 'es'));
%hacemos visible el texto
set(handles.texto1, 'Visible', 'on');
Funcin botonGraficar1_Callback
% --- Executes on button press in botonGraficar1.
function botonGraficar1_Callback(hObject, eventdata, handles)
Funcin botonCargar2_Callback
% --- Executes on button press in botonCargar2.
function botonCargar2_Callback(hObject, eventdata, handles)
%trabajamos con la variable global fis
global fis;
%obtenemos el nombre de la segunda variable de entrada
campoNombreEntrada2 = get(handles.campoNombreEntrada2, 'String');
%obtenemos el rango de valores de la segunda variable de entrada
campoRangoEntrada2 = str2num(get(handles.campoRangoEntrada2, 'String'));
%aadimos la segunda variable de entrada al sistema de inferencia fuzzy
fis{2} = {campoNombreEntrada2, campoRangoEntrada2};
%llamada a la funcion que agrega las particiones
agregarParticiones(2, 2, handles);
%modificamos el texto y ... es
set(handles.texto2, 'String', strcat('y', {' '}, campoNombreEntrada2, {' '}, 'es'));
%hacemos visible el texto
set(handles.texto2, 'Visible', 'on');
Funcin botonGraficar2_Callback
% --- Executes on button press in botonGraficar2.
function botonGraficar2_Callback(hObject, eventdata, handles)
%llamada a la funcion que grafica las particiones
graficarParticiones(2, []);
Funcin botonCargar3_Callback
% --- Executes on button press in botonCargar3.
function botonCargar3_Callback(hObject, eventdata, handles)
%trabajamos con la variable global fis
global fis;
%obtenemos el nombre de la variable de salida
campoNombreSalida = get(handles.campoNombreSalida, 'String');
%obtenemos el rango de valores de la variable de salida
campoRangoSalida = str2num(get(handles.campoRangoSalida, 'String'));
%aadimos la variable de salida al sistema de inferencia fuzzy
fis{3} = {campoNombreSalida, campoRangoSalida};
%llamada a la funcion que agrega las particiones
agregarParticiones(3, 3, handles);
%modificamos el texto entonces ... es
set(handles.texto3, 'String', strcat('entonces', {' '}, campoNombreSalida, {'
'}, 'es'));
%hacemos visible el texto
set(handles.texto3, 'Visible', 'on');
Funcin botonGraficar3_Callback
% --- Executes on button press in botonGraficar3.
function botonGraficar3_Callback(hObject, eventdata, handles)
%llamada a la funcion que grafica las particiones
graficarParticiones(3, []);
Funcin botonAgregarRegla_Callback
% --- Executes on button press in botonAgregarRegla.
function botonAgregarRegla_Callback(hObject, eventdata, handles)
%trabajamos con la variable global fis
global fis;
%trabajamos con la variable global numero de reglas
global numeroReglas;
%obtenemos la particion seleccionada en la primera variable de entrada
numeroParticion1 = get(handles.listaParticiones1, 'Value');
%obtenemos la particion seleccionada en la segunda variable de entrada
numeroParticion2 = get(handles.listaParticiones2, 'Value');
%obtenemos la particion seleccionada en la variable de salida
numeroParticion3 = get(handles.listaParticiones3, 'Value');
%obtenemos la lista de particiones de la primera variable de entrada
listaParticiones1 = get(handles.listaParticiones1, 'String');
%obtenemos la lista de particiones de la segunda variable de entrada
listaParticiones2 = get(handles.listaParticiones2, 'String');
%obtenemos la lista de particiones de la variable de salida
listaParticiones3 = get(handles.listaParticiones3, 'String');
%obtenemmos el valor del checkbox de la primera variable de entrada
operacionNot1 = get(handles.checkNot1, 'Value');
%obtenemmos el valor del checkbox de la segunda variable de entrada
operacionNot2 = get(handles.checkNot2, 'Value');
%obtenemmos el valor del checkbox de la variable de salida
operacionNot3 = get(handles.checkNot3, 'Value');
%si el usuario selecciona la ultima opcion de la lista de particiones
%de la primera variable de entrada, entonces
if(size(listaParticiones1, 1) == numeroParticion1)
%no hacer nada
numeroParticion1 = 0;
%sino, si el usuario selecciona una particion, entonces
else
%comprobar si el usuario marca el operador NOT
if(operacionNot1 == 1)
%entonces es menos la particion
numeroParticion1 = -numeroParticion1;
end;
end;
%si el usuario selecciona la ultima opcion de la lista de particiones
%de la segunda variable de entrada, entonces
if(size(listaParticiones2, 1) == numeroParticion2)
%no hacer nada
numeroParticion2 = 0;
%sino, si el usuario selecciona una particion, entonces
else
Funcin botonEliminarRegla_Callback
% --- Executes on button press in botonEliminarRegla.
function botonEliminarRegla_Callback(hObject, eventdata, handles)
%trabajamos con la variable global fis
global fis;
%trabajamos con la variable global numero de reglas
global numeroReglas;
%obtenemos la regla seleccionada en la lista de la ventana
numeroRegla = get(handles.listaReglas, 'Value');
Funcin botonCalcular_Callback
% --- Executes on button press in botonCalcular.
function botonCalcular_Callback(hObject, eventdata, handles)
%llamada a la funcion que calcula el sistema de inferencia fuzzy
calcularInferencia(handles);
Funcin botonGraficar_Callback
% --- Executes on button press in botonGraficar.
function botonGraficar_Callback(hObject, eventdata, handles)
%llamada a la funcion que grafica el resultado
graficarParticiones(3, get(handles.campoResultado, 'String'));
Funcin botonLimpiar_Callback
% --- Executes on button press in botonLimpiar.
function botonLimpiar_Callback(hObject, eventdata, handles)
%trabajamos con la variable global fis
global fis;
%limpiamos todos los campos de la ventana
for i = 1:1:2
campoNombreEntrada = eval(strcat('handles.campoNombreEntrada', num2str(i)));
campoRangoEntrada = eval(strcat('handles.campoRangoEntrada', num2str(i)));
campoValorEntrada = eval(strcat('handles.campoValorEntrada', num2str(i)));
set(campoNombreEntrada, 'String', '');
set(campoRangoEntrada, 'String', '');
set(campoValorEntrada, 'String', '');
end;
for i = 1:1:3
botonCargar = eval(strcat('handles.botonCargar', num2str(i)));
texto = eval(strcat('handles.texto', num2str(i)));
listaParticiones = eval(strcat('handles.listaParticiones', num2str(i)));
checkNot = eval(strcat('handles.checkNot', num2str(i)));
set(botonCargar, 'Enable', 'on');
set(texto, 'Visible', 'off');
Archivo grafica.m:
Funcin graficarParticiones
%funcion que grafica las particiones de la variable que se este tratando
function graficarParticiones(rango, particiones, resultado)
%trabajamos con la variable global grado de precision
global gradoPrecision;
%habilitamos la superposicion de graficos
hold on;
%definimos los colores de trazo para las graficas
coloresTrazo = {[0 0 1], [0 1 0], [0 1 1], [0.5 0 0], [0.5 0 1], [1 0 1], [1 1 0]};
%recorremos todas las particiones de la variable
for i = 1:1:size(particiones, 2)
%obtenemos los parametros de la grafica
parametrosGrafica = particiones{i}{2};
%definimos los valores de x
x = rango(1):gradoPrecision:rango(2);
%definimos los valores de y
y = max(min((x - parametrosGrafica(1)) / (parametrosGrafica(2) parametrosGrafica(1)), (parametrosGrafica(3) - x) / (parametrosGrafica(3) parametrosGrafica(2))), 0);
%graficamos la particion
plot(x, y, 'Color', coloresTrazo{i});
%colocamos un texto sobre la grafica
text((parametrosGrafica(2) - length(particiones{i}{1}) / (2 *
length(particiones{i}{1}))), (1 + 0.05), particiones{i}{1});
end;
%si la variable resultado no esta vacia, entonces
if(~isempty(resultado))
%definimos los valores de y
y = 0:gradoPrecision:1;
%graficamos el resultado
plot(str2num(resultado), y, 'r');
end;
%definimos los limites del eje y
ylim([-0.1 1.1]);
Funcin figure1_CreateFcn
% --- Executes during object creation, after setting all properties.
function figure1_CreateFcn(hObject, eventdata, handles)
%declaramos la variable grado de precision como global
global gradoPrecision;
%inicializamos el grado de precision
gradoPrecision = 0.001;
%configuramos lo necesario para habilitar la comunicacion entre la ventana
%ejercicio1.fig y grafica.fig
manejadorVentanaPrincipal = getappdata(0, 'manejadorVentanaPrincipal');
%obtenemos la variable rango
rango = getappdata(manejadorVentanaPrincipal, 'rango');
%obtenemos la variable particiones
particiones = getappdata(manejadorVentanaPrincipal, 'particiones');
%obtenemos la variable resultado
resultado = getappdata(manejadorVentanaPrincipal, 'resultado');
%llamada a la funcion que grafica las particiones
graficarParticiones(rango, particiones, resultado);
Disear un script que configure un sistema de inferencia fuzzy para un problema genrico que
contiene tres variables, dos de entrada (x, y) y una de salida (z). Las variables (x, y, z) toman
valores en el intervalo [0,10]. El script debe utilizar las funciones del toolbox fuzzy y responder a
los requerimientos que se indican:
Debe solicitar el tipo de funcin de pertenencia a utilizar, la misma para todas las
variables. Se recomienda trabajar con tringulos y gaussianas.
Ahora, elegimos alguna funcin de pertenencia de las dos que muestra el programa. Si queremos
utilizar la funcin triangular escribimos 1 sino escribimos 2. En nuestro caso utilizaremos una
funcin triangular.
Ahora, elegimos el nmero de particiones que tendrn todas las variables del sistema. Escribimos
1 si queremos 3 (tres) particiones, 2 si queremos 5 (cinco), 3 si queremos 7 (siete). Para
nuestro ejemplo elegiremos solamente 3 (tres) particiones.
Ahora, escribimos el nombre de cada una de las 3 (tres) particiones que forman parte de la
primera variable de entrada (la variable cama). Para nuestro problema, el nombre de la particin
1 es incomoda, de la particin 2 es normal y de la particin 3 es cmoda.
Entonces tenemos.
Presionamos la tecla ENTER y hacemos lo mismo para la segunda variable de entrada (la
variable desayuno), considerando que el nombre de la particin 1 es horrible, de la particin 2 es
normal y de la particin 3 es delicioso.
Entonces tenemos.
Presionamos la tecla ENTER y lo mismo para la variable de salida (la variable servicio), el
nombre de la particin 1 es malo, de la particin 2 es normal y de la particin 3 es bueno.
Entonces tenemos.
Luego, introducimos las reglas de nuestro sistema de inferencia. Las reglas deben tener el
siguiente
formato:
[particionVarEntrada1,
particionVarEntrada2,
particionVarSalida,
operacionLogica] donde,
Si abrimos el archivo generado por el script podemos observar como las particiones de cada
variable estn solapadas un 20%. Las siguientes figuras describen tal situacin.
La siguiente captura visualiza las reglas de nuestro sistema de inferencia, las cuales coinciden
con las enunciadas en nuestro problema de ejemplo.
end;
%salida en consola
fprintf('\nFuncion de pertenencia:');
fprintf('\n\t(1) Triangular');
fprintf('\n\t(2) Gaussiana');
fprintf('\nOpcion: ');
%pedimos al usuario que ingrese la funcion de pertenencia a utilizar
tipoFuncionPertenencia = input('');
%salida en consola
fprintf('\nCantidad de particiones:');
fprintf('\n\t(1) Tres');
fprintf('\n\t(2) Cinco');
fprintf('\n\t(3) Siete');
fprintf('\nOpcion: ');
%pedimos al usuario que ingrese la cantidad de particiones
cantidadParticiones = input('');
%salida en consola
fprintf('\nPorcentaje de solapamiento: ');
%pedimos al usuario que ingrese el porcentaje de solapamiento
porcentajeSolapamiento = input('');
%llamamos a la funcion obtenerParticiones para obtener las particiones con
%sus respectivos parametros (solapados con el porcentaje indicado)
particionesSistema = obtenerParticiones(numerosParticiones(cantidadParticiones),
porcentajeSolapamiento, funcionesPertenencia{tipoFuncionPertenencia});
%recorremos todas las variables
for i = 1:1:size(nombreVariables, 2)
%salida en consola
fprintf('\nParticiones de la variable %s:\n', nombreVariables{i});
%recorremos todas las particiones de la variable
for j = 1:1:numerosParticiones(cantidadParticiones)
%salida en consola
fprintf('\tNombre de la particion %d: ', j);
%pedimos al usuario el nombre de la particion
nombreParticion = input('', 's');
%si es una variable de entrada, entonces
if(i < size(nombreVariables, 2))
%agregamos una particion de entrada al sistema de inferencia
fis = addmf(fis, 'input', i, nombreParticion,
funcionesPertenencia{tipoFuncionPertenencia}, particionesSistema{j});
%sino
else
%agregamos una particion de salida al sistema de inferencia
fis = addmf(fis, 'output', 1, nombreParticion,
funcionesPertenencia{tipoFuncionPertenencia}, particionesSistema{j});
end;
end;
end;
%salida en consola
fprintf('\nReglas:');
fprintf('\n\tForma de la regla: [particionVarEntrada1, particionVarEntrada2,
particionVarSalida, operacionLogica]\n');
Archivo obtenerParticiones.m:
Funcin obtenerParticiones
%funcion que obtiene las particiones
function particiones = obtenerParticiones(numeroParticiones, porcentajeSolapamiento,
tipoFuncion)
%definimos el tamao para la base de un triangulo
tamanoBase = 10;
%calculamos la mitad de la base
mitadTamanoBase = tamanoBase * 0.5;
%definimos los parametros del triangulo ubicado mas a la izquierda
trianguloIzquierdo = [-mitadTamanoBase 0 mitadTamanoBase];
%definimos los parametros del triangulo ubicado despues del triangulo
%izquierdo
trianguloSiguiente = [mitadTamanoBase tamanoBase (mitadTamanoBase * 3)];
%calculamos el area del triangulo ubicado mas a la izquierda
areaTrianguloIzquierdo = mitadTamanoBase * 0.5 * (porcentajeSolapamiento * 0.01);
%definimos un diferencial de aumento
diferencialDelta = 0.0;
%definimos un limite inferior de busqueda
limiteInferiorBusqueda = 0;
%definimos un limite superior de busqueda
limiteSuperiorBusqueda = 0;
Comparativa de resultados
%
20
50
80
Triangulo
Gauss
Triangulo
Gauss
20
50
80
3. Las variables de Salida a las que llamamos Rociadores y Ventilador, tienen dos conjuntos
Crisp, a los que llamamos Encendido y Apagado. Utilizamos esa representacin para
indicar que nicamente nos interesan los valores cero (para indicar que esta pagado) y
uno (para indicar que esta encendido) para definir el estado de los Rociadores y del
Ventilador.
Ya creado nuestro FIS nos dirigimos a Simulink para poder simular como opera nuestro Sistema.
En este caso estamos hablando de un Sistema con Servo Control, el consumo ingresa, pero no
hay ninguna realimentacin que me permita corregir el consumo en el caso de que este sea muy
elevado. Nuestro Sistema implementado en Simulink y guardado como Molino_Simulink.mdl (El
archivo se encuentra dentro de la carpeta que contiene a este documento), es el siguiente:
Tenemos como entrada una seal sinusoidal con una amplitud de 4.5 amperes y un bias de 20.5
amperes dndonos el intervalo necesario para el FIS, es decir de 16 a 25 amperes. Presionamos
Start Simulation y obtenemos los siguientes resultados:
Hemos definido el tiempo de Simulacin en 10 segundos. Como dijimos la entrada es una seal
sinusoidal definida entre 16 y 25 Amperes, como salidas tenemos seales que pueden tomar el
valor 0 para indicar el estado apagado o 1 para indicar el estado encendido de los rociadores y del
ventilador. Como podemos ver el sistema funciona de manera correcta pero no nos avisa en el
caso de que el sistema sobrepase los 22.6 amperes, por lo que no es aconsejable esta
implementacin.
MolinoP.fis tiene una nica variable de entrada que me representa el error entre un valor de
referencia o Set Point al que hemos definido como 20.15 amperes (rango medio del conjunto de
valores que forman parte del consumo ideal) y el consumo que va desde los 16 hasta los 25
amperes. Adems dispone de tres variables de salida, una de ellas me representa el estado de los
rociadores, la otra el estado del ventilador y la otra me representa si el sistema se encuentra o no
en peligro por haber superado el lmite de 22.6 amperes.
La variable de entrada Error tiene cuatro conjuntos, dos de ellos son Crisp (Peligroso e Ideal) y
dos son Fuzzy (Bajo y Alto) con forma triangular. Hemos utilizado esta representacin para indicar
que cuando el sistema me indique un error menor o igual a
-2.45 (Consumo superior a 22.6
amperes) entonces deberemos dar una seal de peligro y si es mayor a -2.45 entonces el sistema
deje de estar en peligro. Adems me permite indicar que mientras el error este definido entre -0.95
y 0.95 entonces nos encontremos en el estado ideal del sistema y no ser necesario realizar
ningn tipo de correccin sobre el mismo.
Las variables de Salida a las que llamamos Peligro, Rociadores y Ventilador, tienen dos conjuntos
Crisp, a los que llamamos Encendido y Apagado para las ltimas y para la primera S y No.
Utilizamos esa representacin para indicar que nicamente nos interesan los valores cero y uno
para definir el estado de los Rociadores, del Ventilador y del Sistema, para poder saber si est o
no, en Peligro.
Corrector.fis tiene una nica variable de entrada que me representa el error entre un valor de
referencia o Set Point al que hemos definido como 20.15 amperes y el consumo que va desde los
16 hasta los 25 amperes. Adems dispone de una variable de salida que me indica la correccin a
realizar sobre el consumo que ha ingresado al sistema, si el consumo supera los 22.6 amperes.
La variable de entrada dispone de tres conjuntos fuzzy con forma triangular que me indican un
Error Bajo, un Error Alto y un Error Medio. Lamentablemente no disponemos de la informacin
suficiente para definir una forma particular para las funciones de pertenencia as que hemos
optado por la forma estndar que es la triangular.
La variable de salida tambin dispone de tres conjuntos fuzzy con forma triangular que me indican
si la accin de control o la correccin sobre el consumo es Baja, Alta o Intermedia, dependiendo
por supuesto del error ingresado al FIS. Lamentablemente no disponemos de la informacin
suficiente para definir una forma particular para las funciones de pertenencia as que hemos
optado por la forma estndar que es la triangular.
Ya creados nuestros FIS nos dirigimos a Simulink para poder simular como opera nuestro
Sistema. En este caso estamos hablando de un Sistema con Realimentacin, el consumo ingresa,
y dicha realimentacin me permite corregir el consumo en el caso de que este sea muy elevado,
es decir superior a los 22.6 amperes. Nuestro Sistema implementado en Simulink y guardado
como MolinoP_Simulink.mdl (El archivo se encuentra dentro de la carpeta que contiene a este
documento), es el siguiente:
El tiempo de Simulacin se estableci en 30 segundos con un paso fijo de 0.1 segundos, pero,
Cmo opera nuestro Sistema? Primeramente generamos un error tomando el Set Point y un
valor de Consumo que se genera a partir de una funcin sinusoidal. Se coloca posteriormente un
Transport Delay para que este error salga del bloque a los 0.2 segundos dndome como salida
hasta ese entonces el valor 0 que es el que tomaremos como error inicial. En base a ese error, mi
sistema opera y me devuelve una salida realimentada (es decir, la accin de control) que corregir
el error que tenamos inicialmente, el sistema entonces operara nuevamente dndome una salida
igual a cero, indicndome que se ha corregido el error.
Despus de ese lapso de tiempo de 0,2 segundos y el Transport Delay deja salir el error calculado
y procederemos a corregir dicho error si es necesario. El sistema seguir operando hasta alcanzar
los 30 segundos.
La grafica de Control, donde ponemos el error, expresado en amarillo y la accin de control en
violeta, es la siguiente: