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.

21 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*

  14. Michaelon 04 Apr 2010 at 8:25 pm

    Hi there,

    I get an error when running this:

    Traceback (most recent call last):
    File “”, line 7, in
    AttributeError: gps instance has no attribute ‘query’

    Has query() been removed from gps.py?
    What needs to be done to fix the above script so it works?

    Thanks

  15. perrygeoon 04 Apr 2010 at 8:34 pm

    Micheal,
    The gpsd python bindings appear to have changed significantly. The best bet would be to introspect/experiment with the gps object with python, consult the gpsd python source or contact the gpsd developers.

  16. Michaelon 04 Apr 2010 at 11:20 pm

    Thanks for the prompt reply :) Appreciated.

  17. Mamoru Yamamotoon 30 Apr 2010 at 10:04 am

    Hi,

    Thank you for all information of gps.py.

    Though you may know very well, I found how to connect
    to the other gpsd server over network. It is just to start
    an application program by

    import gps
    session = gps.gps(host=hostname, port=’2947′)

    hostname should be text of the hostname or of the IP address.
    To connect to the local server, hostname=’localhost’.

    By copying the gps.py to my WINDOWS PC, my PC can read
    data from the LINUX gpsd server over network.
    Thanks for very easy programming with gps.py

    I have one question. Now it is announced that the gpsd
    command interface will be changed soon. What will be
    the change of the gps.py interface? Explanation of the JASON
    command interface is not very clear to me. I am sorry.
    Even some suggestions are useful. Thanks for your help.

    Mamoru Yamamoto
    Kyoto University, JAPAN

  18. perrygeoon 30 Apr 2010 at 10:19 am

    Mamoru,

    You should contact the gpsd developers list for more information .. I am not personally involved in the project so I cant answer your questions about how the interface may change.

  19. Steve Clementon 08 Jun 2010 at 2:06 pm

    Dear all,

    In case you arrived in the year 2010, things have indeed changed!

    For the good:

    eep ;
    import gps

    session = gps.gps()

    print session

    I leave it to you to “implement” the while loop and the sleep ;)

    Also I had to check some terminology on the original script:

    eph == Precision horizontal
    epv == Precision vertical
    ept == Precision total

    in case you want to use the above script, it IS possible just delete the query line:

    session.query(’admosy’)

    and amend eph to epx:

    print ‘epx ‘ , session.fix.epx

    In full:


    import gps, os, time

    session = gps.gps()

    while 1:
    os.system('clear')
    # 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 'epx ' , session.fix.epx
    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)

    Hack on!

    Steve Clemenet

  20. Gausieon 10 Jun 2010 at 7:52 am

    For some reason all my data comes out empty (i.e. longitude is 0, latitude is 0, no satellites) even though xgps tells me i’m connected perfectly.

    is there something i’m missing?

  21. anonymouson 24 Jul 2010 at 4:31 pm

    It appears that the session object has to have streaming turned on, and that it must be polled in order for it to obtain the GPS data:

    #!/usr/bin/python

    import gps, os, time

    session = gps.gps()
    session.poll()
    session.stream()

    while 1:
    os.system(’clear’)
    session.poll()
    # 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 ‘epx ‘ , session.fix.epx
    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)

Trackback URI | Comments RSS

Leave a Reply