import re import numpy as np import matplotlib.pyplot as plt import serial import time from tkinter import Tk, filedialog, simpledialog # Funkce pro načtení dat ze souboru def soubor(): Tk().withdraw() file_path = filedialog.askopenfilename() if file_path: with open(file_path, 'r') as file: data = file.readlines() return data else: print("Soubor nebyl vybrán!") return [] # Funkce pro čtení dat ze sériového portu def seriak(): port = simpledialog.askstring("Input", "Zadejte název sériového portu:", initialvalue="COM3") baudrate = simpledialog.askinteger("Input", "Zadejte baudrate:", initialvalue=9600) time_limit = simpledialog.askinteger("Input", "Zadejte časový limit měření (v sekundách):", initialvalue=90) try: ser = serial.Serial(port, baudrate, timeout=1) data = [] start_time = time.time() while time.time() - start_time < time_limit: line = ser.readline().decode('utf-8').strip() if line: data.append(line) print(line) ser.close() return data except serial.SerialException as e: print(f"Error: {e}") return [] # Dialog pro výběr zdroje dat def main(): root = Tk() root.withdraw() option = simpledialog.askstring("Input", "Jak chcete načíst data? (Port/Soubor)", initialvalue="Soubor") if option.lower() == 'port': data = seriak() elif option.lower() == 'soubor': data = soubor() else: print('Neplatná volba. Zvolte "port" nebo "soubor".') data = [] if data: process_data(data) def process_data(data): # Rozdělení dat do skupin podle počátečního řetězce gpgsvData, glgsvData, gnggaData, gngsaData = [], [], [], [] for line in data: if line.startswith('$GPGSV'): gpgsvData.append(line) elif line.startswith('$GLGSV'): glgsvData.append(line) elif line.startswith('$GNGGA'): gnggaData.append(line) elif line.startswith('$GNGSA'): gngsaData.append(line) # Konverze GPGSV a GLGSV dat def convert_gsv_data(gsvData): gsvData = [line.replace(',,', ',0,').replace(',*', ',0*') for line in gsvData] vectors = [] for line in gsvData: numbers = re.findall(r'-?\d+(\.\d+)?', line) numbers = [float(num) for num in numbers[:-1]] # Remove checksum vectors.append(numbers) return vectors GPGSV_vektor = convert_gsv_data(gpgsvData) GLGSV_vektor = convert_gsv_data(glgsvData) # Příprava výsledných polí pozice = [4, 8, 12, 16, 5, 9, 13, 17, 6, 10, 14, 18, 7, 11, 15, 19] def prepare_result(vectors): vysledek = np.full((len(vectors), len(pozice)), np.nan) for j, vector in enumerate(vectors): for i, pos in enumerate(pozice): if pos <= len(vector): vysledek[j, i] = vector[pos-1] return vysledek vysledek_GP = prepare_result(GPGSV_vektor) vysledek_GL = prepare_result(GLGSV_vektor) # Extrakce dat def extract_data(vysledek): PRN_pre = vysledek[:, :4] ELE_pre = vysledek[:, 4:8] AZI_pre = vysledek[:, 8:12] SNR_pre = vysledek[:, 12:16] return PRN_pre.flatten(), ELE_pre.flatten(), AZI_pre.flatten(), SNR_pre.flatten() GP_PRN_vektor, GP_ELE_vektor, GP_AZI_vektor, GP_SNR_vektor = extract_data(vysledek_GP) GL_PRN_vektor, GL_ELE_vektor, GL_AZI_vektor, GL_SNR_vektor = extract_data(vysledek_GL) # Výpočet kvartilů a interkvartilového rozpětí def filter_outliers(data): Q1 = np.percentile(data, 25) Q3 = np.percentile(data, 75) IQR = Q3 - Q1 lower_limit = Q1 - 1.5 * IQR upper_limit = Q3 + 1.5 * IQR return data[(data >= lower_limit) & (data <= upper_limit)] GP_SNR_clean = filter_outliers(GP_SNR_vektor[~np.isnan(GP_SNR_vektor)]) GL_SNR_clean = filter_outliers(GL_SNR_vektor[~np.isnan(GL_SNR_vektor)]) # Skyplot def skyplot(PRN_vektor, ELE_vektor, AZI_vektor, title): m = PRN_vektor.reshape(-1, 4).shape[1] fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, num=title) for i in range(m): ax.plot(np.deg2rad(AZI_vektor[i::m]), ELE_vektor[i::m], 'o') ax.set_theta_zero_location('top') ax.set_theta_direction(-1) ax.set_ylim(0, 90) plt.legend([f'Sat {int(prn)}' for prn in PRN_vektor[:m]], loc='upper right') plt.show() skyplot(GP_PRN_vektor, GP_ELE_vektor, GP_AZI_vektor, 'Skyplot GPS') skyplot(GL_PRN_vektor, GL_ELE_vektor, GL_AZI_vektor, 'Skyplot GLONASS') # SNR grafy def plot_snr(SNR_clean, PRN_vektor, title): fig, ax = plt.subplots(num=title) ax.plot(SNR_clean) ax.set_title(title) ax.grid(True) plt.legend([f'Sat {int(prn)}' for prn in PRN_vektor[:len(SNR_clean)//4]], loc='upper right') plt.show() plot_snr(GP_SNR_clean, GP_PRN_vektor, 'SNR satelitů GPS') plot_snr(GL_SNR_clean, GL_PRN_vektor, 'SNR satelitů GLONASS') # Konverze GGA def convert_gga_data(ggaData): ggaData = [line.replace(',,', ',0,').replace(',,,', ',0,0,').replace(',*', ',0*') for line in ggaData] vectors = [] for line in ggaData: numbers = re.findall(r'-?\d+(\.\d+)?', line) numbers = [float(num) for num in numbers[:-1]] # Remove checksum vectors.append(numbers) return vectors GNGGA_vektor = convert_gga_data(gnggaData) CAS, N, E, H = [], [], [], [] for vec in GNGGA_vektor: CAS.append(vec[0]) N.append(vec[1] / 100) E.append(vec[2] / 100) H.append(vec[6]) N = filter_outliers(np.array(N)) E = filter_outliers(np.array(E)) H = filter_outliers(np.array(H)) NP = np.mean(N) EP = np.mean(E) VYP = np.mean(H) stredni_chybaN = np.std(N) stredni_chybaE = np.std(E) stredni_chybaH = np.std(H) print(f'N: {NP:.8f} +- {stredni_chybaN}') print(f'E: {EP:.8f} +- {stredni_chybaE}') print(f'H: {VYP:.4f} +- {stredni_chybaH}') # Četnostní grafy def hist_plot(data, title): plt.figure(num=title) plt.hist(data, bins='auto') plt.title(title) plt.grid(True) plt.show() hist_plot(N, 'četnost N') hist_plot(E, 'četnost E') hist_plot(H, 'četnost H') if __name__ == '__main__': main()