Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   FIRST Tech Challenge (http://www.chiefdelphi.com/forums/forumdisplay.php?f=146)
-   -   Trig. Functions in EasyC (http://www.chiefdelphi.com/forums/showthread.php?t=50095)

miketwalker 25-11-2006 15:02

Trig. Functions in EasyC
 
I haven't been able to find an answer to this on any of the Vex forums so I figured I'd throw it here. The students on our Vex team are working on a concept with their autonomous and need to be able to use trig functions (primarily tangent) but they can do everything else they are working with in EasyC if they can get the value of a calculation using these trig. functions. Unlike MPLAB it seems that you can't just plug in a math header file and use it like in FRC, but perhaps I am wrong. Has anyone does this and/or any suggestions on how to go about doing it? Thanks!

Bongle 25-11-2006 16:35

Re: Trig. Functions in EasyC
 
You can approximate sin very well between -PI/2 and PI/2 with the function f(theta) = theta - theta3/6 + theta5/120.

Once you've got that approximation, you can basically compute any sin value by using the periodic properties of sin.

sin(x) = sin(PI - x) between PI/2 and 3PI/2 (this recursively uses the bit we can accurately approximate)
sin(x) = sin(x - 2PI) between 3PI/2 and 2PI.

Here's the code for sin:
Code:

#define PI 3.14159

float ApproxSin(float theta)
{
    while(theta > (3*PI)/2)
    {
        theta -= 2*PI;
    }
    while(theta < -PI/2)
    {
        theta += 2*PI;
    }
    // theta is now between -PI/2 and 3*PI/2

    if(theta > -PI/2 && theta <= PI/2) // basic approximation
    {
        return theta - theta*theta*theta/6 + theta*theta*theta*theta*theta/120;
    }
    else if(theta > PI/2 && theta < 3*PI/2)
    {
        return ApproxSin(PI - theta);
    }
}

An approximation for cos is f(x) = 1 - x2/2 + x4/24, you can do the same thing with it, more or less.

BradAMiller 27-11-2006 13:42

Re: Trig. Functions in EasyC
 
Quote:

Originally Posted by miketwalker
I haven't been able to find an answer to this on any of the Vex forums so I figured I'd throw it here. The students on our Vex team are working on a concept with their autonomous and need to be able to use trig functions (primarily tangent) but they can do everything else they are working with in EasyC if they can get the value of a calculation using these trig. functions. Unlike MPLAB it seems that you can't just plug in a math header file and use it like in FRC, but perhaps I am wrong. Has anyone does this and/or any suggestions on how to go about doing it? Thanks!

The Microchip libaries include math functions. Be sure to add an include for math.h so that the correct types are passed to the functions.

Brad

TubaMorg 27-11-2006 21:46

Re: Trig. Functions in EasyC
 
I would like to suggest, without actually knowing your specific application, that you might want to utilize a lookup table. If it is a situation where you need to do the calculations many, many times, then a lookup table will save you computation time as trig functions do have some overhead. Precalculate your trig function for, say, 0-359 degrees and plug the values into an array (indexed 0-359 of course!). Then when needed you just index the array for the answer. If this is a navigation application 0-359 degrees should really be enough resolution, given the error inherent in the sensors. The only drawback is, of course, you have to use up memory to store the array of floats.

Bongle 04-12-2006 08:16

Re: Trig. Functions in EasyC
 
Quote:

Originally Posted by TubaMorg
I would like to suggest, without actually knowing your specific application, that you might want to utilize a lookup table. If it is a situation where you need to do the calculations many, many times, then a lookup table will save you computation time as trig functions do have some overhead. Precalculate your trig function for, say, 0-359 degrees and plug the values into an array (indexed 0-359 of course!). Then when needed you just index the array for the answer. If this is a navigation application 0-359 degrees should really be enough resolution, given the error inherent in the sensors. The only drawback is, of course, you have to use up memory to store the array of floats.

I always forget about lookup tables :(

I'm not sure how much code space the VEX controller has, but 360 floats in a table is 1440 bytes, which is quite a bit. Another idea in that vein would be to have a smaller table (45 entries) and just interpolate between them.
Code:

float GetSin(int degrees)
{
  int subDegrees = degrees & 7; // gets the last 3 bits
  int tableIndex = degrees / 8; // finds out the table entry we want
  return ((8-subDegrees)*table[tableIndex] + subDegrees*table[tableIndex+1])/8;
}

This function is a very simple linear interpolation. But it would allow you to have a much smaller table taking up much less memory. Another improvement would be to only have a table for between -PI/2 and PI/2, then using the same techniques I posted in my first post to get answers for PI/2 and beyond. This would again cut table size in half.

TubaMorg 07-12-2006 23:27

Re: Trig. Functions in EasyC
 
This is good stuff! Excellent suggestions! :D

Quote:

Originally Posted by Bongle
I always forget about lookup tables :(

I'm not sure how much code space the VEX controller has, but 360 floats in a table is 1440 bytes, which is quite a bit. Another idea in that vein would be to have a smaller table (45 entries) and just interpolate between them.
Code:

float GetSin(int degrees)
{
  int subDegrees = degrees & 7; // gets the last 3 bits
  int tableIndex = degrees / 8; // finds out the table entry we want
  return ((8-subDegrees)*table[tableIndex] + subDegrees*table[tableIndex+1])/8;
}

This function is a very simple linear interpolation. But it would allow you to have a much smaller table taking up much less memory. Another improvement would be to only have a table for between -PI/2 and PI/2, then using the same techniques I posted in my first post to get answers for PI/2 and beyond. This would again cut table size in half.



All times are GMT -5. The time now is 04:45.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi