Introduction: GPS Bus-tracking on the Cheap


Get a spatio-temporal lock on your local flavor of public transportation.  Answer the age-old question, "Where's that bus?" and put it on the internet for the Public Good.  Keep yourself out of the weather by predicting bus arrival times.

Costs:
   $100-200 per vehicle per year
+ $120 per year for serverspace to track the fleet.

Other requirements: 
Instamapper account (free),
Python data-grabber/calculator code (provided free-of-charge below),
Permission.

Check the demo system here: http://weakorbit.com (the prototypes may be turned off and the positions could be old..)

Step 1: Why? ..and an Overview


Why might you want such a system?  I wanted it because my school's bus schedule was all out of whack during exams.  Myself and others were waiting 15-30 minutes for a lift in the un-sheltered cold because we didn't know when to expect a bus. 

For the 'common' routes at my school, buses are quite dependable during the year.  The peculiar and longer routes can mess up timing though.  It comes down to giving bus-riders more control over their time; making public trans more pleasurable and less of a hassle will encourage ridership [admittedly sizeable citation needed here].

Is it really that cheap?  In the worst case scenario this will cost $350 for one bus for the first year.  Additional buses would cost $200 for the first year.  Each bus at my university serves, say, 1200 people/week.  Eight months of school gives 38,400 riders/bus/year.  So the first bus costs one penny per rider, a good ballpark figure for the 'is it worth it' question.  I'll try to include some more detailed economiks (hah, by that I mean division) in a later step.


Here's the way it works:
1) Buy a GPS-enabled prepaid phone
2) Download Instamapper (IM) software to the phone and get an IM account
3) Create custom route file for your bus of choice
4) Run server-side Python script to scrape data from IM, interpret it based on your route file, and put it on your website

Step 2: Get a GPS-enabled Phone


InstaMapper has a really great tutorial covering this step and the next.
  Their forums also have useful info that solved a few of my problems.  I'll outline the basics:

To my knowledge, the cheapest phone that works is the Boost Mobile i290, it's $50 at Target.  You could get an iPhone or Droid or Blackberry but it'll cost you over a grand a year with the coverage plan and you're just going to be leaving it on a bus anyway.  Other Boost flavors work too, check the IM page.

Charge up your phone, pop in your SIM card, and go online to sign up for a plan (this is covered pretty well in the phone's documentation).  Your phone will essentially be accessing the internet all the time so you need an unlimited data plan.  I chose 'Pay-as-you-go' and then selected the 35cents/day 'Wireless Web' option ($130/year).  Your phone will probably come with $5 or so in credit so you'll have a few weeks to try things out before signing up fo real.

Interesting tidbit: you can make this whole thing work without ever enrolling in a data plan due to a loophole in how the Boost phones use their GPS services.  If you do this, you'll just have to keep your phone 'active' by periodically adding airtime (minutes).  You have to do this every three months and the minimum addition is $10, so that's a pseudo-plan of $40/year, good deal.  I tried this out on one phone and didn't notice any difference between this and the one on the legitimate-plan.  Do know that this trick is exploiting a loophole; I don't think it'll close but it might..

And now we have a phone that knows where it is.

Step 3: Download Free InstaMapper Software to Your Phone


Again, the InstaMapper tutorial covers this step and the previous one quite thoroughly; I highly recommend reading their DIY section.
  More of the basics:

Your phone needs to send its position to the internet so you can get a hold of it.  InstaMapper is one way to do this; please read the tutorial linked above.  You'll install the IM 'GPS Tracker' software as a Java app on your phone.  This will send coordinates and other information to your InstaMapper account.  (PS, it's fun to play with IM in many applications outside of transportation-tracking.)

Though InstaMapper is free-of-charge, the development team does not have plans to release the source files of their Java app.  Alternatives to IM that I have not personally tested include Mologogo, OpenGTS, and GPSMapper.  Know some more?  Post a comment or send me a message.

