a3 CARRERA: LIC. EN COMPUTACIÓN MATERIA: PROYECTO DE INVESTIGACI~N11 TÍTULO: " APLICACIONES DEL FILTRO DE KALMAN " ALUMNO: RICARDO CÉSAR LOZANO BECEFUUL DR. HÉCTOR PÉREZ MEANA TIMESTRE LECTIVO 97-0 2811 U1997 En 1809 el gran matemático alemán K. F. Gauss, mientras discutía en su clásica “Teoría Motus” el problema de determinar los elementos de órbita de un cuerpo celeste a partir de mediciones dadas, enunció lo siguiente: Si las observaciones astronómicas y otras cantidades, en las cuales se basan los cálculos de las órbitas, fueran absolutamente correctas, también los elementos, si deducidos de tres o cuatro observaciones fueran estrictamente precisos, y, por lo tanto, si se usaran otras observaciones, podrían ser confirmadas pero no corregidas. Pero desde que todas nuestras mediciones y observaciones no son otra cosa sino aproximaciones a la realidad, lo mismo debe ser cierto para todos los cálculos basados en ellos, y el mayor objetivo de todos los cálculos hechos concernientes a este fenómeno es que se aproximen tanto como se pueda a la realidad. Esto no puede lograrse sino con una combinación conveniente de un número mayor de observaciones que las que se requieren para la determinación de las cantidades desconocidas. Este problema puede ser propiamente atacado solo cuando se ha logrado un conocimiento aproximado de la órbita, el cual será más tarde corregido para satisfacer todas las observaciones de la manera más segura posible. La técnica que Gauss sugirió para obtener aproximaciones (o estimaciones) de cantidades desconocidas se conoce como el método de los mínimos cuadrados. Nótese que él lo llamó asípor aproximar conocimientos de la órbita con el fin de determinar la estimación de los mínimos cuadrados. Estas estimaciones fueron usadas para corregir la órbita de referencia. Una versión moderna de la técnica de los mínimos cuadrados de Gauss se desarrolla y se discute en los siguientes párrafos. Hay dos grandes diferencias entre las técnicas moderna y clásica. La teoría matemática de probabilidad no existía al principio del siglo diecinueve, así que las consideraciones de Gauss fueron de una naturaleza determinística. La información adicional que se acumula por la introducción de consideraciones probabilísticas y estadísticas permiten idear una teoría más precisa, aunque el procedimiento de estimación se vuelve más complejo. La complejidad conduce a la segunda diferencia significativa. El adviento de la moderna tecnología de las computadoras digitales permite usar modelos matemáticos más sofisticados en las investigaciones científicas. Los investigadores contemporáneos a Gauss estaban restringidos a las técnicas que permitían soluciones aproximadas o que envolvían cálculos que podían realizarse en un tiempo razonable usando lápiz y papel. Las soluciones analíticas no eran muy largas pero sí importantes, ya que las soluciones numéricas pueden ser obtenidas para una amplia gama de problemas. * * * * Una convergencia inicial muy rápida de los coeficientes de utilización del ecualizador es un requerimiento de muchos sistemas de comunicación de datos los cuales emplean ecualizadores adaptivos para minimizar la interferencia entre símbolos. Como se muestra en documentos recientes de Codard, y por Citlin y Magee, un algoritmo de estimación de mínimos cuadrados, se puede aplicar para estimar el conjunto óptimo de coeficientes de utilización (mínimo MSEI. Se ha mostrado además que esto produce una convergencia mucho más rápida del ecualizador que la conseguida por el simple algoritmo gradiente estimado, especialmente para varios canales distorsionados. MOSt~aremOScómo ciertas técnicas de "estimación rápida recursiva", originalmente introducidas por MOrf y Ljung, pueden adaptarse al problema de ajuste del ecualizador, dando como resultado la misma convergencia rápida que con la implementación convencional de Kalman, pero lejanamente con un menor número de operaciones por iteración (proporcional al número de utilizaciones del ecualizador, más que al cuadrado del número de utilizaciones del mismo). Estos algoritmos rápidos, aplicables tanto a ecualizadores lineales como de decisión de regeneración, explotan cierta propiedad de traslado-invariante de los contenidos del ecualizador sucesivos. Las propiedades de rápida convergencia de la adaptación del algoritmo "veloz de Kalman" son confirmadas por simulación. Muchos sistemas modernos de comunicación de datos, emplean ecualizadores transversales adaptivos, cuyos coeficientes de utilización pueden ajustarse a minimizar los símbolos de interferencia. TBicamente, un ecualizador adaptivo ajusta sus coeficientes de utilización durante un período de "entrenamiento" inicial en el cual una secuencia de datos, conocida por el receptor, es transmitida. En muchos sistemas existe un requerimiento para un período de entrenamiento tan corto como sea posible. Esto ha despertado un interés considerable reciente en los algoritmos de adaptación de ecualizador que convergen mucho mas rápido 11 que los simples y comúnmente utilizados algoritmos de aproximación de tipo aún para canales seriamente distorsionados. D. Codard, consideró que el problema de adaptación del ecualizador como la estimación de los mínimos cuadrados del vector de coeficientes de utilización, dadas las entradas de las secuencias del ecualizador y las salidas deseadas. Esta formulación, junto con la suposición basada en la estadística de la salida ideal de error del ecualizador, y en la independencia entre la entrada del ecualizador y el conjunto previo de coeficientes de ganancias, conduce a un caso especial del algoritmo de estimación de Kaltnan para los coeficientes óptimos de utilización del ecualizador. Este parece ser el más rápido algoritmo de adaptación de ecualizador conocido. Esta afirmación es sostenida con la interpretación del algoritmo de adaptación del ecualizador de Kalman/Codard como un algoritmo propiamente ortogonal ideal, y también por los resultados de la simulación de un canal de teléfono. Un significado adicional de ese trabajo es su notable y provechosa aplicación de teoría de control en los problemas de adaptación en comunicaciones y procesamiento de señales. Este mismo algoritmo de adaptación del ecualizador tiene lugar, sin utilizar suposiciones basadas en estadística, de un problema clásico de mínimos cuadrados: después de cada nueva entrada y salida del ecualizador, encontrar el conjunto de coeficientes de utilización del ecualizador que minimizan la acumulación de errores cuadráticos en el tiempo. La solución de este problema clásico de tiempo discreto de Wiener-HOpf,implementado recursivamente, es un caso especial del algoritmo de Kalman, con una variable de estado constante. una desventaja del algoritmo de Kalman es su complejidad. una matriz de N x N debe ser adaptada y almacenada una vez en cada iteración, donde N,el número de coeficientes de utilización del ecualizador, puede ser típicamente del orden de 50 o algo similar. Así un orden de N2 operaciones debe ser ejecutado por iteración, en contraste al número aproximado N de operaciones requerido por algoritmos de adaptación generalmente usados en la práctica. Recientemente, ciertos "algoritmos rápidos" han reportado al reducir el número de operaciones por iteración en algoritmos de estimación de vectores Ndimensionales de mínimos cuadrados ser proporcionales a n. Este trabajo tiene ... 111 una relación conceptual con el algoritmo de Levinson para problemas de predicción. Estas algoritmos recursivos rápidos de mínimos cuadrados explotan la "propiedad de traslado" de la mayoría de los problemas de estimación secuencial. En la ecualización, esta propiedad expresa el hecho de que a cada iteración el número de nuevas muestras que entran y las viejas muestras que dejan el ecualizador no es NI sino un número mucho más pequeño p. Por ejemplo, p = 1 para un ecualizador lineal convencional. Aquímostraremos la aplicación del algoritmo del "filtro de Kalman" en varios tipos de ecualizadores adaptivos, y reportamos los resultados de simulaciones computacionales. El algoritmo es matemáticamente equivalente al algoritmo original de adaptación del ecualizador de Kalman y Codard (con algunas restricciones adicionales en las condiciones iniciales). También, se muestra una simple modificación, la cual habilita al algoritmo en las siguientes variaciones en el tiempo del canal. iv ii 1 23 34 CAPÍTULO 1. PRINCIPIOS BÁSICOS. Principios básicos de filtros adaptivos 2 Filtros adaptivos 9 Formulación del ecualizador adaptivo 10 Aplicación de un algoritmo recursivo con mínimos cuadrados para 14 un ecualizador adaptivo El algoritmo fuerte de kalman 16 Simulación de los resultados 19 Conclusiones 20 CAPITULO 11. APLICACIONES DE FILTROS ADAPTIVOS El combinador lineal de impulso-respuesta-finito. 24 ECUaliZaCiÓn de un canal usando un filtro de kalman para la 26 transmisión rápida de datos. CAPITULO 111. DIVERGENCIA Divergencia en el filtro de kalman 29 Causas de la divergencia 29 Control de divergencia 30 Ejemplo ilustrativo 31 CAPITULO IV. EL FILTRO ADAPTIVO DE KALMAN Código fuente del filtro adaptivo de kalman 35 I Aplicaciones del filtro de Kalman 1 Aplicaciones del filtro de Kalman Este trabajo presenta una breve explicación del funcionamiento de los filtros adaptivos. Uno de los principales y más importante de estos filtros es el de Kalman. Gracias a sus investigaciones, los filtros actuales son más precisos en la eliminación de ruido y generación de señales puras. Para poder explicar de manera precisa y clara los funcionamientos de estos filtros se requiere tener conocimientos de términos matemáticos avanzados, como son el manejos de matrices, manejo de fórmulas Gaussianas, Integrales, y muchos más. Se muestra de manera esquemática las funciones y desarrollo de estos filtros por medio de algoritmos computacionales, y así poder transferir su proceso de manejo a lenguajes de programación avanzado, como Lenguaje "C",Pascal entre otros. En el capítulo Iv de este documento se anexa el código fuente de un filtro adaptivo de Kalman, este fue creado por el grupo de alumnos que desarrollaron este reporte. El lenguaje usado fue "C"y su compilación se hace por medio de archivos "Include", ya que sólo se tiene un archivo *.c PRINCIPIOS BASICOS DE FILTROS ADAPTIVOS. En la estructura básica de un filtro adaptivo mostrada en la figura. La senal de entrada es filtrada para producir una salida la cual típicamente es llevada a otro procesamiento subsecuente. La salida de este filtro es también observada por un circuito el cual valora la calidad de la salida. Esta medida de calidad, o alguna función de esta, es pasada al circuito que la utiliza para modificar los parametros del filtro y con esto mejorar la salida. En principio, este ciclo de procesamiento continúa operando hasta que los parámetros del filtro son ajustados para que la salida del filtro sea lo mejor posible. También en principio, si las características de la senal de entrada o la calidad de mejoramiento cambian con el tiempo. Entonces este ciclo mejoramiento/ajuste puede reajustar los parámetros del filtro hasta que la nueva salida optima es obtenida. Los bloques funcionales en la figura son bastante generales y pueden ser seleccionados de diferentes formas para resolver problemas prácticos. El filtro, por 2 Aplicaciones del filtro de Kalman ejemplo, puede ser implementado de forma analógica o digital y puede tener "un canal de retardo", polo cero o estructura enrejada. Los parametros disponibles para ajustar pudieran ser la secuencia de valores impulsorespuesta o funciones mas complicadas de las frecuencias de respuesta del filtro . Similarmente, el circuito con el cual se valora la calidad de la salida del filtro puede tomar diferentes formas dependiendo de la aplicación del filtro adaptivo. La forma en la que la valoración de la calidad de salida es convertida en parametros modificados (ajustados). Las variaciones en la estructura del filtro, el mecanismo de valoración de calidad y la actualización adaptiva son comúnmente usados para catalogar las características de conducta, y así la aplicabilidad de varios filtros adaptivos. FILTROS ADAPTIVOS Los filtros adaptivos tienen una relación estrecha con los ecualizadores. En la practica muchos son de hecho, ecualizadores. Los filtros adaptivos son utilizados (como ecualizadores), para filtrar ruidos de banda estrecha y componentes senoidales discretos. La discusión de filtros adaptivos se hará considerando un filtro general con entradas múltiples. Tal filtro puede también ser usado para nulificar la dirección de aplicaciones de antena y para patrones de emisión. En este caso las entradas pueden llegar de múltiples antenas. En el sentido más convencional para un filtro transversal, las entradas múltiples son simplemente versiones retrasadas de una senal de entrada simple &e. las entradas se originan de un cambio de registro). comencemos por considerar un diagrama de bloques donde cada entrada X,I X2, X3, etc., son originadas de antenas separadas, micrófonos u otro sensor. el término dj es un segmento de la sena1 deseada. Las senales de entrada, Xj, contienen la senal deseada m á s el ruido. En algunas aplicaciones, una muestra de la senal deseada puede no ser habilitada, pero una muestra del ruido puede ser removida. 3 Aplicaciones del filtro de Kalman Podemos utilizar una configuaración donde se tenga la senal más el ruido, n l es el flujo de ruido correlacionado en algún camino con no, y1 es la salida del filtro adaptivo, y Ej es la senal de error minimizada. Para valores reales de X, sea la senal de entrada el vector: (8.93) La j-esima senal de salida es n y(j)=Cwi(j)L(j) i=l (8.94) Esta expresión puede ser más consistente si la escribimos en forma de matriz: y ( j >= W'(j>x(j> =x'(j)w(j) Para un caso donde n = 3 tenemos: 4 (8.95) Aplicaciones del filtro de Kalman o bien y ( j ) = W, ( j ) X ( j ) + W, ( j 1 X ( j 1 + W, ( j ) X, ( j 1 Sea la senal deseada de salida d(j). Entonces la senal de error es: 6 (j) = d ( j ) - y ( j )= d ( j ) - W T ( j ) X ( j ) (8.97) El cuadrado de la senal de error es: Realizando las multiplicaciones tenemos: Deseamos encontrar el error cuadrático medio el cual es: Aplicando el operador de esperanza a la ecuación (8.961, tenemos: E L 2(j)]= E[d2('j)- 2 DT(d, X)W(j) + W'('j) 5 @ (X, X)W(i)] (8.99) Aplicaciones del filtro de Kalman Note que los valores de W no son estadísticos y son constantes en la esperanza. Asimismo, definimos la cual es la correlación cruzada entre las senales de entrada y la respuesta deseada. Para un proceso de tiempo estacionario, tenemos: Una expresión similar para cada una de las entradas Definimos también la matriz de correlación cruzada de las variables de entrada como: (8.102) Puesto que ErrOr[E"CUad"U)Ies una función de segundo orden de la conexión de pesos, podemos visualízarlos como una superficie en forma de tazón (¡.e. Error[E"cuad"U)l es una función parabólica de conexión de pesos). El proceso 6 Aplicaciones del filtro de Kalman adaptivo es entonces la tarea de continuidad observada desde la parte superior del tazón. EI método de pendiente descendente usa el vector gradiente para determinar la dirección en la cual se mueve. Ahora tenemos: "delta"[E"cuad"(j)l= -2"theta"(d,X)+ 2"theta"(x,X)Wcj) (8.104) Derivando esta ecuación, notamos que el primer término, Error[d"cuad"(j)I, es una constante con respecto a W. HaSta entonces la derivada es cero. El segundo término es obtenido multiplicando fuera de la expresión y diferenciando con respecto a W para cada fila. El último término también puede ser obtenido por la multiplicación de las expresiones y diferenciándolas. Aquí podemos notar que "theta" sub(iK) (j) = "theta" Sub(Ki) (j). Ahora, para encontrar el vector de peso óptimo, w sub(LMS1, inicializamos el gradiente a cero. Esta condición es satisfecha si: "theta"(d,X) = "theta"(X,X)W SUb(LMS) (8.105) Solucionando para W sub(LMS1, tenemos W SUb(LMS1 = "theta"[-IlO(,X)"theta"(d,X) (8.106) Esta es la ecuación de Weiner Hopf en forma de matriz. El error mínimo cuadrado es obtenido sustituyendo la ecuación (8.106) en la ecuación (8..99): ErrOr[E"CUad"(j)ISUb(MIN) = Error[d"cuad"(j)l- Wtransl sub(LMS) "theta"(d,X) (8.107) La ecuación 8.106 puede resolverse directamente después de calcular la correlación de matrices. Usando este método, los coeficientes pueden determinarse rápidamente. Este procedimiento es llamado el algoritmo LMS. Aquí, adaptamos los coeficientes un paso a la vez usando la ecuación: 7 Aplicaciones del filtro de Kalman WCj +I) = w(j1- "mu" "grada" [E"-2"(j)l (8.108) donde WCj) = vector de pesos antes de la adaptación vector de pesos después de la adaptación "mu"= constante escalar que controla la razón de convergencia "grada"[E"-2"(j)I = estimación del vector gradiente con respecto aw - WCj + 1) = La estimación del gradiente está hecha para asumir que el gradiente del valor de la esperanza es igual al gradiente de su mismo error. Así, "grada"[E"-2"(j)l"aproximado" "grada"iE"2"(j)l Diferenciando "gradai1[E"2"(j)1= 2E(j) "grada"iE(j)l (8.11O) EI error fue previamente definido (ecuación 8.97) como Entonces el gradiente es: "grada"iE(j)l = -X(j) (8.111) puesto que d(j)no es una función de WCj). Sustituyendo esta en la ecuación (8.110) "grada"[E"2"(j)l = -2Eíj) XCj) (8.112) Finalmente, sustituimos la ecuación 8.112 en la ecuación 8.108 W(j + 1) = WCji + 2"mu"E(j)X(j1 8 (8.113) Aplicaciones del filtro de Kalman EI término E(j)X(j) es simplemente la senal de error multiplicada por cada entrada. Para el ejemplo considerado previamente, tenemos: Por lo tanto: El cual es el algoritmo de Widrow-HOff. LA NECESIDAD DE UN FILTRO ADAPTIVO Un filtro adaptivo es definido de manera muy general como un filtro cuyas características pueden ser modificadas para alcanzar algún fin u objetivo y generalmente es adaptado para llevar a cabo esta modificación automáticamente, sin la necesidad de una sustancial intervención del usuario (mientras no se requiera necesariamente). También usualmente se asume que la escala de tiempo de la modificación es muy lenta comparado con el ancho de banda de la senal que se esta filtrando. Implícitamente con esta suposición es que el disenador de un sistema puede en realidad usar un filtro adaptivo de tiempo invariable, solo si se conoce bastante acerca de la senal de entrada para disenar el filtro. Esta falta de conocimiento puede brotar desde una incertidumbre acerca de las características de la senal cuando el filtro es encendido; o porque las características de la senal de entrada pueden cambiar lentamente durante la operación de "filtración" . A falta de este conocimiento el disenador opta por un filtro "adaptivo" el cual puede "aprender" las características de la senal cuando se activa y que después pueden seguir cambios lentos en esas características. 9 Aplicaciones del filtro de Kalman FORMULACIÓN DEL ECUALIZADOR ADAPTIVO Durante el periodo de enseñanza inicial del ecualizador, una sucesión de símbolos d(l), dO),...,d(n), conocida como el arreglo del algoritmo del ecualizador es transmitida por un canal, dando como resultado una secuencia de salidas ecualizadas y(%, y(21, .......y(n). En un tiempo n , el ecualizador tiene N entradas almacenadas, esto lo denotamos por el vector Indicaríamos la dimensionalidad de los vectores y matrices por sus subscripciones. La ausencia de estos indicaría una sola dimensión; por ejemplo; y(n) es un escalar, x,(n) es un vector de dimensión NI A,(n) es una matriz con N renglones y p columnas. La transpuesta de la matriz se sobrescribe como T. El ecualizador conecta los coeficientes a un tiempo n que son representados por el vector C,(n - 1) y con salidas C,(n- l)'x,(n), que difiere de la salida ideal d(n) por un error e(n) Esta fórmula de la salida del ecualizador y su error difiere de distintos tipos de ecualizador. Los más obvios de estos ecualizadores son los lineales transversales con N conectores, por tal motivo {y(n)} es el canal de salida muestra para los símbolos de rotación. La estructura del ecualizador lineal es también relevante a reserva del algoritmo de detección de viterbi, en tal caso, d(n) en (2)es reemplazado por la combinación lineal de los datos recientes. Una variación de la estructura del ecualizador lineal, son los canales de salida muestra a tiempo p de los símbolos de rotación In,el vector se convierte en 10 Aplicaciones del filtro de Kalman (Ver referencia [Ill). En caso de una decidir retroalimentar el ecualizador con N , delante y N , retroalimentado por las conexiones xN(n) esto queda como donde N = N, + N , , {y(n)} son las muestras del canal de salida y {d(n)} es la decisión previa de los datos. Una aplicación a esta relación es cuando {d(n-I),.......,d(n-N , I} aparece en (IC), N , es el último datos que viene de un local, interfiriendo en la transmisión durante 2 caminos de comunicación simultáneamente, 1121. 11 i Aplicaciones del filtro de Kalman En este y en otras muchas estimaciones y aplicaciones predictivas, las salidas de los vectores xN(n) son tales que xN(n + 1) son obtenidas de xN(n) para satisfacer estos componentes, introduciendo el viejo componente p. Por ejemplo para p = 2 nuevos elementos y(n), d(n) entra la decisión de retroalimentar el ecualizador a un tiempo n +I mientras , lo permitan los elementos y(n-N,) y d(n-N, 1. Esta propiedad es crucial en el algoritmo “fuerte” de Kalman . Para unificar la subsecuente notación, definiremos un vector p-dimensional c,(n)que satisface a nuevos elementos p y un vector p,(n)especificando a p y eliminando los elementos viejos a un tiempo n + 1; por ejemplo; para un ecualizador lineal, 4 (n) = y(n) y pi (n) = y(n - N). Para la decisión retroalimentada del ecualizador, También definiremos un vector extendido Y,,,, (n) , con M = N + p dimensiones, tal que contiene elementos de c,(n) abriendo un campo de orden sobre los elementos de xN(n). Por ejemplo en el caso de una retroalimentación del ecualizador de decisión, con p = 2, 12 Aplicaciones del filtro de Kalman I ----- Las líneas punteadas denotan la partición de los vectores y las matrices. En general SMMes la permutación de matrices obvias y QMei re-arreglo de los elementos del vector extendido XM (n) para desplegar Cp (n) ,pp(n) ,X, (n) y xN(n + 1) en una forma de partición simple, es decir x S M M M Y Cada renglón y columna de S,, y QM I: :[ (n)= ---- y QMMcontiene un simple 1y son matrices identidad en el caso especial del ecualizador lineal. 13 (4) Aplicaciones del filtro de Kalman APLICACI~NDE UN ALGORITMO RECURSIVO CON MINIMOS CUADRADOS PARA UN ECUALIZADOR ADAPTIVO. El problema del ecualizador adaptivo es un clásico problema de mínimos cuadrados recursivos (131, i141. En particular requeriremos del algoritmo del ecualizador adaptivo para generar las conexiones de los coeficientes del vector C,(n) para el tiempo n tal que minimizamos la acumulación del error cuadrático. La minimización del vector es la solución de la ecuación de Wiener-Hopf: donde y 6> =o En la práctica, el parámetro 6 es fijo constante de valor pequeño positivo para asegurar la no singularidad de la matriz R,,(n). Entonces esto puede ser demostrado por (41,que en consecuencia C, (n) puede ser generada recursivamente de la siguiente manera: donde 14 Aplicaciones del filtro de Kalman La covarianza inversa de la matriz estimada RNN(n)-' mostrada en (IO) acelera grandemente la adaptación del ecualizador, independientemente características del canal de dispersión, i41,i51,i61 EI vector k,(n)puede de las ser generada por el algoritmo recursivo tal que produciría N por N de la matriz RNN(n1-I sin requerir explícitamente la matriz inversa. El algoritmo resultante, es el caso especial del algoritmo convencional de Kalman para los ecualizadores adaptivos, reportado por Godard . EI parámetro 6 devuelve salida que serían estimadas al final de un mal error cuadrático; el estado del algoritmo es trascendente y firme y no esta bien sensibilizado para la selección de 6. Esta complejidad del algoritmo, es proporcional a N2,se usa matrices de arista de N por N para computar k, (n). EI "Algoritmo fuerte de Kalman'' será presentado matemáticamente equivalente a esto, por la proeza de cambiar la propiedad para computar los vectores k, (n) recursivamente, sin necesidad de computar o almacenar alguna matriz de N por N. En el algoritmo de Kalman (convencional o fuerte) para el ecualizador adaptivo, todos los vectores previos xN(n) y los errores previos em) son acordados de igual peso en la determinación de conexiones de sus coeficientes estimados. Esta fuente de trabajo para la limitación-duración inicial del arranque de fase. De cualquier modo el estado fijo de operación usualmente requiere de estos vectores { X, (k) } para evitar la siguiente variación en el canal actual y evitar los problemas asociados con los errores digitales aleatorios. Un criterio conveniente a ejecutar estos requerimientos de caso de estudios, es minimizar exponencialmente el peso del error cuadrático en el tiempo n. 2 tX-k[d(k)-Cy(n)Tx,(k)] k=l 15 Aplicaciones del filtro de Kalrnan donde h es algún número positivo cerrado, pero menor que 1. El inverso de I - h es, aproximadamente hablando, la memoria de el algoritmo. La minimización del vector C, (n) es ahora C, ( n ) = R,,,, (n)-' [2 T k d ( k ) x ,( k ) ] k=i donde Note que (12a) implica (12b) EL ALGORITMO FUERTE DE KALMAN Los siguientes escalares, vectores y matrices son almacenadas y actualizadas durante cada iteración: (1) Matrices N por N; A , ( n ) y DNp(n)con valores iniciales A,(O) (2) Matriz N por N; Epp(n)con valor inicial Epp,(0)= dIpp (3) Vector con dimension M; k,(n) donde M=N+p (4) Vector con dimension p; .cP(n),sP(n)',qP(n),y ,up(n) (5) Vector con dimension N; m,(n) Los valores iniciales del vector k, (n)es 16 = D,(O) = O, Aplicaciones del filtro de Kalman k , (1) = o , (13) y todo xin) =O para n < =O. Entonces iniciamos con n = 1, k , (n + 1) este actualizado con el siguiente algoritmo: E,(n) = AE,(n - 1) + E , , ( T Z ) ' E ~ ( ~ ) ~ (Multiplicado por la permutación S, y QM simplificando la cuenta de permutaciones de los componentes de cada vector). La línea de división de la ecuación (18)indica una permutación. Partiendo de ~ , , k , ( n ) tenemos IO siguiente: 17 Aplicaciones del filtro de Kalman Una vez actualizada las conexiones del ecualizador con los coeficientes de cada vector CN(n + 1) entonces tomamos las ecuaciones (2)y (91, usando el vector KN(n + 1). EIconteo del numero de operaciones necesarias para calcular cada salida del ecualizador y su actualización, pone a cada coeficiente de las conexiones un nuevo indicativo como para el algoritmo, 7Np + Np2 + 3p2 + 2N + 4 / 3 p 3- p / 3 multiplicado (ecuaciones (21,(9)y (14)hasta la (22)) y 7Np + N p 2 + p 2 / 2+ An + 4 / 3 p 3+ 19/6p sumas. Estos conteos de divisiones como multiplicaciones y elementos Guassianos eliminan la matriz inversa p por p i151. La correspondencia de convencionalidadimplementación del algoritmo de Kalman es de 3N2+ 3N multiplicaciones y 2N2+ 2N + 1 sumas. Para un sencillo algoritmo gradiente tenemos que C, (n) es actualizado, acordado por: (g una constante) CN (n)= C, (n - 1) + ge(n9xN(n) muitipiicaciones y 2N sumas son necesarias para computar las salidas de ecualizador y actualizar los coeficientes de conexión. De este modo para el ecualizador lineal (p=i), el número de computaciones por intervalo de símbolo es de: 2~ Multiplicaciones gradiente simple Kalman fuerte KaIman co nvencionaI 2N 2N ION +4 12N+5 3N2+ 3N 2N2+ 2N + 1 Para N grande la complejidad del ecualizador con el algoritmo fuerte de Kalman es aproximadamente 5 veces más rápido que el del gradiente sencillo. La 18 Aplicaciones del filtro de Kalman convencionalidad-implementacióndel algoritmo de Kalman es de aproximadamente N veces menor que el del complejo algoritmo del gradiente simple. SIMULACION DE LOS RESULTADOS La figura 1 muestra un esquema de los datos de un sistema de comunicación con un ecualizador lineal cuyas conexiones de coeficientes podrían adaptarse acorde con otros algoritmos, por ejemplo el del fuerte de Kalman o el del algoritmo del gradiente simple. EI programa de simulación estaba dado para el lenguaje BASIC pero se puede usar otros tipos de lenguajes, y ejecutarlo sobre un tiempo-real. 4 niveles de datos pseudo-aleatorios estarán generando y verificando las continuas muestras de impulsos respondidos para 6600 bauds, sistemas de datos de comunicación modulados sobre VSB con 3455 Hz de acarreo de frecuencia, usado sobre un típico canal de teléfono. Los bits de rotación correrían a 13200 bits/c. Adicionando ruido de muestra Gaussianas sumaran al filtro de salida una simulación de señal-ruido en un radio de 31dB. Esta basebanda equivale a la respuesta de impulsos y radios de señalruido que estarán mapeados por el algoritmo de adaptación de Kalman 151. La característica de la frecuencia del canal del teléfono 151, estará anulando los profundos ruidos causados por la baja convergencia del algoritmo gradiente 121. ecualizador lineal tiene N = 31 conexiones. Estas salidas estarán substrayendo de referencia lineal la transmisión de datos que corren d(n), a la forma de la señal de error em). La secuencia del error em) {ecn)} y la secuencia de entradas del ecualizador {xcn)} estarán usadas para ajustar las conexiones del ecualizador adaptivamente, y mensurar el error cuadrático durante la adaptación, estarán desplegando como función, los números de cada iteración. Como muestra la figura 2. Note que (e2)>1 inicialmente porque los datos son (+-)1,(+-)3, con igual probabilidad. El El algoritmo de adaptación del gradiente sencillo esta implementado como en la ecuación (231, donde la constante g, se escoge para rotar la gran convergencia, como de 0.002. El canal de impulsos responde normalmente al tener unidad de energía. 19 ! Aplicaciones del filtro de Kalman El algoritmo fuerte de Kalman estará implementado con h = l . Porque este algoritmo es comenzado con todos los vectores k, A, etc. a cero y con x(n)=O para n < =O, esto se encontrará conveniente para empezar la actualización de k después de leerlo en el corte del primer pulso de datos recibido. Sin embargo para ambos algoritmos, los grandes resultados estarán obteniéndose por el comienzo de la conexión de los coeficientes del ecualizador actualizando antes la principal parte de los primeros pulsos de datos recibidos. "Iteración de Números", en la figura 2 se enumeran los comienzos de las conexiones de actualización de los coeficientes del ecualizador. El error cuadrático estará estimado por cada iteración como el promedio del peso y su exponencial. La memoria del peso exponencial estará sobre las órdenes de 10 intervalos de símbolos. Para ambos algoritmos adaptivos, el valor inicial de todos los coeficientes conectados serán cero. La convergencia del algoritmo del gradiente simple estará bien bajo porque el canal de frecuencia anulará las respuestas. El algoritmo de Kalman converge a un valor firme dentro de aproximadamente 80 intervalos. Esta convergencia comporta a este, como sería esperado un similar algoritmo convencial-implementado de kalman/Godard i51. EI algoritmo del ecualizador adaptivo de Kalman tiene una proporcional complejidad de N, justa en el caso de un algoritmo de gradiente simple, mientras que se tiene un rápida convergencia con el algoritmo de convencionalidadimplementación de Kalman, cuya complejidad es proporcional a N2. El rápido algoritmo es una factor matemáticamente equivalente para el algoritmo convencional de Kalman; el solamente requiere de esto (1) el cambiar la propiedad de entrada de los vectores isatisface en todos los ecualizadores conocidos o cancelaciones de aplicaciones de eco); y (2) que actualice el vector inicial k , (n)con todas la muestra previas x(n) asumidas a cero. El posterior requerimiento garantiza una condición de comienzo simple, con el argumento de inducción usado en el rápido algoritmo de derivación. Para un ecualizador lineal, el algoritmo rápido de Kalman requiere un número de operaciones por iteración solo aproximadamente 5 veces que para el algoritmo 20 Aplicaciones del filtro de Kalman de gradiente simple. Acordando la cantidad de números por operación tabulado anteriormente, una correspondencia del algoritmo convencional-implementación de Kalman requeriría aproximadamente 45 veces tal como muchas operaciones haría el algoritmo del gradiente. 21 Aplicaciones del filtro de Kalman Adición Gaussiana Muestra de ruido 4-Nivel (impuIsos) (31 conexiones) Fig. 1 Simulación de un sistema de transmisión de datos E R R O R Algoritmo del gradiente 1 C U A D R ,; Algoritmo Fuerte de 0.1 C O Error de mínimos 0..01 20 40 60 80 10 NUMERO DE ITERACIONES o 12 O Fig. 2 Convergencia del error cuadrático, todos los ecualizadores inicializados a cero 22 14 O { Aplicaciones del filtro de Kalman CAPlTuLO I1 23 Aplicaciones del filtro de Kalman EL COMBINADOR LINEAL DE IMPULSO-RESPUESTA-FINITO. AnaliZaremOS un filtro con una estructura de impulso-respuesta finita en tiempo y discreta (FIR) , basado en una línea de retardo y un conjunto de N coeficientes de ganancia ajustables Wo hasta WN-1 . La salida del filtro Y(x) es simplemente la suma de las entradas retardadas y escaladas dada por N-I Y(k) = C Wi X(k-i) ¡=O por conveniencia Y(x) también puede ser escrita como los puntos (o interiores) producto de 2 vectores : i e. Y(k) = xt (k) W donde W = [Wl,W2, ........, W(N-1) 1 t y X(k) = [X(k),X(k-l) ,...., X(k-N+1)1 t Esta estructura digital del filtro es una de las más simples. Esta es estable (para algún W dado) y los "impulsos" de respuesta están dados directamente por los elementos del vector W. El filtro mostrado en la figura también usa una forma simple de valoración de calidad de la senal filtrada. La salida del filtro Y(k) es comparada a una forma de onda deseada d(k), y alguna diferencia entre las dos constituye un error y por lo tanto una degradación de la calidad. La forma de onda d(k) es en algunas veces llamada la senal deseada, la referencia, o la forma de onda plantilla. 24 Aplicaciones del filtro de Kalman EI objetivo de seleccionar los coeficientes del filtro adaptivo es para forzar a ser Y(k) igual a d(k) exactamente. Uno pudiera cuestionar porque no simplemente pasamos d(k) en vez de Y(k), ya que es la senal deseada a la salida del filtro. Por ahora citaremos dos circunstancias donde la transmisión de d(k) en vez de Y(k) no es posible. En ciertas aplicaciones d(k) esta solo disponible durante una fase de entrenamiento en conjunción con una secuencia de valores de entrada predeterminada . En tales casos la adaptación es cesada durante el procesamiento de la actual secuencia de entrada X , para cada d(k) no esta disponible (es imposible). En otras aplicaciones d(k) es "medible" solo después de que calculamos Wk). En otras palabras, nuestra evaluación de calidad es derivada de una "perfecta" retrospectiva. Alguna diferencia entre d(k) y Yik) resulta en una senal de error e(k) (distinta de cero), la cual intentamos usar en los parámetros de las reglas de adaptación del filtro. Como hemos notado, el objetivo del ajuste es buscar un conjunto de coeficientes, un vector W; el cual reduce e(k), o alguna función de e(k) al valor más pequeno posible, cuando esta parametrización es alcanzada (y mantenida), es decir el filtro toma convergencia a el conjunto optimo d coeficientes representado por el vector W$. Nótese que si d(k) = xt(k)W$ , entonces W = W$implica que e(k) = O para todo k. Nuestras reglas de ajuste de parámetros son terminadas de adaptar si, cuando la solución optima previa W$ cambia a un nuevo valor. Cada algoritmo adaptivo es necesariamente recursivo; como nuevas entradas son procesadas y su calidad es evaluada, el filtro es actualizado, si es necesario. 25 Aplicaciones del filtro de Kalman ECUALIZACI~N DE UN CANAL USANDO UN FILTRO DE KALMAN PARA LA TRANSMISI~N RÁPIDA DE DATOS. continuación se muestra cómo el filtro de Kalman puede aplicarse en el problema de establecer la ganancia de ecualizadores transversales para minimizar la distorsión cuadrática (meansquare).En presencia de ruido y sin conocimiento previo del canal, el algoritmo del filtro conduce a una convergencia más rápida que otros métodos, su velocidad de convergencia depende solamente del número de recursos. Se dan resultados teóricos y se usa una simulación por computadora para corroborar la teoría y comparar el algoritmo con el método clásico. A Los sistemas de transmisión de datos generalmente usan canales de comunicación de voz de banda. Estos se caracterizan por un ancho de banda relativamente estrecho. (de 300 a 3000 Hz), una alta razón de ruido en la señal (aproximadamente de 20 a 39 dB), y una amplitud y distorsión de fase que varían lentamente con el tiempo. La alta velocidad de transmisión de datos requiere entonces ecualización. Muchos módems receptores usados en la actualidad, están equipados con un filtro para maximizar razón de señal/ruido y un ecualizador para minimizar la interferencia entre símbolos debida a una distorsión. Los ecualizadores generalmente son del tipo de filtro transversal, con ganancias dedicadas a minimizar algunos errores de criterio. Un proceso automático de ecualización requiere un período inicial de entrenamiento durante el cual el ecualizador reduce el error. En la "ecualización preestablecida", pulsos aislados son transmitidos previamente a la transmisión de datos, y las ganancias establecidas derivadas se mantienen constantes durante la transmisión de datos. Periódicamente, debe practicarse un corto lapso de entrenamiento para mantener actualizadas las ganancias. Una segunda clase de proceso de ecualización es conocido como "ecualización adaptiva". Aquí el ecualizador establecido es derivado de la señal recibida. Durante el período de entrenamiento, el ecualizador continuamente busca minimizar la desviación estándar de la muestra de su señal de salida de una referencia ideal generada internamente en sincronía en el receptor. Cuando la distorsión residual es lo suficientemente pequeña, los datos actuales pueden transmitirse. El ecualizador es entonces cambiado en el "modo dirigido de decisión", usando como referencia una señal reconstruida obtenida poniendo en el "umbral" la señal de salida del 26 Aplicaciones del filtro de Kalman ecualizador. La ecualización adaptiva tiene muchas ventajas sobre la ecualización preestablecida, estando entre ellas la capacidad de adaptación a los cambios en las características del canal durante la transmisión. Claramente, hay un retraso en la transmisión de datos proporcional a la longitud del período de entrenamiento, y es deseable un decremento en este retardo. Muchos algoritmos de ajuste han sido descritos en los libros, generalmente haciendo énfasis en la velocidad de convergencia. El bien conocido algoritmo de los mínimos cuadrados de Gersho, muestra que la velocidad de convergencia es determinada por los valores máximo y mínimo del espectro de poder de la señal sin ecualizar . Resultados similares para algoritmos más sofisticados se han reportado por Chang y Kobayashi. Aquí, un nuevo algoritmo, basado en la teoría de filtrado de Kalman, es propuesto para obtener una rápida convergencia en la ganancias de ecualizadores transversales para su óptima configuración. Un filtro de Kalman ha sido aplicado previamente al canal de ecualización por Lawrence y Kaufman, pero en una forma enteramente diferente, comenzando por el hecho de que en su estudio el ecualizador es reemplazado por el filtro. Mostraremos que la convergencia de mínimos cuadrados se obtiene, bajo condiciones de ruido, dentro de un número de iteraciones determinado solamente por el número de utilizaciones, sin previa información sobre el canal. Después de revisar los fundamentos de la teoría de Kalman, mostramos cómo aplicar ése filtrado en la ecualización y en la derivación de una expresión para la velocidad de convergencia. Finalmente, se usarán simulaciones por computadora para comprobar la validez de la teoría y para comparar el algoritmo propuesto con el método descendente. Se hace una comparación además con algunos otros sofisticados algoritmos. 27 I Aplicaciones del filtro de Kalman 28 I Aplicaciones del filtro de Kalman DIVERGENCIA EN EL FILTRO DE KALMAN Bajo ciertas condiciones, la órbita estimada por un filtro de Kalman tiene errores mucho más grandes que los predichos por la teoría. Este fenómeno es llamado divergencia, y proporciona la operación insatisfactoria del filtro de Kalman . La ejecución del filtro de Kalman bajo las condiciones actuales de operación puede degradarse seriamente en relación de la ejecución teórica indicada por el estado de la matriz de covarianza. EIfiltro de Kalman teóricamente produce una estimación cuya precisión va incrementándose con cada observación adicional que es procesada. La magnitud de los errores de estimación medida por el determinante de la matriz de covarianza del error de estimación es una función monótona decreciente del número de observaciones. Sin embargo, se ha observado que bajo las condiciones actuales de operación, los niveles de error en el filtro de kalman son significativamente más altos que los predichos teóricamente. Los errores pueden, de hecho, incrementarse continuamente aunque se estén procesando datos adicionales. La posibilidad de dicha inestabilidad o comportamiento divergente fue sugerida primero por Kalman. Más tarde fue notada por Pines y Knoll y otros en aplicación del filtro de Kalman a la navegaciónespacial y la determinación de Órbitas. CAUSAS DE LA DIVERGENCIA Una causa de la divergencia del filtro es la discrepancia entre el modelo matemático usado para derivar las ecuaciones del filtro y las actuales condiciones bajo las cuales el filtro debe operar, Ejemplos de tales discrepanciasson el descuido de los términos en el potencial gravitacional o un conocimiento inexacto de las constante en el potencial. otro origen de la divergencia son los errores en el coeficiente balístico o en el modelo de densidad de aire usado en el cálculo de la aceleración de arrastre. Tales errores se asumen como errores parciales. Ya que ellos afectan las ecuaciones dinámicas de movimiento, y para diferenciarlos de las observaciones parciales, estos errores se denominan parciales dinámicos. La figura 1 muestra la divergencia causada por un error del 25 % en la aceleración de arrastre. Un origen diferente de divergencia son los errores "round-off" 29 Aplicaciones del filtro de Kalman inherentes en la implementación de las ecuaciones del filtro en una computadora digital de palabras de longitud finita. La figura 2 muestra el efecto de los errores computacionales inducidos por una singular precisión aritmética (IBM 7090) en el filtro de Kalman. Una manifestación de los errores causados por la máquina ocurre en el cálculo del estado de la matriz de covarianza. Después de que el filtro de Kalman ha estado operando por algún tiempo, ésta matriz deja de ser definida positiva y simétrica. Los coeficientes relevantes del filtro calculados usando ésta matriz son entonces erróneos y, consecuentemente, la órbita estimada es incorrecta. J. E. Potter y R. Battin derivaron una variación del filtro de Kalman en la cual la matriz de covarianza permanece al menos simétrica no-negativa. Esta técnica elimina algunos, pero no todos los efectos de los errores computacionales y al mismo tiempo el filtro requiere un algoritmo más complejo. En filtros de procesamiento por lotes, los errores "round-off" en el filtro se vuelven evidentemente serios como errores computacionales en la operación de la matriz de inversión. CONTROL DE DIVERGENCIA Varias aproximaciones han sido sugeridas para prevenir la divergencia del filtro. Una aproximación sostiene que la divergencia ocurre cuando el filtro asigna un peso demasiado pequetío al último dato medido. Así el dato actual hace sólo una pequena corrección en la estimación, de hecho muy pequena, ésos errores crecen actualmente por la interacción natural de los errores de posición y velocidad. Un "arreglo" obvio es incrementar más o menos arbitrariamente el peso del dato actual. Tal arreglo implica incrementar la matriz de covarianza de estado mientras mantenemos constante el período de órbita incierto. La frecuencia y cantidad del incremento debe determinarse empíricamente, y puede emplearse tanto en filtros recursivos como en los no recursivos. Schmidt y Pines han sugerido modificaciones analíticas a las ecuaciones del filtro para representar parciales dinámicas sin incrementar el número de estados a ser estimados por el filtro. Además, Pines ha desarrollado una máquina simple para modificación del ruido basada en modelo asumido de los errores causados por "round-off" en la computadora digital. Otras técnicas, tales como el borrado del filtro 30 Aplicaciones del filtro de Kalman para guardar los elementos de la diagonal de la matriz de covarianza de estado en un "umbral" específico, fueron investigados por Holick. Ditto experimentó la divergencia en el corrector diferencial no-recursivo GeminiBayes, donde los problemas numéricos aparecen en la inversión de matrices no condicionadas, así como en el incumplimiento de parciales dinámicas. La ocurrencia de la divergencia en un filtro no recursivo no es sorprendente en vista de la equivalencia del filtro de Kalman y la mínima varianza no recursiva del filtro. Las modificaciones del filtro empleada por Ditto son similares a las de Schmidt y Pines. EJEMPLO ILUSTRATIVO. Para proporcionar al lector una comprensión intuitiva del problema de la divergencia, daremos un simple ejemplo analítico, donde el filtro de Kalman estima cómo diverge una trayectoria de la verdadera cuando el número de observaciones se incrementa. Éste fenómeno es ocasionado en este caso por la omisión de una de las componentes de estado del vector que describe el sistema. Esta situación ocurre generalmente in la práctica, ya sea deliberadamente para disminuir la complejidad de la representación del sistema, o bien de forma inadvertida porque se desconoce la existencia de ciertos estados. El ejemplo considerado aquí es la estimación de la altitud X de un vehículo de datos de altura. Un filtro de Kalman se diseña primeramente suponiendo que X es constante, ¡.e., el vehículo se encuentra ascendiendo (o cayendo) con una aceleración constante. Una pequeña modificación del filtro de Kalman muestra entonces la eliminación de ésta divergencia. Para diseñar el filtro de Kalman, asumimos que las medidas de altitud tienden a cero es independiente de los errores aleatorios de ruido n(k) que poseen una desviación estándar común O. En resumen, los errores por ruido se asumen acotados, In(k)J< =B. EIfiltro de Kalman estimado de la altitud está dado por: 31 I Aplicaciones del filtro de Kalman Donde o = desviación estándar del error por ruido de la altura ník), P(O-)=varianza de la altura estimada a priori; y los símbolos - y + que aparecen en las ecuaciones precedentes, denotan los estimados inmediatamente al previo e inmediatamente subsecuentes a una observación. Supongamos ahora que el vehículo, en vez de permanecer a una altitud constante, está ascendiendo con una aceleración constante y su trayectoria está descrita por: Supongamos también que las medidas de altitud son tomadas una vez por segundo. un fácil cálculo conduce para el filtro de Kalman, a la altitud observada después de N observaciones: X(N+)= X ( 0 )+ ~ VN 1 + --Cn(k) 2 N+l,=, Substrayéndolo de la trayectoria real: X(N) = X(0) + VN encontramos que para el error O(N) s(N)=X(N)-X(N+)=-+ VN - - C n (1k ) 2 N+1,=, y como los errores de ruido están acotados, 32 Aplicaciones del filtro de Kalman Por lo tanto, la desviación del filtro de Kalman estimada de la trayectoria verdadera, se incrementa decrementando N. 33 1 Aplicaciones del filtro de Kalman 34 Aplicaciones del filtro de Kalman /* DECLARACION DE VARIABLES GLOBALES Y PROTOTIPOS DEL PROGRAMA KALMAN *I # # # # # # # # # include <graphics.h > include <dos.h> include <stdio.h> include <conio.h> include < bi0s.h > include <stdlib.h > include <time.h > include < m0use.h > include < p0rtada.h > #define tam 14 #define muestras 14 #define N 14 #define M 100 #define NUmElem 14 #define NumBloCk 100 #define Numlter 60 #define NumLoop Corr 20 #define Num AR 5#define PI 3.131592 /* orden del predictor */ /* VARIABLES GLOBALES *I double HKítaml,XKítaml, Aítaml; double Qltamlltaml,Q1ltamlltaml; double sena1 Yímuestrasl; double senaIIDímuestras1; double Y2,Y3, D, error; /* salida del filtro */ double arrí2501; int opc = 1,uso; char cadfileoutl501; I* almacena el archivo donde se guardaran los datos */ char cadfileinAí501; /* almacena el archivo donde se leeran los datos de A */ char cadfileinXí501; /* almacena el archivo donde se leeran los datos de X */ char cadfileinD[501; /* almacena el archivo donde se leeran los datos de D */ char USO = 'O'; /* O si es Predictor o 1si es Estimador */ char AA = lo'; /* O si es aleatorio y 1si se toma de archivo A */ char XX = 'O'; /* O si es aleatorio y 1 si se toma de archiuvo X */ char DD='I'; /* 1si se toma de archiuvo D *I char NUMAi51,NUMXi51,NUMDí51; /* almacenan el numero de muestras */ char A I = 'O',DI = 'O'; /* PROTOTIPOS DE FUNCIONES */ /* K A L M A N . H *I void inicializa(void); VO id KALMAN(void); 35 Aplicaciones del filtro de Kalman void vector XK(d0uble nvovai); Void vector-maid); void proyecto(void); void fuera(void1; void correr (void); /* M O U S E . H */ void inicíal(void); void Iim-ve rt(voidi; vo id Iim horiz(void); void mugstra-ra t(voidi; void esconde rat(void1; void reporta edo(int *x,int *y,int *edo); void ¡ni grafiioid); void fletha(int x,int y,int clr); /* G R A F I C O S . H */ void menu(void); void mensaje-mouse(int x,int y); void mensaje tecla(void1; void detecta-%pc(int x,int y); void checa opcion(void1; void mueve opcion(int k); void limpia barra(void1; void limpiaflechas(void); void func(int xi,int yi,int xf,int yf); vo id haz-o pcio n(void); void mensaje tecla func2(void); void checa opcionfunc2(int x,int y); void uso comun mouse(int x,int y,int xi,int yi,int xf,int yf); void rango mouFe(int x,int y,int xi,int yi,int xf,int yf); void mueve opcion uso(int k); void limpia barra u?o(void); void comut¡l(int Kint y,char *cadl,char *cad2); void comun2(int x,int y,char *cadl,char *cad2); void flecha2(int x,int y,int color); void guarda imagemint x1,int y1,int x2,int y2,void **imagen); void botom-ht x,int y,char *cadena,int clr); void boton-press(int x, int y,char *cadena,int clr); void boton circ(int x,int y); void f ondotvoid); void esq-sup-izq(int x, int y); void esq-sup-der(int x,int y); void esq-inf izq(int x, int y); void esq-infIder(ínt x,int y); void Iineas(void); void cuadro2(void); void cuadro3(void); void barrido(int xí,int yi,int xf,int yf,int color); void mensaje(void); void ventana menu(int xi,int y¡, int xf, int yf); void barra(infx,int y,int anch,int ait); void barra1(int x,int y,int anch,int alt,int clr); 36 Aplicaciones del filtro de Kalman void barra2(int x,int y,int anch,int alü; void titülo(v0id); void cuad men(void1; void logotípo(int x,int y,int color1,int color2); Void f ondoazu I(void); void submenus(int x,int y,int x1,int yl); void captura arch ivo(void); void captura arch ivo2(void); void enbarra%nt x,int y,int anch,int alt,iit fondo); void captura(int x,int y,int tope,int clr,char *cadena); void caja(int x,int y, int taml); void advertencia(char *cadi ,char *cad2); void captura muestras(void); void captura-a leato rios(void); void sal¡ da(v6id); void integrantes(void1; void inicializa cadenas(void1; void rango mouse horizontal(intx,int y); void salidaentradatvoíd); void hacer instalacion(void); void restablece(void); void inicializacadenas0 { strcpy(cadfileout,""); strcpy(cadfileinA,""); strcpy(cadfileinx,""); Strcpy(cadfileinD,""); strcpy(NUMA, "'7; /* /* /* /* inicializa las cadenas de salida */ las rutas de los archivos y el */ numero de muestras a tomar para */ cada uno de los par metros */ StrCpY(NUMX,""); StrCpy(NUMD,""); 1 /* FUNCIONES GRAFICAS PARA EL AMBIENTE */ # include < ka1man.h > char entro = 'O'; char entrouso; char NUMTEMPi51; /* guardamos en el, el numero temp. de muestras */ void menuO{ int edo,i,x,y; /* in¡ grafO;*/ fondo o; fondo-azulo; /* cuadros de menu */ barra(10,29,100,418); /* barra(l5,34,90,408); cuadro del menu de opciones */ /* botones de opciones */ 37 Aplicaciones del filtro de Kalman boton(40,i 30,"US0",9); boton(40,170,"A",7); boton(40,21O,"X,7); boton(4OI250,"D",7); boton(40,290,"Run",7); boton(40,33O,"Clr",7); boton (40,370,"Exit",7); cuad-meno; mensajeo; titulo0; /* mensa& de opcion */ lOgotipo(562,431,I 5,O); muestra-ra to; while(1) { edo =O; i =o; reporta-edo(&x, &y,&edo); mensaje-m ouse(x,y); if(edo = = 1 I 1 bioskey(l)){ if(bioskey(1I){ i = bioskey(0); if(¡! = 7181){ 1 1 /* si se hizo un click izq o un enter */ mueve opcion(i); mensaje teciao; checa-opciono; if(edo= =I) { detectaopc(x,y); if(opc ! = O) checa-o pcionO; /* si es un click */ 1 if ((i= = 7181 1 I edo= =I)) { switch(opc1 { case 1: entrouso='O'; uso=1; boton-p ress(40,I30,"USO",YE LLOW); setcolor(7); KaI man''I; outtextxy(35,457,"Forma en que se usar el algoritmo de edo =O; func(l30,100,250,170); boton(40,i30,"US0",9); break; case 2: entrouso = 'O'; uso = 1 ; if (DI = = 'O'){ boton-press(40,17O,"A",YELLOW); setcolor(7); outtextxy(35,457,"Numeros aleatorios"); A I ='I1; 38 Aplicaciones del filtro de Kalman func~1301135,250,205); boton(40,17O,"A",9); boton-preSS(40,250,"D",7); 1 else { sound(1800);de lay(100); sound (2000); de lay(lO0); nosoundo; break; 1 case 3: entrouso = '0'; uso = I; boton~press(40,21 O,"X,YELLOW); setcolor(7); case 4: outtextxy(35,457,"Pesos de la entrada"); func(l30,I 70,250,240); boton(40,21O,"X",9); break; if ( A l = = 'O') { entrouso = 'O';uso = 1; boton press(40,250,"D",YELLOW); setco16r(7); outtextxy(35,457,"Numeros de correlaciCn"); D I ='I1; boton press(40,170,"A",7); boton~40,250,"D",9); }else { soundQ100); delay(l00); sound (2900); de lay(lO0); nosoundO; 1 break; case 5: esconde rato; boton p~ess(40,290,"Run",YELLOW); setco16r(7); outtextxy(35,457,"lnicialos calculos de Kalman"); correro; inicializa cadenaso; /* inicializa las cadenas */ muestra1t-atO; boton(40,290,"Run",9); break; case 6: esconde rato; boton pFe~s(40,330,~~cl r",YE LLOW); barrid6(357,70,595,175,5); restableceO; boton(40,330,"Clr",9); muestra-ra to; break; case 7: entrouso = 'O'; boton preSS(40,370,"EX¡t",RED); salida-%ntradao; 39 Aplicaciones del filtro de Kalman boton(40,370,"Exit",9); break; case 8: esconde-rato; integranteso; muestra-rato; 1; 1 break; } /* endif */ }/* enddo */ /* MENUGENERAL */ /* muestra los mensajes en la barra de estado, de cada una de las opciones cuando estos son tocados con el cursor del mouse */ void mensaje-mouse(int x,int y){ > = 40 && X < = 70 1 { if(y > = 120 & & y < = 140 && entro! ='Ii){ if(X limpia-barrao; setcolor(l5); outtextxy(35,457,"FOrma en que se usar el algoritmo de Kalman"); entro='I'; }else if(y > = 160 && y < = 180 && entro! ='2'){ limpia-barra(); setcolor(l5); outtextxy(35,457,"Numeros aleatorios"); entro = '2'; }else if(y > = 200 && y < = 220 && entro! ='3'){ limpia barrao; setcoior(i 5); outtextxy(35,457,"Pesos de la entrada"); entro = '3'; }else if(y > = 240 && y < = 260 && entro! ='4'){ limpia-barrao; setcolor(l5); outtextxy(35,457,"Numeros de correlaciCn"); entro = '4'; }else if(y > = 280 && y < = 300 && entro! ='5'){ limpia barrao; setcoior(i 5); outtextxy(35,457,"lnicialos caiculos de Kalman"); entro = '5'; 1e ise ifcy > = 320 && y < = 340 && entro! = '67{ Iimpia-ba rrao ; 40 Aplicaciones del filtro de Kalman setcolor(l5); outtextxy(35,457,"Restablece valores al determinado"); entro = '6'; } else if(Y > = 360 & & y < = 380 && entro! ='7'){ limpia barra(); setcoi6r(i 5); outtextxy(35,457,"Calir del programa"); entro = '7'; 1 }/*else limpia-barra(); */ /* muestra los mensajes en la barra de estado, de cada una de las opciones cuando se mueve con las flechas del cursor */ void mensaje-tecla0 { limpia barrao; setcdor(l5); switch(opc){ case I: outtextxy(35,457,"Forma en que se usar el algoritmo de KaIman"1; break; case 2: outtextxy(35,457,"Numeros aleatorios"); break; case 3: outtextxy(35,457,"Pesos de la entrada"); break; case 4: outtextxy(35,457,"Numerosde correlacicn"); break; case 5: outtextxy(35,457,"1nícíalos calculos de Kaltnan"); break; case 6: outtextxy(35,457,"Restablecevalores al determinado"); break; case 7: outtextxy(35,457,"Calir del programa"); /* outtextxy(35,457,"Lista de colaboradores en el programa");*/ break; 1 /* 1 checa el rango del mouse cuando se pulsa el boton izquierdo */ void detecta-opc(int x,int y){ if(X>=7&&X<=28){ if(y > = 5 && y < = 27) OPC = 7; 41 Aplicaciones del filtro de Kalman 1 elseif(x>=603 &&x<=622 & & y > = 5 &&y<=27) OPC =8; else > =40 && X < =70 1 { ¡f(y > = 120 & & y < = 140) OPC = 1; if(X else if(y > = 160 &&y < = 180) else OPC = 2; if(y > = 200 &&y < = 220) opc = 3; else if(y > = 240 & & y < = 260) OPC = 4; else if(y > = 280 &&y else < = 300) OPC = 5; if(y > = 320 & & y < = 340) OPC = 6; else if(y > = 320 & & y < = 370) OPC = 7; else opc=O; }else opc=O; /* cambia las opciones del menu cuando estos son movidos con las flechas del cursor */ void mueve-opcion(int k){ switch(k1 { case 18432 : ope; if(OpC = = 2 && D I = = '1'1 OpC--; if(OpC= =4 && A I = ='I1)OpC--; break; case 20480 : opc + + ; +; +; i f ( O p C = = 2 && D I = ='I1) OpC+ if(OpC= =4 &&Al = ='I1) OpC+ break; case 19200 : ope; i f ( O p C = = 2 && D I = ='I1) OpC--; if(OpC= =4 && A I = = ' I 7 OpC--; 1 break case 19712 : opc+ +; i f ( O p C = = 2 & & D I = =='l') OpC+ +; if(OpC= =4 & & A l = ='I1) OpC+ +; break; if(opc < 1)opc=7; mope > 7) opc=1; 42 Aplicaciones del filtro de Kalman /* refresca la opcion que fu, pulsada con el mouse, limpiando las flechas indicadoras y marcando la que esta activa */ void checa-opciono { switch(opc){ case 1: esconde-rato; limpia flechaso; flecha~40,130,9); muestra-ra to; break; case 2: esconde-rato; if(D1 = ='O'){ l i m p i a flechaso; flecha(40,170,9); 1 muestra-rato; break; case 3: esconde-rato; l i m p i a flechaso; f lecha(40,210,9); muestra-rato; break; case 4: esconde rato; if ( A l = ='Ot){ limpia-f lechaso; f lecha(40,250,9); 1 1 1 muestra-rato; break; case 5: esconde-rato; limpia flechaso; f lecha~40,290,9); muestra-rato; break; case 6: esconde-rato; limpia flechaso; flecha(40,330,9); muestra-ra tO; break; case 7: esconde-rato; limpia flechaso; f lecha~40,370, RED); muestra-rato; break; /* cambia el color de las flecha de selecciCn */ void flechamt x,int y,int clr) { esconde-rato; setcolor(DARKGRAY); line(x+ 35,~-3,x+39,y+4); 43 Aplicaciones del filtro de Kalman line(x + 35,y-3,x + 42,y-3); line(x+ 39,y + 4,x + 42,y-3); setfiIlstyle(S0LID FILL,clr); floodfill(x+ 39,~,8); setcolor(WHITE); iine(x+ 39,y+4,x+42,y-3); 1 muestra-rato; void limpia-barra(){ setcolor(7); /* /* limpia barra de estado */ outtextxy(35,457,"Numeros aleatorios"); outtextxy(35,457,"Pesos de la entrada"); outtextxy(35,457,"Numeros de correlaciCn"); outtextxy(35,457,"1nicialos calculos de Kalman"); outtextxy(35,457,"Salir del programa"); outtextxy(35,457,"Forma en que se usar el algoritmo de Kalman"); outtextxy(35,457,"Restablecevalores al determinado"); outtextxy(35,457,"Lísta de colaboradores en el programa");*/ 1 void Iimpia-flechasO{ flecha(40,130,7); if(D1= = 'O') flecha(40,170,7); f lecha(40,210,7); if ( A l = = 'O') f lecha(40,250,7); /* limpia las flecha de indicacion */ f lecha(40,290,7); f lecha(40,330,7); f lecha(40,370,7); 1 /* S U B M E N U S */ void func(int xi,int yi,int xf,int yf) { int edo =O,x,y,tecla = O; void *dibujol; esconde-ra to; guarda-imagen(xi-l0,yi-l0,xf + 25,yf + IO,&dibujol); submenus(xi,yi,xf ,yf); muestra-rato; while(edo! =2 && tecla ! = 283) { edo =O; tecla =O; reporta edo(&x, &y, &edo); uso-comun-mouse(x,y,xi,yi,xf + 20,yf + 5); 44 Aplicaciones del filtro de Kalman if(edo = = 1 I I bioskey(l)){/* si se hizo un click izq o un enter */ if(bioskey(1)){ tecla = bioskey(0); if(tecla! = 7181){ mueve opcion uso(tecla); mensaje-tecla 3unc20; checa-opcion-func2(xi + 20,yi + I5); 1 1 if(edo= = 1) { /* si es un click */ rango mouse(x,y,xi,yi,xf + 20,yf + 5); if(usoT= O) checa~opcion~func2(xi + 20,yi + 15); if (tecla = = 7181 haz-opciono; I I edo= =I 1 1 )/* enddo */ 1 esconde-rato; putimage(xi-I0,yí-I0,di bujol ,O); free(dibujo1); muestra rato; limpia-barra-us00; void haz opcionO{ /* realiza la funcion de cada una de las opciones */ switch6pc){ case I: switch(uso) { case 1: setcolor(5); 0uttextxy(357,7OJ"Es t i m a d o r"); setcolor(l4); outtextxy(357,70,"P r e d i c t o r"); uso = 'O'; captur a archivoO; */ break; case 2: setcolor(5); outtextxy(357,70,"P r e d i c t o r"); setcolor(l4); Outtextxy(357,70,"Es t i m a d o r"); /* captura archívoo; */ /* uso= '1'; 1; break; break; case 2: switch(uso1{ case 1: setcolor(5); 45 Aplicaciones del filtro de Kalman ~~~~~~~~~~~~~,IOO,"UUUUUUUUUUUUUUUUUUUUUUUUUUUUU~~~; setcolor(l4); outtextxy(357,100,"Leyendo disco"); capturaarchivo20; AA = 'O'; break; case 2: setcolor(5); OU~~~X~~~(~~~,IOO,~~UUUUUUUUUUUUUUUUUUUUUUU~UUUUU~); setcolor(l4); outtextxy(357,I00,"AIeatorio"); captura-aleatorios0; AA = '1'; break; 1; case 3: switch(uso){ break; case 1: setcolor(5); outtextxy(357,i ~O,"UUUUUUUUUUUUUUUU~ÜUUUÜUUUUUUU~~); setcolor(l4); outtextxy(357,130,"Leyen do disco"); captur a archívo20; )o( = 'O'; ' break; case 2: setcolor(5); outtextxy(357,i ~ O , ' ' U U U U U U U U U U U U U U U ~ U U U ~ U U ~ ~ U U U ~ U ~ ~ ~ ; setcolor(l4); outtextxy(357,i 30,"Aleatorio"); captura-aleatoriow; )o(='I'; 1; I* break; break; case 4: switch(uso){ case 1: setcolor(5); outtextxy(357,160,"UUUUUUUUUUUUUUUUUUUU setcolor(l4); UUUUUUÜ"1; outtextxy(357,16O,"Leyendodisco"); captura-a rchivo20; DD = 'O'; break; case 2: setcolor(5); outtextxy(357,i 60,"UUUUUUÜUUUUUUUUUUUU~UÜUUUU UU0"); setcolor(l4); outtextxy(357,160,"Aleatorio"); capturaaleatorios0; DD='I'; break; 46 1 Aplicaciones del filtro de Kalman 1; break;*/ void mensaje tecla func20{ /* muestra el mensaje de funcionamiento */ IirnpiaIbarraIusoO; /* de cada una de las opciones */ setcolor(l5); switch(opc){ case I: switch(uso){ case I: outtextxy(35,457,"EIprograma se usar en modo de Predictor"); break; case 2: o~ttextxy(35~457,"El programa se usar en modo de Estimador"); break; 1; break; default: switch(uso){ case I: case 2: aleatoríamente"); 1; outtextxy(35,457,"Losdatos se leeran de disco"); break; outtextxy(35,457,"Losdatos se generar n break; break; void checa~opcion~func2(int x,int y) { /* de acuerdo a la opcion en que se dio click se muestra su mensaje */ switchiopc){ case I: switch(uso){ Predictor"); E s timador"1; case 1: esconde rato; comunl (x,y,"Priidictor","Estimador"); outtextxy(35,457,"El programa se usar en modo de muestra-rato; break; case 2: esconde-rato; comun2(x,y+ 30,"Estimador","Predictor"); Outtextxy(35,457,"EIprograma se usar en modo de muestra-ra to; break 47 1; break; defauIt: switch(uso){ case 1: esconde-rato; comunl(x,y,"Leer disco","Aleatorio"); outtextxy(35,457,"Losdatos se leeran de disco"); muestra-rato; break; case 2: esconde-rato; comun2(xfy+ 30,"Aleatorio","Leerdisco"); o~ttextxy(35~457,"Los datos se generar n aleatoriamente"); muestra-ra to; break; 1; break; void uso-comun-mouse(int x, int y,int xi,int yi,int xf,int yf){ / * checa las areas en el que se encuentra el puntero del mouse */ /* y pone el mensaje correspondiente a cada una de las areas dentro de la */ /* barra de estado */ í f ( X > X i && X < X f && y>yi && y<yf) { if(y>yi && y<yi+35 && entrouso != 'Ii){ Iimpia-barra-uso O; entrouso = '1'; de Predictor"); esconde rato; switch(opc){ case 1: comunl (xi + 20,yi + 15,"Predictor","Est~mador"~; OUtteXtx~(35~457,"El programa se usar en modo 1 break; default comunl (xi+ 20,yi + 15,"Leer disco","Aleatorio"); outtextxy(35,457,"Los datos se leeran de disco"); break; muestra-ra tO; 1 if(y>yi+35 && y<yf && entrouso ! = '29{ limpia-barra-usoO; entrouso = '2'; esconde rato; switch(opc){ case 1: comun2(xi + 20,yi + 45,"Estimador","Predictor"); outtextxy(35,457,"EIprograma se usar en modo de Estimador"); break; default comun2(xi + 20,yi + 45,"Aleatorio","Leer disco"); outtextxy(35,457,"Losdatos se generar n aleatoriamente"); 48 Aplicaciones del filtro de Kalman break; 1 muestra-rato; void rango mouse(int x,int y,int xi,int yi,int xf,int yf){ /* indica e f q u e area nos encontramos cuando pasamos el puntero del mouse */ / * y se halla hecho click, en ese momento cancelamos la entrada nuevamente */ if(X>Xi && x<xf && y>yi && y<yR { if(y>yi &&y<yi+35)uso=l; else if(y>yi+35 &&y<yf)us0=2; else uso = O; )else USO=O; 1 void mueveppcion-uso(int k){ /* checa la tecla que se pulso y avanza o retorcede en el cuadro de menu */ cwitch(k1 { case 18432 : uso-; break; case 20480 : uso + + ; break; 1 case 19712 : uso+ +; break; case 19200 : uso-; break < 1)us0=2; if(us0 > 2) uso = 1; íf(US0 1 void limpia barra-usoO{ /* limpia barra de estado */ setco Ior(7); outtextxy(35,457,"Presione el boton derecho del mouse para salir C [ESCI"); OUtteXt~(35,457,"EI programa se usar en modo de Estimador"); OUtteXtXy(35,457,"EI programa se usar en modo de Predictor"); outtextxy(35,457,"Los datos se generar n aleatoriamente"); outtextxy(35,457,"Los datos se leeran de disco"); void comunl(int x,int y,char *cadl,char *cad2){ /* dibuja la simulacion de un boton selecionado con el cambio de color en las */ /* flechas de seieccíon */ setcolor(BLACK); outtextxy(x,y+ 30,cad2); 49 Aplicaciones del filtro de Kalman flecha2(x + 95,y,l5); SetfiIlStyle(SOLID_FILL,7); /* rellena de gris la no opcion */ floodfill(x+ 9 7 , ~ +35,7); SetCO IO r(WHITE); setf iIIstyle(S0LID FILL, WHITE); outtextxy(x,y,cacll); flecha2(x 95,y,l5); floodfill(x+97,y 5,WHITE); /* dentro del triangulo*/ + 1 + void flecha2(int x,int y,int color){ /* limpia las flechas para una nueva seleccion */ setcolor(co1or); line(x,y+4,x+4,y); Iine(x,y 4,x + 4,y 8); line(x 4,y,x + 4,y 8); + + + + 1 void comun2(int x,int y,char *cadl,char *cad2){ /* lo mismo que comunl, pero en funcion inversa */ f lecha2(x + 95,Y,l5); setfillstyle(S0LID FILL,7); floodfill(x+ 97,V25,7); /* rellena de gris la no opcion*/ SetCO IO r(WHITE); setf iIlstyle(S0LID FILL,WHITE); outtextxy(x,y, cad11; flecha2(x + 95,y,l5); floodfill(x + 97,y + 5,WHITE); /* dentro del triangulo*/ 1 void submenus(int x,int y,int x1,int y l ) { /* de acuerdo a la opcion hecha en el menu principal se muestra su submenu */ ventana menu(x,y,xl ,yl); Setcolor~BLACK); switch(opc){ case 1:outtextxy(x + 20,y + 15,"Predictor"); outtextxy(x + 20,y + 45,"Estimador"); break default: outtextxy(x+ 20,y+ 15,"~eerdisco"); outtextxy(x + 20,y + 45,"Aleatorio"); break; 1 setcolor(LIGHTBLUE); line(x+ 20,y+ 25,x1-20,yi-45); Iine(x+ 20,y + 55x1 -20,yi -5); I 50 Aplicaciones del filtro de Kalman 1 SetfiIlStyle(SOLID-FILL,BLUE); setcolor(l5); outtextxy(35,457,"Presioneel boton derecho del mouse para salir C [ESCI"); /* FUNCIONES DE CAPTURA PARA ARCHIVOS */ /* funcion que pinta la caja de captura */ void caja(int x,int y, int tam%{ int tamax; /* tam es el numero de caracteres */ tamax= (tam1*8) + 5; /* tamano del caja con la holgura */ /* cuadro exterior de la caja, de color blanco */ setcolor(l5); line(x-l5,y-IO,x+ tamax+8,y-10); line(x-I5,y-IO,X-l5,y+ 25); Iine(x-l5,y+25,x+ tamax+8,y+25); line(x+ tamax+8,y-IO,x+ tamax+8,y+25); / * rellenamos cuadro exterior */ SetfiIlStyle(S0LID FILL, LIGHTGRAY); flood fill(^ + 10,Y 710,151; /* efecto hundido de la caja de captura */ SetCOlOrNVHITE); line(x-5,y+15,x+tamax,y+15); line(x+ tamax,y,x+ tamax,y+l5); setcolor(0); line(x-5,y,x + tamax,y); line(x-5,y,x-5,y + 15); 1 void captura(int x,int y,int tope,int clr,char *cadena) { int i=O,z =O,k =O,band = 1,pos =O,malo = 1; char cad[21fcadli1001; char tecla =O; caja(x,y,tope); /* se pinta la caja de captura */ setcolor(clr); cad11I = 'BO'; setcolortclr); /* marca de inicio de captura (cursor) */ Iine(x+ (IO*i),y + 12,x+ ( I O * i ) + 10,y + 12); /* mientras no presione <ENTER> */ 51 Aplicaciones del filtro de Kalman while(tecla != 13) { malo = 1; while (malo) { /* mientra tecla no valida */ tecla = getchO; if (tecla = = 'ix0') tecla = getcho; else malo = O; if (((tecla = = 8) && i > O) 1 /* si backspace y hay letras */ { I--'I cadIOl =cadena[¡]; cadena[¡] = 'ix0'; if (í < (tope-1)) /* borra caracter hacia la izquierda */ { /* si no hay recorrido */ setcolor(LIGHTGRAY); outtextxy(x+ (8*i),y+4,cad); Iine(x + (8*i) + 10,y + 12,x + (8*i)+ 20,y + 121; setcolor(clr); Iine(x+ (8*i),Y+ 12,x+ (8*í) +10,y+12); 1 1 if (i < (tope-1)) { /* si no esta lleno el cuadro de captura*/ if ((tecla > = 48 &&tecla < = 57) I !(tecla > = 97 &&tecla < = 122) 1 1 (tecla > = 65 &&tecla < = 90)) { cadenaiil= tecla; /* si letra o numero */ cad[Ol =tecla; outtextxy(x+ (8*i),y+4,cad); /* pinta tecla presionada */ setcolor(LIGHTGRAY); /* avanza el cursor */ line(x+ (8*¡),y+ 12,x + (8*i)+ 8,y + 12); i+ +; setcolor(clr1; line(x+ (8*i),y+ 12,x + (8*i)+ 8,y + 12); 1 if ((tecla = = 46 I I tecla = = 58 I I tecla = = 92) && i > = I1 { cadenaIil= tecla; /* si o */ cad[Ol =tecla; outtextxy(x+ (8*i),y+4,cad); /* pinta tecla presionada */ setcolor(LICHTCRAY); /* y avanza el cursor */ line(x + (8*i),y + 12,x + (8*i) + 8,y + 12); '\I, I+ I.' ':I +; setcolor(clr); 52 Aplicaciones del filtro de Kalman line(x+ (8*¡),Y+ 12,X + (8*i)+ 8,y + 12); 1 } /* si tam else < = tope*/ /* si cuadro lleno */ /* hacemos efecto de barrido */ if ((tecla > = 48 &&tecla < = 57) I J(tecla> = 97 &&tecla < = (tecla > = 65 && tecla < = 90)) { { 122) I I cadena[¡] =tecla; cadena[¡ + 11= 7x0'; /* si letra o numero * / cad101=tecla; /* setcolor(L1GHTGRAY): l¡neo(+ (8*(POS-l)),Y+ 12,X+ (8*(POS-l))+ 8,y + 12);*/ I + +; /* setco lor(clr); linea( + (8*(pOS-l)),Y+ 12,X+ (8*(POS-l))+ 8,y + 12); */ 1 if ((tecla = = 46 { 1 I tecla == cadena[¡] =tecla; /* si cadena[¡ + 11= 'UtO'; cad[Ol= tecla; 58 '\I, I.' I I tecla o I:' == 92) && i */ setcolor(LIGHTGRAY); Iine(x+(8*(pos-1)),y+12,x+(8*(pos-l)) +8,y+12); i+ +; setcolor(clr); Iine(x + (8*(pOS-l)),Y+12,X + (8*(pOS-l))+ 8,V + 12); 1 if (band) { band =O; /* si primera vez de barrido */ pos = i; 1 else{ /* si hay mas barrido */ SetCO lOr(L1GHTGRAY); outtextxy(x,y setcolor(clr); + 4,cadl); 1 caja(x,y,tope); /* se pinta la caja de captura */ setcolor(clr); /* pinta cursor */ linea(+ (8*(POS-l)),Y+12,X+ (8*(pOS-l))+8,y+12); /* copia subcadena a mostrar */ z=o; O for(k=(i-(tope-l));k < = i; k + { cadi [zl = cadena[kl; z + +; 53 +1 > = I1 Aplicaciones del filtro de Kalman 1 cad1[topel= '\xO'; /* muestra subcadena */ outtextxy(x,y + 4,cadl); /* sonido cuando barre una caracter a la izquierda */ sound(1000); /* delay(200); nosoundo;*/ 1 cadena[¡] 'ix0'; = 1 /* fin de cadena */ 1 void captura-a rchivoo{ char final[30l,cadenal[501; char band = IF'; struct ffblk a; char unídad~3l,dír[64l,nombrea[9l,extI51; strcpy(cadena1,""); s t rcpy(fi nai,l1UUUUUUUUUUUUUUUUUUUUUUUUUUUUUti); esconde-rato; enbarra2(300,250,300,100,7); setcolor(0); outtextxy(320,270,"Nombre del archivo donde se guar-"); outtextxy(320,280,"dar n los calculos hechos por el "1; outtextxy(320,290," programa:"); /* while(band = ='F'){ setcolor(7); /* borramos lo anterior escrito */ O ~ ~ ~ ~ X ~ ~ ~ ( ~ ~ O , ~ I ~ , " U U U U U U UUUUU"); UUUUUUUUUUUU outtextxy(340,315," '7; captura(340,31O, 25,0,cadenal); -s plitpath(cadena1,unidad,dir,nombrea,ext);*/ if(strcmp(cadena1,cadf ileout)! = O){ /* checamos que no sea enter y que se escriba el nombre del archivo */ advertenCia("FaV0rde introducir el dísco","en la unidad correspondiente"); if (strcmp(cadena1,Y= =O && strcmp(cadfileout,"")!=O) band = 'V'; /* oprimio enter con opcion */ else if(strcmp(nombrea,"")!=O) if(findfirst(cadenal,&a,O)= =O) /* vemos si existe el file */ advertencia("E1nombre del archivo ya se","encuentra, intente con otro"); else{ strcpy(cadfileout,cadenal); /* nueva ruta y file */ band = V; 1 else advertencia(" Falta nombre del archivo",""); 54 Aplicaciones del filtro de Kalman }else if(strcmp(cadfileout,"")= =O) advertencia("Fav0rde introducir la ruta"," y el nombre del archivo"); else{ advertencia("Favorde introducir el disco","en la unidad correspondiente"); band = 'VI; 1 1 barrido(300,250,600,350,1~; setcolor(5); outtextxy(357,85,f inaI); setcolor(l4); strcpy(final,Y; strnc py(fi nal,cadf ileout,29); outtextxy(357,85,final); 1 muestra-rato; void captura-archivo2O{ /* usamos una cadena temporal (cadtemp)para guardar el contenido */ /* de las variables globales cadfilein-, para que estas no cambien */ char unidad[3l,dir[64l,nombrea~9l,ext~51; char cadena11501,fina lI301,cadtem pi501; char band = IF'; struct ffblk a; esconde-rato; enbarra2(350,250,250,85,7); setcoior(0); /* muestra el cuadro de dialogo */ outtextxy(370,270,"Nombre del archivo donde se"); outtextxy(370,280," tomar n los datos: "1; switch(opc){ /* inicializa la cadena temporal */ case 2: strcpy(cadtemp,cadfileinA); break; case 3: strcpy(cadtemp,cadfileinX); break; case 4: strcpy(cadtemp,cadfíleinD); break; 1 while(band = ='F'){ setcolor(7); /* limpia la zona de escritura */ O~tt~Xtx~(380,304,"UuuUuUuuuuUUuuuUU uUUUUUri); Outtextxy(380,305," "1; captura(380,300,25,0,cadenal~; if(strcmp(cadena1,cadtemp)! =O){ /* checamos que no sea enter y que se escriba el nombre del archivo */ 55 Aplicaciones del filtro de Kalman advertencia("Favorde introducir el disco","en la unidad correspondiente"); if (strcmp(cadena1,"") = =O && StrCmp(CadfileinA,"")!=O) band = 'Vi; /* oprimio enter con opcion */ else if(strcmp(nombrea,"")!=O) if(findfirst(cadenal,&a,O)! =O) /* vemos si existe el file */ advertenC¡a("Elnombre del archivo no se","encuentra, intente otra vez"); else{ strcpy(cadtemp,cadenal); /* nueva ruta y file */ band = 'Vi; 1 else advertencia(" Falta nombre del archivo",""); }else if(strcmp(cadtemp,"")= =O) advertencia("Favorde introducir la ruta"," y el nombre del archivo"); else{ advertencia("Favorde introducir el disco","en la unidad correspondiente"); band = 'V'; 1 1 captura muestracO; /* muestra la captura del numero de muestras */ switch(opc){ /* guardamos en las variables globales lo nuevo */ case 2: strCpy(cadfileinA,cadtemp); strcpy(NUMA,NUMTEMPI; break; case 3: strcpy(cadfileinX,cadtemp); Strcpy(NUMX, NUMTEMPI; break; case 4: strcpy(cadfileinD,cadtemp); strcpyiNUMDl NUMTEMPI; break; 1 barrido(350,250,600,375,1); /* cierra el dialogo */ /* aparece los nuevos requerimientos */ switch(opc){ case 2: setcolor(5); outtextxy(357,100,final); outtextxy(357 115,f inaI); setcolor(l4); strcpy(final,""); strncpy(final,cadfileinA,29); outtextxy(357,1OO,final); case 3: OUttextxy(357,I15,NUMA); break; setcolor(5); outtextxy(357,130,f inal); outtextxy(357,145,final); setcolor(l4); strcpy(fínal,""); strncpy(final,cadf ileínX,29); outtextxy(357,130,final); OUtteXtxy(357,145,NUMX); case 4: break; 56 Aplicaciones del filtro de Kalman setcolor(5); outtextxy(357,I 60,final); outtextxy(357,175,f inal); setcolor(l4); strcpy(finaI, '7; strncpy(final,cadf ileinD,29); outtextxy(357,160,final); OUtteW(357,I 75,NUMD); break; 'I 1 1 muestra-ra tO; void captura-muestrasO{ char band = IF'; register int k; enbarra2(350,337,250,31,7); setcolor(0); outtextxy(360,348,"Numero de muestras:"); while(band= ='F'){ 1 1 setcolor(7); /* limpiamos el area de captura */ outtextxy(549,351 ,"UUUU"); outtextxy(549,352,"-"); Captura(549,347,4,0, NUMTEMPI; k=atOi(NUMTEMP); if (k! =O) band ='Vi; captura muestraso; barrido(350,337,600,375,1); swit c h(opc){ case 2: setcolor(5); outtextxy(357,115,final); case 3: case 4: setcolor(l4); strcpy(NUMA,NUMTEMPI; OUtteXtxy(357,I 15,NUMA); break; setcolor(5); outtextxy(357,145,final); setcolor(l4); StrCpy(NUMX,NUMTEMPI; OUtteXtxy(357,I 45,NUMX); break; 57 Aplicaciones del filtro de Kalman setco lor(5); outtextxy(357,175,final); setcolor(l4); StrCpy(NUMD,NUMTEMP); OUttextxy(357,I 75,NUMD); break; void advertenciak har * cad1,char * cad2){ void *parte; sound(2000); delay(200); nosoundo; guarda-imagen(190,190,470,290, &parte); I* zona de escritura *I setcolor(l2); rectangle(200,200,450, 260); setf illstyle(S0LID FILL,4); f loodfiII(300,24032); setcolor(8); I* sombras *I rectang1e(210,261,452,270); setfi IlStyle(S0LID FILL,O); f loodfi11(300,2658); rectang1e(451,210,460,270); SetfiIIStyle(S0LID FILL,O); floodfi11(454,2658); setcoior(i0); I* mensaje */ outtextxy~218,210,cadi); outtextxy(218,220fcad2); setcolor(l5); outtextxy(247,240,"Pulsecualquier tecla"); getch o; putimageil 90,19O,parte,O); f ree(parte1; 1 /* FUNCIONES PARA LA SALIDA */ void salida-entradaO{ int edo =O,teCla = O,x,y; /* funcion principal del cuadro de salida */ Void *pa; UCO=l; sound(2000); delay(200); nosoundo; esconde-rato; guarda ímagen(240,190,460,290,&pa); enbarr~2(250,200,200,80,7); 58 Aplicaciones del filtro de Kalman setcolor(0); OUtteXtxy(278,218,"DeSeasalir ahora?"); barra(270,240,72,20); barra(358,240,72,20); setcoior(l5); outtextxy(279,247,"Aceptarii~; setcolor(8); outtextw(364,247,"Cancelar"); muestra-rato; whilefedo! = 2 && tecla ! = 283) { edo =O; tecla =O; reporta-edo(&x,&y, &edo); if(edo= =I 1 1 bioskey(l)){/*si se hizo un click izq o un enter */ if(bioskey(1)) tecla = bioskey(0); if(tecla! = 7181) { mueve opcion-uso(tecla); ifctecia= = 19200 I I tecla = = 18432){ SetCOlOr(8); outtextxy(364,247,"Cancelar"); setcolor(l5); outtextxy(279,247,"Aceptar"); }else if(tecla= = 19712 I 1 tecla = = 20480){ setcolor(8); outtextxy(279,247,"Aceptar"); setcolor(l5); outtextxy(364,247,"Cancelarii~; 1 1 if(edo= =I) /* si es un click * / rango-mouse horizontal(x,y); if ((tecla = = 7181 I 1 edo= =I)) switch(uso){ case I: free(pa1; cortinao; closegrapho; restorecrtmodeo; exit(1); break; case 2: edo = 2; break; 1 1 1 }/* enddo */ esconde-rato; putimage(240,190,pa,O); f ree(pa); muestra-ra tO; 59 Aplicaciones del filtro de Kalman void rango- mouse horizontal(int x,int y){ /* indica en-que area nos encontramos cuando pasamos el puntero del mouse */ /* y se halla hecho click, en ese momento cancelamos la entrada nuevamente */ if(x>270 &&x<342 &&y>240 &&y<260) USO=l; else if(x>358 && X<430 && y>240 && y<260) uso = 2; else uso =O; I /* PANTALLA PARA LOS INTEGRANTES */ void integrantesO{ enbarra2(200,215,300,200,2); setcolor(l5); outtextxy(215,235,"UNIVERSIDADAUTONOMA METROPOLITANA"); outtextxy(215,245," setcolor(0); IZTA PA LAPA"); outtextxy(246,280,"Profesor asesor de proyecto"); outtextxy(247,280,"Profesor asesor de proyecto"); outtextxy(255,290,"DoctorH,ctor P,rez Meana"); outtextxy(300,315,"Programadores"); outtextxy(301,315,"Programadores"); outtextxy(260,355,"Lic. Cruz QUiraZCO Raul"); outtextxy(215,335,"Lic. Lozano Becerril Ricardo C,sar"); outtextxy(243,345,"Lic. Maldonado MUQOZ Rogelio"); outtextxy(250,325,"Lic. S nchez Arroyo Adriana"); setcolor(l5); outtextxy~263,390,"PuIse cualquier tecla"); getcho; barr~do(200,215,600,415,1~; I /* DECORADOS DE PANTALLA Y AMBIENTE */ void guarda imagemint x1,int y1,int x2,int y2,void **imagen){ unsigned infsize; size = imagesize(x1,y1,x2,y2); *imagen = malloc(size); if(*imagen ! = NULL) getimage(x1,yI,x2,y2, *imagen); else { setcolor(4); sound(l000); delay(lO0); nosoundO; outtextxy(35,457,"No hay suficiente memoria. Pulse una tecla."); getcho; ex¡ t(11; 1 I 60 I Aplicaciones del filtro de Kalman void boton(int x,int y,char *cadena,int clr) /* boton normal */ { void *dibujo; esconde-rat O; guarda imagen(30,40,93,70,&dibujo); putimage(x-I0,y-lO,dibujo,O); f ree(dibujo); SetCOlO r(WHITE); arc(x,y,90,230,1 O); line(x,y-lO,x+40,y-10); SetCOlOr(DARKGRAY); arc(x + 40,y,270,90,10); arc(x + 41,y,270,90,10); arc(x,y,230,270,1 O); line(x,y+10,x+40,y+10); /* flecha*/ line(x+ 35,y-3,x + 39,y + 4); Iine(x + 35,y-3,x + 42,y-3); line(x+39,~+4,~+42,y-3); setf illstyle(SOLID-FI LL,clr); floodfill(x+ 39,y,8); SetCO IO r(WHITE); /*flecha*/ Iine(x 39,y + 4,x + 42,y-3); arc(x + 40,y,50,90,1 O); setcolor(0); + 1 outtextxv(x,y-3,cadena); muestra-ra t0 ; void boton-press(int x,int y,char *cadena,int clr){ esconde-rato; SetCOlOr(LIGHTGRAY); /* flecha*/ line(x+ 35,y-3,x + 39,y + 4); Iine(x+ 35,y-3,x+ 42,y-3); line(x+ 39,y 4,x + 42,y-3); SetCOlOr(DARKGRAY); arc(x,y,90,270,1 O); iine(x,y-lo,x+ 40~y-10); arc(x 40,y,270,90,1 O); arc(x+41,y,270,90,10); line(x,y+ 10,x+40,y+ I O ) ; Setf ¡llStyle(SOLID FILL, LIGHTGRAY); f IO 0df iII(X, y, DARl?G RAY); + ’ + 61 /* boton presionado */ Aplicaciones del filtro de Kalman /* flecha*/ line(x+35,y-3,~+39,y+4); line(x+ 35,y-3,x+ 42,y-3); line(x + 39,y + 4,x+ 42,y-3); setf illstyle(SOLID-FILL,clr); floodfill(x+ 39,y,8); setcolor(LIGHTGRAY); arc(x,y,90,270,10); line(x,y-lO,x+40,y-10); arc(x + 40,y,270,90,10); arc(x + 41,y,270,90,10); Iine(x,y + IO,x+40,y+ IO); SetCOlOr(WHITE); line(x-I,y IO,x+ 40,y I O ) ; arc(x 42,y,27O,7OJ10); SetCO IO r(DARKGRAY); arc(x 2,y,90,270,10); line(x+ 2,y-1OJX+45,y-1O); arc(x + 42,y,60,90,10); setcolor(WHITE); + + + + arc(x + 2,y,230,270,10); /* SetCOlOr(DARKGRAY); line(x-I,y+8,X+4OJy+8); arc(x 42,y,270,70,8); arc(x 2,~,90,270,8); iine(x + 2,y-8,x+ 45,y-8); */ + + setco lor(8); OUttextXv(x 1 + 2,~-3,cadena); muestra-ra to; void boton-circ(int x,int y){ SetCO lOr(DARKGRAY1; circle(x,y,iO); arc(x + l,y,270,90,10); line(x-2,y-3,x-2,y + 4); line(x-2,y-3,x + 3,y + I); SetCO lOr(WHITE); /* circulo */ line(x-2,y + 4,x + 3,y + I); arc(x,y,g0,180,9); 1 void fondo0 { 1 Setf ~IlStyle(SOLID-FI LL,7); f loodf ill(l0,I0,7); void ecq-sup -izq(int x, int y){ 62 Aplicaciones del filtro de Kalman setcolor(l5); 1 line(x,y,x + 10,~); line(x,y,x,y+ IO); SetCO lOr(DARKGRAY); line(x,y + 10,x + 3,y + IO); Iine(x+iO,y,x+10,y+3); line(x+IO,y+3,x+3,y+3); 1íne(x+3,y+3,~+3,y+10); void esq-sup der(int x,int y){ setcolor(WH1TE); line(x,y,x-I0,y); line(x,y,x,y IO); setcolor(DARKGRAY); iine(x-lo,y,x-lo,y+ 3); iine(x,y+ I O , X - ~ , ~ + IO); 1ine(x-3,y+3,X-IO,y+ 3); line(x-3,y+ 3,x-3,y + IO); + 1 void ecq inf izq(int x, int y) { S e t C d O r(WHITE); line(x,y,x,y-lO); line(x,y,x+ 10,~); SetCO IO r(DARKGRAY); iine(x,y-io,x 3,y-io); iine(x+ io,y,x+io,y-3); iine(x+ 3,y-3,x+ 3,y-io); ~ine(x + 10,y-3,x+ 3,y-3); + 1 void esq-inf-der(int x,int y){ setcolor WHITE); Iine(x,y,x,y-I O); 1 Iine(x,y,x-lO,y); setcolor(DARKGRAY); Iine(x-lO,y,x-lO,y-3); Iine(x,y-lO,x-3, y-IO); line(x-3,y-3,x-l O,y-3); line(x-3,y-3,x-3,y-l0); void lineaso { setcolor(l5); Iine(20,459,620,459); line(629,450,629,71); line(20,21,620,21); Iíne(l1,71,I 1,450); 63 Aplicaciones del filtro de Kalman setco lor(0); line(20,22,620,22); line(l2,51,12,430); line(20,438,620,438); line(628,430,628,51); void cuadro20{ setcolor(l5); outtextxy(480,41O,"Abortar< ESC > "1; setcolor(l5); /* cuadro de la pantalla */ line(305,75,595,75); line(305,75,305,395); /* cuadro de la pantalla */ line(305,395,595,395); line(595,395,595,75); 1 void barrido(int xi,int yi,int xf,int yf,int color){ register int i,j,w,z; w = ((yf-yi)/2)+y¡; z=yf +yi+4; for(j=yi; j < =w+4; j + +) for(¡ =xi; i < =xf +4; i +){ /* el 4 es la agregacion para la */ putpixel(i,j,co lor); /* sombra */ putpixel(i,z-j,color); + 1 void cuadro30{ /* cuadro para el RUN */ setcolor(0); /* cuadro interno de pantalla negra */ line(450,80,590,80); l¡ne(450,80,450,390); line(450,390,590,390); Iine(590,390,590,80); setf iIlstyle(S0LID FILL,3); flOodfi11(480,81 1 ,a; void mensajeO{ Setf iIlStyle(SOLID-FILL, LlGHTBLUE); setcolor(l5); 64 Aplicaciones del filtro de Kalman line(30,80,90,80); line(90,80,90,100); line(90,100,30,100); line(30,80,30,100); floodfill(41,81,15); setcolor(1O); OUttextxy(35,88,"OPCION"); 1 void ventana menu(int xi,int yi, int xf, int yf){ SetCOIO r(WHITE); arc(xi + 10,yi + 10,90,180,10); arc(xi + 10,yf-l0,180,270,10); line(xi,yi + lO,xi,yf-lO); line(xi+lO,yi,xf +13,yi); arc(xf + 10,yf-l0,270,360,10); arc(xf 10,yi 10,360,70,10); iine(xi +8,yf,xf + io,yf); Iine(xf 20,yi + 10,xf 20,yf-IO); setf iIlstyle(S0LID FI LL,7); floodfill(xi +IO,Y~+10,15); SetCO IOr(DARKGRAY); arc(xf + 10,yf-I0,270,360,10); arc(xf + 10,yi + 10,360,70,10); line(xi + 8,yf,xf + 10,yf); Iine(xf + 20,yi + 10,xf + 20,yf-IO); setcolor(l1); /* sombra */ arc(xf + 11,yf-9,270,360,10); line(xi+8,yf+l,xf +lO,yf+l); Iine(xf 21,yi + 10,xf 21,yf-lO); arc(xf + 12,yf-8,270,360,10); line(xi +9,yf + 2,xf 10,yf 2); line(xf+22,yi+Il,xf+22,yf-10); + + + + + + + + 1 void barra(int x,int y j n t anch,ínt alt){ setcolor(8); line(x,y,x anch,y); line(x,y,x,y alt); Iine(x+ 1,y + alt,x anch,y + alt); line(x+anch,y + l,x+anch,y+ alt); setf iIIstyle(SOLID-FI LL, 7); f loodfill(x+ 5,y + 5,8); + + + SetCO IO r(WHITE); iine(x,y,x+ anch,y); line(x,y,x,y + alt); setcolor(0); line(x,y+alt+l,x+anch +l,y+alt+l); line(x+anch +l,y,x+anch +l,y+alt+l); 65 Aplicaciones del filtro de Kalman void enbarra2(int x,int y,int anch,int alt,int fondo){ setcolor(8); line(x,y,x+ anch,y); line(x,y,x,y + alt); line(x+l,y+alt,x+anch,y+alt); line(x+anch,y+ l,x+anch,y+alt); setf iIlStyle(S0LID FILL,fondo); floodfill(x+ 5,y+%,8); 1 SetCOlOr(WHITE); Iine(x,y,x + anch,y); Iine(x,y,x,y + alt); /* marco color rojo */ setcolor(4); line(x+ 5,y + 5,x + anch-5,y+ 5); Iine(x+5,y + 5,x + 5,y + alt-5); line(x+ 5,y + alt-5,x + anch-5,y + alt-5); line(x+anch-5,y+ 5,x+ anch-5,y + alt-5); setcolor(0); line(x,y+alt+l,x+anch +l,y+alt+l); line(x+ anch + l,y,x+anch + l , y + alt + 1); setcolor(l1); /* sombra color cyan claro */ Iine(x+2,y+alt+2,x+anch +2,y+alt+2); line(x+ anch + 2,y + 2,x + anch + 2,y + alt + 2); Iine(x+ 2,y + alt + 3,x + anch + 2,y + alt + 3); line(x+ anch + 3,y + 2,x + anch + 3,y + alt + 2); /* barra hundida con color */ void barral(int x,int y,int anch,int alt,int clr){ setcolor(clr); /* inicialmente era blanco para el fondo */ line(x,y,x + anch,y); line(x,y,x,y + alt); line(x,y+ alt,x + anch,y + alt); line(x+anch,y,x+anch,y+alt); SetfiIIStyle(S0LID FILL,CIr); floodfill(x+ 1,Y+? ,6); /* SetCOlOr(DARKGRAY); line(x,y,x + anch,y); Iine(x,y,x,y + alt); */ 1 void barra2Qntx,int y,int anch,int alü{ SetCOlOrWHITE); line(x,y+ alt,x + anch,y + alt); Iine(x+anch,y,x+ anch,y+alt); setcolor(0); Iine(x,y,x+ anch,y); line(x,y,x,y + alt); 1 void tituloO{ barra(l0,5,24,22); barra2(16,15,12,3); /* barrita de cierre de pantalla */ 66 Aplicaciones del filtro de Kalman barra(36,5,565,22); /* boton de ? */ barra(603,5,19,22); barra1(40,8,556,16,6); barra(618,30,4,390); barra(553,422,69,50); /* barra para el logo */ settextstyle(1,O,l); setco lor(0); OUtteXtxy(l97,4,"F i I t r o d e K a I m a n"); outtextxy(610,4,"?"); setcolor(l5); 1 outtextxy(l99,4,"F i I t r o d e K a I m a n"); settextstyle(O,O,O); void cuad meno{ setcoliir(8); line(l0,472,500,472); line(500,472,500,449); line(501,473,501,451); line(502,474,502,451); line(10,473,501,473); iine(12,474,502,474); setcolor(l5); Iine(lO, 450,499,450); line(10,472,10,450); settextstyle(1,O,l); setcolor(0); OUttextxy(508,443,"UAM"); outtextxy(509,443,"UAM"); outtextxy(506,455,"P~~~~~ "1; setcolor(2); settextstyle(2,0,0); outtextxy(559,456,"Iztapalapa1'); 1 outtextxy(558,456,"Iztapalapa"); setcolor(8); outtextxy(560,456,"Iztapalapa"~; settextstyle(O,O,O); void f ondoazulO{ register int a; setcolor(0); rectangie(l21,45,609,430); setfillstyle(S0LID FILL,I); f loodfi11(200,2000); setcoior(l5); line(120,431,610,431); line(610,44,610,431); line(l20,430,610,430); line(609,44,609,431); setcolor(l2); /* lineas de marco del */ /* fondo azul */ /* fondo magenta */ 67 Aplicaciones del filtro de Kalman rectangle(l30,60,600,190); /* marco del fondo magenta */ setf iIlstyle(S0LID FILL, 5); fl00dfi11(140,100~2); a=140; setcolor(3); outtextxy(a,70,"Programa usado como:"); OUttextxy(a,85,"DeSt¡nO del archivo final:"); OUttextxy(a,lOO,"TOma de 10s datos A:"); outtextxy(a,l15,"NUmerO de muestras a tomar:"); outtextxy(a,l30,"TOma de 10sdatos x:~~); OUttextxy(a,l45,"NEmerO de muestras a tomar:"); OUtteXtxy(a,l6O,"TOma de los datos D:"); OUttextxy(a,l75,"NEmerO de muestras a tomar:"); restableceo; 1 void restablece0 { register int a; a = 357; setcolor(l4); outtextxy(a,70,"P r e d i c t o r"); outtextxy(a,IOO,"Aleatorio"); outtextxy(a,l I5,"25"); outtextxy(a,l30,"Aleatorio"); outtextxy(a,l45,"25"); outtextxy(a,l60,"Lecturade disco"); outtextxy(a,l75,"25"); A l = '0'; D l = 'O'; boton (40,170,"A", 7); boton (40,250,"D1',7); sound(2200); delay(lO0); sound(2500); delay(l00); nosoundo; void inigrafO{ int contro1,modo; control = VCA; modo = VCAHI; initgraph(&control,&modo,""); 1 I* KALMAN.H */ # include <globales.h > int q; char aborta='f'; I* contiene la tecla pulsada para la interrupcion */ I* bandera de abortar los c lculos *I 68 Aplicaciones del filtro de Kalman Q = QW; QI = Q(n-I);XK = X(n); XKT = X(n)TranSpUeSta; HK = w(n) ............................................................. /* INlClALlZAClON */ void inicializa(void) { register int i,j; for(i=O; ¡<tam; i++I{ XKIiI = 0.0; HKIII = 0.0; sena1 Y[il =O.O; Senal-DIil= 0.0; AIil =O.O; 1 for(¡ =O; i < tam; i + +) for(j=O; j<tam; j + + I { if(¡= =j){ QIilIjl= 100.0; Q1IilIjl=100.0; }else{ QIilIjl= 0.0; Q1IilIjl=0.0; 1 1 1 /* Filtro de KALMAN */ void KALMAN(Void) { register int i,j; double suma,resuIt,lambda =0.999; double S[taml,KG[taml; for(i=O; i<N; i++ ) forO=O; j<N; j + + ) /*KG = a la ganancia de Kalman */ /* toma de la vieja Q * * * * * * * / Q1IilIjl=QIilIjl; Y2 = 0.0; for(í=O; i<N; i++ ) Y2 =Y2 + (HKíil*XKi¡I); error = y3 - ~ 2 ; /* (X(n)trans*Q(n-l)*X(n)) + lambda */ for(i=O; í<N; i++ I { 69 / Aplicaciones del filtro de Kalman suma=ü.ü; for(j=O; j<N; j + + ) suma =suma + (XKijl*Ql ijliíl); S[il =suma; 1 suma = 0.0; for(i=O; i<N; i + + ) suma =suma + (XK[il*S[il); result =suma + lambda; /* Ganancia de Kalman */ for(i=O; i<N; i+ +){ suma = 0.0; for(j=O; j<N; j + + ) suma =suma + (Q1 [il[jl*XK[jl); KGiiI =suma/resuit; / * Q(n-I)X(n)*/ 1 /*AdaptaCiCn de vector de coeficientes */ /* w(n)=w(n-l)+ K(n)*error*/ /* Calculo del vector QW*/ /* Q(n)= [Q(n-l)-K(n)X(n)transQ(n-l)l/lambda */ for(i=O; i<N; i++ ) for(j=O; j<N; j + + ) Qiilijl= (Q1 iilijl-(KGiiI*Sijl))/lambda; /* Calculo del Vector XK */ void vector-XK(double nvoval) { register int i; for(¡ =O; i < NumElem; i+ +) XKiNurnElem-il = XK[NumElem-i-11; XKiOI = nvoval; /* recorremos */ /* generamos numero aleatorio*/ 70 Aplicaciones del filtro de Kalman /* Calculo del vector A */ void vector-A(void) { Al01 = 7.785205408500e-02; AI1I = 3.965393194820e-01; AI21 = 7.291 320908460e-01; AI31 = 4.697822874050e-01; AI41 = -1.439060039290e-01; AI51 = -2.240361849940e-01; AI61 = 7.130921926700e-02; Al71 = 8.061260915100e-02; AI81 = -3.802993693500e-02; AI91= -1.657454163100e-02; AI101= 1.255099855600e-02; AI1 11= 4.295779730000e-04; AI121= -1.801640704000e-03; Al131= 3.537138000000e-04; /* El resto del Vector A no varia */ 1 /* Calculamos el error */ /* Principal */ void proyectoWoid) { double X =O,x2 I = O,pot-sig,pot -err,pot -noise,mse; long stime; int seed,i,j,k; inícializao; VeCtOr-AO; time(&ctime); seed =stime%l00; srand(seed1; for(¡=O; ¡< NumBlock; i + +) { pot-sig = 0.0; pot-err = 0.0; pot noise = 0.0; for(j=O; j<Numlter; j + + I { /* se generan numero aleatorios */ X = (double)randO/(double)RAND~MAX-0.5; I /* x nuevo */ 71 Aplicaciones del filtro de Kalman x2 = (double)randO/(double)RAND-MAX-0.5; /* ruido nuevo*/ D = 0.0; for(k=O; k<NumElem; k + +) D= D (A[kl*XK[kl); + Y3 = D + X2; KALMANO; pot err+ =(D-Y2)*(D-Y2); POtSig + = (D* DI; pot-noise + = M-D)*N~-D); ifti= =O){ setcoIor(0) ; delay(5); outtextxy(400,457 O "1; delay(2); outtextxy(408,457,"0"); delay(2); outtextxy(416,457,"0"); delay(2); outtextxy(424,457,"0"); delay(2); outtextxy(432,457, " '7; delay(2); outtextxy(440,457," f '7; delay(2); oUttextxy(448,457," f de lay(2); OUttextxy(456,457," "1; delay(2); outtextxy(464,457, "2"); delay(2); outtextxy(472,457, "2"); delay(2); oUttext~(480,457,"2"); delay(2); outtextxy(488,457, "2"); if(bioskey(1)) { q = bioskey(0); if(q = = 283) goto el; ,I' * * 1 mse = pot-err/pot-sig; art-[¡]= mse ; setcolor(l5); 72 Aplicaciones del filtro de Kalman delay(5); 0Uttextxy(400,457,"0"); delay(2); outtextxy(408,457," delay(2); outtextxy(416,4 57, '' o '1; delay(2); outtextxy(424,457, "o'i); delay(2); outtextxy(432,457," f "1; delay(2); outtextxy(440,457," f"1; delay(2); outtextxy(448,457," f delay(2); outtextxy(456,457," f I*); delay(2); outtextxy(464,457, ii2'i); de lay(2); outtextxy(472,457, "2"); delay(2); o~ttextxy(480,457,"~"); delay(2); 0uttextxy(488,457,"~"); if(bioskey(1)) { q = bioskey(0); if(q= = 283) goto el; li); 1 1 e l : fuera(); } /* fin del principal */ void fuera(){ if(q= = 283){ setcolor(7); outtextxy(40,457,"RealizandO c ICUIOS de Kalman"); outtextxy(500,457,"!Tra bajando-"); 0Uttextxy(400,457,"00o o + - _+- +- + 2222"). aborta = It';} 1 1 /* Muestra en pantalla el error cuadr tico del filtro */ void correr0 { int i,k,ini,z,v,band =O; *cadi = char *cad = double cuadr; 'I 'I, 'I 'I- settextStyle(DE FAULT-FONT, HORIZ-DIR, 1); setcolor(l4); 73 Aplicaciones del filtro de Kalman outtextxy(370,350,"Espere un momento.. ..."I; setcoior(i 5); Outtextxy(40,457,"Real¡ZandOc lculos de Kalman"); proyectoo; if(aborta = ='ti) { aborta = If'; goto e2; } setcolor(11; outtextxy(370,3 50,"ESpere un momento....."I; setcolor(7); outtextxy(40,457,"Realizando c lculos de Kalman"); o~ttextxy(400,457,"~ O O O f f f *2**2"); outtextxy(500,457,"!Tra bajando-"); setcolor(l4); outtextxy(450,90,"Error Cuadratico"); setcolor(l5); outtextxy(40,457, "Muestra del conten ido f inal del arch ¡vota); for (v=o; v < { = 150; v + + ) pUtpiXeI(300-V,230,WHITE); putpixeI(300+ v,230,WHITE 1; delay(l0); 1 for (v=o; v < { = 80; v+ +I pUtp¡Xel(l50,230 + V,WHITE); pUtp¡Xe1(450,230 + V,WHITE 1; delay(1O); 1 for (v=o; v < { = 150; v + +) putpiXel(l50+v,310,WHITE); PUtpiXeI(450-V,31O, WHITE 1; delay(l0); 1 SetfiIlStyle(S0LID FILL,DARKGRAY); f lOOdf¡11(300,250~WHITE); band = 1; for (k=O; k < =50; k + +1 { setcolor(LIGHTGREEN); in¡ = k; Z=l; for (¡=in¡; i<=(ini+2); i + + 1 { z+ +; 74 Aplicaciones del filtro de Kalman cuadr = arr[il*arr[il; gcvt(k+zf5,cadl); outtextxy(l70,250 + (z * 1O),cadl1; gcvt(arr[il,5,cad); gcvt(cuadr,5,cadl); outtextxy(350,250+ ( z * l O),cadl); outtextxy(230,250+ (z*lO),cad); I* cuadr = arr[(ini+ 20)-zl*arr[(ini+ 20l-zl; gcvt(arrI(ini + 2O)-zl,5, cad); gcvt(cuadr,5,cadl); outtextxy(470,320-(~*1 O),cad); outtextxy(460,320-(z*1 O),cadl); if(bioskey(1)I{ q = bioskey(0); if(q= = 283) goto e2; 1 *I 1 delay(lO0); if(k = = 80 I { setcolor(7); outtextxy(40,457,"Muestra del contenido final del archivo"); setcolor(l5); outtextxy(450,350,"Presione una tecla"); outtextxy(40,457,"-Proceso terminado!...., los resultados estan listos en el archivo");*I I* getcho; setcolor(7); outtextxy(40,457,"-Proceso terminado! ...., los resultados estan listos en el I* archivo");*I setcolor(3); outtextxy(450,350,"Presioneuna tecla"); OUttextxy(45Of90,"ErrOrCuadratico"); 1 SetColOr(DARKGRAY); z=l; for (i=¡ni; i < =(¡ni + 2); i + + 1 { z + +; gcvt(k+z,5,cadl); outtextxy(l70,250 + (z*lO),cadl); cuadr = arr[il*arr[il; gcvt(arr[il,5,cad); gcvt(cuadr,5,cadl); outtextxy(350,250+ (z*lO),cadl); outtextxy(230,250+(z*lO),cad); /* cuadr = arr[(ini+ 20)-zl*arr[(ini+ 201-21; gcvt(arr[(ini+ 20)-zif5,cad); gcvt(cuadr,5,cadl); 75 Aplicaciones del filtro de Kalman outtextxy(470,320-(~*1 O),cad); outtextxy(460,320-(z*iO),cadl); */ 1 if (bioskey(l)){ q = bioskey(0); if(q= = 283) goto e2; 1 1 for (v=o; v < { = 150; v + + I pUtpiXeI(300-V,230,WHITE); pUtpiXeI(300+ V,230,WHITE 1; delay(l0); 1 e2: aborta =If’; if (band) { setfiIIstyle(S0LID FILL,BLUE); f loodf i11(300,250~WHITE); for (v=O; v < = 150; v + +) { PUt p iXe1(300-V,230,BLUE); putpixeK300+ V,230,BLUE 1; delay(l0); 1 for (v=O; v < = 80; v + { +) putpixel(l50,230 +V,BLUE); pUtpiXe1(450,230 + V,BLUE 1; delay(l0); 1 for (v=o; v < = 150; v + +I { pUtpiXel(l50+V,310,BLUE); pUtpiXeI(450-V,31O,BLUE 1; delay(1O); 1 1 /* fin de if (band) */ setco~or(n; outtextxy(40,457,”Muestra del contenido final del archivo”); 1 76 Aplicaciones del filtro de Kalman /* FUNCIONES PARA EL FUNCIONAMIENTO DEL MOUSE */ void inicialO{ union REGS r; r.x.ax = O; int86(0x33,&r,&r); if (r.x.ax = = O) printf("mouse no encontrado"); I void lim-vertO{ union REGS r; r.x.ax = 8; r.x.cx = O; r.x.dx = 479; int86(0x33,&r,&r); I void lim-ho rizo{ union REGS r; r.x.ax = 7; r.x.cx = O; r.x.dx = 639; int86(0x33,&r,&r); I void muestra-rat0 { union REGS r; r.x.ax = I; int86(0~33,&r,&r); void esconde-rato { union REGS r; r.x.ax = 2; int86(0x33,&r,&r); void reporta edo(int *x,int *y,int *edo){ union R E G . r; r.x.ax = 3; int86(0x33,&r,&r); *x = r.x.cx; *y = r.x.dx; *edo = r.x.bx; 77 Aplicaciones del filtro de Kalman void guardaimagen(int x1,int yl,int X2,int y2,void * *imagen) { unsigned int size; size = imagesize (XI ,y1,x2,y2); *imagen = malloc(size); getimage(x1,y1,x2,y2, *imagen); 1 void brillo(int xlint y) { int ilj; void *imagen; char fbrí i131i131= {" O 0 0 " " 'I1 "1 "1 1 " 1 " 111 "O001111111OOO", " 111 " 1 "I " 1 " "1 'I> 'I1 'I, " I 0 0 0 " " " + "1 "1 "1; guardaimagen(x,y,x 13,y+ 13,&imagen); de lay(200); for (j=O;j<13;+ +j) for (i=O;i<13;+ +i) switch (fbriijliíl) { case 'O' : { putpixeHx ¡,y j,l2); break; } case '1' : { putpíxel(x+ily+j,15);break; } + + 1 delay(500); putirnage(x,y,ímagen,COPY-PUT); f ree(imagen1; 1 void logotipo(int x j n t y j n t color1,int color2) { int i,j; char logo [251i521= 0000000 1111111111111111 0000000 1000000 1111111111111111 0000001 1000000 1111111111111111 0000001 " 111000000111111 111111000000111 " 111000000111111 111111000000111 " 1111000000111111 1111110000001111 111110000001111 111111000011111 ", " 111110000001111 111111000011111 ", " 1111110000000111 1111110000111111 " 111111 00000011 11111100 111111 " 111111 00000011 11111100 111111 {'I I, II I, I, 1 I, I I, I 'I, " 'I, 'I1 'Il 7% I Aplicaciones del filtro de Kalman 111111 111111 ", 111111 000000 111111 111111 ", 111111 000000 " 1111111 10000000 00111111 1111111 ", " 111111 11000000 00111111 111111 ", " 111111 11000000 00111111 111111 ", 0000111111 1111111 ", " 1111111 1110000000 0000111111 111111 " 111111 1111000000 0000111111 111111 ", " 111111 1111000000 " 111111 111111000000 000000111111 111111 ", " 111111 111111000000 000000111111 111111 ", " 1111111 11111110000000 00000001111111 111111 ", "111111 111111 0000000000000000 111111 111111 ", "111111 111111 0000000000000000 111111 111111", "1111111 1111111 0000000000000000 1111111 1111111"); " " 'I, for (j = 0;j < 26; + +j) for (i =O;¡ < 53; + + i) switch ~iogorjirii~ { case 'O' : { putpixel(x+ ¡,y+ j,colorl); break; } case '1' : { putpixel(x + ¡,y +j,color2);break; } 1 1 void barrido-bn (void) { register int i,j; for (j=60;j< =180;j+ + ) for (i=O;i<30;i+ +I{ 1 if (15 = = getpixel(j + i ,50 + i)){ putpixeKj + i,50 + i, O);} delay(1); for (j=85;j< =132;j+ + ) for (i=O;i<25;i+ +) { if(7 = = getpixel(j + i ,50 + i)){ putpixel(j+ i,50 + i, 15);) delay(1); void barrido-co lor(void) { register int i,j; for (j=120;j< =550;j+ +) for (i=O;i<3O;i+ +) { if (!(6= =getpixel(j+i ,190+i))) { putpixel(j+i,190+i,2);} if (!(6= =getpixel(j+i-l0,19O+i))) { putpixel(j+i-l0,19O+i,7);} if (!(6= =getpixel(j+i-20,190+i))) { putpixel(j+i-20,190+i,14);} 1 1 void barrido-co lor2(void) { 79 Aplicaciones del filtro de Kalman register int i,j; for íj=120;j< =550;j+ + ) for (i=O;i<3O;i+ + ) { 1 if (!(6= =getpixel(j+i ,19O+i))) { putpixel(j+i,190+i,7);) if (!(6= =getpixel(j+i-l0,19O+i))) { putpixel(j+i-l0,19O+i,2);} if (!(6 = = getpixelti + i-20,190 + i))) { putpixel(j + i-20,190+ i,6);) void co rtina(void) { register int i; 1 setfiIIstyle(1,l); for (í =O;¡ < getmaxx0;i = i+ 2){ bar(í,O,i + 5,getmaxyO); delay(2);) void portada(void) { setcolor(l5); rectangle(20,20,620,460); setfiIlstyle(l,6); f loodf i11(100,100,1 5); settextjustify(1 ,I); logotipo(90,50,7,15); settextstyle(l,O,2); setcolor(0); outtextxy(360,55,"UNIVERSlDADAUTONOMA METROPOLITANA"); setcolor(7); OUttextxy(362,55,"UNlVERSlDAD AUTONOMA METROPOLITANA"); settextctyle(2,0, 5); setcolor(0); OUttextxy(520,73,"IZTAPALAPA"); OUl3e~(521,73,"IZTAPALAPA"); setcolor(0); settextstyle(2,0,3); outtextxy(l20,80,"Caca abierta al tiempo"); settextjustify(0,l 1; settextstyle(O,O,l); setcolor(l5); outtextxy(50,330, "Programadores:"); outtextxy(50,350,"Lic. S nchez Arroyo Adriana"); outtextxy(50,360,"Lic. Cruz QUiraZCO Raul"); outtextxy(50,370f"Líc. Lozano Becerril Ricardo C,sar"); outtextxy(50,380,"Lic. Maldonado MUG! ROgelio"); outtextxy(450,330,"Profesor-Asesor:"); o~ttextxy(400~350,"Dr. H,ctor P,rez Meana"); delay(800); settextjustífy(1 ,I); brillo(550,50); delay(l00); barrido-bn O; 80 Aplicaciones del filtro de Kalman delay(300); brillo(80,60); bri110(550,50); brillo(l20,40); brillo(550,80); settextstyle(3,0,2); setcolor(4); outtextxy(getmaxxO/2,getmaxy~~/2-4O,"APLlCAClONES DEL FILTRO DE KALMAN"); barrido-coloro; de lay(300); briIlo(l30,180); briI10(480,190); barrid O C OIor20 ; settextstyle(3,0,2); setcolor(l4); outtextxy(getmaxxO/2,getmaxy~/2-4O,"PROYECTO TERMINAL"); briI10(200,180); briIlo(400,190); delay(lOO0); settextstyle(2,0,3); setcolor(0); outtextxy(getmaxxO/2,getmaxyOí2 + 170 ,"Copyright (c) Derechos ReServados"); outtextxy(getmaxx0/2,getmaxy0/2 + 180 ,"Mexico, MCMXCVII"); de lay(2000); /* randomizeo; do{ briIIowandom(6391,random(479)); }while(!kbhitO); */ cortinao; 1 81 Aplicaciones del filtro de Kalman # include <graficos.h > # include "direct.h" void mainO{ c IrscrO; I* hacer instalaciono; ini grafo; poi%adaO; closegrapho; /* cierra los graficos para que se restablescan los *I ¡ni grafo; inicializa-cadenas(); menuo; 1 void hacer-instalaciono { struct ffblk fp; register int fin; ¡f(findfirct("C:\\KALMAN",&fp,FA -DIREC)! =O) { I* 1 1 system("a:\instalar.bat"); printf("lnstalacion terminada.......");*/ inic iaIO; 82 Aplicaciones del filtro de Kalman ADAPTIVE FILTER THEORY HAYKIN, SIMON PRENTlCE-HALL ADAPTIVE FILTERS STRUCTURES, ALGORITHMS AND APLICATIONS HONING, MICHEL LO. ED. KLAWER ADAPTIVE DIGITAL FILTER AND SIGNAL ANALYSIS BELLANGER, MAURICE. DEKKER, NEW YORK ADAPTIVE FILTERING PREDICTION AND CONTROL GOODWIN, GRAHAM, CLIFFORD. PRENTICE HALL 83 Aplicaciones del filtro de Kalman [I1 W. Lucky, "Automatic Equalization for Digital Communication", Bell Sys. Tech, J., April, 1995, pp 547-588 121 Gersho, "Adaptive Ecualization of Highly Dispersive Channels for Data Transmission", Bell Sys. Tech J., January, 1969, pp. 55-70 131 Widrow and M. E. Hoff, Jr., "Adaptive Switching Circuits", IRE wescon Conv. Rec., pt. 4, August, 1960, pp 96-104 141 D. Godard, "Channel Equalization Usin a Kalman Filter for Fast Data TranSmiSSiOn", IBM J. Research and Development, May, 1974, pp 267-273 151 R. D. Gitlin and F. R. Magee, Jr., "Self-Orthogonalizing Adaptive Equalization Algorithms", IEEE Trans. Communications, July 1997, pp. 666-672 [61 R. w. Chang, "A New Equalizer for Fast Sart-Up Digital Communication", Bell Sys Tech. J., July-August, 1971, Pp 1969-2014. 171 MOrf, L. Ljung and T. Kailath, "Fast Algorithms for Recusive identification", Proc. IEEE Conf. On Decision and Control Clearwater Beach, Florida, December, 1976 181 Morf and L. Ljung, "Fast Algorithms for Recursive Identifiaction", IEEE International Symposium on information Theory, June, 1976, Ronneby, Sweden. 191 Levinson, "the Wiener RMS (Root Mean Square) Error Criterion in Filter Desing and Presiction", J. Math. Phys., 1974, Vol. 25, pp.261-278 [I01 Ljung, M. MOrf, and D. D. Falconer, "Fast Calculation of Gain Matrices for Recursive Estimation Shemes", international J. Control, Juanary, 1978. Aplicaciones del filtro de Kalman 1111 Macchi and L. Guidoux, "Un Nouvel Égaiiseur: L' Égaiiseur á Double Échantillonage", Ann. Telecommum., sept-Oct. 1975, pp. 331-338. [I21 D. Falconer, K. H. Mueller and S. B. Weinstein, "Echo Cancellation Techniques for Full-Duplex Data Transmission on TWO-Wire Lines". Proc. Nat. Telecomm. Conf., Dallas, December 1976, pp 877-883 [I31 Soderstrom, L. Ljung and I. Gustavsson, "A Cmparative Study of Recursive identification Methods", Report 7427, 1974, Dept. Of Automatic Control, Lund Institute of Technology, Lund, Sweden. 1141 J. AStrom and P. Eykhoff, "System identification- A Survey", AutOmatiCa, Vol. 7, pp 123-162, (1971) I Steinberg, Computational Matrix Algebra, McGraw-Hill, 1974. [I 51 Identification Methods", Report 7427, 1974, Dept. O f Automatic Control, Lund Institute of Technology, Lund, Sweden. J. AStrom and P. Eykhoff, "System Identification- A Survey", Automatíca, Vol. 7, pp 123-162, (1971) 85