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

Commit

Permalink
iqgen: fixed symbol and code chip delay handling
Browse files Browse the repository at this point in the history
Fixed issue with incorrect symbol and code chip delay handling.
Updated parameters '--symbol-delay' and '--chip-delay'.
  • Loading branch information
valeri-atamaniouk authored and Pasi Miettinen committed May 19, 2016
1 parent 2515410 commit 375b3f8
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 113 deletions.
6 changes: 3 additions & 3 deletions peregrine/iqgen/bits/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def getCodeChipIndex(svTime_s):
long
Code chip index
'''
return long(svTime_s * GPS.L1CA.CODE_CHIP_RATE_HZ)
return (svTime_s * GPS.L1CA.CODE_CHIP_RATE_HZ)

class L2C:
'''
Expand Down Expand Up @@ -170,7 +170,7 @@ def getCodeChipIndex(svTime_s):
long
Code chip index
'''
return long(svTime_s * GPS.L2C.CODE_CHIP_RATE_HZ)
return (svTime_s * GPS.L2C.CODE_CHIP_RATE_HZ)

# GLONASS L1
GLONASS_L1_CENTER_FREQUENCY_HZ = 1602000000l
Expand Down Expand Up @@ -246,7 +246,7 @@ def getSymbolIndex(self, svTime_s):
long
Symbol index
'''
return svTime_s * self.SYMBOL_RATE_HZ
return long(svTime_s * self.SYMBOL_RATE_HZ)

