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 mics

for (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;

}

}

}