Localization (multilateration) code producing the same coordinates every time? - c++

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

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)

Related

Alternative algorithm for integral calculation inaccurate

I thought of an algorithm for integral calculation that should be more accurate that the regular rectangle approach. My algorithm can be best described with a graphic (I am using f(x) = sin(x) as example):
First the x and y positions of the points P1, P2, P3, P4 are
calculated (red dots).
The area of the green four sided figure is a part of the result.
This area is calculated by dividing it into two triangles (blue
line).
The area of each triangle is calculated using the Heron’s formula.
I think it is obvious that this should lead to much better results than the rectangle approach.
In code this looks like this:
double integral(double f(double x), double min, double max) {
Point p1, p2, p3, p4;
double area = 0.0;
double s1 = 0.0;
double s2 = 0.0;
for(double x = min; x < max; x += stepSize) {
p1.x = x;
p1.y = 0.0;
p2.x = x;
p2.y = f(x);
p3.x = x + stepSize;
p3.y = f(x + stepSize);
p4.x = x + stepSize;
p4.y = 0.0;
s1 = 0.5 * (distance(p1, p2) + distance(p2, p4) + distance(p1, p4));
s2 = 0.5 * (distance(p2, p3) + distance(p3, p4) + distance(p2, p4));
area += sqrt(s1 * (s1 - distance(p1, p2)) * (s1 - distance(p2, p4)) * (s1 - distance(p1, p4)));
area += sqrt(s2 * (s2 - distance(p2, p3)) * (s2 - distance(p3, p4)) * (s2 - distance(p2, p4)));
}
return area;
}
The distance function is just returning the distance between two points in 2D space. The Point struct is just holding a x and y coordinate. stepSize is a constant that I set to 0.001
My function is giving a result that is correct, but I wanted to know how much more precise it is compared to the rectangle approach.
On the internet I found this code that is calculating a integral using rectangles:
double integral2(double(*f)(double x), double a, double b, int n) {
double step = (b - a) / n; // width of each small rectangle
double area = 0.0; // signed area
for (int i = 0; i < n; i ++) {
area += f(a + (i + 0.5) * step) * step; // sum up each small rectangle
}
return area;
}
I both tested them using the standard math.h sin function from 0.0 to half π. This area should be 1.
My algorithm has given me the result 1.000204 for a step-size of 0.001.
The rectangle algorithm hast given me the result 1.000010 with a calculated step-size of 0.015708.
How can such a difference in accuracy and step-size be explained?
Did I implement my algorithm wrong?
Update
Using the calculated step-size of the second method, I get the result 0.999983 which is much closer to one than the result with a step-size of 0.001.
Now how can that work??
Your last trapezoid may be too wide: x+stepSize may be above max if max-min isn't a multiple of stepSize. That's why in the rectangular summation code you included, rather than stepSize, they use n (the number of rectangles).
You compute the trapezoid in a complicated way. Note that its area is stepSize * (P2.y + P3.y)/2. This adds computation cost, but I guess is not the cause of the numerical error in your test integral.
Except for these issues, your method is otherwise equivalent to the trapezoid rule. https://en.wikipedia.org/wiki/Trapezoidal_rule
Here is Python code that approximates the integral in three different ways, using 100 rectangles. The three ways are trap_heron (your method, using Heron's rule), trap (trapezoid method), and rect (rectangular summation). Your question is C++, but the results should be the same.
import math
N = 100
def dist(a, b):
dx = a[0] - b[0]
dy = a[1] - b[1]
return math.sqrt(dx*dx + dy*dy)
def trap_heron(f, min, max):
area = 0.0
for i in range(N):
x0 = min + (max-min) * i/N
x1 = min + (max-min) * (i+1)/N
y0 = f(x0)
y1 = f(x1)
p1 = (x0, 0.0)
p2 = (x0, y0)
p3 = (x1, y1)
p4 = (x1, 0.0)
s1 = 0.5 * (dist(p1, p2) + dist(p2, p4) + dist(p1, p4))
s2 = 0.5 * (dist(p2, p3) + dist(p3, p4) + dist(p2, p4))
area += math.sqrt(s1 * (s1 - dist(p1, p2)) * (s1 - dist(p2, p4)) * (s1 - dist(p1, p4)))
area += math.sqrt(s2 * (s2 - dist(p2, p3)) * (s2 - dist(p3, p4)) * (s2 - dist(p2, p4)))
return area
def trap(f, min, max):
area = 0.0
for i in range(N):
x0 = min + (max-min) * i/N
x1 = min + (max-min) * (i+1)/N
y0 = f(x0)
y1 = f(x1)
area += (x1-x0) * (y0+y1)/2
return area
def rect(f, min, max):
area = 0.0
for i in range(N):
y = f(min + (max-min)*(i+0.5)/N)
area += (max-min)/N * y
return area
print(trap(math.sin, 0, math.pi/2))
print(trap_heron(math.sin, 0, math.pi/2))
print(rect(math.sin, 0, math.pi/2))
The output is:
0.9999794382396076
0.9999794382396054
1.0000102809119051
Note that trap and trap_heron produce very nearly the same result.
In your comments, you have a result of 1.015686. The error is very close to stepSize * sin(pi/2), so I guess you've summed up one too many trapezoids.
You can try Kahan summation to reduce the error but the precision issue is real. You are approximating the integral using a numerical method after all.

Code two required condition in finding root with Fixed point method

I'm trying to find a root with simple fixed-point method by C++, but the point is that Xr is a root of f(x) and a inflection point as well. In addition, A equation is a little bit more complex than the normal Fixed-Point method.
The equation is added constant c for check how quickly converge to the root xr.
I was going to find a root and then check if the root is a inflection point or not, but it is not working and I can't find the problem in my code.
I need your help.
The real Problem is
Consider the root finding problem f(x)=0 with root xr, with f'(x)=0.
Convert it to the simple fixed-point problem.
x=x+c*f(x)=g(x)
with c a nonzero constant. How should c be chosen to ensure rapid convergence of
x(n+1)=x(n)+c*f(x(n)) ( x(n+1) means the value of the n+1th of X )
to c (provided that x0 is chosen sufficiently close to xr?). Apply your way of choosing c to the root-finding problem x*x*x-5=0. Start your program with x0=1.0 and run with several values of c and discuss about the observed trend in your results (in other words, the effect of c value on convergence behavior)
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
double gx(double x, double c)
{
return(x + c*(x*x*x - 5));
}
double gxpr(double x, double c)
{
return(x + c*(3 * x*x));
}
void Simple_Fixed_Point(double x, double c)
{
int i = 1;
long double x2=0.0;
long double x3=0.0;
long double ea=0.0;
long double ea2 = 0.0;
long double es = pow(10, -6);
printf("Simple Fixed Point Method\n");
Lbl:
x2 = gx(x,c);
printf("iteration=%d Root=%.5f Approximate error=%.15f\n", i++,
x2, ea);
if (ea=fabs((x2 - x)/x2*100) <es)
{
goto Lbm;
}
else
{
x = x2;
goto Lbl;
}
Lbm:
x3 = gxpr(x2, c);
if (ea2 = fabs((x3 - x2) / x3 * 100) < es)
{
goto End;
}
else
{
x2 = x3;
goto Lbm;
}
End:
getch();
}
int main(void)
{
Simple_Fixed_Point(1.0, 1.0);
return(0);
}
Hope this helps you:
//f(x+dx) = f(x) + (dfdx) * dx;
eps = 1.0;
dx = 1e-7; //something small
x = x0;
while (eps > mineps) {
f1 = f(x);
f2 = f(x + dx);
f3 = f(x + dx + dx);
d2fdx2 = (f3 - f2 - f2 + f1) / dx / dx;
dfdx = (f2 - f1) / dx;
x -= (relax1 * f1 / dfdx + relax2 * dfdx / d2fdx2); //relax - something less 1
eps = max(abs(dfdx), abs(f1));
}

nFinding Xcrossing point using Data Points

I was going through Algorithm which identify crossing point using data points on x axis. I can understand calculation but could not understand purpose of this calculation. As per my understanding, it determine each time new y point and slope and subtract them.
I want to insert Image also but I do not have 10 reputation point.
Please let me know if I need to provide info.
//This function determine the crossing point when the graph is intersecting x axis.
XPoint findXingPoint(Curve & curve, double rfix, double vcc, int type, int pull_up)
{
//curve class contain x and y data point
// rfix is fixed value which is generally 50
// vcc also fix value
// type contain 0 and 1
//pull up to identify graph
XPoint p = { 0.0, 0.0 };
double r_fix = rfix;
double m = -1 / r_fix;
double c = vcc / r_fix;
if(type)
c=0;
double r, s, X1, X2, Y1, Y2, Y3, Y4;
r = (m * curve[0].first) + c;
// r is a kind of y value which determine from x and y point
s = abs(r);
for (Curve::iterator i = curve.begin(); i != curve.end(); i++) {
curve_point p = (*i);
double xcurve = p.first;
double ycurve = p.second;
double yloadline = m * xcurve + c;
double B = ycurve - yloadline;
if (B >= 0 && r >= B) {
r = B;
X1 = xcurve;
Y1 = yloadline;
Y2 = ycurve;
}
if (B <= 0 && r >= abs(B)) {
s = abs(B);
X2 = xcurve;
Y4 = yloadline;
Y3 = ycurve;
}
}
#could not understand purpose of B calculation
if (s == 0)
X1 = X2;
if (r == 0)
X2 = X1;
if (X1 != X2) {
double m1, m2, c1, c2;
m1 = (Y3 - Y2) / (X2 - X1);
m2 = (Y4 - Y1) / (X2 - X1);
c1 = Y3 - (m1 * X2);
c2 = Y4 - (m2 * X2);
// CASE m1==m2 should be handled.
p.x = (c2 - c1) / (m1 - m2);
p.y = (m2 * p.x) + c2;
} else {
p.x = X1;
p.y = Y1;
}
#not able to also understand calculation
if (verbosityValue >= 1)
loginfo<<"found crossing point # " << p.x << " " << p.y << endl;
return p;
}
Output:
first
found crossing point # 7.84541e-08 -1.96135e-09 with type 0
found crossing point # 0.528564 0.0182859 with type 1
second
found crossing point # 0.654357 -0.0163589 with type 0
found crossing point # 1.25827 4.31937e-05 with type 1
This appears to be a straightforward implementation. For a given point x,y on the curve, find the slope, draw a line through the slope, find where that line would cross the x axis, and then find the new y value at that point. For well-behaved functions, the new y value is a lot closer to 0 than the initial y value. You iterate until the approximation is good enough.
If you look at the graph, you see that the middle part is quite straight. Hence, the slope of the line is a locally good approximation of the curve, and your new y value is a lot closer to zero (At least 10x times, probably 100x, looking at the graph.0. If you start on the the steeper slopes on either side, you'll need one extra step. Your second x point will be on the middle part.

How to calculate the point of intersection between two lines

I am attempting to calculate the point of intersection between lines for a Optical Flow algorithm using a Hough Transform. However, I am not getting the points that I should be when I use my algorithm for calculating the intersections.
I save the Lines as an instance of a class that I created called ImageLine. Here is the code for my intersection method.
Point ImageLine::intersectionWith(ImageLine other)
{
float A2 = other.Y2() - other.Y1();
float B2 = other.X2() - other.X1();
float C2 = A2*other.X1() + B2*other.Y1();
float A1 = y2 - y1;
float B1 = x2 - x1;
float C1 = A1 * x1 + B1 * y1;
float det = A1*B2 - A2*B1;
if (det == 0)
{
return Point(-1,-1);
}
Point d = Point((B2 * C1 - B1 * C2) / det, -(A1 * C2 - A2 * C1) / det);
return d;
}
Is this method correct, or did I do something wrong? As far as I can tell, it should work, as it does for a single point that I hard-coded through, however, I have not been able to get a good intersection when using real data.
Considering the maths side: if we have two line equations:
y = m1 * x + c1
y = m2 * x + c2
The point of intersection: (X , Y), of two lines described by the following equations:
Y = m1 * X + c1
Y = m2 * X + c2
is the point which satisfies both equation, i.e.:
m1 * X + c1 = m2 * X + c2
(Y - c1) / m1 = (Y - c2) / m2
thus the point of intersection coordinates are:
intersectionX = (c2 - c1) / (m1 - m2)
intersectionY = (m1*c1 - c2*m2) / m1-m2 or intersectionY = m1 * intersectionX + c1
Note: c1, m1 and c2, m2 are calculated by getting any 2 points of a line and putting them in the line equations.
(det == 0) is unlikely to be true when you're using floating-point arithmetic, because it isn't precise.
Something like (fabs(det) < epsilon) is commonly used, for some suitable value of epsilon (say, 1e-6).
If that doesn't fix it, show some actual numbers, along with the expected result and the actual result.
For detailed formula, please go to this page.
But I love code so, here, check this code (I get it from github, so all credit goes to the author of that code):
///Calculate intersection of two lines.
///\return true if found, false if not found or error
bool LineLineIntersect(double x1, double y1, //Line 1 start
double x2, double y2, //Line 1 end
double x3, double y3, //Line 2 start
double x4, double y4, //Line 2 end
double &ixOut, double &iyOut) //Output
{
//http://mathworld.wolfram.com/Line-LineIntersection.html
double detL1 = Det(x1, y1, x2, y2);
double detL2 = Det(x3, y3, x4, y4);
double x1mx2 = x1 - x2;
double x3mx4 = x3 - x4;
double y1my2 = y1 - y2;
double y3my4 = y3 - y4;
double xnom = Det(detL1, x1mx2, detL2, x3mx4);
double ynom = Det(detL1, y1my2, detL2, y3my4);
double denom = Det(x1mx2, y1my2, x3mx4, y3my4);
if(denom == 0.0)//Lines don't seem to cross
{
ixOut = NAN;
iyOut = NAN;
return false;
}
ixOut = xnom / denom;
iyOut = ynom / denom;
if(!isfinite(ixOut) || !isfinite(iyOut)) //Probably a numerical issue
return false;
return true; //All OK
}
Assuming your formulas are correct, try declaring all your intermediate arguments as 'double'. Taking the difference of nearly parallel lines could result in your products being very close to each other, so 'float' may not preserve enough precision.

Collision detection using the Pythagorean theorem is being unreliable?

Objects can often times pass through each other? Additionally when calculating momentum, occasionally the sprites will form blobs upon collision, moving together instead of bouncing off.
The code does work for most collisions, but it often fails. Any ideas?
xV = X Velocity. yV = Y Velocity. Every frame this velocity values are added to the X and Y positions of the quad.
bool Quad::IsTouching(Quad &q)
{
float distance = 0;
float combinedRadius = (size/2) + (q.GetSize()/2);
distance = sqrt(pow(q.GetX() - GetX(), 2) + pow(q.GetY() - GetY(), 2));
if(distance < combinedRadius)
{
return true;
}
return false;
}
void Quad::Collide(Quad &q)
{
float mX, mY, mX2, mY2, mXTmp, mYTmp;
mX = mass * xV;
mY = mass * yV;
mXTmp = mX;
mYTmp = mY;
mX2 = q.GetMass() * q.GetxV();
mY2 = q.GetMass() * q.GetyV();
mX = mX2;
mY = mY2;
mX2 = mXTmp;
mY2 = mYTmp;
xV = mX/mass;
yV = mY/mass;
q.SetxV(mX2/q.GetMass());
q.SetyV(mY2/q.GetMass());
}
I had the same issue and here is a quick video I made to demonstrate the problem.
The method to solve this is to calculate the exact time of the collision, so the particles would move the remaining time of the iteration/time-step with the new velocity. To do this you would have to check whether the will be a collision before updating the position, so: sqrt((x1 - x2 + dt * (vx1 - vx2))^2 + (y1 - y2 + dt * (vy1 - vy2))^2) <= distance.
You might also be able to get away with a simpler solution, in which you move both object slightly so that they aren't colliding anymore. This would yield a creator inaccuracy but does needs less calculations:
dx = x1 - x2;
dy = y1 - y2;
d = sqrt(dx^2 + dy^2);
D = r1 + r2;
if(d < D)
{
s = (d - D) / (2 * d);
x1 = x1 + s * dx;
x2 = x2 - s * dx;
y1 = y1 + s * dy;
y2 = y2 - s * dy;
}
What type of collisions are you referring to? Elastic or inelastic? For an elastic collision, the code would fail, and you would have to create an additional property to prevent the two objects from sticking together on contact. You would also have to ensure, with a loop or if statement, that if one object is crossing the position of another object at the same time as the other object, that the two will separate with an angle proportional to the collision speed. Use the appropriate physics formulae.
As a deduced, potential, issue (there are no values to the velocities, sizes, etc. supplied so I can't say for sure), you are not accounting that the quads are exactly touching. That is, distance == combinedRadius. Therefore, when this is true the check fails then the objects continue moving on the next tick...right through each other.
Change your check to distance <= combinedRadius. In addition, you may simply be getting a tunneling effect because the objects are small enough and moving fast enough that on each tick they pass through each other. There are multiple ways to fix this some of which are: impose a maximum velocity and a minimum size; increase your frame rate for physics checks; use continuous collision checks versus discrete checks: see wikipedia article on subject