Localización en interiores usando redes WiFi

Ya hemos visto que usar la distancia al emisor para posicionarte dentro de casa es muy difícil, al menos sin usar hardware especializado. ¿Nos hemos quedado sin opciones?. Somos gente ingeniosa, no nos quedamos sin opciones. Si no podemos usar la distancia por la gran variación que tiene la potencia de la señal en interiores, le daremos la vuelta al problema y lo usaremos como ventaja. Si a la gran variación que hay en la potencia de la señal le sumamos la gran cantidad de nodos WiFi que hay alrededor nuestro, resulta muy poco probable que en dos puntos que no estén muy próximos se den los mismos valores para todas las redes.

Vamos a empezar por la idea básica y luego desarrollaremos los distintos problemas que surgen en la vida real.

Primero vamos a movernos por nuestra casa midiendo la potencia de las redes WiFi que se reciben en distintos puntos que consideramos interesantes para localizarnos. Obtendremos una lista de tuplas {SSID, potencia} para cada punto.

Una vez tengamos esa base de datos creada vamos a tratar de saber lo “cerca” que estamos de esos puntos sabiendo solo la potencia de los wifi que nos rodean. En este caso “cerca” no se refiere a distancia física en metros si no a lo parecidas que son las mediciones en dos puntos. Aunque no tenga que ver con la distancia física a este concepto también se le llama distancia.

Para medir esta distancia es fundamental saber que valor o valores vamos a usar, en este caso la potencia de la señal del WiFi. Vamos a compararla con las potencias almacenadas en nuestras mediciones anteriores. Para ello tomaremos las potencias medidas en los nodos con el mismo SSID y las compararemos, sumando luego todas para saber como de “próximos” están esos dos puntos.

Siendo Pi[ssid] la potencia en la base de datos para el nodo con ese SSID en el punto i y Pm[ssid] para la potencia medida de ese mismo nodo la distancia seria:

Dist(Pi) = ∑ √ (Pi[ssid] – Pm[ssid])²

O una forma menos exacta pero también computacionalmente menos costosa (y que a mi me a servido perfectamente)

Dist(Pi) = ∑ ABS(Pi[ssid] – Pm[ssid])

Siendo ABS la función que calcula el valor absoluto.

Que la i no despiste, en ambas formulas el sumatorio se refiere a sumar la diferencias de los distintos SSID medidos de cada punto.

Podemos determinar de que punto estamos más cerca comparando estas distancias y quedándonos con aquel punto Pi cuyo valor sea menor.

Para aplicar esta idea dividí mi casa (realmente solo dos habitaciones contiguas y un trozo de pasillo para probar) en una matriz de cuadrados de un metro de lado y establecí comos puntos de referencia el centro (a ojo) de cada cuadrado.

¿Funciono bien? La sorpresa es que, tras corregir problemas de los que hablo más adelantem mucho mejor de lo que esperaba. Buscando los puntos más cercanos me resultaba fácil saber donde estaba. No siempre me daba como más cercano el punto del que más cerca estaba pero nunca se fue muy lejos, así que podía saber mi posición con bastante precisión.

Problemas

Desgraciadamente de la teoría a la practica suele haber un camino lleno de baches. Por lo que siempre surgen problemas para aplicar la teoría tal cual y que hay que resolver.

Nodos que aparecen y desaparecen

Si los nodos WiFi que usas como referencia están siempre encendidos el hecho de que un nodo no esté entre tus mediciones indica que potencia es 0 y es un gran indicador de donde estamos. Pero si usas los WiFis de tus vecinos el que se apaguen a lo largo del día es algo más habitual de lo que parece. Por lo que tenemos nodos que aparecen y desaparecen. Así que si un nodo no esta entre tus mediciones no se puede considerar que su potencia es 0 (aunque lo sea en ese momento) ya que puedes estar falseando los resultados. Mi experiencia es que si no tienes medición de un nodo lo descartes y no lo tengas en cuenta en tus cálculos.

Ruido en las mediciones

Los valores de potencia pueden variar muchísimo al realizar una medición, mi consejo es que realices varias medidas (yo uso 3) y te quedes con la mediana o la moda de las mismas. Es muy importante sobretodo que realices esto al generar la base de datos de los puntos de referencia.

Otro problema es que no todas los nodos se ven sometidos a las mismas variaciones, contra menor potencia tengan en ese punto más propensas son a sufrir variaciones y más amplias son estas. En algunos casos resulta conveniente fijar un umbral mínimo de potencia para tener en cuenta ese nodo.

Variación de las medidas usando distintos aparatos.

Es recomendable usar el mismo “aparato” para generar la base de datos de puntos que el que luego se va a intentar localizar. Las medidas entre mi portátil, mi smartphone y mi placa Node MCU eran suficientemente distintas como para causar errores si intentaba comprar unas con otras

Guardar datos de nodeMCU (o arduino) en la nube usando IFTTT

La idea es usar IFTTT, que permite interconectar varios servicios, para que nos sirva de repositorio de datos de nuestros sistemas IoT desarrollados con arduino, esp8266, nodeMCU o similares. ¡Y además gratis!.

Webhooks

Nuestro sistema enviara una petición HTTP (GET o POST) al servicio de IFTTT para ello hay que crearse una cuenta allí y activar un evento por webhook, que recibirá los datos que le enviemos.

Los webhook de IFTTT solo permiten pasar hasta tres valores que ademas tiene que ser value1, value2 y value3.

Incluyo un ejemplo de enviar un petición con nodeMCU con 3 valores:

 
void sendMsg(){ 
  http.begin("http://maker.ifttt.com/[tu codigo]/alarm/with/key/[pon aqui tu key]?value1=1&values2=2&value3=3"); //HTTP 
  int httpCode = http.GET(); 
  if(httpCode > 0){
    Serial.println("Alarm send"); 
  } else {
    Serial.println("Error send alarm"); 
  } 
  delay(1000); 
}
 


IFTTT recibe un nombre de evento, tres parámetros y el timestamp de cuando ha ocurrido el evento:

{{OccurredAt}}
{{EventName}}
{{Value1}}
{{Value2}}
{{Value3}}

Okey tenemos esos cinco parámetros ¿Que podemos hacer con ellos?

El que incluya la hora del evento es muy útil ya que muchos sistemas no tiene un reloj y no pueden saber que hora es.

Hay que tener en cuenta es si tenemos una sola placa emitiendo datos o tenemos varias. Si tenemos varias podemos usar el nombre del evento o uno de los valores para indicar que placa es, es algo muy útil sobre todo cuando una de ellas empieza a dar datos erróneos así resulta fácil filtrarlos.

Puede parecer que un nombre de evento y tres valores son pocos pero para muchos sistemas de IoT son mas que suficientes.

Hoja de cálculo

Mi primera idea es guardar los datos que nos interese en una hoja de calculo de Google. IFTTT nos permite guardar los datos en filas, con una columna cada datos. Hasta 2000 filas, luego no deja de guardarlas, pero crea otra hoja de cálculo.

La ventaja de este sistema es que podemos conectarlo para que genere tablas, gráficas o realice cálculos de forma automática. Con poco trabajo nos podemos montar un sistema que almacene y procese lo datos generando informes y gráficas todo ello gratis.

Fichero de texto

Otra opción es usar un fichero de texto y almacenar los datos estilo CSV, que consiste en separar los valores por comas y ya esta. Se pueden usar varios, en mi caso opte por Dropbox. La ventaja de este tipo de ficheros es que es muy sencillo de procesar por cualquier dispositivo. De hecho hay tres maneras de hacerlo con Dropbox.

  • Sincronización: tener Dropbox sincronizado en el dispositivo con lo que el fichero de actualiza “solo” con cada cambio
  • API: usar la API de Dropbox para acceder a ese fichero
  • Publico: Dropbox permite crear enlaces públicos a ficheros. Una vez generado ese enlace leer es fichero es tan sencillo como hace una petición GET

En el caso de este tipo de ficheros el limite de IFTTT esta en 2 megas de datos.

Redes sociales

Si los datos han de ser compartidos con otras personas, las redes sociales pueden ser una buena solución, por ejemplo una cuanta de Twitter (privada si no quieres que los datos sean accesibles por todos). Además también se puede automatizar el acceso a los datos usando la API de Twitter

Notificaciones

Si los avisos tienen que llegar en tiempo real (o casi) se pueden usar las notificaciones a móvil (ya hice un ejemplo) o si tienen que llegar a un grupo de gente se pueden notificar en un grupo de Telegram. Este mismo sistema se puede usar para notificaciones personales si quieres guardar un histórico de ellas.

Calendario

Este caso es solo una idea, pero en el caso de eventos que ocurran solo de vez en cuando y se quiera tener un registro de cuando ocurrieron se podría usar la integración con alguno de los calendarios.

No resulta útil para eventos muy numerosos ya que es difícil de consultar cuando hay muchos en un día

¿Es inteligente todo lo que parece inteligente?

Todos hemos oído hablar del test de Turing u otras pruebas para medir la inteligencia de los agentes inteligentes. La habitación china plantea un escenario que reta la validez de estos test. Voy a explicarla de una manera diferente a la habitual pero que creo que es más sencilla de entender. Una habitación china es una caja donde metes un texto y obtienes una respuesta coherente. Podrida ser un chatbot que superase el test de Turing. Le introduces preguntas y obtienes una respuesta coherente. El comportamiento visto desde fuera es inteligente. ¿Pero realmente lo es? ¿Cómo distinguimos algo que actúa como si fuera inteligente de algo que es inteligente?. (Vamos a dejar de lado que muchas veces solo consideramos inteligentes comportamientos humanos)

