 |
|
 |
| Parallax Forums > Public Forums > BASIC Stamp > Tracy Allen cordic examples | Forum Quick Jump
|
|  Peter Verkaik Registered Member
        Date Joined Jul 2004 Total Posts : 3985 | Posted 12/23/2005 6:21 PM (GMT -7) |   | | Hi,
I converted the basic stamp cordic examples at the top of page
to the javelin and get these results
Test program CORDIC
cos( 0.0) = 0.9997 sin( 0.0) = 0.0000 cos( 0.1) = 0.9997 sin( 0.1) = 0.0017 cos( 1.0) = 0.9996 sin( 1.0) = 0.0175 cos( 30.0) = 0.8659 sin( 30.0) = 0.5000 cos( 45.0) = 0.7071 sin( 45.0) = 0.7071 cos( 60.0) = 0.5000 sin( 60.0) = 0.8659 cos( 89.0) = 0.0175 sin( 89.0) = 0.9996 cos( 89.9) = 0.0017 sin( 89.9) = 0.9997 cos( 90.0) = 0.0000 sin( 90.0) = 0.9997 cos( 0.1) = 0.9997 sin( 0.1) = -0.0017 cos( -1.0) = 0.9996 sin( -1.0) = -0.0175 cos(-30.0) = 0.8660 sin(-30.0) = -0.4998 cos(-45.0) = 0.7071 sin(-45.0) = -0.7071 cos(-60.0) = 0.5000 sin(-60.0) = -0.8659 cos(-89.0) = 0.0175 sin(-89.0) = -0.9996 cos(-89.9) = 0.0018 sin(-89.9) = -0.9997 cos(-90.0) = 0.0000 sin(-90.0) = -0.9997 x = 0.0001 y = 0.0001 len = 0.0001 atn = 43.3 x = 0.0010 y = 0.0010 len = 0.0013 atn = 43.3 x = 0.0100 y = 0.0100 len = 0.0141 atn = 45.0 x = 0.1000 y = 0.1000 len = 0.1413 atn = 45.0 x = 1.0000 y = 1.0000 len = 1.4139 atn = 45.0 x = 0.8660 y = 0.5000 len = 0.9997 atn = 30.0 x = -0.8660 y = 0.5000 len = 0.9997 atn = 120.0 x = -0.8660 y = -0.5000 len = 0.9997 atn = -120.0 x = 0.8660 y = -0.5000 len = 0.9997 atn = -30.0 x = 0.5000 y = 0.8660 len = 0.9997 atn = 60.0 x = -0.5000 y = 0.8660 len = 0.9997 atn = 150.0 x = -0.5000 y = -0.8660 len = 0.9997 atn = -150.0 x = 0.5000 y = -0.8660 len = 0.9997 atn = -60.0 program finished
All results are ok, except the calculated arctan values +-120.0 and +-150.0 which should be swapped according to the x and y values.
Can anyone confirm this for the basic stamp?
Also, is the calculated arctan value for x=y=0.0001 correct? (should be 45.0)
but as said the error increases for low x and y. Also, why is the cordic gain (0.607*65536) set to constant 39793 as it should be 39780?
regards peter
| | Back to Top | | |
  |  Tracy Allen Registered Member

       Date Joined Jul 2004 Total Posts : 3219 | Posted 12/24/2005 9:23 AM (GMT -7) |   | Hi Peter,
You've been busy! 
Thanks for the heads up about the error for the quadrant23 business. I'll correct that in the program (but not today--too much holiday stuff to do!). One of the first steps in the program is to move points that happen to be in quadrants 2 or 3 over into quadrant 1 and 4 by reflection in the y axis (x=-x). So once the angle is computed it makes perfect sense to reflect the computed angles back through the y axis and that is what your correction does. I don't know how the rotation by 90 degrees got in there. There must have been dust in the afterburner.
As to the Cordic gain, when I first wrote the programs, I took 0.6072 as an approximation, and then when I explained it in the text I rounded it off to 0.607. That accounts for the difference between 39793 and 39780. But neither one is right. A closer approximation is 0.607252935, and for that the Stamp ** factor should be 39797. I'll work that into the program too, but that probably won't make much difference.
I did go into the www page and changed the exposition. Always tinkering.
As to the errors to calculate arctangent when x=y=0.0001. It is due to integer roundoff. The algorithm needs digits to work with internally to carry through the precision. One solution would be to put another wrapper on it, so that if the input numbers are "small", they will be multiplied times a constant at the outset and then rounded down or handled appropriately at the end. It would be kind of ad-hoc floating point, so that the algorithm always works at maximum precision. That way one could represent the angle in that particular case correctly as 45 degrees and also the length of the vector at 0.00007071. There is no way to get the 0.00007071 without scaling it at the outset. Another way to do it is to go to double precision, 32 bits, but call it 24 bit precision and keep 8 throwaway bits in reserve to slosh around internally. On the demo page, I was more interested in just getting it working on the Stamp--without getting into the complications of double precision.
Here is the sequence of values of the product of the {cos(atn(1/2^i)}, to show how fast it converges. 0.707106781186547 0.632455532033676 0.613571991077896 0.608833912517752 0.607648256256168 0.607351770141296 0.607277644093526 0.607259112298893 0.607254479332562 0.607253321089875 0.607253031529134 0.607252959138945 0.607252941041397 0.607252936517010 0.607252935385914 0.607252935103139 0.607252935032446 <-- 16th product on Stamp **39797 0.607252935014772 0.607252935010354 0.607252935009249 0.607252935008973 0.607252935008904 0.607252935008887 0.607252935008883 0.607252935008882 0.607252935008881 0.607252935008881 0.607252935008881 0.607252935008881 Tracy Allen www.emesystems.com | | Back to Top | | |
      |  Peter Verkaik Registered Member
        Date Joined Jul 2004 Total Posts : 3985 | Posted 12/25/2005 7:25 AM (GMT -7) |   | Tracy, the atan2(y,x) function really behaves weird when x=0 x = 0.0000 y = 0.0000 atan2(y,x) = - 80.1 x = 0.0000 y = 0.0001 atan2(y,x) = - 90.0 x = 0.0000 y = 0.0010 atan2(y,x) = 90.0 x = 0.0000 y = 0.0100 atan2(y,x) = 90.0 x = 0.0000 y = 0.1000 atan2(y,x) = - 90.0 x = 0.0000 y = 1.0000 atan2(y,x) = 90.0 x = 0.0000 y = -0.0001 atan2(y,x) = 90.0 x = 0.0000 y = -0.0010 atan2(y,x) = - 90.0 x = 0.0000 y = -0.0100 atan2(y,x) = - 90.0 x = 0.0000 y = -0.1000 atan2(y,x) = - 90.0 x = 0.0000 y = -1.0000 atan2(y,x) = - 90.0 x = 0.0001 y = 0.0001 atan2(y,x) = 45.0 x = 0.0001 y = 0.0010 atan2(y,x) = 84.3 x = 0.0001 y = 0.0100 atan2(y,x) = 89.4 x = 0.0001 y = 0.1000 atan2(y,x) = 89.9 x = 0.0001 y = 1.0000 atan2(y,x) = 90.0 x = 0.0001 y = -0.0001 atan2(y,x) = - 45.0 x = 0.0001 y = -0.0010 atan2(y,x) = - 84.3 x = 0.0001 y = -0.0100 atan2(y,x) = - 89.4 x = 0.0001 y = -0.1000 atan2(y,x) = - 89.9 x = 0.0001 y = -1.0000 atan2(y,x) = - 90.0 x = -0.0001 y = 0.0001 atan2(y,x) = 135.0 x = -0.0001 y = 0.0010 atan2(y,x) = 95.7 x = -0.0001 y = 0.0100 atan2(y,x) = 90.6 x = -0.0001 y = 0.1000 atan2(y,x) = 90.1 x = -0.0001 y = 1.0000 atan2(y,x) = 90.0 x = -0.0001 y = -0.0001 atan2(y,x) = -135.0 x = -0.0001 y = -0.0010 atan2(y,x) = - 95.7 x = -0.0001 y = -0.0100 atan2(y,x) = - 90.6 x = -0.0001 y = -0.1000 atan2(y,x) = - 90.1 x = -0.0001 y = -1.0000 atan2(y,x) = - 90.0
When x=0 and y=0 it really is a discontinuity and requires special treatment. When x=0 and y<>0 the result sometimes have correct sign, sometimes incorrect sign. The absolute value of the result is correct. So I test for x=0 as a special case and return angles based on sign of y. Then the results are
x = 0.0000 y = 0.0000 atan2(y,x) = 45.0 x = 0.0000 y = 0.0001 atan2(y,x) = 90.0 x = 0.0000 y = 0.0010 atan2(y,x) = 90.0 x = 0.0000 y = 0.0100 atan2(y,x) = 90.0 x = 0.0000 y = 0.1000 atan2(y,x) = 90.0 x = 0.0000 y = 1.0000 atan2(y,x) = 90.0 x = 0.0000 y = -0.0001 atan2(y,x) = - 90.0 x = 0.0000 y = -0.0010 atan2(y,x) = - 90.0 x = 0.0000 y = -0.0100 atan2(y,x) = - 90.0 x = 0.0000 y = -0.1000 atan2(y,x) = - 90.0 x = 0.0000 y = -1.0000 atan2(y,x) = - 90.0 x = 0.0001 y = 0.0001 atan2(y,x) = 45.0 x = 0.0001 y = 0.0010 atan2(y,x) = 84.3 x = 0.0001 y = 0.0100 atan2(y,x) = 89.4 x = 0.0001 y = 0.1000 atan2(y,x) = 89.9 x = 0.0001 y = 1.0000 atan2(y,x) = 90.0 x = 0.0001 y = -0.0001 atan2(y,x) = - 45.0 x = 0.0001 y = -0.0010 atan2(y,x) = - 84.3 x = 0.0001 y = -0.0100 atan2(y,x) = - 89.4 x = 0.0001 y = -0.1000 atan2(y,x) = - 89.9 x = 0.0001 y = -1.0000 atan2(y,x) = - 90.0 x = -0.0001 y = 0.0001 atan2(y,x) = 135.0 x = -0.0001 y = 0.0010 atan2(y,x) = 95.7 x = -0.0001 y = 0.0100 atan2(y,x) = 90.6 x = -0.0001 y = 0.1000 atan2(y,x) = 90.1 x = -0.0001 y = 1.0000 atan2(y,x) = 90.0 x = -0.0001 y = -0.0001 atan2(y,x) = -135.0 x = -0.0001 y = -0.0010 atan2(y,x) = - 95.7 x = -0.0001 y = -0.0100 atan2(y,x) = - 90.6 x = -0.0001 y = -0.1000 atan2(y,x) = - 90.1 x = -0.0001 y = -1.0000 atan2(y,x) = - 90.0
I treat the case x=0 and y=0 just like y=x and so 45.0 degrees is returned. I will post my class shortly.
regards peter
| | Back to Top | | |
 |  Peter Verkaik Registered Member
        Date Joined Jul 2004 Total Posts : 3985 | Posted 12/26/2005 7:17 AM (GMT -7) |   | Tracy, I have uploaded my class here: http://groups.yahoo.com/group/JavelinCode/files/Javelin%20Stamp%20IDE/lib/stamp/math/
Final results: x=cos( 0.0) = 0.9999 y=sin( 0.0) = 0.0000 tan( 0.0) = 0.00 atan2(y,x) = 0.0 x=cos( 0.1) = 0.9999 y=sin( 0.1) = 0.0017 tan( 0.1) = 0.00 atan2(y,x) = 0.1 x=cos( 0.4) = 0.9999 y=sin( 0.4) = 0.0069 tan( 0.4) = 0.01 atan2(y,x) = 0.4 x=cos( 0.5) = 0.9999 y=sin( 0.5) = 0.0087 tan( 0.5) = 0.01 atan2(y,x) = 0.5 x=cos( 1.0) = 0.9997 y=sin( 1.0) = 0.0176 tan( 1.0) = 0.02 atan2(y,x) = 1.0 x=cos( 15.0) = 0.9660 y=sin( 15.0) = 0.2588 tan( 15.0) = 0.27 atan2(y,x) = 15.0 x=cos( 30.0) = 0.8660 y=sin( 30.0) = 0.5000 tan( 30.0) = 0.58 atan2(y,x) = 30.0 x=cos( 45.0) = 0.7072 y=sin( 45.0) = 0.7072 tan( 45.0) = 1.00 atan2(y,x) = 45.0 x=cos( 60.0) = 0.5000 y=sin( 60.0) = 0.8660 tan( 60.0) = 1.73 atan2(y,x) = 60.0 x=cos( 75.0) = 0.2588 y=sin( 75.0) = 0.9660 tan( 75.0) = 3.73 atan2(y,x) = 75.0 x=cos( 89.0) = 0.0176 y=sin( 89.0) = 0.9997 tan( 89.0) = 56.80 atan2(y,x) = 89.0 x=cos( 89.4) = 0.0104 y=sin( 89.4) = 0.9999 tan( 89.4) = 96.14 atan2(y,x) = 89.4 x=cos( 89.5) = 0.0086 y=sin( 89.5) = 0.9999 tan( 89.5) = 114.93 atan2(y,x) = 89.5 x=cos( 89.8) = 0.0034 y=sin( 89.8) = 0.9999 tan( 89.8) = 294.09 atan2(y,x) = 89.8 x=cos( 89.9) = 0.0017 y=sin( 89.9) = 0.9999 tan( 89.9) = 327.67 atan2(y,x) = 89.9 x=cos( 90.0) = 0.0000 y=sin( 90.0) = 0.9999 tan( 90.0) = 327.67 atan2(y,x) = 90.0 x=cos( 90.1) = -0.0017 y=sin( 90.1) = 0.9999 tan( 90.1) = -327.67 atan2(y,x) = 90.1 x=cos( 90.2) = -0.0034 y=sin( 90.2) = 0.9999 tan( 90.2) = -294.08 atan2(y,x) = 90.2 x=cos(- 0.1) = 0.9999 y=sin(- 0.1) = -0.0017 tan(- 0.1) = 0.00 atan2(y,x) = - 0.1 x=cos(- 0.4) = 0.9999 y=sin(- 0.4) = -0.0069 tan(- 0.4) = - 0.01 atan2(y,x) = - 0.4 x=cos(- 0.5) = 0.9999 y=sin(- 0.5) = -0.0086 tan(- 0.5) = - 0.01 atan2(y,x) = - 0.5 x=cos(- 1.0) = 0.9997 y=sin(- 1.0) = -0.0176 tan(- 1.0) = - 0.02 atan2(y,x) = - 1.0 x=cos(-15.0) = 0.9660 y=sin(-15.0) = -0.2588 tan(-15.0) = - 0.27 atan2(y,x) = - 15.0 x=cos(-30.0) = 0.8660 y=sin(-30.0) = -0.5000 tan(-30.0) = - 0.58 atan2(y,x) = - 30.0 x=cos(-45.0) = 0.7072 y=sin(-45.0) = -0.7072 tan(-45.0) = - 1.00 atan2(y,x) = - 45.0 x=cos(-60.0) = 0.5000 y=sin(-60.0) = -0.8660 tan(-60.0) = - 1.73 atan2(y,x) = - 60.0 x=cos(-75.0) = 0.2588 y=sin(-75.0) = -0.9660 tan(-75.0) = - 3.73 atan2(y,x) = - 75.0 x=cos(-89.0) = 0.0176 y=sin(-89.0) = -0.9997 tan(-89.0) = - 57.13 atan2(y,x) = - 89.0 x=cos(-89.4) = 0.0104 y=sin(-89.4) = -0.9999 tan(-89.4) = - 96.14 atan2(y,x) = - 89.4 x=cos(-89.5) = 0.0087 y=sin(-89.5) = -0.9999 tan(-89.5) = -114.93 atan2(y,x) = - 89.5 x=cos(-89.8) = 0.0034 y=sin(-89.8) = -0.9999 tan(-89.8) = -294.08 atan2(y,x) = - 89.8 x=cos(-89.9) = 0.0017 y=sin(-89.9) = -0.9999 tan(-89.9) = -327.67 atan2(y,x) = - 89.9 x=cos(-90.0) = 0.0000 y=sin(-90.0) = -0.9999 tan(-90.0) = -327.67 atan2(y,x) = - 90.0 x=cos(-90.1) = -0.0017 y=sin(-90.1) = -0.9999 tan(-90.1) = 327.67 atan2(y,x) = - 90.1 x=cos(-90.2) = -0.0034 y=sin(-90.2) = -0.9999 tan(-90.2) = 294.08 atan2(y,x) = - 90.2
regards peter
| | Back to Top | | |
     |  Peter Verkaik Registered Member
        Date Joined Jul 2004 Total Posts : 3985 | Posted 12/26/2005 2:06 PM (GMT -7) |   | Tracy, Here are the results using the 90 words table x=cos( 0.0) = 1.0000 y=sin( 0.0) = 0.0000 tan( 0.0) = 0.00 atan2(y,x) = 0.0 x=cos( 0.1) = 0.9999 y=sin( 0.1) = 0.0017 tan( 0.1) = 0.00 atan2(y,x) = 0.1 x=cos( 0.4) = 0.9999 y=sin( 0.4) = 0.0070 tan( 0.4) = 0.01 atan2(y,x) = 0.4 x=cos( 0.5) = 0.9999 y=sin( 0.5) = 0.0087 tan( 0.5) = 0.01 atan2(y,x) = 0.5 x=cos( 1.0) = 0.9998 y=sin( 1.0) = 0.0175 tan( 1.0) = 0.02 atan2(y,x) = 1.0 x=cos( 15.0) = 0.9659 y=sin( 15.0) = 0.2588 tan( 15.0) = 0.27 atan2(y,x) = 15.1 x=cos( 30.0) = 0.8660 y=sin( 30.0) = 0.5000 tan( 30.0) = 0.58 atan2(y,x) = 30.2 x=cos( 45.0) = 0.7071 y=sin( 45.0) = 0.7071 tan( 45.0) = 1.00 atan2(y,x) = 45.0 x=cos( 60.0) = 0.5000 y=sin( 60.0) = 0.8660 tan( 60.0) = 1.73 atan2(y,x) = 59.8 x=cos( 75.0) = 0.2588 y=sin( 75.0) = 0.9659 tan( 75.0) = 3.73 atan2(y,x) = 74.9 x=cos( 89.0) = 0.0175 y=sin( 89.0) = 0.9998 tan( 89.0) = 57.13 atan2(y,x) = 89.0 x=cos( 89.4) = 0.0105 y=sin( 89.4) = 0.9998 tan( 89.4) = 95.22 atan2(y,x) = 89.4 x=cos( 89.5) = 0.0087 y=sin( 89.5) = 0.9999 tan( 89.5) = 114.93 atan2(y,x) = 89.5 x=cos( 89.8) = 0.0035 y=sin( 89.8) = 0.9999 tan( 89.8) = 285.68 atan2(y,x) = 89.8 x=cos( 89.9) = 0.0017 y=sin( 89.9) = 0.9999 tan( 89.9) = 327.67 atan2(y,x) = 89.9 x=cos( 90.0) = 0.0000 y=sin( 90.0) = 1.0000 tan( 90.0) = 327.67 atan2(y,x) = 90.0 x=cos( 90.1) = -0.0017 y=sin( 90.1) = 0.9999 tan( 90.1) = -327.67 atan2(y,x) = 90.1 x=cos( 90.2) = -0.0035 y=sin( 90.2) = 0.9999 tan( 90.2) = -285.68 atan2(y,x) = 90.2 x=cos(- 0.1) = 0.9999 y=sin(- 0.1) = -0.0017 tan(- 0.1) = 0.00 atan2(y,x) = - 0.1 x=cos(- 0.4) = 0.9999 y=sin(- 0.4) = -0.0070 tan(- 0.4) = - 0.01 atan2(y,x) = - 0.4 x=cos(- 0.5) = 0.9999 y=sin(- 0.5) = -0.0087 tan(- 0.5) = - 0.01 atan2(y,x) = - 0.5 x=cos(- 1.0) = 0.9998 y=sin(- 1.0) = -0.0175 tan(- 1.0) = - 0.02 atan2(y,x) = - 1.0 x=cos(-15.0) = 0.9659 y=sin(-15.0) = -0.2588 tan(-15.0) = - 0.27 atan2(y,x) = - 15.1 x=cos(-30.0) = 0.8660 y=sin(-30.0) = -0.5000 tan(-30.0) = - 0.58 atan2(y,x) = - 30.2 x=cos(-45.0) = 0.7071 y=sin(-45.0) = -0.7071 tan(-45.0) = - 1.00 atan2(y,x) = - 45.0 x=cos(-60.0) = 0.5000 y=sin(-60.0) = -0.8660 tan(-60.0) = - 1.73 atan2(y,x) = - 59.8 x=cos(-75.0) = 0.2588 y=sin(-75.0) = -0.9659 tan(-75.0) = - 3.73 atan2(y,x) = - 74.9 x=cos(-89.0) = 0.0175 y=sin(-89.0) = -0.9998 tan(-89.0) = - 57.13 atan2(y,x) = - 89.0 x=cos(-89.4) = 0.0105 y=sin(-89.4) = -0.9998 tan(-89.4) = - 95.22 atan2(y,x) = - 89.4 x=cos(-89.5) = 0.0087 y=sin(-89.5) = -0.9999 tan(-89.5) = -114.93 atan2(y,x) = - 89.5 x=cos(-89.8) = 0.0035 y=sin(-89.8) = -0.9999 tan(-89.8) = -285.68 atan2(y,x) = - 89.8 x=cos(-89.9) = 0.0017 y=sin(-89.9) = -0.9999 tan(-89.9) = -327.67 atan2(y,x) = - 89.9 x=cos(-90.0) = 0.0000 y=sin(-90.0) = -1.0000 tan(-90.0) = -327.67 atan2(y,x) = - 90.0 x=cos(-90.1) = -0.0017 y=sin(-90.1) = -0.9999 tan(-90.1) = 327.67 atan2(y,x) = - 90.1 x=cos(-90.2) = -0.0035 y=sin(-90.2) = -0.9999 tan(-90.2) = 285.68 atan2(y,x) = - 90.2
It shows the sin and cos are slightly more accurate (and thus tan also), but atan2 is slightly worse. This atan2 is calculated using the approximation
(y/x) 1800 atn = ------------------------ * ---- 0.1 deg units, for |y/x|<1 1 + 0.280872*(y/x)*(y/x) pi
So I favor cordic for atan2 calculation (and that also calculates sqrt(x*x+y*y) ).
regards peter
| | Back to Top | | |
  |  Tracy Allen Registered Member

       Date Joined Jul 2004 Total Posts : 3219 | Posted 12/28/2005 11:30 AM (GMT -7) |   | Hi Peter,
That makes sense. Table lookup, even with interpolation, will always be faster than iterative calculation.
On the other hand, CORDIC has an edge speedwise on polynomials. CORDIC always improves precision on the order of one bit for each iteration, while polynomials (in general) require an increasing number of iterations for each digit of precision.
I'm not sure how SIN, COS, ATN and HYP functions are implemented in the Stamp, (table or CORDIC). They are limited precision, but knowing Chip Gracey, who has a deep appreciation of this stuff, I'd guess they are CORDIC. Tracy Allen www.emesystems.com | | Back to Top | | |
      |  Tracy Allen Registered Member

       Date Joined Jul 2004 Total Posts : 3219 | Posted 12/30/2005 12:47 PM (GMT -7) |   | | | |
 | Forum Information | Currently it is Thursday, July 29, 2010 5:22 PM (GMT -7) There are a total of 462,441 posts in 62,066 threads. In the last 3 days there were 90 new threads and 802 reply posts. View Active Threads
| | Who's Online | This forum has 20143 registered members. Please welcome our newest member, ME01. 61 Guest(s), 16 Registered Member(s) are currently online. Details John Abshier, Erik Friesen, RossH, Kevin Wood, simpsonmichael1, BradC, David Betz, Julian800, Martin Hodge, RDL2004, prof_braino, Harley, Sapieha, wiresalot, Ravenkallen, Tubular |
Forum powered by dotNetBB v2.42EC SP2.02 dotNetBB © 2000-2010 |
|
|