Hi everyone,
I have a calculation that I would like to perform in the Arduino that I would like to gain a little more accuracy from.
Basically what this code does is calculates the intersection point of three circles (I am using it for a TDOA problem). The problem is that these two equations are the least accurate (when comparing to using a calculator or excel) and output is off (in one case, the Y coordinate was off by almost 1cm) too much for my application. I have a feeling this is due to the floating point precision of the arduino but I was wondering if there is something I could do, possibly optimizing the math or to use a fixed point library (which I couldn't get to compile) to increase the accuracy/resolution of the output.
The equations with the highest errors are :
x01 = ((sq(d01) - sq(Rcircle1) + sq(Rcircle0)) / (2.0 * d01)) + c0offset;
and:
ypos = sqrt(sq(Rcircle1) + sq(x01));
With that being said, are there any math wizzes or people with experience with the fixed point libraries that could help me out? I appreciate all the help I can get!
void find_pos(){
// declare variables for this function
float Rcircle0 = 0.0;
float Rcircle1 = 0.0;
float Rcircle2 = 0.0;
float x01 = 0.0;
float x02 = 0.0;
float xerror = 999999.0;
float xerrornew = 999999.0;// set the increment for the iteration (this should be not much smaller then the resolution of your equipment)
float inc = 0.1; // set to 0.1cm or 1mm// set the distance between the microphones (in cm)
float c0offset = -60.0;
float c1offset = 0.0;
float c2offset = 60.0;// calculate the distances between mic 0 and 1 and mic 1 and 2
float d01 = c1offset - c0offset;
float d02 = c2offset - c0offset;// for now the speed of sound is hard coded. TBD: compensate based on air temperature
float Tair = 20.0; // Air temperature hard coded to 20degC
float Vsound = 2004.57*(sqrt(Tair+273.15)); //speed of sound in cm/s// After the time deltas are determined from the microphone processing logic, and normalized so that one microphone is
// time 0, the first step is to calculate the circle radii based on the speed of sound.
// Rcircle0 is the radius of mic0
// Rcircle1 is the radius of mic1
// Rcircle2 is the radius of mic2
// timeL is the normalized time of Mic0 (time0)
// timeC is the normalized time of Mic1 (time1)
// timeR is the normalized time of Mic2 (time2)Rcircle0 = timeL* Vsound/1000000; // Radius is in cm
Rcircle1 = timeC* Vsound/1000000; // Radius is in cm
Rcircle2 = timeR* Vsound/1000000; // Radius is in cm// for every loop, increment each radius by the increment value and then calculate the X coordinate of the
// radical lines of the intersection of circles 0 and 1, and then do it again for circles 0 and 2.
// the difference between these two positions is the error. we are trying to find the point with the least error.
// loop to the radius of the offset of the micsfor (float xloop=0.0; xloop < (c2offset - c0offset); xloop=xloop+inc)
{
// increment each circle by the increment value
Rcircle0 = Rcircle0 + inc;
Rcircle1 = Rcircle1 + inc;
Rcircle2 = Rcircle2 + inc;// calculate the radical lines
x01 = ((sq(d01) - sq(Rcircle1) + sq(Rcircle0)) / (2.0 * d01)) + c0offset;
x02 = ((sq(d02) - sq(Rcircle2) + sq(Rcircle0)) / (2.0 * d02)) + c0offset;xerrornew = abs(x01-x02);
if (xerrornew < xerror)
{
xerror = xerrornew;
xpos = x01;
ypos = sqrt(sq(Rcircle1) + sq(x01));
temp1 = Rcircle1;}
}
}