0

EDIT: The localization is always about x=1980.000032943933547358028590679168701171875, y=3191.99997642902735606185160577297210693359375

I've written the following code to solve the Time Delay of Arrival problem. That is, given the location of three observers, the velocity of some signal, and the time at which each receiver "saw" the signal, I want to localize the source. Here, we assume that the source and the observers are in a 2-dimensional plane (a planar Euclidean space).

My solution is as follows:

Given the time at which each observer saw the signal, I elect one receiver to be the "baseline", which I take to be t=0. I then subtract that time from the Time of Arrival at the other two observers. Now, I assign to each observer a circle, with the radius given by this difference (the "baseline" observer starts with r=0), and I slowly increment the radius of each circle until all three intersect at some point.

In reality, it's unlikely that they'll ever precisely intersect at a single point, as, for one, I can only increase the radius by a discrete amount with each iteration, and we also assume, but do not known, that the observer's clocks are precisely synchronized.

To solve this, I adapted Paul Bourke's code: http://paulbourke.net/geometry/circlesphere/tvoght.c (reasoning here: http://paulbourke.net/geometry/circlesphere/). My adaptation was more-or-less identical to this one: https://stackoverflow.com/a/19724186/14073182.


My problem is, the code always produces the same localization, to within a few tenths of a unit. I tried generating some psuedodata (i.e. pick some location, compute the expected delay, feed that into the algorithm and see if it reconstructs the correct localization), and the algorithm still produces roughly the same localization... namely, fairly close to the center of the triangle formed by the three receivers.

Any idea what I'm doing wrong here? I've talked with a few people (physicists working in GIS, geodesics, similar fields, and a mathematician), and haven't gotten anywhere.

My code is below (it's fairly brief, all things considered). To localize some source, call localizeSource(a,b,c,&xf,&xy). Where a, b, and c are the delays (radii), and xf, xy are where the coordinates of the localization will be stored.

#define EPSILON 0.0001     // Define some threshold

#define x0  3000.00
#define y0  3600.00
#define x1  2100.00
#define y1  2100.00
#define x2  0960.00
#define y2  3600.00

bool findIntersection(double r0, double r1, double r2, double *xf, double *yf){

    double a, dx, dy, d, h, rx, ry;
    double point2_x, point2_y;

    dx = x1 - x0;
    dy = y1 - y0;

    d = sqrt((dy*dy) + (dx*dx));

    if (d > (r0 + r1))
    {
        return false;
    }

    a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ;

    point2_x = x0 + (dx * a/d);
    point2_y = y0 + (dy * a/d);

    h = sqrt((r0*r0) - (a*a));

    rx = -dy * (h/d);
    ry = dx * (h/d);

    double intersectionPoint1_x = point2_x + rx;
    double intersectionPoint2_x = point2_x - rx;
    double intersectionPoint1_y = point2_y + ry;
    double intersectionPoint2_y = point2_y - ry;

    dx = intersectionPoint1_x - x2;
    dy = intersectionPoint1_y - y2;
    double d1 = sqrt((dy*dy) + (dx*dx));

    dx = intersectionPoint2_x - x2;
    dy = intersectionPoint2_y - y2;
    double d2 = sqrt((dy*dy) + (dx*dx));

    if(fabs(d1 - r2) < EPSILON) {

        std::cout << std::setprecision(100) << intersectionPoint1_x << ", " << intersectionPoint1_y << "\n";
        *xf = intersectionPoint1_x; *yf = intersectionPoint1_y;
        return true;
        
    }
    else if(fabs(d2 - r2) < EPSILON) {

        std::cout << std::setprecision(100) << intersectionPoint2_x << ", " << intersectionPoint2_y << "\n";
        *xf = intersectionPoint2_x; *yf = intersectionPoint2_y;
        return true;
        
    }
    else {
        return false;
    }

}

void localizeSource(double r0, double r1, double r2, double *xf, double *yf){

    bool foundSource = false;

    while(foundSource == false){
        foundSource = findIntersection(r0, r1, r2, xf, yf);
        r0 += 0.0001; r1 += 0.0001; r2 += 0.0001;
    }


}

int main(){
    
    double xf, xy;
    localizeSource(1000,3000,0,&xf,&xy);
    
}
Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
10GeV
  • 453
  • 2
  • 14
  • I don't know what you'd expect the code to do. Why should it give different results? Please read [ask] and perhaps provide a [mcve] that really shows what you expect. BTW: You're making several mistakes in your code. Albeit not fatal ones, you'd still benefit from getting it reviewed at codereview.stackexchange.com. – Ulrich Eckhardt Sep 26 '20 at 15:44
  • 1
    To expand on @UlrichEckhardt's suggestion to post on Code Review; the current question would not be on-topic there as the code doesn't work the way you want. If you fix this problem then it may make a good question if you make a new question, check [if it is on-topic](//codereview.stackexchange.com/help/on-topic) and follow [how to post a good question](//codereview.stackexchange.com/help/how-to-ask). – Peilonrayz Sep 26 '20 at 15:48
  • @UlrichEckhardt Hi. Thanks for pointing that out. I think I'm aware of all of these mistakes. In my case, I know enough about the data that I know I'll never run into these mistakes in practice. Also, I posted the entire code as I feel this is an issue with my algo.logic as opposed to some mistake in my code (correct me if I'm wrong, but I think this is still on-topic for SO. I've seen a lot of questions on here asking about algo. solutions/problems with algo. logic). I've included the bare min. required to calc. a localization according to my logic. If I remove anything the code does nothing. – 10GeV Sep 26 '20 at 17:48
  • 1
    Your question is missing the expected results. Given the inputs `1000`, `3000`, and `0`, as in your example, what *should* the answer be? – JaMiT Sep 26 '20 at 18:42
  • *"the radius given by this difference [of times]"* -- what is the justification for using a quantity with units of time as a quantity with units of distance? While I can see how the calculation could be forced to work, this description of the setup smells of bad math. – JaMiT Sep 26 '20 at 18:47
  • @JaMiT Sorry. For example, I would expect to get a localization of `[2486, 2167]` for inputs `-1.90454e-06`, `-5.67589e-06`, and `0`. Instead, as with any inputs I use, I get a localization of about `[1980, 3191]`. Regarding the math, this is a standard solution to the problem, and I wrote the originator of this solution, and a physicist specializing in this sort of thing, before implementing this. – 10GeV Sep 26 '20 at 18:56
  • @KeithMadison Uh, those are not the inputs in your example code. Hmm... if I was testing something like this, I might start with numbers I could more easily follow, something like observers at (0,0), (1000,0), and (0,1000), the signal at (1000,1000), and the timings calculated from that. Not "real" numbers, but easy-to-work-with numbers. – JaMiT Sep 26 '20 at 19:16
  • Your problem as stated has no solutions: (3000,3600) is only 1749.3 away from (2100,2100) but the time difference is 2000. (The latter is also too close to (960,3600).) Accordingly, the program never terminates (for me). – Davis Herring Sep 27 '20 at 00:09
  • Please re-read [mcve]. In particular, this is *not* sufficient, because the code doesn't compile (it lacks includes), which then begets the question what code you compiled and ran. Further, you talk about inputs to your program, but it doesn't seem to take any input. Please [edit] your question to clarify what you would expect from the [mcve] and what it does instead, putting important info into the comment section isn't good. – Ulrich Eckhardt Sep 27 '20 at 08:42
  • @UlrichEckhardt Apologies. I should've noted that this is meant to be run in the Cling interpreter and is a completely valid program with Cling (i.e. I can copy and paste this exact code into a file and run it in Cling right now). – 10GeV Sep 27 '20 at 14:58
  • Just added the "cling" tag. :) – Ulrich Eckhardt Sep 27 '20 at 20:53

1 Answers1

0

It's not super clear what you are trying to solve... Your question talks about "time delay [sic] of arrival" but then you link to the "intersection of circles" algorithm. TDoA algorithm uses parabolas not circles.

Time Difference of Arrival algorithm:

Someone on SO already wrote sample code using Fang's Method Issues implementing the Fang Algorithm for TDOA Trilateration

Hyperbolic Position Location Estimation in the Multipath Propagation Environment Time Difference of Arrival (TDoA) Localization Combining Weighted Least Squares and Firefly Algorithm

If you're just looking for the Triangulation / Trilateration formula:

A = 2*x2 - 2*x1
B = 2*y2 - 2*y1
C = r1*r1 - r2*r2 - x1*x1 + x2*x2 - y1*y1 + y2*y2
D = 2*x3 - 2*x2
E = 2*y3 - 2*y2
F = r2*r2 - r3*r3 - x2*x2 + x3*x3 - y2*y2 + y3*y3
x = (C*E - F*B) / (E*A - B*D)
y = (C*D - A*F) / (B*D - A*E)
Louis Ricci
  • 20,804
  • 5
  • 48
  • 62
  • It’s the intersection of **hyperbolas**, actually. The growing circles, though, are a valid (if iterative and approximate) alternative approach. – Davis Herring Oct 17 '20 at 16:57