98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
|
M
|
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
|