chipKIT® Development Platform

Inspired by Arduino™

Possible ATAN2 error ... where to find library source?

Created Mon, 18 Jul 2011 11:45:33 +0000 by ron.dunn


ron.dunn

Mon, 18 Jul 2011 11:45:33 +0000

I've just spent two days debugging an error in my code that represents a difference between Arduino and Max32 in the ATAN2() function.

The Max32 version appears not to handle the boundary condition where X = 0 and Y < 0. I've had to add a line of code to make the function work correctly for just this case:

angleFrom = atan2(fromY, fromX);
if (fromY &lt; 0 &amp;&amp; fromX == 0) angleFrom = 0 - M_PI_2;

I'd like to check the library code to determine the cause of the problem. Where may it be found?


ron.dunn

Tue, 19 Jul 2011 23:25:34 +0000

bump

In the absence of library documentation or source, it is somewhat difficult to verify the behaviour of this function.

My concern is that my test cases may miss an error condition, which will only show up in production.

This is a machine control application, and I'd rather not have to deal with flying bits of metal as a result of a library error :(


WestfW

Sun, 24 Jul 2011 02:05:53 +0000

atan2() is clearly not part of the chipkit software itself; it's part of the C library for the compiler provided. I think that that is the gcc math library, but it could be a proprietary library from one of the Microchip-provided compilers.

Hmm. Do you have a short program showing the problem, and are you sure that it is the chipkit that is returning the incorrect value? Under normal circumstances, I'd be more inclined to suspect a bug in the AVR math library; it's an 8bit CPU with a single precision floating point "fixup", while I'd expect the MIPS libraries to be more common.


ron.dunn

Sun, 24 Jul 2011 02:36:25 +0000

westfw, where did I say it was an error in the Max32 libraries? My original post said there was a difference between Arduino and Max32, and I wanted to verify the cause. The reason I spent so long finding the root of the problem is that I blame my code first, not libraries.

In the second post I said my code may miss an error. I'm still happy to accept that a library functions as designed, but I need to know what are those design parameters. I can do this by looking at either code or documentation.

All I want to do is investigate the cause of the difference. It may be an error, it may not, especially if documented otherwise.

You said "I think [my emphasis] this is the gcc math library". If so, all I'd like is a comment stating that as a fact from someone authoritative. If not, well, I'm still guessing.

But like others are finding, getting FACTS about this platform is a difficult task.


WestfW

Sun, 24 Jul 2011 07:54:47 +0000

especially if documented otherwise

atan2() is a standardized C function that has nothing to do with chipkit specifically. The documentation (and behavior) ought to be the same on all platforms.

After a bit of poking around, I find that the libm.a (math library) used by mpide contains an atan.o that has symbols like '__mchp_atan2', which to me implies that it's microchip libary code rather than a standard gcc mips library, probably proprietary, and probably without source available. That sort of moves it "up" in possibility of atan2() bug, but also makes it a microchip library issue rather than a chipkit issue. I didn't find any mentions of atan2() bugs in the microchip forums, but I doubt that the FP library functions are too widely used (hypothesis: there's more AVR floating point code running in Arduinos than any other commercial product...) There is some discussion on the mixed-license issues of libm in this thread: http://www.microchip.com/forums/m364626.aspx

This sort of issue is always difficult to address in "conglomerate" projects like Mpide, Arduino, winavr. and similar. Their teams are not equipped to actually fix bugs in the components of the conglomerate; about the best you can hope for is some assistance in isolating and reporting the bug to the appropriate project, and then incorporating the fix in a timely matter. Arduino has its share of similar issues (64k global object initialization, progmem data types, etc.)

Involvement of the community is important, starting with good bug reporting (small example programs, etc.) So...

The following sketch produces 1.57 (pi/2) when run on chipkit, and -1.57 when run on an AVR-based arduino. The chipkit version appears to be incorrect from the way I read the atan2 documentation...

volatile float x, y;
void setup ()
{
  Serial.begin(19200);
  x = 0.0;
  y = -5.0;
}
void loop()
{
  float z;
  z = atan2(y, x);
  Serial.println(z);
  y += 0.1;
  delay(5000);
}

ron.dunn

Sun, 24 Jul 2011 08:23:13 +0000

Thank you for taking the time to run that code :)

You've now reached exactly the same conclusion as me, but we're no closer to fixing the problem other than by the forced correction I used in my code.

Now, it would be nice if one of the chipKit developers would chime in with a process for getting this error corrected ...


jasonk

Mon, 25 Jul 2011 02:25:49 +0000

Hi,

Thanks for reporting the issue. I do see the problem and will look into fixing it.

For now, a workaround might be to add this to the top of your sketch.

#include &lt;math.h&gt;
long double __mchp_atan2(long double y, long double x);
#define atan2(y,x) __mchp_atan2(y,x)

ron.dunn

Mon, 25 Jul 2011 02:54:26 +0000

Thank you!


WestfW

Mon, 25 Jul 2011 07:45:14 +0000

I needed:

#include &lt;math.h&gt;
extern "C" {
  long double __mchp_atan2(long double y, long double x);
}
#define atan2(y,x) __mchp_atan2(y,x)

but that seemed to result in correct results. (is that the correct fix?)


WestfW

Tue, 26 Jul 2011 05:11:09 +0000

Hmm. I downloaded the latest mplabX (which has c32 compiler version v1.11a) and tried a simpler version of the program in the simulator. It appears to work correctly there. (This under MacOSX 10.5) The libraries are not particularly similar looking...

BillW-MacOSX-2&lt;9984&gt; ll /Applications/Mpide.app/Contents/Resources/Java/hardware/pic32/compiler/pic32-tools/pic32mx/lib/libm.a
    -rwxr-xr-x  1 admin  170418 Jun 19 11:11 /Applications/Mpide.app/Contents/Resources/Java/hardware/pic32/compiler/pic32-tools/pic32mx/lib/libm.a*
    BillW-MacOSX-2&lt;9985&gt; ll /Applications/microchip/mplabc32/v1.11a/pic32mx/lib/libm.a
    -rwxr--r--  1 admin  211660 Aug 19  2010 /Applications/microchip/mplabc32/v1.11a/pic32mx/lib/libm.a*

WestfW

Tue, 26 Jul 2011 05:34:05 +0000

(The simpler sketch)

#include &lt;p32xxxx.h&gt;
#include &lt;math.h&gt;

volatile double x,y,z;

int main(void) {
    x = 0.0;
    y = -5.0;
    z = atan2(y, x);
    return 0;
}

Interestingly, it looks like I can copy the mplabX libraries into the mpide application, and the error still occurs. Some sort of mismatch or error in the float vs double arguments or something ?


WestfW

Tue, 26 Jul 2011 06:01:11 +0000

impossible bugs are fun!

It looks like the library produces incorrect results only for single precision floats (which mpide automatically selects, I guess.) That is, mpide code ends up calling "atan2f()" rather than just "atan2()"; if I set up the MPLab simulation to use atan2f() explicitly, it gets the same error.