diff --git a/conf/gnss-sdr_GPS_hybrid_short.conf b/conf/gnss-sdr_GPS_hybrid_short.conf index a01e3167b..053c04a28 100644 --- a/conf/gnss-sdr_GPS_hybrid_short.conf +++ b/conf/gnss-sdr_GPS_hybrid_short.conf @@ -194,7 +194,7 @@ Acquisition_GPS.sampled_ms=1 ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold -Acquisition_GPS.threshold=0.01 +Acquisition_GPS.threshold=0.0075 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] ;Acquisition_GPS.pfa=0.01 ;#doppler_max: Maximum expected Doppler shift [Hz] @@ -220,7 +220,7 @@ Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_Galileo.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_Galileo.pfa=0.00002 +Acquisition_Galileo.pfa=0.0000008 ;#doppler_max: Maximum expected Doppler shift [Hz] Acquisition_Galileo.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] @@ -243,7 +243,7 @@ Tracking_GPS.dump=false Tracking_GPS.dump_filename=../data/epl_tracking_ch_ ;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_GPS.pll_bw_hz=50.0; +Tracking_GPS.pll_bw_hz=45.0; ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_GPS.dll_bw_hz=4.0; @@ -271,7 +271,7 @@ Tracking_Galileo.dump=false Tracking_Galileo.dump_filename=../data/veml_tracking_ch_ ;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_Galileo.pll_bw_hz=20.0; +Tracking_Galileo.pll_bw_hz=15.0; ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_Galileo.dll_bw_hz=2.0; diff --git a/conf/gnss-sdr_Galileo_E1.conf b/conf/gnss-sdr_Galileo_E1.conf index 6603102c4..c901eeb08 100644 --- a/conf/gnss-sdr_Galileo_E1.conf +++ b/conf/gnss-sdr_Galileo_E1.conf @@ -164,12 +164,11 @@ Resampler.sample_freq_out=4000000 ;######### CHANNELS GLOBAL CONFIG ############ -;#count: Number of available satellite channels. ;#count: Number of available GPS satellite channels. Channels_GPS.count=0 ;#count: Number of available Galileo satellite channels. Channels_Galileo.count=4 -;#in_acquisition: Number of channels simultaneously acquiring +;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 ;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS ;#if the option is disabled by default is assigned GPS @@ -281,7 +280,7 @@ Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_Galileo.pfa=0.00003 +Acquisition_Galileo.pfa=0.0000008 ;#doppler_max: Maximum expected Doppler shift [Hz] Acquisition_Galileo.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] diff --git a/conf/gnss-sdr_Galileo_E1_IFEN.conf b/conf/gnss-sdr_Galileo_E1_IFEN.conf index 35a399f86..cc2167c66 100644 --- a/conf/gnss-sdr_Galileo_E1_IFEN.conf +++ b/conf/gnss-sdr_Galileo_E1_IFEN.conf @@ -19,7 +19,7 @@ ControlThread.wait_for_flowgraph=false SignalSource.implementation=Nsr_File_Signal_Source ;#filename: path to file with the captured GNSS signal samples to be processed -SignalSource.filename=/media/DATALOGGER/ION GNSS 2013/E1L1_FE0_Band0.stream +SignalSource.filename=/Volumes/BOOTCAMP/signals/ifen/E1L1_FE0_Band0.stream ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=byte @@ -148,11 +148,12 @@ InputFilter.decimation_factor=8 ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation Resampler.implementation=Pass_Through - ;######### CHANNELS GLOBAL CONFIG ############ -;#count: Number of available satellite channels. -Channels.count=6 -;#in_acquisition: Number of channels simultaneously acquiring +;#count: Number of available GPS satellite channels. +Channels_GPS.count=0 +;#count: Number of available Galileo satellite channels. +Channels_Galileo.count=6 +;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 ;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS ;#if the option is disabled by default is assigned GPS @@ -217,78 +218,115 @@ Channel.system=Galileo ;#if the option is disabled by default is assigned "1C" GPS L1 C/A Channel.signal=1B + + +;Galileo FM3 -> PRN 19 +;Galileo FM4 -> PRN 20 +;######### CHANNEL 0 CONFIG ############ + +;Channel0.system=Galileo +;Channel0.signal=1B +;#satellite: Satellite PRN ID for this channel. Disable this option to random search +;Channel0.satellite=20 + +;######### CHANNEL 1 CONFIG ############ + +;Channel1.system=Galileo +;Channel1.signal=1B +;Channel1.satellite=12 + +;######### CHANNEL 2 CONFIG ############ + +;Channel2.system=Galileo +;Channel2.signal=1B +;#satellite: Satellite PRN ID for this channel. Disable this option to random search +;Channel2.satellite=11 + +;######### CHANNEL 3 CONFIG ############ + +;Channel3.system=Galileo +;Channel3.signal=1B +;Channel3.satellite=19 + ;######### ACQUISITION GLOBAL CONFIG ############ ;#dump: Enable or disable the acquisition internal data file logging [true] or [false] Acquisition.dump=false ;#filename: Log path and filename -Acquisition.dump_filename=./acq_dump.dat +Acquisition_Galileo.dump_filename=./acq_dump.dat ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Acquisition.item_type=gr_complex +Acquisition_Galileo.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] -Acquisition.if=0 +Acquisition_Galileo.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] -Acquisition.sampled_ms=4 +Acquisition_Galileo.sampled_ms=4 ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition.pfa=0.00001 +Acquisition_Galileo.pfa=0.0000008 ;#doppler_max: Maximum expected Doppler shift [Hz] -Acquisition.doppler_max=10000 +Acquisition_Galileo.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] -Acquisition.doppler_step=125 +Acquisition_Galileo.doppler_step=125 ;######### ACQUISITION CHANNELS CONFIG ###### ;######### ACQUISITION CH 0 CONFIG ############ ;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false -;Acquisition0.repeat_satellite = false +;Acquisition_Galileo0.repeat_satellite = true +;Acquisition_Galileo1.repeat_satellite = true +;Acquisition_Galileo2.repeat_satellite = true +;Acquisition_Galileo3.repeat_satellite = true + ;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false]. ;#Use only if GNSS-SDR.internal_fs_hz is greater than or equal to 6138000 -Acquisition0.cboc=false +Acquisition_Galileo0.cboc=false ;######### ACQUISITION CH 1 CONFIG ############ -Acquisition1.cboc=false +Acquisition_Galileo1.cboc=false ;######### TRACKING GLOBAL CONFIG ############ ;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] -Tracking.implementation=Galileo_E1_DLL_PLL_VEML_Tracking +Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking ;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. -Tracking.item_type=gr_complex +Tracking_Galileo.item_type=gr_complex ;#sampling_frequency: Signal Intermediate Frequency in [Hz] -Tracking.if=0 +Tracking_Galileo.if=0 ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking.dump=false +Tracking_Galileo.dump=true ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking.dump_filename=../data/veml_tracking_ch_ +Tracking_Galileo.dump_filename=../data/veml_tracking_ch_ ;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking.pll_bw_hz=20.0; +Tracking_Galileo.pll_bw_hz=20.0; ;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking.dll_bw_hz=2.0; +Tracking_Galileo.dll_bw_hz=2.0; + +;#fll_bw_hz: FLL loop filter bandwidth [Hz] +Tracking_Galileo.fll_bw_hz=10.0; ;#order: PLL/DLL loop filter order [2] or [3] -Tracking.order=3; +Tracking_Galileo.order=3; ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo -Tracking.early_late_space_chips=0.15; +Tracking_Galileo.early_late_space_chips=0.15; ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] -Tracking.very_early_late_space_chips=0.6; +Tracking_Galileo.very_early_late_space_chips=0.6; ;######### TELEMETRY DECODER CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B -TelemetryDecoder.implementation=Galileo_E1B_Telemetry_Decoder -TelemetryDecoder.dump=false +TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder +TelemetryDecoder_Galileo.dump=false ;######### OBSERVABLES CONFIG ############ ;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A. diff --git a/conf/gnss-sdr_Hybrid_IFEN.conf b/conf/gnss-sdr_Hybrid_IFEN.conf new file mode 100644 index 000000000..63d59e987 --- /dev/null +++ b/conf/gnss-sdr_Hybrid_IFEN.conf @@ -0,0 +1,328 @@ +; Default configuration file +; You can define your own receiver and invoke it by doing +; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf +; + +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. +;GNSS-SDR.internal_fs_hz=6826700 +GNSS-SDR.internal_fs_hz=2560000 +;GNSS-SDR.internal_fs_hz=4096000 +;GNSS-SDR.internal_fs_hz=5120000 + +;######### CONTROL_THREAD CONFIG ############ +ControlThread.wait_for_flowgraph=false +;######### SIGNAL_SOURCE CONFIG ############ +;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +SignalSource.implementation=Nsr_File_Signal_Source + +;#filename: path to file with the captured GNSS signal samples to be processed +SignalSource.filename=/Volumes/BOOTCAMP/signals/ifen/E1L1_FE0_Band0.stream + +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +SignalSource.item_type=byte + +;#sampling_frequency: Original Signal sampling frequency in [Hz] +SignalSource.sampling_frequency=20480000 + +;#freq: RF front-end center frequency in [Hz] +SignalSource.freq=1575420000 + +;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) +SignalSource.subdevice=B:0 + +;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. +SignalSource.samples=0 + +;#repeat: Repeat the processing file. Disable this option in this version +SignalSource.repeat=false + +;#dump: Dump the Signal source data to a file. Disable this option in this version +SignalSource.dump=false + +SignalSource.dump_filename=../data/signal_source.dat + + +;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. +; it helps to not overload the CPU, but the processing time will be longer. +SignalSource.enable_throttle_control=false + + +;######### SIGNAL_CONDITIONER CONFIG ############ +;## It holds blocks to change data type, filter and resample input data. + +;#implementation: Use [Pass_Through] or [Signal_Conditioner] +;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks +;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks +SignalConditioner.implementation=Signal_Conditioner + +;######### DATA_TYPE_ADAPTER CONFIG ############ +;## Changes the type of input data. +;#implementation: [Pass_Through] disables this block +DataTypeAdapter.implementation=Pass_Through +DataTypeAdapter.item_type=float + +;######### INPUT_FILTER CONFIG ############ +;## Filter the input data. Can be combined with frequency translation for IF signals + +;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter] +;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation +;# that shifts IF down to zero Hz. + +InputFilter.implementation=Freq_Xlating_Fir_Filter + +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat + +;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. +;#These options are based on parameters of gnuradio's function: gr_remez. +;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse +;#reponse given a set of band edges, the desired reponse on those bands, +;#and the weight given to the error in those bands. + +;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +InputFilter.input_item_type=float + +;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +InputFilter.output_item_type=gr_complex + +;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. +InputFilter.taps_item_type=float + +;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time +InputFilter.number_of_taps=5 + +;#number_of _bands: Number of frequency bands in the filter. +InputFilter.number_of_bands=2 + +;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]. +;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2) +;#The number of band_begin and band_end elements must match the number of bands + +InputFilter.band1_begin=0.0 +InputFilter.band1_end=0.45 +InputFilter.band2_begin=0.55 +InputFilter.band2_end=1.0 + +;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]. +;#The number of ampl_begin and ampl_end elements must match the number of bands + +InputFilter.ampl1_begin=1.0 +InputFilter.ampl1_end=1.0 +InputFilter.ampl2_begin=0.0 +InputFilter.ampl2_end=0.0 + +;#band_error: weighting applied to each band (usually 1). +;#The number of band_error elements must match the number of bands +InputFilter.band1_error=1.0 +InputFilter.band2_error=1.0 + +;#filter_type: one of "bandpass", "hilbert" or "differentiator" +InputFilter.filter_type=bandpass + +;#grid_density: determines how accurately the filter will be constructed. +;The minimum value is 16; higher values are slower to compute the filter. +InputFilter.grid_density=16 + +;# Original sampling frequency stored in the signal file +InputFilter.sampling_frequency=20480000 + +;#The following options are used only in Freq_Xlating_Fir_Filter implementation. +;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz + +InputFilter.IF=5499998.47412109 + +;# Decimation factor after the frequency tranaslating block +InputFilter.decimation_factor=8 + + +;######### RESAMPLER CONFIG ############ +;## Resamples the input data. + +;#implementation: Use [Pass_Through] or [Direct_Resampler] +;#[Pass_Through] disables this block +;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation +Resampler.implementation=Pass_Through + +;######### CHANNELS GLOBAL CONFIG ############ +;#count: Number of available GPS satellite channels. +Channels_GPS.count=4 +;#count: Number of available Galileo satellite channels. +Channels_Galileo.count=4 +;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver +Channels.in_acquisition=1 +;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS +;#if the option is disabled by default is assigned GPS +Channel.system=GPS, Galileo + +;#signal: +;#if the option is disabled by default is assigned "1C" GPS L1 C/A +Channel.signal=1C + + +;######### GPS ACQUISITION CONFIG ############ + +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_GPS.dump=false +;#filename: Log path and filename +Acquisition_GPS.dump_filename=./acq_dump.dat +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_GPS.item_type=gr_complex +;#if: Signal intermediate frequency in [Hz] +Acquisition_GPS.if=0 +;#sampled_ms: Signal block duration for the acquisition signal detection [ms] +Acquisition_GPS.sampled_ms=1 +;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition +;#threshold: Acquisition threshold +Acquisition_GPS.threshold=0.0075 +;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +;Acquisition_GPS.pfa=0.01 +;#doppler_max: Maximum expected Doppler shift [Hz] +Acquisition_GPS.doppler_max=10000 +;#doppler_max: Doppler step in the grid search [Hz] +Acquisition_GPS.doppler_step=500 + + +;######### GALILEO ACQUISITION CONFIG ############ + +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_Galileo.dump=false +;#filename: Log path and filename +Acquisition_Galileo.dump_filename=./acq_dump.dat +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_Galileo.item_type=gr_complex +;#if: Signal intermediate frequency in [Hz] +Acquisition_Galileo.if=0 +;#sampled_ms: Signal block duration for the acquisition signal detection [ms] +Acquisition_Galileo.sampled_ms=4 +;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#threshold: Acquisition threshold +;Acquisition_Galileo.threshold=0 +;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +Acquisition_Galileo.pfa=0.0000008 +;#doppler_max: Maximum expected Doppler shift [Hz] +Acquisition_Galileo.doppler_max=15000 +;#doppler_max: Doppler step in the grid search [Hz] +Acquisition_Galileo.doppler_step=125 + +;######### TRACKING GPS CONFIG ############ + +;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] +Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking +;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +Tracking_GPS.item_type=gr_complex + +;#sampling_frequency: Signal Intermediate Frequency in [Hz] +Tracking_GPS.if=0 + +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_GPS.dump=false + +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_GPS.dump_filename=../data/epl_tracking_ch_ + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_GPS.pll_bw_hz=45.0; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_GPS.dll_bw_hz=4.0; + +;#fll_bw_hz: FLL loop filter bandwidth [Hz] +Tracking_GPS.fll_bw_hz=10.0; + +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_GPS.order=3; + +;######### TRACKING GALILEO CONFIG ############ + +;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] +Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking +;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +Tracking_Galileo.item_type=gr_complex + +;#sampling_frequency: Signal Intermediate Frequency in [Hz] +Tracking_Galileo.if=0 + +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_Galileo.dump=false + +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_Galileo.dump_filename=../data/veml_tracking_ch_ + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_Galileo.pll_bw_hz=15.0; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_Galileo.dll_bw_hz=2.0; + +;#fll_bw_hz: FLL loop filter bandwidth [Hz] +Tracking_Galileo.fll_bw_hz=10.0; + +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_Galileo.order=3; + +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo +Tracking_Galileo.early_late_space_chips=0.15; + +;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] +Tracking_Galileo.very_early_late_space_chips=0.6; + + +;######### TELEMETRY DECODER GPS CONFIG ############ +;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A +TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_GPS.dump=false +;#decimation factor +TelemetryDecoder_GPS.decimation_factor=4; + +;######### TELEMETRY DECODER GALILEO CONFIG ############ +;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B +TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder +TelemetryDecoder_Galileo.dump=false + + +;######### OBSERVABLES CONFIG ############ +;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A. +Observables.implementation=Hybrid_Observables + +;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] +Observables.dump=false + +;#dump_filename: Log path and filename. +Observables.dump_filename=./observables.dat + + +;######### PVT CONFIG ############ +;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. +PVT.implementation=Hybrid_PVT + +;#averaging_depth: Number of PVT observations in the moving average algorithm +PVT.averaging_depth=10 + +;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false] +PVT.flag_averaging=false + +;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms] +PVT.output_rate_ms=10; + +;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms. +PVT.display_rate_ms=500; + +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false + +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT + +;######### OUTPUT_FILTER CONFIG ############ +;# Receiver output filter: Leave this block disabled in this version +OutputFilter.implementation=Null_Sink_Output_Filter +OutputFilter.filename=data/gnss-sdr.dat +OutputFilter.item_type=gr_complex \ No newline at end of file diff --git a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc index 2d3a97aa3..c1b28f7d0 100644 --- a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc @@ -152,7 +152,7 @@ int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items, //d_rx_time = in[i][0].d_TOW_at_current_symbol; // all the channels have the same RX timestamp (common RX time pseudoranges) d_TOW_at_curr_symbol_constellation=in[i][0].d_TOW_at_current_symbol; // d_TOW_at_current_symbol not corrected by delta t (just for debug) d_rx_time = in[i][0].d_TOW_hybrid_at_current_symbol; // hybrid rx time, all the channels have the same RX timestamp (common RX time pseudoranges) - std::cout<<"CH PVT = "<< i << ", d_TOW = " << d_TOW_at_curr_symbol_constellation<<", rx_time_hybrid_PVT = " << d_rx_time << " same RX timestamp (common RX time pseudoranges)"<< std::endl; + //std::cout<<"CH PVT = "<< i << ", d_TOW = " << d_TOW_at_curr_symbol_constellation<<", rx_time_hybrid_PVT = " << d_rx_time << " same RX timestamp (common RX time pseudoranges)"<< std::endl; } } @@ -197,19 +197,21 @@ int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items, // ############ 2 COMPUTE THE PVT ################################ - if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->galileo_ephemeris_map.size() > 0 and d_ls_pvt->gps_ephemeris_map.size() > 0) + // ToDo: relax this condition because the receiver shuld work even with NO GALILEO SATELLITES + //if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->galileo_ephemeris_map.size() > 0 and d_ls_pvt->gps_ephemeris_map.size() > 0) + if (gnss_pseudoranges_map.size() > 0) { - std::cout << "Both GPS and Galileo ephemeris map have been filled " << std::endl; + //std::cout << "Both GPS and Galileo ephemeris map have been filled " << std::endl; // compute on the fly PVT solution if ((d_sample_counter % d_output_rate_ms) == 0) { - bool pvt_result; - pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging); - std::cout << "pvt_result = " << pvt_result << std::endl; + //bool pvt_result; + d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging); + //std::cout << "pvt_result = " << pvt_result << std::endl; - if (pvt_result == true) + if (d_ls_pvt->b_valid_position == true) { - //IMPLEMENT KML OUTPUT d_kml_dump.print_position_galileo(d_ls_pvt, d_flag_averaging); + d_kml_dump.print_position_hybrid(d_ls_pvt, d_flag_averaging); //ToDo: Implement Galileo RINEX and Galileo NMEA outputs // d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging); // @@ -247,15 +249,15 @@ int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items, if (((d_sample_counter % d_display_rate_ms) == 0) and d_ls_pvt->b_valid_position == true) { std::cout << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time) - << " is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d + << " using "<d_valid_observations<<" observations is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d << " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl; LOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time) - << " is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d + << " using "<d_valid_observations<<" observations is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d << " [deg], Height= " << d_ls_pvt->d_height_m << " [m]"; LOG(INFO) << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time) - << " is HDOP = " << d_ls_pvt->d_HDOP << " VDOP = " + << " using "<d_valid_observations<<" observations is HDOP = " << d_ls_pvt->d_HDOP << " VDOP = " << d_ls_pvt->d_VDOP <<" TDOP = " << d_ls_pvt->d_TDOP << " GDOP = " << d_ls_pvt->d_GDOP; } diff --git a/src/algorithms/PVT/libs/hybrid_ls_pvt.cc b/src/algorithms/PVT/libs/hybrid_ls_pvt.cc index 4085f41cf..141bd96d7 100644 --- a/src/algorithms/PVT/libs/hybrid_ls_pvt.cc +++ b/src/algorithms/PVT/libs/hybrid_ls_pvt.cc @@ -251,7 +251,7 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_pseudoranges_map, do if (gnss_pseudoranges_iter->second.System == 'E') { - std::cout << "Satellite System: " << gnss_pseudoranges_iter->second.System <second.System <first); if (galileo_ephemeris_iter != galileo_ephemeris_map.end()) @@ -270,7 +270,7 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_pseudoranges_map, do //JAVIER VERSION: double Rx_time = hybrid_current_time; - std::cout<<"Gal_Rx_time = "<< Rx_time << std::endl; + //std::cout<<"Gal_Rx_time = "<< Rx_time << std::endl; //to compute satellite position we need GST = WN+TOW (everything expressed in seconds) //double Rx_time = galileo_current_time + Galileo_week_number*sec_in_day*day_in_week; @@ -322,7 +322,7 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_pseudoranges_map, do << " [m] Y=" << galileo_ephemeris_iter->second.d_satpos_Y << " [m] Z=" << galileo_ephemeris_iter->second.d_satpos_Z << " [m] PR_obs=" << obs(obs_counter) << " [m]"; - std::cout<<"E"<second.i_satellite_PRN<< " satellite position computed"<< std::endl; + //std::cout<<"E"<second.i_satellite_PRN<< " satellite position computed"<< std::endl; } else // the ephemeris are not available for this SV @@ -337,7 +337,7 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_pseudoranges_map, do } else if (gnss_pseudoranges_iter->second.System == 'G') { - std::cout << "Satellite System: " << gnss_pseudoranges_iter->second.System <second.System <first); if (gps_ephemeris_iter != gps_ephemeris_map.end()) @@ -350,7 +350,7 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_pseudoranges_map, do // COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files) // first estimate of transmit time double Rx_time = hybrid_current_time; - std::cout<<"Gps_Rx_time = "<< Rx_time << std::endl; + //std::cout<<"Gps_Rx_time = "<< Rx_time << std::endl; double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GPS_C_m_s; //std::cout<<"Gps_Tx_time = "<< Tx_time << std::endl; // 2- compute the clock drift using the clock model (broadcast) for this SV @@ -380,7 +380,7 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_pseudoranges_map, do << " [m] Y=" << gps_ephemeris_iter->second.d_satpos_Y << " [m] Z=" << gps_ephemeris_iter->second.d_satpos_Z << " [m] PR_obs=" << obs(obs_counter) << " [m]"; - std::cout<<"G"<second.i_satellite_PRN<< " satellite position computed"<< std::endl; + //std::cout<<"G"<second.i_satellite_PRN<< " satellite position computed"<< std::endl; @@ -405,174 +405,180 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_pseudoranges_map, do obs_counter++; - std::cout<<"Number of observations in PVT = " << obs_counter << std::endl; } + //std::cout<<"Number of observations in PVT = " << obs_counter << std::endl; // ******************************************************************************** // ****** SOLVE LEAST SQUARES****************************************************** // ******************************************************************************** d_valid_observations = valid_obs; - LOG(INFO) << "Galileo PVT: valid observations=" << valid_obs; + LOG(INFO) << "HYBRID PVT: valid observations=" << valid_obs; if (valid_obs >= 4) { + //std::cout<<"LS SOLVER CALLED " << obs_counter << std::endl; + arma::vec mypos; + //std::cout << "satpos=" << satpos; + //std::cout << "obs="<< obs; + //std::cout << "W=" << W; + DLOG(INFO) << "satpos=" << satpos; + DLOG(INFO) << "obs="<< obs; + DLOG(INFO) << "W=" << W; + mypos = leastSquarePos(satpos, obs, W); -// arma::vec mypos; -// DLOG(INFO) << "satpos=" << satpos; -// DLOG(INFO) << "obs="<< obs; -// DLOG(INFO) << "W=" << W; -// mypos = leastSquarePos(satpos, obs, W); -// -// // Compute GST and Gregorian time -// double GST = galileo_ephemeris_iter->second.Galileo_System_Time(Galileo_week_number, hybrid_current_time); -// utc = galileo_utc_model.GST_to_UTC_time(GST, Galileo_week_number); -// // get time string Gregorian calendar -// boost::posix_time::time_duration t = boost::posix_time::seconds(utc); -// // 22 August 1999 00:00 last Galileo start GST epoch (ICD sec 5.1.2) -// boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); -// d_position_UTC_time = p_time; -// LOG(INFO) << "Galileo Position at TOW=" << hybrid_current_time << " in ECEF (X,Y,Z) = " << mypos; -// -// cart2geo((double)mypos(0), (double)mypos(1), (double)mypos(2), 4); -// //ToDo: Find an Observables/PVT random bug with some satellite configurations that gives an erratic PVT solution (i.e. height>50 km) -// if (d_height_m > 50000) -// { -// b_valid_position = false; -// return false; -// } -// LOG(INFO) << "Galileo Position at " << boost::posix_time::to_simple_string(p_time) -// << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d -// << " [deg], Height= " << d_height_m << " [m]"; -// -// std::cout << "Galileo Position at " << boost::posix_time::to_simple_string(p_time) -// << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d -// << " [deg], Height= " << d_height_m << " [m]" << std::endl; -// -// // ###### Compute DOPs ######## -// // 1- Rotation matrix from ECEF coordinates to ENU coordinates -// // ref: http://www.navipedia.net/index.php/Transformations_between_ECEF_and_ENU_coordinates -// arma::mat F = arma::zeros(3,3); -// F(0,0) = -sin(GPS_TWO_PI*(d_longitude_d/360.0)); -// F(0,1) = -sin(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0)); -// F(0,2) = cos(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0)); -// -// F(1,0) = cos((GPS_TWO_PI*d_longitude_d)/360.0); -// F(1,1) = -sin((GPS_TWO_PI*d_latitude_d)/360.0)*sin((GPS_TWO_PI*d_longitude_d)/360.0); -// F(1,2) = cos((GPS_TWO_PI*d_latitude_d/360.0))*sin((GPS_TWO_PI*d_longitude_d)/360.0); -// -// F(2,0) = 0; -// F(2,1) = cos((GPS_TWO_PI*d_latitude_d)/360.0); -// F(2,2) = sin((GPS_TWO_PI*d_latitude_d/360.0)); -// -// // 2- Apply the rotation to the latest covariance matrix (available in ECEF from LS) -// arma::mat Q_ECEF = d_Q.submat(0, 0, 2, 2); -// arma::mat DOP_ENU = arma::zeros(3, 3); -// -// try -// { -// DOP_ENU = arma::htrans(F)*Q_ECEF*F; -// d_GDOP = sqrt(arma::trace(DOP_ENU)); // Geometric DOP -// d_PDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1) + DOP_ENU(2,2)); // PDOP -// d_HDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1)); // HDOP -// d_VDOP = sqrt(DOP_ENU(2,2)); // VDOP -// d_TDOP = sqrt(d_Q(3,3)); // TDOP -// } -// catch(std::exception& ex) -// { -// d_GDOP = -1; // Geometric DOP -// d_PDOP = -1; // PDOP -// d_HDOP = -1; // HDOP -// d_VDOP = -1; // VDOP -// d_TDOP = -1; // TDOP -// } -// -// // ######## LOG FILE ######### -// if(d_flag_dump_enabled == true) -// { -// // MULTIPLEXED FILE RECORDING - Record results to file -// try -// { -// double tmp_double; -// // PVT GPS time -// tmp_double = hybrid_current_time; -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// // ECEF User Position East [m] -// tmp_double = mypos(0); -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// // ECEF User Position North [m] -// tmp_double = mypos(1); -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// // ECEF User Position Up [m] -// tmp_double = mypos(2); -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// // User clock offset [s] -// tmp_double = mypos(3); -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// // GEO user position Latitude [deg] -// tmp_double = d_latitude_d; -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// // GEO user position Longitude [deg] -// tmp_double = d_longitude_d; -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// // GEO user position Height [m] -// tmp_double = d_height_m; -// d_dump_file.write((char*)&tmp_double, sizeof(double)); -// } -// catch (const std::ifstream::failure& e) -// { -// LOG(WARNING) << "Exception writing PVT LS dump file "<< e.what(); -// } -// } -// -// // MOVING AVERAGE PVT -// if (flag_averaging == true) -// { -// if (d_hist_longitude_d.size() == (unsigned int)d_averaging_depth) -// { -// // Pop oldest value -// d_hist_longitude_d.pop_back(); -// d_hist_latitude_d.pop_back(); -// d_hist_height_m.pop_back(); -// // Push new values -// d_hist_longitude_d.push_front(d_longitude_d); -// d_hist_latitude_d.push_front(d_latitude_d); -// d_hist_height_m.push_front(d_height_m); -// -// d_avg_latitude_d = 0; -// d_avg_longitude_d = 0; -// d_avg_height_m = 0; -// for (unsigned int i = 0; i < d_hist_longitude_d.size(); i++) -// { -// d_avg_latitude_d = d_avg_latitude_d + d_hist_latitude_d.at(i); -// d_avg_longitude_d = d_avg_longitude_d + d_hist_longitude_d.at(i); -// d_avg_height_m = d_avg_height_m + d_hist_height_m.at(i); -// } -// d_avg_latitude_d = d_avg_latitude_d / (double)d_averaging_depth; -// d_avg_longitude_d = d_avg_longitude_d / (double)d_averaging_depth; -// d_avg_height_m = d_avg_height_m / (double)d_averaging_depth; -// b_valid_position = true; -// return true; //indicates that the returned position is valid -// } -// else -// { -// // int current_depth=d_hist_longitude_d.size(); -// // Push new values -// d_hist_longitude_d.push_front(d_longitude_d); -// d_hist_latitude_d.push_front(d_latitude_d); -// d_hist_height_m.push_front(d_height_m); -// -// d_avg_latitude_d = d_latitude_d; -// d_avg_longitude_d = d_longitude_d; -// d_avg_height_m = d_height_m; -// b_valid_position = false; -// return false; //indicates that the returned position is not valid yet -// } -// } -// else -// { -// b_valid_position = true; -// return true; //indicates that the returned position is valid -// } + // Compute GST and Gregorian time + double GST = galileo_ephemeris_iter->second.Galileo_System_Time(Galileo_week_number, hybrid_current_time); + utc = galileo_utc_model.GST_to_UTC_time(GST, Galileo_week_number); + // get time string Gregorian calendar + boost::posix_time::time_duration t = boost::posix_time::seconds(utc); + // 22 August 1999 00:00 last Galileo start GST epoch (ICD sec 5.1.2) + boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); + d_position_UTC_time = p_time; + LOG(INFO) << "HYBRID Position at TOW=" << hybrid_current_time << " in ECEF (X,Y,Z) = " << mypos; + + cart2geo((double)mypos(0), (double)mypos(1), (double)mypos(2), 4); + //ToDo: Find an Observables/PVT random bug with some satellite configurations that gives an erratic PVT solution (i.e. height>50 km) + if (d_height_m > 50000) + { + b_valid_position = false; + LOG(INFO) << "Hybrid Position at " << boost::posix_time::to_simple_string(p_time) + << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d + << " [deg], Height= " << d_height_m << " [m]"; + + std::cout << "Hybrid Position at " << boost::posix_time::to_simple_string(p_time) + << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d + << " [deg], Height= " << d_height_m << " [m]" << std::endl; + return false; + } + + LOG(INFO) << "Hybrid Position at " << boost::posix_time::to_simple_string(p_time) + << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d + << " [deg], Height= " << d_height_m << " [m]"; + // ###### Compute DOPs ######## + // 1- Rotation matrix from ECEF coordinates to ENU coordinates + // ref: http://www.navipedia.net/index.php/Transformations_between_ECEF_and_ENU_coordinates + arma::mat F = arma::zeros(3,3); + F(0,0) = -sin(GPS_TWO_PI*(d_longitude_d/360.0)); + F(0,1) = -sin(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0)); + F(0,2) = cos(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0)); + + F(1,0) = cos((GPS_TWO_PI*d_longitude_d)/360.0); + F(1,1) = -sin((GPS_TWO_PI*d_latitude_d)/360.0)*sin((GPS_TWO_PI*d_longitude_d)/360.0); + F(1,2) = cos((GPS_TWO_PI*d_latitude_d/360.0))*sin((GPS_TWO_PI*d_longitude_d)/360.0); + + F(2,0) = 0; + F(2,1) = cos((GPS_TWO_PI*d_latitude_d)/360.0); + F(2,2) = sin((GPS_TWO_PI*d_latitude_d/360.0)); + + // 2- Apply the rotation to the latest covariance matrix (available in ECEF from LS) + arma::mat Q_ECEF = d_Q.submat(0, 0, 2, 2); + arma::mat DOP_ENU = arma::zeros(3, 3); + + try + { + DOP_ENU = arma::htrans(F)*Q_ECEF*F; + d_GDOP = sqrt(arma::trace(DOP_ENU)); // Geometric DOP + d_PDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1) + DOP_ENU(2,2)); // PDOP + d_HDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1)); // HDOP + d_VDOP = sqrt(DOP_ENU(2,2)); // VDOP + d_TDOP = sqrt(d_Q(3,3)); // TDOP + } + catch(std::exception& ex) + { + d_GDOP = -1; // Geometric DOP + d_PDOP = -1; // PDOP + d_HDOP = -1; // HDOP + d_VDOP = -1; // VDOP + d_TDOP = -1; // TDOP + } + + // ######## LOG FILE ######### + if(d_flag_dump_enabled == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + // PVT GPS time + tmp_double = hybrid_current_time; + d_dump_file.write((char*)&tmp_double, sizeof(double)); + // ECEF User Position East [m] + tmp_double = mypos(0); + d_dump_file.write((char*)&tmp_double, sizeof(double)); + // ECEF User Position North [m] + tmp_double = mypos(1); + d_dump_file.write((char*)&tmp_double, sizeof(double)); + // ECEF User Position Up [m] + tmp_double = mypos(2); + d_dump_file.write((char*)&tmp_double, sizeof(double)); + // User clock offset [s] + tmp_double = mypos(3); + d_dump_file.write((char*)&tmp_double, sizeof(double)); + // GEO user position Latitude [deg] + tmp_double = d_latitude_d; + d_dump_file.write((char*)&tmp_double, sizeof(double)); + // GEO user position Longitude [deg] + tmp_double = d_longitude_d; + d_dump_file.write((char*)&tmp_double, sizeof(double)); + // GEO user position Height [m] + tmp_double = d_height_m; + d_dump_file.write((char*)&tmp_double, sizeof(double)); + } + catch (const std::ifstream::failure& e) + { + LOG(WARNING) << "Exception writing PVT LS dump file "<< e.what(); + } + } + + // MOVING AVERAGE PVT + if (flag_averaging == true) + { + if (d_hist_longitude_d.size() == (unsigned int)d_averaging_depth) + { + // Pop oldest value + d_hist_longitude_d.pop_back(); + d_hist_latitude_d.pop_back(); + d_hist_height_m.pop_back(); + // Push new values + d_hist_longitude_d.push_front(d_longitude_d); + d_hist_latitude_d.push_front(d_latitude_d); + d_hist_height_m.push_front(d_height_m); + + d_avg_latitude_d = 0; + d_avg_longitude_d = 0; + d_avg_height_m = 0; + for (unsigned int i = 0; i < d_hist_longitude_d.size(); i++) + { + d_avg_latitude_d = d_avg_latitude_d + d_hist_latitude_d.at(i); + d_avg_longitude_d = d_avg_longitude_d + d_hist_longitude_d.at(i); + d_avg_height_m = d_avg_height_m + d_hist_height_m.at(i); + } + d_avg_latitude_d = d_avg_latitude_d / (double)d_averaging_depth; + d_avg_longitude_d = d_avg_longitude_d / (double)d_averaging_depth; + d_avg_height_m = d_avg_height_m / (double)d_averaging_depth; + b_valid_position = true; + return true; //indicates that the returned position is valid + } + else + { + // int current_depth=d_hist_longitude_d.size(); + // Push new values + d_hist_longitude_d.push_front(d_longitude_d); + d_hist_latitude_d.push_front(d_latitude_d); + d_hist_height_m.push_front(d_height_m); + + d_avg_latitude_d = d_latitude_d; + d_avg_longitude_d = d_longitude_d; + d_avg_height_m = d_height_m; + b_valid_position = false; + return false; //indicates that the returned position is not valid yet + } + } + else + { + b_valid_position = true; + return true; //indicates that the returned position is valid + } } else { diff --git a/src/algorithms/PVT/libs/kml_printer.cc b/src/algorithms/PVT/libs/kml_printer.cc index eb9644ba5..b98cceef8 100644 --- a/src/algorithms/PVT/libs/kml_printer.cc +++ b/src/algorithms/PVT/libs/kml_printer.cc @@ -142,6 +142,34 @@ bool Kml_Printer::print_position_galileo(galileo_e1_ls_pvt* position,bool print_ } } +bool Kml_Printer::print_position_hybrid(hybrid_ls_pvt* position,bool print_average_values) +{ + double latitude; + double longitude; + double height; + if (print_average_values == false) + { + latitude = position->d_latitude_d; + longitude = position->d_longitude_d; + height = position->d_height_m; + } + else + { + latitude = position->d_avg_latitude_d; + longitude = position->d_avg_longitude_d; + height = position->d_avg_height_m; + } + + if (kml_file.is_open()) + { + kml_file << longitude << "," << latitude << "," << height << std::endl; + return true; + } + else + { + return false; + } +} bool Kml_Printer::close_file() { diff --git a/src/algorithms/PVT/libs/kml_printer.h b/src/algorithms/PVT/libs/kml_printer.h index 4638c09aa..994da2d34 100644 --- a/src/algorithms/PVT/libs/kml_printer.h +++ b/src/algorithms/PVT/libs/kml_printer.h @@ -38,7 +38,7 @@ #include #include "gps_l1_ca_ls_pvt.h" #include "galileo_e1_ls_pvt.h" - +#include "hybrid_ls_pvt.h" /*! * \brief Prints PVT information to OGC KML format file (can be viewed with Google Earth) @@ -53,6 +53,7 @@ public: bool set_headers(std::string filename); bool print_position(gps_l1_ca_ls_pvt* position, bool print_average_values); bool print_position_galileo(galileo_e1_ls_pvt* position, bool print_average_values); + bool print_position_hybrid(hybrid_ls_pvt* position, bool print_average_values); bool close_file(); Kml_Printer(); ~Kml_Printer(); diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 8c29fd840..b5d45f8fa 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -118,6 +118,7 @@ int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninpu Gnss_Synchro current_gnss_synchro[d_nchannels]; std::map current_gnss_synchro_map; + std::map current_gnss_synchro_map_gps_only; std::map::iterator gnss_synchro_iter; d_sample_counter++; //count for the processed samples /* @@ -136,6 +137,10 @@ int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninpu { //record the word structure in a map for pseudorange computation current_gnss_synchro_map.insert(std::pair(current_gnss_synchro[i].Channel_ID, current_gnss_synchro[i])); + if (current_gnss_synchro[i].System=='G') + { + current_gnss_synchro_map_gps_only.insert(std::pair(current_gnss_synchro[i].Channel_ID, current_gnss_synchro[i])); + } } } @@ -144,7 +149,7 @@ int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninpu */ DLOG(INFO)<<"gnss_synchro set size="< 0) + if(current_gnss_synchro_map.size() > 0)// and current_gnss_synchro_map_gps_only.size()>0) { /* * 2.1 Use CURRENT set of measurements and find the nearest satellite @@ -152,24 +157,31 @@ int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninpu */ // what is the most recent symbol TOW in the current set? -> this will be the reference symbol gnss_synchro_iter = max_element(current_gnss_synchro_map.begin(), current_gnss_synchro_map.end(), Hybrid_pairCompare_gnss_synchro_d_TOW_hybrid_at_current_symbol); - double d_TOW_reference = gnss_synchro_iter->second.d_TOW_hybrid_at_current_symbol; - std::cout<<"d_TOW_hybrid_reference [ms] = "<< d_TOW_reference*1000 <second.d_TOW_hybrid_at_current_symbol; + char ref_sat_system=gnss_synchro_iter->second.System; + DLOG(INFO)<<"d_TOW_hybrid_reference [ms] = "<< d_TOW_reference*1000 <second.Prn_timestamp_ms; - std::cout<<"ref_PRN_rx_time_ms [ms] = "<< d_ref_PRN_rx_time_ms <second.Channel_ID<<","<second.System<<"]="<second.Channel_ID<<","<second.System<<"]="<second.d_TOW_hybrid_at_current_symbol)*1000.0 + delta_rx_time_ms + GALILEO_STARTOFFSET_ms; + traveltime_ms = delta_TOW_ms + delta_rx_time_ms + GALILEO_STARTOFFSET_ms; pseudorange_m = traveltime_ms * GALILEO_C_m_ms; // [m] - std::cout<<"CH "<second.Channel_ID<<" tracking GNSS System "<second.System<<" has PRN start at= "<second.Prn_timestamp_ms<<" [ms], d_TOW_at_current_symbol = "<<(gnss_synchro_iter->second.d_TOW_at_current_symbol)*1000<<" [ms], d_TOW_hybrid_at_current_symbol = "<<(gnss_synchro_iter->second.d_TOW_hybrid_at_current_symbol)*1000<<"[ms], delta_rx_time_ms = "<< delta_rx_time_ms << "[ms], travel_time = " << traveltime_ms << ", pseudorange[m] = "<< pseudorange_m << std::endl; + DLOG(INFO)<<"CH "<second.Channel_ID<<" tracking GNSS System "<second.System<<" has PRN start at= "<second.Prn_timestamp_ms<<" [ms], d_TOW_at_current_symbol = "<<(gnss_synchro_iter->second.d_TOW_at_current_symbol)*1000<<" [ms], d_TOW_hybrid_at_current_symbol = "<<(gnss_synchro_iter->second.d_TOW_hybrid_at_current_symbol)*1000<<"[ms], delta_rx_time_ms = "<< delta_rx_time_ms << "[ms], travel_time = " << traveltime_ms << ", pseudorange[m] = "<< pseudorange_m << std::endl; // update the pseudorange object //current_gnss_synchro[gnss_synchro_iter->second.Channel_ID] = gnss_synchro_iter->second; @@ -178,35 +190,37 @@ int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninpu current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].d_TOW_hybrid_at_current_symbol = round(d_TOW_reference*1000)/1000 + GALILEO_STARTOFFSET_ms/1000.0; } - std::cout<d_flag_preamble == true and d_nav.flag_TOW_set == true) //update TOW at the preamble instant + // JAVI: 30/06/2014 + // TOW, in Galileo, is referred to the START of the PAGE PART, that is, THE FIRST SYMBOL OF THAT PAGE, NOT THE PREAMBLE. + // thus, no correction should be done. d_TOW_at_Preamble should be renamed to d_TOW_at_page_start. + // Sice we detected the preable, then, we are in the last symbol of that preable, or just at the start of the first page symbol. //flag preamble is true after the all page (even and odd) is recevived. I/NAV page period is 2 SECONDS { Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0; @@ -428,7 +432,7 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector /* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because * if we have a TOW value it means that we are at the begining of the last page part * (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/ - d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD; + d_TOW_at_current_symbol=d_TOW_at_Preamble;//-GALIELO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND; d_nav.flag_TOW_5 = false; } @@ -440,7 +444,7 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector /* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because * if we have a TOW value it means that we are at the begining of the last page part * (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/ - d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD; + d_TOW_at_current_symbol=d_TOW_at_Preamble;//-GALIELO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND; d_nav.flag_TOW_6 = false; } else @@ -461,7 +465,7 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector if(d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) //all GGTO parameters arrived { - delta_t=d_nav.A_0G_10+d_nav.A_1G_10*(d_TOW_at_current_symbol-d_nav.t_0G_10+604800*(fmod((d_nav.WN_0-d_nav.WN_0G_10),64))); + delta_t=d_nav.A_0G_10+d_nav.A_1G_10*(d_TOW_at_current_symbol-d_nav.t_0G_10+604800.0*(fmod((d_nav.WN_0-d_nav.WN_0G_10),64))); } @@ -480,7 +484,7 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector current_synchro_data.d_TOW = d_TOW_at_Preamble; current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol; current_synchro_data.d_TOW_hybrid_at_current_symbol= current_synchro_data.d_TOW_at_current_symbol - delta_t; //delta_t = t_gal - t_gps ----> t_gps = t_gal -delta_t - std::cout<< "delta_t = " << delta_t << std::endl; + DLOG(INFO)<< "delta_t = " << delta_t << std::endl; current_synchro_data.Flag_preamble = d_flag_preamble; current_synchro_data.Prn_timestamp_ms = in[0][0].Tracking_timestamp_secs * 1000.0; current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc index 9c40c2dd7..cfd0ae365 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc @@ -301,10 +301,15 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i //1. Copy the current tracking output current_synchro_data = in[0][0]; //2. Add the telemetry decoder information - if (this->d_flag_preamble == true and d_GPS_FSM.d_nav.d_TOW > 0) //update TOW at the preamble instant (todo: check for valid d_TOW) + if (this->d_flag_preamble == true and d_GPS_FSM.d_nav.d_TOW > 0) + //update TOW at the preamble instant (todo: check for valid d_TOW) + // JAVI: 30/06/2014 + // TOW, in GPS, is referred to the START of the SUBFRAME, that is, THE FIRST SYMBOL OF THAT SUBFRAME, NOT THE PREAMBLE. + // thus, no correction should be done. d_TOW_at_Preamble should be renamed to d_TOW_at_subframe_start. + // Sice we detected the preable, then, we are in the last symbol of that preamble, or just at the start of the first subframe symbol. { d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + GPS_SUBFRAME_SECONDS; //we decoded the current TOW when the last word of the subframe arrive, so, we have a lag of ONE SUBFRAME - d_TOW_at_current_symbol = d_TOW_at_Preamble + GPS_CA_PREAMBLE_LENGTH_BITS/GPS_CA_TELEMETRY_RATE_BITS_SECOND; + d_TOW_at_current_symbol = d_TOW_at_Preamble;//GPS_L1_CA_CODE_PERIOD;// + (double)GPS_CA_PREAMBLE_LENGTH_BITS/(double)GPS_CA_TELEMETRY_RATE_BITS_SECOND; Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0; if (flag_TOW_set == false) { @@ -345,6 +350,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i } //todo: implement averaging + d_average_count++; if (d_average_count==d_decimation_output_factor) { diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc index d4c6d6dd8..ab402ea9e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc @@ -395,7 +395,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect T_prn_samples = T_prn_seconds * (float)d_fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in; d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples - d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) @@ -442,9 +442,18 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect current_synchro_data.Prompt_I = (double)(*d_Prompt).real(); current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag(); - // Tracking_timestamp_secs is aligned with the PRN start sample - current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + - (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples) / (double)d_fs_in; + + // Tracking_timestamp_secs is aligned with the NEXT PRN start sample (Hybridization problem!) + //compute remnant code phase samples BEFORE the Tracking timestamp + //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + //current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + + // (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples) / (double)d_fs_in; + + // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!, but some glitches??) + current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_rem_code_phase_samples) / (double)d_fs_in; + //compute remnant code phase samples AFTER the Tracking timestamp + d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0 current_synchro_data.Code_phase_secs = 0; current_synchro_data.Carrier_phase_rads = (double)d_acc_carrier_phase_rad; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc index 6d8516bc9..afa5c061d 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc @@ -435,7 +435,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in T_prn_samples = T_prn_seconds * (float)d_fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in; d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples - d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) @@ -477,8 +477,18 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in // ########### Output the tracking data to navigation and PVT ########## current_synchro_data.Prompt_I = (double)(*d_Prompt).real(); current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag(); - // Tracking_timestamp_secs is aligned with the PRN start sample - current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples)/(double)d_fs_in; + + // Tracking_timestamp_secs is aligned with the NEXT PRN start sample (Hybridization problem!) + //compute remnant code phase samples BEFORE the Tracking timestamp + //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + //current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples)/(double)d_fs_in; + + // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!, but some glitches??) + current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_rem_code_phase_samples)/(double)d_fs_in; + //compute remnant code phase samples AFTER the Tracking timestamp + d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + + //current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter)/(double)d_fs_in; // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0 current_synchro_data.Code_phase_secs = 0; current_synchro_data.Carrier_phase_rads = (double)d_acc_carrier_phase_rad; diff --git a/src/core/system_parameters/gnss_synchro.h b/src/core/system_parameters/gnss_synchro.h index 4672afb71..8251c9f79 100644 --- a/src/core/system_parameters/gnss_synchro.h +++ b/src/core/system_parameters/gnss_synchro.h @@ -56,12 +56,10 @@ public: double CN0_dB_hz; //!< Set by Tracking processing block double Carrier_Doppler_hz; //!< Set by Tracking processing block double Carrier_phase_rads; //!< Set by Tracking processing block - //old double Code_phase_secs; //!< Set by Tracking processing block double Tracking_timestamp_secs; //!< Set by Tracking processing block - //new - unsigned long int PRN_start_sample; //!< Set by Tracking processing block bool Flag_valid_tracking; + //Telemetry Decoder double Prn_timestamp_ms; //!< Set by Telemetry Decoder processing block double Prn_timestamp_at_preamble_ms; //!< Set by Telemetry Decoder processing block