Skip to content
This repository has been archived by the owner on Apr 13, 2021. It is now read-only.

Extend performance simulation scripts with L1CA band option #47

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions peregrine/analysis/README-sim.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Running L2C Performance Simulations
Running L1CA/L2C Performance Simulations
===================================

Performance simulations are run with run_sim.py tool which invokes iqgen_main.py
and tracking_loop.py. The tool stores all the simulation results (including commands
for generating iq data and tracking l2c signal) in json file. Data is always appended
for generating iq data and tracking l1ca/l2c signal) in json file. Data is always appended
in given json file.

Thereafter, results are illustrated with plt_res.py which reads data from json file.

The json file contains following data for each iqgen and L2C tracking run:
The json file contains following data for each iqgen and L1CA/L2C tracking run:
{
"acc": # Acceleration (L1CA Hz / s)
"avgcn0": # Average of all tracker CN0 estimates
Expand All @@ -18,9 +18,9 @@ The json file contains following data for each iqgen and L2C tracking run:
"dopSigma3": # 3-sigma Doppler error (99.7% of errors is less than this)
"duration": # Length of simulation in seconds
"iqgencmd": # Command line for iqgen
"iqgencn0": # L2C CN0 reported by iqgen
"l2chip": # Initial L2C code phase reported by iqgen
"l2dop": # Initial L2C Doppler frequency reported by iqgen
"iqgencn0": # L1CA/L2C CN0 reported by iqgen
"l_chip": # Initial L1CA/L2C code phase reported by iqgen
"l_dop": # Initial L1CA/L2C Doppler frequency reported by iqgen
"lockrate": # PLL lock rate
"snr": # SNR argument for iqgen
"stamp": # Wall clock time stamp of simulation run
Expand Down Expand Up @@ -52,6 +52,13 @@ Performance data can be generated with following commands:
$ ./plt_res.py -e -f result_3.json


Band selection
==============
By default simulation is run for L2C band. The L1CA is selected with command line option:
-b l1ca (--band)
FPGA delay control simulation option --short-long-cycles can be given for L1CA band simulation with option:
-s (--short-long-cycles)

Varying simulation parameters
=============================
Changing values in the python file is as easy as value in configuration file
Expand Down Expand Up @@ -89,3 +96,4 @@ Changing CN0 estimator of plt_res.py
In plt_res.py there is a string which defines which CN0 estimate is used:
CN0STRING="avgcn0" # CN0 from tracking
#CN0STRING="iqgencn0" # CN0 from iqgen

56 changes: 43 additions & 13 deletions peregrine/analysis/plt_res.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,22 @@
import json
import numpy
import matplotlib.pyplot as plt
import peregrine.gps_constants

CN0STRING = "avgcn0" # CN0 from tracking
# CN0STRING="iqgencn0" # CN0 from iqgen

class CfgClass:

def __init__(self):
# self.CN0STRING = "avgcn0" # CN0 from tracking
self.CN0STRING = "iqgencn0" # CN0 from iqgen
self.BAND = "l2c"

def isL1CA(self):
if "l1ca" == self.BAND:
return True
return False

cfg = CfgClass()


def sigmaFreqPlot(filename):
Expand All @@ -30,7 +43,7 @@ def sigmaFreqPlot(filename):
jsarray = json.loads(s)
r = []
for j in jsarray:
r.append((j["dopSigma1"], j[CN0STRING]))
r.append((j["dopSigma1"], j[cfg.CN0STRING]))
r = sorted(r, key=lambda x: x[1])

dopSigma1 = map(lambda x: x[0], r)
Expand All @@ -40,6 +53,7 @@ def sigmaFreqPlot(filename):
plt.plot(avgcn0, dopSigma1, 'o-')
plt.xlabel('CN0')
plt.ylabel('Doppler sigma-1 error (Hz)')
plt.grid(True)
plt.show()


Expand All @@ -52,7 +66,7 @@ def lockrateCn0Plot(filename):
jsarray = json.loads(s)
r = []
for j in jsarray:
r.append((j["lockrate"], j[CN0STRING]))
r.append((j["lockrate"], j[cfg.CN0STRING]))
r = sorted(r, key=lambda x: x[1])

lockrate = map(lambda x: x[0], r)
Expand All @@ -63,10 +77,14 @@ def lockrateCn0Plot(filename):
plt.xlabel('CN0')
plt.ylabel('PLL lock rate')
#plt.scatter(avgcn0, lockrate)
plt.grid(True)
plt.show()


def dynamicAccPlot(filename, mode):
GRAV_G = 9.80665 # m/s^2
HzToMps = (peregrine.gps_constants.c / peregrine.gps_constants.l1)
HzToG = HzToMps / GRAV_G
fp = open(filename, "r")
s = fp.read()
fp.close()
Expand All @@ -78,8 +96,8 @@ def dynamicAccPlot(filename, mode):
maxCN0 = 0.0
r = []
for j in jsarray:
minCN0 = min(minCN0, j[CN0STRING])
maxCN0 = max(maxCN0, j[CN0STRING])
minCN0 = min(minCN0, j[cfg.CN0STRING])
maxCN0 = max(maxCN0, j[cfg.CN0STRING])
#r.append( (float(j["acc"]),j[CN0STRING]) )
#accVecAll = map(lambda x:x[0], r)
#cn0VecAll = map(lambda x:x[1], r)
Expand All @@ -89,23 +107,28 @@ def dynamicAccPlot(filename, mode):
fig = plt.figure()

r = []
if cfg.isL1CA():
Tcoh = 0.005 # Integration time 5 ms
else:
Tcoh = 0.02 # Integration time 20 ms

for cn0bin in cn0Range:
bestAcc = -1000.0
bestCN0 = 0
print "BIN", cn0bin,
for j in jsarray:
cn0 = j[CN0STRING]
cn0 = j[cfg.CN0STRING]
lockrate = j["lockrate"]
doperr = j["dopSigma1"]
acc = float(j["acc"])
acc = float(j["acc"]) * HzToG
if cn0bin - 0.5 <= cn0 and cn0 < cn0bin + 0.5:
if acc > bestAcc:
if mode == "lockrate" and lockrate >= 0.68:
bestAcc = acc
bestCN0 = cn0
plt.plot(bestCN0, bestAcc, 'bo')
# 1/12T, Tcoh=20 ms
elif mode == "doperr" and doperr <= 1.0 / (12 * 0.02):
# 1/12T, Tcoh=20 ms, Tcoh=5 ms
elif mode == "doperr" and doperr <= 1.0 / (12 * Tcoh):
bestAcc = acc
bestCN0 = cn0
plt.plot(bestCN0, bestAcc, 'bo')
Expand All @@ -122,12 +145,15 @@ def dynamicAccPlot(filename, mode):
#plt.plot(cn0VecAll, accVecAll, 'bo')
plt.plot(bestCN0, bestAcc, 'r.-')
plt.xlabel('CN0')
plt.ylabel('Acceleration Hz/s')
plt.grid()
plt.ylabel('Acceleration (g)')
plt.grid(True)
if mode == "lockrate":
plt.title("PLL lock rate >= 0.68 (1-sigma)")
elif mode == "doperr":
plt.title("Doppler 1-sigma error <= 1/(12*0.02) = 4.2 Hz")
if cfg.isL1CA():
plt.title("Doppler 1-sigma error <= 1/(12*0.005) = 16.7 Hz")
else:
plt.title("Doppler 1-sigma error <= 1/(12*0.02) = 4.2 Hz")
plt.show()


Expand All @@ -147,8 +173,12 @@ def main():
parser.add_argument("-e", "--dyn-acc-dop",
help="x-sigma Doppler error acceleration tolerance vs. CN0",
action="store_true")
parser.add_argument("-b", "--band",
help="l1ca or l2c (default)")

args = parser.parse_args()
if args.band:
cfg.BAND = args.band
if args.lockrate:
lockrateCn0Plot(args.filename)
elif args.dyn_acc_lockrate:
Expand Down
Loading