1

I'm currently trying to develop a trilateration application to track beacons using 3 phones. I converted code I found in python over to c# but I'm having trouble getting it to work. This is my code:

public double[] getPosition(double phoneADistance, double phoneBDistance, double phoneCDistance)
    {
        //meterToFeet is just a conversion method which takes the distance parameter and multiplies it by 3.28.
        double PhoneADist = meterToFeet(phoneADistance);
        double PhoneBDist = meterToFeet(phoneBDistance);
        double PhoneCDist = meterToFeet(phoneCDistance);

        //The phone's x and y coordinates are pre-set
        Vector<double> P1 = new DenseVector(new[] { PhoneA_x, PhoneA_y });
        Vector<double> P2 = new DenseVector(new[] { PhoneB_x, PhoneB_y });
        Vector<double> P3 = new DenseVector(new[] { PhoneC_x, PhoneC_y });

        var ex = (P2 - P1) / (P2 - P1).L2Norm();
        var i = ex.DotProduct(P3 - P1);
        var ey = (P3 - P1 - i * ex) / (P3 - P1 - i * ex).L2Norm();
        var d = (P2 - P1).L2Norm();
        var j = ey.DotProduct(P3 - P1);

        var x = (Math.Pow(PhoneADist, 2) - Math.Pow(PhoneBDist, 2) + Math.Pow(d, 2)) / (2 * d);
        var y = ((Math.Pow(PhoneADist, 2) - Math.Pow(PhoneCDist, 2) + Math.Pow(i, 2) + Math.Pow(j, 2)) / (2 * j)) - ((i / j) * x);


        double[] answer = new double[] { x, y };
        Console.Write(x + " " + y);
        return answer;
    }

When I run this method

Test case #1:

  • PhoneA_x&y = (0,0)
  • PhoneB_x&y = (100,0)
  • PhoneC_x&y = (50,100)
  • phoneADistance = 0
  • phoneBDistance = 100
  • phoneCDistance = 111.803

it returns (-488.195, -366.147)

Test Case #2:

  • PhoneA_x&y = (0,0)
  • PhoneB_x&y = (100,0)
  • PhoneC_x&y = (50,100)
  • phoneADistance = 25
  • phoneBDistance = 25
  • phoneCDistance = 25

it returns (50, 37.5)

