Basic Installation

  • sudo apt-get gpsd gpsd_tools python-gps
  • Edit /etc/default/gpsd and add the GPS device into the boot configuration of gpsd
  • Reboot or restart the GPS daemon gpsd.
  • Try these various tests to make sure it’s working.

Python Script

I’ve written an extension of an Adafruit python script which captures GPS data and writes it to screen and file:

from __future__ import division
import gps
import os
import math

# Listen on port 2947 (gpsd) of localhost
session = gps.gps("localhost", "2947") | gps.WATCH_NEWSTYLE)

num_sats = 0
latitude = 0.0
longitude = 0.0
time = ""
epx = 0.0
epy = 0.0
epv = 0.0
ept = 0.0
eps = 0.0
climb = 0.0
altitude = 0.0
speed = 0.0
direction = 0.0

lat1 = 0.0
lon1 = 0.0

R = 6371000 # radius of the earth in meters

fp_name = "gpstrack.csv"
header = "time, latitude, longitude, satellites, climb, altitude, speed, direction, dx, dy"


print header

with open(fp_name, "wb") as fp:
    fp.write(header + "\n")

    # With a based level longitude and latitude in degrees, we can be the current X and Y coordinates
    # relative to the takeoff position thus:
    # psi = longitude => p below
    # lambda = latitude => l below
    # Using equirectangular approximation: 
    # x = (l2 - l1) * cos ((p1 + p2) / 2)
    # y = (p2 - p1)
    # d = R * ((x*x + y*y) ^ 0.5)
    # More at

    while True:
            report =
#            print report
#            os.system("clear")
            if report['class'] == 'TPV':
                if hasattr(report, 'time'):  # Time 
                    time = report.time
                if hasattr(report, 'ept'):   # Estimated timestamp error - seconds 
                    ept = report.ept

                if hasattr(report, 'lon'):   # Longitude in degrees
                    longitude = report.lon
                if hasattr(report, 'epx'):   # Estimated longitude error - meters 
                    epx = report.epx

                if hasattr(report, 'lat'):   # Latitude in degrees
                    latitude =
                if hasattr(report, 'epy'):   # Estimated latitude error - meters 
                    epy = report.epy

                if hasattr(report, 'alt'):   # Altitude - meters
                    altitude = report.alt
                if hasattr(report, 'epv'):   # Estimated altitude error - meters
                    epv = report.epv

                if hasattr(report, 'track'): # Direction - degrees from true north
                    direction = report.track     
                if hasattr(report, 'epd'):   # Estimated direction error - degrees 
                    epd = report.epd

                if hasattr(report, 'climb'): # Climb velocity - meters per second
                    climb = report.climb
                if hasattr(report, 'epc'):   # Estimated climb error - meters per seconds
                    epc = report.epc

                if hasattr(report, 'speed'): # Speed over ground - meters per second
                    speed = report.speed     
                if hasattr(report, 'eps'):   # Estimated speed error - meters per second
                    eps = report.eps

            if report['class'] == 'SKY':
                if hasattr(report, 'satellites'):
                    num_sats = 0
                    for satellite in report.satellites:
                        if hasattr(satellite, 'used') and satellite.used:
                            num_sats += 1

            # Calculate the X,Y coordinates in meters
            lat2 = latitude * math.pi / 180
            lon2 = longitude * math.pi / 180

            dx = (lat2 - lat1) * math.cos((lon1 + lon2) / 2) * R
            dy = (lon2 - lon1) * R
            lon1 = lon2
            lat1 = lat2

            output = "%s, %f, %f, %d, %f, %f, %f, %f, %f, %f" % (time, 

            print output
            fp.write(output + "\n")
        except KeyError:
        except KeyboardInterrupt:
        except StopIteration:
            session = None
            print "GPSD has terminated"

Here’s what I get plotting a walk around the garden carrying her – it’s not a great match.

Garden track

Garden track

0.0m is my office window.  Everything beyond is -10m, -20m is the garden;  the walk in the garden was

  • 15m SSW
  • 9m ESE
  • 18m N

That’s an approximate right angle triangle, but the scan doesn’t show that without a lot of imagination.  The scaling is right, but the direction is very noisy.  I’m not sure whether this is a code bug or just pushing the limits of GPS accuracy.  I’ll have a few more goes to see if I can get any better.  GPS samples are at roughly 1Hz.

Code update plans for Chloe

  • ultimately, that output file with be a FIFO read by Chloe’s code.  She’ll use to monitor the file contents, and sleep, whereas now she just sleeps.
  • I’ll add command line parameters –indoors or –outdoors to select the range of sensors to be used – primarily GPS; PX4FLOW / Scanse Sweep and LEDDAR will work in both environments.
  • If using the GPS, add startup code to ensure at least 4 satellites are feeding the GPS for accurate triangulation – during the walk, I had 4 indoors and 6 outdoors; obviously the more satellites, the greater the accuracy.

2 thoughts on “GPS

  1. Hello,

    Can you please explain the need of the ‘While True’ statements?
    I mean, in your code you use it in order to read forever. But if I want to get only 1 or a few reads and try to use your code without any ‘While’, I get nothing…

    In addition, if I try to run the code manually (line after line), when I look at ‘report[‘class’]’, sometimes it has ‘TPV’, sometimes it has ‘Sky’, and sometimes other stuff. Why is that?

    Thank you!

    • Hi Oded,

      I use GPS on my piDrone. Before a flight, several target GPS locations are set. During flight, GPS reports the current GPS location compared to the next target, and this defines the direction the piDrone needs to go. This happens everything 1s to make sure the piDrone is heading in the right direction. The “while True” is used to get the latest GPS location information during a flight.

      GPS sends lots of messages to the user in report[‘class’]. I need only ‘TPV’ and ‘Sky’. So the code ignores messages other than these two.

      Hope that helps,


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.