J'ai fait quelques expériences pour obtenir une position précise à l'aide de trois balises.
Résultats de trilatération
Malheureusement, les résultats ont été très décevants en termes de qualité. Il y avait principalement deux questions:
- En non-environnements contrôlés, où vous pouvez trouver des métaux et d'autres objets qui affectent le signal, la force du signal reçu de balises change tellement souvent qu'il semble impossible d'obtenir une marge d'erreur inférieure à 5 mètres.
- Selon la manière dont l'utilisateur est de la manipulation de l'appareil récepteur, les valeurs de mesure peuvent changer beaucoup de choses. Si l'utilisateur met sa main sur l'antenne bluetooth, puis l'algorithme ont de faibles signaux d'entrée, et donc les balises censé être très loin de l'appareil. Voir cette image pour voir l'emplacement précis de l'antenne Bluetooth.
Solutions possibles
Après avoir parlé avec une Pomme ingénieur qui a activement m'a découragé d'aller vers le bas de cette façon, l'option je me sens plus enclins à utiliser est la force brute. Essayez de mettre en place une balise tous les X mètres (X étant l'erreur maximale tolérée dans le système afin que nous puissions le suivre sur ce phares de la grille de la position d'un appareil donné par le calcul qui balise sur la grille la plus proche de l'appareil et en supposant que l'appareil est sur la même position.
Trilatération algorithme
Toutefois, par souci d'exhaustivité, je partage ci-dessous la fonction de base de la trilatération algorithme. Il est basé sur le paragraphe 3 ("Trois distances connues") de cet article.
- (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);
}