martes, 29 de noviembre de 2016

Detalles de implementación y comunicación con otros Módulos

La estructura básica está soportada sobre un  un módulo de detección completo y éste a su vez está compuesto por un Arduino que tiene un led + un sensor de distancia  + un sensor de luz.

El sistema difuso está implementado en el Arduino, debe ser posible definir para cada variable difusa sus etiquetas, definir un sistema de reglas con varias variables de entrada y extraer como salida la situación detectada" (PEATON, COCHE, NADA). 

Un vehículo, al pasar, primero activa el sensor de luz, luego el de distancia y, finalmente, dejará de activar el de luz. Durante todas esas situaciones el estado debería ser COCHE
, sin embargo una vez deje de activar el sensor de luz, la situación sería indistinguible de un PEATON cruzando (distancia activada y sensor de luz no activado). 

Para distinguir ambas situaciones ( la del coche pasando ya fuera del sensor de luz y  la del peatón cruzando) es necesario definir una variable temporal que informe  del tiempo que hace que se activó la “falta de luz” (conocimiento de estado anterior). 

Aunque ahora definiremos sólo el COMPORTAMIENTO de un  módulo vamos a adelantar la estructura prevista para la conexión de varios módulos entre sí. 

La estructura de conexión estará basada en una comunicación por eventos sobre el protocolo MQTT. Los módulos se conectan a un servidor de colas para suscribirse a eventos y para enviar sus propios eventos.

Dependiendo de la tecnología de comunicación existen dos variantes de MQTT:

a) Si se utiliza xbee, es mejor utilizar mqtt-ssn, ya que mqtt espera trabajar con direcciones ip. En dicho caso cada Arduino tendría un xbee-pro y la raspberry otro.  

b) Si se utiliza TCP/IP--> es necesario un shield etherneT/wifi. También es posible utilizar un  ESP8266. El propio ESP8266 se puede utilizar como microcontrolador con el IDE de Arduino o conectar al Arduino como puente para wifi. 


Los módulos (arduino)  envían la información fusionada (hay coche, hay peatón, no hay peatón) como un evento y escuchan el evento “hay peatón”, así si un módulo detecta peatón se enciende su propio led y emite el evento “peatón” que será recibido por los otros . Cuando no se haya recibido un evento peatón en un cierto tiempo y el mismo módulo no esté detectando peatón  el led del módulo se apaga. 

En la Raspberry/servidor MQTT:

- Instalar el servidor MQTT
- Desarrollar un script que visualice por pantalla el estado de cada módulo (COCHE/PEATON/NADA) y LED[ENCENDIDO/APAGADO] en python o java.
- Desarrollar un script para simular la acción de un módulo  enviando eventos. 

Inicio del programa: 
Calibración

Cuando se inicia el programa se produce una calibración donde se mide la luz mínima, máxima, sin coche y con coche. la calibración determinará el límite de las etiquetas Lingüísticas OSCURO/CLARO.

Comunicación 
Cada Arduino deberá implementar el cliente de MQTT para leer los eventos a los que se suscribe (PEATON) y escribir los eventos (PEATON, COCHE,NADA). se debe configurar cada arduino con una IP o direccion de Xbee diferente y conectar con el servidor MQTT al principio del programa.

Definir la calidad de envío de los eventos y justificar. 



Esquema General de Programa  
Nota importante :Se puede desarrollar de multiples  formas , con otras variables, otras  etiquetas , orden etc.., el siguiente esquema es sólo una sugerencia ;), pero debe usar esos dos sensores y la estructura definida anteriormente por cada Arduino .

********************************************************************************************************************


Sistema difuso:
variables : 

tiempoNoLuz : [0,MAX]  en milisegundos , dos etiquetas POCO ,MUCHO
distancia:[0, DistanciaMAX] en cms. dos etiquetas CERCA, LEJOS
luz:[LuzMin,LuzMax] en medidas de arduino de 0 a 1024. proveniente de la calibración inicial. 

