ECE497 Project GPS Tracker

Team members: Robert Fendricks, Chris Hopwood

Grading Template
I'm using the following template to grade. Each slot is 10 points. 0 = Missing, 5=OK, 10=Wow!

 00 Executive Summary - Out of date 00 Installation Instructions - Many important steps missing 00 User Instructions - Can't test 08 Highlights - Nice video, but a bit fuzzy. 10 Theory of Operation - Good 08 Work Breakdown - Not finished 09 Future Work - Good 10 Conclusions - Good 10 Demo - It works, but I can't reproduce it. 00 Late Comments: I'm looking forward to seeing this.

Score: 55/100

Executive Summary
This project was done to interface the Adafruit Ultimate GPS to the Beaglebone Black in order to create a system that can track the whereabouts of the Beaglebone. There were two main goals for this project: to create a system that can track and store where the Beaglebone has been and to create an easy-to-use GUI that utilizes Google Maps to display this information on a map. We were ultimately successful in meeting these goals by creating an interface that can track the Bone's whereabouts in both real time and by passing it a time range to display.

Packaging
The GPS, battery, and wifi dongle are the only components needed outside of the beaglebone. We did not build a cape, but if we did,it would be a small cape for the GPS and a charging circuit for a lithium battery to power the system. The board and cape would go into a project box, with an antenna protruding for the GPS.

Installation Instructions
These instructions were testing against a fresh SD card installation of the 2013.09.05 image found here: http://downloads.angstrom-distribution.org/demo/beaglebone/

First, clone our github located here: Github Link If git says "HTTP request failed," create a file called .gitconfig in your home directory with these contents:

 [http] sslCAinfo = /etc/ssl/certs/ca-certificates.crt 

You may have to find where the ssl certificates are stored, and change the sslCAinfo line appropriately. This did work for the 2013.09.05 image.

GPS
The GPS we are using is MTK3339. Breakout board: http://learn.adafruit.com/downloads/pdf/adafruit-ultimate-gps.pdf

To load the device tree overlay on the beaglebone, cd to the ./bin directory and run:  root@beaglebone# ./load_uart_overlay.sh  Wire up the GPS's TX pin to the bone's P9_11 pin, the GPS's VCC to the bone's P9_3, and the GPS's GND to the bone's P9_1.

To confirm which tty the UART is exposed as, run: root@beaglebone# dmesg | tail On our beagle it outputted:  [  50.991396] bone-capemgr bone_capemgr.8: slot #8: 'Override Board Name,00A0,Override Manuf,BB-UART4' [  50.991495] bone-capemgr bone_capemgr.8: slot #8: Requesting part number/version based 'BB-UART4-00A0.dtbo [  50.991514] bone-capemgr bone_capemgr.8: slot #8: Requesting firmware 'BB-UART4-00A0.dtbo' for board-name 'Override Board Name', version '00A0' [  50.991542] bone-capemgr bone_capemgr.8: slot #8: dtbo 'BB-UART4-00A0.dtbo' loaded; converting to live tree [  50.991860] bone-capemgr bone_capemgr.8: slot #8: #2 overlays [  50.995484] 481a8000.serial: ttyO4 at MMIO 0x481a8000 (irq = 61) is a OMAP UART4 [  50.996082] bone-capemgr bone_capemgr.8: slot #8: Applied #2 overlays. [  51.171271] [drm:output_poll_execute], [CONNECTOR:5:HDMI-A-1] status updated from 2 to 2 [  61.202485] [drm:output_poll_execute], [CONNECTOR:5:HDMI-A-1] status updated from 2 to 2 [  71.233751] [drm:output_poll_execute], [CONNECTOR:5:HDMI-A-1] status updated from 2 to 2



According to [  50.995484] 481a8000.serial: ttyO4 at MMIO 0x481a8000 (irq = 61) is a OMAP UART4 our port is mapped to ttyO4.

To test if the GPS is connected correctly, run:  root@beaglebone# screen /dev/ttyO4 9600  replacing ttyO4 with whatever device dmesg reported earlier.

You should see NMEA sentences that look similar to the ones in the links at the bottom of the page.

To disconnect from the screen session correctly, press + then type ":quit" then press enter. (If you are running a screen to connect to the bone, read the man pages about passing the escape codes down)

Installing pyserial
First, install pip, python's package manager:  root@beaglebone# opkg install python-pip python_setuptools  Now install pyserial  root@beaglebone# pip install pyserial 

pyserial should now be installed! Load it in python by doing:  import serial 

