Demonstration of Communication between a GPS receiver and Macromedia's Director - GPS Based Art Events

Stephen Wilson, Professor, Conceptual Information Arts Program, SFSU

This document explains the basics necessary to set up communication between a GPS receiver and a Macintosh computer.  It uses GPSy software to read the current GPS location and Macromedia's Director to orchestrate  location based events.  It uses appleScript and the ZScript Xtra to communicate between GPSy and Director.   This document assumes the reader has a basic familiarity with the GPS satellite location system and Director's Lingo authoring language.  Check the links page for addresses to tutorials.
1. GPS Receiver:  Obtain a GPS Receiver that has data communication capabilities and an appropriate data cable.  In our work we have used the Garmin 12XL.  The GPS device constantly accesses multiple satellites to triangulate on its longitude, latitude, and altitude.  Latitude and longitude can be reported in a variety of formats include degrees/minutes/seconds and decimal degrees.  The Gypsy software is able to convert among formats.  This example will assume that the communication is set up in decimal degreees because it requires fewer conversions in Director. The Garmin receiver is also capable of indicating tracking (that is the compass direction of movement), speed,  and very precise UTC (Greenwich International) time.  Most GPS receivers have many other capabilities such as Waypoints (stored point locations), headings to designated points (compass directions from where you are to a target) and a variety of live maps.  Check the manual for the device you are using to understand what these are and how they can be set up.  This example does not discuss these supplementary capabilities.

2. Limiations of GPS:  GPS location technology has some critical limitations.  GPS devices need a relatively clear view of the sky to work.  Thus they don't work inside and work inconsistantly under heavy tree cover and in urban "canyons" (surrounded by tall buildings).  Also, the accuracy is limited.  The US military which runs the system introduced "selective availabilty" to dumb down the accuracy via random errors.  They didn't want enemies to have such precise positioning accuracy.  The technology itself is theoretically capable of locating objects to within 1 meter/3 feet or less.  Civilian users without the magic codes, however, cannot count on being accurate to less than 80 feet.  You can see this in action by standing still and watching your receiver's indications of location - they may vary within 50 meters/ 160 feet.  Precision civilian uses require supplemental information to correct for the error.  For example, the Coast Guard in the US broadcasts correction information via marine beacons.  With a supplementary beacon receiver linked to your GPS receiver, you could get accuracy to within  5 meters/15 feet.  This is called Differential GPS. There is also Internet based differential GPS you can use if you have a live connection.

3.  Start the GPSy software: GPSy  is Macintosh software that allows you to use your computer to enhance the raw GPS data.  For example, it allows you to coordinate the GPS data with maps, translate the data into multiple formats, manipulate waypoint arrays, and configure the GPS receiver.  The capability we focus on here is its ability to take in the GPS data and prepare it for use of the Macintosh.  You must configure the software to communicate with the GPS receiver.  Assuming you are using a Garmin receiver, you would need to set the preferences in the serial communication in the preferences menu.  You would also need to configure the receiver to match the settings in the software.  We have found the following settings to work:

Real Time Display:  NMEA- 0183 (Default) This is a standard for GPS communications
Protocol BPS Rate:  4800 (NMEA -  0183)  This is 4800 bits per second - a standard
Data Transfer Protocol: Garmin Data Protocol
4 Use AppleScript to Communicate:  GPSy is set up to accept an AppleEvent to report its current location data. AppleEvents are the Mac OS system's method for communication between applications.  Obviously, this example cannot teach you Applescirpt; if you need more details, consult a relevant text or online tutorial.  The AppleScript needs to format the returning values in a way that Director can use.  Here is an example of the AppleScript we use:
tell application "GPSy 3.35 (Fat)"
     copy latitude to lat
     copy longitude to lon
     copy speed to spd
     copy track to trk
     copy utctime to utc
     set y to "lat= " & lat & " long= " & lon &" tr= "&trk
end tell
The tell command aims the event at GPSy.  The name in quotes must match exactly the file name of the application and it best be in the same folder as your Director movie.  (It could be somewhere else but you would have to give the exact path including folders identifying the application location.)  GPSy is set up to return the values for latitutde, longitude, speed, tracking, and utctime.  The sample script copies the values to variables that we have arbitraily named lat,lon,spd,trk, andutc.  The next line prepares a string of text that combines the values with text that identifies it - for example lat=(whatever the value is).  In Applescript the & symbol just ties strings of text and values together.  Note the spaces inside the quotes that also help to set up the format.  Gypsy would return a line to whatever program sent the appleScript that looked something like this:
lat= 35.4333333 lon= 122.45555 tr=208
The Director Movie would then need to extract the values it needed and do something with them.  In our example we don't send back the values for speed or utc.  If your Director movie needed them, you could certainly arrange to send them back.

5.  Prepare Director to send and receive an appleEvent:  Macromedia's Director does not have built in capabilities to send appleEvents and understand AppleScript. It requires an extra piece of software to allow it to do so.  In Director these supplementary pieces of software are called X-tras, Xobjects, or XCMDs (X-commands).  These are called an "Xlibrary" in Director.   The special software must be placed in the X-tras folder near the Director application or in the same folder as the Director movies you create.  You must obtain an Xtra that has the capability.  ZScript is an excellent example written by  &&&&&&&&.  You can get it at web address &&&&.  Once you have it, you must install it in the relevant folders.  A full licence requires a charge but the author has made a version available for non-commercial experimentaion.

6.  Open Xtra and instantiate it as an object:  In your Director movie you must open the Xlibrary before you use it.  Typically this script is placed in the StartMovie handler.  The  example below shows the script.  Note the name in the script must exactly match the name of the XCMD file name.  When the movie is over, it is customary to close the X-library in the StopMovie handler.  Typing "showXlib" in the message window will list all the Xtras Director knows about.  ZScript should show up if it has been successfully loaded. Also the Xlibrary needs to be in the right folder or the openXlib command won't work. Since zScript is an contempoary Xtra, Director should load it automatically if it is located in the right place.  ZScript adds new commands and functions to Director.  The example below is based on the demo offered by ZScript.   Their full version includes checks to see if the Xtra is loading correctly and if the operating system has the appropriate AppleScript extension.
 on startmovie 
  --test to see if a zscript object already exists --1 
global gzscriptID 
    if objectP (gzscriptID) = true then 
        set gzscriptID = 0 
    end if 
  -- Check that AppleScript is installed --2 
  if zScriptingActive() <> "true" then 
    alert "no AppleScript" 
  end if 
(-- If you use of the Scriptable Finder you could use 
--the  zFinderScriptable() function to test - see the zscript demo) 
  --check if zScript xtra is installed and 
  -- instantiate the Xtras  --3 
     if XtraInstalled ("zScript") = "true" then 
       set gzscriptID = new (xtra "zScript") 
       if not objectP (gzscriptID) then 
           alert "Problem setting up the xtra"   --4 
       end if 

    alert "zScript is not installed." 
  end if 
end startmovie 

--clean up instance   --5 
on stopMovie 
  global gzscriptID  
  set gzscriptID = 0 
end stopMovie

In Director Xtras require a process called "instantiation".  You do this by using the new function.  You also need to check if a previous instance exists, ifthe appropriate support extensions are in the Mac OS and if the process has succeeded.  
All of this should happen in a startMovie handler to insure it is done before your scripts try to access the new commands and functions made available by the Xtra. 

--1 This sets up a global variable arbitraily called gzScriptID that will hold the identification number for the instance of the Xtra object once it is established.  The if statement checks if an object with the same ID exists - objectP(gzscriptID) will return true if it exists already.  If it does, setting it to 0 will clean it out. 

--2 This checks if the operating system has the appleScript extension active by using the function called zScriptingActive() .  If it isn't, it issues an alert and exits. 

--3 This function checks if the Xtra has been installed.  If it is installed,  it tries to instantiate a new zcript object .  If it is not installed it alerts the user and halts the script. (the part after the else) 
Assuming the Xtra is installed, the line set gzscriptID = new (xtra "zScript") uses the new function to create a new xtra object.  It puts the resulting identification number into the global variable called  gzscriptID. All subsequenct uses of the new commands and functions will need to use that ID.  

--4 The next if notobjectP line checks to see if the object has been successfully set up. 

--5 When the movie stops, the instance should be undone.  This is accomplished by set the variable gzscriptID = 0. 

7 Check the location from Director:  Next you must write routines in your Director movie to send a request to GPSy to get the current location and to process the information when it comes back.  You can send the appleScript request to GPSy by using the ZScript Xtra.  I wrote the following issueEvent handler to illustrate how you can send the appleScript (the name issueEvent is arbitrary).  This routine assumes the text of the appleScript is in a cast member called "event".  The AppleScript is presented in item 4 above.
on issueEvent 
  global gzscriptID ,textStr, lat 
  -- assumes the script is in member event -- 1 
  set textStr = the text of member "event" 
  setScriptText (gzscriptID , textStr)  --2 
  run(gzscriptID )  
  put getStatus(gzscriptID ) into status --3 
  put getResult(gzscriptID ) into lat  --4 
  put lat into member "cur.lat2" 
end issueEvent
This routine uses the new ZScript Xtra commands and functions. They all must refer to the object ID number which the startMovie placed in a global variable called gzscriptID.  
--1 The routine sets a variable called textStr = the text of member "event".  Remember that member contains the appleScript described in item 4 above.  (You could enter the appleScript in other ways such as putting the text right into the handler.  Putting it in a cast member makes it clearer and easier to edit.)  

-- 2 The setScriptText(gzscriptID , textStr) Xtra command places the variable textStr appleScript into the Xtra to be sent out.  The run(gzscriptID) actually runs the appleScript.  In this demo it sends an appleEvent to GPSy requesting location information. 

-- 3 The put getStatus(gzscriptID ) command checks if the appleEvent ran correctly.  It would return an error message if there were a problem.  This demo doesn't do anything with the info. 

--4 If the appleScript runs correctly it will put its last action into the result.  The line put getResult(gzscriptID) puts the result into a variable we have arbitrarily named lat.  In our demo (see item 4) it returns a text line such as "lat= 37.73443 long= -122.49040 tr= 90.7".  It also puts it into a text field called "curlat2" so we can see what is happening.

8.  Extracting the location information:  Director now has current location and direction information every time the issueEvent handler is run.  Your movie must extract the location information.  The IssueEvent handler puts the string into a varible arbitraily called lat.  The appleScript carefully set up the text line so the elements could be extracted.  We wrote a routine called defpos to put the information into global variables.In Director every element in a text string separated by a space is called a word.  Thus the line "lat= 37.73443 long= -122.49040 tr= 90.7" contains 6 words.  For example, word 1 is lat= and word 2 is 37.73443.
on defpos 
  global qns,qew,tr,lat  
  set q = the text of member "cur.lat2" 
  put word 2 of q into qns 
  put word 4 of q into qew 
  put word 6 of q into tr 
end defpos
The routine sets up 3 global variables - qns(to store latitutde-north/south); qew (to store longitude - east/west); and tr to store tracking directions information (indicated by compass degree bearings - eg 0 for north, 180 for south). Member "cur.lat2" and the variable lat contain the text string returned as a result of the issueEvent handler. 

This routine takes word 2 (the value of latititude) and puts it into variable qns. It puts word 4 into qew and word 6 into tr.

9. Set up a database:  Here is the creative part.  Your script might orchestrate an event (for example, a sound or visual sequence) based on the location.  The example below is just one of an infinity of possibilities.  In this example there is a database stored in a text cast member of location names and their latitude and longitude.  It is precisely set up with each line in this pattern - item 1 = name; item 2 = latitude; item 3 = longitude; item 4 = sound to play (remember, Director defines everything on a line separated by commas as items).  To set up the database you would visit the places with the gps receiver to record location information.  Be aware of the need to take several readings in order to average over the selective availability random errors.  The locations items you record in your data base should be the best approximation of "true location".  Here is an example of a database with some locations in San Francisco.

top of twenty ninth,37.74343, -122.43622, 29.aiff
safeway,37.74414, -122.43804, safeway.aiff
Portola,37.74704, -122.44467, portola.aiff
Gas station,37.74517, -122.45172, gas.aiff
West portal, 37.73942,-122.46582, wportal.aiff
Junipero Sera, 37.73532, -122.47106, junipero.aiff
Lucky Store, 37.73380, -122.49062, lucky.aiff
Zoo, 37.72543, -122.50264, zoo.aiff
Pacific Ocean, 37.72523, -122.450609, ocean.aiff
10 Doing something with location information:  This example assumes someone is moving around the city with a GPS receiver hooked to a portable Macintosh.  This example constantly checked current location using the issueEvent.  It then checked the database to see if the current locations was near one of the designated locations.  If it was near, it then would orchestrate an event.  In my example, it would play a sound specially composed for that particular location.  Because of GPS inaccuracies you cannot check for exact locations since selective availability made any given reading have a potential error.  The routine introduces a variable called fudge that defines a range of locations that would constitute a "hit".  You would need to fine tune the size of the fudge variable that would work to activate correctly without missing locations but at the same time not falsely activating.
on checkifnearboth 
  set the floatprecision to 5  --1 

  global qns,qew,tr  --2 
  global fudge, soundflag 

  set fudge = .00150 --3 
  set qnsn = qns - fudge 
  set qnsp = qns + fudge 
  set qewn = qew - fudge 
  set qewp = qew + fudge 

  set soundflag = 0 -- 4 

  set q = the text of member "places" --5 
  set qn = the number of lines in q 
  repeat with n = 1 to qn 
    put item 2 of line n of q into temp  
    put item 3 of line n of q into temp1 

    -- check if within range latitude  and longitude --6 
    if temp > qnsn  and temp < qnsp  and temp1 > qewn and temp1 < qewp then 

     set soundflag = 1   --7 
     put item 4 of line n of q into tempsound 
     if soundbusy(3) = false then 
         soundplay file tempsound,3 
     end if 
   end if 
  end repeat  

   if soundflag = 0 then  --8 
     sound stop 3 
   end if 

end checkifnearboth

--1 Director needs an indication of the number of decimal points it should read and store. 

--2 The routine uses the same global variables used by defpos routine (described in items 7 and 8 above). 

--3 The routine sets the fudge variable at .00150 degrees.  You would need to fine tune the amount for your event.  It also sets up upper and lower limits for the current latitutde and longitude readings.  For example qnsn (negative) is current latitutde qns - fudge and qnsp (positive) it current lattitude + fudge.  The routine will check if the latititude in the database falls between qnsn and qnsp. 

--4   The routine uses a  a variable called soundflag  to control whether the special location based sounds should play or stop. The variable is set to 0 before each test comparing current locations with the database locations.   It will be set to 1 only if the current locations is still withing the area of one of the disignated locations. 

--5  This routine reads in the cast member with the database into a temporary variable q and the number of lines to check into qn.  It then sets up a repeat loop to go through each line checking if the latitude or longitude of the designated place is within the fudge distance of the current live readings.  It puts latitutde (item 2) into a variable called temp and the longitude (item 3) into a variable called temp1. 
--6 This is the heart of the routine.  The comparisons  if temp > qnsn  and temp < qnsp check if the designated latitude from the database (temp)  is greater than the lower limit (qnsn)  calculated from the current latitude reading and less than the upper limit (qnsp).   The test  also checks the longitude temp1 > qewn and temp1 < qewp in the same way.  The "and" forces the test to make sure both condiitions are true simultaneously. 

--7 If the current location passes the test then the routine sets soundflag variable to 1 and plays the special location based sound in arbitraily selected sound channel 3.  It determines the sound to play by extracting item 4 of the line of the database which is set up to contain the name of the sound to play for that locations.   The if soundbusy() structure checks if the sound is done and replays it if necessary. 

--8 This if statemennt stops the souund playing if you are no longer within a hit range for a designated locations.  Before each repeat loop test to check designated locations,  the soundflag variable is reset to 0.  It gets reset to 1 only if a hit is detected.  If the routine reaches this point  with it still = 0, then the current active location is not near one of the designated places and any sound should be stopped.


More information about the course exploring the artisitic use of these capabilities is available at the description of the Trio of Experimental Technologies Course Description.
Stephen Wilson, Professor, Art, Conceptual/Information Arts Program, San Francisco State University 
Information about the Conceptual/Information Arts program    (415) 338-2291  Wilson web page 
Copyright, Stephen Wilson, 1999 - You are free to use the text as long as you attribute source and do not use them commercially.