tool example eddystone comprar beacons beacon bluetooth-lowenergy ibeacon

bluetooth-lowenergy - example - estimote



Ejemplo triangular para iBeacons (13)

Estoy estudiando la posibilidad de utilizar múltiples iBeacons para hacer una ubicación de posición interior "accidentada". La aplicación es una especie de configuración de ''museo'', y sería más fácil poder formar una cuadrícula con ubicaciones para los diferentes objetos que balizas individuales (aunque eso podría no ser imposible también).

¿Hay ejemplos, experiencias, con el uso de múltiples balizas para triangular en algún tipo de ubicación, o alguna lógica que me ayude a escribirlo yo mismo?


Aquí hay una biblioteca java de código abierto que realizará la trilateración / multilateración: https://github.com/lemmingapex/Trilateration

Utiliza un optimizador no lineal de mínimos cuadrados, el algoritmo Levenberg-Marquardt, de Apache Commons Math.

double[][] positions = new double[][] { { 5.0, -6.0 }, { 13.0, -15.0 }, { 21.0, -3.0 }, { 12.42, -21.2 } }; double[] distances = new double[] { 8.06, 13.97, 23.32, 15.31 }; NonLinearLeastSquaresSolver solver = new NonLinearLeastSquaresSolver(new TrilaterationFunction(positions, distances), new LevenbergMarquardtOptimizer()); Optimum optimum = solver.solve(); // the answer double[] calculatedPosition = optimum.getPoint().toArray(); // error and geometry information RealVector standardDeviation = optimum.getSigma(0); RealMatrix covarianceMatrix = optimum.getCovariances(0);

La mayoría de los ejemplos académicos, como el de wikipedia , tratan exactamente tres círculos y asumen información perfectamente precisa. Estas circunstancias permiten formulaciones de problemas mucho más simples con respuestas exactas, y generalmente no son satisfactorias para situaciones prácticas.

El problema en el espacio euclidiano R 2 o R 3 con distancias que contienen error de medición, un área (elipse) o volumen (elipsoide) de interés se obtiene generalmente en lugar de un punto. Si se desea una estimación puntual en lugar de una región, se debe usar el centroide o el centroide del volumen. El espacio R 2 requiere al menos 3 puntos y distancias no degenerados para obtener una región única; y de forma similar, el espacio R 3 requiere al menos 4 puntos y distancias no degenerados para obtener una región única.


Ecuación alternativa

- (CGPoint)getCoordinateWithBeaconA:(CGPoint)a beaconB:(CGPoint)b beaconC:(CGPoint)c distanceA:(CGFloat)dA distanceB:(CGFloat)dB distanceC:(CGFloat)dC { CGFloat x, y; x = ( ( (pow(dA,2)-pow(dB,2)) + (pow(c.x,2)-pow(a.x,2)) + (pow(b.y,2)-pow(a.y,2)) ) * (2*c.y-2*b.y) - ( (pow(dB,2)-pow(dC,2)) + (pow(c.x,2)-pow(c.x,2)) + (pow(c.y,2)-pow(b.y,2)) ) *(2*b.y-2*a.y) ) / ( (2*b.x-2*c.x)*(2*b.y-2*a.y)-(2*a.x-2*b.x)*(2*c.y-2*b.y) ); y = ( (pow(dA,2)-pow(dB,2)) + (pow(c.x,2)-pow(a.x,2)) + (pow(b.y,2)-pow(a.y,2)) + x*(2*a.x-2*b.x)) / (2*b.y-2*a.y); return CGPointMake(x, y); }


El posicionamiento preciso en interiores con iBeacon será un reto por las siguientes razones:

  1. Como se señaló en comentarios anteriores, la señal de iBeacon tiende a fluctuar mucho. La razón es que incluye el efecto multipath , las obstrucciones dinámicas entre el teléfono y iBeacon cuando la persona se está moviendo, otras interferencias de 2.4GHz y más. De modo que, idealmente, no desea confiar en los datos de 1 paquete único y, en su lugar, hacer un promedio de varios paquetes del mismo dispositivo. Eso requeriría que la distancia del teléfono / baliza no cambie demasiado entre esos varios paquetes. Para los paquetes BLE generales (como las balizas de StickNFind) se puede configurar fácilmente a una velocidad de baliza de 10Hz. Sin embargo, para iBeacon, será difícil, porque
  2. La frecuencia de balizaje de iBeacon probablemente no puede ser superior a 1Hz. Me alegrará si alguien puede señalar a la fuente que dice lo contrario, pero toda la información que he visto hasta el momento confirma esta afirmación. Eso en realidad tiene sentido, ya que la mayoría de las iBeacons funcionarán con baterías y la alta frecuencia tendrá un impacto significativo en la duración de la batería. Teniendo en cuenta que la velocidad promedio para caminar de las personas es de 5.3km (~ 1.5 m / s), incluso si solo usas un modesto paquete de 3 faros para hacer el promedio, será difícil obtener ~ 5 m de precisión.

Por otro lado, si puede aumentar la frecuencia de iBeacon a más de 10 Hz (lo que dudo que sea posible), entonces es posible tener una precisión de 5 mo superior con un método de procesamiento adecuado. En primer lugar, las soluciones triviales basadas en la Ley del Cuadrado Inverso , como la trilateración, a menudo no funcionan bien porque en la práctica la relación distancia / RSSI para diferentes balizas a menudo está muy alejada de la Ley Sqare inversa por el motivo 1 anterior. Pero mientras el RSSI sea relativamente estable para una cierta baliza en cualquier ubicación determinada (que generalmente es el caso), puede usar un enfoque llamado huella digital para lograr una mayor precisión. Un método común utilizado para la toma de huellas dactilares es kNN ( k-Nearest Neighbourhood ).

Actualización 2014-04-24

Algunos iBeacons pueden transmitir más de 1Hz, como Estimote usa 5Hz por defecto. Sin embargo, de acuerdo con este link : " Esta es la restricción de Apple. IOS devuelve balizas que se actualizan cada segundo, sin importar la frecuencia con la que el dispositivo anuncia ". Hay otro comentario allí (probablemente del vendedor de Estimote) que dice " Nuestras balizas pueden transmitir mucho más rápido y puede mejorar los resultados y la medición ". Entonces, si una mayor frecuencia de iBeacon es beneficiosa no está claro.


Encontré la solución de Vishnu Prahbu muy útil. Lo porté a c #, si alguien lo necesita.

public static PointF GetLocationWithCenterOfGravity(PointF a, PointF b, PointF c, float dA, float dB, float dC) { //http://.com/questions/20332856/triangulate-example-for-ibeacons var METERS_IN_COORDINATE_UNITS_RATIO = 1.0f; //http://.com/a/524770/663941 //Find Center of Gravity var cogX = (a.X + b.X + c.X) / 3; var cogY = (a.Y + b.Y + c.Y) / 3; var cog = new PointF(cogX,cogY); //Nearest Beacon PointF nearestBeacon; float shortestDistanceInMeters; if (dA < dB && dA < dC) { nearestBeacon = a; shortestDistanceInMeters = dA; } else if (dB < dC) { nearestBeacon = b; shortestDistanceInMeters = dB; } else { nearestBeacon = c; shortestDistanceInMeters = dC; } //http://www.mathplanet.com/education/algebra-2/conic-sections/distance-between-two-points-and-the-midpoint //Distance between nearest beacon and COG var distanceToCog = (float)(Math.Sqrt(Math.Pow(cog.X - nearestBeacon.X, 2) + Math.Pow(cog.Y - nearestBeacon.Y, 2))); //Convert shortest distance in meters into coordinates units. var shortestDistanceInCoordinationUnits = shortestDistanceInMeters * METERS_IN_COORDINATE_UNITS_RATIO; //http://math.stackexchange.com/questions/46527/coordinates-of-point-on-a-line-defined-by-two-other-points-with-a-known-distance?rq=1 //On the line between Nearest Beacon and COG find shortestDistance point apart from Nearest Beacon var t = shortestDistanceInCoordinationUnits / distanceToCog; var pointsDiff = new PointF(cog.X - nearestBeacon.X, cog.Y - nearestBeacon.Y); var tTimesDiff = new PointF(pointsDiff.X * t, pointsDiff.Y * t); //Add t times diff with nearestBeacon to find coordinates at a distance from nearest beacon in line to COG. var userLocation = new PointF(nearestBeacon.X + tTimesDiff.X, nearestBeacon.Y + tTimesDiff.Y); return userLocation; }


He estado haciendo algunos experimentos para obtener una posición precisa usando tres balizas.

Resultados de la trilateración

Desafortunadamente, los resultados fueron muy decepcionantes en términos de calidad. Hubo principalmente dos problemas:

  1. En entornos no controlados, donde puede encontrar metales y otros objetos que afectan la señal, la intensidad de la señal recibida de las balizas cambia tan a menudo que parece imposible obtener un rango de error inferior a 5 metros.
  2. Dependiendo de la forma en que el usuario maneje el dispositivo receptor, las lecturas pueden cambiar mucho también. Si el usuario pone su mano sobre la antena del bluetooth, entonces el algoritmo tendrá señales bajas como entrada, y por lo tanto se supone que las balizas estarán muy lejos del dispositivo. Vea esta imagen para ver la ubicación precisa de la antena Bluetooth.

Soluciones posibles

Después de hablar con un ingeniero de Apple que activamente me desalentó a seguir por este camino, la opción que me siento más inclinado a usar en este momento es la fuerza bruta. Intente configurar una baliza cada X metros (X es el error máximo tolerado en el sistema) para que podamos rastrear en esta cuadrícula de balizas la posición de un dispositivo determinado calculando qué baliza en la red es la más cercana al dispositivo y suponiendo que el dispositivo está en la misma posición.

Algoritmo de trilateración

Sin embargo, para completar, comparto debajo de la función central del algoritmo de trilateración. Se basa en el párrafo 3 ("Tres distancias conocidas") de este artículo .

- (CGPoint)getCoordinateWithBeaconA:(CGPoint)a beaconB:(CGPoint)b beaconC:(CGPoint)c distanceA:(CGFloat)dA distanceB:(CGFloat)dB distanceC:(CGFloat)dC { CGFloat W, Z, x, y, y2; W = dA*dA - dB*dB - a.x*a.x - a.y*a.y + b.x*b.x + b.y*b.y; Z = dB*dB - dC*dC - b.x*b.x - b.y*b.y + c.x*c.x + c.y*c.y; x = (W*(c.y-b.y) - Z*(b.y-a.y)) / (2 * ((b.x-a.x)*(c.y-b.y) - (c.x-b.x)*(b.y-a.y))); y = (W - 2*x*(b.x-a.x)) / (2*(b.y-a.y)); //y2 is a second measure of y to mitigate errors y2 = (Z - 2*x*(c.x-b.x)) / (2*(c.y-b.y)); y = (y + y2) / 2; return CGPointMake(x, y); }


Implementé un algoritmo de Huellas dactilares muy simple para Android 4.4, probado en un entorno relativamente "malo":

  • casi 10 wifi AP cerca.
  • varias otras señales de Bluetooth cercanas.

la precisión parece en 5-8 metros y depende de cómo coloqué a ese 3 locutor de Ibeacon. El algoritmo es bastante simple y creo que puedes implementar uno solo, los pasos son:

  1. carga el mapa de interior
  2. muestreo con el mapa para todos los puntos de posicionamiento pendientes.
  3. registrar todos los datos de muestreo, los datos deben incluir: coordenadas del mapa, señales de posición y su RSSI.

entonces, cuando comienzas a posicionarte, es solo un reverso de los pasos a seguir.


Lo que realmente me ayudó fue este proyecto en Code.Google.com: https://code.google.com/p/wsnlocalizationscala/ contiene muchos códigos, varios algoritmos de trilateración, todo escrito en C #. Es una gran biblioteca, pero no pretende ser usada "out-of-the-box".


Mi arquitecto / gerente, que escribió el siguiente algoritmo,

public static Location getLocationWithCenterOfGravity(Location beaconA, Location beaconB, Location beaconC, double distanceA, double distanceB, double distanceC) { //Every meter there are approx 4.5 points double METERS_IN_COORDINATE_UNITS_RATIO = 4.5; //http://.com/a/524770/663941 //Find Center of Gravity double cogX = (beaconA.getLatitude() + beaconB.getLatitude() + beaconC.getLatitude()) / 3; double cogY = (beaconA.getLongitude() + beaconB.getLongitude() + beaconC.getLongitude()) / 3; Location cog = new Location("Cog"); cog.setLatitude(cogX); cog.setLongitude(cogY); //Nearest Beacon Location nearestBeacon; double shortestDistanceInMeters; if (distanceA < distanceB && distanceA < distanceC) { nearestBeacon = beaconA; shortestDistanceInMeters = distanceA; } else if (distanceB < distanceC) { nearestBeacon = beaconB; shortestDistanceInMeters = distanceB; } else { nearestBeacon = beaconC; shortestDistanceInMeters = distanceC; } //http://www.mathplanet.com/education/algebra-2/conic-sections/distance-between-two-points-and-the-midpoint //Distance between nearest beacon and COG double distanceToCog = Math.sqrt(Math.pow(cog.getLatitude() - nearestBeacon.getLatitude(),2) + Math.pow(cog.getLongitude() - nearestBeacon.getLongitude(),2)); //Convert shortest distance in meters into coordinates units. double shortestDistanceInCoordinationUnits = shortestDistanceInMeters * METERS_IN_COORDINATE_UNITS_RATIO; //http://math.stackexchange.com/questions/46527/coordinates-of-point-on-a-line-defined-by-two-other-points-with-a-known-distance?rq=1 //On the line between Nearest Beacon and COG find shortestDistance point apart from Nearest Beacon double t = shortestDistanceInCoordinationUnits/distanceToCog; Location pointsDiff = new Location("PointsDiff"); pointsDiff.setLatitude(cog.getLatitude() - nearestBeacon.getLatitude()); pointsDiff.setLongitude(cog.getLongitude() - nearestBeacon.getLongitude()); Location tTimesDiff = new Location("tTimesDiff"); tTimesDiff.setLatitude( pointsDiff.getLatitude() * t ); tTimesDiff.setLongitude(pointsDiff.getLongitude() * t); //Add t times diff with nearestBeacon to find coordinates at a distance from nearest beacon in line to COG. Location userLocation = new Location("UserLocation"); userLocation.setLatitude(nearestBeacon.getLatitude() + tTimesDiff.getLatitude()); userLocation.setLongitude(nearestBeacon.getLongitude() + tTimesDiff.getLongitude()); return userLocation; }

  1. Calcula el centro de gravedad de un triángulo (3 balizas)
  2. calcular la distancia más corta / faro más cercano
  3. Calcule la distancia entre la baliza y el centro de gravedad
  4. Convierte la distancia más corta en unidades de coordenadas, que es solo una constante, solía predecir la precisión. Puedes probar con varing la constante
  5. calcular la distancia delta
  6. agregue el delta con el faro más cercano x, y.

Después de probarlo, lo encontré con una precisión de 5 metros.

Por favor coménteme sus pruebas, si podemos refinarlo.


Miré en esto. El término que quiere es trilateración. (En triangulación tienes ángulos de 3 puntos conocidos. En trilateración tienes distancia de 3 puntos conocidos) Si lo buscas en Google, deberías encontrar varios artículos, incluido uno en Wiki. Implica resolver un conjunto de 3 ecuaciones simultáneas. Los documentos que vi fueron para la trilateración en 3D: 2D es más fácil porque solo puedes soltar el término Z.

Lo que encontré fue matemática abstracta. Todavía no me he tomado el tiempo para mapear el algoritmo general en un código específico, pero planeo abordarlo en algún momento.

Tenga en cuenta que los resultados que obtendrá serán MUY crudos, especialmente en cualquier cosa que no sea una habitación vacía. Las señales son lo suficientemente débiles como para que una persona, una estatua o cualquier cosa que bloquee la línea de visión aumenten significativamente sus lecturas de distancia. Incluso podría tener lugares en un edificio donde la interferencia constructiva (principalmente desde las paredes) hace que algunos lugares se lean mucho más cerca de lo que realmente son.


Para aquellos que necesitan la función de trilateración de @Javier Chávarri para dispositivos Android (por ahorrar algo de tiempo):

public static Location getLocationWithTrilateration(Location beaconA, Location beaconB, Location beaconC, double distanceA, double distanceB, double distanceC){ double bAlat = beaconA.getLatitude(); double bAlong = beaconA.getLongitude(); double bBlat = beaconB.getLatitude(); double bBlong = beaconB.getLongitude(); double bClat = beaconC.getLatitude(); double bClong = beaconC.getLongitude(); double W, Z, foundBeaconLat, foundBeaconLong, foundBeaconLongFilter; W = distanceA * distanceA - distanceB * distanceB - bAlat * bAlat - bAlong * bAlong + bBlat * bBlat + bBlong * bBlong; Z = distanceB * distanceB - distanceC * distanceC - bBlat * bBlat - bBlong * bBlong + bClat * bClat + bClong * bClong; foundBeaconLat = (W * (bClong - bBlong) - Z * (bBlong - bAlong)) / (2 * ((bBlat - bAlat) * (bClong - bBlong) - (bClat - bBlat) * (bBlong - bAlong))); foundBeaconLong = (W - 2 * foundBeaconLat * (bBlat - bAlat)) / (2 * (bBlong - bAlong)); //`foundBeaconLongFilter` is a second measure of `foundBeaconLong` to mitigate errors foundBeaconLongFilter = (Z - 2 * foundBeaconLat * (bClat - bBlat)) / (2 * (bClong - bBlong)); foundBeaconLong = (foundBeaconLong + foundBeaconLongFilter) / 2; Location foundLocation = new Location("Location"); foundLocation.setLatitude(foundBeaconLat); foundLocation.setLongitude(foundBeaconLong); return foundLocation; }


Si eres como yo y no te gustan las matemáticas, es posible que desees hacer una búsqueda rápida de "sdk de posicionamiento en interiores". Hay muchas compañías que ofrecen posicionamiento en interiores como servicio.

Enchufe desvergonzado: trabajo para indoo.rs y puedo recomendar este servicio. También incluye el enrutamiento y demás en el posicionamiento "justo" en interiores.


También estamos tratando de encontrar la mejor manera de ubicar con precisión a alguien en una habitación utilizando iBeacons. El problema es que la potencia de la señal de la baliza no es constante y se ve afectada por otras señales de 2,4 Ghz, objetos metálicos, etc., para lograr la máxima precisión es necesario calibrar cada baliza individualmente, y una vez que se haya colocado en la posición deseada . (y realice algunas pruebas de campo para ver las fluctuaciones de señal cuando otros dispositivos Bluetooth estén presentes). También tenemos algunos iBeacons de Estimote (el mismo del video de Konrad Dzwinel), y ya han desarrollado una demostración técnica de lo que se puede hacer con las iBeacons. Dentro de su aplicación es posible ver un radar en el que se muestran iBeacons. A veces es bastante preciso, pero a veces no lo es (y parece que el movimiento del teléfono no se considera para calcular las posiciones). Verifique la demostración en el video que hicimos aquí: http://goo.gl/98hiza

Aunque en teoría 3 iBeacons debería ser suficiente para lograr una buena precisión, tal vez en situaciones del mundo real se necesiten más balizas para garantizar la precisión que está buscando.


Verifique la referencia https://proximi.io/accurate-indoor-positioning-bluetooth-beacons/

Proximi SDK se encargará de la triangulación. Este SDK proporciona bibliotecas para manejar toda la lógica para el posicionamiento de la baliza, la triangulación y el filtrado de forma automática en el fondo. Además de balizas, puede combinar IndoorAtlas, Wi-Fi, GPS y posicionamiento celular.