Bilateration with iBeacons

1k views Asked by At

I am trying to use multiple iBeacons to track the user's location in iOS. I know this can be done (somewhat) using 3 beacons and trilateration, but I would like to do it with two (bilateration). I know that I will likely end up with two answers. Does anyone know of a simple way to accomplish this, given the (x,y) location of the beacons (relative to the room), and an averaged RSSI from each beacon?

I have this code for trilateration that I altered to objective-c from 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;
}
1

There are 1 answers

0
rmooney On

So this is the code I ended up using, thanks to ChuckCottrill's suggestion that I look for a formula to calculate intersection of two circles. It is modified from a C version I found online here: http://paulbourke.net/geometry/circlesphere/tvoght.c

The results are somewhat inconsistent due to the inconsistency of the RSSI values returned from the iBeacons.

I will still need to add code to select the correct point somehow (it gives two results).

- (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;
}