Handicap Route Logging and Mapping

Acknowledgments
I would like to thank Mr Arno Barnard for his guidance throughout the entirety of this
project, and for never minding my ramblings when I go to his office to think out loud on
a weekly basis.
I would also like to extend gratitude to MTN and Trinity Telecommunications for their
technical training and financial support.
The completion of this project also required much patience from Tamsyn Lunt, which I
thank her for, but also for always being caring and supportive no matter my mood swings
or selfish behaviour. Her sharp wit has also lightened the mood on many a critical
occasion.
Lastly, I would like to thank my parents, Leon and Sariana Dykman, for providing me
with a world of opportunities and always encouraging me to make the most of it. I am
endlessly grateful.
i
Declaration of own work
I, the undersigned, hereby declare that the work contained in this report is my own
original work unless indicated otherwise.
Signature
Date
ii
Abstract
This project aims to provide a solution that aids decision makers in effective fund
allocation when infrastructure upgrades are targeted, specifically when said
infrastructure is to be improved for persons with disabilities.
It is done by developing a mobile, battery powered route logging device, based on the
Arduino Uno microcontroller, which transmits route data to a web application via a GSM
modem. The data is then processed so that it may be visually categorised based on the
traffic each section of the route generates. Lastly, the visually categorised data is
displayed on a map.
A fully functional prototype system is developed with success that suggests it could be
a viable solution in the commercial arena.
iii
Opsomming
Hierdie projek poog om ʼn oplossing te bied wat besluitnemers in staat sal stel om fondse
so effektief as moontlik te allokeer wanneer dit kom by die opgradering van
infrastruktuur vir persone met gestremdhede.
Dit word gedoen deur die ontwikkeling van ʼn draagbare, battery gedrewe roete toestel,
gebaseer op die Arduino Uno mikrobeheerder, wat gebruikers se roetes kan opneem en
dan na ‘n web platform stuur deur middel van ʼn GSM modem. Hierdie roete data word
dan verwerk sodat dit visueel geklassifiseer kan word voordat dit op ʼn kaart vertoon
word.
Die sukses waarmee ʼn ten volle funksionele prototipe stelsel ontwikkel is dui daarop dat
dit moontlik ʼn oplossing in die kommersiële arena kan bied.
iv
Contents
1.
2.
Introduction
1.1.
Problem Description and Project Background
1
1.2.
Suggested Solution
1
1.3.
Project Layout
2
1.4.
Requirements
2
Literature study
2.1.
Satellite Navigation Systems
3
3
2.1.1.
Galileo
3
2.1.2.
GLONASS
4
2.1.3.
GPS
4
2.1.4.
NMEA 0183 Interface Standard
5
2.2.
Wireless Communication
6
2.2.1.
GSM Communication
7
2.2.2.
Trintel SMART Platform
7
2.3.
JavaScript
8
2.4.
Meteor Web Application Platform
9
2.5.
Database Solutions
9
2.5.1.
2.6.
MongoDB
10
Mapping Solutions
11
2.6.1.
Google Maps
11
2.6.2.
OpenStreetMap
12
2.6.3.
Practical Testing
13
Software Algorithms
13
2.7.
2.7.1.
The Least Squares Method
13
2.7.2.
The Haversine Formula
14
2.7.3.
The Orientation Method for Line Intersections
15
2.8.
Arduino Libraries
15
2.8.1.
Arduino TinyGPS Library
15
2.8.2.
Arduino SD Library
16
2.9.
Serial Communication
2.9.1.
3.
1
ASCII
High-Level Design
16
16
17
3.1.
System Overview
17
3.2.
Administrative Structure
17
v
3.3.
4.
5.
6.
Technical Specifications
17
3.3.1.
Logging Device
17
3.3.2.
Web Application
18
Hardware Design and Component Selection
19
4.1.
Required Components
19
4.2.
Component Selection
19
4.2.1.
Microcontroller
19
4.2.2.
GPS Receiver
23
4.2.3.
Storage
24
4.2.4.
Power Supply
24
4.3.
AirLink GL6100 Power Consumption
25
4.4.
RS232 and TTL Serial Communication
26
Software Design
27
5.1.
Microcontroller Programming
27
5.2.
Communicating with the Trintel SMART Platform
29
5.3.
Web Application Overview
30
5.3.1.
Login Page
31
5.3.2.
Map Display Page
31
5.3.3.
Data Management Page
31
5.4.
Sectioning routes
31
5.5.
Boundary Boxes
34
5.6.
Intersections
35
5.7.
Heat Mapping the Data
38
Implementation, Testing and Results
6.1.
Power Usage and Battery Life
39
39
6.1.1.
Power Consumption
39
6.1.2.
Battery Life
40
6.1.3.
Power Saving
40
6.2.
Average Section Positions
41
6.3.
Boundary Boxes and Intersections
41
6.4.
Practical Data Flow
42
6.5.
Arduino Shield PCB Design
43
6.6.
Panic button
44
7.
Conclusion
45
8.
References
46
Appendix A: Project Planning Schedule
46
vi
Appendix B: Project Specification
54
Appendix C: Outcomes Compliance
57
Appendix D: FreeMove User Manual
58
Appendix E: Cost of Components
62
Appendix F: Motivation for Adafruit GPS Shield
63
Appendix G: Calculating the Distance between Coordinates
64
Appendix H: Power Consumption versus Processor Speed
67
Appendix H: Schematic for PCB Design
68
Appendix I: Arduino Uno Code
71
Appendix J: FreeMove Web Application Folder Structure
74
Appendix K: FreeMove Web Application Code
75
vii
List of Figures
Figure 1: Possible positions detected using 2 satellites (left) and 3 satellites (right) [26] 3
Figure 2: Horizontal position error histogram [8]
5
Figure 3: MTN network coverage [10]
6
Figure 4: A simple view of the variable history of an asset on the Trintel SMART platform
7
Figure 5: A simple Venn diagram representation of web applications with JavaScript [12]
8
Figure 6: Google searches for NoSQL database management systems [25]
11
Figure 7: NoSQL skills listed on LinkedIn [25]
11
Figure 8: Total number of connector downloads according to the Jaspersoft Big Data
Index, for document storage data stores [25]
11
Figure 9: Intersecting line that satisfy Condition 1 [42]
15
Figure 10: Example of RS232 data transmission with no parity bit [47]
16
Figure 11: A simple system overview diagram
17
Figure 12: A simple visualisation of product use flow
17
Figure 13: An example Arduino sketch in the proprietary IDE
27
Figure 14: A simple flowchart representation for reading the GPS receiver
28
Figure 15: The UART settings used for the Uno microcontroller
29
Figure 16: The process of sectioning data
33
Figure 17: Bounding box representation
34
Figure 18: A simple example of sections with (left) and without (right) their bounding
boxes displayed
35
Figure 19: Distance for possible intersection
36
Figure 20: Explaining this application of Pythagoras' theorem
37
Figure 21: Example effect demonstrating a section (with count 1) being partially
intersected. All distances are in metres.
37
Figure 23: A visual example of the different section heat levels - from most traffic on the
left to least traffic on the right
38
Figure 24: An explanation for the bounding box size choices
42
Figure 25: The potential Arduino shield's PCB layout
43
Figure 26: Process flow for potential panic button
44
Figure 27: The FreeMove welcome page
58
Figure 28: Signing into a new or existing FreeMove account
58
Figure 29: The error message when a user tries to navigate the web application without
logging in
58
Figure 30: A successful sign in message
58
Figure 31: The FreeMove navigation bar
59
Figure 32: The data upload box on the FreeMove web application
59
Figure 33: The login page from Trintel's platform
59
Figure 34: The "Data" tab on the Trintel platform
60
Figure 35: A visual example of the different section heat levels - from most traffic on the
left to least traffic on the right
61
Figure 36: Selecting which data is displayed
61
Figure 37: Triangle XYZ [85]
64
Figure 38: Unit sphere coordinates [85]
64
Figure 39: Final steps for spherical cosine law [85]
65
viii
Figure 40: Performance comparison of spherical distance calculation methods [88] 66
Figure 41: ICC versus Frequency for the TI AHC00 [90]
67
Figure 42: (a) Counter-clockwise, (b) clockwise and (c) collinear orientation of 3 points
[42]
68
Figure 43: Intersecting line that satisfy Condition 1 [42]
68
Figure 44: Intersecting collinear lines that satisfy Condition 2 [42]
68
Figure 45: Folder structure for the web application
74
ix
List of Tables
Table 2: Power supply options
Table 3: Power usage of the AirLink GL6100 modem
Table 4: Power usage of the logging device
Table 5: Battery comparison
Table 6: Motivation for Adafruit Ultimate GPS Logger Shield
25
26
39
40
63
x
1. Introduction
Providing infrastructure that allows persons with disabilities to move safely and
independently is a priority for both local and national governments and other non-profit
organisations in South Africa.
It is, however, extremely costly to upgrade infrastructure to fulfil these needs, and the
parties interested in doing so are often very limited in their financial capability. The
efficient allocation of funds is therefore critical in order to extract the maximum benefit
from that which is available.
The aim of this project is to provide interested parties with a way of gathering data about
the routes used by persons with disabilities, and then presenting this data to them in a
manner that allows for sensible interpretation.
1.1.
Problem Description and Project Background
The government has identified persons with disabilities as “one of the most
marginalized and vulnerable groups” [1] in South Africa, and as such is trying to help
these people (born into both wealthy and poor families) to live as independently and
sustainably as possible.
A part of this mission involves improving infrastructure in a way that allows persons
with disabilities to have freedom of movement, in the sense that they can safely move
from point A to point B without the help of others.
The steps taken include equipping traffic lights at pedestrian crossings with speakers
that beep to let those with sight disabilities know when it is safe to cross the road, ramps
that allow wheelchair users to ascend or descend ledges, and specially designed
contours on sidewalks that guide those with limited sight.
The problem is that there is very little data available about the actual usage of said
infrastructure, as well as the transportation routes of persons with disabilities. This
means that the organisations that plan these infrastructure upgrades cannot properly
optimise the spending of their very limited resources.
1.2.
Suggested Solution
The objectives of this project, as broadly described above, will be achieved by producing
a portable, battery-powered route logging device, codename FreeMove, which relevant
people can carry with them for an extended period of time.
The device will then periodically transmit their route data to a central command station,
from where the data can be downloaded to any computer that is authorised and
connected to the internet. The route data will be completely anonymised before it can
be viewed by anyone that is not part of the authorised technical staff.
The data will also be visualised, on a webpage, in a manner that allows it to be easily
interpreted in order to allow people to make more informed decisions about the
upgrading of infrastructure.
1
1.3.
Project Layout
Chapter 1 handled the introduction to the project as well as a problem description.
Chapter 2 provides the literature study that provides background information and
research that was done in order to complete the project successfully.
Chapter 3 describes the high-level design of the project by providing a system overview
and the functional specifications for thereof.
Chapter 4 handles the hardware design and component selection for this project.
Chapter 5 explains all the software design that were taken in order to create a functional
system.
Chapter 6 discusses how the system was integrated, and what results were obtained
after some testing.
Finally, Chapter 7 analyses the success of the project based on the starting requirements,
and provides a conclusion.
1.4.
Requirements
Some primary requirements for the success of this project were agreed upon by the
author and Mr Arno Barnard at the start thereof, as per Appendix B. These are now listed.

The logging device must be portable.

The logging device must be battery operated.

A Trintel-based system must be used to collect, display and distribute the data
collected by the logging device.

The collected data must be visualised and displayed on a map.
The core requirements were then extended during the project planning phase by the
author to improve the usefulness and validity of the project. The added requirements are
listed below.

The logging device must have a reasonable battery life between charge cycles.

The logging device must be as small and light as possible.

The logging device must be cheap to produce.

The logging device must be made from components that are easily sourced in
South Africa.

The logging device must log route data in such a manner that the invasion of the
person carrying its privacy is as minimally invaded as possible.

The logging device has to be realisable by a single person in a relatively short
space of time.

The route data must be anonymised before any unauthorised person has access
thereto.

The route data must be visualised in a manner which allows it to be easily
interpreted in a useful way.
2
2. Literature study
In this section, some of the key concepts upon which the success of this project relies is
investigated in detail using external and specialised sources.
2.1.
Satellite Navigation Systems
Satellite navigation systems are made possible by constellations of artificial satellites
that orbit the earth. These satellites transmit information about their own location, as
well as the precise time of transmission. [2]
This information can then be used by small electronic receivers to determine their own
locations by comparing the locations of 3 or more satellites with the time it took to get
the message from the satellite to the receiver. This last step is possible by comparing the
time the message was sent with the time it was received, according to the receiver’s
internal clock.
If only a single satellite’s signal is received, the receiver can only be determine that its
position is a certain distance from the satellite – represented by the green sphere in
Figure 1. If two satellites’ transmissions are received, the receiver can then be sure it is
on the line where the spheres of the two satellites intersect, as represented by the circle
on the same sketch.
If a third satellite is introduced, the receiver can then pinpoint its own location to one of
either two positions. One of these positions will not be on the earth’s surface, and
therefore invalid, and so the receiver determines its position. Using more satellites will
improve the accuracy of the determined position, especially if altitude is also of concern.
Figure 1: Possible positions detected using 2 satellites (left) and 3 satellites (right) [26]
There are three primary satellite navigation systems currently available, namely Galileo,
GLONASS and GPS. Each of these options are now investigated, and a conclusion is
drawn about which is most suited to this project.
2.1.1. Galileo
The Galileo project is an effort by the European Union to create a satellite navigation
system that is run independently from the American and Russian counterparts. It is
suggested that the primary reason for its creation is because Europe has become too
dependent on satellite navigation to rely on other countries to provide it, since these
countries could easily decide to block Europe’s access thereto. It is estimated that about
3
6-7% of European GDP (Gross Domestic Product, an important economic indicator) is
reliant on satellite navigation. [3]
The first four satellites were successfully launched by October 2012, allowing the system
to be tested and validated. It was originally planned that the system would become
operational for civilian use by 2014, but progress has been slower than expected.
Satellites number 5 and 6 were launched on the 22nd of August, 2014, but their orbits were
not correctly circularised [4].
This means that the Galileo project is not yet operational for civilian use, and as such
cannot yet be considered as a solution for this project.
2.1.2. GLONASS
GLONASS (or “Globalnaya navigatsionnaya sputnikovaya sistema”, which translates to
“Global Navigation Satellite System”) is satellite-based navigation system operated by
the Russian Aerospace Defence Forces. The purpose of the project is to allow Russia to
have an independent navigation system in place, should conflict or another reason lead
to America blocking or scrambling their use of the GPS system. It also allows for
receivers that can connect to both GPS and GLONASS satellites for increased accuracy.
[5]
The project was started in 1976 by the Soviet Union, and by October 2011 the system had
reached a 24 satellite constellation capable of global coverage. This was ensured by a
substantial financial backing from the Vladimir Putin presidency for the Russian
Federal Space Agency. It was made free for civilian use in 2007. [5]
The relative infancy of the system, which his only been fully operational on a global scale
for three years at the time of writing, means that there are fewer receivers on the market
that connect to the Russian satellites than to the American GPS counterparts.
Neither Adafruit nor Sparkfun, two of the largest online electronics hobby stores in the
world, sell any GLONASS compatible receivers. All of the other hardware components,
as described in section 4.2 on page 19, can be found at both these stores. This has led to
the discounting of GLONASS as a serious option for this project, especially given the
timeframe of the project and the relative inexperience of the author. Exotic parts with
little online support were actively avoided.
2.1.3. GPS
GPS (Global Positioning System) was developed, and funded, by the United States
Department of Defence in 1973. It was originally for their use only because of fears that
it could be used by terrorists and other unwanted entities [6]. That changed after the
Korean Airlines Flight 007 was shot down by a Soviet Union anti-aircraft airplane in 1983
after it accidently crossed into their territory en route from New York City to Seoul.
President Ronal Reagan, of the United States of America, promised that GPS would be
available for international civilian use once it became fully operational. This happened
in 1993. [7]
In terms of horizontal location accuracy, the U.S. government claim that high quality
receivers should have an error margin of smaller than ~3.5𝑚, as shown in Figure 2. This
value, together with update frequency, does however differ based on the GPS receiver
module used.
4
Figure 2: Horizontal position error histogram [8]
GPS is widely used as the satellite navigation system of choice. There are many GPS
receivers available on the market at reasonable prices. Both the Adafruit and Sparkfun
online stores have a selection of GPS receivers that are compatible with the Arduino Uno,
or a similar microcontroller system, available for less than $40.
GPS is an appropriate satellite navigation solution for the following reasons:

GPS receivers are widely available at affordable prices.

GPS has global coverage, and as such would work equally well anywhere in the
world.

GPS provides sufficient horizontal accuracy for the logging device to be able to
track a person’s routes in satisfactory detail for this project.
2.1.4. NMEA 0183 Interface Standard
NMEA is short for National Marine Electronics Association, which is the organisation
that developed this communications standard. It defines an electrical interface and data
protocol for equipment communications – specifically marine equipment. [9]
The standard applies to various GPS receivers, such as the GlobalTop FGPMMOPA6H
which is used for this project – as explained in section 4.2.2 on page 23. It is important
to understand the standard used, because it not only describes the format of the
information received from the GPS receiver, but also what exactly is received.
This standard requires information to be sent serially using specific ASCII string formats,
one of which is applicable to GPS receivers. The information encased in the comma
separated string includes the position of the receiver (in terms of latitude, longitude and
altitude), the land speed at which the receiver is moving, the current time and date, and
whether or not the receiver has a valid satellite fix.
5
2.2. Wireless Communication
The wireless communication of this project will be done via a Sierra Wireless AirLink
GL6100 GSM modem. It makes use of quad band GPRS for transmissions, and accepts
data from a RS232 serial port. The modem accesses the GPRS network by using a
standard, commercially available, cell phone SIM card.
South Africa boasts far reaching GSM network coverage, since the technology is used by
the major cell phone network operators in the country. The GPS route logger will almost
exclusively be used in urban areas where GSM coverage is all but guaranteed. This leads
to GSM networks being an appropriate choice for the wireless communications required
in this project.
The mobile operator of choice for the SIM card required by the modem is MTN. This is
primarily the case because the SIM card was supplied for this, project free of charge, by
Trintel, but MTN also provide more than adequate network coverage in the metropolitan
areas of South Africa, as can be seen in Figure 3.
Figure 3: MTN network coverage [10]
The modem is operated by using Trintel’s specifically developed AT (Attention)
commands, called AWTDA commands. These commands are in the form of an ASCII text
string transmitted serially, and as such can be produced by the microcontroller of choice
(the Arduino Uno) without any difficulties.
When used successfully, the AWTDA commands allow the route logging device to
interact with Trintel’s so-called “SMART platform”. This means that if data is sent using
the preceding command it can easily be accessed on Trintel’s website at
smart.trintel.co.za.
The platform also allows for events to be sent to the server, which can then either
activate an SMS or an email alert.
According to the datasheet, the GL6100 modem requires a minimum of 5V voltage to
guarantee successful communication, with a maximum current draw at this voltage
level given as 2A. This power usage is way out of line with the rest of the peripherals
used in this device, when current draw in the 20mA to 50mA range is the norm. It would
seriously impede battery life if the modem drew 2A of current every time a transmission
is made.
6
This would imply that a solution would have to be designed where the modem was not
part of the mobile device, but this would degrade both the user friendliness and reliability
of the product, because users would need to connect the mobile device to the modem
before it can upload data to the cloud.
The modem was tested, however, which revealed that the maximum power dissipation
stated in the datasheet was overly conservative. The test and results can be seen in
section 4.3 on page 25.
2.2.1. GSM Communication
Global System for Mobile (GSM) communication is a cell phone technology that is used
by about 3 billion people globally to place wireless calls, according to the GSM
Association (GSMA). This makes it the most widely used wireless communications
method in the world, and GSM coverage is generally better in rural areas than that of the
competing CDMA technology.
GSM communication requires a Subscriber Identity Module (SIM) card, which attaches
an identification number to each GSM device. This number can then be used to identify
from which device data transmissions are originating. [11]
2.2.2. Trintel SMART Platform
The SMART platform was developed by Trinity Telecommunications (Trintel) in order to
allow users to easily monitor and control telemetry devices wirelessly. The data from
said devices (called ‘assets’) gets uploaded to the web platform is the form of a variable.
Figure 4: A simple view of the variable history of an asset on the Trintel SMART platform
The history of each data variable is maintained, so that value changes can be tracked
over time. These changes, or simply the current values, can be displayed on a dashboard
page using so-called ‘widgets’. These widgets allow users to visualise and display data
in an intuitive manner that allows for quick interpretation.
Assets are also able to trigger events on the platform, or the other way around. It is
possible because the platform is able to send data downstream, towards the asset, as
well. This means that both the asset and the platform can react to predefined
circumstances.
An example of a predefined trigger would be an asset being told by the platform to adjust
the power being supplied to an element in a geyser once the water temperature is
detected as above a certain threshold by the platform. An example of the asset triggering
a response on the platform would be if the asset sends an event trigger to the platform
7
based on the water temperature, from where the platform can then react by for example
sending an SMS to a specified number.
2.3. JavaScript
The author was not at all familiar with JavaScript before the start of this project, but
some research revealed it to be necessary in order to create the functional and
interactive web application that this project requires.
Web applications, that run client-side as opposed to server-side, are built with three
primary components, namely:

HTML (or HyperText Markup Language) is the standard markup language used
for web pages. It has embedded information that tell web browsers how to
structure and display a web page.

CSS (or Cascading Style Sheets) is used to customise the visual look and feel of
the web page, defining things like text fonts and sizes, button shapes and
background colours.

JavaScript is a client-side scripting language that allows web developers to
design interactive web applications with scripts that run asynchronously within
the users’ browsers.
HTML
Page, structure
and content
Modern Web
Applications
Base level
interactivity
JavaScript
CSS
Scriptable page
manipulation
Page design /
Look and feel
High level
interactivity
Simple
interactivity
Figure 5: A simple Venn diagram representation of web applications with JavaScript [12]
JavaScript (or JS, for short) is an object orientated coding language primarily used in
web development for client-side scripting in web applications.
Unlike the name suggests, it is unrelated to the Java coding language. It was originally
called LiveScript, but the developers (Netscape) decided to rename it after Java shot to
popularity in the 1990s. This is regarded by many as purely a marketing tactic, as it
coincided with Netscape adding Java support to their web browser, the late Netscape
Navigator. [13]
Although JS originally only operated on the client side of a web application, Node.js [14]
has allowed it to be used on the server side as well. This means that the backend as well
8
as the frontend of the web application can be written in JavaScript, and as such it is only
necessary to learn a single language in order to create a high quality web application.
The web applications that can be built with JavaScript come in almost endless shapes
and sizes, but it is useful and relevant to this project because of a few reasons. The
primary reasons are as follows:
1. There are many tutorials on JavaScript available on the internet free of charge,
many of them published by recognised universities [15][16][17].
2. It allows the implementation of user authentication.
3. It can be used in conjunction with an industry standard database solution, such
as MongoDB [18]. Please refer to section 2.4 for more information.
4. There are recognised solutions available for displaying maps with information on
them, as is discussed in section 2.6 on page 11.
5. JavaScript, in combination with HTML5 (the most recent revision of the HTML
standard), makes incorporating file uploads into a web application relatively
simple.
2.4. Meteor Web Application Platform
The accompanying web application for this website will be based on the Meteor
platform. Meteor is an open-source JavaScript-based platform for creating web
applications as simply and quickly as possible [19].
Meteor is fully JavaScript compatible, which means that all the APIs [20] are available on
both the client and the server side of the application, so no functionality is lost when
compared to a pure JavaScript solution.
Meteor has numerous advantages over a “vanilla” JavaScript web application, however.
The platform allows for reactive page updates – meaning that pages will update
automatically when data in the database is changed. Meteor also updates and renders
templates individually, rather than full pages, for a much more responsive feel when
compared to traditional webpages.
Crucially, Meteor also allows the access to sensitive data to be controlled very
effectively. This is very important for this specific project, as the client should only be
allowed to access the logged route data if the user has privileged access to do so. It is
very important to protect the privacy and safety of users taking part in the logging
process of this project.
Meteor’s so-called Smart Packages allow for the adding of various extra functions with
relative ease, meaning that features such as user accounts and access, mapping widgets
and professional notifications can be implemented by someone with limited web
development experience (such as the author of this document).
2.5. Database Solutions
There are two major classes of database management systems (DBMS) popular today,
namely SQL (Structured Query Language) and NoSQL (Not Only SQL) systems.
SQL is a language used to interact with relational databases. The language enables the
use of many functions used to manage, store or retrieve data. Relational databases
9
comprise of tables with rigid columns, or fields. Each data entry should have a value in
every field, and the system does not deal well with data where the fields are not static.
[21]
NoSQL refers to a non-relational manner in which data storage and retrieval is handled,
as opposed to the relational manner in which SQL based solutions approach this. A
NoSQL database does not always maintain referential integrity, and it favours low
latency above all. [22]
The database management required for this project is relatively simple, as coordinates
are simply stored along with a few other values, such as the timestamp for each
coordinate, or the section it belongs to (more on sections later).
An SQL-based solution would be perfectly adequate, since the data stored in the database
will always maintain a standard format. All coordinates will possess over the exact same
attributes.
NoSQL, on the other hand, is also more than capable of providing the storage solution for
this project. NoSQL systems can also handle data with rigid attributes, although the
structure is not so easy to visualise if viewing the data after it is stored. The structure is,
however, known because it is chosen.
NoSQL generally reacts better to horizontal performance scaling than SQL, but it is
highly unlikely that this will be of any significance given that the database performance
(in terms of the time it takes to load all the data) is not critical to the success of the project
at all, as it will only be relevant while new data is being added.
Since there is very little to separate the two, the reasons for choosing to implement a
NoSQL system rather than a SQL system were trivial in the end, namely:

The author developed a slight personal bias for NoSQL systems (specifically the
document-storage variety, as discussed in the following subsection) after some
limited hands-on experience with both SQL and NoSQL implementations.

Research suggested that it could be beneficial to the author to develop some
familiarity with MongoDB (a NoSQL database management system), as it is one
of the most popular database management skills currently advertised by IT
professionals on LinkedIn. Please see the following subsection for more
information on this point.
2.5.1. MongoDB
MongoDB is an open-source, NoSQL database management solution.
MongoDB uses what is referred to as “Document-Orientated Storage”. This is a data
model where so-called documents are stored in the database. These documents have
one or more named fields which are dynamic and can be defined differently for each
document. These fields can contain anything from variables to arrays of objects.
Documents themselves do not behave completely unlike objects. These documents are
then stored in so-called collections, so that it is simple to retrieve relevant data when
required.
MongoDB is one of the leading NoSQL solutions currently available. It has received at
least 3 times as many Google searches than any other NoSQL data management system,
many more professionals on LinkedIn[23] list MongoDB in their profile than any other
10
NoSQL database management system, and Japersoft[24] lists MongoDB as the top
performer in their Big Data Index. This is a difficult aspect to measure concretely, but the
abovementioned statistics provide a substantial argument. [25]
Figure 6: Google searches for NoSQL database management systems [25]
Figure 7: NoSQL skills listed on LinkedIn [25]
Figure 8: Total number of connector downloads according to the Jaspersoft Big Data Index, for
document storage data stores [25]
Figures Figure 6 to Figure 8 show that there is clearly some value in investing the time
to get a proper understanding of how to use MongoDB, which makes it an apt choice as
the database solution for this project. Almost more important, however, is its opensource nature. This means that it can be obtained and used free of charge – regardless
of how successful or unsuccessful the project eventually is.
2.6. Mapping Solutions
There are two main options available to handle the mapping display of this project,
namely Google Maps [26] and OpenStreetMap [27].
2.6.1. Google Maps
Google Maps is a web based mapping service provided by Google [28] that allows third
party websites to embed their service via the Google Maps API [29]. The embedded map
then downloads the map tiles from Google’s servers as they are needed, depending on
the embedded map’s bounds and zoom level. The page does not have to be reloaded for
new tiles to show, instead they download individually and appropriately as the user pans
and zooms on the map.
11
Third party websites may make use of this service free of charge, unless “you
consistently generate a high amount of traffic” when “you will need to pay for extra
usage” [29]. Google defines this as a website generating more than 25 000 “map loads”
[30] per day consecutively for 90 or more days.
It is extremely unlikely that this project will ever generate that kind of web traffic, but it
is still worth noting that it may result in some costs should the product become
surprisingly successful.
There is currently no advertisement from Google involved with making use of this
service, but Google does reserve the right to display ads in the future. This is again
something that is unlikely to become a reality in the immediate future, but it is worth
taking note of.
2.6.2. OpenStreetMap
OpenStreetMap [27] (referred to as OSM from here onwards) is a community built and
driven mapping service. The idea is to create a map of the entire world that is free to use
and is created by a voluntary community, much like what is done at Wikipedia [31].
The data provided by this mapping service can be used at no cost as long as OSM is given
credit therefor. This is easily done with a tiny link in the bottom of the mapping widget,
and is of no detriment to this particular project. This service is also free from
advertisements.
In order to use the OSM data on a third-party website (like that of the web application for
this project) there are two popularly used JavaScript libraries, namely Leaflet and
OpenLayers.
Leaflet
Leaflet [32] (also referred to as Leaflet.js or LeafletJS) is a widely used JavaScript library
for creating interactive maps on websites or web applications by combining it with OSM
or another mapping service. It is also an open-source project, which means that all the
source code is available and the library is free to use.
The documentation on the project’s official website [32] is well organised and easy to
follow, with enlightening examples and tutorials thrown in for good measure. This
means that even someone with next to no experience with JavaScript or mapping APIs
(like the author of this document) can get a simple map, complete with basic markers or
polylines, up in running in minimal time.
Leaflet has a map controller that can be implemented to allow the user to change map
data, but specifically it allows users to select the visible layers. This is relevant to this
project as it would allow users to choose to view data from different categories
individually or together in any possible combination.
The library places focus on being “mobile friendly” – meaning that the interactive maps
created using Leaflet display and work as expected on mobile devices and implement
features such as multi-touch zooming. This is of minimal consequence for this project
though, as it is not expected that many users will wish to visit the web application from
a mobile device, but nevertheless it allows for more flexibility should the direction of the
project change somewhat with time.
12
OpenLayers
OpenLayers [33], like Leaflet, is an open-source JavaScript library used to display
interactive and dynamic maps on websites or web applications. The library is not biased
towards any map provider, and can be used to display, among others, Google Maps or
OpenStreetMap map data. Since the Google Maps API [29] is more than adequate for use
with Google Maps, OpenLayers is investigated as an option for the display of OSM map
data.
There is an impressive amount of examples on the official OpenLayers website (207 at
the time of writing [34]), but it is not sensibly organised (alphabetically instead of
categorically) which means that finding an example on a specific topic of interest is not
always an intuitive process.
There is an extensive API available for developers to view [35], but again the navigation
of this document is (in the opinion of the author) tedious and often frustrating.
2.6.3. Practical Testing
Since the literature study provided no clear answers as to which mapping solution would
be best suited to for the needs of this project, it was decided to create a basic
implementation of each option. This allowed for a more first-hand assessment of the
strengths and weaknesses of each solution.
The goal here was to implement a simple interactive map in the Meteor environment
that could draw routes based on data in the MongoDB database.
In the end, there was almost no difference between using the different solutions and as
such it mostly came down to personal preference. OpenStreetMap was chosen ahead of
Google Maps simply because there was no chance that it would be commercialised and
start costing money, unlike Google Maps where a future subscription fee is not
impossible. In terms of auxiliary libraries used to access OSM, the author preferred the
way in which the documentation for Leaflet was set up, and that ended up as the main
reason why it was chosen over OpenLayers as there was so little to differentiate between
the two.
2.7. Software Algorithms
2.7.1. The Least Squares Method
The Least Squares Method is a regression model that is often accredited to the great
German mathematician Carl Friedrich Gauss, who claims to have investigated this way
of data fitting as early as 1794, but it seems likely that French mathematician Legendre
was in fact first to publish it in 1805. [36][37][38]
This method is essentially an algorithm that is used to calculate the line that would best
represent a number of, somehow related, data points by finding the values that would
produce the smallest total error when each error, or discrepancy between the line and
each point, is squared and summed.
In the context of this project, it is used to calculate the straight line that best represents
a number of latitude/longitude coordinates. The following formulae were used to
calculate the straight line that would best describe the coordinates:
13
𝑚=
(∑ 𝑥)(∑ 𝑦)
𝑛
(∑
𝑥)2
∑(𝑥 2 ) −
𝑛
∑ 𝑥𝑦 −
(1)
Where m is the slope of the new line, n is the number of coordinates and x and y
represent each coordinate’s latitude and longitude, respectively.
𝑏 = 𝑦̅ − 𝑚𝑥̅
(2)
Where b is the latitude-intercept of the new line, and 𝑥̅ and 𝑦̅ represent the mean values
of the latitude and longitude, respectively, of each coordinate.
The slope, m, and latitude-intercept, b, are then used to compute the definition of the
new straight line that will represent the collection of coordinates. The linear equation
used to calculate the coordinates of this new line is shown next.
𝑦 = 𝑚𝑥 + 𝑏
(3)
All the variables have the same meanings as before, except that the actual latitudes and
longitudes are used instead of their mean values.
The start and end of this line segment is defined by the latitude of the first and last
coordinates in the segment. From there, the above linear equation is used to calculate
the matching longitude values, as well as any coordinate values that appear in the
segment.
2.7.2. The Haversine Formula
The haversine formula is used to calculate the distance between two coordinate points,
described by their latitude and longitude values, along the outside of a sphere. It is a
specific case of the general Law of Cosines.
The derivation of the haversine formula, as well as the differences between it and the
Law of Cosines, is available in Appendix G. Please see this appendix for a more in-depth
analysis of the formula.
The haversine formula is more complex to implement in JavaScript than the Law of
Cosines, and as such there is a performance penalty. The performance penalty is offset
by the fact that it is regarded as more accurate than the Spherical Law of Cosines when
working with distances where accuracy of a few meters is required [39][40][41]. The
processing power on the server is also more than capable of handling such calculations,
and therefore it is of little consequence for this particular implementation. The distance
calculation code will only run when data is being added to the database, and as such a
few milliseconds, or even a few seconds, performance difference may be dismissed.
The performance differences between the haversine formula and the Law of Cosines is
also discussed in more detail, along with test data, in Appendix G.
As the performance impact is negligible to the success of this project, the haversine
formula will be used because of the increased accuracy when compared to the Spherical
Law of Cosines when calculating the distance between two coordinates on the earth’s
surface.
14
2.7.3. The Orientation Method for Line Intersections
The so-called ‘orientation method’, as described by Dr Patrick Prosser of the University
of Glasgow [42], is used to determine whether or not two line segments intersect one
another. This is a very important step when trying to determine whether a newly
generated route section crosses a previously generated section’s bounding box area.
Figure 9: Intersecting line that satisfy Condition 1 [42]
Please refer to the example in Figure 9 for the short explanation of the orientation
method. If the line segments defined by points (p1, q1, p2) and (p1, q1, q2), respectively,
have different orientations, as do those defined by points (p2, q2, p1) and (p2, q2, q1), two
lines intersect. Lines can also intersect while perfectly collinear, but that situation is
extremely unlikely in this application.
Please see Appendix I for a much more detailed explanation of the orientation method.
2.8. Arduino Libraries
The Arduino Uno is selected as the microcontroller system of choice for the mobile
logging device. Please see section 4.2.1 on page 19 for an in-depth explanation on why it
is chosen.
This subsection discusses two of the core software libraries investigated and
implemented on the Arduino Uno during this project.
2.8.1. Arduino TinyGPS Library
TinyGPS [43] is an Arduino library, created by Mikal Hart, that allows users to easily
access information from a GPS receiver that applies the NMEA standard, as explained in
section 2.1.4 on page 5.
The library provides an object that can be given the NMEA GPS data serially, one
character at a time, as the GPS receiver generates it. This object will then return a ‘true’
value when a valid NMEA sentence has been parsed, which then allows the program to
execute functions only when a new, complete sentence has been received. This object
can then be queried in order to retrieve the information given by the GPS receiver. These
various functions will then return the data, such as position or time, in a sensible format.
The library also avoids any unnecessary floating point operations. This is done because
the Arduino Uno is based on the 8-bit Atmel ATmega328P processor. The processor
cannot compute 32-bit floats natively, and so there is a severe penalty in terms of
required resources when a program does require to use this variable type.
The fact that the library avoid floating point operations is useful, not because the
processing speed is an issue, but rather because battery life is so crucial for this project.
Using less resources means that the processor drains less battery, so making use of
performance optimal code has a direct influence on the device’s power usage.
15
2.8.2. Arduino SD Library
As the name suggests, this is an Arduino software library that helps users to write and
read data to and from an SD storage card. This library is an extension of sdfatlib, another
SD library for the Arduino, written by William Greiman. [44].
2.9. Serial Communication
Serial communication is to be used for data communication between the microcontroller and the AirLink GL6100 modem. The Arduino Uno uses TTL (TransistorTransistor Logic) serial, while the modem uses RS232 serial.
A UART (or Universal Asynchronous Receiver / Transmitter) is used as a parallel to serial
converter in each device. Data can be fed to the UART in parallel, but it is then converted
so that it may be sent serially. On the other side, it is received serially and converted
back to a parallel format. This is done so that a minimal number of physical wires is
required between the two devices. In this case, a single wire is used for data transfer in
each direction, therefore only two wires are required between the two devices. [45]
The transmission consists of a start bit, the data bits, a stop bit, and then an optional
parity bit. This parity bit indicates whether the number of bits sent was even or odd, and
as such functions as a very simple form of error detection. [46]
Figure 10: Example of RS232 data transmission with no parity bit [47]
The communication protocol for RS232 and TTL serial is the same, but the voltage levels
used to represent the logical values of the signal do differ.
The RS232 serial specifies that a logical ‘1’ has a voltage of between -3V and -25V, while
a logical ‘0’ has a voltage level of between +3V and +25V. The standard allows for an
undefined state to exist between the values of -3V and +3V.
TTL serial represents a logical ‘1’ with the VCC voltage of the system (normally 3.3V or 5V),
while a logical ‘0’ is represented by the ground voltage of the system.
The difference in voltage levels used by each standard means that voltage conversion
would have to take place between the two devices in order to allow for successful data
communication.
2.9.1. ASCII
The American Standard Code for Information Interchange (ASCII) is a globally accepted
standard whereby numerous letters and symbols are referred to by numerical codes in
a 7-bit format. The 8th bit in the byte is used as a parity bit for error detection purposes.
[48]
This is also the standard which the AirLink GL6100 uses to decode instructions.
16
3. High-Level Design
In this chapter, the high-level design of the system is presented.
3.1.
System Overview
The complete system of this project is explained visually, in a very simple high-level
manner, in Figure 11.
Figure 11: A simple system overview diagram
3.2. Administrative Structure
Upon showing official
identification, the
logging device is
handed to the user
User carries logging
device on their
person
Logging data is
automatically
uploaded to cloud
System administrator
transfers data from
Trintel SMART to
FreeMove web
application
END PHASE
Logging device is set
up according to user
disability
LOGGING PHASE
START PHASE
The administrative structure is an important design step in this project, as it determines
the background with which all other considerations must be made. The steps of the life
cycle of a single user’s routing efforts are outlined in Figure 12.
User returns logging
device after logging
period
System administrator
uploads routing data
from SD card to web
application
Web application
automatically
determines which
coordinates have not
been uploaded to web
database yet
Figure 12: A simple visualisation of product use flow
3.3. Technical Specifications
The technical specifications were drawn up by using the project requirements given in
section 1.4 on page 2.
3.3.1. Logging Device

The mobile logging device must weigh less than 500 grams in order to not be
overly intrusive to its wearer.
17

The logging device must have outer dimensions of smaller than 100mm x 80mm
x 30mm, and have a flat, rectangular shape for the same reason as the preceding
point. Although the packaging for the device is outside of the scope of this project,
it must be conceivable that the device could be packaged to said dimensions.

The logging device has to be cheaper than R1500 to produce in South Africa so
that it may be commercially viable.

The logging device must be able to run from a single charge of its power source
for at least 12 hours.
o
If the power source is a 9V battery, this equates to a power consumption of
about 0.3375W. (Please see section 4.2.4 on page 24 for an explanation of
battery life calculations.)
o
If the power source is four 1.5V AA batteries in series, this power
consumption equates to about 1.25W. (Please see section 4.2.4 on page 24
for an explanation of battery life calculations.)

The logging device must be able to track a user’s travel route by recording GPS
coordinates at a rate of at least 0.25Hz. The update rate was decided upon after
some experimentation by walking around with GPS receivers in order to estimate
how far the average person would move in a second.

The logging device must be able to save the GPS coordinates (as well as the time
at which each coordinate was logged) to an external storage device of minimal
size, such as a microSD card.

The logging device must be able to communicate the abovementioned GPS data
to the AirLink GL6100 GSM modem via RS232 serial, with or without peripheral
ICs. This project would benefit from the immediate and wireless communication
provided by the modem, as it would prevent data loss in the event that a logging
device is lost or broken before its data could be manually uploaded. Data that is
received near real-time also opens up other development options, such as a panic
button – as discussed in section 6.6 on page 44. The modem was also sponsored
and set up for the project by MTN and Trintel, which means it added no financial
strains.
3.3.2. Web Application

The web application has to allow users to create unique profiles, with both a
username and a password.

The web application must only make route data available to a person who has
been given the privilege by a system administrator.

The web application must anonymize all route data before it is made visible to
anyone beside authorised system administrators in order to protect the privacy
of those whose tracks are stored.

The web application must divide route data into sections, over which traffic may
be counted.

The web application must visualise the traffic over each section by using, for
example, colour intensity and line thickness.
18
4. Hardware Design and Component Selection
This section handles all the hardware design steps that allowed the fulfilment of the
goals set at the beginning of this project. This involves choosing components and
integrating them, acknowledging power usage and the issues involved with that, as well
as focussing on the general user friendliness of the prototype product.
4.1.
Required Components
The following list of components has been deemed necessary after studying the lists of
requirements carefully. The reasoning behind each choice is also listed.

Microcontroller: A microcontroller of some sort is required to control all the
necessary sensors and log the data to some form of storage, before it is uploaded
to the central command station.

GPS receiver: A Global Positioning System (GPS) receiver is required in order to
accurately and easily track the wearer’s movements.

Storage: External storage is required in order to store the GPS coordinates until it
can be uploaded to the central command station.

Power supply: A battery solution has to be found to power the device.

Wireless communication: A modem of some sort is required in order to upload
the GPS routing data to Trintel’s web service.

Communication between components: An integrated circuit (IC) solution is
required to allow the microcontroller (TTL serial) to communicate with the
modem (RS232 serial).
There are many options available for each of these components. These options will be
explored and compared in the section 4.2 of this report.
4.2. Component Selection
4.2.1. Microcontroller
There are several microcontroller systems capable as functioning as part of the mobile
logging device for this project. After some careful research, the options were narrowed
down to the Arduino Uno, Beaglebone Black, Raspberry Pi, Texas Instruments MSP430
and TinyDuino.
The abovementioned options are now further examined in order to determine which is
most suited to this particular project.
Arduino Uno
The Arduino Uno Revision is a microcontroller board based on the ATmega328
microcontroller. The Uno is promoted as the mainstream Arduino board, which means
that there is a vastly superior number of accessories available for it in comparison to the
other Arduino products, and most tutorials and resources assume that this model is
used.
The large scale support for the Uno, combined with no need for any of the features made
available exclusively by some of the other products in the range, the availability in South
19
Africa (see [49]–[52]) and the low retail price of less than R300 (again, see [49]–[52]) made
the Uno the Arduino product of choice.
According to the manufacturer’s website, the Uno features “14 digital input/output pins
(of which 6 can be used as PWM outputs), 6 analogue inputs, a 16 MHz ceramic resonator,
a USB connection, a power jack, an ICSP header, and a reset button.” [53]
The aforementioned specifications more than meet the minimum requirements, since
the microcontroller will not be expected to perform any complex calculations. In fact,
the relatively slow processor (when compared to the other microcontroller options) is
ideal as minimal power usage is integral to the success of this project. Please refer to
Appendix H for a detailed analysis of the relation between power usage and processor
speed.
The stock Uno can operate with an input voltage of between 7V and 12V, meaning that a
9V battery provides an easy early start for testing. However, there are many guides on
the internet (such as the one referenced at [54]) that suggest it is entirely possible to
replace the stock 7805 5V voltage regulator with one that provides 3.3V output.
This means that if a regulator such as the Texas Instruments LM1117 800mA low-dropout
linear regulator is used an input voltage of as little as 4.3V is required to provide a stable
3.3V to the system [55]. This means that, theoretically and ideally, three AA batteries
which provide 1.5V each could power the system when placed in series, since:
𝑉 = 1.5 ∙ 3 = 4.5𝑉 > 4.3𝑉
This is an advantage over having to use a 9V battery, since AA or even AAA batteries
would typically last longer. Please see section 4.2.4 for a detailed explanation on
different battery solutions.
The Uno has been tested to draw 46.5mA when not driving any external logic, and is not
placed into “sleep mode” with software[56]. This means that the power usage in such a
scenario (and using the stock 5V setup) would be as follows [57]:
𝑃 = 𝑉 ∙ 𝐼 = 5𝑉 ∙ 46.5𝑚𝐴 = 232.5𝑚𝑊
The physical dimensions of the Uno PCB are listed as having a maximum length and
width of 6.86cm and 5.33cm, respectively [53].
Beaglebone Black
The BeagleBoard BeagleBone Black is a “low-cost, community-supported development
platform for developers and hobbyists” based around a 1 GHz Cortex A8 processor [58].
This board has been commercially available since 2013 [59] and has a recommended
retail price (RRP) of $55 (or about R585 [60]). In South Africa, however, the Black sells for
closer to R900 [61].
This development board offers a general purpose computer running Linux, with two PRU
32-bit microcontrollers and some input and output (I/O) pins (2x 46 pin headers, to be
exact) in order to connect to external sensors and expansion devices. The device also
provides 512MB DDR3 RAM, 4GB on-board flash storage, HDMI output and Ethernet
capabilities. [58]
The board needs 210-460mA current at 5V voltage, depending on the tasks being
employed and what speed the processor is running at, in order to operate [62]. The power
(P=VI [57]) consumption is now calculated for both the best and worst case scenarios.
20
𝑃 = 𝑉 ∙ 𝐼 = 5𝑉 ∙ (210𝑚𝐴 𝑡𝑜 460𝑚𝐴) = 1.05𝑊 𝑡𝑜 2.3𝑊
It is, however, possible to run the BeagleBone Black with a lower voltage if 5V voltages
are not required elsewhere in the system for expansion devices. In fact, it is
manufactured and sold with a Texas Instruments TPS65217C based power management
IC which allows for 3.7V Lithium-Polymer (LiPo) rechargeable batteries to power the
device.
The physical dimensions of the Beaglebone Black is 8.76cm by 5.84cm.
Raspberry Pi
The Raspberry Pi (from here on referred to simply as “Pi”) is more than a microcontroller
– it is a fully fledged personal computer, capable of running a Linux operating system
and performing general computing tasks such as playing videos or editing documents.
The Pi model B, which is the most readily available version of the development board,
comes with a 700 MHz ARMv6 CPU, 512 MB of RAM and a Broadcom VideoCore IV video
processor. It has 8 general purpose digital I/O pins, a UART and a SPI bus. There is also
HDMI video and audio output, and an Ethernet port for networking.
The model B draws between 700-1000mA at 5V, “depending on which peripherals are
connected” [63], which equates to 3.5W – 5W of power consumption (P=VI [57]).
The physical dimensions of the Pi is 8.56cm by 5.6cm – very similar to that of the
Beaglebone Black. It sells for around R665 from reputable online retailers in South Africa
[64][65].
Texas Instruments MSP430
The MSP430 is a line of low-power, value-driven microprocessor systems developed by
Texas Instruments (TI). The model that was singled out as a potential solution for this
project is the MSP-EXP430G2, which is the most basic and affordable version of the
MSP430 that TI offers.
It is based on a 16MHz processor with 512B RAM and 16kB of flash memory for programs.
The board provides both 8 digital and analogue I/O pins.
The device is advertised for an incredible $9.99 on TI’s website [66], significantly less
than any other listed option. In South Africa, however, it sells for closer to R200 [67].
The MSP430 has been tested to consume as little as 1mW power, when all of the on-board
LEDs are disabled [68], which also makes it the most power-friendly of the options listed.
The MSP430 has recently exchanged an Eclipse-based programming environment for
one based on the open-source Energia prototyping platform. Energia is credited with
allowing Arduino programs to be directly ported to the MSP430, and it provides a crossplatform solution that works on Linux, OS X and Windows. The platform does not,
however, support the user generated Arduino libraries, but many have been ported to
work on the MSP430. [69]
TinyDuino
The TinyDuino is microcontroller system based on the same Atmega328P processor as
the Arduino Uno, but it runs at a slower 8MHz clock frequency. The entire TinyDuino
board comes in dimensions of only 20mm x 20mm, but it does not include a USB
programmer to load programs onto the device.
21
The device sells for $20 on the TinyDuino website without the USB programmer, or $40
for a basic starter kit which includes both the processor and the programmer. The
system is not for sale from any local South African distributors.
Tiny Circuits, the company that produces the TinyDuino, claim that most Arduino
programs will run on the TinyDuino without any modifications, but Arduino shields to
not fit on the device because of size miss matches. TinyDuino does have shields
developed specifically for it, but the range of these is still quite limited. There is,
importantly for this project, a GPS shield produced by the company, but it is out of stock
at the time of writing with no estimated time for new stock arrivals.
Conclusion
The Beaglebone Black and Raspberry Pi are by far the fastest and most versatile of the
systems investigated, but their excessive power consumption (1W – 2.3W for the Black
and 3.5W for the Pi, respectively) immediately rule them out for this project. The
specifications listed in section 3.3 on page 17 state that the device should be able to run
on batteries for at least 12 hours, a feat which would prove difficult for either of these
systems. They are also more expensive than the other options, with prices of R900 and
R665 for the Black and the Pi, respectively.
The TinyDuino comes in an impressively small package, and it has the technical
capabilities to complete this project, but there are two reasons for its dismissal. Firstly,
and most importantly, the TinyDuino would have to be imported from its American
producers. This is an issue because there are serious time constraints on the project, and
many horror stories are told about products getting stuck at the South African customs
office for indefinite periods.
Secondly, at $40 dollars before any shipping costs are added, it is relatively expensive
when compared to the Arduino Uno and TI MSP430 – especially since the AirLink
GL6100 modem and the GPS receiver will likely make the small size of the
microcontroller obsolete as they are significantly larger. The form factor of the
TinyDuino also means that it is not compatible with many Arduino Uno accessories.
In terms of power consumption, the TI MSP430 is streets ahead of any other option listed.
The system uses about 30mW without any modifications [68], while the second best
option, the Arduino Uno, uses about 230mW after it is heavily modified to reduce power
consumption [56].
The MSP430 is also the cheapest solution available, at about R200. The second best
choice in terms of pricing is once again the Arduino Uno, which sells for about R300 in
South Africa.
A major drawback of the MSP430 is that it does not support all of the user-generated
software libraries available to the Arduino Uno, and only some of the accessories.
Granted, it is possible to complete this project using a MSP430 as the base, but given the
time constraints and the minimal relevant experience of the author, the lack of
widespread support, compared to that offered by the Arduino solution, is a definite
caveat.
The Arduino Uno offers a more all-round solution. It is not the cheapest or the most
power efficient solution on offer, but it performs admirably in both these areas. The Uno
is also stocked by various distributors in South Africa, and availability is not an issue.
22
The Uno provides enough I/O pins to allow for communication with all the required
sensors and peripherals.
The area in which the Uno excel above all else, however, is support. There is a vast
amount of learning material available free of charge on the internet, ranging from
introductory tutorials on generating a blinking LED program to specific lessons on how
to read a GPS receiver using the built-in UART.
There are various user-generated software libraries to make tasks such as reading an SD
card straightforward using an Arduino Uno. Hobbyist shops sell Arduino Uno specific
peripherals, or “shields”, that simply attach to the device using header pins to perform
almost any function imaginable, from determining position using GPS receivers [70] to
the amount of radiation in the air [71].
Thus, based on availability, performance, power consumption, price, size and support,
the Arduino Uno was chosen as the microcontroller system of choice to act as the base
for the portable logging device developed for this project.
4.2.2. GPS Receiver
The various factors impacting the choice of GPS receiver used for this project are briefly
discussed here, in order to explain why the selected component is an appropriate choice.
The antenna of the module determines the accuracy of the receiver. A good antenna
allows the receiver to read weaker signals, sometimes as weak as -165dBm, in areas
where the signal reception is not very good. Urban areas with many tall buildings, for
example, tend to have poor satellite reception. A sensitive antenna would mean that the
logging device is able to track routes in dense cities where satellite visibility is limited.
For the purpose of this project, the physical size and layout of the receiver is of great
import, since the logging device has to be small and light in order for someone to
consider carrying the device around all day with minimal disruption to their routines
and comfort. This means that the form factor of the products were also given serious
consideration.
Power usage is another concern, since the mobile route logging device will be powered
by batteries, and having the maximum time between necessary charges is important in
order to build a user friendly and cost efficient prototype.
The ease of use was also considered, in the sense that it was estimated how long it would
take to integrate said GPS receiver into a working route logging device in conjunction
with an Arduino Uno. This was a consideration mainly because of time constraints for
the development of a prototype product, and as such as large a time buffer as possible
had to be allowed for to enable possible troubleshooting of unforeseen problems that
could (or will, probably) arise.
Lastly, the price of the unit also plays a major role. The success of this project relies on a
very affordable product that is aimed at providing aid to a market segment that has
extremely limited financial capabilities. In fact, this is the main reason for the very
existence of this project. An expensive route logging device would be counterproductive,
to say the least.
With the aforementioned criteria in mind, the GPS receiver chosen is the Adafruit
Ultimate GPS Logger Shield (henceforth referred to simply as the ‘Adafruit GPS shield’).
23
This product is based on the GlobalTop FGPMMOPA6H (also referred to simply as ‘PA6H’)
GPS receiver module.
The unit has an ideal form factor, as it is simply attached to the top of a Uno using header
pins. The components on the shield are already wired correctly to allow an easy setup
which merely involves connecting the 5V voltage pin, ground pin and the required digital
I/O pins from the Uno appropriately. The ease of setup should lead to minimal time lost
to debugging before a simple system can be successfully implemented.
Another attractive feature of the Adafruit shield is that it has an integrated microSD card
slot, which has also been connected with the appropriate ICs for easy setup. This
integration helps to justify the price of the shield, as it covers two of the components
required for this project in full. There are no extra capacitors or resistors needed, or any
other so-call “hidden costs”.
The unit is also widely used, which has led to a large support base on the internet as well
as many documented stories of its successful implementation, meaning that the product
may be purchased with confidence that it will function as advertised.
The shield uses minimal power (20mA current draw at 5V), and it is sold for R781.00 in
South Africa. The choice is further justified in Table 5, which can be found in Appendix
F.
4.2.3. Storage
Some form of storage is required in case there is an issue with the wireless transmission,
such as a loss of signal or technical issues on Trintel’s side. The data is relatively small
in size, however, with each coordinate saved taking up 28 bytes as calculated in section
5.2 on page 29. This means that if a coordinate is stored each second, 24 hours’ data
would total the following:
𝑇𝑜𝑡𝑎𝑙 𝑓𝑖𝑙𝑒 𝑠𝑖𝑧𝑒 = 24ℎ𝑟𝑠 × 60𝑚𝑖𝑛𝑠 × 60𝑠𝑒𝑐𝑠 × 28𝑏𝑦𝑡𝑒𝑠 = 2419200 𝑏𝑦𝑡𝑒𝑠 = 2.42 𝑚𝑒𝑔𝑎𝑏𝑦𝑡𝑒𝑠
The preceding calculation shows that thousands and thousands of coordinate entries
still only result in a small text file by modern standards. This means that using a microSD card of a very modest size, such as is easily done with the Adafruit Ultimate GPS
Logger Shield, and would allow the device to store weeks’ worth of routing data.
For example, a year’s worth of data would be equal to 2.42 𝑀𝐵 × 365 𝑑𝑎𝑦𝑠 = 883.3 𝑀𝐵.
This implies that if each device was equipped with a 1 gigabyte micro-SD card, it would
be able to contain all the routing data for that user for a year – which is in all probability
much longer than a user will keep a logging device.
A 1 gigabyte micro-SD card would therefore allow each user to store the entirety of their
routing data with the logging device on a single storage device. When the user then
returns the logging device, an administrator can upload all the data to the FreeMove
website by simply dragging and dropping the data files, and the system will then ensure
that all the routing data is in fact added to the database.
4.2.4. Power Supply
The Arduino Uno requires an input voltage of at least 6V in order for normal functionality
to be guaranteed, according to the datasheet. This means that there are three options, in
terms of commercially available battery solutions, that stand out. These options are
tabulated in Table 1.
24
The microcontroller will be run from a conventional commercial 9V battery in the
beginning, since this allows for immediate development of the most crucial features of
the product. The 9V battery has a convenient form factor, is easily acquirable at a modest
price, and it does not require any special casing in order to get it to work with the Arduino
Uno.
Table 1: Power supply options
Option
Voltage
1x 9V Battery
[72]
4x AA Battery
[73]
4x AAA Battery
[74]
9V
Capacity (at constant
100mA discharge
current)
450mAh
4 x 1.5V = 6V
2500mAh
4 x 1.5V = 6V
1000mAh
Dimensions
Weight
48.5mm x 24.5mm
x 17.5mm
202mm x 58mm
x 58mm
178mm x 42mm
x 42mm
45.6g
23g x4
= 92g
11.5g x4
= 46g
This is only a temporary solution, however, as the option with 4 AA batteries in series is
clearly the best choice. The AA batteries, and even the AAA batteries, provide a much
larger capacity than the 9V battery does – if at a reduced voltage level.Consider a
situation where the device requires 100mA, and assume that the current required by the
voltage regulator is negligible.
If a 9V battery setup is used, and power is defined by P=VI [57], the power consumed by
the device is P = VI = 9V*0.1A = 0.9W. A typical 9V alkaline battery setup would therefore
450𝑚𝐴ℎ
last for about 𝑡 = 100𝑚𝐴 = 4.5 ℎ𝑜𝑢𝑟𝑠.
If four AA alkaline batteries are used in series, for a total voltage of 6V, the power
dissipated by the device would be equal to P = VI = 6V*0.1A = 0.6W, or about 33% less than
the power used in the 9V setup. This is because the voltage now only has to be regulated
from 6V down to 5V, rather than from 9V.
The larger capacity of AA batteries also have a significant impact. A typical AA battery
2500𝑚𝐴ℎ
solution would power the logging device for around 𝑡 = 100𝑚𝐴 = 25 ℎ𝑜𝑢𝑟𝑠 – or about 5.5
times as long as 9V solution would.
Four AAA batteries in series would also provide a significant upgrade on using a 9V
battery solution. This solution would give the logging device a battery life of
900𝑚𝐴ℎ
approximately 𝑡 =
= 9 ℎ𝑜𝑢𝑟𝑠.
100𝑚𝐴
The impressive battery life that four AA batteries in series can provide the logging device
with means that it is the power supply solution of choice for this product. Rechargeable
batteries would be preferable in order to minimise the long term cost and environmental
impact of the product.
4.3. AirLink GL6100 Power Consumption
As noted in section 2.2 on page 6, the power consumption of the AirLink GL6100 had to
be tested in order to determine whether or not it would be feasible to package it as part
of the mobile logging device. If the modem displayed a current draw of anywhere near
the 2A maximum specified in the datasheet, a solution would have to be found where
the modem forms part of some sort of charging base station.
25
The simple testing methodology used is now listed:
1. Identify which ports on the AirLink GL6100 modem are used for VCC and Ground,
respectively.
2. Set an adjustable bench mounted power supply, with controllable current, to 5V.
3. Connect the power supply to the modem, and monitor current draw from it.
4. Connect the modem to the Arduino Uno microcontroller, and transmit a typical
message to the Trintel SMART platform.
5. Monitor the power spikes as messages were transmitted via GSM.
This process was repeated for several transmissions, in order to assure that no
anomalies were found. The results were deemed consistent and conclusive, and are
displayed in Table 2. The start-up current drawn by the system is within a few milliamps
of the idle current draw.
Table 2: Power usage of the AirLink GL6100 modem
Supplied voltage
Average current draw (idle)
Average current draw (transmitting)
Average power consumption (idle)
Average power consumption (transmitting)
5V
45mA
80mA
0.225W
0.4W
This means that the power consumption of the modem is in fact in line with that of the
rest of the peripherals used in the project. It would not have such a drastic impact on
battery life that it becomes impractical to attach it to the mobile device. This is the
solution of choice because it requires minimal effort from the user.
4.4. RS232 and TTL Serial Communication
RS232 and TTL serial communication is identical in terms of the protocol used; the
difference is only in the voltages used to represent either a logical ‘1’ or ‘0’ – as discussed
in section 2.9 on page 16. The Uno microcontroller makes use of TTL serial
communication, while the AirLink GL6100 modem adheres to the RS232 standard.
In order to allow for communication between the two standards, the RS232 signal has to
be both inverted and regulated to ensure that the mechanical circuits on the Uno is not
damaged. The TTL signals from the microcontroller also has to be inverted and amplified
in order to ensure that it can be correctly interpreted by the modem.
This is done with a designated integrated circuit, such as the Texas Instruments
MAX232. There are many ‘clones’ on the market that perform similarly, such as the Sipex
SP232ACP. These ICs are used to transform the TTL and RS232 signals so that they are
compatible, and one is simply placed between the Uno and the modem to make
communication possible.
The Sipex SP232ACP is chosen for this project because it fits the requirements (which is
to allow the microcontroller to communicate with the modem without adding bulk to the
device), and it was obtainable immediately and free of charge.
26
5. Software Design
This section documents and discusses all the software development that went into this
project, both for the programming of the Arduino Uno microcontroller and the website
that would be used for data analysis.
5.1.
Microcontroller Programming
Arduino provide users with development software used to create programs, called
‘sketches’, which run on the Uno microcontroller. The language is based on C++, but
some hardware abstraction and specific libraries are included.
Figure 13: An example Arduino sketch in the proprietary IDE
The purpose of the microcontroller, and therefore the code on the Arduino Uno, for this
project is to:
1. Read the data from the GPS receiver
2. Process this data into a String of a specific, recognisable format
3. Save the modified data to a microSD card
4. Send the modified data to the Trintel SMART platform cloud via the AirLink
modem
The design processes used to achieve each of these goals is now discussed. The Arduino
microcontroller code used to perform all of these functions can be viewed in its entirety
in Appendix K.
27
Adafruit provide a software library for use with their Ultimate GPS Logger Shield product,
which is supposed to help users read data from the GPS receiver quickly and easily.
Whilst it does allow the user to get functional GPS readings with only about an hour or
so of work, the author found the code to be very rigid.
The TinyGPS library, developed by Mikal Hart and investigated more fully in section 2.8,
made this step a much simpler process when some customisation is desired. Please
refer to Figure 14 for a simplified visual explanation of this process.
Figure 14: A simple flowchart representation for reading the GPS receiver
The first step was defining the baud rate for the serial connection between the Arduino
microcontroller and the GPS receiver as 9600 baud. This value is given by Adafruit as the
rate at which the GPS receiver transmits data. Next, a “new data” variable of type Boolean
is defined, so that it can be determined whether the GPS object, as previously explained
in section 2.8, has received any new data from the receiver.
The data from the GPS receiver is then continuously polled for three seconds to check
for new data. This time was chosen, because after some experimentation it was deemed
that it was enough time to allow a significant movement to take place, but not so much
as to belittle the accuracy of the routing data. After some testing was done, however, it
was determined that a more energy efficient way to do this was to only poll the receiver
for 1 second, and then put the device in a low-power mode for 2 seconds. This is
discussed in section 6.1.3 on page 40.
If the GPS receiver has new data available (which it should, as the receiver updates at a
frequency of 1 Hz), the data is then passed to a post processing function.
Once a new GPS sentence has been passed to the GPS object, it is ready to be processed.
This is a simple step where the data is simply put in the correct format to include the
correct modem command.
The Arduino SD library is then used to save the data to a SD storage card. The program
will assign a name for text file it is saving to by checking for any files already on the SD
card, and simply iterating the number at the end of the name. This means that a new file
is created every time the Arduino restarts, and simply stops files from becoming millions
of lines in length.
The string format for data saved to the SD card is as follows:
[latitude] | [longitude] | [speed] | [time] <carriage return>
The data is also sent to the modem, along with the appropriate command, in order to
upload it via GSM to Trintel’s SMART platform. The commands used to communicate
with the SMART platform are discussed in the following section, section 5.2.
28
Since the modem is connected to the microcontroller’s hardware UART, it is simply a
matter of sending the data, in the correct format, to the serial output of the Arduino Uno.
The format is similar to the format used when saving to SD card storage, minus the
carriage return at the end, and inserted into an ASCII command.
5.2. Communicating with the Trintel SMART Platform
In order to communicate with the AirLink GL6100 modem, the UART on the Uno had to
be set up in a compatible manner. The settings used are shown in Figure 15. These
mirrored the protocol used by the modem.
Figure 15: The UART settings used for the Uno microcontroller
Since data will never be transmitted at a rate faster than 1 Hz (as this is the maximum
update rate of the chosen GPS receiver), a baud rate of 9600 is more than adequate, as
shown by the calculations that follow.
𝑇𝑟𝑎𝑛𝑠𝑚𝑖𝑠𝑠𝑖𝑜𝑛 𝑏𝑖𝑡𝑠 = 1 𝑠𝑡𝑎𝑟𝑡 𝑏𝑖𝑡 + 8 𝑑𝑎𝑡𝑎 𝑏𝑖𝑡𝑠 + 1 𝑠𝑡𝑜𝑝 𝑏𝑖𝑡 = 10 𝑏𝑖𝑡𝑠
𝑇𝑟𝑎𝑛𝑠𝑓𝑒𝑟 𝑙𝑖𝑚𝑖𝑡 =
9600
= 960 𝑏𝑦𝑡𝑒𝑠 𝑝𝑒𝑟 𝑠𝑒𝑐𝑜𝑛𝑑
10
The data is converted into a concatenated String before being sent to the modem. This
String is of the following format: [latitude]/[longitude]/[speed]/[time]. It is done this way
because it allows all the information to be easily contained in a single variable when
uploaded to the Trintel SMART platform.
The different parts of the String take on the following sizes:

[latitude]: 9 bytes
o

[longitude]: 9 bytes
o

Example: “18866570” (divide by 1000000 for degrees)
[speed]: 4 bytes
o

Example: ”-33928463” (divide by 1000000 for degrees)
Example: “49” (knots)
[time]: 6 bytes
o
Example: “130956” (hhmmss)
29
This means that the data string’s total size can be calculated as follows:
9 + 9 + 4 + 6 = 28 𝑏𝑦𝑡𝑒𝑠
However, as explained in section 2.2 on page 6, the modem also requires an AWTDA
command of a specific format in order to be able to transmit the data. The length of this
command, when the previously discussed string is given as the data value, has a total
length of 44 bytes, excluding the data string. This value could change depending on the
length of the variable names chosen.
This means that the total byte count is 28+44=72 bytes. Therefore, the data string can be
transmitted to the modem at a rate of 1Hz with a baud rate of 9600, because it can
transmit 9600 bits per second and this setup only requires 72*8=576 bits per second to
be transmitted.
The modem is operated via an extended selection of AT (attention) commands created
by Trintel called AWTDA. This means that in order to send commands to the modem the
microcontroller only has to send properly formatted ASCII text strings to the serial port.
Trintel has set up the firmware on the modems so that sending data across the wireless
network is a relatively simple process, as the modem is merely provided with a
command and, if applicable, some data.
The modem can even poll the device if such a command is sent from the Trintel
platform, but for this project most of the commands are limited to data upload
commands. These come in the following format:
AT+AWTDA=d,"{assetID}.{path}",{number of data points},"{variable},{data type},{value}"
The modem will always return a text string starting with “OK” if the command was
executed successfully, or “ERROR” if not.
5.3.
Web Application Overview
The Trintel SMART platform allows data that is uploaded to the website to be presented
in various ways. However, because of the amount of post-processing desired, such as
sectioning and heat mapping, the platform is inadequate when it comes to displaying
the data in a manner which is easily interpretable. It is still required in order to get the
data from each logging device into the cloud, but it cannot be relied upon on its own.
The processing of the data should not occur on the logging device itself, because battery
life is such a primary concern and any extra processing impacts that negatively. The
algorithms also need to be able to take all the data in the data store into account.
The web application also requires different user levels, in order to specify the
administrative rights only some users have as well as who has access to potentially
sensitive data. The SMART platform does not allow the implementation of different user
levels.
The conclusion is that, based on the limited customisation options offered by the Trintel
platform, the battery life concerns of the logging device and the requirement for different
user levels, that a web application should be developed specifically for this project, in
order to accommodate all the requirements, as explained in section 3.3.2 on page 18.
The application has three major components, namely login, map display and data
management. These components are briefly discussed in sections 5.3.1 to 5.3.3, but
30
please refer to the user manual in Appendix D for an in-depth explanation of every
section of the web application along with screenshots.
5.3.1. Login Page
The login page has a very simple purpose: allowing users to log in to the web application.
Users will be greeted with a simple welcome message and a brief explanation of the
website. They will be asked to log in by either providing the username and password for
an existing account, or by creating a new one.
The web application will not allow a visitor to navigate to any of the other tabs without
logging into an account first. Currently there is little security benefits in doing so, but it
means that there is a system in place which can be upgraded to facilitate different
account permission levels, or so that it may be tracked who uploaded which data.
5.3.2. Map Display Page
The map display page is where all the routing data will be displayed via a map widget.
The widget is powered by OpenStreetMap and is implemented using the Leaflet.JS
library, for reasons explained in section 2.6 on page 11.
5.3.3. Data Management Page
The data management page is where files are uploaded manually to the web
application’s data store. It is implemented so that files can simply be ‘dragged and
dropped’ into a designated area, and the application will read the files and update its
contents into the data store, after applying the proper post processing, such as
sectioning, to it. The map is then populated using the route data in the data store.
5.4. Sectioning routes
The data is to be presented in manner that can be likened to a so-called “heat map”. This
means that the colour and colour intensity of the data, as displayed on the map, will
represent the amount of traffic it has generated. In order to be able to present data in
such a manner, it has to be divided into sections. These sections will then count traffic
that crosses it, and this number will be stored with the section in order to represent it in
a sensible manner. Please refer to Figure 16 on page 33 for a one page flow chart of the
process, as it is now explained.
In order to section the data, a temporary segment is created first. The starting point of
the first segment of the data set, or file, is simply the first coordinate that is read into the
database. For any other segment it is the first coordinate that is read into the database
after a previous segment has been finalised.
The program will then continue to read coordinates into a temporary array,
chronologically from the same data set, and measure the distance from the starting
point each time. This is done by using the haversine formula, as explained in section
2.7.2 on page 14 of this report. The value for R which is used is the earth’s mean radius
(6371.0 km, according to NASA [75]).
The end point of the temporary segment is defined when either the end of the data set
is reached or if the coordinate being added to the database is more than 20 meters from
the starting point of that segment, whichever occurs first. The ‘Least Squares Method’,
31
as described in section 2.7.1, is then used to determine a straight line that best represents
this temporary collection of latitude and longitude coordinates.
The next step is to calculate whether the best fit line of the data intersects the bounding
boxes of any other predefined sections, and by how much. For more information on how
bounding boxes are generated, and on how it is determined whether a line does in fact
cross any bounding boxes, please refer to sections 5.5 (‘Bounding Boxes’) and 5.6
(‘Intersections’) that follow.
If the straight line segment does intersect with any other sections, the ratio of the line
segment within that particular section’s bounding box is calculated. This ratio is then
used to update both the section’s average position and traffic count appropriately. The
average position of the section is updated by weighing the intruding segment’s average
position, as determined by the line of best fit, based on the segment’s ratio within in the
section and that section’s traffic count.
For example, if 0.65 of the segment is within the bounding box, and the section has a
traffic count of 4.3, the position of the section’s start and end points will be calculated as
follows:
𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑛𝑒𝑤 =
=
Or, in general terms:
4.3 ∙ 𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑜𝑙𝑑 0.65 ∙ 𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑠𝑒𝑔𝑚𝑒𝑛𝑡
+
4.3 + 0.65
4.3 + 0.65
(4.3 ∙ 𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑜𝑙𝑑 ) + (0.65 ∙ 𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑠𝑒𝑔𝑚𝑒𝑛𝑡 )
(4.3 + 0.65)
𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑛𝑒𝑤 =
(𝑐𝑜𝑢𝑛𝑡 ∙ 𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑜𝑙𝑑 ) + (𝑟𝑎𝑡𝑖𝑜 ∙ 𝑝𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑠𝑒𝑔𝑚𝑒𝑛𝑡 )
𝑐𝑜𝑢𝑛𝑡 + 𝑟𝑎𝑡𝑖𝑜
(4)
(5)
(6)
The aim of redefining the average position of every section when a person moves
through it is to, with time, generate sections that truly represent the road and the user’s
movement.
In a similar vein, the traffic count of the section is also updated with the ratio of the
segment that is within that section. The start and end points of the ratio of the segment
that is within a section is noted for future reference.
The process described up to this point is continued until all the section with which the
segment intersects has been identified. Referring to the start and end points of the ratios
within sections, it can be identified which parts of the segment is not within a section.
The remainder of the section is then used to generate a new section. This also occurs
when the segment does not intersect with any sections.
First, a new section ID is generated. This is done by checking the database for previous
sections. If no other sections exist, i.e. this is the first section generated on the entire
map, the section ID ‘1’ is generated. Otherwise, the section ID is calculated by
incrementing the ID of the previously generated section by 1. The bounding box for that
section is generated, as described in the “Bounding Boxes” subsection that follows, and
then the section is inserted into the database. Its average position will be equal to that of
the line segment used to generate it.
32
Figure 16: The process of sectioning data
33
5.5.
Bounding Boxes
Route sections should be defined in a manner which allows the program to detect when
route segments are in fact on the same path. People will not be moving on exactly the
same route, even when walking on the same pathway or sidewalk, so there needs to be
some room for variation.
Sidewalks, in South Africa and the United States of America, are generally between 1.5
and 2.0 meters in width [76][77]. As such, it makes sense to give the bounding box a reach
of 1.5 meters on either side of the line, as explained by Figure 17, in order to make sure
that all routes on the same sidewalk are consolidated to a single section.
Figure 17: Bounding box representation
The bounding box is generated by calculating the equations that describe the short lines
of the box, as visualised in Figure 17, with different values of b:
𝑦 = 𝑚𝑥 + 𝑏
(7)
Where m represents the slope of the line, b represents the longitude intercept of the line,
and x and y represent the latitude and longitude, respectively, of each coordinate.
The slope for these short lines can easily be obtained because they are perpendicular to
the section line. This means that the slope of the short lines, m1, can be derived from the
slope of the section line, m0, which is already known, via the following formula:
𝑚1 =
−1
𝑚0
(8)
This is true for the slopes of all perpendicular lines [78][79]. This is then used, together
with the start and end coordinates of the section line, in the linear equation above to
determine the longitude intersections for each line, namely b1 and b2. This then provides
complete definitions for both the short sides of the bounding box, given that it is known
how long they should be (which it is – 1.5 meter to either side of the section line).
The Pythagorean Theorem can be used to calculate the distance between two points on
a coordinate grid by drawing a line between them and regarding it as the long side of a
right triangle, as shown in the following figure.[80]
From the preceding figure it is clear that the distance between the two coordinates is
equal to the length of the long side of the right triangle, which may be calculated from
Pythagoras’ Theorem as follows:
𝑐 2 = 𝑎2 + 𝑏 2
(9)
∴ 𝑑 = (𝑥2 − 𝑥1 )2 + (𝑦2 − 𝑦1 )2
( 10 )
Where d represents the distance between the two coordinates, and 𝑥𝑖 and 𝑦𝑖 represent
the latitude and longitude, respectively, of each coordinate.
2
34
The latitude and longitude coordinates for each of the four corners of the bounding box
can now be calculated, since the start and end points of the section line are also on the
lines that make up the short sides of the bounding box. This means that, for the
preceding distance formula, the distance and the latitude and longitude for one of the
coordinates is known.
The slope can also be used to eliminate a variable from the distance formula, as follows:
𝑦2 − 𝑦1
𝑚1 =
( 11 )
𝑥2 − 𝑥1
∴ 𝑦2 = 𝑚1 (𝑥2 − 𝑥1 ) + 𝑦1
( 12 )
Therefore, the distance equation may be simplified:
𝑑2 = (𝑥2 − 𝑥1 )2 + (𝑚1 (𝑥2 − 𝑥1 ) + 𝑦1 − 𝑦1 )2
)2
( 13 )
2
= (𝑥2 − 𝑥1 + (𝑚1 (𝑥2 − 𝑥1 ))
= (𝑥2 − 𝑥1 )2 + 𝑚2 (𝑥2 − 𝑥1 )2
= (1 + 𝑚2 )(𝑥2 − 𝑥1 )2
𝑑2
∴
= (𝑥2 − 𝑥1 )2
1 + 𝑚2
𝑑
∴ 𝑥2 = 𝑥1 ±
( 14 )
√1 + 𝑚12
Here x2 represents the latitude coordinate of the corner. x1 represents the latitude of
either start or end point of the section line, depending on which corner is being
calculated. The second term of the final equation is either positive or negative depending
on which corner is being calculated.
The longitude is calculated by substituting this latitude value into the linear equation for
the straight line of the short side of the bounding box that is currently applicable.
Sections are displayed with and without their borders in Figure 18 as a simple visual
example.
Figure 18: A simple example of sections with (left) and without (right) their bounding boxes
displayed
5.6. Intersections
Please refer to the flowchart in Figure 16 on page 33 as a supplement to the following
description.
Once the straight line approximation has been made for a potential new section, the
program compares its position to that of all the previously generated sections. Any
35
existing sections that are close enough to the temporary section for a possible
intersection are now identified.
The first step in this identification process is to search the database for only those
previously generated sections that are close enough for the line to potentially intersect
with the section’s bounding box. This preliminary round of elimination is there so that
the line is only tested against the remaining few sections for intersections with their
bounding boxes, and not against all the sections in the database.
This elimination is done because the mathematics required to calculate whether two
line segments intersect is relatively complex and rather computationally expensive if it
has to be done for (potentially) thousands of sections. This step is simply there to keep
the time needed to import a new set of routes to a minimum. The idea is expressed
visually in Figure 19, after which a detailed explanation of the process follows.
Figure 19: Minimum distance for possible intersections
The furthest the centre of a line segment can be from the centre of a section while the
possibility of that line segment intersecting the section’s bounding box remains is now
calculated below. A reminder that the bounding box of a section totals 7m in width, and
around 20m in length.
𝑑 = 10 + √102 + 3.52 = 20.5948 𝑚
The aforementioned calculation can be broken down as follows:

( 15 )
d is the maximum distances between the two centres, or the distance between
points F and H in the preceding figure.

10 is the approximate distance between the segment’s centre and one of its
end points, or the distance between points H and C, or H and G, in the
preceding figure.

The √102 + 3.52 term represents the distance from the centre of a section’s
bounding box to one of its corners, or the distance between points F and C in
the preceding figure.
The 2nd term of the sum is calculated by using Pythagoras’ theorem on the right angled
triangle that can be created with its longest side between points F and C. The triangle
AEC, in Figure 20, explains this idea visually.
36
Figure 20: Explaining this application of Pythagoras' theorem
By only looking at the sections that have centres within d metres of the segment centre,
as illustrated by the circle in Figure 19, all these remaining sections have a chance of
intersecting with the line segment. Not all of them do, however, and further calculations
are required.
The next step is to determine which of these remaining sections’ bounding boxes are in
fact intersected. This is done by making use of the so-called ‘orientation method for
determining intersections’ [42], as explained in section 2.7.3 on page 15. The
approximated straight line is tested against each of the borders of the bounding box of
each of the sections within the determined distance for possible intersections.
A visual example of how an established section, with a single traffic count, would be
shifted when it is partially intersected by a newly inserted section can be found in Figure
21.
Figure 21: Example effect demonstrating a section (with count 1) being partially intersected. All
distances are in metres.
Based on the amount of boundaries intersected, the segment of the line that is within
the bounding box of the particular section is now defined. In the case where two
boundary lines are intersected, the points of intersection provide the start and end
points of the segment. In the case where only one boundary is intersected, the closest
point to the centre of the bounding box is taken as the one point of the segment, and the
point of intersection as the other.
The ratio of the line segment within the section bounding box is using calculated with
the following formula:
𝑟𝑎𝑡𝑖𝑜 =
𝑙𝑒𝑛𝑔𝑡ℎ 𝑜𝑓 𝑠𝑒𝑔𝑚𝑒𝑛𝑡 𝑖𝑛 𝑏𝑜𝑢𝑛𝑑𝑖𝑛𝑔 𝑏𝑜𝑥
𝑡𝑜𝑡𝑎𝑙 𝑙𝑒𝑛𝑔𝑡ℎ 𝑜𝑓 𝑙𝑖𝑛𝑒 𝑠𝑒𝑔𝑚𝑒𝑛𝑡
( 16 )
37
5.7. Heat Mapping the Data
In order to clearly differentiate between the traffic certain route sections generate, an
approach similar to heat mapping is implemented. Each section is assigned a so-called
heat level, based on the traffic that passed through it. There are 9 levels, defined as
follows:
Level 1: The section has only been passed through once.
Level 2: The section has been passed through between 2 and 10 times.
Level 3: The section has been passed through between 11 and 25 times.
Level 4: The section has been passed through between 26 and 50 times.
Level 5: The section has been passed through between 51 and 100 times.
Level 6: The section has been passed through between 101 and 250 times.
Level 7: The section has been passed through between 251 and 500 times.
Level 8: The section has been passed through between 501 and 1000 times.
Level 9: The section has been passed through more than 1000 times.
The line that represents the section on the map is then modified according to the
section’s heat level in terms of its weight and colour. Figure 22 is an example of this
implementation, with each line having a lower heat level than the one before. There are
different colour schemes available for the route data from people with different
disabilities in order to be able to differentiate, for example, between route data from
people with sight disabilities and people with walking disabilities.
Figure 22: A visual example of the different section heat levels - from most traffic on the left to
least traffic on the right
38
6. Implementation, Testing and Results
6.1.
Power Usage and Battery Life
This section discusses the power usage of the logging device, the expected battery life
of the device and power saving steps taken to improve it.
6.1.1. Power Consumption
The logging device’s power usage had to be tested, as the theoretical values cannot
account for the combination of peripherals and the program run on the microcontroller.
Since the battery provided a near-constant voltage of 9V, the current is what had to be
measured in order to calculate the power using the formula P=V*I [57].
The methodology consisted of the following steps:
1. Both the AirLink GL6100 modem and the Sipex SP232ACP were disconnected
from the microcontroller. This means that only the Arduino Uno and the Ultimate
GPS Logger shield remained.
2. The Arduino Uno was switched on until it achieved a satellite fix.
3. A multimeter was set to its ammeter setting and placed in series between the
positive pole of the 9V battery and the VIN pin on the Arduino Uno.
4. The current draw was measured and recorded over an extended period of time in
order to avoid any anomalies.
5. The Sipex SP232ACP serial converter IC was re-attached to the Uno, and the
current was again measured and recorded over an extended period of time.
6. The Sipex SP232ACP was disconnected from the Uno, and the AirLink modem
was attached again. Then the current was recorded again in the same manner.
7. Lastly, the Sipex IC was reattached to the Uno whilst the modem was also
connected, and the current draw was measured in the same way for the last time.
Please refer to Table 3 for the results of these tests.
Table 3: Power usage of the logging device
Setup (with 9V battery)
Arduino Uno and GPS Shield only
(base setup)
Base setup with Sipex IC
Base setup with both Sipex IC and
modem
Average Current Draw
67mA
Average Power Usage
0.603W
75mA
111mA – 143mA
0.675W
0.999W – 1.287W
The power usage of the device is very clearly cyclical when the modem is connected. It
hits a peak current, and then drops to a minimum, and then back to the peak, and so
forth, at a rate of about 1Hz. This is in line with the frequency at which the new GPS data
gets transmitted wirelessly.
The swing between maximum and minimum current draw is only about 2mA when the
modem is not connected.
39
6.1.2. Battery Life
According to the datasheet, the Arduino Uno requires a minimum input voltage of 6V for
the manufacturer to guarantee normal functionality. This means that, in terms of
commercially available portable batteries, there are three obvious power supply
solutions for this project, as discussed in section 4.2.4 on page 24.
These options are now listed in Table 4, and are compared in terms of the battery life
that can be expected if it is used as the solution in this project. This table is also revisited
in the next subsection, after certain power saving techniques have been implemented.
In order to determine the current required at 6V, the power that was tested in the
preceding subsection for the full setups (between 0.999W and 1.287W) is reverted back to
current using the formula I = P/V [57]. The expected battery life is then calculated by
dividing the capacity, in milliamp-hours, by the current draw, in milliamps. This answer
is in hours.
Table 4: Battery comparison
Solution
1x 9V Battery [72]
4x AA Alkaline [73]
Batteries in series
4x AAA Alkaline [74]
Batteries in series
Voltage
9V
4 x 1.5V = 6V
Current
111mA – 143mA
167mA – 215mA
Capacity
450mAh
2500mAh
Battery Life
~4.5 hours
~25 hours
4 x 1.5V = 6V
167mA – 215mA
1000mAh
~9 hours
The preceding table makes it clear that the expected battery life can only meet the
requirement of 12 hours continuous battery life, as set out in section 3.3.1 on page 17,
when the setup consists of 4 1.5V alkaline AA batteries in series. Such a power supply
setup does, however, provide more than double the minimum requirement in terms of
battery life hours.
6.1.3. Power Saving
After the power usage of the logging device was measured, steps were taken to improve
the battery life of the unit.
The GPS receiver frequency, which was originally set at the lowest frequency advertised
by Adafruit at 1Hz, was set to an even lower update frequency of 0.333Hz. This was done
by sending a command using the PMTK protocol specified by GlobalTop (the
manufacturer of the actual GPS receiver chip) along with a newly generated checksum.
The command looks as follows:
$PMTK220,3000*3D
The checksum follows the * symbol, and is calculated as the XOR of all the bytes between
the * and $ symbols, written in hexadecimal. The 220 PMTK command specifies that it
should adjust the period between updates to the value, in milliseconds, between the
comma and the * symbol.
An additional Arduino library called JeeLib [81] is used. This library was developed by
JeeLabs – a weblog dedicated to what it calls “physical computing”, that is electronics
that interact with the physical world through sensors [82].
The class primarily utilised is called “Sleepy”. This class has functions that allow the
Arduino microcontroller to enter a low-power state for a set amount of time using the
40
Watchdog Timer. Since the GPS receiver is set to update at a frequency of once every 3
seconds, this provides a low-power delay in order to stop the microcontroller from
checking the GPS receiver for new data quicker than it updates.
The “loseSomeTime” function does just that, and it is used to provide a delay of about 2
seconds between GPS receiver checks. The JeeLib documentation does warn that the
time delay is not always accurate, but over a testing period of 40 minutes the delays were
always between 2 and 5 seconds. It is therefore accurate enough for this application.
The current draw of the logging device, in a full setup (i.e. with all the peripherals
connected), was measured again after this function was implemented along with the
slower GPS receiver update frequency.
The minimum current draw is now slightly lower at 98mA rather than 111mA, but it also
stays there for longer. The current draw is at its low point, on average, for about 2 seconds
out of every 3 second cycle.
2×0.098
1×0.141
+ 3 )×
3
This means that the average power usage for such a setup is now (
9=
1.011𝑊 instead of 1.143𝑊 – an improvement of 11.56%, without sacrificing functionality.
6.2. Average Section Positions
The system currently used to determine the positions of sections has some clear
advantages and drawbacks.
The main drawback of this system is that it is heavily reliant on a high numbers of users
for accuracy of data. Accuracy here refers the fact that there is no guarantee that a user
is taking a sensible route – for example, someone might cross the road at a normally
dangerous place because they wanted to greet someone on the other side and the road
happened to be empty. Outlier data from situations like those are without much use, and
in fact it may encourage incorrect assumptions.
In order to combat potential issues in that vein, a system is implemented where the
visibility of routes that have only a single count can be toggled easily on the map
interface. This means that users can choose whether or not to view single count routes
at all. As soon as a second user also takes a similar route, the likelihood of that route
being a sensible one increases drastically.
It was impossible to test the logging device with the high number of users that provide
the ideal use case it was designed for during the development thereof, but it is expected
that by averaging the section positions based on all routes that pass through it will result
in accurate depictions of the routes.
The major advantage of this method of route mapping is that the actual routes people
use get logged, not where the map expects a route to be. For example, if many people
really do cross the road at a certain place where there is no regulated crossing, it is useful
to be able to display that so that someone might be able to interpret it as a place where a
formal crossing is needed. Another example would be many people crossing a grass
area, which could mean that it would be sensible to build a path there.
6.3. Bounding Boxes and Intersections
The bounding boxes were originally designed to be 3m in width, and 10m in length, for
reasons explained in section 5.5 on page 34. However, since there is a lot of
41
computational intensity involved in order to calculate whether or not two lines cross
one another, the temporary sections are not assigned bounding boxes before
determining whether they intersect other sections.
This is because it would take a factor of 16 more processing power to check all four
borders of the bounding box of the temporary section with those of the bounding boxes
of all the sections which could possibly be intersected.
Instead it was decided to, crudely, enlarge the bounding boxes of the sections to be 7m
in width and only check whether the line of the temporary section crosses any of the
established sections’ borders. This way, if a new section is in fact generated, its “actual”
bounding box, with a width of 1.5m on either side of the line, cannot intersect with
another section it is parallel to.
This concept is explained simply in Figure 23, where the red rectangles represent the
“actual” bounding boxes of the sections, and the blue rectangle represents the oversized
bounding box used in order to eliminate the need for the temporary section’s bounding
box.
Figure 23: An explanation for the bounding box size choices
It is clear that the actual bounding boxes of the sections cannot intersect if the
temporary section did not intersect with the oversized bounding box originally.
6.4. Practical Data Flow
There are two practical paths whereby the data can get from the logging device to the
MongoDB database on the FreeMove website.
The first, and preferred, data path involves the data being transmitted to the Trintel
SMART platform via the modem. From there a system administrator can download the
data in a semicolon separated format text file and upload it to the web application for
post processing.
Uploading the data is as simple as dragging and dropping the file on the appropriate area
under the “Data Management” tab of the web application. The data is not very time
sensitive, in the sense that this process only has to be done on a weekly or even monthly
basis and takes seconds to complete, and as such this method is not as labour intensive
as it might suggest.
The alternative is to gather the data from the microSD storage card on the actual logging
device. This method is meant merely as a backup for when the GPRS transmission fails,
or if the user would like to use their own raw routing data for personal projects. The route
42
data text files can then also be uploaded to the web application, again simply by dragging
and dropping it in the correct box.
In order for the web application to be able to determine which coordinates have already
been uploaded successfully, and which have not, each coordinate is also assigned a
random number between 0 and 1000. This is done because it is possible for two people
to have crossed the exact same coordinate, and as such the system cannot simply check
whether a coordinate is already in the data store. However, it is exceptionally improbable
that two people cross the exact same coordinate and get assigned the same random
number. The random number generator is seeded by using the relatively random
analogue voltage from an open pin.
This means that a system administrator should always upload all the files from the SD
card to the web application as soon as a logging device is returned, as this will guarantee
that all data points are added to the data store.
6.5. Arduino Shield PCB Design
Although the packaging of the FreeMove logging device was outside of the scope of this
project, it is vital to the success of this project that the device can in fact be packaged in
a way that allows in to be user-friendly to carry. This implies that the size of the device
has to be minimal.
Figure 24: The potential Arduino shield's PCB layout
In an effort to demonstrate that the device complies with this requirement, a PCB layout
was designed using the EAGLE (Easily Applicable Graphical Layout Editor) CAD
(Computer Aided Design) program. The design is displayed in Figure 24.
The PCB was designed in a manner that allows it to connect to an Arduino Uno as an
expansion shield. This means that the device is already a single unit, and it only needs
to be placed inside a sturdy case in order to protect the device from physical damage.
The shield has been designed to have an overhang of 21mm, under which the battery
pack may be fitted in order to reduce the logging device to a single physical unit. The
AirLink GL6100 modem was taken apart in order to reverse engineer a schematic for it,
43
but the unit was too complicated for this. Instead, the unit was removed from all
unnecessary packaging and measured. The resulting measurements were then used to
make sure that there is appropriate space on the PCB shield in order to mount it on the
shield.
The wiring can then also be done in a way that bypasses the TTL to RS232 converter
inside the modem, meaning that the converter between the microcontroller and the
modem can be removed. If communication takes place at TTL voltage levels instead of
converting it to RS232 levels by both the modem and the microcontroller, it should
increase the battery life of the device as well as minimise unnecessary components that
add bulk to the product.
Please see Appendix J for the full schematic diagram of the design.
6.6. Panic button
The Trintel SMART platform provides SMS and email notifications when an alert or
event is triggered from the side of an asset. It was thought feature could be used to in
order to implement some sort of ‘panic button’ on each device with relative ease.
Figure 25: Process flow for potential panic button
Users would simply supply a next of kin to whom the alert would be SMSed, along with
the current coordinates of the user. This coordinate data would be transmitted in a
format that allows smartphone users to simply click on a link which takes them to a
Google Maps page that points to the location from where the stress signal is triggered.
After trying to implement this feature, however, it became clear that it is currently not
practically feasible. Firstly, the response time on the SMS events is poor. During testing,
it would take anywhere between a few seconds and 15 minutes before an SMS was
received. This is likely a fault on the behalf of the network operator, but the system needs
to be reliably responsive before it can be used in such a way.
Secondly, the Trintel platform only allows the position attributes of the asset to be sent.
These coordinates have to be manually updated through the web platform, and cannot
be changed from the logging device.
These two stumbling blocks have currently halted the implementation of a panic button
feature, but it could yet be implemented if they are addressed by Trintel and MTN.
44
7. Conclusion
The prototype system developed during this project meets all the objectives specified at
the start of it, as per Appendix B. These objectives are now listed and evaluated to
confirm the success of the project.
The development and implementation of a portable (battery powered) logging device to log
transportation routes used by persons with disabilities.
Testing has shown that the Arduino Uno based logging device provides acceptable
accuracy of data, especially considering the post-processing that is applied to the
routing data before it is displayed. The battery life of the device is also satisfactory, given
that a solution comprising of four AA alkaline batteries, in a series setup, is used.
The form factor of the current prototype is not ideal, and some improvements in this
area can definitely made in future, but the packaging was outside the scope of this
project. It is, however, conceivable that the entire product can be fitted into a welldesigned case of an acceptably small size.
In short, this objective is met successfully by the prototype logging device developed
during the project.
The development and implementation of a Trintel-based user interface to collect, display and
distribute route data.
The Trintel SMART Platform is used to collect all the route data generated by the,
potentially multiple, logging device(s). No data was ever lost while transmitting to the
SMART platform during the testing phase of this project.
The Trintel SMART platform has been deemed incapable of applying the post-processing
techniques required to display the routing data in a manner that allows for effective
interpretation of the data with relative ease. For this reason the displaying of data was
redirected to a separate web application, but there it was implemented successfully –
with results that are much more desirable than those achievable with the SMART
platform’s built-in widgets.
The Trintel platform is also used to distribute the data by allowing system administrators
to download all the routing data of every logging device (or “asset”) in a semicolon
separated text file. This file can then be uploaded to the FreeMove web application with
minimal effort.
The development and implementation of a stand-alone data visualisation tool to display route
data on a map.
The FreeMove web application draws lines in different colours and various weights on
an accurate street map in order to show how much traffic each section generates, which
means that interpreting the data is a very simple, visual process.
The main objective of the project was to develop a system that allows a user to look at
visualised data, and draw sensible conclusions from it about where funds should be
spent for maximum gain. This objective is achieved by the FreeMove web application
and, together with the mobile logging device prototype, the project as a whole has to be
considered a success. It provides a platform from which, with some slight tweaking, a
commercially viable product is definitely realisable.
45
8. References
[1]
W. Hartley, “Census: South Africans mostly a healthy nation | Health | BDlive.”
[Online]. Available: http://www.bdlive.co.za/national/health/2012/10/30/censussouth-africans-mostly-a-healthy-nation. [Accessed: 28-Jul-2014].
[2]
R. W. Pogge and The Ohio State University, “GPS and Relativity.” [Online].
Available: http://www.astronomy.ohio-state.edu/~pogge/Ast162/Unit5/gps.html.
[Accessed: 30-Sep-2014].
[3]
European Space Agency, “What is Galileo? / The future - Galileo / Navigation /
Our Activities / ESA,” 2014. [Online]. Available:
http://www.esa.int/Our_Activities/Navigation/The_future__Galileo/What_is_Galileo. [Accessed: 21-Oct-2014].
[4]
Arainespace, “Galileo satellites experience orbital injection anomaly on Soyuz
launch: Initial report,” 2014. [Online]. Available:
http://www.arianespace.com/news-press-release/2014/8-23-2014.asp. [Accessed:
21-Oct-2014].
[5]
K. Moskvitch, “Glonass: Has Russia’s sat-nav system come of age?,” BBC News,
2010. [Online]. Available: http://news.bbc.co.uk/2/hi/8595704.stm. [Accessed: 21Oct-2014].
[6]
US Aeronautics and Space Engineering Boards and National Research Council
Staff, The Global Positioning System: A Shared National Asset. 1997.
[7]
E. Magnuson and W. R. Doerner, “Atrocity in the skies: KAL Flight 007 shot down
by the Soviets,” TIME Mag., vol. September , 1983.
[8]
William J. Hughes Technical Center, “Global Positioning System ( GPS ) Standard
Positioning Service ( SPS ) Performance Analysis Report,” vol. 86, no. June, 2014.
[9]
National Marine Electronics Association, “NMEA 0183 Standard.” [Online].
Available:
http://www.nmea.org/content/nmea_standards/nmea_0183_v_410.asp.
[Accessed: 30-Sep-2014].
[10]
“MTN-SA coverage maps - OpenSignal.” [Online]. Available:
http://opensignal.com/networks/south-africa/mtn-sa-coverage. [Accessed: 21Sep-2014].
[11]
A. Fendelman, “What is GSM? (Cell Phone Glossary Definition).” [Online].
Available: http://cellphones.about.com/od/phoneglossary/g/gsm.htm. [Accessed:
30-Sep-2014].
46
[12]
J. Patterson and The Ohio State University, “Interactive Arts Media I course 5140,”
2012. [Online]. Available: http://accad.osu.edu/~jpatters/740/images/Web
App.png. [Accessed: 07-Oct-2014].
[13]
D. Flanagan, JavaScript: The Definitive Guide, 5th ed. O’Reilly Media, Inc., 2006.
[14]
“node.js.” [Online]. Available: http://nodejs.org/. [Accessed: 06-Oct-2014].
[15]
R. Soule and Cornell University, “Client-Side Scripting (JavaScript) [Part of CS
5142 course],” 2013. [Online]. Available:
http://www.cs.cornell.edu/Courses/cs5142/2013fa/2013-1007-client-javascript1.pdf. [Accessed: 06-Oct-2014].
[16]
N. Parlante and Stanford University, “CS101: Introduction to Computing
Principles,” 2014. [Online]. Available: http://web.stanford.edu/class/cs101/.
[Accessed: 06-Oct-2014].
[17]
L. Cozzens, A. Kudler, I. Sulam, and Brown University, “JavaScript Tutorial,” 1998.
[Online]. Available:
http://cs.brown.edu/courses/bridge/1998/res/javascript/javascript-tutorial.html.
[Accessed: 06-Oct-2014].
[18]
“MongoDB.” [Online]. Available: http://www.mongodb.org/. [Accessed: 06-Oct2014].
[19]
“Documentation - Meteor.” [Online]. Available: http://docs.meteor.com/.
[Accessed: 15-Aug-2014].
[20]
“JavaScript reference - JavaScript | MDN.” [Online]. Available:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference. [Accessed:
15-Aug-2014].
[21]
A. Bhattacharjee, “NoSQL vs SQL – Which is a Better Option?,” 2014. [Online].
Available: https://www.udemy.com/blog/nosql-vs-sql-2/. [Accessed: 24-Oct-2014].
[22]
P. Brown, “NoSQL Databases: An Introduction.” [Online]. Available:
http://www.browniethoughts.com/2013/02/nosql-databases-introduction.html.
[Accessed: 07-Oct-2014].
[23]
“World’s Largest Professional Network | LinkedIn.” [Online]. Available:
https://www.linkedin.com/. [Accessed: 07-Oct-2014].
[24]
“Jaspersoft Business Intelligence.” [Online]. Available:
https://www.jaspersoft.com/. [Accessed: 07-Oct-2014].
[25]
“MongoDB – The Leading NoSQL Database.” [Online]. Available:
http://www.mongodb.com/leading-nosql-database. [Accessed: 07-Oct-2014].
47
[26]
“Google Maps.” [Online]. Available: maps.google.com. [Accessed: 15-Aug-2014].
[27]
“OpenStreetMap.” [Online]. Available: http://www.openstreetmap.org. [Accessed:
15-Aug-2014].
[28]
“Google.” [Online]. Available: https://www.google.co.za/. [Accessed: 15-Aug-2014].
[29]
“Google Maps JavaScript API v3.” [Online]. Available:
https://developers.google.com/maps/documentation/javascript/basics.
[Accessed: 15-Aug-2014].
[30]
“‘Map Loads’ - Google Maps API — Google Developers.”[Online]. Available:
https://developers.google.com/maps/faq#usage_mapload. [Accessed: 15-Aug2014].
[31]
“Wikipedia, the free encyclopedia.” [Online]. Available:
http://en.wikipedia.org/wiki/Main_Page. [Accessed: 15-Aug-2014].
[32]
“Leaflet - a JavaScript library for mobile-friendly maps.” [Online]. Available:
http://leafletjs.com/. [Accessed: 15-Aug-2014].
[33]
“OpenLayers: Home.” [Online]. Available: http://openlayers.org/. [Accessed: 15Aug-2014].
[34]
“OpenLayers Examples.” [Online]. Available: http://openlayers.org/dev/examples/.
[Accessed: 15-Aug-2014].
[35]
“OpenLayers API.” [Online]. Available:
http://dev.openlayers.org/apidocs/files/OpenLayers-js.html. [Accessed: 15-Aug2014].
[36]
A. Olivier and University of Stellenbosch, “The Least Squares Regression Model,”
2007. [Online]. Available:
http://academic.sun.ac.za/mathed/174WG/LeastSquares.pdf. [Accessed: 17-Sep2014].
[37]
S. M. Stigler, “Gauss and The Invention of Least Squares,” Ann. Stat., vol. 9, no. 3,
pp. 465–474, 1981.
[38]
H. Abdi, “The Method of Least Squares,” pp. 1–7, 1974.
[39]
Movable Type Scripts, “Calculate distance and bearing between two
Latitude/Longitude points using haversine formula in JavaScript.” [Online].
Available: http://www.movable-type.co.uk/scripts/latlong.html. [Accessed: 18Sep-2014].
48
[40]
Doctor Rick, “Deriving the Haversine Formula,” The Math Forum, 1999. [Online].
Available: http://mathforum.org/library/drmath/view/51879.html. [Accessed: 18Sep-2014].
[41]
“Latitude & Longitude Haversine Formula.” [Online]. Available:
http://www.longitudestore.com/haversine-formula.html. [Accessed: 18-Sep-2014].
[42]
P. Prosser and Glasgow University, “Geometric Algorithms,” 2000.
[43]
M. Hart, “TinyGPS | Arduiniana.” [Online]. Available:
http://arduiniana.org/libraries/tinygps/. [Accessed: 30-Sep-2014].
[44]
W. Greiman, “SdFat Arduino Library.” .
[45]
R. H. Katz, “EECS150: UART Design,” 2000.
[46]
I. Poole, “RS-232 Voltage Levels | RS232 Signals | Radio-Electronics.Com.” [Online].
Available: http://www.radioelectronics.com/info/telecommunications_networks/rs232/signals-voltageslevels.php. [Accessed: 30-Sep-2014].
[47]
Gdansk University of Technology, “Exercise 8 - Port RS-232.” [Online]. Available:
http://www.ue.eti.pg.gda.pl/fpgalab/zadania.spartan3/zad_rs232_en.html.
[Accessed: 30-Sep-2014].
[48]
R. Kochhar and University of Wisconsin, “ASCII Table: 7-bit,” 2008. [Online].
Available: http://www.neurophys.wisc.edu/comp/docs/ascii/. [Accessed: 09-Oct2014].
[49]
“RS Comp - Buy Arduino UNO R3.” [Online]. Available: http://za.rsonline.com/web/p/processor-microcontroller-development-kits/7154081/.
[Accessed: 29-Jul-2014].
[50]
“Netram Technologies - buy arduino uno.” [Online]. Available:
http://netram.co.za/1009-arduino-uno-r3.html. [Accessed: 29-Jul-2014].
[51]
“Hobbytronics. buy Arduino UNO.” [Online]. Available:
http://www.hobbytronics.co.za/p/20/arduino-uno. [Accessed: 29-Jul-2014].
[52]
“MicroRobotics - buy Arduino UNO R3.” [Online]. Available:
https://www.robotics.org.za/index.php?route=product/product&path=20_67&prod
uct_id=50. [Accessed: 29-Jul-2014].
[53]
“Arduino Uno.” [Online]. Available: http://arduino.cc/en/Main/ArduinoBoardUno.
[Accessed: 29-Jul-2014].
49
[54]
“3.3V Conversion | Arduino Tips, Tricks, and Techniques | Adafruit Learning
System.” [Online]. Available: https://learn.adafruit.com/arduino-tips-tricks-andtechniques/3-3v-conversion. [Accessed: 29-Jul-2014].
[55]
“LM1117/LM1117I 800mA Low-Dropout Linear Regulator (Rev. M) - lm1117-n.pdf.”
[Online]. Available: http://www.ti.com/lit/ds/symlink/lm1117-n.pdf. [Accessed: 29Jul-2014].
[56]
“Arduino Power Consumption - Gadget Makers’ Blog.” [Online]. Available:
http://gadgetmakersblog.com/arduino-power-consumption/. [Accessed: 29-Jul2014].
[57]
D. Silverman, “Energy Units and Conversions.” [Online]. Available:
http://www.physics.uci.edu/~silverma/units.html. [Accessed: 29-Jul-2014].
[58]
“BeagleBoard.org - black.” [Online]. Available: http://beagleboard.org/black.
[Accessed: 29-Jul-2014].
[59]
E. Brown, “BeagleBone hops up to 1GHz. Drops price to $45. Woof! ·
LinuxGizmos.com,” 2013. [Online]. Available: http://linuxgizmos.com/beagleboneblack-speeds-up-to-1ghz-drops-price-to-45-dollars/. [Accessed: 28-Jul-2014].
[60]
“XE Currency Converter - Live Rates.” [Online]. Available:
http://www.xe.com/currencyconverter/. [Accessed: 30-Jul-2014].
[61]
“BeagleBone Black | MircoRobotics.” [Online]. Available:
https://www.robotics.org.za/index.php?route=product/product&path=20_201&pro
duct_id=611. [Accessed: 20-Sep-2014].
[62]
“BeagleBone Black | Arch Linux ARM.” [Online]. Available:
http://archlinuxarm.org/platforms/armv7/ti/beaglebone-black. [Accessed: 30Jul-2014].
[63]
“POWER | FAQs | Raspberry Pi.” [Online]. Available:
http://www.raspberrypi.org/help/faqs/#power. [Accessed: 20-Sep-2014].
[64]
“Generic Raspberry Pi Model B | Buy Online in South Africa | TAKEALOT.com.”
[Online]. Available: http://www.takealot.com/raspberry-pi-modelb/PLID28026129. [Accessed: 20-Sep-2014].
[65]
“Raspberry Pi - Model B - Netram Technologies.” [Online]. Available:
http://netram.co.za/1714-raspberry-pi-model-b.html. [Accessed: 20-Sep-2014].
[66]
Texas Instruments, “MSP-EXP430G2.” [Online]. Available:
http://www.ti.com/ww/en/launchpad/launchpads-msp430-mspexp430g2.html#tabs.
50
[67]
“RS-Components: TI MSP430 Development Board.” [Online]. Available:
http://za.rs-online.com/web/p/processor-microcontroller-developmentkits/7122649/.
[68]
“How Much Power Does MSP430 / TI Launchpad Use?,” 2011. [Online]. Available:
http://www.elperfecto.com/2011/01/08/how-much-power-does-msp430-tilaunchpad-use/. [Accessed: 26-Oct-2014].
[69]
A. Allan, “Which Board is Right for Me?,” MakeZine. [Online]. Available:
http://makezine.com/magazine/make-36-boards/which-board-is-right-for-me/.
[Accessed: 26-Oct-2014].
[70]
“Overview | Adafruit Ultimate GPS Logger Shield | Adafruit Learning System.”
[Online]. Available: https://learn.adafruit.com/adafruit-ultimate-gps-loggershield/overview. [Accessed: 28-Jul-2014].
[71]
“Arduino Radiation Sensor Shield.” [Online]. Available:
http://microcontrollershop.com/product_info.php?products_id=5035. [Accessed:
27-Oct-2014].
[72]
“Energizer 522 Datasheet,” pp. 1–2.
[73]
“ENERGIZER E91 Datasheet,” pp. 1–2.
[74]
Energizer, “ENERGIZER E92 Datasheet,” pp. 1–2.
[75]
NASA, “Earth Fact Sheet.” [Online]. Available:
http://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html. [Accessed: 18Sep-2014].
[76]
CSIR, “Roads : Geometric design and layout planning.”
[77]
U.S. Department of Transportation and Federal Highway Aministration, “Chapter
4 - Sidewalk Design Guidelines and Existing Practices - Sidewalks - Publications
- Bicycle & Pedestrian Program - Environment - FHWA.” [Online]. Available:
http://www.fhwa.dot.gov/environment/bicycle_pedestrian/publications/sidewal
ks/chap4a.cfm. [Accessed: 18-Sep-2014].
[78]
“Slope: Parallel and Perpendicular Lines.” [Online]. Available:
http://www.purplemath.com/modules/slope2.htm. [Accessed: 18-Sep-2014].
[79]
“Slope of Parallel and Perpendicular Lines.” [Online]. Available:
http://www.algebralab.org/lessons/lesson.aspx?file=geometry_coordparallelperp
endicular.xml. [Accessed: 18-Sep-2014].
[80]
“The Distance Formula.” [Online]. Available:
http://www.purplemath.com/modules/distform.htm. [Accessed: 18-Sep-2014].
51
[81]
“JeeLib: Introduction.” [Online]. Available: http://jeelabs.net/pub/docs/jeelib/.
[Accessed: 08-Oct-2014].
[82]
“JeeLabs.” [Online]. Available: http://jeelabs.org/. [Accessed: 08-Oct-2014].
[83]
A. Bogomolny, “The Law of Cosines (Cosine Rule).” [Online]. Available:
http://www.cut-the-knot.org/pythagoras/cosine.shtml. [Accessed: 18-Sep-2014].
[84]
S. Hartke and University of Nebraska–Lincoln, “Spherical Law of Cosines,” pp. 1–
4, 2011.
[85]
H. Whitey, Great Moments in Mathematics (before 1650). 1983, pp. 29–32.
[86]
D. E. Joyce and Clark University, “Measurement of angles.” [Online]. Available:
http://www.clarku.edu/~djoyce/trig/angle.html. [Accessed: 18-Sep-2014].
[87]
M. van ’t Hooft, “Performance: Vincenty vs Haversine vs Sferical Law of Cosines
Distance Calculations,” 2013.
[88]
“Intel® 22 nm Technology.” [Online]. Available:
http://www.intel.com/content/www/us/en/silicon-innovations/intel-22nmtechnology.html. [Accessed: 21-Sep-2014].
[89]
Texas Instruments, “CMOS Power Consumption and C pd Calculation,” no. June,
1997.
52
Appendix A: Project Planning Schedule
53
Appendix B: Project Specification
The project specifications, as agreed upon between the author and Mr Arno Barnard, are
as follows:
1. The development and implementation of a portable (battery powered) logging
device to log transportation routes used by persons with disabilities.
2. The development and implementation of a Trintel-based user interface to collect,
display and distribute route data.
3. The development and implementation of a stand-alone data visualisation tool to
display route data on a map.
These specification can be expanded in to functional specifications, interfaces and
performance, as is done below.
Functional Specification
 The system consists of a portable route logging device, a Trintel-based web portal
that captures and distributes the route data, and a web application that displays
the route data.
 Route data is transmitted to the Trintel-based web portal via a GSM modem.
 The route data is downloaded from the web portal in a semicolon separated text
file, and uploaded onto the web application.
 The web application stores all uploaded route data in a MongoDB data store.
Interfaces
 The mobile route logging device is based on an Arduino Uno, which can be
programmed via its USB connection.
 The AirLink GL6100 GSM modem communicates via RS232 serial.
 The visualised route data can be viewed on the FreeMove web application.
 The raw route data can be viewed on the Trintel web portal, or accessed directly
from the micro-SD storage card in the mobile logging device.
 The mobile logging device requires a power supply which can provide 200mA
current at a voltage of between +6V and +12V.
Performance
1
 The mobile logging device updates its position at a rate of 3Hz.





The average power usage of the mobile logging device is between 1W and 1.3W.
The mobile logging device has an average expected battery life of 25 hours when
using a AA battery solution with four batteries in series.
No data was lost in transmission between the mobile logging device and the
Trintel web platform during the testing phase of the project.
The dimensions of the logging device are currently as follows:
o The Arduino Uno, along with the GPS and micro-SD shield, has
maximum dimensions of 78mm x 53mm x 21mm.
o The RS232 to TTL converting IC has maximum dimensions of
59mm x 41mm x 12mm.
o The AirLink GL6100 GSM modem has maximum dimensions of
67mm x 51mm x 25mm.
If the specifically designed Arduino shield is implemented, the entire logging unit
should have maximum dimensions of 98mm x 53mm x 33mm.
54
55
56
Appendix C: Outcomes Compliance
Outcome
Problem solving: Demonstrate competence
to identify, assess, formulate and solve
convergent and divergent engineering
problems creatively and innovatively.
Application of scientific and engineering
knowledge: Demonstrate competence to
apply knowledge of mathematics, basic
science and engineering sciences from first
principles to solve engineering problems.
Engineering design: Demonstrate
competence to perform creative, procedural
and non-procedural design and synthesis of
components, systems, engineering works,
products or processes.
Investigations, experiments and data
analysis: Demonstrate competence to design
and conduct investigations and experiments.
Engineering methods, skills and
tools, including Information
Technology: Demonstrate competence to use
appropriate engineering methods, skills and
tools, including those based on information
technology.
Professional and technical communication:
Demonstrate competence to communicate
effectively, both orally and in writing, with
engineering audiences and the community at
large.
Independent learning ability: Demonstrate
competence to engage in independent
learning through well-developed learning
skills.
Where is this outcome achieved?
Throughout this entire report.
Sections 2.8, 4, 5, 6 and 7.
Sections 4, 5 and 6.
Sections 2, 6 and 7.
Sections 2, 3, 4, 5, 6 and 7.
Throughout this entire report, but also during
my weekly meetings with my project
supervisor and our regular email
communication.
Throughout this entire report, but specifically
in section 2.
57
Appendix D: FreeMove User Manual
Logging In
Start the FreeMove web application by using a web browser to navigate to
freemove.meteor.com. Here you will find the welcome page, as shown in Figure 26: The
FreeMove welcome page.
Figure 26: The FreeMove welcome page
To log in, click the “sign in / up” button in the top right corner. Here you can choose to
either sign into a previously created account with the correct username and password,
or you can create a new account.
Figure 27: Signing into a new or existing FreeMove account
The web application will not allow you to navigate away from this main page unless you
log into an account, new or existing.
Figure 28: The error message when a user tries to navigate the web application without logging
in
If you logged into a new or existing account successfully, the system will display an
informative message stating so.
Figure 29: A successful sign in message
58
Once you have logged in successfully, you can now navigate to the other tabs of the web
application. To do so, click on the various links on the navigation bar. The details of how
to use each section of the web application follows.
Figure 30: The FreeMove navigation bar
Managing Data
In order to add coordinate sets to the data store, click on the “Manage data” tab in the
navigation bar. This will take you to the data upload page. In order to add more data to
the data store, simply drag and drop the route coordinate files into the designated file
upload box, as shown in Figure 31: The data upload box on the FreeMove web application.
Figure 31: The data upload box on the FreeMove web application
The files can either be downloaded from Trintel’s platform, or copied directly from the
microSD card found in a logging device.
In order to get the data manually from the SD card of a logging device, simply connect
the storage card to a computer, select all the text files on the card, and drag and drop
them into the data upload box. No modification of the data files are needed. The web
application will automatically determine which coordinates have not been uploaded yet,
and only add those to the online data store.
In order to get the data from Trintel’s platform, you will have to be registered on their
system. If you are, point your web browser to platform.trintel.co.za, and log in with your
username and password.
Figure 32: The login page from Trintel's platform
59
After you have logged in, click on “Asset Management”. From here, navigate to the “Data”
tab of the resulting page. The “Data” tab will display all the variables currently set up for
each asset viewable under your account.
Figure 33: The "Data" tab on the Trintel platform (Pay no attention to the actual data – many are
still simply left over from previous testing exercises!)
In order to download the history of the tracking data, select the appropriate variable and
click on the “Export…” button to save the text file. This file can be uploaded directly to the
FreeMove web application without any modification. The web application will, as before,
automatically detect whether coordinates have already been added to the data store or
not, and will only add those which have not been added before.
Viewing the Map
To view the routing data visualized on a map, click on the “Visualize data” tab on the
navigation panel. Doing so will bring up an OpenStreetMap widget, with the current data
in the data store visualized on it.
Route sections are categorised based on how much traffic it generates. These different
categories are represented using lines of varying colours and thicknesses. The
categories for route traffic is defined as follows:
Level 1: The section has only been passed through once.
Level 2: The section has been passed through between 2 and 10 times.
Level 3: The section has been passed through between 11 and 25 times.
Level 4: The section has been passed through between 26 and 50 times.
Level 5: The section has been passed through between 51 and 100 times.
Level 6: The section has been passed through between 101 and 250 times.
Level 7: The section has been passed through between 251 and 500 times.
Level 8: The section has been passed through between 501 and 1000 times.
Level 9: The section has been passed through more than 1000 times.
The categorisation can be seen in Figure 34.
60
Figure 34: A visual example of the different section heat levels - from most traffic on the left to
least traffic on the right
The visualised data on the map will automatically be updated based on the coordinates
in the data store.
The user can also choose to view only data for persons with specific disabilities, or to
exclude routes which have only been used once in order to eliminate data anomalies
and to view only relevant data.
Figure 35: Selecting which data is displayed
61
Appendix E: Cost of Components
Item
Cost
Retailer
9V Alkaline Battery (Duracell)
R33.70
RS Components
Adafruit Ultimate GPS Logger
Shield
Arduino Uno
MicroSD Storage Card (1gb)
Sierra AirLink GL6100 GSM
modem
Sipex SP232ACP
R781.00
MicroRobotics.org
R269.00
R40.00
Free
MicroRobotics.org
WootWare.co.za
Sponsored by MTN and Trintel
Free
Sponsored by Mr Arno Barnard
TOTAL
R1123.70
62
Appendix F: Motivation for Adafruit GPS Shield
Table 5: Motivation for Adafruit Ultimate GPS Logger Shield
Criteria
Channels
Antenna
Physical
dimensions
Power usage
Ease of use
Price
Extra features
Motivation
The PA6H GPS receiver module boasts 66 channels, which is on par with
the leading industry standard for small form factor GPS receivers.
The PA6H has a ceramic patch antenna with a sensitivity of -165dBm.
16 x 16 x 4.7 mm for the PA6H module, and
70 x 54 x 7 for the entire shield. However, the shield’s form factor means
that it integrates with the Arduino Uno in a well thought out manner, and
as such keeps the form factor of the entire device looking professional. This
also means that the product maintains a smooth shape similar to that of a
pack of playing cards, whereas a smaller GPS receiver might still have
caused a less desirable shape.
20mA at 5V
The unit really stands out in this department. The shield is manufactured
specifically for use with the Arduino Uno microcontroller, and as such it is
very easy to connect using headers. Adafruit also provide extremely
detailed documentation and example code in order to get the receiver up
and running as quickly as possible.
R781.00 in South Africa
Integrated SD card slot
The GPS receiver shield provides a preconfigured micro-SD card slot out of
the box. This means that no time has to be spent on the hardware side to
find a storage solution, which is time saved.
Integrated RTC battery
The shield module has a RTC battery included, which the manufacturer
claims has a 7 year lifetime. This battery greatly improves the time needed
for the GPS receiver to find a satellite fix, as it allows the module to keep its
internal clock running even when external power is removed. As such, the
module does not have to take time to calculate the time from satellites.
Prototyping area
The shield has a 15x12 hole prototyping area, where extra components may
be added. In the case of this project, it is an ideal place to put the TTL to
RS232 converter IC.
Fix LED
The shield provides a clearly visible LED that blinks in order to show when
a satellite is obtained. This is very helpful when debugging new code.
Built in data logging
The shield has the option of internal data logging. It is unlikely that this
feature will be used, as it can only store data at a rate of 1/16 Hz, and store it
on a 64 kB flash.
Soft serial and direct connect
The GPS receiver can be connected to the microcontroller using soft serial,
which means that it leaves the Uno’s physical UART free for other
peripherals (such as the modem, in this case). The direct connect option
means that the GPS receiver can be debugged directly over USB, using a
terminal program.
63
Appendix G: Calculating the Distance between Coordinates
In order to calculate the distance between two coordinate points there are two methods
that stand out:

The Spherical Law of Cosines formula

The haversine formula
These methods have much in common, but also have unique traits that lead to different
pros and cons. Both methods are used to measure the shortest distance between two
points on the outside of a sphere, following a straight line on the outside of said sphere.
The Spherical Law of Cosines formula is similar to the Euclidean Law of Cosines (also
referred to as the Cosine Law) [83], and it makes sense to regard it first. Considering the
triangle XYZ, with side lengths a, b and c, and corner angles α, β and γ.
Figure 36: Triangle XYZ [84]
The Cosine Law is a generalised form of the Pythagorean Theorem [85], where the angle
γ is not necessarily 90⁰. The Cosine Law is defined as follows:
𝑐 2 = 𝑎2 + 𝑏 2 − 2𝑎𝑏 cos 𝛾
( 17 )
If 𝛾 is at a right angle:
𝑐 2 = 𝑎2 + 𝑏 2 − 2𝑎𝑏 cos 90°
= 𝑎2 + 𝑏 2 − 2𝑎𝑏 ∙ 0
= 𝑎2 + 𝑏 2
This is equal to Pythagoras’ Theorem.
( 18 )
In order to convert the Cosine Law to a spherical system, place the triangle XYZ on a
sphere with a radius of 1 (also known as a unit sphere). A, B and C are the angles opposite
lines a, b and c at the middle point of the sphere, denoted by O.
Figure 37: Unit sphere coordinates [84]
The lines a, b and c now also have the same length as the angle (in radians) at A, B and
C, since the formula for the length of an arc is defined as
𝐴𝑟𝑐 = 𝑟𝜃 = 1 ∙ 𝜃 [86]
( 19 )
And therefore 𝐴𝑟𝑐 = 𝜃, or b = B, as long as the sphere has a radius of 1. Further, if Z is
made the North point on the sphere, then a tangent plane can be drawn to it. The last
64
step is to extend the lines from O through X and Y until they meet this tangent plane at
W and U.
Figure 38: Final steps for spherical cosine law [84]
Next, the length of UW is calculated by applying the Cosine Law to UZW. Lastly, the
Cosine Law can be applied to the triangle OWU in order to calculate C, the angle between
the rays from O to W and U, respectively. This leads to the Spherical Law of Cosines
theorem [84]:
cos 𝐶 = cos 𝐴 ∙ cos 𝐵 + sin 𝐴 ∙ sin 𝐵 ∙ cos 𝛾
( 20 )
𝛾 is the angle of UZW.
A special derivation of this formula is known as the Haversine Formula. It is slightly
more complex in that it is not simply a one-line calculation in Javascript, but it is
regarded as more accurate than the Spherical Law of Cosines when working with
distances where accuracy of a few meters is required. [39][40][41]
This formula can be presented as three separate calculations [39]:
a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
( 21 )
c = 2 ⋅ atan2( √a, √(1 − a) )
d = R ⋅ c
Where φ and λ represent latitude and longitude, respectively, and R is the radius of the
sphere in question. The distance between the two points is given by d.
There is also a performance implication by using the Haversine Formula instead of the
Spherical Law of Cosines, as is noted in Figure 39. Since the processing power on the
server is more than capable of handling such calculations, however, it is of little
consequence for this particular implementation – the distance calculation code will only
run when data is being added to the database, and as such a few milliseconds, or even
seconds, performance difference may be dismissed.
The data in the following chart is presented in operations per second, with a higher
number being better. Three different internet browsers were tested for more conclusive
results.
65
Performance of distance calculations
900000
Operations per second
800000
700000
600000
500000
400000
300000
200000
100000
0
Chrome 37.0.2062
Haversine Formula
Firefox 29.0
Internet Explorer 10.0
Spherical Law of Cosines
Figure 39: Performance comparison of spherical distance calculation methods [87]
It can be seen that using the Spherical Law of Cosines instead of the haversine formula
would result in an increase in performance of between 20% and 30%, depending on which
internet browser is used, but this performance impact can be ignored in favour of higher
accuracy for this project.
66
Appendix H: Power Consumption versus Processor Speed
Modern processors make use of transistors that switch at very high frequencies [88]. This
transistor toggling, as it is sometimes called, directly influences the power consumption
of the processor. The relationship can be described by the following formula:
𝑃 = 𝑎 ∙ 𝐶 ∙ 𝑉2 ∙ 𝑓
Where P represents the power consumption, and f the frequency of the transistor
toggling. This implies a linear increase in power usage as the frequency of the capacitive
toggling increases, and while this is not completely true in practice, the results very
closely resemble this. The following figure is from a Texas Instruments document on
CMOS power consumption, and it shows the ICC current versus frequency for their AHC00
integrated circuit.
Figure 40: ICC versus Frequency for the TI AHC00 [89]
Figure 40 shows that the relationship between frequency and power consumption is
almost linear, even in practice, for transistors. This strongly suggests that a slower
processor, for all the drawbacks it has, will be beneficial from a power usage point of
view.
67
Appendix I: The Orientation Method
The orientation of three points in a 2-dimensional space can be defined as either
clockwise, counter-clockwise, or collinear, as shown in Figure 41(a), (b) and (c).
Figure 41: (a) Counter-clockwise, (b) clockwise and (c) collinear orientation of 3 points [42]
Two line segments, defined by points (p1, q1) and (p2, q2) respectively, intersect if and
only if one of the following two conditions are true:
1. Condition 1
a. (p1, q1, p2) and (p1, q1, q2) have different orientations, and
b. (p2, q2, p1) and (p2, q2, q1) have different orientations
2. Condition 2
a. (p1, q1, p2), (p1, q1, q2), (p2, q2, p1) and (p2, q2, q1) are all collinear, and
b. The x-projections of (p1, q1) and (p1, q1) intersect, and
c. The y-projections of (p1, q1) and (p2, q2) intersect
Condition 1 results in two lines intersecting at some angle, whilst Condition 2 is true if
the lines intersect in a collinear manner. This is shown in Figures Figure 42 and Figure
43.
Figure 42: Intersecting line that satisfy Condition 1 [42]
Figure 43: Intersecting collinear lines that satisfy Condition 2 [42]
In order to determine the orientation of three points, the slope of sections (point1, point2)
and (point2, point3) are required. The slope of a line segment can be calculated as follows:
𝑠𝑙𝑜𝑝𝑒 =
(𝑦1 − 𝑦0 )
(𝑥1 − 𝑥0 )
( 22 )
68
In the context of this project, 𝑦𝑖 and 𝑥𝑖 represent the latitude and longitude of a
coordinate, respectively. If the slope of the line segment (point1, point2) is defined as 𝜎
and that of the line segment (point2, point3) is defined as 𝜏 there are three possible
outcomes when comparing the slopes:
1. 𝜎 < 𝜏 , or a counter-clockwise orientation
2. 𝜎 > 𝜏 , or a clockwise orientation
3. 𝜎 = 𝜏 , or a collinear orientation
These outcomes are then used to determine whether either Condition 1 or Condition 2,
as previously defined, are satisfied and the lines intersect.
69
Appendix J: Schematic for PCB Design
70
Appendix K: Arduino Uno Code
1 /*
2
ACKNOWLEDGEMENTS:
3
JeeLabs, for the power saving sleepy class
<http://jeelabs.net/pub/docs/jeelib/classSleepy.html>
4
Jeremy Blum, for detailed Arduino tutorials that helped A LOT
<http://www.jeremyblum.com/>
5 */
6
7
8 #include <SoftwareSerial.h>
9 #include <TinyGPS.h>
10 #include <SD.h>
11 #include <Ports.h>
12
13 TinyGPS gps;
14
15 #define RXPIN 8
16 #define TXPIN 7
17
18 ISR(WDT_vect) { Sleepy::watchdogEvent(); }
19 SoftwareSerial ss(RXPIN, TXPIN);
20 const int chipSelect = 10;
21 File logfile;
22 long randnum;
23
24 void setup(){
25
// Start the serial at 9600 baud rate
26
Serial.begin(9600);
27
ss.begin(9600);
28
// Set the GPS receiver update rate to 1/3Hz
29
PMTK_SET_UPDATE_3SEC;
30
31
Serial.println("FreeMove GPS tracking unit");
32
Serial.println();
33
Serial.print("Initializing SD card...");
34
pinMode(10, OUTPUT);
35
// Check to see if SD card is present
36
if (!SD.begin(chipSelect)) {
37
Serial.println("Card failed, or not present");
38
// don't do anything more:
39
return;
40
}
41
Serial.println(" card initialized.");
42
43
// Generate new file. Name iterates if exists.
44
char filename[15];
45
strcpy(filename, "GPSLOG00.TXT");
46
for (uint8_t i = 0; i < 100; i++) {
47
filename[6] = '0' + i/10;
48
filename[7] = '0' + i%10;
49
// create if does not exist, do not open existing, write, sync after
write
50
if (! SD.exists(filename)) {
51
break;
52
}
53
}
54
// Open the file on SD card for writing
55
logfile = SD.open(filename, FILE_WRITE);
56
if( ! logfile ) {
71
57
Serial.print("Couldnt create ");
58
Serial.println(filename);
59
}
60
Serial.print("Writing to ");
61
Serial.println(filename);
62
63
// Seed the random generator from unused analogue pin 0
64
randomSeed(analogRead(0));
65 }
66
67 void loop(){
68
delay(100);
69
Sleepy::loseSomeTime(2000);
70
bool newData = false;
71
unsigned long chars;
72
unsigned short sentences, failed;
73
74
// For one second we parse GPS data and report some key values
75
for (unsigned long start = millis(); millis() - start < 1000;)
76
{
77
while (ss.available())
78
{
79
char c = ss.read();
80
if (gps.encode(c)) // Did a new valid sentence come in?
81
newData = true;
82
}
83
}
84
// If new data is received from GPS receiver
85
if (newData){
86
long lat, lon;
87
unsigned long fix_age, time, date, speed, course;
88
unsigned long chars;
89
unsigned short sentences, failed_checksum;
90
91
// retrieves +/- lat/long in 100000ths of a degree
92
gps.get_position(&lat, &lon, &fix_age);
93
94
// time in hhmmsscc, date in ddmmyy
95
gps.get_datetime(&date, &time, &fix_age);
96
97
// returns speed in 100ths of a knot
98
speed = gps.speed();
99
100
// course in 100ths of a degree
101
course = gps.course();
102
103
// Generate random ID number
104
randnum = random(1000);
105
106
// Send command to modem over serial
107
Serial.print("AT+AWTDA=d,\"logger.stat\",1,\"info,string,");
108
Serial.print(lat);
109
Serial.print("|");
110
Serial.print(lon);
111
Serial.print("|");
112
Serial.print(speed);
113
Serial.print("|");
114
Serial.print(time);
115
Serial.print("|");
116
Serial.print(randnum);
117
Serial.print("\"");
72
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 }
136}
Serial.println();
// Log coordinate data to text file, if SD card present
if (logfile) {
logfile.print(lat);
logfile.print("|");
logfile.print(lon);
logfile.print("|");
logfile.print(speed);
logfile.print("|");
logfile.print(time);
logfile.print("|");
logfile.print(randnum);
logfile.println();
logfile.flush();
Serial.println("Logged to SD card.");
}
73
Appendix L: FreeMove Web Application Folder Structure
Figure 44: Folder structure for the web application
74
Appendix M: FreeMove Web Application Code
Client: HTML
data.html
1<template name="data">
2
<div align="center" style="margin-top: 5px">
3
<p><em>To upload more data, please drag and drop the file(s)
generated by the logging unit below.</em></p>
4
</div>
5
<div align="center" style="margin-top: 5px" id="dropbox">
6
Drop files here
7
</div>
8</template>
home.html
1 <template name="home">
2
<div align="center" style="margin-top: 20px">
3
<h1>Welcome to FreeMove.</h1>
4
<h4>Here data is added and visualized in order to provide a
platform for effective resource planning.</h4>
5
{{#if loggedIn}}
6
<p><em>Welcome, <b>{{loggedIn.username}}</b>.</em></p>
7
{{else}}
8
<p><em>Please log in to continue.</em></p>
9
{{/if}}
10
</div>
11</template>
index.html
1 <head>
2
<title>FreeMove</title>
3
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet0.7.3/leaflet.css" />
4
<script src="http://cdn.leafletjs.com/leaflet0.7.3/leaflet.js"></script>
5 </head>
6 <body>
7 </body>
8
9 <template name="layout">
10 <div class="container">
11
<header>
12
{{> nav }}
13
</header>
14
{{> yield}}
15 </div>
16</template>
17
18<template name='nav'>
19 <nav class="navbar navbar-default" role="navigation">
20
<div class="container-fluid">
21
<div class="navbar-header">
22
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1">
23
<span class="sr-only">Toggle navigation</span>
24
<span class="icon-bar"></span>
25
<span class="icon-bar"></span>
75
26
<span class="icon-bar"></span>
27
</button>
28
{{> navBrand}}
29
</div>
30
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse1">
31
<ul class="nav navbar-nav">
32
{{> navItems}}
33
</ul>
34
<ul class="nav navbar-nav navbar-right">
35
{{> loginButtons }}
36
</ul>
37
</div>
38
</div>
39 </nav>
40</template>
41
42<template name="navBrand">
43 <a class="navbar-brand" href="{{ pathFor 'home' }}">FreeMove</a>
44</template>
45
46<template name='navItems'>
47 <li class="{{ activeIfTemplateIs 'home' }}">
48
<a href="{{ pathFor 'home'}}">Home</a>
49 </li>
50 <li class="{{ activeIfTemplateIs 'map' }}">
51
<a href="{{pathFor 'map'}}">Visualize data</a>
52 </li>
53 <li class="{{ activeIfTemplateIs 'data' }}">
54
<a href="{{pathFor 'data'}}">Manage data</a>
55 </li>
56</template>
map.html
1<template name="map">
2
<div id="map-info">
3
<p><em>Adjust which layers are visible using the tool in the
top right corner of the map widget.</em></p>
4
</div>
5
<div id="map-canvas"></div>
6</template>
Client: JavaScript
home.js
1 var first = true;
2
3 Template.data.rendered = function () {
4
// Check for the various File API support.
5
if (window.File && window.FileReader && window.FileList &&
window.Blob) {
6
// Great success! All the File APIs are supported.
7
toastr.info('Your browser supports the HTML5 File APIs.', 'Good
stuff');
8
} else {
9
toastr.error('Your browser does not support the HTML5 File APIs.',
'Oh no');
10
}
11
12
// Listen for files dropped to upload
76
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
var dropZone = document.getElementById('dropbox');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFiles, false);
}
Template.home.rendered = function () {
if (first){
var displayed_in = false;
var displayed_none = false;
first = false;
}
Deps.autorun(function () {
if (Meteor.user() && !displayed_in){
toastr.clear();
toastr.success("You have signed in succesfully.", "Hello.");
displayed_in = true;
displayed_none = false;
} else if (!displayed_none) {
toastr.clear();
toastr.info("No one is currently logged in.", "");
displayed_none = true;
displayed_in = false;
}
});
}
// Read in a new file
function newRead(text, set) {
var lines;
// Check whether the data is generated by logger
// (and therefore split by new lines) or by the
// Trintel portal (and therefore split using ;s)
var dataType = text.indexOf(";");
if (dataType == -1) {
lines = text.split("\n");
} else {
lines = text.split(";");
}
// Previous coordinate
var prev_lat = 0.0;
var prev_lng = 0.0;
// Section starting point
var start_lat = 0.0;
var start_lng = 0.0;
// Section points
var sec_lats = [];
var sec_lngs = [];
// Current section ID
var current_sec_ID = 0;
// Amount of generated sections, from current file
var sec_count = 0;
var ccc = 0;
// Read in each line of the current file
_.each(lines, function(line) {
var split_line = line.split("|");
// Time format: hhmmss
var time = parseFloat(split_line[3]);
var timeslot;
// Between 06h00 and 12h00
77
74
if (time >= 6000000 && time < 12000000) {
75
timeslot = 'A';
76
}
77
// Between 12h00 and 18h00
78
if (time >= 12000000 && time < 18000000) {
79
timeslot = 'B';
80
}
81
// Between 18h00 and 06h00
82
else {
83
timeslot = 'C';
84
}
85
86
// Generate lat and lng values
87
var lat = parseFloat(split_line[0]) / 1000000;
88
var lng = parseFloat(split_line[1]) / 1000000;
89
90
// Read random ID for coordinate
91
var randnum = parseFloat(split_line[4]);
92
93
// Check if coordinate has been added before
94
var checker = Coordinates.findOne({ lat: lat, lng: lng, randnum:
randnum});
95
96
ccc += 1;
97
98
// Check that latitude and longitude are numbers
99
if (!isNaN(lat) && !isNaN(lng) && !checker) {
100
//console.log("Working");
101
// Compare distance to previous section start
102
var sec_dist = distToPrev(lat, lng, start_lat, start_lng);
103
sec_dist = Math.abs(sec_dist);
104
105
// Point not in a previously generated section
106
if (sec_dist > 20) {
107
// If not first section for file, finalise previous
section first
108
if (sec_count > 0) {
109
// Calculate average section line by using least
squares method
110
111
// Declare some variables
112
var lat_sum = 0;
113
var lng_sum = 0;
114
var lat_mean = 0;
115
var lng_mean = 0;
116
var lat_sqrd = 0;
117
var pair_sqrd = 0;
118
119
for (var i = 0; i < sec_lats.length; i++) {
120
// Calculate the lat and lng sums
121
lat_sum += sec_lats[i];
122
lng_sum += sec_lngs[i];
123
124
// Calculate the sum of each pair multiplied
125
pair_sqrd += sec_lats[i] * sec_lngs[i];
126
127
// Calculate the sum of lats squared
128
lat_sqrd += sec_lats[i] * sec_lats[i];
129
}
130
131
// Calculate latitude and longitude means
78
132
lat_mean = lat_sum / sec_lats.length;
133
lng_mean = lng_sum / sec_lngs.length;
134
135
// Calculate the slope, m
136
var m = (pair_sqrd - (lat_sum * lng_sum /
sec_lats.length)) / (lat_sqrd - (lat_sum * lat_sum / sec_lngs.length));
137
138
// Calculate b = y_mean - m*x_mean
139
var b = lng_mean - (m * lat_mean);
140
141
// Form new line with lng = m*lat + b
142
var s_lng = m*sec_lats[0] + b;
143
var f_lng = m*sec_lats[sec_lats.length - 1] + b;
144
145
// Create start, end and centre points
146
var start_obj = {
147
lat: sec_lats[0],
148
lng: s_lng
149
};
150
var finish_obj = {
151
lat: sec_lats[sec_lats.length - 1],
152
lng: f_lng
153
};
154
var segment_centre = {
155
lat: (start_obj.lat + finish_obj.lat)/2,
156
lng: (start_obj.lng + finish_obj.lng)/2
157
}
158
159
160
161
// Calculate length of new line
162
var line_length = distToPrev(start_obj.lat,
start_obj.lng, finish_obj.lat, finish_obj.lng);
163
164
// See if in another section's bounds
165
var in_bounds = false;
166
var intersections = 0;
167
var secs = Sections.find().fetch();
168
_.each(secs, function(section) {
169
// Check whether the section is within reach
before doing any calculations
170
var dist_to_centre =
Math.abs(distToPrev(section.bounds.centre.lat, section.bounds.centre.lng,
segment_centre.lat, segment_centre.lng));
171
if(dist_to_centre < 22) {
172
//Find the four lines that define the
bounding box
173
//Source:
http://mathforum.org/library/drmath/view/53254.html
174
//For each of these lines:
175
//1. Get y = m2x + b2
176
//2. Subtract from current line to find
intersection x (latitude):
177
//
y - y = (m1 - m2)x + (b1 - b2)
178
//
0 = (m1-m2)x + (b1-b2)
179
//
x = -(b1-b2)/(m1-m2)
180
//3. Get intersection y (longitude): y =
mx+b
181
//4. See if point (x,y) is on the line
section
79
182
//
i.e. is start.lat < intersect_lat <
end.lat ?
183
//5. Set in_bounds appropriately
184
185
// Get the four latlng intersections
186
var lat_short0 = -(b - section.short_bb.b0)
/ (m - section.short_bb.m);
187
var lat_short1 = -(b - section.short_bb.b1)
/ (m - section.short_bb.m);
188
var lat_long0 = -(b - section.long_bb.b0) /
(m - section.long_bb.m);
189
var lat_long1 = -(b - section.long_bb.b1) /
(m - section.long_bb.m);
190
191
var lng_short0 = m * lat_short0 + b;
192
var lng_short1 = m * lat_short1 + b;
193
var lng_long0 = m * lat_long0 + b;
194
var lng_long1 = m * lat_long1 + b;
195
196
// Use the orientation method to determine
if intersections occur
197
// Source for algorithm:
http://www.dcs.gla.ac.uk/~pat/52233/slides/Geometry1x1.pdf
198
var hit;
199
var inters = [];
200
201
// Check short 0
202
hit = checkIntersection(start_obj,
finish_obj, section.bounds.cnr1, section.bounds.cnr2);
203
if (hit) {
204
var temp_obj = {
205
lat: lat_short0,
206
lng: lng_short0
207
};
208
inters.push(temp_obj);
209
210
}
211
212
// Check short 1
213
hit = checkIntersection(start_obj,
finish_obj, section.bounds.cnr3, section.bounds.cnr4);
214
if (hit) {
215
var temp_obj = {
216
lat: lat_short1,
217
lng: lng_short1
218
};
219
inters.push(temp_obj);
220
}
221
222
// Check long 0
223
hit = checkIntersection(start_obj,
finish_obj, section.bounds.cnr1, section.bounds.cnr3);
224
if (hit) {
225
var temp_obj = {
226
lat: lat_long0,
227
lng: lng_long0
228
};
229
inters.push(temp_obj);
230
}
231
232
// Check long 1
80
233
hit = checkIntersection(start_obj,
finish_obj, section.bounds.cnr2, section.bounds.cnr4);
234
if (hit) {
235
var temp_obj = {
236
lat: lat_long1,
237
lng: lng_long1
238
};
239
inters.push(temp_obj);
240
}
241
242
// If a section was intersected
243
if(inters[0]) {
244
var temp_seg;
245
in_bounds = true;
246
// If the line runs through a section
247
if (inters.length > 1){
248
temp_seg = {
249
start:
{
250
lat:
inters[0].lat,
251
lng:
inters[0].lng
252
},
253
finish:
{
254
lat:
inters[1].lat,
255
lng:
inters[1].lng
256
}
257
}
258
}
259
// If the line only intersects section
once
260
else {
261
262
var distFromStart =
distToPrev(start_obj.lat, start_obj.lng, section.bounds.centre.lat,
section.bounds.centre.lng);
263
var distFromFinish =
distToPrev(finish_obj.lat, finish_obj.lng, section.bounds.centre.lat,
section.bounds.centre.lng);
264
if (distFromStart < distFromFinish)
{
265
266
temp_seg = {
267
start:
{
268
lat:
inters[0].lat,
269
lng:
inters[0].lng
270
},
271
finish:
{
272
lat:
start_obj.lat,
273
lng:
start_obj.lng
274
}
275
}
276
277
} else {
278
81
279
temp_seg = {
280
start:
{
281
lat:
inters[0].lat,
282
lng:
inters[0].lng
283
},
284
finish:
{
285
lat:
finish_obj.lat,
286
lng:
finish_obj.lng
287
}
288
}
289
290
}
291
}
292
293
// Calculate ratio of segment in section
294
var ratio =
distToPrev(temp_seg.start.lat, temp_seg.start.lng, temp_seg.finish.lat,
temp_seg.finish.lng) /
295
distToPrev(start_obj.lat,
start_obj.lng, finish_obj.lat, finish_obj.lng);
296
297
// Adjust section average position and
count according to ratio
298
var temp_section = {
299
start:
section.start,
300
finish:
section.finish
301
}
302
var new_pos = calcNewPos(ratio,
section.count, temp_seg, temp_section);
303
Sections.update(
{_id: section._id},
304
{ $set: {start:
new_pos.start, finish: new_pos.finish, count: section.count+ratio}});
305
306
// Reset the lats array
307
sec_lats = [];
308
sec_lngs = [];
309
310
}
311
}
312
})
313
// Intersects a previous section area
314
if (in_bounds) {}
315
//Does not intersect previous section sufficiently
316
else {
317
// Calculate bounding box
318
var new_bb = generateBB(start_obj, finish_obj,
m);
319
320
// Create sections object
321
var section_obj = {
322
sec_ID: current_sec_ID,
323
start: start_obj,
324
finish: finish_obj,
325
bounds: new_bb.bb_obj,
326
short_bb: new_bb.short_obj,
82
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
knots
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
long_bb: new_bb.long_obj,
count: 1
};
// Update sections database
Sections.insert(section_obj);
// Reset the lats array
sec_lats = [];
sec_lngs = [];
}
}
// Set start of section
start_lat = lat;
start_lng = lng;
// Update section points
sec_lats.push(lat);
sec_lngs.push(lng);
if (sec_count == 0) {
// Generate section ID
var section_check = Sections.findOne({});
if(section_check){
current_sec_ID = section_check.sec_ID + 1;
} else {
current_sec_ID = 1;
}
} else {
current_sec_ID += 1;
}
// Create coordinate object
var coord_obj = {
timeslot:
timeslot,
lat:
lat,
lon:
lng,
speed:
parseFloat(split_line[2]), // unit:
type:
set:
section:
randnum:
"A",
set,
current_sec_ID,
randnum
}
// Push coordinate obj to database
Coordinates.insert(coord_obj);
// Update sections counter
sec_count += 1;
}
// Point in the previously generated section
else {
// Update section points
sec_lats.push(lat);
sec_lngs.push(lng);
// Create coordinate object
83
387
var coord_obj = {
388
timeslot:
timeslot,
389
lat:
lat,
390
lon:
lng,
391
speed:
parseFloat(split_line[2]), // unit:
knots
392
type:
"A",
393
set:
set,
394
section:
current_sec_ID,
395
randnum:
randnum
396
}
397
398
// Push coordinate obj to database
399
Coordinates.insert(coord_obj);
400
}
401
}
402
});
403}
404
405// Calculates the new avergae position of a section
406function calcNewPos(ratio, count, segment, section) {
407
var new_start = {
408
lat:
((segment.start.lat*ratio)+(section.start.lat*count))/(ratio+count),
409
lng:
((segment.start.lng*ratio)+(section.start.lng*count))/(ratio+count)
410
}
411
412
var new_finish = {
413
lat:
((segment.finish.lat*ratio)+(section.finish.lat*count))/(ratio+count),
414
lng:
((segment.finish.lng*ratio)+(section.finish.lng*count))/(ratio+count)
415
}
416
417
var new_pos = {
418
start: new_start,
419
finish: new_finish
420
}
421
return new_pos;
422}
423
424// Checks whether lines, defined by 2x start and end points, intersect
425// Uses getOrientation
426// Returns boolean result
427function checkIntersection(p1, p2, p3, p4){
428
var dir1 = getOrientation(p1, p2, p3);
429
var dir2 = getOrientation(p1, p2, p4);
430
var dir3 = getOrientation(p3, p4, p1);
431
var dir4 = getOrientation(p3, p4, p2);
432
433
if (dir1 != dir2 && dir3 != dir4){
434
return true;
435
} else {
436
return false;
437
}
438}
439
440// Calculate the orientation of line segment defined by 3 points
441// Return:
442// 0 - points are colinear
84
443// 1 - counterclockwise
444// 2 - clockwise
445function getOrientation (p1, p2, p3) {
446
var val = (p2.lng - p1.lng) * (p3.lat - p2.lat) 447
(p2.lat - p1.lat) * (p3.lng - p2.lng);
448
if (val == 0) {
449
return 0;
450
} else if (val > 0){
451
return 1;
452
} else {
453
return 2;
454
}
455}
456
457// Generate the bounding box for a given line
458function generateBB(start_obj, finish_obj, m) {
459
// Calculate bounding box
460
// Perpendicular line: y = (-1/m)x + b
461
/* (lat1,lng1) |-----------------------| (lat3,lng3)
462
|
|
463
|-----------------------|
464
|
|
465
(lat2,lng2) |-----------------------| (lat4, lng4)
466
*/
467
// Formula: x1 = x0 + D/sqrt(1+m1^2), with m1 = -1/m
468
469
// Calculate the four corners
470
var m1 = -1/m; // Slope for normal line
471
var b0 = start_obj.lng - (start_obj.lat * m1); // Y-intercept for
normal line
472
var b1 = finish_obj.lng - (finish_obj.lat * m1); // Y-intercept for
normal line
473
var d = 0.000035 // Approximately 1.5m on either side of line
474
// Corner 1
475
var lat1 = start_obj.lat + ( d / Math.sqrt( 1+(m1 * m1) ) );
476
var lng1 = (m1 * lat1) + b0;
477
var cnr1 = {
478
lat: lat1,
479
lng: lng1
480
}
481
// Corner 2
482
var lat2 = start_obj.lat - ( d / Math.sqrt( 1+(m1 * m1) ) );
483
var lng2 = (m1 * lat2) + b0;
484
var cnr2 = {
485
lat: lat2,
486
lng: lng2
487
}
488
// Corner 3
489
var lat3 = finish_obj.lat + ( d / Math.sqrt( 1+(m1 * m1) ) );
490
var lng3 = (m1 * lat3) + b1;
491
var cnr3 = {
492
lat: lat3,
493
lng: lng3
494
}
495
// Corner 4
496
var lat4 = finish_obj.lat - ( d / Math.sqrt( 1+(m1 * m1) ) );
497
var lng4 = (m1 * lat4) + b1;
498
var cnr4 = {
499
lat: lat4,
500
lng: lng4
501
}
85
502
503
// Centre point
504
var clat = (lat1 + lat2 + lat3 + lat4) / 4;
505
var clng = (lng1 + lng2 + lng3 + lng4) / 4;
506
var centre = {
507
lat: clat,
508
lng: clng
509
}
510
511
// Generate the bounding box object
512
var bb_obj = {
513
cnr1: cnr1,
514
cnr2: cnr2,
515
cnr3: cnr3,
516
cnr4: cnr4,
517
centre: centre
518
}
519
520
// Store line attributes for later use
521
var short_obj = {
522
m: m1,
523
b0 : b0,
524
b1 : b1
525
}
526
var long_b0 = cnr1.lng - (m*cnr1.lat); // b = y-mx
527
var long_b1 = cnr2.lng - (m*cnr2.lat); // b = y-mx
528
var long_obj = {
529
m: m,
530
b0 : long_b0,
531
b1 : long_b1
532
}
533
534
//return bb_obj, short_obj, long_obj;
535
return {
536
bb_obj: bb_obj,
537
short_obj: short_obj,
538
long_obj: long_obj
539
};
540}
541
542// Converts GPS data points to decimal coordinates
543// Decimal value = Degrees + (Minutes/60) + (Seconds/3600)
544function convertToDecimal(val, latlng, dir) {
545
var dec_result = 0;
546
if (latlng == "lat"){
547
dec_result += parseFloat(val.substring(0,2));
548
dec_result += parseFloat(val.substring(2)) / 60;
549
if (dir == "S"){
550
dec_result *= -1.0;
551
}
552
}
553
else if (latlng == "lng"){
554
dec_result += parseFloat(val.substring(0,3));
555
dec_result += parseFloat(val.substring(3)) / 60;
556
if (dir == "W"){
557
dec_result *= -1.0;
558
}
559
}
560
return dec_result;
561}
562
86
563// Calculates the distance between the previous coordinate and the new
one
564// for the purpose of a "Trackpoint Distance Threshold" filter
565function distToPrev(lat1, lng1, lat2, lng2) {
566
// Using the Haversine formula
567
// a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
568
// c = 2 ⋅ atan2( √a, √(1−a) )
569
// d = R ⋅ c
570
// Credits: http://www.movable-type.co.uk/scripts/latlong.html
571
var R = 6371000; // metres
572
var radlat1 = degToRad(lat1);
573
var radlat2 = degToRad(lat2);
574
var deltaLat = degToRad(lat2 - lat1);
575
var deltaLng = degToRad(lng2 - lng1);
576
577
var a = (Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2))
578
+ ( (Math.cos(radlat1) * Math.cos(radlat2))
579
* (Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2)) );
580
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
581
var d = R * c;
582
583
return d;
584}
585
586// Converts degrees to radians
587function degToRad(degrees) {
588
return (degrees * Math.PI / 180);
589}
590
591// Handles file upload
592function handleFiles(e) {
593
e.stopPropagation();
594
e.preventDefault();
595
596
var files = e.dataTransfer.files;
597
598
var output = [];
599
var set = 0;
600
601
for (var i = 0, f; f = files[i]; i++) {
602
var reader = new FileReader();
603
reader.onload = function(e) {
604
var text = reader.result;
605
newRead(text, set);
606
set += 1;
607
}
608
609
reader.readAsText(f);
610
}
611
612
toastr.info("Coordinates succesfully added to the database.",
"Done")
613}
614
615function handleDragOver(e) {
616
e.stopPropagation();
617
e.preventDefault();
618
e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a
copy.
619 }
620
87
621// Set sign up field to only ask for username
622Accounts.ui.config({
623
passwordSignupFields: 'USERNAME_ONLY'
624});
map.js
1 //Only run function once "map" template has finished rendering
2 //in order to avoid errors
3 Template.map.rendered = function() {
4
// Draw each section
5
//Initialise the map according to OSM_maps.js in lib
6
osm_maps.initialise();
7
8
//Run the following when the Sections Meteor collection changes
9
//i.e. new coordinates inserted or old ones removed
10
Deps.autorun(function() {
11
var secs = Sections.find().fetch();
12
var latlngs = [];
13
//Check that collection is not empty
14
if (secs) {
15
// Temporarily set the type to "A"
16
var t = "A";
17
var heat = 0;
18
//For each section, add the line to the map
19
_.each(secs, function(section) {
20
// console.log(section);
21
latlngs = [];
22
23
if (typeof section.start !== 'undefined' &&
24
typeof section.finish !== 'undefined') {
25
// Add section start and end to coordinate
data
26
latlngs.push(new L.LatLng(section.start.lat,
section.start.lng));
27
latlngs.push(new L.LatLng(section.finish.lat,
section.finish.lng));
28
29
// Set user type
30
var type = "A";
31
32
// Generate heat rankings
33
var heat = 0;
34
if (section.count > 1000) {
35
heat = 9;
36
} else if (section.count > 500) {
37
heat = 8;
38
} else if (section.count > 250) {
39
heat = 7;
40
} else if (section.count > 100) {
41
heat = 6;
42
} else if (section.count > 50) {
43
heat = 5;
44
} else if (section.count > 25) {
45
heat = 4;
46
} else if (section.count > 10) {
47
heat = 3;
48
} else if (section.count > 1) {
49
heat = 2;
50
} else {
51
heat = 1;
88
52
53
54
55
56
57
58
59
60
61
62
63
type = "C";
}
// Generate a line from the section data
osm_maps.addLine(latlngs, type, heat);
}
});
}
});
nav.js
1// Helper for navigation bar
2Template.navItems.helpers({
3
activeIfTemplateIs: function (template) {
4
var currentRoute = Router.current();
5
return currentRoute &&
6
template === currentRoute.lookupTemplate() ? 'active' : '';
7
}
8 });
Client: CSS
styles.css
#map-canvas {
width: 100%;
height: 600px;
}
#map-info {
word-spacing:2pt;
font-size:12px;
text-align:center;
font-family:arial black, sans-serif;
}
#dropbox {
width: 350px;
height: 60px;
border: 4px dashed #B0B0B0;
margin-left: auto;
margin-right: auto;
font-weight:bold;
color:#B0B0B0;
letter-spacing:1pt;
word-spacing:2pt;
font-size:20px;
text-align:center;
font-family:arial black, sans-serif;
line-height:1;
}
Lib: JavaScript
OSM_maps.js
1
2
osm_maps = {
map: null,
89
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
A: null,
B: null,
C: null,
//Add the line to the appropriate map layer, based on type
addLine : function (latlngs, type, heat) {
var c;
switch (heat) {
case 1:
c = 'Aqua';
break;
case 2:
c = 'DeepSkyBlue';
break;
case 3:
c = 'Teal';
break;
case 4:
c = 'Blue';
break;
case 5:
c = 'MediumBlue';
break;
case 6:
c = 'DarkBlue';
break;
case 7:
c = 'Navy';
break;
case 8:
c = 'MidnightBlue';
break;
case 9:
c = 'Black';
break;
}
switch (type) {
case 'A':
var polyline = L.polyline(latlngs, {
color: c,
weight: heat
});
this.A.addLayer(polyline);
break;
case 'B':
var polyline = L.polyline(latlngs, {
color: 'red',
weight: 2
});
this.B.addLayer(polyline);
break;
case 'C':
var polyline = L.polyline(latlngs, {
color: 'yellow',
weight: 2
});
this.C.addLayer(polyline);
break;
}
},
90
64
65
// Adds a polygon to the map
66
addPolygon : function(latlngs) {
67
var polygon = L.polygon(latlngs).addTo(this.map);
68
},
69
70
// Adds a marker to the map
71
addMarker : function(latlng, t) {
72
//var marker = L.marker(latlng).addTo(this.map);
73
if (t == "A"){
74
var circle = L.circle(latlng, 0.1, {
75
color: 'red',
76
fillColor: '#f03',
77
fillOpacity: 0.5
78
}).addTo(this.map);
79
} else {
80
var circle = L.circle(latlng, 0.1, {
81
color: 'red',
82
fillColor: '#f03',
83
fillOpacity: 0.7
84
}).addTo(this.map);
85
}
86
},
87
88
//Initialise the map, centered on the student part of Stellenbosch,
and add the appropriate
89
//layers
90
initialise : function () {
91
console.log("Initialising the map...");
92
var cloudmadeUrl =
'http://{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg';
93
var subDomains = ['otile1','otile2','otile3','otile4'];
94
var cloudmadeAttrib = 'Data, imagery and map information provided
by <a href="http://open.mapquest.co.uk" target="_blank">MapQuest</a>, <a
href="http://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> and
contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/"
target="_blank">CC-BY-SA</a>';
95
var cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18,
attribution: cloudmadeAttrib, subdomains: subDomains});
96
97
var dagbreek = new L.LatLng(-33.932607, 18.868643);
98
99
var A = L.layerGroup(); //Wheelchair user
100
this.A = A;
101
var B = L.layerGroup(); //Sight disabled
102
this.B = B;
103
var C = L.layerGroup(); //Singular traffic section
104
this.C = C;
105
106
this.map = new L.Map('map-canvas', {center: dagbreek, zoom: 14,
layers : [cloudmade, this.A, this.B, this.C]});
107
108
//Add map controller
109
//Reference: http://leafletjs.com/examples/layers-control.html
110
var baseMaps = {
111
"Open Street Maps": cloudmade
112
};
113
var overlayMaps = {
114
"Wheelchair users" : this.A,
115
"Sight disabled" : this.B,
116
"Routes only used once" : this.C
91
117
118
119
120}
};
L.control.layers(baseMaps, overlayMaps).addTo(this.map);
}
router.js
1 Router.configure({
2
layoutTemplate: 'layout' //can be any template name
3 });
4
5 Router.map(function () {
6
this.route('home', {
7
path: '/',
8
waitOn: function () {return Meteor.subscribe('all_coords')},
9
data: function () {
10
return {
11
loggedIn: Meteor.user()
12
};
13
}
14
});
15
16
this.route('map', {
17
onBeforeAction: function() {
18
if(!Meteor.loggingIn() && !Meteor.user()) {
19
toastr.error('You need to log in to see this.', 'Oh no!')
20
this.redirect('home');
21
}
22
},
23
waitOn: function () {return Meteor.subscribe('all_coords')},
24
data: function () {
25
var coords = Coordinates.find({}).fetch();
26
return {
27
coords : coords
28
};
29
}
30
});
31
32
this.route('data', {
33
onBeforeAction: function() {
34
if(!Meteor.loggingIn() && !Meteor.user()) {
35
toastr.error('You need to log in to see this.', 'Oh no!')
36
this.redirect('home');
37
}
38
},
39
waitOn: function () {return Meteor.subscribe('all_coords')}
40
})
41
42})
schema.js
1// _id, type, lat, lon, time, set
2Coordinates = new Meteor.Collection("coordinates");
3// _id, sec_ID, start (lat, lng), finish (lat, lng), centre(lat, lng),
4// bounds (cnr1-4(lat, lng)), short_bb, long_bb, lat_min, lat_max,
5// lng_min, lng_max, count
6Sections = new Meteor.Collection("sections");
7// Temporary storage for all the intersections
8Intersecs = new Meteor.Collection("intersecs");
92
Server: JavaScript
dummy.js
1 var dummy_coords = [
2
{type: 'A', lat: -33.932536, lon: 18.868616, set: 1},
3
{type: 'A', lat: -33.932604, lon: 18.867879, set: 1},
4
{type: 'A', lat: -33.931161, lon: 18.867707, set: 1},
5
{type: 'A', lat: -33.932336, lon: 18.858781, set: 1}
6 ];
7
8 Meteor.methods({
9
//Adds the above defined data to the collection
10
loadDummyData: function () {
11
dummy_coords.forEach(function (dummy_coord) {
12
Coordinates.insert(dummy_coord);
13
console.log("Added the dummy coordinates.");
14
});
15
},
16
//Clears the database
17
DBclear: function () {
18
Coordinates.remove({});
19
Sections.remove({});
20
Intersecs.remove({});
21
console.log("Cleared the database.");
22
},
23
// Returns the coordinates in the data store
24
COORDshow: function () {
25
console.log(Coordinates.find({}).fetch());
26
},
27
// Returns the sections in the data store
28
SECshow: function () {
29
console.log(Sections.find({}).fetch());
30
}
31});
server.js
1Meteor.publish('all_coords', function () {
2
return Coordinates.find({});
3});
93