Shop OBEX P1 Docs P2 Docs Learn Events
Sine function — Parallax Forums

Sine function

scottascotta Posts: 168
edited 2007-03-27 00:19 in Propeller 1
Does anyone know of a way to enhance the resolution of
the sine lookup table ?

I'm trying to generate segments of a circle from assembler.

Thanks,

Scott

Comments

  • cgraceycgracey Posts: 14,133
    edited 2007-03-24 17:59
    You could linearly interpolate between adjacent table samples, as the slope change between·them is nearly negligible. I assume you've read the propeller_guts document? It shows how to do sine lookups, as well as multiplies for scaling.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • scottascotta Posts: 168
    edited 2007-03-24 18:19
    Chip,

    Saw the propeller_guts document, and also the CORDIC discussion (which
    I did not understand, just my luck the solution was in Greek).

    I'm developing a 3 axis motion control based on G-code. Everything
    is going very well, but I can't sell something that has that size step-over.

    The profile cog does linear interpolation between points in
    900 bytes of cog ram (it uses a floating point package).

    The circle (arc) function has to fit in the same cog, or its all over (512
    longs is not enough ram for a processor that does 20+ mips).

    By the way, It has a C# interface:

    Propeller mypropeller = new Propeller("id=34421",115000);

    Encoder myencoder = mypropeller.NewEncoder();
    EncoderChannel xencoder=myencoder.NewChannel(1,2) //A=pin1, B=pin2

    PWM mypwm = mypropeller.NewPWM();
    PWMChannel xpwm = mypwm.NewChannel(3,4) //dir=3,modulation=4

    PID mypid = mypropeller.NewPid();
    PidChannel x_axis=mypid.NewChannel(xencoder,xpwm);

    x_axis.Goto(3.14) //inches

    Scott
  • Tracy AllenTracy Allen Posts: 6,660
    edited 2007-03-24 19:08
    What resolution are you looking for? The sine table is 11 bits for 90 degrees, so that is a little over 10 arc-minutes. If linear interpolation won't cut it, the CORDIC should be able to generate much higher resolution. Graham posted a solid and documented code at the top of the CORDIC thread.

    I'm curious how the profile comes in, as X,Y coordinates in mils? And for a mechanical device, why does that have to be stored in COG ram?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • scottascotta Posts: 168
    edited 2007-03-24 19:31
    Thousands of an inch on a 30 inch circle (or arc). I think the 11 bit lookup table
    gives me 23 thousands at 30 inches. I will have to look for Graham's posting but
    I'm pretty sure it will be over my head.


    The profiles are block or dripped deltas, depending if the controller is in block
    or delta mode. All X,Y,Z,... coordinates are in inches or MM. This data is stored
    in Global memory. (the routine that works on them is inside a single cog, this
    is why I'm running out of ram).

    Block mode is strait G-code (g1x10.4y30F120). Codes are decomposed into
    floating point registers in a circular buffer, which the profiler runs.

    The drip mode accepts xyz deltas and executes them at a constant rate (up to
    15000 deltas per second for a single axis, 5000 for 3 axises). Drip mode
    has proven to be unreliable on windows machines (the virus checker grabs
    updates every few hours and hammers the delta generator's CPU time).

    Scott
  • camtcamt Posts: 45
    edited 2007-03-26 16:51
    If you're already working with floating point numbers, you can use the SIN function in the Float32 object. It already has the sine table interpolation built-in.

    Cam Thompson
    Micromega Corporation

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cam Thompson
    Micromega Corporation
  • scottascotta Posts: 168
    edited 2007-03-26 18:09
    Is there an easy way to extend the accuracy ?
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-26 19:09
    Scott,

    I'm working on a cordic object that will sit in a cog and do a sine/cosine/atan/asin etc etc and you just call functions from it with spin, I'm hoping to get that up and running soon.

    If you intend to use assembly for your motion control then I can send you the code for doing sine/cosine in an example format where it is clear what it does and how to use it. You can just cut and paste in to your code.

    Graham
  • scottascotta Posts: 168
    edited 2007-03-26 21:25
    Its all assembly (with a spin wrapper).

    Would love to see it work.

    Scott
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-26 21:47
    Scott,

    See what you make of the attached, the code produces values for R.Sin(theta) and R.Cos(theta) simultaneously.

    So basically you provide R and theta, and it works out the components in the two directions. Note that if you just want sin(theta) then set R to one but that should be represented as a binary fraction, i.e. FFFFFFFF represents one. You may be resolving anyway so perhaps R will have a real value in which case the sin(theta) will modify it by the appropriate amount.

    Run the demo and try different angles etc, note they are also reprented as a binary fraction where FFFFFFFF is both zero and 360 degrees.

    To use it just paste in the assembly, at the moment R is stored in _R, theta in ca and the results are put in cx (R.cos(theta)) and cy (R.sin(theta)) before being written to hub ram, you can remove the hub ram part I suspect unless you intend to have a dedicated cog for doing the sine/cos.

    Please do run the demo and read the general comments even if you don't go in to the nitty gritty. Feel free to ask anything.

    Graham
  • camtcamt Posts: 45
    edited 2007-03-26 21:58
    There are two threads going now. CORDIC and Float32. Here's a response to your earlier question with respect to Float32.

    >...Is there an easy way to extend the accuracy ?

    The SIN function in the Float32 object returns an appropriate value for any angle passed. It uses the internal SIN lookup table, but has floating point interpolation between points. As Chip pointed out, the slope change between points is almost negligible, so the 32-bit floating point value returned is quite accurate.The SIN function takes an angle in radians and returns the sin(angle) as a 32-bit floating point number.There are also a full set of other functions available.

    The Float32 object has Spin wrappers for all routines, but it's modularized to make it easy to cut and paste the necessary routines to an existing assembler program. If you're working in assembler, the SIN function executes in about 93 usec. An assembler cog can fill up fairly fast though, so often using the SPIN wrapper makes more sense. If you're using Spin calls, the Sin function executes in about 128 usec.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cam Thompson
    Micromega Corporation
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-03-27 00:19
    I made a mistake, the output is signed because Sin(theta) can be negative so one is not represented by FFFF.

    Cam's numbers for a sine reminded me to do something I have meant to do for a while, find out how fast the cordic is. I stuck the assembly in a loop and toggled a pin on each loop, it takes 14us to do the calculations, its value added because it gives you a sine a cos and two multiplys by R at once.

    Cheers,

    Graham
Sign In or Register to comment.