6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Sep 22, 2024 5:33 am

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: 16 Bit Fixed Point Trig
PostPosted: Mon Oct 19, 2020 2:15 am 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
A few years back I wrote a 16 bit fixed point trig package in Forth for a microcontroller. I used it for inverse kinematics and navigation for several hobby robots. One was a small robot arm https://youtu.be/14BX50aHDAk.

I just ported it line by line from Forth to 6502 assembly using my page zero stack macros and posted it to my GitHub repo:
https://github.com/Martin-H1/6502/blob/ ... trig16.asm

It subdivides the unit circle into 1024 binary radians which was more than enough accuracy for my uses. The sine and cosine functions being table driven seem robust. But the tangent function has its limits. I scaled the output of tangent to be useful from -80 degrees to 80 degrees, but it quickly goes out of range near the Y axis. Since robots are physical machines I avoided having the robot move in ways that provoked those values.

The asin function uses a binary search to find the corresponding angle for the sine value, and has good performance.

The atan2 function uses CORDIC with eight angle samples, it's quick, but only gets to within a few brads. The one exception is when the point has a negative X component and zero Y component, then it gives the wrong answer. But again with a robot that would be a point inside the robot and not in the work envelope.

Anyway it's MIT licensed if you find it useful. Let me know if you have improvement suggestions, or spot any bugs. Particularly in the CORDIC routine.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 19, 2020 4:05 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8510
Location: Southern California
For TAN, I just return both the SIN and the COS; then it's up to the calling word how to use them, including what to do if the denominator becomes 0 as TAN has a nasty habit of doing at ±90°. I use 16-bit signed results, so returning both the SIN and the COS effectively gives a 32-bit range. If the performance of the multiplications and divisions of using the first three terms of the infinite series for sines and four terms for cosines for the first 45° is acceptable, you can use tweaked coefficients to get 16-bit results that are never more than 1 bit off, and are usually correct to the last bit, without tables. Then other words apply what they get from those lower-level 0-45° words and get the rest of the circle.

ATAN's infinite series converges terribly slowly. However, it works out nicely to interpolate from a small table, and the accuracy improves dramatically with even small increases in the size of the table. Here are some notes I have in a Forth source-code file from years ago. This is for the circle being split into 65,536 divisions.
Code:
\ ARCTAN can be interpolated nicely for 0-45°-- it works out much better than
\ the approximation X(1+BX²)/(1+CX²)-DX^^6 not to mention the infinite series!
\ With arctangents from 0-45° (π/4 radians, or 1/8 of the circle), you can get
\ the rest of the circle, except that the tangent has this nasty habit of
\ reaching infinity as you get to ±90°.

\ The numbers in the arctangent table below are not exactly the right values for
\ the points they represent; but since the interpolated values sag below, the
\ numbers in the table are optimized so the maximum error from the function
\ atan45 will be < .02°.  The resolution of the table--that is, the angle
\ difference made by each count--is about .007° worst case (near 0).  Each
\ segment is a sixteenth of 45°, and the last number is actually the scaled atan
\ of 17/16 of 45°.  atan45 takes about 520µs at 5MHz.


CREATE ATAN_TBL
         0 ,  28C ,  512 ,  78E ,  9FC ,  C58 ,  E9F , 10CF ,
      12E5 , 14E2 , 16C4 , 188B , 1A39 , 1BCE , 1D4B , 1EB1 ,
      2000 , 213C ,   \ Resolution is .0084° worst case (near 45°)
<snip>

You might be interested in http://www.ganssle.com/approx.htm .

Then there are my large look-up tables where every value is there, pre-calculated, accurate to all 16 bits, needing no interpolation, at http://wilsonminesco.com/16bitMathTables/, since memory is cheap now. They make it like having a scaled-integer coprocessor. (Notice I did not say "fixed-point," which is a limited subset of scaled integer.) In most cases, they're hundreds of times faster than actually having to calculate the value, and in the extreme case, nearly a thousand times as fast. If you have to interface to them through a serial connection, it will not be nearly as fast of course, but still way faster than actually having to calculate them. There are log and other things there too.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 19, 2020 11:28 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
Thanks for sharing your code Martin, and applying a permissive license!


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 19, 2020 2:18 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
@BigEd, you're welcome.

@Garth, thanks for the links. Tables are definitely the way to go when you have the space, as they have constant execution time coupled with higher accuracy. Fortunately even ancient computers are fast compared to physical systems, so slower algorithms like CORDIC are usually good enough.

I'm curious, when you return the sin and cos are they on the data stack as if the consumer called one after the other, or blended together in some way? The thing about tangent is that a zero or near zero in the denominator is going to risk blowing out any calculation. So you have to guard against getting near it, especially when the system is a physical system.

For inverse kinematics that means the robot is likely moving a joint in a way that is unbalanced, strained, or physically impossible. I've had a few interesting programming bugs when I didn't guard against it, and the robot behaved erratically. Fortunately I only do desktop scale robot arms so there's no risks. Industrial robots are a whole other ballgame.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 19, 2020 3:26 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
I'd hope that in an industrial-grade robot, you'd use a controller capable of processing coordinates in floating-point at the required speed. It could still be a 6502, just with a 68882 FPU mapped in for the heavy lifting.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 19, 2020 6:00 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
You would hope, as given the cost of those systems, the CPU cost isn't an issue. But the mathematical challenges exist independent of the implementation. Particularly because for a particular tool position there can be multiple solutions, or no solutions.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 19, 2020 7:13 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8510
Location: Southern California
Martin_H wrote:
I'm curious, when you return the sin and cos are they on the data stack as if the consumer called one after the other, or blended together in some way? The thing about tangent is that a zero or near zero in the denominator is going to risk blowing out any calculation. So you have to guard against getting near it, especially when the system is a physical system.

It's A., two cells, as if you asked for both the SIN and the COS. The caller knows what it asked for and will know how to handle it.

Quote:
I'd hope that in an industrial-grade robot, you'd use a controller capable of processing coordinates in floating-point at the required speed. It could still be a 6502, just with a 68882 FPU mapped in for the heavy lifting.

It will still be operated by stepper motors which have a limited number of steps for the entire range of motion. If that's 65,536 or less, 16 bits is still enough, without floating-point. Otherwise you might go to 24 bits. However, the TAN of ±90° is infinite, and floating-point does not relieve you of that. You still have to deal with it.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 20, 2020 2:33 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Working in floating point gives you the ability to handle anomalous intermediate values without blowing out the logical complexity. That's actually what IEEE-754 was intended to standardise and enable - not floating-point itself, which was already in widespread use, but the finer points of error handling and rounding to improve reliability. Most 8-bit BASICs predate that, but there's no theoretical reason why they couldn't implement IEEE-754 in a new version.

So you can come up with the correct theoretical result, then recognise that it's outside the mechanical limits of the machine, and handle that. Or you could recognise during the intermediate calculation that some particular joint is implied to be in a non-physical state, and handle the error from there.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 20, 2020 8:10 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
While that's true, my guess would be that avoiding tan, with its difficult behaviour, would also be a common tactic. Indeed, by some approaches it's just as cheap to calculate both sin and cos for the same cost, and a sincos function is provided which returns two results - just as Garth's does.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 1:18 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8510
Location: Southern California
These polynomial approximations from Namir Shammas should be of interest:
http://www.namirshammas.com/NEW/ShamPoly.html

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC


Who is online

Users browsing this forum: jds and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: