Билатерация с iBeacons

Я пытаюсь использовать несколько iBeacons для отслеживания местоположения пользователя в iOS. Я знаю, что это можно сделать (в некоторой степени), используя 3 маяка и трилатерацию, но я хотел бы сделать это с двумя (билатерация). Я знаю, что, скорее всего, у меня будет два ответа. Кто-нибудь знает простой способ сделать это, учитывая (x, y) расположение маяков (относительно комнаты) и усредненный RSSI от каждого маяка?

У меня есть этот код для трилатерации, который я изменил на target-c из javascript:

- (CGPoint)getTrilaterationWithBeacon1:(BBBeacon *)beacon1 Beacon2:(BBBeacon *)beacon2 Beacon3:(BBBeacon *)beacon3 {
    float xa = beacon1.x;
    float ya = beacon1.y;
    float xb = beacon2.x;
    float yb = beacon2.y;
    float xc = beacon3.x;
    float yc = beacon3.y;
    float ra = beacon1.distance;
    float rb = beacon2.distance;
    float rc = beacon3.distance;

    float S = (pow(xc, 2.) - pow(xb, 2.) + pow(yc, 2.) - pow(yb, 2.) + pow(rb, 2.) - pow(rc, 2.)) / 2.0;
    float T = (pow(xa, 2.) - pow(xb, 2.) + pow(ya, 2.) - pow(yb, 2.) + pow(rb, 2.) - pow(ra, 2.)) / 2.0;
    float y = ((T * (xb - xc)) - (S * (xb - xa))) / (((ya - yb) * (xb - xc)) - ((yc - yb) * (xb - xa)));
    float x = ((y * (ya - yb)) - T) / (xb - xa);

    CGPoint point = CGPointMake(x, y);
    return point;
}

person rmooney    schedule 07.01.2014    source источник
comment
У вас есть только две точки a(x,y) и b(x,y), а не три (у вас нет c(x,y)). И у вас есть только два расстояния, a(r) и b(r), поэтому вам нужно вычислить пересечение двух окружностей a(x,y,r) и b(x,y,r). Найдите формулу для вычисления пересечения двух окружностей.   -  person ChuckCottrill    schedule 07.01.2014
comment
Я имел удовольствие поиграть с маяком Qualcomm, и я думаю, что маяки не годятся для точного позиционирования в помещении. Если вы остаетесь в одном положении, уровень сигнала все равно меняется, плюс это зависит от батареи, окружающей среды и прочего. Маяки хороши тем, что говорят вам, что вы близки к чему-то.   -  person Dávid Kaszás    schedule 07.01.2014
comment
Согласен с Кашашем: RSSI — отвратительный индикатор расстояния. Он будет сильно различаться в зависимости от таких трудно учитываемых факторов, как относительная ориентация антенны, препятствия в комнате (особенно люди для сигналов 2,4 ГГц), помехи от других устройств и т. д. и т. д. Во что бы то ни стало, попробуйте, но будьте готовы к разочарованию.   -  person ryanm    schedule 08.01.2014


Ответы (1)


Итак, это код, который я в итоге использовал, благодаря предложению Чаккоттрила найти формулу для вычисления пересечения двух кругов. Он изменен из версии C, которую я нашел в Интернете здесь: http://paulbourke.net/geometry/circlesphere/tvoght.c

Результаты несколько противоречивы из-за несогласованности значений RSSI, возвращаемых iBeacons.

Мне все равно нужно будет добавить код, чтобы как-то выбрать правильную точку (это дает два результата).

- (CGPoint)getBilaterationWithBeacon1:(BBBeacon *)beacon1 Beacon2:(BBBeacon *)beacon2 {
    float x0 = beacon1.locationX;
    float y0 = beacon1.locationY;
    float r0 = beacon1.filteredDistance;
    float x1 = beacon2.locationX;
    float y1 = beacon2.locationY;
    float r1 = beacon2.filteredDistance;

    float a, dx, dy, d, h, rx, ry;
    float x2, y2;

    /* dx and dy are the vertical and horizontal distances between
     * the circle centers.
     */
    dx = x1 - x0;
    dy = y1 - y0;

    /* Determine the straight-line distance between the centers. */
    d = sqrt((dy*dy) + (dx*dx));

    /* Check for solvability. */
    if (d > (r0 + r1)) {
        /* no solution. circles do not intersect. */
        return CGPointMake(-1, -1);
    }
    if (d < abs(r0 - r1)) {
        /* no solution. one circle is contained in the other */
        return CGPointMake(-1, -1);
    }

    /* 'point 2' is the point where the line through the circle
     * intersection points crosses the line between the circle
     * centers.
     */

    /* Determine the distance from point 0 to point 2. */
    a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ;

    /* Determine the coordinates of point 2. */
    x2 = x0 + (dx * a/d);
    y2 = y0 + (dy * a/d);

    /* Determine the distance from point 2 to either of the
     * intersection points.
     */
    h = sqrt((r0*r0) - (a*a));

    /* Now determine the offsets of the intersection points from
     * point 2.
     */
    rx = -dy * (h/d);
    ry = dx * (h/d);

    /* Determine the absolute intersection points. */
    float xi = x2 + rx;
    float xi_prime = x2 - rx;
    float yi = y2 + ry;
    float yi_prime = y2 - ry;

    CGPoint point1 = CGPointMake(xi, yi);
    CGPoint point2 = CGPointMake(xi_prime, yi_prime);

    //pick one

    return point2;
}
person rmooney    schedule 08.01.2014