IM limits its update frequency based on whether anyone is viewing the tracking information on your IM account's webpage and also according to your rate of travel.  This is explained in the IM FAQ.  I initially thought these limits would be debilitating but they have not proven to be an issue through initial testing.

Now you have a personal GPS tracking system based on your little phone there.  You can log on to InstaMapper and see a screen like the one below.

Step 4: Define a Route for Your Bus of Choice


At this point, the system has a good degree of functionality; we could still add some more features like predicting arrival times and simplifying the output information. 

To do this, we'll define a route so that users can know what landmarks are closest to a bus's current position.  We'll also calculate arrival times based on that position.

We want a a five-column comma separated value (CSV) file where each row is a waypoint along the route (see the screenshot below and the attached file for an example -- it should open in Excel or something like Notepad++).  Waypoints are entirely of your choosing (hello, Easter Eggs) and you can add any number of them to the file.  The bus I'm describing takes a linear A to B route one way and then travels B to A on the exact same roads.  The entries for each of my waypoints are as follows: 

title,
latitude,
longitude,
time in minutes to get to A from the waypoint,
time in minutes to get to B from the waypoint. 

Latitude and longitude can be determined with the industrious Simon Willison's www.getlatlon.com.

My time values are only placeholders at the moment; these values could be determined by timing a few rides manually or using a yet-to-be-written logging script for autonomous assistance.

This setup may be expanded in the future to consider buses that travel more complex routes (those routes not of the same-path A-to-B, B-to-A variety).

Step 5: Interpret and Display Your Data


Your InstaMapper data can be viewed in the 'IM API' by visiting a site with your device's key; read more about how to access this page here (requires free registration).  A screenshot of the site is below.  This is the site we will poll to get the current location of a bus.

The Python script is attached below as bus_tracker_v8.txt; you can download it and change the extension to .py.  The code does a little bit of math and a good deal of clumsy data-parsing.  To run the script for the first time, you need the route CSV file you created earlier and a bus data text file like the one below.  The bus data file is accessed every time the script runs and writes the time and position info about your buses.  You also need Python.. I used 2.6.4.

IM requests that you limit your API access to once every ten seconds so the script checks this first.  If the data file is less than ten seconds old, the existing data file is used as the output.  If the data's older than ten seconds, the script seeks new data from the API page using any API keys you provide. 

The script then imports your route file of waypoints and calculates the distance between the current bus location (its latitude and longitude) and each waypoint.  The index of the smallest distance is stored, establishing a position for each bus.  Finally the data for each bus is written to the screen and logged in a separate text file. 

This Python script is used as a CGI, a protocol which allows Python to create a webpage after performing the functions described above.  The user goes to a page which links to the script, the script runs on the server, and the output is formatted into HTML so the browser can view it.  CGI is commonly used with Perl and parsing data from HTML forms.  A very readable tutorial on CGI scripting with Python is available at Penzilla.net

The host of your site will have specific guidelines about where CGI scripts can live and how they must be formatted.  Here are two of the CGI-troubleshooting FAQs from my host that generally apply no matter what language you're scripting in: CGI troubleshooting, Python CGI.

All of this outputs to something like the final image on this step.  The final presentation can be more cleverly arranged in a template or beautified with CSS.  You can also have Python print a meta tag so the page is automatically refreshed (and the script is called again).

Step 6: Future Steps


And there you have it, a bus-tracker with arrival prediction for under $300/bus/year.  Since you made it this far, here's the link to my trackers (they're not currently attached to any buses but if you get lucky you might see it being tested..you'd have to be absurdly lucky, actually).

Some more things to think about, somewhat in order:

development of physical displays at bus stops
integration of phones into electrical system of vehicle
better exception handling in script
prettier output; smartphone compatible pages
evaluation of opengts (as compared to IM)
increased CGI script security
autonomous route detection
autonomous route timing and adjustments
migration of data storage to sqlite

Thanks to savage22 for this last photo.  And to my housemates, thanks for carrying my phones around..

Have some more ideas about what this could do?  Leave a comment or send me an email -- matt (dot) ball (dot) 2 at gmail.  Happy tracking.