def getCodeChipIndex(self, svTime_s):
'''
Expand Down
38 changes: 22 additions & 16 deletions peregrine/iqgen/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@
from peregrine.iqgen.bits.satellite_glo import GLOSatellite
from peregrine.iqgen.bits.filter_lowpass import LowPassFilter
from peregrine.iqgen.bits.filter_bandpass import BandPassFilter

from peregrine.iqgen.bits.amplitude_base import NoiseParameters

from peregrine.iqgen.bits import signals

import sys
import traceback
import logging
import scipy
import scipy.constants
import numpy
import time
import copy
Expand Down Expand Up @@ -457,9 +456,15 @@ def printSvInfo(sv_list, outputConfig, lpfFA_db, noiseParams, encoder):
_d2 = signal2.calcDopplerShiftHz(_dist0_m, _speed_mps)
_f1 = signal1.CENTER_FREQUENCY_HZ
_f2 = signal2.CENTER_FREQUENCY_HZ
_bit = signal1.getSymbolIndex(_svTime0_s)
_c1 = signal1.getCodeChipIndex(_svTime0_s)
_c2 = signal2.getCodeChipIndex(_svTime0_s)
_signal_delay1_s = _sv.getDoppler().computeSignalDelayS(
signal1.CENTER_FREQUENCY_HZ)
_signal_delay2_s = _sv.getDoppler().computeSignalDelayS(
signal2.CENTER_FREQUENCY_HZ)

_bit1 = signal1.getSymbolIndex(_signal_delay1_s)
_bit2 = signal1.getSymbolIndex(_signal_delay1_s)
_c1 = signal1.getCodeChipIndex(_signal_delay1_s)
_c2 = signal2.getCodeChipIndex(_signal_delay2_s)

print "{} = {{".format(_svNo)
print " .amplitude: {}".format(_amp)
Expand All @@ -468,25 +473,26 @@ def printSvInfo(sv_list, outputConfig, lpfFA_db, noiseParams, encoder):
print " .l1_message: {}".format(_msg1)
if _sv.isBandEnabled(band2, outputConfig):
print " .l2_message: {}".format(_msg2)
if _l2ct:
print " .l2_cl_type: {}".format(_l2ct)
print " .epoc:"
print " .SNR (dB): {}".format(svSNR_db)
if _sv.isBandEnabled(band1, outputConfig):
print " .L1 CNo: {}".format(svCNoL1)
if _sv.isBandEnabled(band2, outputConfig):
print " .L2 CNo: {}".format(svCNoL2)
print " .distance: {} m".format(_dist0_m)
print " .distance: {} m".format(_sv.getDoppler().distance0_m)
print " .speed: {} m/s".format(_speed_mps)
if _sv.isBandEnabled(band1, outputConfig):
print " .l1 CNo: {}".format(svCNoL1)
print " .l1_doppler: {} hz @ {}".format(_d1, _f1)
if _sv.isBandEnabled(band2, outputConfig):
print " .l2_doppler: {} hz @ {}".format(_d2, _f2)
print " .symbol: {}".format(_bit)
if _sv.isBandEnabled(band1, outputConfig):
print " .l1_delay: {} ms".format(_signal_delay1_s * 1000.)
print " .l1_PR: {} m".format(_signal_delay1_s * scipy.constants.c)
print " .symbol: {}".format(_bit1)
print " .l1_chip: {}".format(_c1)
if _sv.isBandEnabled(band2, outputConfig):
print " .l2 CNo: {}".format(svCNoL2)
print " .l2_doppler: {} hz @ {}".format(_d2, _f2)
print " .l2_delay: {} ms".format(_signal_delay2_s * 1000.)
print " .l1_PR: {} m".format(_signal_delay2_s * scipy.constants.c)
print " .symbol: {}".format(_bit2)
print " .l2_chip: {}".format(_c2)
if _l2ct:
print " .l2_cl_type: {}".format(_l2ct)
print "}"


Expand Down
110 changes: 49 additions & 61 deletions peregrine/iqgen/iqgen_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,17 @@
'snr-db': AmplitudeBase.UNITS_SNR_DB}


def computeTimeDelay(doppler, symbol_index, chip_index, signal):
def computeDistanceDelay(delay_symbols, delay_chips, signal):
'''
Helper function to compute signal delay to match given symbol and chip
indexes.
delays.
Parameters
----------
doppler : object
Doppler object
symbol_index : long
Index of the symbol or pseudosymbol
chip_index : long
Chip index
delay_symbols : float, optional
Delay in symbols
delay_chips : float, optional
Delay in chips
signal : object
Signal object
Expand All @@ -116,13 +114,16 @@ def computeTimeDelay(doppler, symbol_index, chip_index, signal):
User's time in seconds when the user starts receiving the given symbol
and code.
'''
if symbol_index == 0 and chip_index == 0:
return 0.

symbolDelay_s = (1. / signal.SYMBOL_RATE_HZ) * symbol_index
chipDelay_s = (1. / signal.CODE_CHIP_RATE_HZ) * chip_index
distance_m = doppler.computeDistanceM(symbolDelay_s + chipDelay_s)
return distance_m / scipy.constants.c
if delay_symbols is not None:
symbolDelay_s = (1. / signal.SYMBOL_RATE_HZ) * delay_symbols
else:
symbolDelay_s = 0.
if delay_chips is not None:
chipDelay_s = (1. / signal.CODE_CHIP_RATE_HZ) * delay_chips
else:
chipDelay_s = 0.
return (symbolDelay_s + chipDelay_s) * scipy.constants.c


def prepareArgsParser():
Expand Down Expand Up @@ -161,10 +162,12 @@ def __call__(self, parser, namespace, values, option_string=None):
namespace.doppler_type = "zero"
namespace.doppler_value = 0.
namespace.doppler_speed = 0.
namespace.distance = 0.
namespace.distance = None
namespace.tec = 50.
namespace.doppler_amplitude = 0.
namespace.doppler_period = 1.
namespace.symbol_delay = None
namespace.chip_delay = None

# Source message data
namespace.message_type = "zero"
Expand Down Expand Up @@ -231,9 +234,9 @@ def __init__(self, option_strings, dest, nargs=None, **kwargs):
def doUpdate(self, sv, parser, namespace, values, option_string):
if isinstance(sv, GPSSatellite):
if sv.l1caEnabled:
frequency_hz = signals.GPS.L1CA.CENTER_FREQUENCY_HZ
signal = signals.GPS.L1CA
elif sv.l2cEnabled:
frequency_hz = signals.GPS.L2C.CENTER_FREQUENCY_HZ
signal = signals.GPS.L2C
else:
raise ValueError("Signal band must be specified before doppler")
elif isinstance(sv, GLOSatellite):
Expand All @@ -246,21 +249,31 @@ def doUpdate(self, sv, parser, namespace, values, option_string):
else:
raise ValueError("Signal band must be specified before doppler")

frequency_hz = signal.CENTER_FREQUENCY_HZ

# Select distance: either from a distance parameter or from delays
if namespace.symbol_delay is not None or namespace.chip_delay is not None:
distance = computeDistanceDelay(namespace.symbol_delay,
namespace.chip_delay,
signal)
else:
distance = namespace.distance if namespace.distance is not None else 0.

if namespace.doppler_type == "zero":
doppler = zeroDoppler(namespace.distance, namespace.tec, frequency_hz)
doppler = zeroDoppler(distance, namespace.tec, frequency_hz)
elif namespace.doppler_type == "const":
doppler = constDoppler(namespace.distance,
doppler = constDoppler(distance,
namespace.tec,
frequency_hz,
namespace.doppler_value)
elif namespace.doppler_type == "linear":
doppler = linearDoppler(namespace.distance,
doppler = linearDoppler(distance,
namespace.tec,
frequency_hz,
namespace.doppler_value,
namespace.doppler_speed)
elif namespace.doppler_type == "sine":
doppler = sineDoppler(namespace.distance,
doppler = sineDoppler(distance,
namespace.tec,
frequency_hz,
namespace.doppler_value,
Expand Down Expand Up @@ -428,8 +441,6 @@ def __call__(self, parser, namespace, values, option_string=None):
'gps_sv': encoded_gps_sv,
'profile': namespace.profile,
'encoder': namespace.encoder,
'chip_delay': namespace.chip_delay,
'symbol_delay': namespace.symbol_delay,
'generate': namespace.generate,
'noise_sigma': namespace.noise_sigma,
'filter_type': namespace.filter_type,
Expand All @@ -449,8 +460,6 @@ def __call__(self, parser, namespace, values, option_string=None):
loaded = json.load(values)
namespace.profile = loaded['profile']
namespace.encoder = loaded['encoder']
namespace.chip_delay = loaded['chip_delay']
namespace.symbol_delay = loaded['symbol_delay']
namespace.generate = loaded['generate']
namespace.noise_sigma = loaded['noise_sigma']
namespace.filter_type = loaded['filter_type']
Expand Down Expand Up @@ -493,15 +502,25 @@ def __call__(self, parser, namespace, values, option_string=None):

delayGrp = parser.add_argument_group("Signal Delay Control",
"Signal delay control parameters")

# Common delays: ionosphere
delayGrp.add_argument('--tec',
type=float,
help="Ionosphere TEC for signal delay"
" (electrons per meter^2)",
action=UpdateDopplerType)
# Distance control over direct parameter
delayGrp.add_argument('--distance',
type=float,
help="Distance in meters for signal delay (initial)",
action=UpdateDopplerType)
delayGrp.add_argument('--tec',
# Distance control over delays
delayGrp.add_argument('--symbol-delay',
type=float,
help="Ionosphere TEC for signal delay"
" (electrons per meter^2)",
help="Initial symbol index",
action=UpdateDopplerType)
delayGrp.add_argument('--chip-delay',
type=float,
help="Initial chip index",
action=UpdateDopplerType)
dopplerGrp.add_argument('--doppler-amplitude',
type=float,
Expand Down Expand Up @@ -566,12 +585,6 @@ def __call__(self, parser, namespace, values, option_string=None):
choices=['01', '1', '0'],
help="GPS L2 CL code type",
action=UpdateBands)
delayGrp.add_argument('--symbol_delay',
type=int,
help="Initial symbol index")
delayGrp.add_argument('--chip_delay',
type=int,
help="Initial chip index")
parser.add_argument('--filter-type',
default='none',
choices=['none', 'lowpass', 'bandpass'],
Expand Down Expand Up @@ -857,42 +870,17 @@ def main(args=None):
# Check which signals are enabled on each of satellite to select proper
# output encoder
enabledBands = computeEnabledBands(args.gps_sv, outputConfig)

enabledGPSL1 = enabledBands[outputConfig.GPS.L1.NAME]
enabledGPSL2 = enabledBands[outputConfig.GPS.L2.NAME]

# Configure data encoder
encoder = selectEncoder(args.encoder, outputConfig, enabledBands)

if enabledGPSL1:
signal = signals.GPS.L1CA
elif enabledGPSL2:
signal = signals.GPS.L2C
else:
signal = signals.GPS.L1CA

# Compute time delay for the needed bit/chip number
# This delay is computed for the first satellite
initial_symbol_idx = 0 # Initial symbol index
initial_chip_idx = 0 # Initial chip index
if args.chip_delay is not None:
initial_chip_idx = args.chip_delay
if args.symbol_delay is not None:
initial_chip_idx = args.symbol_delay

time0_s = computeTimeDelay(args.gps_sv[0].doppler,
initial_symbol_idx,
initial_chip_idx,
signal)
logger.debug("Computed symbol/chip delay={} seconds".format(time0_s))

startTime_s = time.time()
n_samples = long(outputConfig.SAMPLE_RATE_HZ * args.generate)

logger.debug("Generating {} samples for {} seconds".
format(n_samples, args.generate))

pbar = makeProgressBar(args.progress_bar, n_samples)
time0_s = 0.

generateSamples(args.output,
args.gps_sv,
Expand Down
5 changes: 2 additions & 3 deletions peregrine/tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.

import numpy as np
import os
import math
import parallel_processing as pp
import multiprocessing as mp
Expand All @@ -29,7 +28,7 @@
from peregrine.acquisition import AcquisitionResult
from peregrine.include.generateCAcode import caCodes
from peregrine.include.generateL2CMcode import L2CMCodes
from peregrine.filename_utils import createTrackingOutputFileNames
from peregrine.tracking_file_utils import createTrackingOutputFileNames

import logging
import sys
Expand Down Expand Up @@ -1195,7 +1194,7 @@ def _equal(self, other):
if isinstance(self.__dict__[k], np.ndarray):
# If np.ndarray, elements might be floats, so compare accordingly.
if any(np.greater((self.__dict__[k] - other.__dict__[k]),
np.ones(len(self.__dict__[k])) * 10e-6)):
np.ones(len(self.__dict__[k])) * 10e-6)):
return False
elif self.__dict__[k] != other.__dict__[k]:
return False
Expand Down
Loading

0 comments on commit 375b3f8

Please sign in to comment.