camolas
Posts: 69
Joined: Mon Jun 17, 2013 6:58 pm

GPS not working well

Sat Jul 13, 2013 7:31 pm

Hi,

I have a usb gps receiver and i works well on PuTTY i get the data, but is not giving any data on GPSD or in a simple serial port reader code in Python. :oops:
Any ideas to solve my problem?

Thanks

ITDiscovery
Posts: 12
Joined: Tue Jul 09, 2013 6:45 pm

Re: GPS not working well

Sun Jul 14, 2013 4:24 pm

I've been working on my notes to connect a Parallax PMB-648 SiRF Module to the Raspberry Pi, and your post seems a good opportunity to put them up. If you get stuck, post your specific problem that I don't address, and I'll try to recommend something. Additionally, I am stuck at a good way to generate logs readable by Google Maps. The ultimate goal of this project is to use a USB or Pi camera to walk/ride around and have it take pictures that are geo-tagged.

Note that the XXX's in the minicom dump are redactions of the actual lat/long data.

========CHOMP==================

Connections:

Pin 1 on GPS (Yellow/TTL TX) to Pin 10 on P1 connector of RPi
Pin 2 on GPS (Blue/TTL RX) to Pin 8 on P1 connector of RPi
Pin 3 on GPS (Red/Vcc) to Pin 2 or Pin 4 on P1 connector of RPi
Pin 4 on GPS (Black/Gnd) to Pin 6 or Pin 9 on P1 connector of RPi

Disable serial port login by commenting out any line in /etc/inittab that contains "ttyAMA0".
Disable Bootup info going to the serial port by removing any argument with ttyAMA0 in /boot/cmdline.txt.
Reboot.

If you already haven't, make sure you have the most up-to-date platform:
pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get upgrade

Get the minicom terminal program:
pi@raspberrypi ~ $ sudo apt-get install mini com

pi@raspberrypi ~ $ minicom -b 4800 -o -D /dev/ttyAMA0
Welcome to minicom 2.6.1

OPTIONS: I18n
Compiled on Apr 28 2012, 19:24:31.
Port /dev/ttyAMA0

Press CTRL-A Z for help on special keys

.8,210.5,M,-23.5,M,,0000*6A
$GPGSA,A,3,05,29,25,12,02,10,21,26,15,,,,1.6,0.8,1.4*32
$GPRMC,XXXXXXXXXX.000,A,3235.8452,N,xxxxx.9157,W,0.00,122.74,100713,,,A*70
$GPGGA,xxxxxxx.000,3235.8452,N,xxxxxxx.9157,W,1,08,1.0,210.5,M,-23.5,M,,0000*61
$GPGSA,A,3,05,29,25,12,02,10,26,15,,,,,2.1,1.0,1.9*31
$GPGSV,3,1,10,05,69,049,34,25,44,252,35,29,43,320,36,02,37,059,37*78
$GPGSV,3,2,10,12,33,200,30,26,23,134,17,10,16,043,28,15,10,173,28*7F
$GPGSV,3,3,10,21,07,272,,04,06,076,*78
$GPRMC,XXXXXX.000,AXXXXX.8452,N,0XXXX.9157,W,0.00,122.74,100713,,,A*73
$GPGGA,032153.000,3235.8452,N,09717.9157,W,1,08,1.0,210.5,M,-23.5,M,,0000*60
$GPGSA,A,3,05,29,25,12,02,10,26,15,,,,,2.1,1.0,1.9*31
$GPRMC,0XXXXX.000,A,3235.8452,N,XXXXXX.9157,W,0.00,122.74,100713,,,A*72
$GPGGA,0XXXXXX.000,3235.8452,N,XXXXX.9157,W,1,08,1.0,210.5,M,-23.5,M,,0000*67
$GPGSA,A,3,05,29,25,12,02,10,26,15,,,,,2.1,1.0,1.9*31

Install the software:
pi@raspberrypi ~ $ sudo apt-get install gpsd
pi@raspberrypi ~ $ sudo apt-get install gpsd-clients
pi@raspberrypi ~ $ sudo apt-get install python-gps <------optional

Launch the deamon:
pi@raspberrypi ~ $ sudo gpsd /dev/ttyAMA0

Check gpsd with:
pi@raspberrypi ~ $ cps

Check from X-windows desktop (nice graphic display of GPS info):
pi@raspberrypi ~ $ xgps

Log locations via:
pi@raspberrypi ~ $ gpxlogger -f /home/pi/gpslog'%Y%m%d%H%M'

Startup GPS Server on Boot:
Add to /etc/rc.local with:
“gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock"

Start logging on Boot:
Add to /etc/rc.local: gpxlogger -m -f /home/pi/gpslog'%Y%m%d%H%M' <-----still a work in progress

I can't get the gpxlogger to close out cleanly by shutting it off, so I end up with a file that doesn't have the closing xml lines. I tried manually editing the file, but I can't get Google Maps to recognize the hosted file.

Maybe a button and LED connected to the PIO to start and stop? Suggestions welcome...

camolas
Posts: 69
Joined: Mon Jun 17, 2013 6:58 pm

Re: GPS not working well

Sun Jul 14, 2013 11:53 pm

Hi

The problem is the usb gps (prolific chip) work well in PuTTY ( is a serial terminal software) windows pc and not working (dont print any data) in gpsd and in a very simple serial port read python code

Please help

Thanks

texy
Forum Moderator
Forum Moderator
Posts: 5161
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England

Re: GPS not working well

Mon Jul 15, 2013 6:55 am

Stating the make/model or link to the product may help others help you. There could be 100 different 'usb gps modules' out there...........

Texy
Various male/female 40- and 26-way GPIO header for sale here ( IDEAL FOR YOUR PiZero ):
https://www.raspberrypi.org/forums/viewtopic.php?f=93&t=147682#p971555

ITDiscovery
Posts: 12
Joined: Tue Jul 09, 2013 6:45 pm

Re: GPS not working well

Tue Jul 16, 2013 3:14 am

Hey Camolas: Try using the minicom terminal emulator I show in the example. I connect it /dev/ttyAMA0 and at 4800BPS....your connect speed may vary, so putting in the model of GPS is as the moderator stated, very critical.

To the rest of the folks, I did have a small problem with the gpxlogger was starting up before the gpsd was stable (hence the "sleep" in the script). Any suggestions for better stability would be appreciated...

Add Deamon and Logger to Startup:
pi@raspberrypi ~ $ dpkg-reconfigure gpsd

Create /etc/init.d/gpslog.sh:
# ==========CHOMP================
#! /bin/sh
# /etc/init.d/gpslog.sh

### BEGIN INIT INFO
# Provides: noip
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Simple script to start a program at boot
# Description: A simple script from www.stuffaboutcode.com which will start / stop a program a boot / shutdown.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
start)
log_suffix=$(date +%Y%m%d%H%M%S)
# run application you want to start
sleep 10
echo "[ OK ] Starting GPXLogger: gpxlog${log_suffix}"
/usr/bin/gpxlogger -m 1 -f /home/pi/gpxlog'%Y%m%d%H%M%S'.gpx 2> /home/pi/gpserr.out &
;;
stop)
echo "Stopping GPXLogger"
# kill application you want to stop
killall gpxlogger
;;
*)
echo "Usage: /etc/init.d/gpslog.sh {start|stop}"
exit 1
;;
esac

exit 0
# ==========CHOMP================

Add the script to the startup:
pi@raspberrypi ~ $ chmod 755 /etc/init.d/gpslog.sh
pi@raspberrypi ~ $ update-rc.d gpslog.sh defaults

After the boot up and capturing a few files, add the closing tags to the file:
</trkseg>
</trk>
</gpx>

Convert the file:
http://gpx2kml.com/

Not really sure why the raspbian version of gpxlogger doesn't have the deamon and minmove switches are present. I'd also like to see a interval switch too....so after I'll be revving up my C programming skills, then hooking up an led and switch to the GPIO to allow me to start and stop gpxlogger.

camolas
Posts: 69
Joined: Mon Jun 17, 2013 6:58 pm

Re: GPS not working well

Wed Jul 17, 2013 12:16 am

Hi,

I solve the problem http://blog.retep.org/2012/06/18/gettin ... pberry-pi/ doing this

Code: Select all

sudo killall gpsd
sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock
sudo service ntp restart
before using runing cgps, how can i run the 3 commands in the Python code?

Thanks

ITDiscovery
Posts: 12
Joined: Tue Jul 09, 2013 6:45 pm

Re: GPS not working well

Wed Jul 17, 2013 12:47 am

Camalos: Gratz on getting that up...looks like your GPS is running off the USB port, so I guess I was a little confused by the references to "serial" in your question. The permanent fix to your problem is to run "dpkg-reconfigure gpsd" and tell it to use "/dev/ttyUSB0" instead of what it was defaulted to. Reboot, and never have to run those three lines again.

Then use the cgps or xgps (windows) command just to watch it working.

I am pretty much done with trying to get gpxlogger to work right on boot up. A better direction is as you mentioned, using python.

I found an article at:

http://www.danmandle.com/blog/getting-g ... th-python/

in which the python worked first time, and was well documented. Thanks Dan!! I'll post back to your site with a reference to this one with any modifications.

I need to: Output in kml, check to make sure the GPS is running, a switch to report the time from the GPS (to sync the system clock with). All with the stuff I was looking for gpxlogger to do!

danmandle
Posts: 3
Joined: Thu Sep 06, 2012 6:36 am

Re: GPS not working well

Wed Jul 17, 2013 2:38 am

ITDiscovery wrote: I found an article at:
http://www.danmandle.com/blog/getting-g ... th-python/
in which the python worked first time, and was well documented. Thanks Dan!! I'll post back to your site with a reference to this one with any modifications.

I need to: Output in kml, check to make sure the GPS is running, a switch to report the time from the GPS (to sync the system clock with). All with the stuff I was looking for gpxlogger to do!
Thanks Peter! Here's a link to another thing I'm working on and uses most of my existing code, but also writes out to a SQLite database AND doesn't write if the distance from the last point is less than a pre-set amount. https://github.com/danmandle/pyobdgps/b ... d_to_DB.py You could either modify the code to write out in the XML/KML format you need or run another job to make the KML file from the SQLite database.

ITDiscovery
Posts: 12
Joined: Tue Jul 09, 2013 6:45 pm

Re: GPS not working well

Tue Jul 23, 2013 1:46 am

I've modified Dan's code to write out kml code, and while I didn't add the ability to pass arguments via command line (I'm lazy and want to move forward), it's easy to change the follow attributes:

slpinterval: The amount of time between samples
dbug: 0 for no debug, 1 for putting sample info to screen
lncolor: Line color
pcolor: 2ndary line color
mindist = minimum move distance (if you stop, it will stop logging)
fname = path and beginning of name to save kml file as

I added and tested one more helpful element: An indicator that shows that GPS readings are being added to the file.
To implement this, pick up the connection from Pin 11 (it was handy on the ribbon cable I had) to the plus lead (anode) of an LED. Run the negative (cathode) to a 270 ohm to 330 ohm and then to a ground pin (6 or 7).

One other thing I will absolutely need to do is to add a button, and then have the python script look for the button press as part of a "sleep cycle". That's just a matter of removing the "time.sleep(slpinterval)" line with code that grabs the time, then a do (time+interval) while that looks for the switch press. It is required because right now I have to pull the plug to start a new track...meaning I have to manually add the closing kml lines:

That being the case these lines never run and have to be added to the file after the fact.
fhandle.write(" </coordinates>\n")
fhandle.write(" </LineString>\n")
fhandle.write("</Placemark>\n")
fhandle.write("</Document>\n")
fhandle.write("</kml>\n")

In testing, the 5 second interval works extremely well in the car. A 45 mile drive consumed a pittance 40K of SDCard and was perfectly on target. A walk in the woods worked well, but a smaller interval of 1 second would have worked better. A sample of the 5 second interval track of a walk around Meridian State Park's Shinnery Ridge Trail was captured as a sample. Go to maps.google.com and enter as the location: http://www.itdiscovery.info/files/Merid ... yRidge.kml

I purchased a LiO battery that had a USB in/out and was meant to provide "emergency" charge to cellphones for around $20. That got me around the hour long hike on the path easily.

Code: Select all

#! /usr/bin/python
# Written by Dan Mandle http://dan.mandle.me September 2012
# Modified by Peter Nichols for output to kml file http://www.itdiscovery.info
# License: GPL 2.0

import os
from gps import *
from time import *
import time
import threading
from math import radians, cos, sin, asin, sqrt

# LED Hooked to Pin 11
#import RPi.GPIO as GPIO
#GPIO.setmode(GPIO.BOARD)
#GPIO.setwarnings(False)
#GPIO.setup(11, GPIO.OUT, initial=GPIO.LOW)

# Arguments [-D debug-level] [-j interval] [-i track timeout]
# [-m minimum distance] [-c color of line] [-p color of polygon]

def haversine(lon1, lat1, lon2, lat2):
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    km = 6367 * c
    return km

slpinterval = 5
dbug = 0
datestmp = time.strftime("%Y%m%d%H%M%S")
gpsd = None #seting the global variable
lncolor = "7f00ffff"
pcolor = "7f00ff00"
tlat = 0
tlong = 0
mindist = 1
dist = 0 
ttime = 0
fname = "/home/pi/gpsdata"

#Write out the kml header
fhandle = open(fname + datestmp + ".kml", "w")
fhandle.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
fhandle.write("<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n")
fhandle.write("<Document>\n")
fhandle.write("<name>Paths</name>\n")
fhandle.write("<description>Path created by gpsklogger on Raspberry Pi</description>\n")
fhandle.write("<Style id=\"yellowLineGreenPoly\">\n")
fhandle.write("    <LineStyle>\n")
fhandle.write("      <color>" + lncolor + "</color>\n")
fhandle.write("      <width>4</width>\n")
fhandle.write("   </LineStyle>\n")
fhandle.write("   <PolyStyle>\n")
fhandle.write("      <color>" + pcolor + "</color>\n")
fhandle.write("   </PolyStyle>\n")
fhandle.write("</Style>\n")
fhandle.write("<Placemark>\n")
fhandle.write("   <name>Absolute Extruded</name>\n")
fhandle.write("   <description>Transparent " + pcolor + " wall with " + lncolor + "outlines</description>\n")
fhandle.write("   <styleUrl>#yellowLineGreenPoly</styleUrl>\n")
fhandle.write("   <LineString>\n")
fhandle.write("       <extrude>1</extrude>\n")
fhandle.write("       <tessellate>1</tessellate>\n")
fhandle.write("       <altitudeMode>absolute</altitudeMode>\n")
fhandle.write("       <coordinates>\n")
fhandle.close

#clear the terminal if in debug mode (optional)
if dbug<>0:
     os.system('clear') 
 
class GpsPoller(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    global gpsd #bring it in scope
    gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
    self.current_value = None
    self.running = True #setting the thread running to true
 
  def run(self):
    global gpsd
    while gpsp.running:
      gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer
 
if __name__ == '__main__':
  gpsp = GpsPoller() # create the thread
  try:
    gpsp.start() # start it up
    while True:
      #It may take a second or two to get good data
      if gpsd.fix.longitude<>0:
          #Compute Distance between last point and this point
          dist = haversine(tlong,tlat,gpsd.fix.longitude,gpsd.fix.latitude) * 1000 
          if dist > mindist:
               #Turn on the LED
               #GPIO.output(11, True)
               #Write the longtitude, latitude and then altitude
               fhandle = open(fname + datestmp + ".kml", "a")
               fhandle.write("       "+str(gpsd.fix.longitude) + ", ")
               fhandle.write(str(gpsd.fix.latitude) + ", ")
               fhandle.write(str(gpsd.fix.altitude) + "\n")
               fhandle.close
               #Reset the position
               tlat = gpsd.fix.latitude
               tlong = gpsd.fix.longitude
               ttime = gpsd.utc
          #clear the terminal if in debug mode (optional)
          if dbug<>0:
              os.system('clear') 
              print
              print ' GPS reading'
              print '----------------------------------------'
              print '----------------------------------------'
              print 'latitude    ' , gpsd.fix.latitude
              print 'longitude   ' , gpsd.fix.longitude
              print 'time utc    ' , gpsd.utc,' + ', gpsd.fix.time
              print 'altitude (m)' , gpsd.fix.altitude
              print 'eps         ' , gpsd.fix.eps
              print 'epx         ' , gpsd.fix.epx
              print 'epv         ' , gpsd.fix.epv
              print 'ept         ' , gpsd.fix.ept
              print 'speed (m/s) ' , gpsd.fix.speed
              print 'climb       ' , gpsd.fix.climb
              print 'track       ' , gpsd.fix.track
              print 'mode        ' , gpsd.fix.mode
              print
              print 'distance    ' , dist
              print 'TTIME       ' , ttime
          
          #Take a nap for # of secs.
          #This would be a good place to look for the GPIO switch pushbutton push
          time.sleep(slpinterval)
          #GPIO.output(11, False)

  except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
    if dbug<>0:
      print "\nKilling Thread..."
    fhandle = open(fname + datestmp + ".kml", "a")
    fhandle.write("       </coordinates>\n")
    fhandle.write("   </LineString>\n")
    fhandle.write("</Placemark>\n")
    fhandle.write("</Document>\n")
    fhandle.write("</kml>\n")
    fhandle.close()
    gpsp.running = False
    gpsp.join() # wait for the thread to finish what it's doing

    #Close out the LED
    GPIO.cleanup()
  print "Done.\nExiting."
So the next step for me is that I have purchased a $20 webcam (Logitech C270) and I'll be looking add a picture with the geotag to the SD Card. I'm pretty sure I can do that, I am undecided as to the best approach to presenting this web wise...the Keyhole Markup Language provides quite the few options.

ITDiscovery
Posts: 12
Joined: Tue Jul 09, 2013 6:45 pm

Re: GPS not working well

Sat Aug 03, 2013 2:32 am

Here's the completed code. While I added the ability to have it take a picture, in practice the delay to take the picture dragged down the speed needed to capture and geotag. I'll be adding another python module to take a picture track.

Code: Select all

#! /usr/bin/python
# Written by Dan Mandle http://dan.mandle.me September 2012
# Modified by Peter Nichols for output to Google Mapmaker compatible kml file http://www.itdiscovery.info July 2013
# Added headless operation with status LED, and untested stub for switch to exit from program (OS restarts it on exit would create new track file)
# Added command line parser with help (requires Python 2.7)
# License: GPL 2.0

from gps import *
from time import *
import time
import threading
from math import radians, cos, sin, asin, sqrt
import sys
import argparse

# LED Hooked to Pin 11, Switch Hooked to Pin 12
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(11, GPIO.OUT, initial=GPIO.LOW)
#GPIO.setup(12, GPIO.IN)

def haversine(lon1, lat1, lon2, lat2):
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    km = 6367 * c
    return km

#Initialize Temp Variables
datestmp = time.strftime("%Y%m%d%H%M%S")
gpsd = None
slptime = 0
startflg = 0
dbug = 0
tlat = 0
tlong = 0
dist = 0 
ttime = 0

#Command line parser 
parser = argparse.ArgumentParser(description='Python script that captures GPS coords in a Mapmaker compatible KML format.')
parser.add_argument('-d','--debug', default=0, help='Debug -d --debug [0] 0=off, 1=screen, 2=logfile',required=False)
parser.add_argument('-i','--interval',default=2, help='-i --interval [2] Interval between GPS data captures, in seconds.', required=False)
parser.add_argument('-m','--mindist', default=1, help='-m --mindist [1] Minimum distance required for a new capture (in meters).',required=False)
parser.add_argument('-c','--color', default="800000FF", help='-c --color [800000FF] Line color input into the KML file.',required=False)
parser.add_argument('-f','--file', default="/home/pi/gpsdata", help='-f --file [/home/pi/gpsdata] The directory and file header name for the KML files.',required=False)
args = parser.parse_args()

#Get the arguments for this run
dbug = int(args.debug)
slpinterval = float(args.interval)
mindist = float(args.mindist)
lncolor = args.color
fname = args.file

#Open a log entry for this run
if dbug==2:
     fhandle = open("/home/pi/kmllogger.log","a")
     fhandle.write("Start:" + time.strftime("%H:%M %m-%d") + "\n")
     fhandle.close

#Write out the kml header
fhandle = open(fname + datestmp + ".kml", "w")
fhandle.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
fhandle.write("<kml xmlns=\"http://earth.google.com/kml/2.2\">\n")
fhandle.write("<Document>\n")
fhandle.write("<name>Paths</name>\n")
fhandle.write("<description><![CDATA[trail hiking\n")
fhandle.write("RPI" + datestmp + "\n")
fhandle.write("Created by GPSKLogger on Raspberry Pi.]]>\n")
fhandle.write("</description>\n")
fhandle.write(" <Style id=\"style1\">\n")
fhandle.write("    <IconStyle>\n")
fhandle.write("      <Icon>\n")
fhandle.write("        <href>http://maps.google.com/mapfiles/kml/paddle/grn-circle_maps.png</href>\n")
fhandle.write("      </Icon>\n")
fhandle.write("    </IconStyle>\n")
fhandle.write("  </Style>\n")
fhandle.write("  <Style id=\"style1\">\n")
fhandle.write("    <LineStyle>\n")
fhandle.write("      <color>800000FF</color>\n")
fhandle.write("      <width>5</width>\n")
fhandle.write("    </LineStyle>\n")
fhandle.write("  </Style>\n")
fhandle.write("  <Style id=\"style1\">\n")
fhandle.write("    <IconStyle>\n")
fhandle.write("      <Icon>\n")
fhandle.write("        <href>http://maps.google.com/mapfiles/kml/paddle/red-circle_maps.png</href>\n")
fhandle.write("      </Icon>\n")
fhandle.write("    </IconStyle>\n")
fhandle.write("  </Style>\n")
fhandle.close

#clear the terminal if in debug mode (optional)
if dbug==1:
     os.system('clear') 
 
class GpsPoller(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    global gpsd #bring it in scope
    gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
    self.current_value = None
    self.running = True #setting the thread running to true
 
  def run(self):
    global gpsd
    while gpsp.running:
      gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer
 
if __name__ == '__main__':
  gpsp = GpsPoller() # create the thread
  try:
    gpsp.start() # start it up
    while True:
      #It may take a second or two to get good data
      if (gpsd.fix.longitude<>0) and (gpsd.fix.longitude<>'nan'):
          #Check if this is first time through loop with good data
          if startflg==0:
               #Write the KML for the first good Coord
               fhandle = open(fname + datestmp + ".kml", "a")
               fhandle.write("<Placemark>\n")
               fhandle.write("   <name>RPI" + datestmp + "(Start) </name>\n")
               fhandle.write("   <description><![CDATA[]]></description>\n")
               fhandle.write("   <styleUrl>#style1</styleUrl>\n")
               fhandle.write("   <Point>\n")
               fhandle.write("      <coordinates>"+str(gpsd.fix.longitude) + ", ")
               fhandle.write(str(gpsd.fix.latitude) + ", ")
               fhandle.write(str(gpsd.fix.altitude) + "</coordinates>\n")
               fhandle.write("   </Point>\n")
               fhandle.write("</Placemark>\n")
               #Write out the KML for the rest of the track
               fhandle.write("<Placemark>\n")
               fhandle.write("   <name>RPI" + datestmp + "</name>\n")
               fhandle.write("   <description><![CDATA[]]></description>\n")
               fhandle.write("   <styleUrl>#style1</styleUrl>\n")
               fhandle.write("   <LineString>\n")
               fhandle.write("       <extrude>1</extrude>\n")
               fhandle.write("       <tessellate>1</tessellate>\n")
               fhandle.write("       <altitudeMode>absolute</altitudeMode>\n")
               fhandle.write("       <coordinates>\n")
               #Close the file guarenteeing a write in case we get shutdown
               fhandle.close
               if dbug==2:
                   fhandle = open("/home/pi/kmllogger.log","a")
                   fhandle.write("Header Write:" + time.strftime("%H:%M %m-%d") + "\n")
                   fhandle.close
               #Make sure this is run once
               startflg = 1
          #Compute Distance between last point and this point
          dist = haversine(tlong,tlat,gpsd.fix.longitude,gpsd.fix.latitude) * 1000 
          if dist > mindist:
               #Turn on the LED
               GPIO.output(11, True)
               #Write the longtitude, latitude and then altitude
               fhandle = open(fname + datestmp + ".kml", "a")
               fhandle.write("       "+str(gpsd.fix.longitude) + ", ")
               fhandle.write(str(gpsd.fix.latitude) + ", ")
               fhandle.write(str(gpsd.fix.altitude) + "\n")
               fhandle.close
               #Reset the position
               tlat = gpsd.fix.latitude
               tlong = gpsd.fix.longitude
               ttime = gpsd.utc
               if dbug==2:
                    fhandle = open("/home/pi/kmllogger.log","a")
                    fhandle.write("Coord-Write:" + time.strftime("%H:%M %m-%d"))
                    fhandle.write(" Lat:" + str(tlat) + " Long:" + str(tlong) + "\n")
                    fhandle.close
          #clear the terminal if in debug mode (optional)
          if dbug==1:
              os.system('clear') 
              print
              print ' GPS reading'
              print '----------------------------------------'
              print '----------------------------------------'
              print 'latitude    ' , gpsd.fix.latitude
              print 'longitude   ' , gpsd.fix.longitude
              print 'time utc    ' , gpsd.utc,' + ', gpsd.fix.time
              print 'altitude (m)' , gpsd.fix.altitude
              print 'eps         ' , gpsd.fix.eps
              print 'epx         ' , gpsd.fix.epx
              print 'epv         ' , gpsd.fix.epv
              print 'ept         ' , gpsd.fix.ept
              print 'speed (m/s) ' , gpsd.fix.speed
              print 'climb       ' , gpsd.fix.climb
              print 'track       ' , gpsd.fix.track
              print 'mode        ' , gpsd.fix.mode
              print
              print 'distance    ' , dist
              print 'TTIME       ' , ttime
          
          #Take a nap for # of secs, this will include taking a picture
          #This would be a good place to look for the GPIO switch pushbutton push
          slptime = time.time()
          while (time.time() < slptime + slpinterval):
               #Exit on switch
	           #if GPIO.input(12)=1:
		          #raise SystemExit, 0
               j=0               
          #time.sleep(slpinterval)           
          if dbug==2:
               fhandle = open("/home/pi/kmllogger.log","a")
               fhandle.write("Loop:" + time.strftime("%H:%M:%S %m-%d"))
               fhandle.write(" Lat:" + str(tlat) + " Long:" + str(tlong) + "\n")
               fhandle.close
          GPIO.output(11,False)
  except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
    if dbug<>0:
      print "\nKilling Thread..."
    #Close out the KML file
    fhandle = open(fname + datestmp + ".kml", "a")
    fhandle.write("       </coordinates>\n")
    fhandle.write("   </LineString>\n")
    fhandle.write("</Placemark>\n")
    fhandle.write("<Placemark>\n")
    fhandle.write("   <name>RPI" + datestmp + "(End) </name>\n")
    fhandle.write("   <description><![CDATA[]]></description>\n")
    fhandle.write("   <styleUrl>#style1</styleUrl>\n")
    fhandle.write("   <Point>\n")
    fhandle.write("      <coordinates>"+str(gpsd.fix.longitude) + ", ")
    fhandle.write(str(gpsd.fix.latitude) + ", ")
    fhandle.write(str(gpsd.fix.altitude) + "</coordinates>\n")
    fhandle.write("   </Point>\n")
    fhandle.write("</Placemark>\n")
    fhandle.write("</Document>\n")
    fhandle.write("</kml>\n")
    fhandle.close()
    if dbug==2:
         fhandle = open("/home/pi/kmllogger.log","a")
         fhandle.write("End:" + time.strftime("%H:%M %m-%d") + "\n")
         fhandle.close
    gpsp.running = False
    gpsp.join() # wait for the thread to finish what it's doing

    #Close out the LED
    GPIO.cleanup()
  print "Done.\nExiting."

ITDiscovery
Posts: 12
Joined: Tue Jul 09, 2013 6:45 pm

Re: GPS not working well

Wed Aug 07, 2013 11:56 pm

So I pulled out the picture taking and it put it in a separate module (so I can tell it to take pictures at a different/faster rate than the track).

Code: Select all

#! /usr/bin/python
# Written by Dan Mandle http://dan.mandle.me September 2012
# Modified by Peter Nichols for output to Google Mapmaker compatible kml file http://www.itdiscovery.info
# Added headless operation with status LED, and untested stub for switch to exit from program (OS restarts it on exit would create new track file)
# Added command line parser with help (requires Python 2.7)
# License: GPL 2.0

from gps import *
from time import *
import time
import threading
from math import radians, cos, sin, asin, sqrt
import sys
import argparse

# LED Hooked to Pin 11, Switch Hooked to Pin 12
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(11, GPIO.OUT, initial=GPIO.LOW)
#GPIO.setup(12, GPIO.IN)

def haversine(lon1, lat1, lon2, lat2):
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    km = 6367 * c
    return km

#Initialize Temp Variables
datestmp = time.strftime("%Y%m%d%H%M%S")
gpsd = None
slptime = 0
startflg = 0
dbug = 0
tlat = 0
tlong = 0
dist = 0 
ttime = 0

#Command line parser 
parser = argparse.ArgumentParser(description='Python script that captures GPS coords in a Mapmaker compatible KML format.')
parser.add_argument('-d','--debug', default=0, help='Debug -d --debug [0] 0=off, 1=screen, 2=logfile',required=False)
parser.add_argument('-i','--interval',default=2, help='-i --interval [2] Interval between GPS data captures, in seconds.', required=False)
parser.add_argument('-m','--mindist', default=1, help='-m --mindist [1] Minimum distance required for a new capture (in meters).',required=False)
parser.add_argument('-c','--color', default="800000FF", help='-c --color [800000FF] Line color input into the KML file.',required=False)
parser.add_argument('-f','--file', default="/home/pi/gpsdata", help='-f --file [/home/pi/gpsdata] The directory and file header name for the KML files.',required=False)
args = parser.parse_args()

#Get the arguments for this run
dbug = int(args.debug)
slpinterval = float(args.interval)
mindist = float(args.mindist)
lncolor = args.color
fname = args.file

#Open a log entry for this run
if dbug==2:
     fhandle = open("/home/pi/kmllogger.log","a")
     fhandle.write("Start:" + time.strftime("%H:%M %m-%d") + "\n")
     fhandle.close

#Write out the kml header
fhandle = open(fname + datestmp + ".kml", "w")
fhandle.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
fhandle.write("<kml xmlns=\"http://earth.google.com/kml/2.2\">\n")
fhandle.write("<Document>\n")
fhandle.write("<name>Paths</name>\n")
fhandle.write("<description><![CDATA[trail hiking\n")
fhandle.write("RPI" + datestmp + "\n")
fhandle.write("Created by GPSKLogger on Raspberry Pi.]]>\n")
fhandle.write("</description>\n")
fhandle.write(" <Style id=\"style1\">\n")
fhandle.write("    <IconStyle>\n")
fhandle.write("      <Icon>\n")
fhandle.write("        <href>http://maps.google.com/mapfiles/kml/paddle/grn-circle_maps.png</href>\n")
fhandle.write("      </Icon>\n")
fhandle.write("    </IconStyle>\n")
fhandle.write("  </Style>\n")
fhandle.write("  <Style id=\"style1\">\n")
fhandle.write("    <LineStyle>\n")
fhandle.write("      <color>800000FF</color>\n")
fhandle.write("      <width>5</width>\n")
fhandle.write("    </LineStyle>\n")
fhandle.write("  </Style>\n")
fhandle.write("  <Style id=\"style1\">\n")
fhandle.write("    <IconStyle>\n")
fhandle.write("      <Icon>\n")
fhandle.write("        <href>http://maps.google.com/mapfiles/kml/paddle/red-circle_maps.png</href>\n")
fhandle.write("      </Icon>\n")
fhandle.write("    </IconStyle>\n")
fhandle.write("  </Style>\n")
fhandle.close

#clear the terminal if in debug mode (optional)
if dbug==1:
     os.system('clear') 
 
class GpsPoller(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    global gpsd #bring it in scope
    gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
    self.current_value = None
    self.running = True #setting the thread running to true
 
  def run(self):
    global gpsd
    while gpsp.running:
      gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer
 
if __name__ == '__main__':
  gpsp = GpsPoller() # create the thread
  try:
    gpsp.start() # start it up
    while True:
      #It may take a second or two to get good data
      if (gpsd.fix.longitude<>0) and (gpsd.fix.longitude<>'nan'):
          #Check if this is first time through loop with good data
          if startflg==0:
               #Write the KML for the first good Coord
               fhandle = open(fname + datestmp + ".kml", "a")
               fhandle.write("<Placemark>\n")
               fhandle.write("   <name>RPI" + datestmp + "(Start) </name>\n")
               fhandle.write("   <description><![CDATA[]]></description>\n")
               fhandle.write("   <styleUrl>#style1</styleUrl>\n")
               fhandle.write("   <Point>\n")
               fhandle.write("      <coordinates>"+str(gpsd.fix.longitude) + ", ")
               fhandle.write(str(gpsd.fix.latitude) + ", ")
               fhandle.write(str(gpsd.fix.altitude) + "</coordinates>\n")
               fhandle.write("   </Point>\n")
               fhandle.write("</Placemark>\n")
               #Write out the KML for the rest of the track
               fhandle.write("<Placemark>\n")
               fhandle.write("   <name>RPI" + datestmp + "</name>\n")
               fhandle.write("   <description><![CDATA[]]></description>\n")
               fhandle.write("   <styleUrl>#style1</styleUrl>\n")
               fhandle.write("   <LineString>\n")
               fhandle.write("       <extrude>1</extrude>\n")
               fhandle.write("       <tessellate>1</tessellate>\n")
               fhandle.write("       <altitudeMode>absolute</altitudeMode>\n")
               fhandle.write("       <coordinates>\n")
               #Close the file guarenteeing a write in case we get shutdown
               fhandle.close
               if dbug==2:
                   fhandle = open("/home/pi/kmllogger.log","a")
                   fhandle.write("Header Write:" + time.strftime("%H:%M %m-%d") + "\n")
                   fhandle.close
               #Make sure this is run once
               startflg = 1
          #Compute Distance between last point and this point
          dist = haversine(tlong,tlat,gpsd.fix.longitude,gpsd.fix.latitude) * 1000 
          if dist > mindist:
               #Turn on the LED
               GPIO.output(11, True)
               #Write the longtitude, latitude and then altitude
               fhandle = open(fname + datestmp + ".kml", "a")
               fhandle.write("       "+str(gpsd.fix.longitude) + ", ")
               fhandle.write(str(gpsd.fix.latitude) + ", ")
               fhandle.write(str(gpsd.fix.altitude) + "\n")
               fhandle.close
               #Reset the position
               tlat = gpsd.fix.latitude
               tlong = gpsd.fix.longitude
               ttime = gpsd.utc
               if dbug==2:
                    fhandle = open("/home/pi/kmllogger.log","a")
                    fhandle.write("Coord-Write:" + time.strftime("%H:%M %m-%d"))
                    fhandle.write(" Lat:" + str(tlat) + " Long:" + str(tlong) + "\n")
                    fhandle.close
          #clear the terminal if in debug mode (optional)
          if dbug==1:
              os.system('clear') 
              print
              print ' GPS reading'
              print '----------------------------------------'
              print '----------------------------------------'
              print 'latitude    ' , gpsd.fix.latitude
              print 'longitude   ' , gpsd.fix.longitude
              print 'time utc    ' , gpsd.utc,' + ', gpsd.fix.time
              print 'altitude (m)' , gpsd.fix.altitude
              print 'eps         ' , gpsd.fix.eps
              print 'epx         ' , gpsd.fix.epx
              print 'epv         ' , gpsd.fix.epv
              print 'ept         ' , gpsd.fix.ept
              print 'speed (m/s) ' , gpsd.fix.speed
              print 'climb       ' , gpsd.fix.climb
              print 'track       ' , gpsd.fix.track
              print 'mode        ' , gpsd.fix.mode
              print
              print 'distance    ' , dist
              print 'TTIME       ' , ttime
          
          #Take a nap for # of secs, this will include taking a picture
          #This would be a good place to look for the GPIO switch pushbutton push
          slptime = time.time()
          while (time.time() < slptime + slpinterval):
               #Exit on switch
	           #if GPIO.input(12)=1:
		          #raise SystemExit, 0
               j=0               
          #time.sleep(slpinterval)           
          if dbug==2:
               fhandle = open("/home/pi/kmllogger.log","a")
               fhandle.write("Loop:" + time.strftime("%H:%M:%S %m-%d"))
               fhandle.write(" Lat:" + str(tlat) + " Long:" + str(tlong) + "\n")
               fhandle.close
          GPIO.output(11,False)
  except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
    if dbug<>0:
      print "\nKilling Thread..."
    #Close out the KML file
    fhandle = open(fname + datestmp + ".kml", "a")
    fhandle.write("       </coordinates>\n")
    fhandle.write("   </LineString>\n")
    fhandle.write("</Placemark>\n")
    fhandle.write("<Placemark>\n")
    fhandle.write("   <name>RPI" + datestmp + "(End) </name>\n")
    fhandle.write("   <description><![CDATA[]]></description>\n")
    fhandle.write("   <styleUrl>#style1</styleUrl>\n")
    fhandle.write("   <Point>\n")
    fhandle.write("      <coordinates>"+str(gpsd.fix.longitude) + ", ")
    fhandle.write(str(gpsd.fix.latitude) + ", ")
    fhandle.write(str(gpsd.fix.altitude) + "</coordinates>\n")
    fhandle.write("   </Point>\n")
    fhandle.write("</Placemark>\n")
    fhandle.write("</Document>\n")
    fhandle.write("</kml>\n")
    fhandle.close()
    if dbug==2:
         fhandle = open("/home/pi/kmllogger.log","a")
         fhandle.write("End:" + time.strftime("%H:%M %m-%d") + "\n")
         fhandle.close
    gpsp.running = False
    gpsp.join() # wait for the thread to finish what it's doing

    #Close out the LED
    GPIO.cleanup()
Here's the picture taking code:

Code: Select all

#! /usr/bin/python
# Written by Dan Mandle http://dan.mandle.me September 2012
# Modified by Peter Nichols to take picture and geotag it. http://www.itdiscovery.info
# Modified by Peter Nichols for headless operation.
# License: GPL 2.0

import os
from gps import *
from time import *
import time
import threading
from math import radians, cos, sin, asin, sqrt
import pexif 
import argparse

slptime = 0
dbug = 0

gpsd = None #seting the global variable
tlat = 0
tlong = 0
dist = 0 
ttime = 0

#Parse the command line for additional arguments
parser = argparse.ArgumentParser(description='Python script that captures GPS coords in a Mapmaker compatible KML format.')
parser.add_argument('-d','--debug', default=0, help='Debug -d --debug [0] 0=off, 1=screen, 2=logfile',required=False)
parser.add_argument('-i','--interval',default=10, help='-i --interval [2] Interval between GPS data captures, in seconds.', required=False)
parser.add_argument('-m','--mindist', default=1, help='-m --mindist [1] Minimum distance required for a new capture (in meters).',required=False)
parser.add_argument('-c','--caption', default="Raspberry Pi Track", help='-c --caption [Raspberry Pi Track] Text placed into ImageDescription tag.',required=False)
parser.add_argument('-n', '--devname', default="/dev/video0", help='-n --devname [/dev/video0] Device Name')
parser.add_argument('-f','--fname', default="/home/pi/gpspics/gpspic", help='-f --file [/home/pi/gpspics] The directory and file header name for the JPG files.',required=False)
args = parser.parse_args()

dbug = int(args.debug)
slpinterval = float(args.interval)
mindist = float(args.mindist)
imgcaption = args.caption
fname = args.fname
devname = args.devname

def haversine(lon1, lat1, lon2, lat2):
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    km = 6367 * c
    return km

#Add to log file
if dbug==2:
     fhandle = open("/home/pi/kmllogger.log","a")
     fhandle.write("Start:" + time.strftime("%H:%M %m-%d") + "\n")
     fhandle.close

#clear the terminal if in debug mode (optional)
if dbug==1:
     os.system('clear') 
 
class GpsPoller(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    global gpsd #bring it in scope
    gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
    self.current_value = None
    self.running = True #setting the thread running to true
 
  def run(self):
    global gpsd
    while gpsp.running:
      gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer
 
if __name__ == '__main__':
  gpsp = GpsPoller() # create the thread
  try:
    gpsp.start() # start it up
    while True:
      #It may take a second or two to get good data
      if (gpsd.fix.longitude<>0) and (gpsd.fix.longitude<>'nan'):
          #Compute Distance between last point and this point
          dist = haversine(tlong,tlat,gpsd.fix.longitude,gpsd.fix.latitude) * 1000 
          if dist > mindist:
               #Turn on the LED
               #GPIO.output(13, True)
               #Take a picture 
               temptime = time.strftime("%Y%m%d%H%M%S")
               cmdstr = "fswebcam --no-banner -r 960x720 -q -d "+ devname + " " + fname + "-" + temptime + ".jpg"
               os.system(cmdstr) # returns the exit status
               #Tag the file with the coords
               ef = pexif.JpegFile.fromFile(fname + "-" + temptime + ".jpg")
               img = ef.get_exif(create=True)
               img.primary.ImageDescription = imgcaption
               img.primary.DateTime = time.strftime("%H:%M:%S  %m/%d/%Y")
               img.primary.Software = "Raspberry Pi Picttracker.py"
               ef.set_geo(gpsd.fix.latitude, gpsd.fix.longitude)
               ef.writeFile(fname + datestmp + "-" + temptime + ".jpg")
               #Reset the position
               tlat = gpsd.fix.latitude
               tlong = gpsd.fix.longitude
               ttime = gpsd.utc
               if dbug==2:
                    fhandle = open("/home/pi/kmllogger.log","a")
                    fhandle.write("Coord-Write:" + time.strftime("%H:%M %m-%d"))
                    fhandle.write(" Lat:" + str(tlat) + " Long:" + str(tlong) + "\n")
                    fhandle.close
          #clear the terminal if in debug mode (optional)
          if dbug==1:
              os.system('clear') 
              print
              print ' GPS reading'
              print '----------------------------------------'
              print '----------------------------------------'
              print 'latitude    ' , gpsd.fix.latitude
              print 'longitude   ' , gpsd.fix.longitude
              print 'time utc    ' , gpsd.utc,' + ', gpsd.fix.time
              print 'altitude (m)' , gpsd.fix.altitude
              print 'eps         ' , gpsd.fix.eps
              print 'epx         ' , gpsd.fix.epx
              print 'epv         ' , gpsd.fix.epv
              print 'ept         ' , gpsd.fix.ept
              print 'speed (m/s) ' , gpsd.fix.speed
              print 'climb       ' , gpsd.fix.climb
              print 'track       ' , gpsd.fix.track
              print 'mode        ' , gpsd.fix.mode
              print
              print 'distance    ' , dist
              print 'TTIME       ' , ttime
          
          #Take a nap for # of secs, this will include taking a picture
          #This would be a good place to look for the GPIO switch pushbutton push
          #slptime = time.time()
          #while (time.time() < slptime + slpinterval):
               #Exit on switch
	           #if GPIO.input(12)=1:
		          #raise SystemExit, 0
               #j=0               
          time.sleep(slpinterval)           
          if dbug==2:
               fhandle = open("/home/pi/kmllogger.log","a")
               fhandle.write("Loop:" + time.strftime("%H:%M:%S %m-%d"))
               fhandle.write(" Lat:" + str(tlat) + " Long:" + str(tlong) + "\n")
               fhandle.close
          #GPIO.output(13,False)
  except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
    if dbug<>0:
      print "\nKilling Thread..."
    if dbug==2:
         fhandle = open("/home/pi/kmllogger.log","a")
         fhandle.write("End:" + time.strftime("%H:%M %m-%d") + "\n")
         fhandle.close
    gpsp.running = False
    gpsp.join() # wait for the thread to finish what it's doing

    #Close out the LED
    #GPIO.cleanup()
  print "Done.\nExiting."
They do log to the same file, and it works fairly well...although it seems the RPi has trouble with taking pictures at 2 sec intervals and still tagging the files....likely an I/O issue to the "disk". Thoughts?

Also any thoughts on integrating them via mapmaker??

I have code I am using to upload files to Google Drive, which I think needs a new thread as it has lots of other applications...working on command line options, and I'll need to gather my notes for the HowTo.

-petern

ITDiscovery
Posts: 12
Joined: Tue Jul 09, 2013 6:45 pm

Re: GPS not working well

Sun Sep 01, 2013 9:15 pm

One final note to close out this topic...

While google mapmaker seems to work well with the output file (edited to add in the end that gets chopped off), files uploaded to Google Drive (via my python script) error out in Google Earth. The fix was to remove the spaces between the Latitude, Longitude and Altitude here:

fhandle.write(" "+str(gpsd.fix.longitude) + ", ")
fhandle.write(str(gpsd.fix.latitude) + ", ")
fhandle.write(str(gpsd.fix.altitude) + "\n")

Changing:
fhandle.write(" <altitudeMode>absolute</altitudeMode>\n")
To:
fhandle.write(" <altitudeMode>clampToGround</altitudeMode>\n")

Will also guarantee you see a solid line on the map.

Cheers!!

Return to “HATs and other add-ons”