Trabajo de Graduación - Franco Javier Salinas Mendoza

Anuncio
U NIVERSIDAD NACIONAL DE T UCUMÁN - FACULTAD DE C IENCIAS E XACTAS Y T ECNOLOGÍA
D EPARTAMENTO DE E LECTRICIDAD , E LECTRÓNICA Y C OMPUTACIÓN
I NGENIERÍA EN C OMPUTACIÓN
J UNIO 2016
Trabajo de Graduación
D ESARROLLO DE UN FRAMEWORK EN LENGUAJE
C PARA CONTROLADORES DIFUSOS
R EVISIÓN 1
autor
Franco Javier S ALINAS M ENDOZA
CX1416301
tutor
Ing. Esteban VOLENTINI
co-tutor
Dr. Adrián W ILL
Agradecimientos
A Leandro Gutierrez, quien trabajó conmigo en los inicios de este proyecto, y a mis tutores,
Esteban Volentini y Adrián Will, quienes me acompañaron durante todo el desarrollo.
1
Dedicatorias
Dedico este trabajo a mis padres, por su esfuerzo a lo largo de estos años, a mi abuela por su
afecto incondicional, y a Lucía, quien me inspiró para seguir adelante.
2
Prólogo
A lo largo de este trabajo de graduación se describen los procesos de diseño, implementación y
prueba de µFuzzy: un framework de lógica difusa pensado especialmente para sistemas embebidos.
A su vez, se presentan dos ejemplos de aplicación sobre un robot móvil autónomo terrestre.
3
Índice general
1. Introducción
1.1. Motivación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
6
7
2. Conceptos de lógica difusa
2.1. Conceptos básicos . . . . . . . . . . . . . . . . .
2.1.1. Estructura de un sistema difuso . . . . .
2.1.2. Funciones de membresía . . . . . . . . .
2.1.3. Parámetros de los sistemas difusos . . . .
2.2. Construcción de un sistema difuso . . . . . . . .
2.2.1. Elección de las variables del sistema . . .
2.2.2. Definición de las reglas . . . . . . . . . .
2.2.3. Definición de las funciones de membresía
2.3. Proceso de inferencia . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
8
8
9
10
10
10
11
11
11
3. Diseño
3.1. Aspectos generales . . . . . . . . . . . . . . . .
3.1.1. Necesidad de un formato propio . . . . .
3.1.2. Visión general . . . . . . . . . . . . . .
3.2. µFuzzy . . . . . . . . . . . . . . . . . . . . . .
3.2.1. Elección del lenguaje de desarrollo . . .
3.2.2. Consideraciones respecto al lenguaje . .
3.2.3. Utilización de aritmética de punto fijo . .
3.2.4. Limitaciones debidas al uso de punto fijo.
3.2.5. Características soportadas . . . . . . . .
3.3. cfsconvert . . . . . . . . . . . . . . . . . . . . .
3.3.1. Características generales . . . . . . . . .
3.3.2. Elección del lenguaje de desarrollo . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
14
14
14
14
15
15
15
16
16
17
18
18
18
.
.
.
.
.
.
20
20
20
20
21
21
23
4. Aplicación
4.1. Introducción . . . . . . . . . . . . . . . . .
4.2. Control de lazo cerrado para los motores . .
4.2.1. Estudio de los motores . . . . . . .
4.2.2. Estructura del controlador . . . . .
4.2.3. Diseño del sistema de control difuso
4.3. Seguimiento de pared . . . . . . . . . . . .
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Desarrollo de un framework en lenguaje C para controladores difusos
5. Resultados
5.1. Framework . . . . . . . . . . . .
5.1.1. Calidad del código fuente
5.1.2. Pruebas . . . . . . . . . .
5.1.3. Integración a la CIAA . .
5.2. Aplicaciones . . . . . . . . . . .
5.2.1. Control de velocidad . . .
5.2.2. Seguimiento de pared . . .
5.3. Conclusiones y trabajos futuros . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Anexos
A. API de µFuzzy
A.1. Tipos de dato . .
A.2. Funciones . . . .
A.3. Macros . . . . .
A.4. Códigos de error
26
26
26
26
28
28
28
29
29
34
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
35
35
35
39
39
B. Manual de cfsconvert
41
C. Especificación del formato CFS
42
D. Cálculo de los coeficientes de Sugeno-Takagi
46
ÍNDICE GENERAL
5
Desarrollo de un framework en lenguaje C para controladores difusos
Capítulo 1
Introducción
1.1.
Motivación
Desde su formulación en 1965, la lógica difusa se ha utilizado con éxito en inumerables aplicaciones tales como sistemas de predicción de clima, reconocimiento de patrones faciales, automatización industrial y robótica [7], aunque sin dudas, sus aplicaciones más destacadas pertenecen al
campo de los sistemas de control. El ejemplo más representativo es el sistema utilizado en el metro de Sendai, Japón. El mismo se encuentra operativo desde 1988 y su desempeño supera tanto a
opeararios como a sistemas de control convencionales [5].
Por otro lado, desde hace más de cuatro décadas, la cantidad de transistores en los circuitos
integrados aumenta tal como lo establece la ley de Moore, y como consecuencia, su costo se reduce
[1]. En el año 1997 Intel lanzó el microprocesador Pentium II 233 a un precio de mercado de
US$636. Dos décadas más tarde, en febrero de 2016, la fundación Raspberry PI lanzó la Raspberry
PI 3 Model B, una Placa de Tamaño Reducido (SBC) de performance comparable al procesador
de Intel a un precio casi 20 veces menor. Por su parte, en el segmento de los sistemas embebidos
de bajo costo, un microcontrolador con núcleo ARM Cortex-M0 puede adquirirse por centavos de
dólar. Esto permite aplicaciones embebidas cada vez más complejas y abre la puerta a incorporar
software e inteligencia artificial a dispositivos que hoy no los tienen, por una fracción mínima de su
coste de producción.
En el marco del proyecto de investigación del CIUNT, Inteligencia Artificial y Aplicaciones
a Robótica, surgió la necesidad de implementar sistemas de control complejos, y la lógica difusa
se eligió como herramienta para llevarlos a cabo. Hoy existen diversas librerías de lógica difusa
libres y gratuitas tales como fuzzylite, Free Fuzzy Logic Library (FFLL), o Embedded Fuzzy Logic
Library (eFLL), sin embargo solo esta última está pensada para sistemas embebidos, lo cual resulta
un requisito indispensable para las necesidades del proyecto. Aún asi, esta librería tiene fuertes
limitaciones. En primer lugar, utiliza operaciones con punto flotante, lo cual repercute fuertemente
en la performance en microcontroladores sin Unidad de Punto Flotante (FPU). En segundo lugar,
reserva memoria dinámicamente, lo que la hace inadecuada para Sistemas Operativos en Tiempo
Real (RTOSs). Finalmente, no permite realizar ajustes al sistema sin recompilar, lo cual impacta
negativamente en el flujo de trabajo. Esto plantea la necesidad de crear una nueva librería, liviana y
flexible, que sea capaz de ejecutarse en la gama más económica de los microcontroladores.
CAPÍTULO 1. INTRODUCCIÓN
6
Desarrollo de un framework en lenguaje C para controladores difusos
1.2.
Objetivos
El objetivo central de este proyecto es desarrollar un framework de lógica difusa, capaz de
funcionar en microcontroladores de bajo costo independientemente de su arquitectura, y compatible
con las herramientas más difundidas de lógica difusa de la actualidad. Dado el potencial de este
framework para ser utilizado en aplicaciones industriales en las que la seguridad es prioritaria, se
plantea como una meta adicional someterlo a exhaustivas pruebas de funcionamiento.
Finalmente, el framework será aplicado en un robot para resolución de laberintos[3] desarrollado en el marco de otro trabajo de graduación. Este robot posee dos microcontroladores: uno para
interactuar con los sensores y actuadores, y otro para ejecutar algoritmos de alto nivel y tomas de
decisiones. µFuzzy se utilizará en el primero para efectuar control de lazo cerrado sobre las velocidades de los motores, mientras que en el segundo servirá para generar un comportamiento de wall
follower.
CAPÍTULO 1. INTRODUCCIÓN
7
Desarrollo de un framework en lenguaje C para controladores difusos
Capítulo 2
Conceptos de lógica difusa
2.1.
Conceptos básicos
En la lógica booleana o binaria, esencial para la electrónica digital y la programación de computadoras, cada proposición o variable puede tomar uno de dos valores de verdad: verdadero o falso.
Por ejemplo, París está en Francia es una proposición verdadera y Los perros son peces es una
proposición falsa. Sin embargo ciertas situaciones no pueden ser modeladas con precisión usando
lógica booleana. Considérese la proposición Juan es alto y supóngase que Juan mide 1.75 m. No
puede decirse a ciencia cierta si la proposición es verdadera o falsa porque no existe una definición nítida del concepto de altura. Dicho de otro modo, no existe una altura umbral que sirva para
clasificar a las personas como altas o bajas. En cambio, tenemos una noción de altura mucho más
vaga, dependiente del contexto y cargada de subjetividad. La lógica difusa, que puede entenderse
como una extensión de la lógica binaria, modela estas situaciones imprecisas o ambiguas típicas del
razonamiento humano, permitiendo que las proposiciones en lugar de ser absolutamente verdaderas
o absolutamente falsas puedan tener un cierto grado de verdad.
2.1.1.
Estructura de un sistema difuso
La Fig. 2.1 ilustra la estructura básica de un sistema de inferencia basado en lógica difusa.
Fundamentalmente, está compuesto por un conjunto de reglas, que permiten obtener el valor de
ciertas variables de salida a partir de una serie de variables de entrada. Estas reglas, al igual que las
de la lógica proposicional, están conformadas por un antecedente y un consecuente. Sin embargo,
en la lógica difusa, el valor de verdad de las proposiciones se representa con un número real en el
intervalo [0, 1]. Por ejemplo, una proposición con un valor de verdad de 0.8 puede entenderse como
razonablemente cierta, mientras que un grado de verdad 0 indica que la misma es absolutamente
falsa.
Otra diferencia respecto a la lógica clásica, es que las variables involucradas en el proceso de
inferencia no son numéricas ni booleanas, sino que son variables lingüísticas. Por ejemplo, si un
sistema utiliza la variable temperatura, entonces la misma tomaría valores tales como alta, baja
o muybaja, en lugar de valores numéricos expresados en grados. No obstante, si dicho sistema
necesitara una medición de la temperatura para funcionar, probablemente la obtendría de un sensor cuya lectura sí sea numérica. Por esta razón, el primer paso en el proceso de inferencia difusa
consiste en convertir valores numéricos a valores difusos. Este paso recibe el nombre de fuzzificación. Análogamente, el último paso consiste en realizar el proceso inverso, y se lo conoce como
defuzzificación.
CAPÍTULO 2. CONCEPTOS DE LÓGICA DIFUSA
8
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 2.1: Estructura de un sistema de inferencia basado en lógica difusa
2.1.2.
Funciones de membresía
Antes de poder efectuar la fuzzificación, es necesario dar un sentido a cada uno de los términos
lingüísticos utilizados en el sistema. Para el ejemplo anterior, esto implica que se debe definir qué
significa que la temperatura sea alta, baja o muy baja. Cabe destacar que el significado de estos
conceptos depende de cada sistema particular; lo que para un horno puede ser una temperatura muy
baja, para una heladera podría resultar extremadamente alta.
Matemáticamente, cada término lingüístico puede entenderse como un conjunto, pero en el que
la pertenencia al mismo no es booleana sino difusa. Para cierto sistema, una temperatura de 10 ◦C
puede pertenecer en gran medida al conjunto de las temperaturas bajas, en menor medida al conjunto
de las temperaturas muy bajas, y no pertenecer en absoluto al conjunto de las temperaturas altas.
Estos conjuntos difusos se definen utilizando una función de pertenencia o membresía, que asigna
a cada elemento del universo de discurso (en este caso el conjunto de temperaturas posibles), un
valor en el intervalo [0, 1] que representa el grado de pertenencia de dicho elemento al conjunto.
Por ejemplo, para la variable temperatura podrían definirse las funciones de membresía que se
muestran en la Fig. 2.2.
Figura 2.2: Funciones de membresía
CAPÍTULO 2. CONCEPTOS DE LÓGICA DIFUSA
9
Desarrollo de un framework en lenguaje C para controladores difusos
2.1.3.
Parámetros de los sistemas difusos
En la lógica clásica, los operadores utilizados para la conjunción o la disyunción se definen
mediante tablas de verdad. Esto es posible ya que operan sobre valores booleanos y solo pueden
ocurrir unas pocas combinaciones de entrada. En cambio, en la lógica difusa las proposiciones
pueden tomar cualquier valor en el intervalo [0, 1], por lo que los operadores deben definirse como
funciones. El operador conjuntivo puede escogerse de un conjunto de funciones denominadas Tnormas, entre las cuales la más habitual es la función mínimo. Análogamente, el disyuntivo se elige
de la familia de S-normas, y la elección más habitual es la función máximo.
A su vez, existen diferentes métodos de inferencia, entre los cuales probablemente los más difundidos son el método de Mamdani y el de Sugeno-Takagi. La principal diferencia entre estos
métodos es que en el método de Sugeno, los consecuentes de las reglas no utilizan variables lingüísticas, sino que son una constante, o bien una combinación lineal de las entradas. Así, una regla de
un sistema basado en el método de Sugeno tiene la forma:
SI temperatura es alta Y humedad es baja ENTONCES y = aT + bh + c
Donde T y h son los valores numéricos de la temperatura y la humedad respectivamente, a, b y c
son constantes, y y es la variable de salida.
En la práctica, la ventaja del método de Mamdani es que, ya que los consecuentes utilizan variables lingüísticas, la definición de las reglas resulta más intuitiva. Por su parte, el método de SugenoTakagi, es más eficiente, ya que al utilizar variables numéricas en los consecuentes, el proceso de
defuzzificación suele requerir menos operaciones.
Otro parámetro que debe definirse es qué método se utilizará para la defuzzificación, es decir,
de qué manera se convertirán los conjuntos difusos producto del proceso de inferencia, a valores
numéricos. Para el método de Mamdani, el más habitual es el centro de gravedad, mientras que para
Sugeno-Takagi suele utilizarse la media ponderada.
2.2.
Construcción de un sistema difuso
Supóngase que se desea desarrollar un sistema para controlar el nivel de agua en un tanque.
El líquido ingresa al mismo a través de una cañería, cuyo caudal puede controlarse mediante una
electroválvula. El fluído abandona el tanque a un ritmo variable que depende de un factor externo y
no puede controlarse. A su vez, el sistema cuenta con un sensor que mide el nivel del tanque, y otro
que mide la presión de agua en la cañería de alimentación. La apertura de la válvula puede ajustarse
entre 0 mm2 y 100 mm2 . El nivel de agua óptimo es 1 m.
En este caso, se desarrollará un sistema difuso basado en el método de Mamdani, dado que el
planteamiento del mismo resulta mucho más intuitivo que con el método de Sugeno. Asimismo, para
simplificar la explicación del proceso de inferencia, se utilizarán las funciones mínimo y máximo
para la conjunción y la disyunción respectivamente. Como defuzzificador se utilizará el centro de
gravedad.
2.2.1.
Elección de las variables del sistema
La construcción del sistema comienza con la elección de las variables de entada y salida. Se
trata de una elección y no una identificación, porque además de la opción trivial de elegir la lectura
de los sensores como variables de entrada, podría elegirse el error de los mismos respecto a un
punto de referencia; incluso podrían adicionarse variables de entrada tales como las derivadas o las
integrales de las lecturas respecto del tiempo. Como salida, por ejemplo, podría elegirse la apertura
CAPÍTULO 2. CONCEPTOS DE LÓGICA DIFUSA
10
Desarrollo de un framework en lenguaje C para controladores difusos
de la válvula, o bien la corrección en la apertura respecto a un modelo ideal. Existen varios criterios
para decidir, por ejemplo: si la lectura de los sensores tuviera altos niveles de ruido probablemente
la derivada no podría utilizarse; si puede tolerarse cierto corrimiento en el valor de referencia o
setpoint puede omitirse la integral; si el valor de referencia es variable posiblemente sea mejor
utilizar el error en las lectura del nivel y no el nivel como variable de entrada. En este caso, por
cuestiones de simplicidad, se utilizarán sólo las lecturas de los sensores como entradas, y la apertura
de la válvula como salida.
2.2.2.
Definición de las reglas
Las reglas se definen en base al conocimiento de un experto o al estudio del comportamiento
del sistema. En este caso, se utilizarán las siguientes:
1. SI nivel es alto ENTONCES apertura es nula
2. SI nivel es normal Y presion es baja ENTONCES apertura es grande
3. SI nivel es normal Y presion es normal ENTONCES apertura es media
4. SI nivel es normal Y presion es alta ENTONCES apertura es chica
5. SI nivel es bajo Y presion es baja ENTONCES apertura es máxima
6. SI nivel es bajo Y presion es normal ENTONCES apertura es grande
7. SI nivel es bajo Y presion es alta ENTONCES apertura es media
Puede observarse que en la primera regla, la variable presion no interviene. Esto implica que siempre que el nivel sea alto, la apertura será nula, independientemente del valor de la presión.
2.2.3.
Definición de las funciones de membresía
Las funciones de membresía, al igual que las reglas, se obtienen a partir de un estudio del
sistema. En este caso, se definieron como se ilustra en la Fig. 2.3. Como puede observarse, si el
nivel del agua es menor a 80 cm entonces se lo considera absolutamente bajo. A partir de este
punto, el nivel comienza a aproximarse a un nivel normal. Un nivel de 1 m es absolutamente normal,
pero para alturas mayores comienza a ser alto. Si la altura es mayor a 120 cm entonces el nivel es
absolutamente alto. En cuanto a la presión, la misma se considera baja si es inferior 300 kPa, normal
si es aproximadamente 500 kPa, y absolutamente alta si supera los 700 kPa. Finalmente, para la
apertura de la válvula se definen las etiquetas lingüísticas nula, chica, media, grande, y maxima,
que corresponden a aperturas de aproximadamente 0 %, 25 %, 50 %, 75 %, y 100 %.
2.3.
Proceso de inferencia
Para el ejemplo dado en la sección anterior, se explicará gráficamente el proceso de inferencia
cuando el nivel medido es de 105 cm y que la presión es de 400 kPa.
El primer paso consiste en la obtención del grado de verdad de cada uno de los antecedentes
de las reglas, para el valor actual de las variables de entradas. Como se muestra en la Fig. 2.4, los
valores de verdad se obtienen evaluando la función de membresía asociada al término lingüístico
que aparece en la proposición. Puede observarse que, por ejemplo, la proposición nivel = alto
tiene un grado de verdad de 0.25, y como esa es la única proposición en el antecedente de la primera
CAPÍTULO 2. CONCEPTOS DE LÓGICA DIFUSA
11
Desarrollo de un framework en lenguaje C para controladores difusos
(b) Presión en la cañería
(a) Nivel del agua
(c) Apertura de la válvula
Figura 2.3: Funciones de membresia para las variables del sistema
regla, 0.25 también es el peso o valor de verdad del antecedente. A su vez, para la segunda regla,
los valores de verdad de las proposiciones nivel = normal y presion = baja son 0.75 y 0.50. En
este caso, como se utiliza la función mínimo para la conjunción, el grado de verdad del antecedente
resulta ser 0.50. La tabla 2.1 muestra los grados de verdad de los antecedentes de cada regla.
regla
grado de verdad
1
0.25
2
0.50
3
0.50
4
0.00
5
0.00
6
0.00
7
0.00
Cuadro 2.1: Grados de verdad de los antecedentes de las reglas.
Una vez que se conocen los pesos de los antecedentes de cada regla, se procede a truncar las
funciones de membresía del correspondiente consecuente, siempre que el valor que tome la función
excede el peso del antecedente. El resultado de esta operación se muestra en la Fig. 2.5a. Como
puede observarse, las únicas funciones de pertenencia que tienen peso son las correspondientes a
las aperturas media, grande y nula, siendo la última la menos relevante.
Luego, como se ilustra en la Fig. 2.5b, las funciones de membresía se combinan tomando en cada
punto el valor máximo entre ellas para formar un conjunto difuso. Finalmente, se utiliza el método
de defuzzificación, que en este caso es el centro de gravedad, para obtener el valor numérico de la
variable de salida. En este caso, el cálculo del centro de gravedad da como resultado una apertura
CAPÍTULO 2. CONCEPTOS DE LÓGICA DIFUSA
12
Desarrollo de un framework en lenguaje C para controladores difusos
(b) Presión en la cañería
(a) Nivel de agua
Figura 2.4: Evaluación de las funciones de membresía de entrada
(a) Pesos de cada función de membresía
(b) Conjunto difuso de salida y defuzzificación
Figura 2.5: Obtención del valor de la variable de salida
del 40 %, que representa la salida del sistema difuso.
CAPÍTULO 2. CONCEPTOS DE LÓGICA DIFUSA
13
Desarrollo de un framework en lenguaje C para controladores difusos
Capítulo 3
Diseño
3.1.
Aspectos generales
3.1.1.
Necesidad de un formato propio
En la actualidad existen diversos formatos utilizados para definir sistemas difusos tales como el
Fuzzy Inference System (FIS) de MATLAB, el FuzzyLite Language (FLL) de fuzzylite o el Fuzzy
Control Language (FCL). Sin embargo, estos formatos no son los más adecuados para ser utilizados
en microcontroladores de bajo costo, dado que estan basados en texto y el análisis de estos archivos
produce una demanda de recursos computacionales que puede ser evitada. Una alternativa a esto
es incorporar la definición del sistema difuso, es decir cantidad de entradas, salidas, reglas, etc.,
al momento de la compilación. No obstante, esta solución requiere recompilar cada vez que se
haga un ajuste al sistema y se debe observar que, en la práctica, quien realiza dichos ajustes es un
experto en lógica difusa y no necesariamente un programador experimentado. La alternativa por la
que finalmente se optó es definir un formato binario propio, denominado Compact Fuzzy System
(CFS), que pueda ser incorporado en tiempo de compilación o tiempo de ejecución. Esta solución
es flexible y notablemente más eficiente que usar archivos de texto.
3.1.2.
Visión general
El framework está compuesto por dos módulos. El módulo principal, µFuzzy, es una librería de
lógica difusa pensada para ser utilizada en sistemas embebidos. Su principal objetivo es permitir la
implantación de sistemas de control difusos y sistemas expertos difusos en microcontroladores de
bajo costo con cantidades limitadas de memoria y baja velocidad de procesamiento. La librería no
constituye una herramienta para el diseño de sistemas basados en lógica difusa, sino para su implementación. El módulo secundario, cfsconvert, es un software de escritorio que permite convertir
los formatos de archivos difundidos de descripción de sistemas difusos, como ser el formato FIS, al
formato CFS de µFuzzy.
Antes de entrar en los detalles del diseño de cada módulo, es necesario comprender cómo éstos
interactúan entre sí y cómo se integrarían a una aplicación que haga uso del framework (ver Fig.
3.1). Supóngase que se desea implementar un sistema de control para un aire acondicionado usando
µFuzzy. En primer lugar, el modelador estudiará el problema, definirá cuáles son las entradas y salidas del sistema, las reglas que rigen su comportamiento y otros parámetros que hacen al proceso
de inferencia difusa. Esta información debe plasmada ser por el modelador en un archivo FIS, FLL
o FCL. Por otro lado, el implantador desarrollará el software que se instalará en el aire acondicionado utilizando la librería µFuzzy. Finalmente, deberá cargar el archivo creado por el modelador
CAPÍTULO 3. DISEÑO
14
Desarrollo de un framework en lenguaje C para controladores difusos
en la aplicación de escritorio cfsconvert para convertirlo a formato CFS e incorporarlo al software
desarrollado.
Figura 3.1: Módulos de µFuzzy
3.2.
µFuzzy
3.2.1.
Elección del lenguaje de desarrollo
Al desarrollar software para microcontroladores la elección del lenguaje de programación se ve
limitada por diversos factores. En primer lugar se descartaron los lenguajes interpretados tales como
Python dada la imposibilidad de instalar un intérprete en microcontroladores de bajo costo, e incluso
por la incompatibilidad de dichos intérpretes con ciertas arquitecturas de procesadores típicas de
los sistemas embebidos. Por las mismas razones resulta inviable la instalación de una máquina
virtual que permita ejecutar código escrito en Java o similares. En segundo lugar, debió dejarse
de lado la posibilidad de usar lenguaje ensamblador ya que desarrollar software multiplataforma
implicaría reescribirlo para cada Arquitectura del Set de Instrucciones (ISA) con la que se desea
compatibilidad. Las dos opciones más firmes fueron los lenguajes C y C++, favorecidas por la
existencia de compiladores para todas las familias de microcontroladores populares en el mercado,
pero finalmente se eligió el lenguaje C por razones de performance.
3.2.2.
Consideraciones respecto al lenguaje
El lenguaje C cuenta con varios estándares publicados desde su creación los cuales no fueron
totalmente implementados por todos los compiladores. Características incluidas en C99 (ISO/IEC
9899:199) tales como funciones inline o la posibilidad de declarar variables en cualquier lugar del
cuerpo de las funciones no están disponibles en muchos compiladores actualmente, por lo que se
optó por escribir código compatible con ANSI C. Además, muchos de los microcontroladores con
los que se busca compatibilidad no cuentan con un Sistema Operativo (OS), lo que implica que
características tales como administración dinámica de memoria y E/S provistas por las librerías
estándar del lenguaje a través del OS no están disponibles. Para maximizar la compatibilidad se
decidió no hacer uso de dichas librerías. Asimismo, es frecuente encontrar microcontroladores sin
soporte para aritmética con punto flotante. Por esta razón µFuzzy utiliza operaciones con punto fijo.
CAPÍTULO 3. DISEÑO
15
Desarrollo de un framework en lenguaje C para controladores difusos
3.2.3.
Utilización de aritmética de punto fijo
La aritmética de punto fijo se implementa con variables enteras destinando algunos bits para la
parte entera y los restantes para la parte fraccionaria. La adición y la sustración se efectúan tal como
se hace con enteros, pero no sucede lo mismo con el producto y el cociente. Si se utilizan n bits para
la parte fraccionaria, después de un producto debe realizarse un desplazamiento de n bits hacia la
derecha sobre el resultado para obtener el valor correcto. En el caso del cociente, el desplazamiento
debe realizarse antes de dividir y hacia la izquierda. Cuando se utilizan enteros, el rango de valores
que pueden representarse con una variable de 32 bits habitualmente excede las necesidades de las
aplicaciones, y resulta poco frecuente necesitar variables de 64 bits o más. En cambio, si se trabaja
con punto fijo y por ejemplo se destinan 16 bits para la parte entera y 16 bits para la fraccionaria,
el valor máximo representable es 32535. Además debe tenerse en cuenta que al multiplicar o al
dividir, por la forma en la que se efectúan estas operaciones, los valores intermedios son varios
ordenes de magnitud mayores al resultado. Como consecuencia, el uso de variables de 64 bits para
almacenar estos valores intermedios puede ser necesario y acarrea dos problemas: performance y
compatibilidad. Es que para las arquitecturas a las que µFuzzy está destinada las operaciones de
64 bits son naturalmente más lentas y de hecho, algunos compiladores para estas arquitecturas ni
siquiera soportan variables de 64 bits.
Al momento de elegir la cantidad de bits para las variables de punto fijo, es necesario analizar el
proceso de inferencia difusa. En este proceso, los números que intervienen provienen de las variables
de entrada y salida, y en particular las funciones de membresía definidas para estas. El dominio de
estas funciones de membresía corresponde al de la variable para la que se definieron, mientras que
su rango (que representa un grado de pertenencia) es [0,1]. El dominio depende de la aplicación y
dentro de una misma aplicación puede haber variables con dominios muy diferentes entre sí. Por
consiguiente, la elección del tamaño de la parte entera y fraccional se convierte en una decisión de
compromiso; si se usan pocos para la parte entera se limita el valor máximo representable, mientras
que si se usan pocos para la parte fraccionaria se limita la precisión. Esa decisión puede evitarse si
las variables y sus respectivas funciones de membresía se someten a un proceso de normalización tal
y como se muestra en la Fig. 3.2. Como se puedo observar, las variables de entrada son normalizadas
al intervalo [0,1] antes del proceso de inferencia. Luego del proceso, se obtiene un resultado también
dentro del intervalo [0,1]. Finalmente, este resultado se convierte a su valor real. De esta manera, la
parte entera puede ser pequeña y todos los bits restantes pueden usarse para la parte fraccionaria.
En vista de lo expuesto se decidió utilizar variables de 16 bits, con 2 bits para la parte real
y 14 para la parte fraccionaria, las cuales permiten representar valores en el intervalo [-2, 2) con
incrementos de 2−14 . La ventaja de usar variables de 16 bits es que los valores intermedios caben
en variables de 32 bits, que pueden utilizarse en todas las arquitecturas. Se requiere el bit de signo
porque cuando se usa el método de Sugeno-Takagi, los coeficientes de los consecuentes de las reglas
pueden ser negativos.
3.2.4.
Limitaciones debidas al uso de punto fijo.
Al margen de las pérdidas de precisión, existen otras límitaciones relacionadas con el uso de
aritmética de punto fijo. En primer lugar, el rango de las variables de entrada y salida debe estar
bien definido de modo que sea posible efectuar la normalización. Todos los formatos compatibles
con µFuzzy tienen campos destinados para esos efectos, sin embargo, en el caso de los sistemas
basados en el método de Sugeno-Takagi, el rango de las variables de salida es opcional. Para poder
convertirlos a formato CFS y utilizarlos con µFuzzy esa información debe ser provista. Dicho de otro
modo, si el rango de una variable de salida no se especifica en el archivo que describe al sistema
CAPÍTULO 3. DISEÑO
16
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 3.2: Proceso de inferencia con variables normalizadas
difuso, entonces ese archivo no es compatible con el framework.
Otra limitación aparece cuando se analizan los coeficientes utilizados en los consecuentes de las
reglas de los sistemas de Sugeno-Takagi. El valor de estos coeficientes debe modificarse de manera
acorde a la normalización de las variables de entrada y de salida, para no alterar el comportamiento
del sistema. En algunos casos, el nuevo valor de los coeficientes no pertenece al intervalo representable [-2, 2). Cuando eso sucede, la solución es sobredimensionar el rango de las variables de
salida en forma proporcional al exceso en el valor del coeficiente, de modo que tras la normalización, los coeficientes sean representables. Dicho de otro modo, si el rango original de una variable
de salida es [0, 100] y uno de los coeficientes luego de la normalización resulta 3, entonces redefiniendo ese rango como [0, 200] el valor del coeficiente será 1.5 y podrá representarse. El proceso
de normalización de coeficientes se explica en el anexo D.
3.2.5.
Características soportadas
Los sistemas de inferencia difusos cuentan con una gran cantidad de parámetros que pueden ser
ajustados para lograr el comportamiento deseado. La Tabla 3.1 expone las características soportadas
por µFuzzy.
Las funciones de mebresía de µFuzzy ofrecen flexibilidad y eficiencia. Las funciones de pertenencia trapezoidales, que también pueden ser utilizadas como triangulares o rectangulares, optimizan el uso de memoria y son procesadas rápidamente. Por otro lado, las tabuladas, permiten
representar funciones arbitrarias y, aunque demandan más memoria que las anteriores, el tamaño
de las tablas es configurable. Ambos tipos de funciones de membresía pueden coexistir e incluso,
los tamaños de las tablas pueden configurarse independientemente para cada una. A su vez, µFuzzy
permite configurar independientemente métodos de inferencia, operadores de activación, operadores de agregación y defuzzificadores para cada variable de salida. Es decir que un controlador podría
calcular el valor de una variable de salida utilizando el método de Sugeno y otras usando el método
de Mamdani.
CAPÍTULO 3. DISEÑO
17
Desarrollo de un framework en lenguaje C para controladores difusos
Métodos de inferencia
Funciones de membresía
T-normas
S-normas
Métodos de defuzzificación
Conectivos lógicos
Sugeno
Mamdani
trapezoidal
tabulada
mínimo
producto algebraico
diferencia acotada
producto drástico
producto de Einstein
producto de Hamacher
máximo
suma algebraica
suma acotada
suma drástica
suma de Einstein
suma de Hamacher
centroide
media ponderada
conjunción
disyunción
negación
Cuadro 3.1: Características soportadas por µFuzzy
3.3.
cfsconvert
3.3.1.
Características generales
cfsconvert es un conversor de archivos FIS a formato CFS. Para agilizar el desarrollo de esta
aplicación se la diseño como una herramienta por línea de comandos. Si bien el uso de este tipo de
herramientas puede resultar poco intuitivo, cfsconvert ofrece funcionalidad Drag & Drop a fin de
simplificar la tarea del usuario final. A su vez, al funcionar por línea de comandos, cfsconvert puede
integrarse a cadenas de herramientas automatizadas.
El conversor genera dos tipos de salidas: código fuente C con los datos en formato CFS incrustados, o un archivo binario que puede ser interpretado por la librería. En el primer caso, el sistema
difuso se define en tiempo de compilación, es decir que para realizar ajustes el software debe ser
recompilado. Esta opción es la más adecuada para proyectos simples, en los que recompilar no
represente un esfuerzo significativo. En el segundo caso, en cambio, el archivo binario generado
puede cargarse dinámicamente. Esto permite por ejemplo cargar el archivo CFS en una tarjeta SD o
transferirlo a través de una red. La elección dependerá de cuál de las dos opciones se integre mejor
al flujo de trabajo del proyecto.
3.3.2.
Elección del lenguaje de desarrollo
La elección del lenguaje de desarrollo pudo efectuarse con mayor libertad que en el caso de
µFuzzy, dado que el conversor es una aplicación de escritorio y su performance es un elemento
secundario. Aunque podrían haberse escogido lenguajes ágiles tales como Python o Lua, finalmente
se optó por C++. El factor clave a la hora de decidir fue que la librería fuzzylite es gratuita, de código
CAPÍTULO 3. DISEÑO
18
Desarrollo de un framework en lenguaje C para controladores difusos
abierto y provee funciones para leer archivos FIS. Es decir que haciendo uso de fuzzylite sólo es
necesario crear las funciones para exportar a formato CFS y programar la interfaz de comandos.
CAPÍTULO 3. DISEÑO
19
Desarrollo de un framework en lenguaje C para controladores difusos
Capítulo 4
Aplicación
4.1.
Introducción
A lo largo de este capítulo se describe una aplicación de µFuzzy en un robot móvil autónomo
terrestre pensado para resolver laberintos. En esta aplicación el framework se emplea a dos niveles:
en primer lugar se utiliza para efectuar control de lazo cerrado sobre la velocidad de las ruedas, y
en segundo lugar para que el robot avance siguiendo una pared lateral (wall-following).
El robot consiste en una versión modificada del presentado en Robot para Laberintos[3]. Posee
una placa principal, basada en un microcontrolador MC9S08JM32 de 8 bits que opera a una frecuencia de bus de 24 MHz y cuenta con 2 KB de memoria RAM y 32 KB de memoria flash. Se
desplaza usando motores de corriente continua que le permiten alcanzar velocidades de hasta 360
mm/s, y cuenta con encoders incrementales de 30 pulsos por revolución en cada rueda. A su vez,
dispone de tres sensores ultrasónicos de distancia: uno frontal y dos laterales a 90o del primero.
Además posee una interfaz Arduino compatible que le permite comunicarse con una placa secundaria a través del puerto serie y delegarle la toma de decisiones. En esta aplicación se usa para ese
propósito una FRDM-KL25Z, una placa de desarrollo basada en un microcontrolador de 32 bits con
núcleo Cortex-M0+ que trabaja a 48 MHz, y que cuenta con 16 KB de memoria RAM y 128 KB de
memoria flash.
4.2.
Control de lazo cerrado para los motores
4.2.1.
Estudio de los motores
Como se mencionó anteriormente el robot cuenta con dos motores de corriente continua, los
cuales se controlan mediante Modulación por Ancho de Pulsos (PWM). El primer paso en el diseño
del controlador fue obtener la relación entre el ciclo de trabajo ρ y la velocidad del robot v, la cual
se muestra en la Fig. 4.1. En el intervalo [80, 380] la curva puede aproximarse mediante una función
cuadrática, mientras que las velocidades inferiores a 80 mm/s no pueden lograrse.
Por otro lado, la Fig. 4.2 muestra la velocidad en función del tiempo para un ciclo de trabajo
dado, partiendo desde el reposo. Se puede observar que aunque el ciclo de trabajo se mantenga
constante, la respuesta tiene una cantidad considerable de ruido. Esto se debe a que el cálculo de la
velocidad se realiza tomando el tiempo entre pasos del encoder, y en el robot utilizado ese tiempo no
puede ser medido con más precisión ya que encoders están conectados a entradas analógicas. Esto
implica que los pasos deben ser detectados por software muestreando la señal, pero la frecuencia de
muestreo (que determina el error de la medición) está fuertemente limitada por las capacidades del
CAPÍTULO 4. APLICACIÓN
20
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 4.1: Ciclo de trabajo en función de la velocidad
procesador.
4.2.2.
Estructura del controlador
En base a los datos obtenidos, se desarrolló el modelo de controlador que se muestra en la Fig.
4.3. El mismo está basasdo en un controlador PI, en el cual la parte derivada se omite dado que el
ruido en la señal no permite utilizarla. Toma como entradas la velocidad de referencia o setpoint vr ,
el error e en la velocidad respecto al setpoint, y la integral de este error ie . A partir de la vr se calcula
un ciclo de trabajo aproximado ρ0 utilizando la función cuadrática que se obtuvo anteriormente. A
su vez, las tres variables de entrada son sometidas al proceso de inferencia mediante lógica difusa
para obtener como salida ρc , que constituye una corrección a la primera aproximación. El ciclo de
trabajo ρ que finalmente se aplica al motor es la suma de estos dos factores. Usando los encoders,
se mide la velocidad va y se la utiliza para realimentar el controlador.
4.2.3.
Diseño del sistema de control difuso
El sistema de control difuso tiene como objetivo solventar las limitaciones de un controlador
PI con ganancias constantes. Emplea el método de inferencia de Takagi-Sugeno, ya que resulta
notablemente más eficiente que el método de Mamdani[4], y con este mismo criterio, utiliza los
operadores máximo y mínimo para implementar la unión y la intersección difusas respectivamente.
El sistema utiliza tres reglas:
SI e no es chico
ENTONCES ρc = kp0 e
SI e es chico Y vr es baja
ENTONCES ρc = kp1 e + ki1 ie
CAPÍTULO 4. APLICACIÓN
21
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 4.2: Velocidad del robot en función del tiempo para un ciclo de trabajo del 80 %
SI e es chico Y vr no es baja
ENTONCES ρc = kp2 e + ki2 ie
La primera diferencia entre el sistema difuso y el controlador PI es que el primero define las
ganancias en función del setpoint, tal como puede apreciarse en la segunda y tercera regla. Para
velocidades bajas las ganancias son menores, ya que la pendiente de la curva del ciclo de trabajo en
función de la velocidad es menor. Asimismo, para velocidades altas se utilizan ganancias mayores.
Los valores constantes kp1 y kp2 corresponden aproximadamente a la pendiente de la curva para
velocidades bajas y altas respectivamente.
Por otro lado, se encontraron grandes dificultades a la hora de definir las ganancias del término
integral, especialmente para velocidades elevadas. Esto se debe a que en las pruebas, en las que
se partió del reposo, el robot tardaba un tiempo considerable en vencer la inercia y durante ese
tiempo, la integral se acumulaba. Ganancias bajas del termino integral conducían a tiempos de
convergencia altos, mientras que ganancias altas implicaban mayor overshoot. Por este motivo se
utiliza la primera regla, la cual establece que se la parte integral se use solo cuando la velocidad
medida se encuentre próxima al setpoint, es decir cuando el error sea pequeño. Cuando el error
es grande, se utiliza solamente la parte proporcional. Esto permite asignar un valor alto a kp0 para
aproximarse rápidamente al valor deseado sin perder estabilidad, y a su vez, permite que ki1 y ki2
relativamente altas sin el overshoot que habitualmente esto implica.
Las funciones de membresía utilizadas se muestran en la Fig. 4.4. Como puede observarse se
utiliza sólo una para la velocidad de referencia y el error, mientras que para la integral no se usa
ninguna. Esta última variable se usa sólamente en el cálculo de los consecuentes. El rango de la
velocidad de referencia se limita al intervalo [80,400], porque velocidades menores que 80 no son
posibles. Asimismo, el rango del error del error se limita al intervalo [-50, 50] y si el error excede
ese intervalo entonces se trunca.
CAPÍTULO 4. APLICACIÓN
22
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 4.3: Proceso de control
(a) Velocidad de referencia
(b) Error en la velocidad
Figura 4.4: Funciones de membresía para las variables de entrada
4.3.
Seguimiento de pared
El objetivo de este controlador es que el robot avance manteniendo constante la distancia a una
pared lateral valiéndose de un único sensor ultrasónico. En este caso, para disminuir la carga de
tareas en la placa principal, el programa se ejecuta en la placa de toma de decisiones. La Fig. 4.5
muestra el esquema de funcionamiento de este controlador. Las entradas son la distancia da a la
pared, y la derivada de esta distancia respecto al tiempo d0a . Las salidas son la velocidad v y la
velocidad angular ω que deben aplicarse al robot para corregir su dirección.
Esta aplicación, al igual que la anterior, utiliza el método de Takagi-Sugeno y los operadores
máximo y mínimo para implementar las operaciones difusas. El diseño de las reglas y las funciones
de membresía se basa en la geometría del problema. Este sistema dista de ser lineal ya que la
distancia leída por el sensor no es proporcional a la distancia del robot a la pared, sino que esta
afectada por la orientación del robot. Es decir que un cambio brusco en la lectura del sensor no
implica que el robot se haya alejado o acercado a la pared, sino que puede deberse a un cambio en
su orientación. A su vez, cuanto más lejos se encuentra el robot de la pared más sensible es a los
cambios de orientación. A partir de este análisis se plantearon 3 reglas para controlar la velocidad
angular:
CAPÍTULO 4. APLICACIÓN
23
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 4.5: Proceso de control
SI da es pequeña Y d0a no es grande positiva
ENTONCES ω es lineal
SI da no es pequeña Y d0a no es grande positiva
ENTONCES ω es lineal suave
SI d0a es grande positiva
ENTONCES ω es nula
La primera regla emula el comportamiento de un controlador PD y actúa en la operación normal
del robot, es decir cuando se encuentra cerca de la pared y aproximadamente alineado con ésta. La
segunda se activa cuando la distancia del robot a la pared es grande y se similar a la primera pero
con menor ganancia. Finalmente, la última actúa cuando se detecta que la distancia a la pared crece
bruscamente, es decir que el robot está girando alejándose de la pared. El propósito de esta regla es
que el sistema no salga de la zona estable.
Para el control de la velocidad se utilizan dos reglas independientes de las anterirores:
SI da es muy pequeña Y d0a es grande negativa
ENTONCES v es nula
SI da no es muy pequeña O d0a no es grande negativa
ENTONCES v es constante
Cuando el robot se encuentra muy próximo a la pared y continúa aproximándose a ésta, la
velocidad tangencial debe hacerse nula para evitar una colisión. En otro caso, avanza con velocidad
constante. Las funciones de membresía definidas para este controlador se presentan en la Fig. 4.6.
CAPÍTULO 4. APLICACIÓN
24
Desarrollo de un framework en lenguaje C para controladores difusos
(a) Lectura del sensor
(b) Derivada de la lectura
Figura 4.6: Funciones de membresía para las variables de entrada
CAPÍTULO 4. APLICACIÓN
25
Desarrollo de un framework en lenguaje C para controladores difusos
Capítulo 5
Resultados
5.1.
Framework
5.1.1.
Calidad del código fuente
µFuzzy se desarrolló siguiendo el estándar de código fuente propusto en [2] y fue íntegramente
documentada usando doxygen, una herramienta para generar documentación a partir de comentarios
en el código fuente. La densidad de comentarios de la librería es del 92 %, lo que significa que
prácticamente se escribió una línea de comentario por cada línea de código. Por otro lado, la librería
fue sometida a exhaustivas pruebas de funcionamiento. Tanto es así que la cantidad de líneas de
código escritas para las pruebas unitarias es casi el doble que las escritas para la librería propiamente
dicha. Estas estadísticas, generadas con la herramienta CLOC, se muestran en la Tabla 5.1.
Librería
Pruebas unitarias
Total
archivos
29
13
42
comentarios
1405
424
1829
líneas de código
1528
2608
4136
Cuadro 5.1: Estadísticas del código fuente
5.1.2.
Pruebas
Para realizar las pruebas unitarias se utilizó Ceedling, un conjunto de herramientas y librerías
para desarrollo basado en pruebas en lenguaje C. Se escribieron pruebas unitarias para todas las
funciones externas de µFuzzy, y se logró una cobertura del 100 % de las líneas de código. Es decir
que cada línea de código de la librería es ejecutada por al menos una función de prueba, o en otras
palabras, que cada posible camino de ejecución fue probado.
Adicionalmente, se diseñó un software para realizar pruebas funcionales automáticas, que procesa un conjunto de archivos FIS con µFuzzy y fuzzylite, y compara los resultados. Este programa
prueba n combinaciones de entrada uniformemente distribuidas para cada controlador, y calcula
para todas las combinaciones el error normalizado e definido como:
e=
|(oµ − of )|
(omax − omin )
(5.1)
Donde oµ es el valor calculado por µFuzzy, of es el valor calculado por fuzzylite, y omax y omin
son el máximo y el mínimo valor que puede tomar la variable de salida respectivamente. Como
CAPÍTULO 5. RESULTADOS
26
Desarrollo de un framework en lenguaje C para controladores difusos
resultado, presenta el error máximo emax y el error promedio ē. Cabe destacar que este software
prueba tanto µFuzzy como cfsconvert ya que todos los archivos son convertidos de formato FIS a
CFS como parte del procedimiento.
Se realizaron pruebas funcionales sobre un conjunto de archivos FIS tomados de los ejemplos
distribuidos con MATLAB R2014a. Se utilizaron todos los ejemplos exceptuando dos, por hacer uso
de características incompatibles con cfsconvert: constantes simbólicas y funciones personalizadas.
Para los controladores basados en el método de Sugeno, fue necesario redefinir los rangos de las
variables de salida, tal como se explica en 3.2.4. Se probaron 100000 combinaciones de entrada para
cada variable de salida de cada controlador, y los resultados utilizando tablas para las funciones de
membresía de 512 y 4096 entradas se muestran en las Fig.5.1 y 5.2 respectivamente.
Figura 5.1: Errores con tablas de 512 entradas
Como puede observarse en la Fig.5.1, en general, el error máximo se ubica debajo del 0.5 %
mientras que el medio no supera el 0.1 %. En el caso más desfavorable (fpeaks) se obtuvo un error
significativamente mayor. La diferencia se debe a la forma en la que está construido ese sistema.
Utiliza el método de Sugeno y tiene definidas 16 reglas con dos variables de entrada y una de salida.
Cada una de las variables de entrada tiene cuatro funciones de membresía gausianas, las cuales
acarrean el error propio de la tabulación. Por otro lado, en este caso, los coeficientes utilizados en
los consecuentes de las reglas tienen magnitudes muy diferentes entre sí, por lo que el error debido
al uso de aritmética de punto fijo impacta directamente sobre los resultados. Finalmente, utiliza
como operador de conjunción el producto algebráico, lo cual ocasiona pérdidas de precisión que no
ocurrirían si se utilizara por ejemplo el mínimo como operador.
En la Fig. 5.2 se muestran los resultados de las pruebas cuando se aumenta la cantidad de
entradas en las tablas de las funciones de membresía a 4096. En general, tanto errores máximos
como medios se ubican debajo del 0.05 %. Con esta configuración, el error máximo de fpeaks se
CAPÍTULO 5. RESULTADOS
27
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 5.2: Errores con tablas de 4096 entradas
redujo a la cuarta parte, y el error medio a menos de la mitad. El caso más desfavorable pasó a ser
tank2, y su error máximo es idéntico al obtenido con la configuración anterior porque este sistema
utiliza sólo funciones de membresía trapezoidales las cuales no se tabulan. La razón por la cual
presenta un error máximo grande comparado con el resto es que utiliza los operadores algebráicos
para la conjunción y la disyunción, y se pierde precisión tal y como ocurre con fpeaks.
5.1.3.
Integración a la CIAA
La Computadora Industrial Abierta Argentina (CIAA) es una plataforma electrónica libre y gratuita desarrollada colaborativamente en Argentina con el apoyo de universidades y empresas de todo
el país. Se distribuye con un RTOS y un conjunto de módulos orientados a aplicaciones industriales, todos ellos desarrollados específicamente para esta plataforma y siguiendo estrictas normas de
calidad. Por la potencial aplicabilidad de µFuzzy a la industria, se propuso a los responsables del
proyecto CIAA incluirlo como módulo, y como fruto de los esfuerzos realizados en pos de la confiabilidad y mantenibilidad del framework, la propuesta fue aceptada. Esto significa que las futuras
versiones del firmware de la CIAA incluirán una copia de µFuzzy lista para usarse.
5.2.
Aplicaciones
5.2.1.
Control de velocidad
Para evaluar la respuesta del controlador se midió la velocidad del robot en función del tiempo
para distintos setpoints partiendo desde el reposo. Los resultados de los 7 casos de prueba, que
corresponden a velocidades entre 80 mm/s y 360 mm/s con incrementos de 40 mm/s, se presentan
CAPÍTULO 5. RESULTADOS
28
Desarrollo de un framework en lenguaje C para controladores difusos
en la Fig. 5.3a. Como puede observarse, en todos los casos la velocidad converge al valor deseado.
Cuanto más bajo es el setpoint más rápida es la convergencia, y en ningún caso se observa overshoot.
En el caso más desfavorable en término de tiempo de convergencia, es decir cuando la velocidad
deseada es de 360 mm/s, no pueden lograrse mejores resultados dado que para llegar a esa velocidad
se utiliza un ciclo de trabajo del 100 %.
La Fig. 5.3b muestra una comparación de las respuestas usando el controlador difuso y usando
control de lazo abierto, para una velocidad de referencia de 240 mm/s. Puede observarse que usando
control de lazo cerrado la velocidad converge al valor deseado en menos de 400 ms, mientras que
usando control de lazo abierto la velocidad nunca llega al setpoint y se estabiliza en 1 segundo
aproximadamente.
5.2.2.
Seguimiento de pared
Para el caso de este controlador, dada la imposibilidad de medir la distancia del robot a la pared,
lo que se evaluó fue la lectura del sensor ultrasónico en función del tiempo. Nótese que la lectura del
sensor está influenciada por la orientación del robot, es decir que la distancia medida no corresponde
a la distancia a la pared excepto cuando el robot avanza de forma paralela a la misma. El controlador
fue probado para 4 condiciones inciales y una distancia objetivo de 47 mm.
La Fig. 5.4 muestra los resultados para un ángulo incial nulo, y dos distancias iniciales diferentes. En ambos casos hay overshoot en la lectura del sensor, aunque el overshoot en la distancia real
del robot a la pared es considerablemente menor. El tiempo de convergencia a la distancia objetivo
es de aproximadamente 4 segundos en los dos casos.
El comportamiento del controlador también fue evaluado para ángulos iniciales distintos de 0.
Las Fig. 5.5 y 5.6 muestran los resultados para ángulos iniciales de -22o (acercándose a la pared) y
45o (alejándose de la pared). Ángulos mayores a 45o no son viables dado que en esos casos el sensor
no es capaz de detectar las ondas reflejadas por la pared, por lo tanto la distancia no se puede medir.
Ángulos menores a -22o con distancias iniciales pequeñas no pudieron lograrse con este controlador,
dado que se requiere un tiempo de respuesta muy rápido y que la distancia real a la pared es mucho
menor que la medida.
5.3.
Conclusiones y trabajos futuros
A lo largo de este trabajo de graduación se expuso los procesos de diseño, desarrollo y prueba
de µFuzzy. El funcionamiento del framework fue validado satisfactoriamente usándolo en un robot
móvil, para dos propositos diferentes en dos microcontroladores de bajo costo de arquitecturas totalmente distintas entre sí. A futuro, se planea mejorar la librería ampliando la gama de métodos
de defuzzificación y dando permitiendo asignar pesos a cada regla. Esta última característica es importante porque otorgaría total compatibilidad con Sistemas de Inferencia Adaptativos de Inferencia
Neuro-Difusa (ANFIS).
En vista de los resultados, puede afirmarse que µFuzzy constituye una herramienta confiable
y potente, que puede utilizarse en aplicaciones reales y complejas, y en entornos extremadamente
limitados en términos de recursos procesamiento.
CAPÍTULO 5. RESULTADOS
29
Desarrollo de un framework en lenguaje C para controladores difusos
(a) v(t) para distintos setpoints
(b) Control de lazo abierto vs control de lazo cerrado
Figura 5.3: Respuesta en velocidad usando control difuso
CAPÍTULO 5. RESULTADOS
30
Desarrollo de un framework en lenguaje C para controladores difusos
(a) Distancia inicial de 20 mm
(b) Distancia inicial de
Figura 5.4: Lectura del sensor en función del tiempo con ángulo inicial nulo
CAPÍTULO 5. RESULTADOS
31
Desarrollo de un framework en lenguaje C para controladores difusos
Figura 5.5: Ángulo inicial de -22o
Figura 5.6: Ángulo incial de 45o
CAPÍTULO 5. RESULTADOS
32
Bibliografía
[1] David M Byrne, Stephen D Oliner, and Daniel E Sichel. How fast are semiconductor prices
falling? Technical report, National Bureau of Economic Research, 2015.
[2] Jerry Doland and Jon Valett. C style guide. 1994.
[3] Martin Izquierdo and Gabriel A Parodi. Robot para resolución de laberintos. Tesis, Universidad
Nacional de Tucumán, Tucumán, Argentina, 2015.
[4] Javad J Jassbi, SH Alavi, Paulo JA Serra, and Rita Almeida Ribeiro. Transformation of a
mamdani fis to first order sugeno fis. In FUZZ-IEEE, pages 1–6, 2007.
[5] Bart Kosko and Satoru Isaka. Fuzzy logic. Scientific American, 269(1):62–7, 1993.
[6] Timothy J Ross. Fuzzy logic with engineering applications. John Wiley & Sons, 2009.
[7] Harpreet Singh, Madan M Gupta, and Thomas et al. Meitzler. Real-life applications of fuzzy
logic. Advances in Fuzzy Systems, 2013.
33
Anexos
34
Desarrollo de un framework en lenguaje C para controladores difusos
Anexo A
API de µFuzzy
A.1.
Tipos de dato
uF_controller_dt
Objeto que contiene la información de un controlador. Son creados por la
función uF_ufuzInit.
uF_fixed_point_dt
Tipo de dato numérico representado en punto fijo. Pueden utilizarse las
funciones uF_fixpToInt, uF_fixpFromInt, uF_fixpToLongInt y uF_fixpFromLongInt
para convertir entre este formato y tipos conocidos.
uF_error_dt
Tipo de dato para representar códigos de error.
A.2.
Funciones
uF_ufuzInit
Crea un nuevo controlador a partir de un bloque de datos con formato CFS.
prototipo
uF_controller_dt* uF_ufuzInit(uint8_t *controller_data, uint32_t data_size);
parámetros
controller_data
Referencia al bloque de memoria que contiene la estructura CFS.
data_size
Tamaño del bloque.
valor de retorno
En caso de éxito, devuelve un puntero a un controlador inicializado. En caso contrario devuelve 0,
y el código de error puede obtenerse llamando a uF_ufuzError.
uF_ufuzClear
Libera los recursos utilizados por un controlador. En la implementación actual, sin reserva dinámica
de memoria, esta función no efectúa ninguna acción.
ANEXO A. API DE µFUZZY
35
Desarrollo de un framework en lenguaje C para controladores difusos
prototipo
uF_ufuzClear(uF_controller_dt *controller);
parámetros
controller
Puntero al controlador devuelto por uF_ufuzInit.
uF_ufuzProcess
Calcula la salida del controlador.
prototipo
uF_error_dt uF_ufuzProcess(uF_controller_dt *controller, uF_fixed_point_dt *inputs,
int inputs_size, uF_fixed_point_dt *outputs, int outputs_size);
parámetros
controller
Puntero al controlador devuelto por uF_ufuzInit.
inputs
Arreglo con los valores de las variables de entrada expresados en punto fijo. Pueden utilizarse las funciones uF_fixpFromInt y uF_fixpFromLong
para obtener valores en punto fijo a partir de los tipos int y long respectivamente.
inputs_size
Tamaño del arreglo de entrada. Debe coincidir con la cantidad de variables
de entrada del controlador.
outputs
Arreglo para devolver las salidas del controlador. Pueden utilizarse las
funciones uF_fixpToInt y uF_fixpToLongInt para convertir estos valores a los tipos int y long respectivamente.
outputs_size
Tamaño del arreglo de salida. Debe coincidir con la cantidad de variables
de salida del controlador.
valor de retorno
Devuelve el código de error si hubiera uno. En caso contrario devuelve uF_ERROR_NONE.
uF_ufuzError
Devuelve el código del último error registrado para un controlador en particular. Una llamada a esta
función también limpia el registro de errores para dicho controlador.
prototipo
uF_error_dt uF_ufuzError(uF_controller_dt *controller);
parámetros
controller
Puntero al controlador devuelto por uF_ufuzInit.
ANEXO A. API DE µFUZZY
36
Desarrollo de un framework en lenguaje C para controladores difusos
valor de retorno
Si controller no es nulo, devuelve el último código de error producido sobre ese controlador.
En caso contrario, devuelve el último error global. Esto es útil, cuando uF_ufuzInit devuelve un
puntero nulo.
uF_fixpFromInt
Convierte un número entero perteneciente al intervalo [range_min, range_max], a un valor de
punto fijo normalizado.
prototipo
uF_fixed_point_dt uF_fixpFromInt(short i, short range_min, short range_max);
parámetros
i
Número a convertir.
range_min
Valor mínimo que puede tomar la variable a convertir.
range_max
Valor máximo que puede tomar la variable a convertir.
valor de retorno
Devuelve el valor convertido a punto fijo.
uF_fixpFromLongInt
Convierte un número entero perteneciente al intervalo [range_min, range_max], a un valor de
punto fijo normalizado.
prototipo
uF_fixed_point_dt uF_fixpFromLongInt(long i, long range_min, long range_max);
parámetros
i
Número a convertir.
range_min
Valor mínimo que puede tomar la variable a convertir.
range_max
Valor máximo que puede tomar la variable a convertir.
valor de retorno
Devuelve el valor convertido a punto fijo.
uF_fixpToInt
Convierte un número en punto fijo, a un entero en el intervalo [range_min, range_max].
ANEXO A. API DE µFUZZY
37
Desarrollo de un framework en lenguaje C para controladores difusos
prototipo
short uF_fixpToInt(uF_fixed_point_dt fp, short range_min, short range_max);
parámetros
fp
Número a convertir.
range_min
Valor mínimo que puede tomar la variable a convertir.
range_max
Valor máximo que puede tomar la variable a convertir.
valor de retorno
Devuelve el valor convertido a entero.
uF_fixpToLongInt
Convierte un número en punto fijo, a un entero en el intervalo [range_min, range_max].
prototipo
short long uF_fixpToLongInt(uF_fixed_point_dt fp, long range_min, long range_max);
parámetros
fp
Número a convertir.
range_min
Valor mínimo que puede tomar la variable a convertir.
range_max
Valor máximo que puede tomar la variable a convertir.
valor de retorno
Devuelve el valor convertido a entero.
uF_poolSpace
Devuelve el espacio disponible en el pool de memoria.
prototipo
uint_fast32_t uF_poolSpace(void);
valor de retorno
La cantidad de bytes disponibles.
ANEXO A. API DE µFUZZY
38
Desarrollo de un framework en lenguaje C para controladores difusos
A.3.
Macros
uF_POOL_SIZE
Tamaño en bytes del pool de memoria. El valor por defecto es 1024.
uF_NO_INT64
Si se define, la librería no hace uso de enteros de 64 bits para las operaciones internas. Por defecto no esta definido. Esta opción es util para
compiladores sin soporte para enteros de 64 bits.
A.4.
Códigos de error
uF_ERROR_NONE
Ningún error.
uF_ERROR_UNKNOWN
Error desconocido.
uF_ERROR_NULL_CFS_DATA
La función de inicialización fue llamada con un
puntero nulo.
uF_ERROR_MEMORY_POOL_TOO_SMALL
No hay suficiente espacio en el pool de memoria. uF_POOL_SIZE debe ser redefinido con un
valor mayor.
uF_ERROR_INPUT_ARRAY_TOO_SMALL
El arreglo de valores de entrada pasado como
argumento a uF_ufuzProcess no tiene suficientes elementos. Debe tener tantos elementos
como variables de entrada tenga el sistema.
uF_ERROR_OUTPUT_ARRAY_TOO_SMALL
El arreglo de valores de salida pasado como argumento a uF_ufuzProcess no tiene suficientes elementos. Debe tener tantos elementos como variables de salida tenga el sistema.
uF_ERROR_DATA_SIGNATURE
El bloque de datos pasado como argumento a
uF_ufuzInit tiene una firma inválida. El puntero al bloque o los datos del mismo son inválidos.
uF_ERROR_RESERVED_FIELD_NOT_ZERO
Los campos reservados en el bloque CFS deben
ser cero.
uF_ERROR_UNKNOWN_AND_OPERATOR
El operador and en el bloque CFS no es válido.
uF_ERROR_UNKNOWN_OR_OPERATOR
El operador or en el bloque CFS no es válido.
uF_ERROR_NO_INPUT_VARIABLES
El controlador definido en el bloque CFS no tiene variables de entrada.
uF_ERROR_NO_OUTPUT_VARIABLES
El controlador definido en el bloque CFS no tiene variables de salida.
uF_ERROR_UNKNOWN_ACTIVATION_OPERATOR
El operador de activación definido para una variable de salida en el bloque CFS no es válido.
ANEXO A. API DE µFUZZY
39
Desarrollo de un framework en lenguaje C para controladores difusos
uF_ERROR_TABLE_INDEX_SIZE_TOO_BIG
El tamaño del índice de una función de membresía tabulada en el bloque de datos CFS es
demasiado grande.
uF_ERROR_SENSOR_RESERVED_FIELD_NOT_ZERO Uno de los campos reservados de una variable
de entrada en el bloque CFS no es cero.
uF_ERROR_UNKNOWN_INFERENCE_METHOD
El método de inferencia definido para una variable de salida en el bloque CFS no es válido.
uF_ERROR_UNKNOWN_AGGREGATION_OPERATOR
El operador de agregación definido para una variable de salida en el bloque CFS no es válido.
uF_ERROR_UNKNOWN_DEFUZZIFICATION_METHOD El método de defuzzificación definido para una
variable de salida en el bloque CFS no es válido.
uF_ERROR_INVALID_TABLE_PARAMETERS
Uno de los grados de verdad que definen una
función de membresía tabulada no pertenence
al intervalo [0, 1].
uF_ERROR_INVALID_TRAPEZOID_PARAMETERS
Uno de los puntos que definen una función de
membresía trapezoidal no pertenence al intervalo [0, 1].
uF_ERROR_MEM_FUNC_RESERVED_FIELD_NOT_ZERO
Uno de los campos reservados de una función
de membresiía en el bloque CFS no es cero.
uF_ERROR_UNKNOWN_MEM_FUNC_TYPE
Una de las funciones de membresía definidas
en el bloque CFS tiene tipo inválido.
uF_ERROR_READER_OVERFLOW
La función de inicialización intentó leer más
allá de los límites del bloque CFS. Los datos
del bloque están dañados.
uF_ERROR_TOO_MANY_DEFUZZIFICATION_STEPS El campo del bloque CFS que define la cantidad
de pasos en el proceso de defuzzificación tiene
un valor mayor al permitido.
uF_ERROR_UNKNOWN_LOGICAL_CONNECTIVE
Una de las reglas del bloque CFS tiene un conectivo lógico inválido.
uF_ERROR_INVALID_MEMBERSHIP_FUNCTION_ID Una de las reglas del bloque CFS hace referencia a una función de membresía inexistente.
uF_ERROR_CONTROLLER_NOT_INITIALIZED
El controlador no fue inicializado antes de llamar a la función de procesamiento.
uF_ERROR_PADDING_NOT_ZERO
Uno de los campos de relleno en el bloque CFS
no es cero.
ANEXO A. API DE µFUZZY
40
Desarrollo de un framework en lenguaje C para controladores difusos
Anexo B
Manual de cfsconvert
Descripción
cfsconvert es una herramienta por línea de comandos para convertir archivos FIS a formato CFS.
Utilización
cfsconvert [-d dsteps] [-s tsize] [-c] [-b] [-t] SOURCE [DESTINATION]
-d dsteps
Logaritmo en base dos del número de pasos a realizar en el proceso de
defuzzificación. El valor por defecto es 8, que corresponde a 256 pasos.
-s tsize
Logaritmo en base dos del número de entradas en las funciones de membresía tabuladas. El valor por defecto es 8, que corresponde a 256 entradas
por tabla.
-c
El conversor entrega como salida código fuente C. Esta opción es apropiada para integrar el conversor en un toolchain.
-b
El conversor entrega como salida un archivo binario con la estructura
CFS.
-t
El conversor entrega como salida un archivo de texto con la estructura
CFS definida como un struct en C.
SOURCE
Ruta al archivo FIS a convertir.
DESTINATION
Nombre del archivo o los archivos de salida sin extensión. Si DESTINATION
se omite, entonces los archivos de salida tienen el mismo nombre que el
archivo FIS, pero diferente extensión.
Si no se especifica ninguno de los parámetros -c, -b o -t, entonces el conversor entrega un archivo
de texto.
ANEXO B. MANUAL DE CFSCONVERT
41
Desarrollo de un framework en lenguaje C para controladores difusos
Anexo C
Especificación del formato CFS
Estructura
8 bytes
x bytes
cabecera
variable de
entrada 1
...
y bytes
z bytes
variable de
entrada n
variable de
salida 1
w bytes
...
variable de
salida m
Cabecera
byte 0
byte 1
byte 2
byte 3
1
'C'
'F'
'S'
RES:=0
2
AND_OP
OR_OP
INPUT_NUM
OUTPUT_NUM
RES
Campo reservado. Debe valer 0.
AND_OP
Identificador del operador conjuntivo.
OR_OP
Identificador del operador disyuntivo.
INPUT_NUM
Cantidad de variables de entrada.
OUTPUT_NUM
Cantidad de variables de salida.
ANEXO C. ESPECIFICACIÓN DEL FORMATO CFS
42
Desarrollo de un framework en lenguaje C para controladores difusos
Variables de entrada
1 byte
1 byte
x bytes
y bytes
MF_NUM
RES:=0
función de membresía 1
...
función de membresía n
MF_NUM
Cantidad de funciones de membresía para esta variable.
RES
Campo reservado. Debe valer 0.
Funciones de membresía trapezoidales
1
byte 0
byte 1
MF_TYPE:=0
RES:=0
2
X1
3
X3
byte 2
byte 3
X0
X2
MF_TYPE
Tipo de función de membresía. 0 para trapezoidales.
RES
Campo reservado. Debe valer 0.
X0
Coordenada x del primer punto del trapezoide. La coordenada y es 0.
X1
Coordenada x del segundo punto del trapezoide. La coordenada y es 1.
X2
Coordenada x del tercer punto del trapezoide. La coordenada y es 1.
X3
Coordenada x del cuarto punto del trapezoide. La coordenada y es 0.
Funciones de membresía tabuladas
1
byte 0
byte 1
MF_TYPE:=1
INDEX_SIZE
byte 2
byte 3
Y0
...
m
MF_TYPE
Yn
Tipo de función de membresía. 1 para tabuladas.
ANEXO C. ESPECIFICACIÓN DEL FORMATO CFS
43
Desarrollo de un framework en lenguaje C para controladores difusos
INDEX_SIZE
Tamaño del índice de la tabla. La cantidad de elementos en la tabla es 2i , donde
i es el tamaño del índice.
Y0
Coordenada y del primer punto de la tabla.
Yn
Coordenada y del último punto de la tabla.
Variables de salida calculadas por Mamdani
1 byte
1 byte
x bytes
INF_TYPE:=0
MF_NUM
función de
membresía 1
...
y bytes
z bytes
función de
membresía n
parámetros
Mamdani
INF_TYPE
Método de inferencia. 0 para Mamdani.
MF_NUM
Cantidad de funciones de membresía para esta variable.
Parámetros Mamdani
1 byte
1 byte
1 byte
1 byte
1 byte
1 byte
n bytes
ACT_OP
AGG_OP
DEFUZ
STEPS
RES:=0
RULE_NUM
regla 1
n bytes
...
regla n
ACT_OP
Identificador del operador de activación.
AGG_OP
Identificador del operador de agregación.
DEFUZ
Identificador del método de defuzzificación.
STEPS
Logaritmo en base 2 de la cantidad de pasos a realizar en el proceso de defuzzificación. Se realizan 2d pasos, donde d=STEPS.
RES
Campo reservado. Debe valer 0.
RULE_NUM
Cantidad de reglas para calcular esta variable.
Reglas Mamdani
1 byte
1 byte
CON
MF1
...
1 byte
1 byte
1 byte
MFn
OMF
[PAD]
ANEXO C. ESPECIFICACIÓN DEL FORMATO CFS
44
Desarrollo de un framework en lenguaje C para controladores difusos
CON
Identificador del conectivo lógico de la regla.
MF1
Identificador de la función de membresía de la variable de entrada 1.
MFn
Identificador de la función de membresía de la variable de entrada n.
OMF
Identificador de la función de membresía de la variable de salida.
[PAD]
Padding para alinear la regla a 16 bits si es necesario.
Variables de salida calculadas por Sugeno
1 byte
1 byte
x bytes
INF_TYPE:=1
RULE_NUM
regla 1
y bytes
...
regla n
INF_TYPE
Método de inferencia. 1 para Sugeno.
RULE_NUM
Cantidad de funciones de reglas para calcular esta variable.
Reglas Sugeno
1 byte
1 byte
CON
MF1
...
1 byte
1 byte
2 bytes
2 bytes
MFn
[PAD]
C0
C1
2 bytes
...
CON
Identificador del conectivo lógico de la regla.
MF1
Identificador de la función de membresía de la variable de entrada 1.
MFn
Identificador de la función de membresía de la variable de entrada n.
[PAD]
Padding para alinear la regla a 16 bits si es necesario.
C0
Término independiente del consecuente en formato big-endian.
C1
Coeficiente de la variable 1 en formato big-endian.
Cn
Coeficiente de la variable n en formato big-endian.
ANEXO C. ESPECIFICACIÓN DEL FORMATO CFS
Cn
45
Anexo D
Cálculo de los coeficientes de
Sugeno-Takagi
Considérese un sistema basado en el métdo de Sugeno-Takagi con n variables de entrada. Los
consecuentes de las reglas de este sistema tienen la forma:
y=
n
X
ai xi + a0
(D.1)
i=1
Donde se utilizan los símbolos x para las entradas, y para las salidas y a para los coeficientes. Si
ymax e ymin son los valores máximo y mínimo que puede tomar y, entonces la variable normalizada
y 0 puede obtenerse como:
n
y0 =
X
ai
a0 − ymin
y − ymin
=
xi +
ymax − ymin
ymax − ymin
ymax − ymin
(D.2)
i=1
Renombrando los coeficientes se obtiene:
n
X
y0 =
bi xi + b0
(D.3)
i=1
Por otro lado, las entradas del sistema no serán las variables xi , sino las variables normalizadas
x0i , las cuales pueden definirse como:
x0i =
xi − ximin
ximax − ximin
(D.4)
Donde ximax e ximin son los valores máximo y mínimo que puede tomar la variable xi . Despejando
xi y reemplazando en la ecuación D.7 se obtiene:
0
y =
n
X
bi [x0i (ximax − ximin ) + ximin ] + b0
(D.5)
i=1
Reordenando resulta:
0
y =
n
X
bi (ximax −
ximin )x0i
i=1
+
n
X
i=1
46
bi ximin + b0
(D.6)
Desarrollo de un framework en lenguaje C para controladores difusos
Finalmente, esta ecuación puede escribirse como:
0
y =
n
X
ci x0i + c0
(D.7)
i=1
Donde:
ci = bi (ximax − ximin ) = ai
c0 =
n
X
i=1
ximax − ximin
, i = 1..n
ymax − ymin
Pn
bi ximin + b0 =
+ a0 − ymin
ymax − ymin
i=1 ai ximin
ANEXO D. CÁLCULO DE LOS COEFICIENTES DE SUGENO-TAKAGI
(D.8)
(D.9)
47
Descargar