Show Posts
Pages: [1]
1  Using Arduino / Programming Questions / Re: Any ideas how to increase floating point accuracy? on: July 31, 2011, 09:36:25 pm
Ok, It turns out I am an idiot!

I had a slight error in my Y position calculation, + instead of -  (comes from c^2 - a^2 = b^2).  I was so involved with thinking of all these other possibilities I overlooked a simple pythagorean theorem typo.

I re-ran my simulations with comparing to microsoft excel and the arduino answers are on average about 0.5mm off either direction with the worst case around 1mm error.  This is well within the error of other parameters in my system so It is good enough for this application.

Thanks to all that answered and sorry for my massive loss of brain function!   smiley-grin
2  Using Arduino / Programming Questions / Any ideas how to increase floating point accuracy? on: July 29, 2011, 09:20:31 am
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;

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;

Pages: [1]