May 27 2007

Python gpsd bindings

Published by perrygeo at 11:31 am under Python

If you want to get a linux/unix machine talking to your GPS unit, most likely you’ll be using gpsd. There are many great apps that build off of gpsd such as kismet and gpsdrive.

Installing gpsd on debian/ubuntu systems is as simple as

sudo apt-get install gpsd gpsd-clients

You should be able to connect your gps via serial port and start a gpsd server

sudo gpsd /dev/ttyS0

The gpsd server reads NMEA sentences from the gps unit and is accessed on port 2947. You can test if everything is working by running a pre-built gpsd client such as xgps.

This is very useful for situations where you need lower-level access to the gps data; for logging your position to a postgres database for example. The debian packages (and most others I’m assuming) come with gps.py, a python interface to gpsd allowing you to pull your lat/long from the gps in real time. This opens the door for all sorts of neat real-time gps apps.

import gps, os, time

session = gps.gps()

while 1:
    os.system('clear')
    session.query('admosy')
    # a = altitude, d = date/time, m=mode,
    # o=postion/fix, s=status, y=satellites

    print
    print ' GPS reading'
    print '----------------------------------------'
    print 'latitude    ' , session.fix.latitude
    print 'longitude   ' , session.fix.longitude
    print 'time utc    ' , session.utc, session.fix.time
    print 'altitude    ' , session.fix.altitude
    print 'eph         ' , session.fix.eph
    print 'epv         ' , session.fix.epv
    print 'ept         ' , session.fix.ept
    print 'speed       ' , session.fix.speed
    print 'climb       ' , session.fix.climb

    print
    print ' Satellites (total of', len(session.satellites) , ' in view)'
    for i in session.satellites:
        print '\t', i

    time.sleep(3)

… which gives you a simple readout to the terminal every 3 seconds.

Obviously there are much more interesting applications for this ( logging data to postgis, displaying real-time tracking data in QGIS via a python plugin, etc). But this is a good start for any python based app.

13 Responses to “Python gpsd bindings”

  1. dylanon 27 May 2007 at 7:15 pm

    Hi Matt, nice article! Here is a way to get differential corection on-the-fly to a gpsd application.

    1. Get and install dgpsip

    2. attach gps, set IO to RTCM/NMEA

    3. start gpsd

    4. run dgpsip: sudo dgpsip -o /dev/ttyS0 -s 9600 -v 2

    5. ???

    6. i noticed that my garmin GPS12 shows a “3D DIFF” message about 5 seconds after dgpsip has been started, and the EPE goes down to about 3 meters. I find that averaging waypoint locations gets the accuracy down to about 2.7 meters!! not bad for a GPS from 2000, and an old laptop with a wireless card. This only really works if you have an internet connection.

    Apparently it is also possible to differentially correct data from a garmin using some tools. Haven’t tried this yet. If it works it would be a heck of a lot simpler than using our trimble and their crappy software.

    Cheers,

    Dylan

  2. serial porton 14 Aug 2007 at 6:45 am

    great article, I love your style. All the best green this commentary comes out of England.

  3. Ronald Lon 09 Sep 2007 at 1:27 am

    Hi Matt, I’m new to Linux and trying to learn how I can interface my notebook (running Mepis Linux), my Holux GR-213 USB GPS and Google Earth to give me real-time posits while mobile.
    Running XP, I interfaced the three with Earthbridge and it worked fine. I plugged in by GPS, fired up Earthbridge to get the satellite fixes and then started Google Earth to get plots on GE’s maps.
    What is your recommendation for a newbie to do the same using Linux? How do I get gpsd to I/F with GE? Would I be better off using another program that has a GUI that would be easier for me to use?

    Thanks much,

    Ron
    Izmir, Turkey

  4. harry hobsonon 29 Jun 2008 at 11:40 pm

    Hi, We are using gps.py to test some rail road signals We would like to know what session.fix.speed is out putting; miles, kilometers or knots per hour? NMEA uses knots, but I noticed that the positioning is not standard NMEA. Thanks! Harry

  5. perrygeoon 09 Jul 2008 at 10:41 am

    @harry

    Not sure what the units are on session.fix.speed… it’s been a while since I read up on it. I’m sure its in the gpsd docs somewhere.

  6. bilouroon 12 Jul 2008 at 2:49 pm

    Hi Matt,
    So, I’m Brazilian and here is so difficult to see gps oem hardwares.

    So, do you suggest any hardware to use at freebsd(preferred) or linux with less work as possible?

    thanks in advance!

    Bilouro

  7. Niklason 22 Sep 2008 at 10:31 am

    Thanks for this nice example, however I have a problem running your code, when trying to execute it on Ubuntu 8.10 Python Version 2.5.2 I only get

    Traceback (most recent call last):
    File “./gps.py”, line 2, in
    import gps, os, time
    File “/home/niklas/maps/gps.py”, line 4, in
    session = gps.gps()
    TypeError: ‘module’ object is not callable

  8. Michael Matheron 27 Nov 2008 at 3:18 pm

    session.fix.speed looks like metres per second.

  9. speak to gpsd with python « My Blogon 31 Jan 2009 at 8:39 am

    […] to gpsd with python simple class to interface with gpsd: outch!: perhaps this is a better […]

  10. daveon 28 Apr 2009 at 12:12 pm

    @Niklas I know it’s late, but in case other people run into this page and are having the same problem:

    Make sure you have the gps.py file that is distributed from your version of gpsd. You can download the full tarball from http://gpsd.berlios.de/ Simply copy gpsd.py to your working directory, and re-run the script.

    cheers!

  11. djeimson 04 May 2009 at 11:02 pm

    @Niklas
    Change the name of the file you’ve saved it to. It’s trying to import itself.

  12. Jenson 30 Nov 2009 at 10:59 am

    Hi there,
    thanks a lot for your PYTHON/GPSD tutorial !

    I am a beginner to Python and need to count the number of sattelites used.
    Therefore, I would like to read out the last character of each “session.satellites[n]” line, which is either “y” or “n”.

    s = session.satellites[i] # where i is the actual number of the satellite
    print s[-1] # this should give me the first sign from the right = last sign of string, which is either y or n

    The example above does not work, I get the following error:

    AttributeError: satellite instance has no attribute ‘__getitem__’

    As I understand it, it must be some mistake related to object-oriented programming, which I haven’t learned yet.

    Could you please help me ?
    Thanks a lot in advance,
    Jens

  13. Jenson 01 Feb 2010 at 6:50 am

    ROFL !
    I just found it out all by myself…

    It just has to be

    s = str(session.satellites[i])

    and then

    print s[-1]

    works as intended and gives me either “y” or “n”.

    I did not expect it to be THAT simple !
    Now I feel a little bit ashamed… *smile*

Trackback URI | Comments RSS

Leave a Reply