CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

cordic implementation
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
heli_potter



Joined: 20 Apr 2009
Posts: 6

View user's profile Send private message

cordic implementation
PostPosted: Mon Apr 20, 2009 11:09 pm     Reply with quote

Trying to implement cordic32 routine provided in code library, on the following formula. Separate value of sin(), cos etc are ok but when used in formula, the result is weird. i.e.
Code:
tmp2 = cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(dLon);

gives inappropiate result.
Any ideas .... ?

Regards...
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Apr 21, 2009 12:31 am     Reply with quote

You may want to tell example input and intermediate results of the individual terms to allow others to trace the problem.
heli_potter



Joined: 20 Apr 2009
Posts: 6

View user's profile Send private message

sample data
PostPosted: Tue Apr 21, 2009 1:22 am     Reply with quote

Ok here is the sample data.
53.15055 is 531505500.

tmp = cos(531505500)*sin(532047200)-sin(531505500)*cos(532047200)*cos(17038888)

with calculator: tmp= -0.3445466179551353
cordic: tmp=-641923529

even breaking up the equation in multiple line doesnt work.
implemented in Borland C compiler for the time.
Ttelmah
Guest







PostPosted: Tue Apr 21, 2009 3:05 am     Reply with quote

Hint.
You have obviously got your calculator set to work in degrees, to give the result you are seeing. This is _not_ the angular format used in most languages (including C)...

Best Wishes
heli_potter



Joined: 20 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Tue Apr 21, 2009 3:24 am     Reply with quote

Ttelmah wrote:
Hint.
You have obviously got your calculator set to work in degrees



Calculator is set to radians.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Tue Apr 21, 2009 6:53 am     Reply with quote

So cos(531505500) is taking the cosine of 8 1/2 revolutions? That strikes me as odd. What is the application?

53.51 radians = 3045 degrees = 8.4 revs (aprox)
_________________
The search for better is endless. Instead simply find very good and get the job done.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Apr 21, 2009 10:28 am     Reply with quote

The cordic library is using degrees, as far as I understand.
heli_potter



Joined: 20 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Tue Apr 21, 2009 10:56 pm     Reply with quote

SherpaDoug wrote:
So cos(531505500) is taking the cosine of 8 1/2 revolutions? That strikes me as odd. What is the application?


You people took it wrong. Actually cordic library take the argument in degree. What I mentioned was that for calculator I converted it to radians. i.e given here 53.15055 (531505500) is in degress which gives 599714461 and calculator gives .5997144588 for Cosine, which is correct. But my question remains when multiple values of sines and cosine are multiplied the result gets wrong. I have even tried to break it up in multiple expressions.

The application is to calculate bearing from given latitude and longitude.
thanks...
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Apr 21, 2009 11:58 pm     Reply with quote

Quote:
But my question remains when multiple values of sines and cosine are multiplied the result gets wrong. I have even tried to break it up in multiple expressions.


Yes, thus I previously suggested
Quote:
to tell example input and intermediate results of the individual terms to allow others to trace the problem.


This would have avoided also the degree/radians misunderstanding. Either an elementary Cordic function is giving wrong results, or it's another problem not directly related to Cordic. But no need to guess.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Wed Apr 22, 2009 12:10 am     Reply with quote

The purpose of the cordic is to avoid especially for the PIC the overhead of floating point and trig operations. I added the cordic to the library for that very reason. The cordic introduces the concept of binary notation in respect of angles. The tangent of 45 deg is represented by 1. then the tangent of 26.56 as 1/2 as binary 0.1 . Rotations then are performed using simple binary shift operations instead of multiplications . It is quadrant dependent and uses angles 0 to 90 degs and loses some precision as angles near 90 and 0. It could have been done in radians but wasn't. The cordic algorithm can have any precision. 32 bit was chosen since CCS provides for 32 bit binary storage and operations ( add subtract and rotate). Your calculation of a bearing in spherical geometry almost negates this purposed in that it uses
Quote:
tmp2 = cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(dLon);

and is burdened by multiplication. 32 bit times 32 bit times 32 bits needs a 96 bit accumulator to maintain precision. If your two points on a sphere are within the same hemisphere set one pt as the center of a unit circle in a plane tangential to that point and project the other point onto it then rotate the co-ordinates using the cordic to the zero degree axis to get the angle. If you don't understand the mathematics then just do the whole thing in trig using the formula you have and accept the overhead.
Calculators use binary coded decimal and thus never leave decimal notation so they inherently will vary from pure binary notation used by the PIC and the CCS compiler. These are not errors just the expected variance between notations Ex 0.1 in decimal can't be notated in binary to arbitrary precision.
heli_potter



Joined: 20 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Apr 22, 2009 1:05 am     Reply with quote

Quote:
If your two points on a sphere are within the same hemisphere set one pt as the center of a unit circle in a plane tangential to that point and project the other point onto it then rotate the co-ordinates using the cordic to the zero degree axis to get the angle.


It will be so nice of u if u elaborate a bit with an example.
BTW I have tried it on Borland C, regarding 96 bit accumulator issue.Its the same.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Apr 22, 2009 4:01 am     Reply with quote

@heli_potter: Basically, the cordic library uses a fixed point numeric representation. Fixed point numbers can't be multiplied without scaling the result during respectively after the multiply. As recently discussed in another thread, if you multiply two 32 bit integers to an int32 result, the upper 32 bits are discarded. That means, that a fractional number (representing -1..1) or most fixed point numbers must be downscaled before the multiply. Also, if your result has 64 or 96 bit resolution, a scaling or a shift after multiply is necessary.

@Douglas Kennedy: I must admit, that I don't see at first look, which number representation is used in the library. The 10e-7 scaling for degrees is clear, but the "length" or result scaling isn't. Mainly, because I didn't run the example code, I think. But it can be stated more clearly in the comments to my opinion. So in the below comment, what's the int32 value representing a "length" value of 0.607? Is it 1000000000 (0x3B9ACA00) or 607252935 (0x2431F1C7)? Or neither?
Quote:
/// so 1000000000 is 607252935 for 0.6072529350088813

Or, as another simple question, what's the int32 value representing tan(45°) respectively 1.0
heli_potter



Joined: 20 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Apr 22, 2009 5:55 am     Reply with quote

You are right Fvm. I dont know what Mr. Douglas has to say.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Apr 22, 2009 6:15 am     Reply with quote

Quote:
I dont know what Mr. Douglas has to say.

Well, the int32 * in32 point clearly says, why your code can't work. I only wondered about the correct scaling of the product. But it must be scaled, you didn't however.

P.S.: According to the results of the cordic.c example, the length values have a 1e9 scaling.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Wed Apr 22, 2009 5:04 pm     Reply with quote

As expected all numbers in the CCS compiler are binary and all operations by the cpu are binary. The compiler converts from decimal notation to binary when it sees numeric constants first they are decoded from ascii and then to binary and similarly various routines ex printf do the reverse. Within the storage requirement limitation on precision all operations are in binary and are exact in binary notation. Translation from binary to decimal notation produces differences that are often mislabeled as rounding errors especially when compared with a hand held calculator that never leaves decimal notation. Now when numerical values are scaled up so that integers represent what would otherwise be a fractional value higher correspondence between decimal and binary notation results. Now trig numbers are not rational numbers with the exception of certain values like cos(60) cos(0) cos(90) and no non rational number can be accurately represented in any notation except algebraic. Even rational numbers like 1/3 can't be expressed in decimal without some cut of point in precision. 32 bits puts the precision in the 9 significant decimal digit range. Iterations accumulate inaccuracies so the final result is likely to be accurate to 7or 8 significant digits. The CORDIC can be written to say 91 bit precision ( or any number of bits) but is cumbersome to implement unless the register sizes were also 91 bit. For CCS 16 bit precision is a bit low so the next most convenient size is 32 although 24 bit is fairly useful. As to heli_potter this is a self help board not a help yourself board. If the CORDIC isn't to your liking then don't help yourself to it. To define the help you get as not meeting your needs might come from the fact that you can't express your needs or maybe you don't understand your needs.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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 vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group