Skip to content

Instantly share code, notes, and snippets.

@Williangalvani
Last active December 12, 2018 19:02
Show Gist options
  • Save Williangalvani/ff07e3f877f7ce9569557e3888f43cae to your computer and use it in GitHub Desktop.
Save Williangalvani/ff07e3f877f7ce9569557e3888f43cae to your computer and use it in GitHub Desktop.
usage: ./udpgpstestpy [--noheading] --ip 127.0.0.1 --port 14401
#!/usr/bin/python
import time
import socket
import argparse
from datetime import datetime
import operator
from functools import reduce
from math import floor
parser = argparse.ArgumentParser(description="Driver for the Water Linked Underwater GPS system.")
parser.add_argument('--ip', action="store", type=str, default="127.0.0.1", help="remote ip to query on.")
parser.add_argument('--port', action="store", type=str, default="14401", help="remote port to query on.")
parser.add_argument('--noheading', dest='noHeading', action='store_true', help="do not sent heading")
args = parser.parse_args()
# Nmea messages templates
# https://www.trimble.com/oem_receiverhelp/v4.44/en/NMEA-0183messages_GGA.html
gpgga = ("$GPGGA," # Message ID
+ "{hours:02d}{minutes:02d}{seconds:02.4f}," # UTC Time
+ "{lat:02.0f}{latmin:02.6f}," # Latitude (degrees + minutes)
+ "{latdir}," # Latitude direction (N/S)
+ "{lon:03.0f}{lonmin:02.6f}," # Longitude (degrees + minutes)
+ "{londir}," # Longitude direction (W/E)
+ "1," # Fix? (0-5)
+ "06," # Number of Satellites
+ "1.2," # HDOP
+ "0," # MSL altitude
+ "M," # MSL altitude unit (Meters)
+ "0," # Geoid separation
+ "M," # Geoid separation unit (Meters)
+ "00," # Age of differential GPS data, N/A
+ "0000" # Age of differential GPS data, N/A
+ "*67") # Checksum
gpzda = "$GPZDA,{hours:02d}{minutes:02d}{seconds:02.4f},04,07,2018,00,00*60"
# https://www.trimble.com/oem_receiverhelp/v4.44/en/NMEA-0183messages_RMC.html
gprmc = ("$GPRMC," # Message ID
+ "{hours:02d}{minutes:02d}{seconds:02.4f}," # UTC Time
+ "A," # Status A=active or V=void
+ "{lat:02.0f}{latmin:02.6f}," # Latitude (degrees + minutes)
+ "{latdir}," # Latitude direction (N/S)
+ "{lon:03.0f}{lonmin:02.6f}," # Longitude (degrees + minutes)
+ "{londir}," # Longitude direction (W/E)
+ "0.0," # Speed over the ground in knots
+ "{orientation:03.2f}," # Track angle in degrees
+ "{date}," # Date
+ "," # Magnetic variation in degrees
+ "," # Magnetic variation direction
+ "A" # A=autonomous, D=differential,
# E=Estimated, N=not valid, S=Simulator.
+ "*76") # Checksum
def fixChecksum(string):
"""
Fixes checksum of an Nmea string
"""
data, checksum = string.split("*")
original_checksum = int(checksum.strip().lower(), 16)
calculated_checksum = reduce(operator.xor, bytearray(data[1:], encoding="utf-8"), 0)
return (data + "*%02x\r\n" % calculated_checksum).upper()
def format(message, now=0, lat=0, lon=0, orientation=0):
"""
Formats data into nmea message
"""
now = datetime.now()
latdir = "N" if lat > 0 else "S"
londir = "E" if lon > 0 else "W"
lat = abs(lat)
lon = abs(lon)
print (lat, (lat % 1.0) * 60.0)
msg = message.format(date=now.strftime("%d%m%y"),
hours=now.hour,
minutes=now.minute,
seconds=(now.second + now.microsecond/1000000.0),
lat=floor(lat),
latmin=(lat % 1.0) * 60.0,
latdir=latdir,
lon=floor(lon),
lonmin=(lon % 1.0) * 60.0,
londir=londir,
orientation=orientation)
return fixChecksum(msg)
qgcNmeaSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
qgcNmeaSocket.setblocking(0)
orientation = 0.0
while True:
time.sleep(0.1)
orientation = (orientation + 3) % 360.0
messages = [gpgga, gpzda] if args.noHeading else [gpgga, gprmc]
for message in messages:
msg = format(message,
datetime.now(),
-27.589743,
-48.52129,
orientation=orientation)
print(msg)
qgcNmeaSocket.sendto(bytearray(msg, encoding="utf-8"), (args.ip, int(args.port)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment