To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.legosOpen lugnet.robotics.rcx.legos in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / legOS / 3527
3526  |  3528
Subject: 
math library
Newsgroups: 
lugnet.robotics.rcx.legos
Date: 
Sat, 29 Nov 2003 01:25:09 GMT
Viewed: 
4381 times
  
Hello all.
About a year ago I researched math functions so I could write some for
the RCX. I found some power series functions that work really well.
I see another message here posted by "nanobapt" has also posted some
functions so I tested his against the ones I found and the ones I found
last year are more accurate (sine is anyway).
Ironically he uses his sine to calculate cosine, and his cosine is more
accurate than sine! weird.
Anyway I don't remember where I got these series functions, since they
came from different sources on the web, the square root function
definitely came from Isaac Newton, I think the others were derived from
Newton's with improvements made by later math geniuses (all much smarter
than me!).
I also have inverse functions, last year I tested all of these functions
using a spreadsheet and the built-in "SERIESSUM" function to emulate
these C functions before I actually wrote the C functions. The goal then
was to test them out, and see how many iterations of the series was
needed to get the desired accuracy.

I hope others will find this useful, incidentally the built-in functions
use a different approach. Instead of doing a power series, they do
another type of binary math that is more accurate, all calculators and
math-co's use this binary approach. I found a PDF file explaining it but
at the time didn't spend enough time to figure out how to implement it.

How I tested these in a real RCX was by writing a short program to
divide a circle into 50 equal pieces, in radians, from -PI to +PI.
Then calculate the sine and cosine of each value, I did this with my
functions, the functions supplied by nanobapt, and the built-in
spreadsheet functions, and plotted them all on a chart. My sine follows
the built-in sine all the way across the chart, my cosine isn't quite as
accurate as it starts to rise above the built-in cosine between -PI and
-2.65 and again at +2.65 to +PI. Nano's cosine does the same, in the
same spot, in the other direction. His sine went way off the built-in
sine until -1.5, and after +1.5, which is odd because his sine is used
to calculate his cosine, which is as accurate as the one I used! I may
have made a mistake somewhere. If I did his equations may be better
since they seem more simple, and may be faster, but they all run so fast
I can't tell. All of them are accurate enough for robot navigation,
which is probably why you want them :)
Apparently I can't attach files so the jpg of a graph made with
OpenOffice Calc comparing these functions is at:
http://billkoontz.com/files/compare_trigs.jpg

A slightly earlier version of this math header is available on my web
site also.


--------

/*
    * rcxmath.h
    *
    * Basic RCX math library
    *
    * Version 1.0
    *      Date: 12/30/2002
    * Author
    *      Bill Koontz
    *      wkoontz@insight.rr.com
    *
    *      int abs(int value);     Returns absolute value of value.
    *      float sqrt(float x);        Returns square root of x.
    *      float hypot(float x, float y);
    *              length of hypotenuse of a right triangle
    *              whose shorter sides are x and y.
    *              In other words, the distance between (0,0) and (x,y).
    *      float cos(float x);   Returns cosine of x, where x is in radians.
    *      float sin(float x);   Returns sine of x, where x is in radians.
    *      float asin(float x);  Returns the value whose sine is x.
    *      float acos(float x);  Returs the value whose cosine is x.
    *      float pow(float x, float y);  Returns x to power of y.
    *
    */


#include <unistd.h>

/* Define real pi (sorta) */
#define PI 3.14159

int abs(int value);
float cos(float x);
float sin(float x);
float sqrt(float x);
float hypot(float x, float y);
float asin(float x);
float acos(float x);
float pow(float x, float y);

int abs(int value) {
           if(value<0) {
                   return value*-1;
           } else {
                   return value;
           }
}

float sqrt(float x) {
           float newsq=x;
           float oldsq=0;
           float try=0;
           while((newsq != oldsq) && (try<10)) {
                   oldsq=newsq;
                   newsq=(oldsq+x/oldsq)/2;
                   try++;
           }
           return newsq;
}

float hypot(float x, float y) {
           return sqrt( (x*x) + (y*y) );
}

float pow(float x, float y) {
           float r=1,i=0;
           for(i=0;i<y;i++) {
                   r=r*x;
           }
           return r;
}

float cos(float x) {
           float cosine;
           cosine=1;
           cosine-=(pow(x,2)/2);
           cosine+=(pow(x,4)/24);
           cosine-=(pow(x,6)/720);
           cosine+=(pow(x,8)/40320);
           return cosine;
}

float sin(float x) {
           float sine;
           sine=x;
           sine-=(pow(x,3)/6);
           sine+=(pow(x,5)/120);
           sine-=(pow(x,7)/5040);
           sine+=(pow(x,9)/362880);
           return sine;
}

float asin(float x) {
           float arcsine;
           arcsine=x;
           arcsine+=(pow(x,3)*(float)0.166667);
           arcsine+=(pow(x,5)*(float)0.075);
           arcsine+=(pow(x,7)*(float)0.044643);
           arcsine+=(pow(x,9)*(float)0.030381944);
           return arcsine;
}

float acos(float x) {
           return PI/2-asin(x);
}



1 Message in This Thread:

Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR