6

Grid

(The small dots in the corners are the nodes and the red dot is the person being tracked)

Coordinates:

Node   X    Y   Position
1      0    0   Top left
2    450    0   Top right
3      0  450   Bottom left
4    450  450   Bottom right

Person    X    Y
Red dot  84   68

Method to get signal strength:

(Just need the signal strength relative to other nodes, which it seem to achieve. Or am I wrong here?)

public int GetSignalStrength(OvalShape node)
{
    int xd = node.Left - this.person.Left;
    int yd = node.Top - this.person.Top;

    var signalStrength = Math.Sqrt((xd * xd) + (yd * yd));

    return Convert.ToInt32(-signalStrength);
}

Signal strengths:

Node   Signal Strength
1                 -108
2                 -372
3                 -391
4                 -529

Method to get coordinates of person:

(s1, s2, s3, s4 are the signal strengths above)

public int[] GetPositionInGrid(int s1, int s2, int s3, int s4)
{
    var tx1 = this.node1.Left;
    var ty1 = this.node1.Top;

    var tx2 = this.node2.Left;
    var ty2 = this.node2.Top;

    var tx3 = this.node3.Left;
    var ty3 = this.node3.Top;

    var tx4 = this.node4.Left;
    var ty4 = this.node4.Top;

    double w1 = ((double)s1) / ((double)(s1 + s2 + s3 + s4));
    double w2 = ((double)s2) / ((double)(s1 + s2 + s3 + s4));
    double w3 = ((double)s3) / ((double)(s1 + s2 + s3 + s4));
    double w4 = ((double)s4) / ((double)(s1 + s2 + s3 + s4));

    var px = ((tx1 * w1) + (tx2 * w2) + (tx3 * w3) + (tx4 * w4)) / (w1 + w2 + w3 + w4);
    var py = ((ty1 * w1) + (ty2 * w2) + (ty3 * w3) + (ty4 * w4)) / (w1 + w2 + w3 + w4);

    return new int[] { Convert.ToInt32(px), Convert.ToInt32(py) };
}

Person position:

x: 290
y: 296

As you can see I'm not that good at math and the "Person position" is way off. Not that it matters but it works if the person is in the middle of the grid.

I'm working with the assumption that if every node has the same signal strength the person is in the middle of the grid.

Can someone please help me with this? Been googling and bashing my head against the table for awhile now.

Community
  • 1
  • 1
Tiax
  • 269
  • 5
  • 14
  • What value does the signal approach as the person gets closer to a node? I'm guessing it goes towards 0? – abelenky Jul 26 '13 at 19:50
  • 1
    Are your nodes always going to be in the four corners? Or is it possible to have a node, at say `(150, 250)` – crush Jul 26 '13 at 19:51
  • Another critical question is does signal strength decrease linearly? exponentially? – Kevin Jul 26 '13 at 20:16
  • @abelenky: Yes, that's how I'm simulating the signal strength. Don't have the actual nodes yet. – Tiax Jul 26 '13 at 20:44
  • @crush: I put them that way to make it easier for me to get the positioning working. I'd like it to work with the nodes randomly placed as well. – Tiax Jul 26 '13 at 20:45
  • @Kevin: That's a good question. I'll let you know when I got the nodes :P – Tiax Jul 26 '13 at 20:46
  • @Kevin signal strength is the distance between the nodes. So, linearly. – Luke Willis Jul 26 '13 at 20:58
  • @LukeW. I don't think that's the case... he is going to have an actual value for signal strength that will be coming from HW and is most likely non-linear. I just mentioned it to try and help him with his final solution. – Kevin Jul 26 '13 at 21:03
  • @Kevin OP never mentioned HW, but you are correct that that will need consideration if and when this algorithm is implemented with physical sensors. – Luke Willis Jul 26 '13 at 21:05
  • Hey just a comment... what is this "signal strength" value? If it is real electromagnetic signals then the strength is proportional to the inverse of the square distance (not linear). See "inverse square law" – Alan Jul 26 '13 at 21:05
  • @Alan That would be my assumption. OP will have to determine whether that's the case or not. – Kevin Jul 26 '13 at 21:06
  • Another comment, indoors with EM signals you will have standing waves that reflect all over the place and locating off signal strength will basically be a lost cause. Don't waste your time. Outdoors with long distances and/or with directional antennae it is more possible – Alan Jul 26 '13 at 21:09

2 Answers2

4

I think you got the term wrong, you should be searching for Trilateration. You can check out this good explanation of an algorithm.

Community
  • 1
  • 1
the_lotus
  • 12,668
  • 3
  • 36
  • 53
3

You should actually only need 3 nodes to do this.

The basic concept here is that each signal strength tells you distance from the node. With no other information, you can construct a semicircle from each node with radius equal to the signal strength. Certainly, the person must lie somewhere on the semicircle.

So, with one node, we construct a semicircle and it results in an infinite number of points where the person could be.

With two nodes, we find that the two semicircles may intersect in as many as two locations. In fact, the two opposite nodes will intersect at two distinct points within the window's boundaries if the person is not in the exact center, but will intersect at only one point (the center) if the person is at the center of the screen.

With the introduction of the third node, the third semicircle is guaranteed to intersect the first two semicircles at one of the two points at which they intersect.

The location where these three nodes intersect is where the person resides.

As stated by the_lotus, this is a Trilateration problem.

Here's the function, you need (you can even cut s4 from the parameter list):

public int[] GetPositionInGrid(int s1, int s2, int s3, int s4)
{
  var px = ((s1 * s1) 
            - (s2 * s2) 
            + (this.node2.Left * this.node2.Left)) 
           / ((double)(2 * this.node2.Left));

  var py = ((s1 * s1) 
            - (s3 * s3) 
            + (this.node3.Left * this.node3.Left) 
            + (this.node3.Top * this.node3.Top)) 
           / (2 * this.node3.Top) 
           - (this.node3.Left / (double)this.node3.Top) 
           * px;

  return new int[] { Convert.ToInt32(px), Convert.ToInt32(py) };
}
Luke Willis
  • 8,429
  • 4
  • 46
  • 79
  • I tried with 3 nodes first but to make it easier I added a forth. I get the concept just not the bloody math :P thanks for taking time to help me out! – Tiax Jul 26 '13 at 20:50
  • @Tiax I fixed a small problem. The calculation for `py` didn't have a cast to double where it was needed. Also, note that this solution will only work if node1 and node2 have the same y value. I'm working on a solution where this need not be true. – Luke Willis Jul 26 '13 at 21:13
  • Thanks a lot! Will play with it tomorrow :) – Tiax Jul 26 '13 at 21:28
  • Works like a charm! If you solve the "problem" with node1 and node2 having the same y value, please let me know! Would be truly great! – Tiax Jul 31 '13 at 07:26
  • @Tiax Unfortunately, I don't have time to work on implementing it right now, but the algorithm to do so isn't too bad. Just the pre and post processing of the nodes to make them line up with the specifications and then move them back. – Luke Willis Jul 31 '13 at 13:43