Install the hardware: Plug it in, of course.
- Check the kernel message log to discover the GPS dongle location in the filesystem:
$ dmesg | grep tty [1769190.919411] usb 2-1: pl2303 converter now attached to ttyUSB0
- Test for signal with the following command:
$ cat /dev/ttyUSB0 5�y�220,N,08754.5061,W,000.0,316.5,271111,,,A*71 $GPVTG,316.5,T,,M,000.0,N,000.0,K,A*0C $GPGGA,173905.000,4259.7220,N,08754.5060,W,1,08,1.0,190.0,M,-33.8,M,,0000*63 $GPGSA,A,3,12,04,10,23,02,05,17,25,,,,,1.7,1.0,1.4*31 $GPRMC,173905.000,A,4259.7220,N,08754.5060,W,000.0,316.5,271111,,,A*71
Use CTRL+C to end the signal check.
If you get a bunch of zero-data, then try moving closer to a window, since GPS signals are line-of-sight. Or try a USB hub or extension cable, to reduce interference from your computer.
Install the gps daemon so you can use gps data.
sudo apt-get install gpsd gpsd-clients
- Normally, udev will start gpsd automatically when a USB GPS device is inserted. If it fails to start after 5-10 seconds, you can start it manually:
gpsd /dev/ttyUSB0 #You must tell gpsd where to look for the dongle
- Test the GPS and gpsd output using the gpsmon and cgps terminal programs, or the xgps program (all included in the gpsd-clients package)
- Capture data for recycling (optional - handy for development). gpsfake will simulate gpsd output
$cat /dev/ttyUSB0 > path/to/datalog # Create data file. Use CTRL+C to end the capture. $gpsfake path/to/datalog # Run gpsd simulator (not a daemon - it will occupy the terminal)
Command-line tools to get GPS data
- Use the gpspipe command to get gpsd data:
$ gpspipe -w -n 5 netlib_connectsock() returns socket on fd 3 {"class":"VERSION","release":"2.95","rev":"2011-07-27T11:20:24","proto_major":3,"proto_minor":3} {"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyUSB0"}]} {"class":"WATCH","enable":true,"json":true,"nmea":false,"raw":0,"scaled":false,"timing":false} {"class":"TPV","tag":"RMC","device":"/dev/ttyUSB0","time":1322418390.001,"ept":0.005,"lat":42.995410000,"lon":-87.908430000,"alt":195.400,"epx":11.739,"epy":17.294,"epv":36.800,"track":342.2000,"speed":0.000,"climb":0.000,"eps":34.59,"mode":3} {"class":"SKY","tag":"GSV","device":"/dev/ttyUSB0","xdop":0.66,"ydop":1.15,"vdop":1.46,"tdop":1.01,"hdop":1.32,"gdop":2.22,"pdop":1.97,"satellites":[{"PRN":2,"el":77,"az":360,"ss":26,"used":true},{"PRN":10,"el":58,"az":72,"ss":32,"used":true},{"PRN":12,"el":51,"az":247,"ss":34,"used":true},{"PRN":5,"el":45,"az":192,"ss":21,"used":true},{"PRN":4,"el":40,"az":65,"ss":20,"used":true},{"PRN":25,"el":39,"az":292,"ss":21,"used":true},{"PRN":13,"el":15,"az":60,"ss":18,"used":true},{"PRN":24,"el":14,"az":258,"ss":0,"used":false},{"PRN":29,"el":12,"az":304,"ss":23,"used":false},{"PRN":17,"el":8,"az":121,"ss":17,"used":true},{"PRN":23,"el":7,"az":35,"ss":10,"used":false},{"PRN":31,"el":0,"az":334,"ss":0,"used":false}]}
- Let's refine the command a bit, limit to the first "TPV" (time, position, velocity) sentence:
$ gpspipe -w -n 5 | grep -m 1 TPV netlib_connectsock() returns socket on fd 3 {"class":"TPV","tag":"RMC","device":"/dev/ttyUSB0","time":1322418481.001,"ept":0.005,"lat":42.995406667,"lon":-87.908428333,"alt":195.300,"epx":10.003,"epy":17.383,"epv":36.800,"track":342.2000,"speed":0.000,"climb":0.000,"eps":34.77,"mode":3}
- We can use basic shell commands to extract single variables from this sentence:
tpv=$(gpspipe -w -n 5 | grep -m 1 TPV | cut -d, -f4,6-8,13) seconds=$(echo $tpv | cut -d, -f1 | cut -d: -f2) latitude=$(echo $tpv | cut -d, -f2 | cut -d: -f2) longitude=$(echo $tpv | cut -d, -f3 | cut -d: -f2) altitude=$(echo $tpv | cut -d, -f4 | cut -d: -f2) speed=$(echo $tpv | cut -d, -f5 | cut -d: -f2)
- For fun, let's compare GPS time with system time using shell commands:
date -u +%s # System utc time in seconds gpspipe -w -n 5 | grep -m 1 TPV | cut -d, -f4 | cut -d: -f2 # GPS utc time in seconds # Let's compare them side-by side $ echo System: $(date -u +%s) , GPS: $(gpspipe -w -n 5 | grep -m 1 TPV | cut -d, -f4 | cut -d: -f2) netlib_connectsock() returns socket on fd 3 System: 1322419689 , GPS: 1322419689.000 # Our sytem time is within one second of GPS time. That's good!
- For fun, let's use shell script to post the GPS location to Google Maps:
The format is simple enough: http://maps.google.com/?ll=40.480381,-92.373047&z=16 will return a valid map. So that's three variables: Latitude, longitude, and zoom Level.
tpv=$(gpspipe -w -n 5 | grep -m 1 TPV | cut -d, -f4,6-8,13) latitude=$(echo $tpv | cut -d, -f2 | cut -d: -f2) longitude=$(echo $tpv | cut -d, -f3 | cut -d: -f2) zoom=20 map_url="http://maps.google.com/?ll=${latitude},${longitude}&z=${zoom}" firefox $map_url
Python tools to get GPS data
- Python bindings to gpsd are provided by the python-gps package.
sudo apt-get install python-gps
- The python tools have changed a *lot* in two years. The old methods don't work anymore. No Python 3 version is available yet. There's a decent example here, but I couldn't get it to work.
Conversion between Lat/Lon and MGRS/UTM and other systems: gpsd doesn't do this, though apparently the geographiclib-tools package does. And so does this website.
Thanks for the recipe. I also do some experiments my self with some xexun gpstrackers and Google earth.
ReplyDeleteRegards,
Marco