Announcement

Collapse
No announcement yet.

NMEA extraction AppleScript need help

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • NMEA extraction AppleScript need help

    I am trying to improve my GPS to Google Earth script.
    One way is to get rid of the GPSNavX program, and get the NMEA data off the serial port in the first place.

    I am just learning apple script and I have gotten far enough to see the actual data in the return window.

    Code:
    New Code below
    But I am having problems processing that data in order to extract the $GPRMC data. I may be going about this all wrong.

    SerialPortX is needed to interface AppleScript and the Serial Port.
    http://osaxen.com/files/serialportx1.0.html

  • #2
    Question: if you build this into an application, does the user need to install the SerialPortX scripting addition, or will it be embedded in the executable?
    Originally posted by ghettocruzer
    I was gung ho on building a PC [until] just recently. However, between my new phone having internet and GPS and all...and this kit...Im starting to have trouble justfiying it haha.
    Want to:
    -Find out about the new iBug iPad install?
    -Find out about carPC's in just 5 minutes? View the Car PC 101 video

    Comment


    • #3
      I have no idea

      I did fix my problem above

      Here is the new code though:

      Code:
      New code below

      Comment


      • #4
        Ok so I now have integrate a some-what working script with my other GPS to Google Earth script.

        But my GPS seems to spit out a LOT of crap data before spiting out the GPS data.

        The script runs once or twice in a row, but then craps out returning the giberish.
        Anyone want to try it out and see if it does the same on your GPS puck?

        Code:
        --WRITTEN by ZAPWIZARD
        --Requires GPSNavX and XML RPC
        
        --Find current Serial Ports
        property thePorts : {} --Attached Serial Ports
        
        --List the Serial Ports & select one from list
        set thePorts to serialport list
        set dev to choose from list thePorts
        
        --UnComment this, and insert your serial port name to diable the prompt menu.
        --set dev to "/dev/cu.usbserial"
        
        --Set your Time Zone Offset here
        set TimeZoneOffset to -6
        
        --Set Default Course direction
        set Old_Course to 0
        
        repeat
        	--Get data no more then twice a second
        	delay 0.5
        	
        	--Open Serial Port
        	set portRef to serialport open dev bps rate 4800 data bits 8 parity 0 stop bits 1 handshake 0
        	
        	
        	--Check if available
        	if portRef is equal to -1 then
        		--Close port if program quit in error
        		serialport close portRef
        		serialport close 10
        		serialport close "/dev/cu.usbserial"
        		--Try again
        		set portRef to serialport open dev bps rate 4800 data bits 8 parity 0 stop bits 1 handshake 0
        		
        		--Display Dialog if still cannot open port.
        		if portRef is equal to -1 then
        			display dialog "Could not open port "
        		end if
        	end if
        	--Que enough GPS data to capture valid data
        	repeat until (serialport bytes available of portRef) > 370
        	end repeat
        	--Read Buffered Data	
        	set Buffer to serialport read portRef as text
        	--return Buffer --Uncomment to Debug your Buffer
        	--Split raw data into data After $GPMRC
        	set AppleScript's text item delimiters to "$GPRMC"
        	set x to text items of Buffer as list
        	set y to second text item of x as string
        	--Extract data before "$GPGGA"
        	set AppleScript's text item delimiters to "$GPGGA"
        	set z to first text item of y as string
        	--Split up data
        	set AppleScript's text item delimiters to ","
        	set GPS to text items of z as list
        	set GPS_TIME to second item of GPS
        	set GPS_Status to third item of GPS
        	set GPS_Latitude to fourth item of GPS
        	set GPS_NS to fifth item of GPS
        	set GPS_LOngitude to sixth item of GPS
        	set GPS_EW to seventh item of GPS
        	set GPS_Speed to eighth item of GPS
        	set GPS_Course to ninth item of GPS
        	set AppleScript's text item delimiters to ""
        	
        	
        	
        	--If Moving store course in Old_Course
        	if GPS_Speed > 1 then
        		set Old_Course to GPS_Course
        	end if
        	--Close Serialport
        	serialport close portRef
        	
        	
        	
        	--Is GPS fix valid?
        	if GPS_Status = "V" then
        		display dialog "Lost GPS, Click OK to try again"
        	end if
        	
        	--Convert GPS_Latitude into Decimal
        	set dd to characters 1 thru 2 of GPS_Latitude as string
        	set mm to characters 3 thru 9 of GPS_Latitude as string
        	set mmD to mm / 60
        	set GPS_Latitude to dd + mmD
        	if GPS_NS is equal to "S" then
        		set GPS_Latitude to "-" & GPS_Latitude as string
        	end if
        	
        	--Convert GPS_Longitude into Decimal
        	set ddd to characters 1 thru 3 of GPS_LOngitude as string
        	set mm to characters 4 thru 10 of GPS_LOngitude as string
        	set mmD to mm / 60
        	set GPS_LOngitude to ddd + mmD
        	if GPS_EW is equal to "W" then
        		set GPS_LOngitude to "-" & GPS_LOngitude as string
        	end if
        	
        	--Convert Knots to MPH
        	set GPS_Speed to GPS_Speed * 1.15077945
        	
        	--Convert Time to 12hr time
        	set hh to characters 1 thru 2 of GPS_TIME as string
        	set mm to characters 3 thru 4 of GPS_TIME as string
        	set ss to characters 5 thru 10 of GPS_TIME as string
        	set ss to round ss
        	
        	--Setup time formats
        	if hh > 12 then
        		set PM to "PM"
        		
        	else
        		set PM to "AM"
        	end if
        	set hhh to hh - 12 + TimeZoneOffset
        	
        	set GPS_Time12 to hhh & ":" & mm & ":" & ss & " " & PM as string
        	set GPS_Time24 to hh & ":" & mm & ":" & ss as string
        	
        	--Camera range above ground linked to speed
        	set GPS_Range to 300 + (100 * GPS_Speed)
        	
        	--Camera tilt angle linked to current speed
        	set GPS_Tilt to GPS_Speed * (50 / 100)
        	
        	--Don't change angle data unless moving
        	if GPS_Speed > 1 then
        		set GPS_Course2 to GPS_Course
        		
        	else
        		set GPS_Course2 to Old_Course
        	end if
        	
        	--Generate KML File
        	set XMLFile to {class:XML element, XML tag:"kml", XML attributes:{xmlns:"http://earth.google.com/kml/2.0"}, XML contents:{{class:XML element, XML tag:"Placemark", XML contents:{{class:XML element, XML tag:"Name"}, {class:XML element, XML tag:"LookAt", XML contents:{{class:XML element, XML tag:"longitude", XML contents:GPS_LOngitude}, {class:XML element, XML tag:"latitude", XML contents:GPS_Latitude}, {class:XML element, XML tag:"range", XML contents:GPS_Range}, {class:XML element, XML tag:"tilt", XML contents:GPS_Tilt}, {class:XML element, XML tag:"heading", XML contents:GPS_Course2}}}, {class:XML element, XML tag:"Style", XML contents:{{class:XML element, XML tag:"IconStyle", XML contents:{class:XML element, XML tag:"Icon", XML contents:{{class:XML element, XML tag:"href", XML contents:"root://icons/palette-4.png"}, {class:XML element, XML tag:"x", XML contents:"32"}, {class:XML element, XML tag:"y", XML contents:"128"}, {class:XML element, XML tag:"w", XML contents:"32"}, {class:XML element, XML tag:"h", XML contents:"32"}}}}}}, {class:XML element, XML tag:"Point", XML contents:{{class:XML element, XML tag:"coordinates", XML contents:GPS_LOngitude & "," & GPS_Latitude & "," & 0}}}}}}}
        	
        	generate XML XMLFile saving as file "Macintosh HD:Users:Shared:GPS-XML.kml"
        	
        end repeat
        --If you get error "Cannot open port" then the script crashed.
        --Try Runnning this code in a seperate script: 
        --serialport close 10
        --serialport close "/dev/cu.usbserial"

        Comment


        • #5
          I ran it and got the following:

          1. Couldn't compile the XML stuff but figured I'm missing a scripting addition for that. I commented it out.

          2. It ran, and I got the following:

          "xx0aGPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0 *05

          $GPGSV,1,1,01,25,00,000,00*4F

          $GPRMC,000820.969,V,0000.0000,N,00000.0000,E,0.000 000,,101102,,*05

          $GPVTG,,T,,M,0.000000,N,0.000000,K*4E

          $GPGGA,000821.969,0000.0000,N,00000.0000,E,0,00,50 .0,0.0,M,0.0,M,0.0,0000*7B

          $GPGLL,0000.0000,N,00000.0000,E,000821.969,V*2E

          $GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05

          $GPGSV,1,1,01,25,00,"
          Originally posted by ghettocruzer
          I was gung ho on building a PC [until] just recently. However, between my new phone having internet and GPS and all...and this kit...Im starting to have trouble justfiying it haha.
          Want to:
          -Find out about the new iBug iPad install?
          -Find out about carPC's in just 5 minutes? View the Car PC 101 video

          Comment


          • #6
            I got it to work.

            I see you also have some giberish at the beginning, I wonder if that is something the GPS units do, or something SerialPortX does.

            But, basiclly when it pulls the serial port buffer the data there is randomly located.
            So what I have it do is first split the data up by "$GPMRC
            " as a list.
            This means that the first chunk of data is always $GPMRC, which has all the info we need to work.
            I think split that bit of data by "$GPGGA" which on my GPS is sent as the next line after $GPMRC, but in your case it looks like it is $GPVTG, so you would have to change that to match.

            But the solution to the script not running more then a frew times is to let the buffer fill to 100% (1020 bytes in the case of my GPS) then read the buffer (effectivly clearing it) then reading about half of it again (512bytes)
            Worked for me, ran for 15 minutes on a test drive.

            Of course there is lots more to do.

            The new code to fix the repeating bug is:

            Code:
            --Let buffer fill up (1020 bytes in my case, set to a high number and watch your script log to see your max number)
            repeat until (serialport bytes available of portRef) >= 1020
            end repeat
            --CLear buffer
            set Junk to serialport read portRef as text
            --Que enough GPS data to capture valid data
            	repeat until (serialport bytes available of portRef) > 512
            	end repeat
            	--Read Buffered Data	
            	set Buffer to serialport read portRef as text
            --Split up data

            Comment


            • #7
              It's working for me now, although I don't get reception in the house, so I get the "GPS Lost" message. Here's the output:

              $GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05

              $GPGSV,1,1,01,19,00,000,00*40

              $GPRMC,003739.862,V,0000.0000,N,00000.0000,E,0.000 000,,101102,,*0B

              $GPVTG,,T,,M,0.000000,N,0.000000,K*4E

              $GPGGA,003740.862,0000.0000,N,00000.0000,E,0,00,50 .0,0.0,M,0.0,M,0.0,0000*7A

              $GPGLL,0000.0000,N,00000.0000,E,003740.862,V*2F

              $GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05

              $GPGSV,1,1,01,19,00,000,00*40

              $GPRMC,003740.862,V,0000.0000,N,00000.0000,E,0.000 000,,101102,,*05

              $GPVTG,,T,,M,0.000000,N,0.000000,K*4E

              If you don't mind, I'm modularizing the script just a little bit. You don't have to use it, but I just wanted to play around with it a little bit to see if I understand how it works.
              Originally posted by ghettocruzer
              I was gung ho on building a PC [until] just recently. However, between my new phone having internet and GPS and all...and this kit...Im starting to have trouble justfiying it haha.
              Want to:
              -Find out about the new iBug iPad install?
              -Find out about carPC's in just 5 minutes? View the Car PC 101 video

              Comment


              • #8
                Ya, you will get GPS lost if there is a "V" in the GPRMC line, it stands to inValid.

                There are lots of comments on what each part does, and it's all linear so it shouldn't be to hard to pick around.

                Comment


                • #9
                  I've messed around with it a little bit. It works fine on my system now, although I haven't tested it to see if I can get a lock from the GPS. It ought to work.

                  It turns out that you don't need to constantly close the serial port. I also made use of the Record function in Applescript to put all of the GPS info into a list. The main changes were to make most of the program into handlers and move them out of the main repeat loop.

                  This was fun and now I'm psyched to work with the serial port. I've got all kinds of stuff I want to do with it.

                  Here's the code:

                  (*WRITTEN by ZAPWIZARD
                  Requires GPSNavX available from here: http://osaxen.com/files/serialportx1.0.html
                  and XML RPC*)

                  global dev --the serial port device
                  global TimeZoneOffset
                  --UnComment this, and insert your serial port name to diable the prompt menu.
                  --set dev to "/dev/cu.usbserial"

                  set TimeZoneOffset to -6 --Set your Time Zone Offset here
                  set dev to FindPorts() --Find out what ports are available
                  set portRef to OpenSerial() --Open the port select by the user

                  repeat
                  --Get data no more then twice a second
                  delay 0.5


                  set GPSBufferData to FillBuffer(portRef)
                  set GPSinfo to ParseData(GPSBufferData)

                  --Close Serialport
                  --serialport close portRef --is this necessary?

                  --Is GPS fix valid?
                  (*if Status of GPSinfo = "V" then
                  display dialog "Lost GPS, Click OK to try again"
                  end if*)
                  GEGenerate(GPSinfo)
                  end repeat

                  ----------------------------------------------------------------------------
                  ---------- This handler lists all the available ports ----------------------
                  ----------------------------------------------------------------------------

                  on FindPorts()

                  --List the Serial Ports & select one from list
                  set thePorts to serialport list
                  set dev to choose from list thePorts

                  end FindPorts

                  ----------------------------------------------------------------------------
                  ------ This handler opens the serial port ----------------------------------
                  ----------------------------------------------------------------------------
                  on OpenSerial()
                  --Open Serial Port
                  set SerialPortReference to serialport open dev bps rate 4800 data bits 8 parity 0 stop bits 1 handshake 0


                  --Check if available
                  if SerialPortReference is equal to -1 then
                  --Close port if program quit in error
                  serialport close SerialPortReference
                  serialport close 10
                  serialport close "/dev/cu.usbserial"
                  --Try again
                  set SerialPortReference to serialport open dev bps rate 4800 data bits 8 parity 0 stop bits 1 handshake 0

                  --Display Dialog if still cannot open port.
                  if SerialPortReference is equal to -1 then
                  log "Failed to open serial port"
                  return false
                  end if
                  end if
                  log "Serial port opened"
                  return SerialPortReference
                  end OpenSerial

                  ----------------------------------------------------------------------------
                  -----This handler fills the buffer from the serial port ---------------
                  ----------------------------------------------------------------------------

                  on FillBuffer(myPortRef)
                  --Let buffer fill up (1020 bytes in my case, set to a high number and watch your script log to see your max number)
                  repeat until (serialport bytes available of myPortRef) ? 1020
                  end repeat
                  --CLear buffer
                  set Junk to serialport read myPortRef as text
                  --Que enough GPS data to capture valid data
                  repeat until (serialport bytes available of myPortRef) > 512
                  end repeat
                  --Read Buffered Data
                  set Buffer to serialport read myPortRef as text
                  return Buffer
                  end FillBuffer

                  ----------------------------------------------------------------------------
                  -----This handler receives a buffer with the GPSData inside it and ---------------
                  -----splits it into the right bits of information by putting it into -------------
                  -----a record, then returning that record -------------
                  ----------------------------------------------------------------------------

                  on ParseData(GPSBufferData)
                  --Split up data
                  --Look at the buffer data and find where it begins with $GPMRC
                  set AppleScript's text item delimiters to "$GPRMC"
                  set x to text items of GPSBufferData as list --This put the data that begins with $GPRMC into a list
                  set y to second text item of x as string --This sets a string variable that contains only the data itself

                  --Look at the Y data and find where it contains "$GPGGA"
                  set AppleScript's text item delimiters to "$GPGGA"
                  set z to first text item of y as string
                  --Split up data
                  set AppleScript's text item delimiters to ","
                  set GPS to text items of z as list --Here's where the good stuff like position, speed, course, etc. are stored in a list

                  set AppleScript's text item delimiters to ""
                  set GPSdata to {GPStime:second item of GPS, Status:third item of GPS, Latitude:fourth item of GPS, NS:fifth item of GPS, Longitude:sixth item of GPS, EW:seventh item of GPS, Speed:eighth item of GPS, Course:ninth item of GPS, OldCourse:0}
                  return GPSdata
                  end ParseData

                  ----------------------------------------------------------------------------
                  -----This handler receives a record with the GPS info in it. ---------------
                  -----It uses this record to generate a KML file for Google Earth -------------
                  -----tracking -------------
                  ----------------------------------------------------------------------------

                  on GEGenerate(geGPSinfo)
                  --Convert GPS_Latitude into Decimal
                  set dd to characters 1 thru 2 of Latitude of geGPSinfo as string
                  set mm to characters 3 thru 9 of Latitude of geGPSinfo as string
                  set mmD to mm / 60
                  set Latitude to dd + mmD
                  if NS of geGPSinfo is equal to "S" then
                  set Latitude of geGPSinfo to "-" & Latitude of geGPSinfo as string
                  end if

                  --Convert GPS_Longitude into Decimal
                  set ddd to characters 1 thru 3 of Longitude of geGPSinfo as string
                  set mm to characters 4 thru 10 of Longitude of geGPSinfo as string
                  set mmD to mm / 60
                  set Longitude of geGPSinfo to ddd + mmD
                  if EW of geGPSinfo is equal to "W" then
                  set Longitude of geGPSinfo to "-" & Longitude of geGPSinfo as string
                  end if

                  --Convert Knots to MPH
                  set Speed of geGPSinfo to (Speed of geGPSinfo) * 1.15077945

                  --Convert Time to 12hr time

                  set hh to characters 1 thru 2 of GPStime of geGPSinfo as string
                  set mm to characters 3 thru 4 of GPStime of geGPSinfo as string
                  set ss to characters 5 thru 10 of GPStime of geGPSinfo as string
                  set ss to round ss

                  --Setup time formats
                  if hh > 12 then
                  set PM to "PM"

                  else
                  set PM to "AM"
                  end if
                  set hhh to hh - 12 + TimeZoneOffset

                  set GPS_Time12 to hhh & ":" & mm & ":" & ss & " " & PM as string
                  set GPS_Time24 to hh & ":" & mm & ":" & ss as string

                  --Camera range above ground linked to speed
                  set GPS_Range to 300 + (100 * (Speed of geGPSinfo))

                  --Camera tilt angle linked to current speed
                  set GPS_Tilt to (Speed of geGPSinfo) * (50 / 100)

                  --Don't change angle data unless moving
                  if Speed of geGPSinfo > 1 then
                  set GPS_Course2 to Course of geGPSinfo

                  else
                  set GPS_Course2 to OldCourse of geGPSinfo
                  end if

                  --Generate KML File
                  set XMLFile to {class:XML element, XML tag:"kml", XML attributes:{xmlns:"http://earth.google.com/kml/2.0"}, XML contents:{{class:XML element, XML tag:"Placemark", XML contents:{{class:XML element, XML tag:"Name"}, {class:XML element, XML tag:"LookAt", XML contents:{{class:XML element, XML tag:"longitude", XML contents:GPS_LOngitude}, {class:XML element, XML tag:"latitude", XML contents:GPS_Latitude}, {class:XML element, XML tag:"range", XML contents:GPS_Range}, {class:XML element, XML tag:"tilt", XML contents:GPS_Tilt}, {class:XML element, XML tag:"heading", XML contents:GPS_Course2}}}, {class:XML element, XML tag:"Style", XML contents:{{class:XML element, XML tag:"IconStyle", XML contents:{class:XML element, XML tag:"Icon", XML contents:{{class:XML element, XML tag:"href", XML contents:"root://icons/palette-4.png"}, {class:XML element, XML tag:"x", XML contents:"32"}, {class:XML element, XML tag:"y", XML contents:"128"}, {class:XML element, XML tag:"w", XML contents:"32"}, {class:XML element, XML tag:"h", XML contents:"32"}}}}}}, {class:XML element, XML tag:"Point", XML contents:{{class:XML element, XML tag:"coordinates", XML contents:GPS_LOngitude & "," & GPS_Latitude & "," & 0}}}}}}}

                  --generate XML XMLFile saving as file "Macintosh HD:Users:Shared:GPS-XML.kml"
                  end GEGenerate

                  --If you get error "Cannot open port" then the script crashed.
                  --Try Runnning this code in a seperate script:
                  --serialport close 10
                  --serialport close "/dev/cu.usbserial"
                  Originally posted by ghettocruzer
                  I was gung ho on building a PC [until] just recently. However, between my new phone having internet and GPS and all...and this kit...Im starting to have trouble justfiying it haha.
                  Want to:
                  -Find out about the new iBug iPad install?
                  -Find out about carPC's in just 5 minutes? View the Car PC 101 video

                  Comment


                  • #10
                    Thanks for the edits.
                    I have fixed some bugs in yours (typos mostly)
                    I added a MPH readout as a seperate placemark.
                    I also split out the XML code, finally found the dang carriage return button.


                    The code is located here (too long to post)
                    http://www.zapwizard.com/GPS.scpt

                    Comment


                    • #11
                      wow im pretty darn lost in all this.... i have been looking over other theads about using google earth as a gps tracker on a mac but i cant get it to work. I think mostly because i cant get my handheld gps to sync with my mac at all... I have this usb adapter from an old palm handheld that i have and i am currently using it to interface my garmin etrex legend to my mac. The only trouble is my mac cant see it at all. you guys know of any software that might will recognize it? Otherwise I guess i will just have to caugh up ~$200 for a gps receiver ...

                      Not sure exactly what i need to get this to work though (your applescript software) i keep getting this error:
                      Attached Files
                      MacCar progress:
                      Planning:-----> [||||||||||||||||||||] 70%
                      Parts:---------> [||||||||||||||||||||] 0%
                      Construction:-> [||||||||||||||||||||] 0%

                      Car broken into... progress is basically zip...

                      Comment


                      • #12
                        Did you install the driver software for the USB interface? If it doesn't have a driver, then the interface isn't working. Also, what's the event SPA_ISPA reference in your code? It looks like AS isn't getting to the point of talking to the serial driver.

                        Comment


                        • #13
                          the drivers are os 9 only...
                          MacCar progress:
                          Planning:-----> [||||||||||||||||||||] 70%
                          Parts:---------> [||||||||||||||||||||] 0%
                          Construction:-> [||||||||||||||||||||] 0%

                          Car broken into... progress is basically zip...

                          Comment


                          • #14
                            Note the first line in the script:
                            (*WRITTEN by ZAPWIZARD
                            Requires GPSNavX available from here: http://osaxen.com/files/serialportx1.0.html
                            and XML RPC*)

                            You need to install the serialportx1.0.html and also the XML RPC scripting additions before this script will work. They are easy and free, but required.

                            If you did that, then you are getting a driver error. But it looks like in trying to execute the command to get a list of the serial ports -which depends on the serialportX scripting addition to do this on Applescript's behalf, it is getting an error. That points to the scripting addition not being installed.

                            One way to test your GPS is to download GPS Utility. You can set your serial port and watch the data come in from the GPS. If that's working, then you know your GPS is working.

                            Also, GPS receivers aren't $200. You can get one of the BU-303's for under $100, I'm sure.
                            Originally posted by ghettocruzer
                            I was gung ho on building a PC [until] just recently. However, between my new phone having internet and GPS and all...and this kit...Im starting to have trouble justfiying it haha.
                            Want to:
                            -Find out about the new iBug iPad install?
                            -Find out about carPC's in just 5 minutes? View the Car PC 101 video

                            Comment


                            • #15
                              got a link to gps utility? when i googled it all i got was something for windows...
                              MacCar progress:
                              Planning:-----> [||||||||||||||||||||] 70%
                              Parts:---------> [||||||||||||||||||||] 0%
                              Construction:-> [||||||||||||||||||||] 0%

                              Car broken into... progress is basically zip...

                              Comment

                              Working...
                              X