Using gpsd, NTRIP, and pygpsclient to share GPS data

Sharing data with multiple apps is pretty easy with gpsd.  Gpsd can read data from a number of GPS and other systems, local, remote, serial, etc… and share it out as JSON on an easily-read port like http://localhost:2947. Gpsd can work with hot-plugging, so all one would need to do is to plug a GPS in to your computer, and a number of programs could share the outputs.  I recently had a nautical navigation software OpenCPN, a GIS system QGIS, two monitoring programs (cgps and xgps from the gpsd package), and a couple loggers (gpscat and netcat localhost 2947) all work through a hot-swap between 4 different GPSs.  I'm amazed at how seamlessly all the parts worked together.

GPS positions can be improved by using NTRIP to deliver a RTCM datastream which carries GPS correction data from a known good GPS station to improve the GPS position calculations from meter-scale down to centimeter scale.  Gpsd can gather a single NTRIP correction data and pass it on to the GPSs it is communicating with using a line like:

    gpsdctl add ntrip://user:password@ntripcompany.com/stationname

For one of my GPS modules (an older Ardusimple ZED-F9P board) the NTRIP improved the accuracy from ~1m to about ~2cm.

Unfortunately the gpsd hotplugging interferes with using software to control and configure the GPSs because only one program can communicate with the GPS device at any one time.  If you use the manufacturer's software (e.g., u-center ) to configure the device, it excludes gpsd and breaks all the things that depend on it. You can't connect configuration software to gpsd because gpsd provides one-way JSON-formatted information, while the config software needs proprietary write-access to the GPS.  I was able to find a workaround with pyGPSclient 

pyGPSclient can configure my uBlox ZED-F9P GPS, can share NTRIP RTCM data with the GPS (using the NTRIP Client config) and can still share the improved results through a "Socket Server" feature out to multiple programs.  gpsd can consume the pyGPSclient Socket Server output with a command like:

    sudo gpsdctl add tcp://localhost:50012   # to enable consumption of pyGPSclient data

Or if you have to shut down the gpsd hotplugging, you can do something like this on my Ubuntu laptop:

    sudo systemctl stop gpsd    # to shut down hotplugging
    gpsd tcp://localhost:50012  # to start a user-space daemon using pyGPSclient output 

It took me a while to find the mix of incantations, but I'm pleased I was able to make the systems work together.

If you are writing anything that needs GPS info, look into consuming the standardized gpsd JSON output through tcp://localhost:2947  If you are doing anything that produces GPS-like info (GPS, AIS, IMU, etc…) write in as NMEA data so gpsd can share it.

For example this Wokwi simulation of a ESP32 with a 9DOF magnetometer, accelerometer, gyroscope 9DOF sensor should make $HCHDG, $PASHR, and $GYOACC messages for gpsd. For example:

$HCHDG,75.99,,,,*40
$PASHR,,75.99,M,+35.26,+35.26,,,,,,*15
$GYOACC,,,0.000000,10.000000,20.000000,,9.806650,9.806650,9.806650,,11,,,*17

Comments

Leave a Reply

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