# GPS P code construction # # Copyright 2014 Peter Monta import numpy as np chip_rate = 10230000 code_length = chip_rate*86400*7 def x1a_shift(x): return [x[11]^x[10]^x[7]^x[5]] + x[0:11] def x1b_shift(x): return [x[11]^x[10]^x[9]^x[8]^x[7]^x[4]^x[1]^x[0]] + x[0:11] def x2a_shift(x): return [x[11]^x[10]^x[9]^x[8]^x[7]^x[6]^x[4]^x[3]^x[2]^x[0]] + x[0:11] def x2b_shift(x): return [x[11]^x[8]^x[7]^x[3]^x[2]^x[1]] + x[0:11] def make_12bit(reg_shift,reg_initial,n): x = reg_initial s = np.zeros(n) for i in range(n): s[i] = x[11] x = reg_shift(x) return s x1a = make_12bit(x1a_shift,[0,0,0,1,0,0,1,0,0,1,0,0],4092) x1b = make_12bit(x1b_shift,[0,0,1,0,1,0,1,0,1,0,1,0],4093) x2a = make_12bit(x2a_shift,[1,0,1,0,0,1,0,0,1,0,0,1],4092) x2b = make_12bit(x2b_shift,[0,0,1,0,1,0,1,0,1,0,1,0],4093) def x1(prn,start,len): idx = start + np.arange(len) idx = idx % 15345000 p_x1a = x1a[idx % 4092] hold = idx>=(15345000-343) idx[hold] = 4092 p_x1b = x1b[idx % 4093] return np.logical_xor(p_x1a,p_x1b) def x2(prn,start,len): idx = start + np.arange(len) idx = idx % 15345037 idx_a = idx.copy() hold = idx_a>=(15345037-37) idx_a[hold] = 4091 p_x2a = x2a[idx_a % 4092] idx_b = idx.copy() hold = idx_b>=(15345037-37-343) idx_b[hold] = 4092 p_x2b = x2b[idx_b % 4093] return np.logical_xor(p_x2a,p_x2b) def last_x2(prn,start,len): idx = start + np.arange(len) idx_x2 = idx % 15345037 idx_a = idx % 15345000 hold = idx_a>=(15345000-1069) idx_x2_a = idx_x2.copy() idx_x2_a[hold] = 4091 p_x2a = x2a[idx_x2_a % 4092] idx_b = idx % 15345000 hold = idx_b>=(15345000-965) idx_x2_b = idx_x2.copy() idx_x2_b[hold] = 4092 p_x2b = x2b[idx_x2_b % 4093] return np.logical_xor(p_x2a,p_x2b) def p_code(prn,start,len): day = (prn-1)//37 prn = prn - 37*day start += chip_rate*86400*day start = start%code_length p_x1 = x1(prn,start,len) p_x2 = x2(prn,start-prn,len) p_last_x2 = last_x2(prn,(start-prn)%code_length,len) idx_x2 = (start - prn + np.arange(len)) % code_length idx_last_x2 = idx_x2>=(code_length-4092) p_x2[idx_last_x2] = p_last_x2[idx_last_x2] return np.logical_xor(p_x1,p_x2) def code(prn,chips,frac,incr,n): len = np.int(np.floor(n*incr)+5) c = p_code(prn,chips,len).astype('int') idx = frac + incr*np.arange(n) idx = np.floor(idx).astype('int') x = c[idx] return 1.0 - 2.0*x # test vectors in IS-GPS-200J def first_12_chips(prn): c = p_code(prn,0,12) r = 0 for i in range(12): r = 2*r + c[i] return r def binary(s): n = s.shape[0] r = 0 for i in range(n): r += s[i]*2**((n-1)-i) return r def hex_digit(s): return "%x"%binary(s) def chips2hex(c): n = c.shape[0]//4 r = c.shape[0]%4 if r!=0: s = octal_digit(c[0:r]) else: s = "" for i in range(n): s += hex_digit(c[r+4*i:r+4*(i+1)]) return s def first_256_chips_hex(prn): start = 0 len = 256 c = p_code(prn,start,len) return chips2hex(c) def last_1024_chips_hex(prn): start = (7*86400*10230000) - 1024 len = 1024 c = p_code(prn,start,len) return chips2hex(c) def print_first_12_chips(): for prn in range(1,211): print('%3d: %04o' % (prn,first_12_chips(prn))) def print_first_256_chips(): for prn in [1,2,37,38,74,75,111,112,148,149,185,186,210]: print('%3d: %s' % (prn,first_256_chips_hex(prn))) def print_last_1024_chips(): for prn in [1,2,37,38,74,75,111,112,148,149,185,186,210]: print('%3d: %s' % (prn,last_1024_chips_hex(prn))) if __name__=='__main__': print_first_12_chips() print_first_256_chips() print_last_1024_chips()