Caso 1 : (coche pasando)
      Si  distancia es CERCA  y Luz es OSCURO y tiempoNoLuz es POCO —> COCHE
      Si distancia es CERCA  y Luz es OSCURO y tiempoNoLuz es MUCHO —> COCHE // esta no se puede dar, pero por coherencia
      Si distancia es LEJOS  y Luz es OSCURO y tiempoNoLuz es MUCHO —> COCHE // esta no se puede dar, pero por coherencia
      Si distancia es LEJOS  y Luz es OSCURO y tiempoNoLuz es POCO —> COCHE   // antes de ser detectado por el sensor de distancia
      Si distancia es LEJOS   y  Luz es CLARO y tiempoNoLuz es POCO —> COCHE   // antes de ser detectado por el sensor de distancia y y ya no tapa sensor luz

 // vamos a suponer que no va a pasar un coche mientras esté pasando el peatón  para simplificar el esquema

    
Caso 2 : (Coche pasando pero ya no tapa el detector de luz)

      Si se distancia es CERCA  y Luz es CLARO y TiempoNoLuz es POCO —> COCHE

Caso 3: (peatón pasando)

       Si distancia es CERCA   y  Luz es CLARO y TiempoNoLuz es MUCHO —> PEATON  

 //  Se supone que el coche espera antes de llegar al sensor  de luz cuando hay un peatón pasando por lo que luz es CLARO cuando un coche espera. 
       
Caso 4: (No Peatón y No Coche:
       Si distancia es LEJOS   y  Luz es CLARO y TiempoNoLuz es MUCHO —> NADA (ni coche ni peatón) 
   


Es importante resaltar que la salida de este difuso es una etiqueta lingüística, no un número, por lo que la agregación deberá calcular que etiqueta es la que corresponde a la clasificación [COCHE, PEATON,NADA]


Con la salida del difuso y una entrada externa Evento[PEATON] (que podemos simular en el modo “un sólo modulo” con un interruptor ): 

loop(){

   luz=leerLuz(); //usando ventana de medias 
   distancia= leerdistancia()
   Estado = Fuzzy[distancia,luz,tiempoNoLuz] ;
   MAX = 3000// para tener un universo de discurso de la variable tiempoNoLuz definido entre [0,MAX]

   Si  luz es  OSCURO  —> instanteNoluz= millis(); //variable que captura el momento en el que pasa el coche
   tiempoNoLuz millis() - instanteNoLuz; 
   Si (tiempoNoLuz) > Max —> instanteNoluz =MAX ; 


//OJO : aunque luz es una variable  de entrad al difuso, aquí no es necesario realizar un difuso. Sin embargo podemos utilizar la definición de la etiqueta lingüística para hacer nuestro sistema más flexible. Para ello, basta con calcular el grado de emparejamiento de la etiqueta OSCURO > límite . 
//La entrada luz debe estar filtrada (metodo de la ventana de medias) para evitar que un breve cambio de luz afecte a esta variable, pero no debe tener en la ventana muchos valores ni un tiempo entre medidas alto, porque no detectaría el coche al pasar)

//podríamos usar una máquina de estados, pero dadas las pocas combinaciones se puede hacer a mano con IF-Then-ELSE

   Si Estado es PEATON —> emitir Evento[PEATON] //envia evento a Cola mqtt
   Si Estado es COCHE —> emitir Evento[COCHE] 


   ProcesarListaEventosMQTT();   
   Si EventoRecibido[PEATON] == True  or Estado es PEATON—>  {
      encender [LED]; 
      instantePeaton =millis(); //para saber el instante de la ultima vez que hubo un peaton   pasando
        }
   }
   tiempoPeaton= millis() - instantePeaton ; 
   Si tiempoPeaton > MAX —> apagar [LED]

}

********************************************************************************************************************