Jay
  • 73
  • 3
  • 14
  • 1
    How does the result differ from what's expected? When you step through in a debugger, at what point does the calculation differ from what's expected? – David Jan 31 '17 at 13:38
  • @David In test case #1, the answer should be positive and be at position (0,0). Also, in most of my test cases, they almost always returns (50,37.5) which is wrong. – Jay Jan 31 '17 at 16:17
  • 1
    Where did the test data come from? It doesn't look like these numbers could solve the equations if correct. – Simon Jan 31 '17 at 17:08
  • @Simon They were just dummy test data that I plugged in to test the algorithm – Jay Feb 01 '17 at 13:26
  • Oh and it's using the MathNet Numerics library to calculate the dot products and norms as well as for the vector structures. – Jay Feb 01 '17 at 13:27
  • 1
    The reason I ask is that the algorithm is supposed to be the intersection of 3 circles centred at x,y with radius as your distance number. (See the picture in this link https://en.wikipedia.org/wiki/Trilateration). Using the numbers you're testing with the circles wouldn't overlap, so no wonder the results are unexpected. – Simon Feb 01 '17 at 13:52
  • Could you try the numbers from this page http://jwilson.coe.uga.edu/EMAT6680Fa05/Schultz/6690/Barn_GPS/Barn_GPS.html – Simon Feb 01 '17 at 13:55
  • A: r = 13 x,y: (0, 0), B: r = 5 x,y: (9, 15), C: r = 20 x,y: (21, 0), output: (5, 12) – Simon Feb 01 '17 at 13:56
  • @Simon Just tried plugging it in, but I'm getting output: (53.027, -88.576) – Jay Feb 01 '17 at 14:51
  • Could you try it without converting the distances to feet first, that is probably messing up the calculation. – Simon Feb 01 '17 at 15:50
  • @Simon I think there was something wrong with the algorithm to start off with. Instead of that algorithm, I tried redoing the whole algorithm based off the link you attached. I will be back with updates tomorrow. – Jay Feb 01 '17 at 22:47

1 Answers1

0

It's very sloppy but this is my new algorithm so far.

I just took the excel spreadsheet from the site that Simon linked and converted into C# code.

There is still a lot of clean up to do.

It's still in testing process so I'm not 100 with the results, but from the testings I've done so far it seems pretty accurate.

    public double[] getPosition(double phoneADistance, double phoneBDistance, double phoneCDistance)
    {
        double[] answer = new double[] { 0, 0 };
        double PhoneADist = meterToFeet(phoneADistance);
        double PhoneBDist = meterToFeet(phoneBDistance);
        double PhoneCDist = meterToFeet(phoneCDistance);

        Vector<double> P1 = new DenseVector(new[] { PhoneA_x, PhoneA_y });
        Vector<double> P2 = new DenseVector(new[] { PhoneB_x, PhoneB_y });
        Vector<double> P3 = new DenseVector(new[] { PhoneC_x, PhoneC_y });

        //Translate values for the three points
        var B3 = PhoneA_x;
        var C3 = PhoneA_y;
        var D3 = phoneADistance;
        var B4 = PhoneB_x;
        var C4 = PhoneB_y;
        var D4 = phoneBDistance;
        var B5 = PhoneC_x;
        var C5 = PhoneC_y;
        var D5 = phoneCDistance;
        //Translate P1 to Origin
        var B8 = B3 - B3;
        var C8 = C3 - C3;
        var D8 = D3;
        var B9 = B4 - B3;
        var C9 = C4 - C3;
        var D9 = D4;
        var B10 = B5 - B3;
        var C10 = C5 - C3;
        var D10 = D5;
        //Find Calculation Values
        var B13 = Math.Atan2(C9, B9); ;
        var B14 = Math.Atan2(C10, B10);
        var B15 = Math.Sqrt(Math.Pow(B4 - B3, 2) + Math.Pow(C4 - C3, 2));
        var B16 = Math.Sqrt(Math.Pow(B5 - B3, 2) + Math.Pow(C5 - C3, 2));
        //Polar Coordinates for the Rotated System
        //var B20 = 0;
        //var C20 = 0;
        var D20 = D3;
        var B21 = B15;
        //var C21 = 0;
        var D21 = D4;
        var B22 = B16;
        var C22 = B14 - B13;
        var D22 = D5;
        //Rectangular Coordinates for the Rotated System
        //var B26 = 0;
        //var C26 = 0;
        var D26 = D3;
        var B27 = B21;
        //var C27 = 0;
        var D27 = D4;
        var B28 = B22 * Math.Cos(C22);
        var C28 = B22 * Math.Sin(C22);
        var D28 = D5;
        //Coordinates of Roated Solution
        var B31 = (Math.Pow(D3, 2) - Math.Pow(D4, 2) + Math.Pow(B27, 2)) / (B27 * 2);
        var B32 = Math.Sqrt(Math.Pow(D3, 2) - Math.Pow(B31, 2));
        var D32 = -B32;
        //Convert to Polar
        var B35 = Math.Sqrt(Math.Pow(B31, 2) + Math.Pow(B32, 2));
        var B36 = Math.Atan2(B32, B31);
        var D36 = Math.Atan2(D32, B31);
        //Unrotate
        var B39 = B35;
        var B40 = B36 + B13;
        var D40 = D36 + B13;
        //Rectangular Coordinates
        var B43 = B39 * Math.Cos(B40);
        var D43 = B39 * Math.Cos(D40);
        var B44 = B39 * Math.Sin(B40);
        var D44 = B39 * Math.Sin(D40);
        //Untranslate
        var B47 = B43 + B3;
        var D47 = D43 + B3;
        var B48 = B44 + C3;
        var D48 = D44 + C3;
        var x = B47;
        var y = B48;
        //Return Answer
        if (!Double.IsNaN(x) || !Double.IsNaN(y))
        {
            answer = new double[] { x, y };
            Console.Write(x + " " + y);
        }
        return answer;
    }
Jay
  • 73
  • 3
  • 14