range-testing/functions/location.py

98 lines
3.4 KiB
Python

import serial
from functions.helper_functions import calculate_distance, parse_lat_lon
def read_gps_data(
port: str = "/dev/ttyACM0", baudrate: int = 9600, timeout: int = 5
) -> dict:
"""
Reads GPS data from a u-blox 7 GPS/GLONASS device and returns it as a dictionary.
Args:
port (str): The serial port the GPS device is connected to. Default is '/dev/ttyACM0'.
baudrate (int): Baud rate for serial communication. Default is 9600.
timeout (int): Timeout in seconds for the serial port. Default is 5 seconds.
Returns:
dict: A dictionary containing parsed GPS data.
"""
gps_data = {}
attempts = 0
try:
with serial.Serial(port, baudrate=baudrate, timeout=timeout) as ser:
while True:
# Read a line from the GPS device
line = ser.readline().decode("ascii", errors="ignore").strip()
# Filter for GGA or RMC sentences for relevant data
if line.startswith("$GPGGA"): # Global Positioning System Fix Data
parts = line.split(",")
gps_data["utc_time"] = parts[1]
gps_data["latitude"] = parse_lat_lon(parts[2], parts[3])
gps_data["longitude"] = parse_lat_lon(parts[4], parts[5])
gps_data["altitude"] = float(parts[9]) if parts[9] else None
# Count number of times GPGGA has been queried
attempts = attempts + 1
# Stop after collecting sufficient data
if (
gps_data.get("utc_time")
and gps_data.get("latitude")
and gps_data.get("longitude")
):
break
elif attempts >= 3:
gps_data = {}
break
except serial.SerialException:
pass
except Exception as e:
print(f"Error: {e}")
return gps_data
def set_base_location(base_location={}):
try:
gps_data = read_gps_data()
base_location["latitude"] = gps_data["latitude"]
base_location["longitude"] = gps_data["longitude"]
if gps_data.get("altitude"):
base_location["altitude"] = gps_data["altitude"]
print("Base location found")
except KeyError:
print("Base location could not be found")
except Exception as e:
print(f"Error finding location: {e}")
return base_location
def get_current_location(dictionary={}, base_location={}):
try:
gps_data = read_gps_data()
dictionary["latitude"] = gps_data["latitude"]
dictionary["longitude"] = gps_data["longitude"]
if gps_data.get("altitude"):
dictionary["altitude"] = gps_data["altitude"]
if base_location and "latitude" in base_location:
dictionary["baseLatitude"] = base_location["latitude"]
dictionary["baseLongitude"] = base_location["longitude"]
if base_location.get("altitude"):
dictionary["baseAltitude"] = base_location["altitude"]
dictionary["distance"] = calculate_distance(base_location, gps_data)
except KeyError:
print("Location could not be found")
dictionary["distance"] = "Unknown"
except Exception as e:
print(f"Error finding location: {e}")
dictionary["distance"] = "Error"
return dictionary