Shop OBEX P1 Docs P2 Docs Learn Events
string/decimal question — Parallax Forums

string/decimal question

In the gps objects, why are coordinates converted and displayed as strings and not just left as decimals?
term.str(gps.s_longitude)                                                  'gps basic demo
/////////////////////////////////////////////////////
 DBG.Str(STRING(" Latitude in degres as FLOAT : "))           'gps float lite demo
  fv := GPS.Float_Latitude_Deg
  IF fv <> floatNaN
    DBG.Str(FS.FloatToString(fv))  

Comments

  • Coordinates are not decimals (integers), they are floating point values, which are not supported by the serial objects.
  • An NMEA string is .. a string.

    So every good NMEA GPS follow the NMEA protocol.

    You get first asci strings out of the NMEA GPS.
    If you want to do math, you have to convert to decimal or floating.




  • The number represents degrees, minutes, seconds and tenths of a second. You need to convert them to a number to use them as a number.

    www.fcc.g

    Mike
  • Thank you all for the info, that makes sense. I found this in a thread about changing strings to floats. I'm not clear on the first parameter from the code below, for the (from Str(str)), i put in the string value of the latitude to be converted to decimal and got back a really long integer that was nowhere near my latitude. Is this the way to change a string to a float? If the propeller receives the NMEA coordinates as a string in ASCII, how is the decimal dealt with? Is it converted to a char number equivalent?
    deSilva Posts: 2,967
    2007-09-15 - 15:19:33 edited 2007-09-15 - 15:19:33 Flag
    Absultely easy if the ste string has less than 10 digits and the decimal is implicite and on a known position (say always 2 digits from the end)
    floatval := FDiv( FFloat(fromStr(str)) , 100)
  • looks like FloatString version 1.2 has a method for changing strings to floats...
  • In all my years programming the Propeller, I have never used, or had a need for, floating-point math. It is especially unnecessary for GPS applications. Attached is some code that I use for GPS. Basically latitude and longitude are stored in integer microdegrees. From there, computations are pretty simple.

    -Phil
  • Today most modern day microcontroller have floating point processor built in and it is far simpler to use floating point math then to try and figure out some cryptic fixed point math that doesn't work.

    Mike
  • iseries,

    We're talking about the Propeller here, and it does not have a floating-point processor. Moreover, your comment about "cryptic fixed point math that doesn't work" is way off the mark. Floating-point math has precision and round-off issues that the casual user -- regardless of its so-called "simplicity" -- can get trapped by. If you can define units for which integer precision is adequate (in my case microdegrees), you're way better off using integer math.

    -Phil
  • Thank you for posting your code Phil. I'm having a problem printing the values in the serial terminal. I've tried PST and FDS, they both work in a different template and different baud rates, but even ahead of the main gps code a test string prints a few odd characters. (I am hitting enable ahead of the program starting, and terminal baud rate matches start call). Also i have a question about 2 of the 3 private methods below the start method, they use indefinite repeat loops like the start method. How does that work without using other cogs? Does RETURN "release"it from the repeat loop?
    PUB start 
      pst.start(19200)
      waitcnt(clkfreq+cnt)
      gps.start(GPS_RX, GPS_TX, 0, 9600)            'May need to change baud to 4800 for most GPS units.
      
       pst.str(string("test"))                   '////////////////////////////////////test print to terminal ahead of everything else
       
      repeat                                        'Repeat until receiving data from satellites.
        get_gps(string("GPRMC"), @gps_utc, 9)
      until (gps_stat == "A")
      repeat                                        'Repeat until hdop is small enough for accurate readings.
        get_gps(string("GPGSA"), @gps_utc, 16)
        hdop := get_integer(@gps_hdop, 0, 0)
      until (hdop < 140)
      repeat                                        'Get data from GPS and convert to lat/lon, time, speed, and course.
        get_gps(string("GPRMC"), @gps_utc, 9)
        date := get_integer(@gps_date, 0, 0)
        date := date // 100 * 10000 + (date / 100) // 100 * 100 + date / 10000 + 20000000  'Convert date to 20yymmdd format.
        time := get_integer(@gps_utc, 0, 6)
        latitude := get_udegrees(@gps_lat, gps_ns)  'Convert lat to microdegrees.
        longitude := get_udegrees(@gps_lon, gps_ew) 'Convert lon to microdegrees.
        speed := get_integer(@gps_spd, 0, 0)
        course := get_integer(@gps_course, 0, 0) / 10
        
        pst.dec(latitude)                     '//////////////////////////////////////////////////////print latitude to terminal
        pst.str(string(13))                   '//////////////////////////////////////////////////////
    
  • The start method is a main program. It's not something you would call from an external object and is mainly just for demonstration. The return in get_gps terminates the infinite repeat loop. Not sure why you're getting odd characters from pst. Feel free to convert the PRI methods to PUB methods if you want to call them from an external object.

    -Phil
  • The reason for the odd characters in the serial terminal was from having not declared the clock mode in the CON section. Thank you Phil, and everyone for your help!
  • Phil, I was intrigued by your microdegrees format so checked out your object, and I cannot for the life of me figure out what it's reporting.

    Sending it the coordinates 3848.7563,N,12117.7583,W results in 4414593 x -12196263.

    I took a closer look at the get_udegrees method and something looks off.
    fds.dec(get_udegrees(string("0600.0000"),"N")) results in 1_000_000
    fds.dec(get_udegrees(string("1000.0000"),"N")) also results in 1_000_000

    mikea,
    I'm a little late to the party, but I just uploaded this single cog GPS receiver / parser / converter to the obex, written in PASM with a Spin handler. In addition to ASCII strings, it also provides lat and lon in minutes (degrees x 600_000 + minutes to 4 decimal places), and in degrees/decimal minutes x 10_000.

  • Thank you ChrisGadd, I'll check it out
  • Chris,

    The string sent to get_udegrees needs to be in this format:

    ddmm.mmmmm

    i.e. five decimal places for the minutes, not four. If your GPS only returns four, then get_udegrees will need to be changed. Sorry for the mix-up. It was tailored for my GPS, but I should've made it more general-purpose.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2019-04-21 01:21
    Try this revised version of get_udegrees instead:
    PRI get_udegrees(str_addr, dir) | places, dec_pos, minutes, degrees
    
      dec_pos~
      repeat until (byte[str_addr][dec_pos] == ".")
        dec_pos++  
      places := strsize(str_addr) - dec_pos - 1
      minutes := get_integer(str_addr, dec_pos - 2, 0)
      degrees := get_integer(str_addr, 0, dec_pos - 2)
      degrees *= 1_000_000
      if (places < 5)
        repeat 5 - places
          minutes *= 10
      elseif (places > 5)
        repeat places - 5
          minutes /= 10
      degrees += (minutes + 3) / 6
      if (dir == "S" or dir == "W")
        -degrees
      return degrees
    

    It should accept strings of any length in the form ddmm.m... or dddmm.m..., where the number of decimal places in minutes is computed by the method instead of being fixed.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2019-04-21 01:32
    In case anyone wonders how long a microdegree is, at the equator one microdegree of longitude is about 4.4 inches (112 mm) and diminishes as you approach either pole. At 45 degrees latitude, it's about 3.1 inches (79 mm). One microdegree of latitude is about 4.4 inches (112 mm) everywhere.

    A GPS that returns minutes to five decimal places is precise to 1.67 microdegrees, so there's no loss of precision in converting to that integer scale from such a device.

    -Phil
  • Cluso99Cluso99 Posts: 18,069
    In case anyone wonders how long a microdegree is, at the equator one microdegree of longitude is about 4.4 inches (112 mm) and diminishes as you approach either pole. At 45 degrees latitude, it's about 3.1 inches (79 mm). One microdegree of latitude is about 4.4 inches (112 mm) everywhere.

    A GPS that returns minutes to five decimal places is precise to 1.67 microdegrees, so there's no loss of precision in converting to that integer scale from such a device.

    -Phil

    Thanks for that trivial info. Never really thought about it, other than 1 minute is 1nm at the equator for longitude and anywhere for latitude - essential facts for ocean sailing ;)
  • kwinnkwinn Posts: 8,697
    edited 2019-04-21 12:59
    Cluso99 wrote: »
    In case anyone wonders how long a microdegree is, at the equator one microdegree of longitude is about 4.4 inches (112 mm) and diminishes as you approach either pole. At 45 degrees latitude, it's about 3.1 inches (79 mm). One microdegree of latitude is about 4.4 inches (112 mm) everywhere.

    A GPS that returns minutes to five decimal places is precise to 1.67 microdegrees, so there's no loss of precision in converting to that integer scale from such a device.

    -Phil

    Thanks for that trivial info. Never really thought about it, other than 1 minute is 1nm at the equator for longitude and anywhere for latitude - essential facts for ocean sailing ;)

    One minute of latitude = 1.84 km or 1.15 miles, according to http://longitudestore.com/how-big-is-one-gps-degree.html

    1nm is in the x ray band of wavelengths (0.01nm to 10nm).
  • kwinn wrote: »
    Cluso99 wrote: »
    In case anyone wonders how long a microdegree is, at the equator one microdegree of longitude is about 4.4 inches (112 mm) and diminishes as you approach either pole. At 45 degrees latitude, it's about 3.1 inches (79 mm). One microdegree of latitude is about 4.4 inches (112 mm) everywhere.

    A GPS that returns minutes to five decimal places is precise to 1.67 microdegrees, so there's no loss of precision in converting to that integer scale from such a device.

    -Phil

    Thanks for that trivial info. Never really thought about it, other than 1 minute is 1nm at the equator for longitude and anywhere for latitude - essential facts for ocean sailing ;)

    One minute of latitude = 1.84 km or 1.15 miles, according to http://longitudestore.com/how-big-is-one-gps-degree.html

    1nm is in the x ray band of wavelengths (0.01nm to 10nm).

    I think Ray meant Nautical Mile (NM).
  • kwinnkwinn Posts: 8,697
    Publison wrote: »
    kwinn wrote: »
    Cluso99 wrote: »
    In case anyone wonders how long a microdegree is, at the equator one microdegree of longitude is about 4.4 inches (112 mm) and diminishes as you approach either pole. At 45 degrees latitude, it's about 3.1 inches (79 mm). One microdegree of latitude is about 4.4 inches (112 mm) everywhere.

    A GPS that returns minutes to five decimal places is precise to 1.67 microdegrees, so there's no loss of precision in converting to that integer scale from such a device.

    -Phil

    Thanks for that trivial info. Never really thought about it, other than 1 minute is 1nm at the equator for longitude and anywhere for latitude - essential facts for ocean sailing ;)

    One minute of latitude = 1.84 km or 1.15 miles, according to http://longitudestore.com/how-big-is-one-gps-degree.html

    1nm is in the x ray band of wavelengths (0.01nm to 10nm).

    I think Ray meant Nautical Mile (NM).

    LOL, I thought it was probably something like that, but not being much of a sailor nautical miles did not occur to me. On the plus side I now know the how and why of the nautical mile.
  • Cluso99Cluso99 Posts: 18,069
    Yep, the circumference of the earth is 360*60 nautical miles. At the equator, latitude = longitude, so 1 minute = 1NM. As you travel away from the equator, latitude stays the same distance wise, but the distance between longitude gets smaller since the circumference along the latitude line gets smaller.
  • Cluso99 wrote:
    ...but the distance between longitude gets smaller since the circumference along the latitude line gets smaller.
    ... in proportion to the cosine of the latitude.

    -Phil
  • evanhevanh Posts: 15,915
    Hey, cool. Never knew that. I guess that's something commonly learnt when at sea.

    And the history according to Wikipedia: https://en.wikipedia.org/wiki/Nautical_mile#History
    The word mile is from the Latin word for a thousand paces: mille passus. Navigation at sea was done by eye[10] until around 1500 when navigational instruments were developed and cartographers began using a coordinate system with parallels of latitude and meridians of longitude.

    Heh, a bit further down it mentions that the degrees of latitudes aren't exact NM either due to Earth not being completely spherical.
  • evanh wrote:
    Heh, a bit further down it mentions that the degrees of latitudes aren't exact NM either due to Earth not being completely spherical.
    Right, it's an oblate spheroid due to rotational forces, but more specifically a "geoid" that's also shaped by local gravitational anomalies.

    -Phil
  • Cluso99Cluso99 Posts: 18,069
    It's easy to measure distances on land, but on the big ocean there is nothing relative of course until satellites and GPS.
    IIRC Hawaii moved 0.5 miles on the map when we got GPS. Cruise ships never had a problem finding it tho, even before GPS.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2019-04-23 08:48
    Before GPS there was Loran, and before Loran there were sextants and chronometers. Determining latitude with a sextant is pretty easy. Longitude, however is much harder. A really good read is Dava Sobel's book Longitude, which chronicles the British objective during Isaac Newton's era to solve the problem of determining one's longitude at sea.

    -Phil
  • Cluso99Cluso99 Posts: 18,069
    edited 2019-04-23 08:55
    Because clocks were not accurate enough the old sailors sailed to the correct latitude, the went east or west. That way they didn’t miss their target.
    Still think navigating up/down the coast using land formations is quite scary. I couldn’t really recognise landforms reliably. Did this before i got GPS on my boat. Just used paper charts to navigate. Now the GPS and electronic charts are so nice. But there are inaccuracies in those charts still.
    Reported a bug years ago that when you zoomed in a rock outcrop disappeared from the chart. Big trap for the unwary!
  • This is a little off topic, but if you are a pilot or are looking for the nuts and bolts of doing GPS math in an approachable form, bookmark this page. :wink:

    https://edwilliams.org/avform.htm

    That site is a goldmine. It has been bailing me out of spherical trig problems for better than 20 years and is the basis of my GPS libraries.
Sign In or Register to comment.