The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: someone on May 24, 2010, 03:35:16 AM

Title: radians to degrees
Post by: someone on May 24, 2010, 03:35:16 AM

i have some 64 bit numbers which are elsewhere declared in a c++ structure as "double"
and also some 32 bit numbers declared as "float"
(of course in assembly i just have the bits/bytes with no specific declaration yet)

the values are radians and i need to convert them to degrees and then later to strings

how can i do this, especially the radians to degrees part ?
Title: Re: radians to degrees
Post by: clive on May 24, 2010, 03:50:28 AM
360 degrees is 2PI radians.

Multiply the Radians value by the floating point constant (180.0 / PI), to go the other way multiply by (PI / 180.0)

Need this in 80x87 instructions?


rad2deg  REAL8  57.295779513082323
deg2rad  REAL8  0.017453292519943295

  fld yournumber
  fmul qword ptr rad2deg
  fstp answer


Using higher precision 80-bit constants


rad2deg  REAL10  57.2957795130823208767
deg2rad  REAL10  0.0174532925199432957691

  fld yournumber
  fmul tbyte ptr rad2deg
  fstp answer
Title: Re: radians to degrees
Post by: raymond on May 24, 2010, 05:02:17 AM
Once your input is declared as a QWORD or REAL8 (for doubles), or DWORD or REAL4 (for floats), and you don't want to precalculate those conversion constants and include them in your .data section, you could simply use the following which is less prone to errors:

fld myradian
pushd 180
fimul dword ptr[esp]   ;multiply by the integer 180
add   esp,4            ;clean the stack
fldpi                  ;load the pi constant from the FPU
fdiv                   ;divide by pi
fstp  mydegree         ;store the result
;mydegree would have been declared previously as a REAL8 or REAL4 depending on the required precision


And later, if you want to convert such numbers to text, you could use one of the several available conversion functions, one of them being FpuFLtoA provided in the Fpulib.

Title: Re: radians to degrees
Post by: someone on May 26, 2010, 12:12:02 PM
ok, now i understand it  :U
thanks guys
Title: Re: radians to degrees
Post by: someone on May 26, 2010, 02:24:26 PM
ok, it seems i still need help with this one
i've got the radians to degrees conversion working, but there is still something not right with my code

i'm reading the longitude and latitude from a garmin gps unit, the data is received in their 'proprietary format'
all source code that i can find is in c/c++, so the received data packet as i know it, is a c structure defining the longitude
and latitude (seperately) as 'float64' and in different versions 'double', (i assume 'float64' and 'double' are the same), the
protocol documents say the float64 is the standard ieee format (1 sign bit, 11 exponent bits, and 52 mantissa bits)

it says they are radians, and so i need to convert them to degrees (*180/pi), which i know how to do now
but i still can't get the right result, the fpu result is still another exponent value, nothing that resembles a lat/lon degree
all example source code that i can see does exactly what i do (value*180/pi) but in c/c++, and the result is different
i don't know what is going wrong with the conversion, but perhaps it's just being displayed wrong

how can i display a 64bit floating point value in proper decimal notation (ie not the exponent value) the result should
obvisouly be something like: 123.456789 not 1.234567e-89

Title: Re: radians to degrees
Post by: dedndave on May 26, 2010, 02:34:44 PM
well - there are different IEEE specs   :bg
i think i would try to simply display a few of the values in hexidecimal to verify the format and that the values make sense
it may be something simple like reversed byte order (Intel stores values in "little-endian" order)
if you can show us a floating point value in hexidecimal form, and tell us approx what it should be in radians, we will check it

EDIT - it might also help to have the Garmin model number
there may be documentation and/or code available online that we can look at

http://www8.garmin.com/support/userManual.jsp?market=1&subcategory=All&product=All
Title: Re: radians to degrees
Post by: someone on May 26, 2010, 03:02:16 PM
i'm using the garmin gps 18x usb module

here are the specifications for that module:
http://www8.garmin.com/manuals/GPS18x_TechnicalSpecifications.pdf
the pvt structure is defined in "APPENDIX B: GARMIN BINARY OUTPUT FORMAT" under "Position Record" as "cpo_pvt_data"
on page 30of37

and here are the specifications for the garmin proprietary format:
http://www.garmin.com/support/pdf/iop_spec.pdf
the pvt structure is defined at 7.4.40 as "D800_Pvt_Data_Type" on page 53of70
also the more relevant definition of the data type "radian_position_type" is on page 30-31of70

also here is some example code that i've been trying to learn from, but unfortunately it's mostly c/c++
http://www.personal.psu.edu/sqm110/GPS_Development/Garmin18USB_write.c
https://svn.freepository.com/50lItuLQ7fW6s-web/browser/Tracker2/trunk/sources/garmin.c?rev=103
http://www.powerbasic.com/support/pbforums/showthread.php?t=24565
Title: Re: radians to degrees
Post by: clive on May 26, 2010, 03:14:35 PM
I work on GPS receivers, most everything uses IEEE-754 floating point, there may however be endian issues, say if the system uses a Motorola processor. The Garmin data I'm familiar with from the consumer units is directly compatible with the PC.

Which Garmin packet are you using? Record 0x33?

Record should be a combination of float (32-bit) and double (64-bit)

float Altitude;
float ErrorPosition; // PDOP eqv
float ErrorHoriziontal; // HDOP eqv
float ErrorVertical; // VDOP eqv

short int FixType;

double GPSTimeOfWeek;

double Latitude;
double Longitude;

float VelocityLongitude;
float VelocityLatitude;
float VelocityVertical;
float MeanSeaLevelHeight;

short int LeapSeconds;
long int GarminDays;// Since GPS Week 521
Title: Re: radians to degrees
Post by: someone on May 26, 2010, 03:24:33 PM
yeh that's the one 0x33 (51) for the pvt data (and 0x72 (114) comes simultaneously for the satellite data)
and yeh that's the structure with a combination of 32 bit and 64 bit floats
Title: Re: radians to degrees
Post by: clive on May 26, 2010, 03:28:49 PM
Ok, we are talking about the same structure(cpo_pvt_data). I will note that 'int' in the documentation refers to a 16-bit integer, and 'long' to a 32-bit integer.

The packet is marked 0x33 (record), 0x40 (length), cpo_pvt_data

0000 : 33 40 17 45 3F 43 BF ED-92 41 58 44 1B 41 F8 7C 3@.E?C...AXD.A.|
0010 : 79 41 03 00 35 39 FF FF-43 49 14 41 6E 33 30 EA yA..59..CI.An30.
0020 : 3F 58 E7 3F 72 D7 44 46-60 A6 F8 BF E0 35 40 BC ?X.?r.DF`....5@.
0030 : CE 2F 15 BC B8 28 4A 3B-30 C6 08 42 0E 00 24 1A ./...(J;0..B..$.
0040 : 00 00                                           ..

Size of 64
Ellipsoid Altitude             191.269882
Estimated Position Error       18.366087
Position Error Horizontal      9.704185
Position Error Vertical        15.593010
Fix Type                       3
GPS Time-of-Week               332368.999997
Latitude                       41.798570
Longitude                      -88.270976
Longitude Velocity             -0.011732
Latitude Velocity              -0.009106
Altitude Velocity              0.003085
Mean sea lebel height          34.193542
Leap seconds                   14
Garmin Days                    6692
Title: Re: radians to degrees
Post by: dedndave on May 26, 2010, 03:38:18 PM
in the Garmin SDK, there is a document called IntfSpec.pdf (interface specification)
it says that the data is received in little-endian order
maybe there is something amiss with the way you have defined the structure
Title: Re: radians to degrees
Post by: clive on May 26, 2010, 03:44:28 PM
My exemplar from some time ago is correctly decoded. My eTrex unit wasn't outputting record 0x72, and the output frankly sucked from technical standpoint (UART data generally overran itself, and the embedded CPU was overloaded). I was looking a gathering raw data (pseudorange, phase, doppler) and ephemeris, and generating RINEX data. I have a GPS 18 LVC on shelf, but haven't look at it in a while.

You have to make sure you have the offsets decoded properly when extracting the data. Any reason this has to be done in assembler?
Title: Re: radians to degrees
Post by: oex on May 26, 2010, 03:56:07 PM
RINEX sounds interesting, I dont get outside the web much, it is my prison four walls since my teenage years so rarely see data formats info for satellites, medical and the like.
Title: Re: radians to degrees
Post by: someone on May 26, 2010, 03:57:05 PM
clive:
i've already done the whole gps part in assembler, all that's left is to decode/calculate the values received in the pvt structure, which should be just mathematical calculations, but somethings going wrong
the data received from the gps seems to be the data pushed onto the fpu stack for the calculations, so the offsets should be ok
i think the gps 18 lvc can interface directly via com ports, therefore you can use the nmea commands which seem to be a bit easier
than the garmin proprietary format, although i only say that having experienced these calculation problems

dedndave:
until i get it worked out, i've only been defining the value as i need it (ie in code), at the moment the structure just contains an array of 8 bytes for longitude and 8 for latitude, i define what it is when i push it onto the stack
also i've been trying all different combinations of bit orders, even clearing out the sign and exponent bits, but
the result never seems to even come close to what i am looking for

the document in the garmin sdk (IntfSpec.pdf) is the same as the linked document (iop_spec.pdf)
http://www.garmin.com/support/pdf/iop_spec.pdf

i think the real problem is that i get stuck with the conversion with floating point numbers
also the conversion between radians and degrees and semicircles has made it more complicated
and the fpu result in my debugger always shows an exponent value, which has stopped me from being able to figure it out
Title: Re: radians to degrees
Post by: clive on May 26, 2010, 04:06:47 PM
Quote from: oex on May 26, 2010, 03:56:07 PM
RINEX sounds interesting, I dont get outside the web much, it is my prison four walls since my teenage years so rarely see data formats info for satellites, medical and the like.

The post-processing of the data is where the real fun is. Using consumer grade receivers (ie L1 only) to get an antenna position to around a centimeter accuracy. I've built a couple of RINEX converters, and have some Ashtech G12's and Sharpe XR5/XR6's with solutions converging in the millimeters.

I have a CORS (continually operating reference site) at the FAA facility about 7 km from me.
Title: Re: radians to degrees
Post by: clive on May 26, 2010, 04:34:17 PM
; garmasm.asm
; ml -coff -Fl garmasm.asm \masm32\lib\msvcrt.lib -link /SUBSYSTEM:CONSOLE

        .486
        .MODEL FLAT, C
        .DATA

    c_msvcrt typedef PROTO C :VARARG

    externdef _imp__printf:PTR c_msvcrt
    crt_printf equ <_imp__printf>

Rec33   STRUC

GarminRecord            DB      ?
GarminLength            DB      ?

Altitude                REAL4   ?
ErrorPosition           REAL4   ?
ErrorHoriziontal        REAL4   ?
ErrorVertical           REAL4   ?

FixType                 DW      ?

GPSTimeOfWeek           REAL8   ?

Latitude                REAL8   ?
Longitude               REAL8   ?

VelocityLongitude       REAL4   ?
VelocityLatitude        REAL4   ?
VelocityVertical        REAL4   ?
MeanSeaLevelHeight      REAL4   ?

LeapSeconds             DW      ?
GarminDays              DD      ? ; Since GPS Week 521

Rec33   ENDS

Example db      033h,040h,017h,045h,03Fh,043h,0BFh,0EDh,92h,041h,058h,044h,01Bh,041h,0F8h,07Ch
        db      079h,041h,003h,000h,035h,039h,0FFh,0FFh,43h,049h,014h,041h,06Eh,033h,030h,0EAh
        db      03Fh,058h,0E7h,03Fh,072h,0D7h,044h,046h,60h,0A6h,0F8h,0BFh,0E0h,035h,040h,0BCh
        db      0CEh,02Fh,015h,0BCh,0B8h,028h,04Ah,03Bh,30h,0C6h,008h,042h,00Eh,000h,024h,01Ah
        db      000h,000h

rad2deg REAL8   57.2957795130823208767
answer  REAL8   ?
outdbl  db      "%14.10lf",10,13,0

        .CODE

start:
                lea     esi,Example

                fld     Rec33.Latitude[esi]
                fmul    rad2deg
                fstp    answer

                invoke  crt_printf, addr outdbl, answer

                fld     Rec33.Longitude[esi]
                fmul    rad2deg
                fstp    answer

                invoke  crt_printf, addr outdbl, answer

                ret

        END     start


41.7985697322
-88.2709756051


This is decimal degrees, not the DDDMM.mmmm format used by NMEA

The 80-bit version codes like this, but the printf doesn't support it (%Lf)
rad2deg REAL10  57.2957795130823208767
answer  REAL10   ?

                fld     Rec33.Latitude[esi]
                fld     rad2deg
                fmulp   st(1),st(0)
                fstp    answer


Technically that is probably overkill, as the value of PI used by GPS receivers should be 3.1415926535898, as defined in the ICD-200 interface control document. I was thinking more of a general radian/degree conversion when the question was initially posed.

Also 32-bit Microsoft C/C++ has both double and long double as 64-bit. The older DOS versions long double was 80-bit. Some more profession compilers and things like FORTRAN (REAL*10) can support 80-bit. The 80x87 intrinsically supports it.
Title: Re: radians to degrees
Post by: someone on May 26, 2010, 05:20:41 PM
ok, the problem here is that i don't have the library msvcrt.lib
what function exactly is crt_printf in the dll, using Dependency Walker i can't find crt_printf or _imp__printf
Title: Re: radians to degrees
Post by: clive on May 26, 2010, 05:35:50 PM
MSVCRT.DLL (\WINDOWS\SYSTEM32)

Exp Addr Hint   Ord Export Name by msvcrt.dll - Sun Apr 13 11:41:06 2008
-------- ---- ----- ---------------------------------------------------------
0003186A  2E5   742 printf


__imp__printf is a linker mechanism for pulling it in. If you have some other method for printing floats/doubles you could use that.

Download MASM32 if you need the libraries. http://www.masm32.com/masmdl.htm
Title: Re: radians to degrees
Post by: vanjast on May 26, 2010, 09:06:59 PM
A thought...
May I suggest you do not waste your time with Garmin and move onto the cheaper GPSs, like TomTom..etc.
Garmin is 2x or 3x the price of the others (where I am at least) so probably has a very limited lifespan.
:lol
Title: Re: radians to degrees
Post by: clive on May 26, 2010, 09:41:42 PM
The unit in question is an OEM puck antenna implementation, not a dash mount. Plus the poster is pulling raw PVT (Position,Velocity,Time) as a single binary message instead of a couple of $GPxxx NMEA sentences. This is a lot more efficient, and usually provides lat,lon,alt with more precision. Certainly the eTrex I have can push NMEA, or propriety raw data, but I can't say I was impressed with it's accuracy, quality of raw data, or it's MGRS conversion.

I'd probably pick up a $20 USB device which I could program to get 10 Hz raw measurements, and PVT solutions.
Title: Re: radians to degrees
Post by: someone on May 27, 2010, 03:23:55 AM
ok, it's working now  :bg

from comparing your code to mine, i can see the difference, i had defined the structure wrong, uint16_fix (FixType) was only declared as one byte when it should have been using two, a stupid mistake
this threw off all values after that in the structure by one byte, which is why the floating point conversions always
shown something in scientific notation with exponent, rather than a clear decimal representation, i thought it was just me
doing the float to string conversion wrongly

i've been using a really old version of masm which didn't include msvcrt or fpulib among other things, now i've installed
the new version i still can't get the crt_printf function working from msvcrt, but that doesn't matter, because now i can
use the FpuFLtoA function from the fpulib which is even better

thank you so much for all your help
Title: Re: radians to degrees
Post by: raymond on May 27, 2010, 04:14:01 AM
Quotenow i can use the FpuFLtoA function from the fpulib which is even better

If you recently downloaded the fpulib from:
http://www.ray.masmcode.com/fpu.html#fpulib
you are guaranteed to have the very latest version, last modified in January 2010. It does have more flexibility than older versions previously distributed with the MASM32 package or downloadable from other sites.

Otherwise, you may want to get that latest version.