Installing socketIO_client
First, for whatever reason, the 2013.09.05 python interpreter is missing netrc.py. We've included the file in the root of the repository, you should put it in python's lib folder (not site-packages). Typically it is in /usr/lib/python or /lib/python, but it varies. Google for more info.

After you have copied the netrc.py file over, you should be able to download socketIO_client:  root@beaglebone# pip install socketIO_client </b>

installing dateutil
Our program uses dateutil for processing dates. To install it:  root@beaglebone# opkg install python-dateutil </b>

Creating the Database
First, install sqlite3 on your beaglebone:  root@beaglebone# opkg install sqlite3 </b>

cd to the project's ./bin directory and run ./make_db. This creates a sqlite3 database in the project's ./var directory.

Starting the Tracker
To start up the tracker, first run ./webpage/MapServer.js, then run ./bin/gps_tracker.py. It should now be serving a webpage on port 8080!

Ad Hoc Networking
For this project, we felt that being able to connect to the Beaglebone directly to access the web interface would be beneficial. To do this, Robert looked into setting up an ad-hoc wireless network.

To do this, first make sure that you have a wireless interface installed an configured on the Bone. We used Adafruit's RTL8192CU wireless adapter on our bone.

Once your wireless adapter has been configured, you are now ready to set up the Ad Hoc network. The following commands must be run on both the Beaglebone and the computer you want to connect to the Beaglebone. Note that this will utilize the wireless adapter on your computer, so you won't be able to use it for connecting to the internet. These commands are:  bash# ip link set down #This will bring your wireless interface down bash# iw set type ibss #This sets your interface to act as an Ad Hoc Network bash# ip link set up #Bring your interface back up bash# iw ibss join <SSID> #This sets up an SSID for your ad hoc network. </b>

Once these commands have been run on both machines, you now want to assign an IP address to both. The most straight forward way is to use a static IP for both, making sure they are on the same subnetwork. Running the following command on each will accomplish this:  bash# ip addr add <IP address>/ dev </b>
 * 1) e.g.: ip addr add 192.168.5.1/24 dev wlan0
 * 2) This should go without saying, but make sure the IP address is different on the two machines

Now you should be able to ping the IP of the opposite machine and get a response. If you get it, you're done! In our experience, it can take a while of pinging before we get a response back. We will have to look into what the cause of this is.

Automated Script
For our project, we compiled these changes into a easy to use script, called "ad-hoc_setup.sh". The script works as follows:  ad-hoc_setup.sh <IP_Address> <SSID> </b> This script must be run on both the Bone and the host that you want to add to the ad-hoc network. Keep in mind that the IP_Address must be different (but on the same subnet, /24) and the SSID must be the same.

User Instructions
The user instructions are based off of the assumption that you have already followed the installation instructions and have ran into no issues.

Browse to the web interface hosted by your beagle on port 8080. From here, you should be able to see a map centered on Rose-Hulman. At the top you will see two modes, live and search. Selecting live will let you see what GPS data you're receiving in realtime. If no satelites have been acquired or a fix hasn't been established, no data will be displayed. In search mode, new data acquired from the GPS won't be shown. Instead, you can specify a time range you'd like to display on the map. By setting the Start Time, the End time, and then hitting go, you can display any GPS data acquired during this time.

Whether you're in live mode or search mode, the time of the most recently plotted information will be displayed just above the map.

The color of the path changes depending on the Horizontal Dilution of Precision (HDP) received from the GPS tracker. Green indicates a good HDP, red indicates a less optimal HDP.

Highlights
Our project is able to track its position and recall the path later. Once the beaglebone is connected to a computer (wirelessly or by other means), it is able to serve up a webpage, where the user can either view the position with live updates or search for past locations the device was at.

Check out this video to see a quick demonstration of the GPS tracker in action. It is fairly raw and unedited, so we apologize for the lack of clarity.

Theory of Operation
We broke the project into three major parts: A python back-end, a Javascript server, and a Javascript client. The python back-end reads from the GPS tracker through UART then processes the data, stores it, then sends it to the JS Server when requested. The JS server acts as a middle man between the Python side and the client side. The server also serves the webpage to the user when they try to connect to the interface. The JS Client handles displaying information and sending user requests to the server.

Within the Python Backend, there are three processes, one handling the GPS serial connection, one listening for incoming messages from the server, and one handling search requests from the server. These threads share state through a SQL database and a semaphore controlling access to it.

Serial Thread
The serial thread reads data from the GPS, parses the important fields from it, and stores the results into a SQL database. It also checks if theh application is running in "live" mode, and if so, emits the latest info to the server.

Settings Handler
This thread manages updates to settings in the software. It sets up several callbacks, and waits for messages from the server. Currently, there are only two messages, "mode", which sets whether it is operating "live" or by "search", and "time_query", which stores in the SQL database that a time_query is pending along with its start and end times.

Search Handler
The search handler checks the SQL database for pending queries, executes them, and emits the results to the server.

JavaScript Server
As mentioned before, this acts as the middle-man between the backend and frontend. It uses SocketIO to listen for emissions from one side and then broadcasts the data to the other side.

Webpage Frontend
Javascript is used to create the majority of the webpage (Google Maps) and to listen for user input. Any user commands, such as a search request or a request to switch to live mode, are emitted to the JavaScript server. Further, the JS frontend is also listening for emissions from the server. These emissions are usually plot requests.

Work Breakdown
We first attempted to connect to the Beaglebone via the included FTDI cable. Here is a link to the FTDI cable's ref. sheet: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf. To connect the (Clean this up!)

Python Backend
Chris worked on the python side of the program. This included logging data, parsing messages from the GPS, and interfacing with Robert's server.

Javascript Server
Robert worked on creating the Javascript server. The code was mainly modeled after Dr. Yoder's Bonescript Server code. All of the extraneous features were stripped away, and all that was left was the code that created the server and interacted with the webpage. Code was then added to make the server act as a middle man between the Python backend and the webpage frontend.

Google Maps Webpage
We used Google Maps in Javascript to interface with the Beaglebone Black and display our GPS information.

Robert worked on the webpage, first using Dr. Yoder's Boneserver script to create a simple server. A new webpage was added that just had map on it.

Google provides free documentation for their API, and it turns out it's fairly straight forward to use. One of the many features that Google offers with this API is the ability to draw on the map, such as placing markers and drawing lines. By using the marker class in conjunction with actionlisteners, we were able to create a button that would place a marker on coordinates specified by the user.

This was only a proof of concept. The ability to place arbitrary markers was not left in, but the code used to create these markers was incorporated into creating paths. To test this, we would feed live data from the GPS-tracker to the frontend webpage. We were able to see our position in real time. After this functionality was added, the ability for the user to interact with our system came next. A time-range functionality was added, which allowed the user to specify over what time period he or she would like to see the position of the Bone. Lastly, we added the ability for the user to choose whether they wanted to be in live mode or search mode with the use of radio buttons.

Incomplete Work
While working on this project, there were a few features that we ended up scrapping or didn't have the chance to get around to. Some of the features are suggested later in the Future Work section, others have not.

Though the Ad-Hoc wireless network works there are a few issues with it. It takes a long time for the computers to start communicating, it can be slow, and it will frequently disconnect, forcing you to wait for few seconds before the signal can be reestablished. One thing we wanted to do but weren't able to get around to was to create a keep-alive signal so that when a connection was established, it wouldn't become disconnected after a while of inactivity. The wireless network wasn't the focus of our project, however, so we never put a huge priority on this.

We planned on changing the line thickness of the paths on Google Maps based on velocity, but due to time constraints we were not able to implement this feature.

Future Work
Adding the ability to hover over lines to get data would be a good feature. For example, hovering over a line and seeing that it was tracked at at certain time and being able to see the exact longitude and latitude associated with it would be a nice feature.

Another feature that may be harder is adding algorithms that would analyze the GPS data and attempt to fix it or give a better sense of the accuracy of the reading. While we were using our tracker, we found that it often would stray a few meters from where we actually were, especially if we were moving fast. Given more time, we may have been able to find a way to rectify the accuracy issues.

The UI has plenty of room for improvement as well. More search options could be added, such as by speed or proximity to a location. If the wifi dongle were replaced by a 3G modem, it could be set to send notifications to the operator when the tracker gets near certain locations, or if the tracker isn't near certain locations at schedule times (e.g., if your child isn't at school when they were supposed to).

Conclusions
Working with the Beaglebone to interface with a GPS tracker and then allow a user to view this information was a fun and interesting exercise. We had to work on a wide range of issues from working on the hardware to creating a usable user interface. Luckily the Beaglebone Black as a platform gave us many tools that made this possible and not ridiculously difficult. Through this project, we learned not only more about how the Beaglebone works, but about some non-Beaglebone related topics such as Javascript, HTML, and GPS Standards. Overall, working on this GPS Tracker for the Beaglebone was an interesting and enlightening project.

Useful Links
Server Side Events info: http://www.html5rocks.com/en/tutorials/eventsource/basics/

GPS Ref. Sheet: http://learn.adafruit.com/downloads/pdf/adafruit-ultimate-gps.pdf

GPS NMEA Sentences: http://www.gpsinformation.org/dale/nmea.htm