nousian 2022-01-09 14:37:14 +01:00 zatwierdzone przez GitHub
commit 70ed9f239c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
1 zmienionych plików z 223 dodań i 22 usunięć

Wyświetl plik

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
"""
# MicropyGPS - a GPS NMEA sentence parser for Micropython/Python 3.X
# Copyright (c) 2017 Michael Calvin McCoy (calvin.mccoy@protonmail.com)
@ -43,9 +45,7 @@ class MicropyGPS(object):
Setup GPS Object Status Flags, Internal Data Registers, etc
local_offset (int): Timzone Difference to UTC
location_formatting (str): Style For Presenting Longitude/Latitude:
Decimal Degree Minute (ddm) - 40° 26.767 N
Degrees Minutes Seconds (dms) - 40° 26 46 N
Decimal Degrees (dd) - 40.446° N
"""
#####################
@ -86,12 +86,28 @@ class MicropyGPS(object):
self.geoid_height = 0.0
# GPS Info
self.satellites_in_view = 0
self.gsatellites_in_view = 0
self.rsatellites_in_view = 0
self.esatellites_in_view = 0
self.satellites_in_use = 0
self.satellites_used = []
self.last_sv_sentence = 0
self.total_sv_sentences = 0
self.satellite_data = dict()
self.gsatellites_used = []
self.rsatellites_used = []
self.esatellites_used = []
self.last_gsv_sentence = 0
self.total_gsv_sentences = 0
self.gsatellite_data = dict()
self.last_rsv_sentence = 0
self.total_rsv_sentences = 0
self.rsatellite_data = dict()
self.last_esv_sentence = 0
self.total_esv_sentences = 0
self.esatellite_data = dict()
self.hdop = 0.0
self.pdop = 0.0
self.vdop = 0.0
@ -472,25 +488,78 @@ class MicropyGPS(object):
self.pdop = pdop
return True
def gngsa(self):
"""Parse GNSS DOP and Active Satellites (GSA) sentence. Updates GPS fix type, list of satellites used in
fix calculation, Position Dilution of Precision (PDOP), Horizontal Dilution of Precision (HDOP), Vertical
Dilution of Precision, and fix status"""
# Fix Type (None,2D or 3D)
try:
fix_type = int(self.gps_segments[2])
except ValueError:
return False
# Read All (up to 12) Available PRN Satellite Numbers
sats_used = []
for sats in range(12):
sat_number_str = self.gps_segments[3 + sats]
if sat_number_str:
try:
sat_number = int(sat_number_str)
sats_used.append(sat_number)
except ValueError:
return False
else:
break
# PDOP,HDOP,VDOP
try:
pdop = float(self.gps_segments[15])
hdop = float(self.gps_segments[16])
vdop = float(self.gps_segments[17])
except ValueError:
return False
# Update Object Data
self.fix_type = fix_type
# If Fix is GOOD, update fix timestamp
if fix_type > self.__NO_FIX:
self.new_fix_time()
gnss_system = int(self.gps_segments[18])
if gnss_system == 1:
self.gsatellites_used = sats_used
if gnss_system == 2:
self.rsatellites_used = sats_used
if gnss_system == 3:
self.esatellites_used = sats_used
self.hdop = hdop
self.vdop = vdop
self.pdop = pdop
return True
def gpgsv(self):
"""Parse Satellites in View (GSV) sentence. Updates number of SV Sentences,the number of the last SV sentence
parsed, and data on each satellite present in the sentence"""
try:
num_sv_sentences = int(self.gps_segments[1])
current_sv_sentence = int(self.gps_segments[2])
sats_in_view = int(self.gps_segments[3])
num_gsv_sentences = int(self.gps_segments[1])
current_gsv_sentence = int(self.gps_segments[2])
gsats_in_view = int(self.gps_segments[3])
except ValueError:
return False
# Create a blank dict to store all the satellite data from this sentence in:
# satellite PRN is key, tuple containing telemetry is value
satellite_dict = dict()
gsatellite_dict = dict()
# Calculate Number of Satelites to pull data for and thus how many segment positions to read
if num_sv_sentences == current_sv_sentence:
if num_gsv_sentences == current_gsv_sentence:
# Last sentence may have 1-4 satellites; 5 - 20 positions
sat_segment_limit = (sats_in_view - ((num_sv_sentences - 1) * 4)) * 5
sat_segment_limit = (gsats_in_view - ((num_gsv_sentences - 1) * 4)) * 5
else:
sat_segment_limit = 20 # Non-last sentences have 4 satellites and thus read up to position 20
@ -523,19 +592,151 @@ class MicropyGPS(object):
break
# Add Satellite Data to Sentence Dict
satellite_dict[sat_id] = (elevation, azimuth, snr)
gsatellite_dict[sat_id] = (elevation, azimuth, snr)
# Update Object Data
self.total_sv_sentences = num_sv_sentences
self.last_sv_sentence = current_sv_sentence
self.satellites_in_view = sats_in_view
self.total_gsv_sentences = num_gsv_sentences
self.last_gsv_sentence = current_gsv_sentence
self.gsatellites_in_view = gsats_in_view
# For a new set of sentences, we either clear out the existing sat data or
# update it as additional SV sentences are parsed
if current_sv_sentence == 1:
self.satellite_data = satellite_dict
if current_gsv_sentence == 1:
self.gsatellite_data = gsatellite_dict
else:
self.satellite_data.update(satellite_dict)
self.gsatellite_data.update(gsatellite_dict)
return True
def glgsv(self):
"""Parse Satellites in View (GSV) sentence. Updates number of SV Sentences,the number of the last SV sentence
parsed, and data on each satellite present in the sentence"""
try:
num_rsv_sentences = int(self.gps_segments[1])
current_rsv_sentence = int(self.gps_segments[2])
rsats_in_view = int(self.gps_segments[3])
except ValueError:
return False
# Create a blank dict to store all the satellite data from this sentence in:
# satellite PRN is key, tuple containing telemetry is value
rsatellite_dict = dict()
# Calculate Number of Satelites to pull data for and thus how many segment positions to read
if num_rsv_sentences == current_rsv_sentence:
# Last sentence may have 1-4 satellites; 5 - 20 positions
sat_segment_limit = (rsats_in_view - ((num_rsv_sentences - 1) * 4)) * 5
else:
sat_segment_limit = 20 # Non-last sentences have 4 satellites and thus read up to position 20
# Try to recover data for up to 4 satellites in sentence
for sats in range(4, sat_segment_limit, 4):
# If a PRN is present, grab satellite data
if self.gps_segments[sats]:
try:
sat_id = int(self.gps_segments[sats])
except (ValueError,IndexError):
return False
try: # elevation can be null (no value) when not tracking
elevation = int(self.gps_segments[sats+1])
except (ValueError,IndexError):
elevation = None
try: # azimuth can be null (no value) when not tracking
azimuth = int(self.gps_segments[sats+2])
except (ValueError,IndexError):
azimuth = None
try: # SNR can be null (no value) when not tracking
snr = int(self.gps_segments[sats+3])
except (ValueError,IndexError):
snr = None
# If no PRN is found, then the sentence has no more satellites to read
else:
break
# Add Satellite Data to Sentence Dict
rsatellite_dict[sat_id] = (elevation, azimuth, snr)
# Update Object Data
self.total_rsv_sentences = num_rsv_sentences
self.last_rsv_sentence = current_rsv_sentence
self.rsatellites_in_view = rsats_in_view
# For a new set of sentences, we either clear out the existing sat data or
# update it as additional SV sentences are parsed
if current_rsv_sentence == 1:
self.rsatellite_data = rsatellite_dict
else:
self.rsatellite_data.update(rsatellite_dict)
return True
def gagsv(self):
"""Parse Satellites in View (GSV) sentence. Updates number of SV Sentences,the number of the last SV sentence
parsed, and data on each satellite present in the sentence"""
try:
num_esv_sentences = int(self.gps_segments[1])
current_esv_sentence = int(self.gps_segments[2])
esats_in_view = int(self.gps_segments[3])
except ValueError:
return False
# Create a blank dict to store all the satellite data from this sentence in:
# satellite PRN is key, tuple containing telemetry is value
esatellite_dict = dict()
# Calculate Number of Satelites to pull data for and thus how many segment positions to read
if num_esv_sentences == current_esv_sentence:
# Last sentence may have 1-4 satellites; 5 - 20 positions
sat_segment_limit = (esats_in_view - ((num_esv_sentences - 1) * 4)) * 5
else:
sat_segment_limit = 20 # Non-last sentences have 4 satellites and thus read up to position 20
# Try to recover data for up to 4 satellites in sentence
for sats in range(4, sat_segment_limit, 4):
# If a PRN is present, grab satellite data
if self.gps_segments[sats]:
try:
sat_id = int(self.gps_segments[sats])
except (ValueError,IndexError):
return False
try: # elevation can be null (no value) when not tracking
elevation = int(self.gps_segments[sats+1])
except (ValueError,IndexError):
elevation = None
try: # azimuth can be null (no value) when not tracking
azimuth = int(self.gps_segments[sats+2])
except (ValueError,IndexError):
azimuth = None
try: # SNR can be null (no value) when not tracking
snr = int(self.gps_segments[sats+3])
except (ValueError,IndexError):
snr = None
# If no PRN is found, then the sentence has no more satellites to read
else:
break
# Add Satellite Data to Sentence Dict
esatellite_dict[sat_id] = (elevation, azimuth, snr)
# Update Object Data
self.total_esv_sentences = num_esv_sentences
self.last_esv_sentence = current_esv_sentence
self.esatellites_in_view = esats_in_view
# For a new set of sentences, we either clear out the existing sat data or
# update it as additional SV sentences are parsed
if current_esv_sentence == 1:
self.esatellite_data = esatellite_dict
else:
self.esatellite_data.update(esatellite_dict)
return True
@ -819,11 +1020,11 @@ class MicropyGPS(object):
'GPGGA': gpgga, 'GLGGA': gpgga,
'GPVTG': gpvtg, 'GLVTG': gpvtg,
'GPGSA': gpgsa, 'GLGSA': gpgsa,
'GPGSV': gpgsv, 'GLGSV': gpgsv,
'GPGSV': gpgsv, 'GLGSV': glgsv, 'GAGSV': gagsv,
'GPGLL': gpgll, 'GLGLL': gpgll,
'GNGGA': gpgga, 'GNRMC': gprmc,
'GNVTG': gpvtg, 'GNGLL': gpgll,
'GNGSA': gpgsa,
'GNGSA': gngsa,
}
if __name__ == "__main__":