Source code for gps_helper.prn
import json
import os
from collections import deque
prn_json = open(os.path.join(os.path.dirname(__file__), 'prn_info.json')).read()
prn_info = json.loads(prn_json)
[docs]class ShiftRegister:
"""
This class implements a shift register as described in the ICD 200 for using two taps.
This is used by :class:`PRN`.
"""
def __init__(self, poly_taps, prn_taps):
"""
:param poly_taps: The polynomial taps to be used for the shift register. Usually G1, or G2 as specified in the
ICD 200.
:param prn_taps: The taps for the output, generally 10 for G1, or the sv taps listed in the ICD 200.
"""
self.G = deque([1 for i in range(10)]) # Needs to be ints for binary addition)
self.poly_taps = poly_taps
self.prn_taps = prn_taps
[docs] def next(self):
"""
Generate the next output and return it. This method includes the feedback step.
:return: Bit
"""
out = self.get_output()
self.do_feedback()
return out
[docs] def do_feedback(self):
"""
Generate the feedback, and shift the values.
:return:
"""
fb = [self.G[i - 1] for i in self.poly_taps]
fb = sum(fb) % 2
self.G.pop()
self.G.appendleft(fb)
[docs] def get_output(self):
"""
Generate the next output value for the sequence.
:return: Bit
"""
out = [self.G[i - 1] for i in self.prn_taps]
out = sum(out) % 2
return out
[docs]class PRN:
"""
This class implements the coarse acquisition prn sequence as described in ICD 200.
"""
def __init__(self, prn):
"""
:param prn: SV ID No. as described in the ICD 200.
"""
sv_range_message = "prn must be 1-63"
self.prn = prn
if prn < 1 or prn > 63:
ValueError(sv_range_message)
if prn < 38:
self.sv_prn = prn
else:
self.sv_prn = 0
self.sv_taps = prn_info['taps'][str(self.sv_prn)]
self.g1 = ShiftRegister(prn_info['taps']['G1'], [10])
self.g2 = ShiftRegister(prn_info['taps']['G2'], self.sv_taps)
if prn > 37:
delays = prn_info['delays'][str(self.prn)]
delays = list(bin(int(delays, 8))[2:])
while len(delays) < 10:
delays.insert(0, 0)
for i in range(10):
self.g2.G[i] = int(delays[i])
self.iteration = 0
self.ca = []
[docs] def next(self):
"""
Get the next chip in the sequence.
:return:
"""
if self.iteration < 1023:
g1 = self.g1.next()
g2 = self.g2.next()
ca = (g1 + g2) % 2
self.ca.append(ca)
self.iteration += 1
else:
ca = self.ca[self.iteration % 1023]
self.iteration += 1
if self.iteration == 2047:
self.iteration = 1023
return ca
[docs] def prn_seq(self):
"""
Return the full ca sequence. (1023 bits)
Uses :func:`PRN.next` to generate full sequence.
:return:
"""
if self.iteration < 1023:
while self.iteration < 1023:
self.next()
return self.ca