25
25
from swiftnav .signal import signal_from_code_index
26
26
from peregrine import defaults
27
27
from peregrine import gps_constants
28
+ from peregrine import glo_constants
28
29
from peregrine import alias_detector
29
30
from peregrine .acquisition import AcquisitionResult
31
+ from peregrine .acquisition import GloAcquisitionResult
30
32
from peregrine .include .generateCAcode import caCodes
31
33
from peregrine .include .generateL2CMcode import L2CMCodes
34
+ from peregrine .include .generateGLOcode import GLOCode
32
35
from peregrine .tracking_file_utils import createTrackingOutputFileNames
33
36
34
37
import logging
@@ -120,6 +123,8 @@ def _tracking_channel_factory(parameters):
120
123
return TrackingChannelL1CA (parameters )
121
124
if parameters ['acq' ].signal == gps_constants .L2C :
122
125
return TrackingChannelL2C (parameters )
126
+ if parameters ['acq' ].signal == glo_constants .GLO_L1 :
127
+ return TrackingChannelGLOL1 (parameters )
123
128
124
129
125
130
class TrackingChannel (object ):
@@ -686,6 +691,7 @@ def _run_postprocess(self):
686
691
687
692
# Handover to L2C if possible
688
693
if self .l2c_handover and not self .l2c_handover_acq and \
694
+ gps_constants .L2C in self .samples and \
689
695
'samples' in self .samples [gps_constants .L2C ] and sync :
690
696
chan_snr = self .track_result .cn0 [self .i ]
691
697
chan_snr -= 10 * np .log10 (defaults .L1CA_CHANNEL_BANDWIDTH_HZ )
@@ -808,6 +814,139 @@ def _run_postprocess(self):
808
814
self .coherent_ms
809
815
810
816
817
+ class TrackingChannelGLOL1 (TrackingChannel ):
818
+ """
819
+ GLO L1 tracking channel.
820
+ """
821
+
822
+ def __init__ (self , params ):
823
+ """
824
+ Initialize GLO L1 tracking channel with GLO L1 specific data.
825
+
826
+ Parameters
827
+ ----------
828
+ params : dictionary
829
+ GLO L1 tracking initialization parameters
830
+
831
+ """
832
+ # Convert acquisition SNR to C/N0
833
+ cn0_0 = 10 * np .log10 (params ['acq' ].snr )
834
+ cn0_0 += 10 * np .log10 (defaults .GLOL1_CHANNEL_BANDWIDTH_HZ )
835
+ params ['cn0_0' ] = cn0_0
836
+ params ['coherent_ms' ] = 1
837
+ params ['coherent_iter' ] = 1
838
+ params ['loop_filter_params' ] = defaults .l1ca_stage1_loop_filter_params
839
+ params ['lock_detect_params' ] = defaults .l1ca_lock_detect_params_opt
840
+ params ['IF' ] = params ['samples' ][glo_constants .GLO_L1 ]['IF' ]
841
+ params ['prn_code' ] = GLOCode
842
+ params ['code_freq_init' ] = params ['acq' ].doppler * \
843
+ glo_constants .glo_chip_rate / glo_constants .glo_l1
844
+ params ['chipping_rate' ] = glo_constants .glo_chip_rate
845
+ params ['sample_index' ] = 0
846
+ params ['alias_detector' ] = \
847
+ alias_detector .AliasDetectorGLO (params ['coherent_ms' ])
848
+
849
+ TrackingChannel .__init__ (self , params )
850
+
851
+ self .glol2_handover_acq = None
852
+ self .glol2_handover_done = False
853
+
854
+ # TODO add nav msg decoder (GLO L1)
855
+
856
+ def is_pickleable (self ):
857
+ """
858
+ GLO L1 tracking channel object is not pickleable due to complexity
859
+ of serializing cnav_msg_decoder Cython object.
860
+
861
+ out : bool
862
+ False - the GLO L1 tracking object is not pickleable
863
+ """
864
+ return False
865
+
866
+ def _get_result (self ):
867
+ """
868
+ Get GLO L1 tracking results.
869
+ The possible outcome of GLO L1 tracking operation is
870
+ the GLO L1 handover to GLO L2 in the form of an GloAcquisitionResult object.
871
+
872
+ Returns
873
+ -------
874
+ out : AcquisitionResult
875
+ GLO L2 acquisition result or None
876
+
877
+ """
878
+
879
+ if self .glol2_handover_acq and not self .glol2_handover_done :
880
+ self .glol2_handover_done = True
881
+ return self .glol2_handover_acq
882
+ return None
883
+
884
+ def _run_preprocess (self ):
885
+ """
886
+ Run GLONASS tracking loop preprocessor operation.
887
+ It runs before every coherent integration round.
888
+
889
+ """
890
+
891
+ self .coherent_iter = self .coherent_ms
892
+
893
+ def _short_n_long_preprocess (self ):
894
+ if self .stage1 :
895
+ self .E = self .P = self .L = 0.j
896
+ else :
897
+ # When simulating short and long cycles, short step resets EPL
898
+ # registers, and long one adds up to them
899
+ if self .short_step :
900
+ self .E = self .P = self .L = 0.j
901
+ self .coherent_iter = 1
902
+ else :
903
+ self .coherent_iter = self .coherent_ms - 1
904
+
905
+ self .code_chips_to_integrate = glo_constants .glo_code_len
906
+
907
+ return self .coherent_iter , self .code_chips_to_integrate
908
+
909
+ def _short_n_long_postprocess (self ):
910
+ more_integration_needed = False
911
+ if not self .stage1 :
912
+ if self .short_step :
913
+ # In case of short step - go to next integration period
914
+ self .short_step = False
915
+ more_integration_needed = True
916
+ else :
917
+ # Next step is short cycle
918
+ self .short_step = True
919
+ return more_integration_needed
920
+
921
+ def _run_postprocess (self ):
922
+ """
923
+ Run GLO L1 coherent integration postprocessing.
924
+ Runs navigation bit sync decoding operation and
925
+ GLO L1 to GLO L2 handover.
926
+ """
927
+
928
+ # Handover to L2C if possible
929
+ if self .glol2_handover and not self .glol2_handover_acq and \
930
+ glo_constants .GLO_L2 in self .samples and \
931
+ 'samples' in self .samples [glo_constants .GLO_L2 ]: # and sync:
932
+ chan_snr = self .track_result .cn0 [self .i ]
933
+ # chan_snr -= 10 * np.log10(defaults.GLOL1_CHANNEL_BANDWIDTH_HZ)
934
+ chan_snr = np .power (10 , chan_snr / 10 )
935
+ glol2_doppler = self .loop_filter .to_dict ()['carr_freq' ] * \
936
+ glo_constants .glo_l2 / glo_constants .glo_l1
937
+ self .glol2_handover_acq = \
938
+ GloAcquisitionResult (self .prn ,
939
+ self .samples [glo_constants .GLO_L2 ]['IF' ] +
940
+ glol2_doppler ,
941
+ glol2_doppler , # carrier doppler
942
+ self .track_result .code_phase [
943
+ self .i ],
944
+ chan_snr ,
945
+ 'A' ,
946
+ glo_constants .GLO_L2 ,
947
+ self .track_result .absolute_sample [self .i ])
948
+
949
+
811
950
class Tracker (object ):
812
951
"""
813
952
Tracker class.
@@ -822,6 +961,7 @@ def __init__(self,
822
961
sampling_freq ,
823
962
check_l2c_mask = False ,
824
963
l2c_handover = True ,
964
+ glol2_handover = True ,
825
965
progress_bar_output = 'none' ,
826
966
loop_filter_class = AidedTrackingLoop ,
827
967
correlator = track_correlate ,
@@ -877,6 +1017,7 @@ def __init__(self,
877
1017
self .tracker_options = tracker_options
878
1018
self .output_file = output_file
879
1019
self .l2c_handover = l2c_handover
1020
+ self .glol2_handover = glol2_handover
880
1021
self .check_l2c_mask = check_l2c_mask
881
1022
self .correlator = correlator
882
1023
self .stage2_coherent_ms = stage2_coherent_ms
@@ -1021,6 +1162,7 @@ def _create_channel(self, acq):
1021
1162
'samples_to_track' : self .samples_to_track ,
1022
1163
'sampling_freq' : self .sampling_freq ,
1023
1164
'l2c_handover' : l2c_handover ,
1165
+ 'glol2_handover' : self .glol2_handover ,
1024
1166
'show_progress' : self .show_progress ,
1025
1167
'correlator' : self .correlator ,
1026
1168
'stage2_coherent_ms' : self .stage2_coherent_ms ,
0 commit comments