Supongamos una inteligencia artificial que funciona de forma similar a la habitación china, pero que en lugar de responder preguntas juega a las damas o al ajedrez. Parar ello no tiene un complicado algoritmo para deducir el siguiente movimiento, tiene una base de datos con todos los posibles movimientos y sus posible respuestas. Para juegos como el ajedrez o el go eso es imposible pero es posible para juegos mucho mas sencillos como el tres en raya, el conecta 4 o incluso algunas versiones dé las damas. Esta IA solo busca la posición actual en su base de datos y nos responde con el mejor movimiento. Desde fuera nos parecerá un jugador realmente bueno y lo clasificaríamos como inteligente, sin embargo no actúa de forma mucho más inteligente que cualquier otra búsqueda en un base de datos.

Si habéis visto análisis de partidas de ajedrez o de go donde alguno de los jugadores es una I.A. veréis que los comentaristas hablan de “estrategia”, como los movimientos que se han realizado en momentos anteriores de la partida le han permitido colocar sus fichas en la posición para ganar la partida o tomar ventaja al rival o “asestar un golpe al tablero”. El problema es que las maquinas no tienen estrategia de ningún tipo, o al menos no nuestra idea de “tener una estrategia” estos algoritmos en su mayor parte ven el tablero cada vez de manera independiente a las anteriores. Es decir cada vez que tiene que decidir parten de cero, observan el tablero, deciden el mejor movimiento y excepto por datos que se almacenen para no volver calcularlos olvidan todo para su próximo movimiento. Para estas I.A. la partida como tal no existe, una partida es una sucesión de tableros para los que deciden cual es el mejor movimiento sin pensar en los anteriores tableros ni en los siguientes. Lo mismo les daría llegar a mitad de una partida. Esta forma de jugar es inconcebible para un humano, nosotros desarrollamos estrategias e intentamos llevarlas acabo. La I.A. parte del tablero actual, simula posibles movimientos, valora posiciones y elige aquel que piensa que le da más probabilidades de ganar y olvida todo eso en el siguiente movimiento.

Ahora mismo tenemos algoritmos que serian capaces de trazar un plan y que la I.A. elija sus movimientos para cumplir ese plan. Esa forma de actuar Seria más  apreciada a la forma de los humanos e crear una estrategia, sin embargo no se usan para este tipo de juegos porque no dan tan buen resultado.

¿No podria pasar lo mismo con la inteligencia de lo que nos pasa con estrategia? ¿Qué algo nos parezca inteligente pero no es nada más que una interpretación que hacemos nosotros de forma engañosa? Y volvemos a la habitación china y a su maquina que no piensa, solo busca respuestas de una enorme base de conocimientos. Que actúa de forma que parece (o es) inteligente.

¿Cuál es la definición de inteligencia? Pues sorprendentemente (o no) no existe un única definición, no se tiene muy claro ni el alcance de lo que es inteligencia. La inteligencia parece recoger diferentes fenómenos y capacidades. Gente que decimos que es inteligente: si entiendes textos complicados, si resuelves problemas matemáticos complejos, si eres bueno en algún aspecto técnico, si eres de respuesta rápida, si tiene una lenguaje muy rico, si tienes bastos conocimientos…. hay ejemplos para aburrir. Nos resulta fácil decir que es inteligente, pero no definirlo.

Incluso a nivel humano cuesta, por ejemplo el cubo de Rubik. La primera vez que te dan un cubo de Rubik y tratas de resolverlo te sorprende que haya gente que sea capaz de resolverlo, tienen que ser tremendamente inteligentes. Cuando investigas un poco, ves que hay técnicas para resolverlo y que en muchos casos es más un asunto de memoria y habilidad. De repente algo que nos parecía sin duda inteligente ha perdido parte de “inteligencia”. Sin embargo parte de ser un gran jugador de muchos juegos necesitas aprender de memoria gran cantidad de movimientos y posiciones para no tener que pensarlos de cero cada partida.

 Si vemos la inteligencia más como un fenómeno, un resultado de las acciones, cualquier cosa que parezca inteligente sería inteligente. Daría igual que supiéramos resolver cubos de Rubik gracias a nuestro razonamiento o a nuestra memoria. En ese caso el test de Turing volvería a ser válido. Es decir la habitación china nos obliga a plantearnos si vamos considerar inteligente todo lo que se comporta de forma inteligente o si vamos a más requisitos. teniendo en cuenta que ni siquiera estamos seguros de nuestra inteligencia o nuestro libre albedrío yo no seria muy exigente.