17
17
import numpy as np
18
18
import pyfftw
19
19
import cPickle
20
- import defaults
21
20
22
21
from include .generateCAcode import caCodes
22
+ from include .generateGLOcode import GLOCode
23
+ from peregrine .gps_constants import L1CA
24
+ from peregrine .glo_constants import GLO_L1 , glo_l1_step
23
25
24
26
import logging
25
27
logger = logging .getLogger (__name__ )
@@ -191,13 +193,15 @@ def interpolate(self, S_0, S_1, S_2, interpolation='gaussian'):
191
193
192
194
**Parabolic interpolation:**
193
195
194
- .. math:: \Delta = \\ frac{1}{2} \\ frac{S[k+1] - S[k-1]}{2S[k] - S[k-1] - S[k+1]}
196
+ .. math:: \Delta = \\ frac{1}{2} \\ frac{S[k+1] -
197
+ S[k-1]}{2S[k] - S[k-1] - S[k+1]}
195
198
196
199
Where :math:`S[n]` is the magnitude of FFT bin :math:`n`.
197
200
198
201
**Gaussian interpolation:**
199
202
200
- .. math:: \Delta = \\ frac{1}{2} \\ frac{\ln(S[k+1]) - \ln(S[k-1])}{2\ln(S[k]) - \ln(S[k-1]) - \ln(S[k+1])}
203
+ .. math:: \Delta = \\ frac{1}{2} \\ frac{\ln(S[k+1]) -
204
+ \ln(S[k-1])}{2\ln(S[k]) - \ln(S[k-1]) - \ln(S[k+1])}
201
205
202
206
The Gaussian interpolation method gives better results, especially when
203
207
used with a Gaussian window function, at the expense of computational
@@ -342,24 +346,39 @@ def find_peak(self, freqs, results, interpolation='gaussian'):
342
346
freq_index , cp_samples = np .unravel_index (results .argmax (),
343
347
results .shape )
344
348
345
- if freq_index > 1 and freq_index < len (freqs ) - 1 :
346
- delta = self .interpolate (
347
- results [freq_index - 1 ][cp_samples ],
348
- results [freq_index ][cp_samples ],
349
- results [freq_index + 1 ][cp_samples ],
350
- interpolation
351
- )
352
- if delta > 0 :
353
- freq = freqs [freq_index ] + \
354
- (freqs [freq_index + 1 ] - freqs [freq_index ]) * delta
355
- else :
356
- freq = freqs [freq_index ] - \
357
- (freqs [freq_index - 1 ] - freqs [freq_index ]) * delta
358
- else :
359
- freq = freqs [freq_index ]
360
-
361
349
code_phase = float (cp_samples ) / self .samples_per_chip
362
350
351
+ #print results[freq_index]
352
+ #pp(results[freq_index - 6][cp_samples])
353
+ #pp(results[freq_index - 5][cp_samples])
354
+ #pp(results[freq_index - 4][cp_samples])
355
+ #pp(results[freq_index - 3][cp_samples])
356
+ #pp(results[freq_index - 2][cp_samples])
357
+ #pp(results[freq_index - 1][cp_samples])
358
+ #pp(results[freq_index][cp_samples])
359
+ #pp(results[freq_index + 1][cp_samples])
360
+ #pp(results[freq_index + 2][cp_samples])
361
+ #pp(results[freq_index + 3][cp_samples])
362
+ #pp(results[freq_index + 4][cp_samples])
363
+ #pp(results[freq_index + 5][cp_samples])
364
+ #pp(results[freq_index + 6][cp_samples])
365
+
366
+ #if freq_index > 3 and freq_index < len(freqs) - 3:
367
+ #delta = self.interpolate(
368
+ #results[freq_index - 3][cp_samples],
369
+ #results[freq_index][cp_samples],
370
+ #results[freq_index + 3][cp_samples],
371
+ #interpolation
372
+ #)
373
+ #if delta > 0:
374
+ #freq = freqs[freq_index] + \
375
+ #(freqs[freq_index + 3] - freqs[freq_index]) * delta
376
+ #else:
377
+ #freq = freqs[freq_index] - \
378
+ #(freqs[freq_index - 3] - freqs[freq_index]) * delta
379
+ #else:
380
+ freq = freqs [freq_index ]
381
+
363
382
# Calculate SNR for the peak.
364
383
results_mean = np .mean (results )
365
384
if results_mean != 0 :
@@ -370,7 +389,8 @@ def find_peak(self, freqs, results, interpolation='gaussian'):
370
389
return (code_phase , freq , snr )
371
390
372
391
def acquisition (self ,
373
- prns = range (32 ),
392
+ prns = xrange (32 ),
393
+ channels = [x - 7 for x in xrange (14 )],
374
394
doppler_priors = None ,
375
395
doppler_search = 7000 ,
376
396
doppler_step = None ,
@@ -379,10 +399,10 @@ def acquisition(self,
379
399
multi = True
380
400
):
381
401
"""
382
- Perform an acquisition for a given list of PRNs.
402
+ Perform an acquisition for a given list of PRNs/channels .
383
403
384
- Perform an acquisition for a given list of PRNs across a range of Doppler
385
- frequencies.
404
+ Perform an acquisition for a given list of PRNs/channels across a range of
405
+ Doppler frequencies.
386
406
387
407
This function returns :class:`AcquisitionResult` objects containing the
388
408
location of the acquisition peak for PRNs that have an acquisition
@@ -394,8 +414,13 @@ def acquisition(self,
394
414
395
415
Parameters
396
416
----------
417
+ bandcode : optional
418
+ String defining the acquisition code. Default: L1CA
419
+ choices: L1CA, GLO_L1 (in gps_constants.py)
397
420
prns : iterable, optional
398
421
List of PRNs to acquire. Default: 0..31 (0-indexed)
422
+ channels : iterable, optional
423
+ List of channels to acquire. Default: -7..6
399
424
doppler_prior: list of floats, optional
400
425
List of expected Doppler frequencies in Hz (one per PRN). Search will be
401
426
centered about these. If None, will search around 0 for all PRNs.
@@ -413,10 +438,11 @@ def acquisition(self,
413
438
Returns
414
439
-------
415
440
out : [AcquisitionResult]
416
- A list of :class:`AcquisitionResult` objects, one per PRN in `prns`.
441
+ A list of :class:`AcquisitionResult` objects, one per PRN in `prns` or
442
+ channel in 'channels'.
417
443
418
444
"""
419
- logger .info ("Acquisition starting" )
445
+ logger .info ("Acquisition starting for " + self . signal )
420
446
from peregrine .parallel_processing import parmap
421
447
422
448
# If the Doppler step is not specified, compute it from the coarse
@@ -428,9 +454,6 @@ def acquisition(self,
428
454
# magnitude.
429
455
doppler_step = self .sampling_freq / self .n_integrate
430
456
431
- if doppler_priors is None :
432
- doppler_priors = np .zeros_like (prns )
433
-
434
457
if progress_bar_output == 'stdout' :
435
458
show_progress = True
436
459
progress_fd = sys .stdout
@@ -446,33 +469,55 @@ def acquisition(self,
446
469
show_progress = False
447
470
logger .warning ("show_progress = True but progressbar module not found." )
448
471
472
+ if self .signal == L1CA :
473
+ input_len = len (prns )
474
+ offset = 1
475
+ pb_attr = progressbar .Attribute ('prn' , '(PRN: %02d)' , '(PRN --)' )
476
+ if doppler_priors is None :
477
+ doppler_priors = np .zeros_like (prns )
478
+ else :
479
+ input_len = len (channels )
480
+ offset = 0
481
+ pb_attr = progressbar .Attribute ('ch' , '(CH: %02d)' , '(CH --)' )
482
+ if doppler_priors is None :
483
+ doppler_priors = np .zeros_like (channels )
484
+
449
485
# Setup our progress bar if we need it
450
486
if show_progress and not multi :
451
487
widgets = [' Acquisition ' ,
452
- progressbar . Attribute ( 'prn' , '(PRN: %02d)' , '(PRN --)' ) , ' ' ,
488
+ pb_attr , ' ' ,
453
489
progressbar .Percentage (), ' ' ,
454
490
progressbar .ETA (), ' ' ,
455
491
progressbar .Bar ()]
456
492
pbar = progressbar .ProgressBar (widgets = widgets ,
457
- maxval = int (len ( prns ) *
458
- (2 * doppler_search / doppler_step + 1 )),
493
+ maxval = int (input_len *
494
+ (2 * doppler_search / doppler_step + 1 )),
459
495
fd = progress_fd )
460
496
pbar .start ()
461
497
else :
462
498
pbar = None
463
499
464
500
def do_acq (n ):
465
- prn = prns [n ]
501
+ if self .signal == L1CA :
502
+ prn = prns [n ]
503
+ code = caCodes [prn ]
504
+ int_f = self .IF
505
+ attr = {'prn' : prn + 1 }
506
+ else :
507
+ ch = channels [n ]
508
+ code = GLOCode
509
+ int_f = self .IF + ch * glo_l1_step
510
+ attr = {'ch' : ch }
466
511
doppler_prior = doppler_priors [n ]
467
512
freqs = np .arange (doppler_prior - doppler_search ,
468
- doppler_prior + doppler_search , doppler_step ) + self . IF
513
+ doppler_prior + doppler_search , doppler_step ) + int_f
469
514
if pbar :
470
515
def progress_callback (freq_num , num_freqs ):
471
- pbar .update (n * len (freqs ) + freq_num , attr = { 'prn' : prn + 1 } )
516
+ pbar .update (n * len (freqs ) + freq_num , attr = attr )
472
517
else :
473
518
progress_callback = None
474
519
475
- coarse_results = self .acquire (caCodes [ prn ] , freqs ,
520
+ coarse_results = self .acquire (code , freqs ,
476
521
progress_callback = progress_callback )
477
522
478
523
code_phase , carr_freq , snr = self .find_peak (freqs , coarse_results ,
@@ -485,13 +530,22 @@ def progress_callback(freq_num, num_freqs):
485
530
status = 'A'
486
531
487
532
# Save properties of the detected satellite signal
488
- acq_result = AcquisitionResult (prn ,
489
- carr_freq ,
490
- carr_freq - self .IF ,
491
- code_phase ,
492
- snr ,
493
- status ,
494
- self .signal )
533
+ if self .signal == L1CA :
534
+ acq_result = AcquisitionResult (prn ,
535
+ carr_freq ,
536
+ carr_freq - int_f ,
537
+ code_phase ,
538
+ snr ,
539
+ status ,
540
+ L1CA )
541
+ else :
542
+ acq_result = GloAcquisitionResult (ch ,
543
+ carr_freq ,
544
+ carr_freq - int_f ,
545
+ code_phase ,
546
+ snr ,
547
+ status ,
548
+ GLO_L1 )
495
549
496
550
# If the acquisition was successful, log it
497
551
if (snr > threshold ):
@@ -501,9 +555,9 @@ def progress_callback(freq_num, num_freqs):
501
555
502
556
if multi :
503
557
acq_results = parmap (
504
- do_acq , range ( len ( prns ) ), show_progress = show_progress )
558
+ do_acq , xrange ( input_len ), show_progress = show_progress )
505
559
else :
506
- acq_results = map (do_acq , range ( len ( prns ) ))
560
+ acq_results = map (do_acq , xrange ( input_len ))
507
561
508
562
# Acquisition is finished
509
563
@@ -512,9 +566,11 @@ def progress_callback(freq_num, num_freqs):
512
566
pbar .finish ()
513
567
514
568
logger .info ("Acquisition finished" )
515
- acquired_prns = [ar .prn + 1 for ar in acq_results if ar .status == 'A' ]
516
- logger .info ("Acquired %d satellites, PRNs: %s." ,
517
- len (acquired_prns ), acquired_prns )
569
+ acq = [ar .prn + offset for ar in acq_results if ar .status == 'A' ]
570
+ if self .signal == L1CA :
571
+ logger .info ("Acquired %d satellites, PRNs: %s." , len (acq ), acq )
572
+ else :
573
+ logger .info ("Acquired %d channels: %s." , len (acq ), acq )
518
574
519
575
return acq_results
520
576
@@ -531,7 +587,7 @@ def save_wisdom(self, wisdom_file=DEFAULT_WISDOM_FILE):
531
587
pyfftw .export_wisdom (), f , protocol = cPickle .HIGHEST_PROTOCOL )
532
588
533
589
534
- class AcquisitionResult :
590
+ class AcquisitionResult ( object ) :
535
591
"""
536
592
Stores the acquisition parameters of a single satellite.
537
593
@@ -560,7 +616,7 @@ class AcquisitionResult:
560
616
"""
561
617
562
618
__slots__ = ('prn' , 'carr_freq' , 'doppler' ,
563
- 'code_phase' , 'snr' , 'status' , 'signal' )
619
+ 'code_phase' , 'snr' , 'status' , 'signal' , 'sample_index' )
564
620
565
621
def __init__ (self , prn , carr_freq , doppler , code_phase , snr , status , signal ,
566
622
sample_index = 0 ):
@@ -574,7 +630,7 @@ def __init__(self, prn, carr_freq, doppler, code_phase, snr, status, signal,
574
630
self .sample_index = sample_index
575
631
576
632
def __str__ (self ):
577
- return "PRN %2d (%s) SNR %6.2f @ CP %6.1f , %+8.2f Hz %s" % \
633
+ return "PRN %2d (%s) SNR %6.2f @ CP %6.3f , %+8.2f Hz %s" % \
578
634
(self .prn + 1 , self .signal , self .snr , self .code_phase ,
579
635
self .doppler , self .status )
580
636
@@ -615,6 +671,20 @@ def _equal(self, other):
615
671
return True
616
672
617
673
674
+ class GloAcquisitionResult (AcquisitionResult ):
675
+
676
+ def __init__ (self , channel , carr_freq , doppler , code_phase , snr , status ,
677
+ signal , sample_index = 0 ):
678
+ super (GloAcquisitionResult , self ).__init__ (channel , carr_freq , doppler ,
679
+ code_phase , snr , status ,
680
+ signal , sample_index )
681
+
682
+ def __str__ (self ):
683
+ return "CH %2d (%s) SNR %6.2f @ CP %6.3f, %+8.2f Hz %s" % \
684
+ (self .prn , self .signal , self .snr , self .code_phase , self .doppler ,
685
+ self .status )
686
+
687
+
618
688
def save_acq_results (filename , acq_results ):
619
689
"""
620
690
Save a set of acquisition results to a file.
@@ -676,4 +746,5 @@ def print_scores(acq_results, pred, pred_dopp=None):
676
746
677
747
print "Found %d of %d, mean doppler error = %+5.0f Hz, mean abs err = %4.0f Hz, worst = %+5.0f Hz" \
678
748
% (n_match , len (pred ),
679
- sum_dopp_err / max (1 , n_match ), sum_abs_dopp_err / max (1 , n_match ), worst_dopp_err )
749
+ sum_dopp_err / max (1 , n_match ), sum_abs_dopp_err /
750
+ max (1 , n_match ), worst_dopp_err )
0 commit comments