From b0d33328d5886c835957ce12d7db3aa4ead720e1 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 10 Jun 2014 18:58:17 +0200 Subject: [PATCH] Simultaneous multi-GNSS system acquisition, tracking and telemetry decoding: Changes in the flowgraph and in the configuration files to mix channels from different GNSS systems in the same receiver. Hybrid observables and PVT under construction. The changes in the configuration file parameter names are NOT backward compatible. The receiver can still work as usual in single GNSS system mode but some modification on configuration files are required. Use the example provided of Hybrid configuration file. --- conf/gnss-sdr_GPS_hybrid_short.conf | 342 ++++++++++++++++++ conf/gnss-sdr_Galileo_E1.conf | 68 ++-- src/algorithms/PVT/adapters/CMakeLists.txt | 1 + src/algorithms/PVT/adapters/hybrid_pvt.cc | 109 ++++++ src/algorithms/PVT/adapters/hybrid_pvt.h | 97 +++++ .../PVT/gnuradio_blocks/CMakeLists.txt | 1 + .../PVT/gnuradio_blocks/hybrid_pvt_cc.cc | 260 +++++++++++++ .../PVT/gnuradio_blocks/hybrid_pvt_cc.h | 122 +++++++ src/algorithms/channel/adapters/channel.cc | 14 +- src/algorithms/channel/adapters/channel.h | 2 +- .../observables/adapters/CMakeLists.txt | 1 + .../adapters/hybrid_observables.cc | 101 ++++++ .../observables/adapters/hybrid_observables.h | 93 +++++ .../gnuradio_blocks/CMakeLists.txt | 1 + .../gnuradio_blocks/hybrid_observables_cc.cc | 215 +++++++++++ .../gnuradio_blocks/hybrid_observables_cc.h | 85 +++++ .../adapters/gps_l1_ca_telemetry_decoder.cc | 4 + .../galileo_e1b_telemetry_decoder_cc.cc | 2 + .../gps_l1_ca_telemetry_decoder_cc.cc | 24 +- .../gps_l1_ca_telemetry_decoder_cc.h | 10 + .../galileo_e1_dll_pll_veml_tracking_cc.cc | 1 + .../gps_l1_ca_dll_pll_tracking_cc.cc | 1 + src/core/receiver/gnss_block_factory.cc | 122 +++++-- src/core/receiver/gnss_block_factory.h | 6 +- src/core/receiver/gnss_flowgraph.cc | 40 +- 25 files changed, 1634 insertions(+), 88 deletions(-) create mode 100644 conf/gnss-sdr_GPS_hybrid_short.conf create mode 100644 src/algorithms/PVT/adapters/hybrid_pvt.cc create mode 100644 src/algorithms/PVT/adapters/hybrid_pvt.h create mode 100644 src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc create mode 100644 src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h create mode 100644 src/algorithms/observables/adapters/hybrid_observables.cc create mode 100644 src/algorithms/observables/adapters/hybrid_observables.h create mode 100644 src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc create mode 100644 src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h diff --git a/conf/gnss-sdr_GPS_hybrid_short.conf b/conf/gnss-sdr_GPS_hybrid_short.conf new file mode 100644 index 000000000..a01e3167b --- /dev/null +++ b/conf/gnss-sdr_GPS_hybrid_short.conf @@ -0,0 +1,342 @@ +; 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=4000000 + +;######### CONTROL_THREAD CONFIG ############ +ControlThread.wait_for_flowgraph=false + +;######### SIGNAL_SOURCE CONFIG ############ +;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +SignalSource.implementation=File_Signal_Source + +;#filename: path to file with the captured GNSS signal samples to be processed +SignalSource.filename=/Users/javier/signals/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN_run2.dat +;SignalSource.filename=/Users/javier/signals/cttc_4M_50dB.dat + +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +SignalSource.item_type=short + +;#sampling_frequency: Original Signal sampling frequency in [Hz] +SignalSource.sampling_frequency=4000000 + +;#freq: RF front-end center frequency in [Hz] +SignalSource.freq=1575420000 + +;#gain: Front-end Gain in [dB] +SignalSource.gain=60 + +;#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. Please disable it in this version. +;#implementation: [Pass_Through] disables this block +DataTypeAdapter.implementation=Ishort_To_Complex + +;######### 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] +;#[Pass_Through] disables this block +;#[Fir_Filter] enables a FIR Filter +;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz. + +;InputFilter.implementation=Fir_Filter +;InputFilter.implementation=Freq_Xlating_Fir_Filter +InputFilter.implementation=Pass_Through + +;#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=gr_complex + +;#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 + +;#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.sampling_frequency=4000000 +InputFilter.IF=0 + + + +;######### 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=Direct_Resampler +Resampler.implementation=Pass_Through + +;#dump: Dump the resamplered data to a file. +Resampler.dump=false +;#dump_filename: Log path and filename. +Resampler.dump_filename=../data/resampler.dat + +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Resampler.item_type=gr_complex + +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=4000000 + +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=4000000 + + +;######### CHANNELS GLOBAL CONFIG ############ +;#count: Number of available GPS satellite channels. +Channels_GPS.count=2 +;#count: Number of available Galileo satellite channels. +Channels_Galileo.count=2 +;#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.01 +;#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.00002 +;#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=50.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=20.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=100 + +;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false] +PVT.flag_averaging=true + +;#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=100; + +;#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 diff --git a/conf/gnss-sdr_Galileo_E1.conf b/conf/gnss-sdr_Galileo_E1.conf index ee08e951d..6603102c4 100644 --- a/conf/gnss-sdr_Galileo_E1.conf +++ b/conf/gnss-sdr_Galileo_E1.conf @@ -18,6 +18,7 @@ SignalSource.implementation=File_Signal_Source ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/Users/javier/signals/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN_run2.dat +;SignalSource.filename=/Users/javier/signals/cttc_4M_60dB.dat ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=short @@ -164,7 +165,10 @@ Resampler.sample_freq_out=4000000 ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available satellite channels. -Channels.count=1 +;#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 Channels.in_acquisition=1 ;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS @@ -239,106 +243,106 @@ Channel.signal=1B ;Channel0.system=Galileo ;Channel0.signal=1B ;#satellite: Satellite PRN ID for this channel. Disable this option to random search -Channel0.satellite=20 +;Channel0.satellite=20 ;######### CHANNEL 1 CONFIG ############ ;Channel1.system=Galileo ;Channel1.signal=1B -Channel1.satellite=12 +;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 +;Channel2.satellite=11 ;######### CHANNEL 3 CONFIG ############ ;Channel3.system=Galileo ;Channel3.signal=1B -Channel3.satellite=19 +;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.00003 +Acquisition_Galileo.pfa=0.00003 ;#doppler_max: Maximum expected Doppler shift [Hz] -Acquisition.doppler_max=15000 +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 = true -Acquisition1.repeat_satellite = true -Acquisition2.repeat_satellite = true -Acquisition3.repeat_satellite = true +;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=true +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.fll_bw_hz=10.0; +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/src/algorithms/PVT/adapters/CMakeLists.txt b/src/algorithms/PVT/adapters/CMakeLists.txt index e9c5682cb..4b65fef4b 100644 --- a/src/algorithms/PVT/adapters/CMakeLists.txt +++ b/src/algorithms/PVT/adapters/CMakeLists.txt @@ -19,6 +19,7 @@ set(PVT_ADAPTER_SOURCES gps_l1_ca_pvt.cc galileo_e1_pvt.cc + hybrid_pvt.cc ) include_directories( diff --git a/src/algorithms/PVT/adapters/hybrid_pvt.cc b/src/algorithms/PVT/adapters/hybrid_pvt.cc new file mode 100644 index 000000000..0f0c9c2bf --- /dev/null +++ b/src/algorithms/PVT/adapters/hybrid_pvt.cc @@ -0,0 +1,109 @@ +/*! + * \file hybrid_pvt.cc + * \brief Implementation of an adapter of a GALILEO E1 PVT solver block to a + * PvtInterface + * \author Javier Arribas, 2011. jarribas(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "hybrid_pvt.h" +#include +#include "configuration_interface.h" +#include "hybrid_pvt_cc.h" + + +using google::LogMessage; + +HybridPvt::HybridPvt(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams, + boost::shared_ptr queue) : + role_(role), + in_streams_(in_streams), + out_streams_(out_streams), + queue_(queue) +{ + // dump parameters + std::string default_dump_filename = "./pvt.dat"; + std::string default_nmea_dump_filename = "./nmea_pvt.nmea"; + std::string default_nmea_dump_devname = "/dev/tty1"; + DLOG(INFO) << "role " << role; + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + // moving average depth parameters + int averaging_depth; + averaging_depth = configuration->property(role + ".averaging_depth", 10); + bool flag_averaging; + flag_averaging = configuration->property(role + ".flag_averaging", false); + // output rate + int output_rate_ms; + output_rate_ms = configuration->property(role + ".output_rate_ms", 500); + // display rate + int display_rate_ms; + display_rate_ms = configuration->property(role + ".display_rate_ms", 500); + // NMEA Printer settings + bool flag_nmea_tty_port; + flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false); + std::string nmea_dump_filename; + nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename); + std::string nmea_dump_devname; + nmea_dump_devname = configuration->property(role + ".nmea_dump_devname", default_nmea_dump_devname); + // make PVT object + pvt_ = hybrid_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname); + DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")"; +} + + +HybridPvt::~HybridPvt() +{} + + +void HybridPvt::connect(gr::top_block_sptr top_block) +{ + // Nothing to connect internally + DLOG(INFO) << "nothing to connect internally"; +} + + +void HybridPvt::disconnect(gr::top_block_sptr top_block) +{ + // Nothing to disconnect +} + +gr::basic_block_sptr HybridPvt::get_left_block() +{ + return pvt_; +} + + +gr::basic_block_sptr HybridPvt::get_right_block() +{ + return pvt_; +} + diff --git a/src/algorithms/PVT/adapters/hybrid_pvt.h b/src/algorithms/PVT/adapters/hybrid_pvt.h new file mode 100644 index 000000000..43de22c0c --- /dev/null +++ b/src/algorithms/PVT/adapters/hybrid_pvt.h @@ -0,0 +1,97 @@ +/*! + * \file hybrid_pvt.h + * \brief Interface of an adapter of a GALILEO E1 PVT solver block to a + * PvtInterface. + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + + +#ifndef GNSS_SDR_HYBRID_PVT_H_ +#define GNSS_SDR_HYBRID_PVT_H_ + +#include +#include +#include "pvt_interface.h" +#include "hybrid_pvt_cc.h" + + +class ConfigurationInterface; + +/*! + * \brief This class implements a PvtInterface for Galileo E1 + */ +class HybridPvt : public PvtInterface +{ +public: + HybridPvt(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams, + boost::shared_ptr queue); + + virtual ~HybridPvt(); + + std::string role() + { + return role_; + } + + //! Returns "Hybrid_Pvt" + std::string implementation() + { + return "Hybrid_PVT"; + } + + void connect(gr::top_block_sptr top_block); + void disconnect(gr::top_block_sptr top_block); + gr::basic_block_sptr get_left_block(); + gr::basic_block_sptr get_right_block(); + + void reset() + { + return; + } + + //! All blocks must have an item_size() function implementation. Returns sizeof(gr_complex) + size_t item_size() + { + return sizeof(gr_complex); + } + +private: + hybrid_pvt_cc_sptr pvt_; + bool dump_; + unsigned int fs_in_; + std::string dump_filename_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + boost::shared_ptr queue_; +}; + +#endif diff --git a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt index 131fddc55..585b71ad6 100644 --- a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt @@ -19,6 +19,7 @@ set(PVT_GR_BLOCKS_SOURCES gps_l1_ca_pvt_cc.cc galileo_e1_pvt_cc.cc + hybrid_pvt_cc.cc ) include_directories( diff --git a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc new file mode 100644 index 000000000..b7ae2d318 --- /dev/null +++ b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc @@ -0,0 +1,260 @@ +/*! + * \file hybrid_pvt_cc.cc + * \brief Implementation of a Position Velocity and Time computation block for GPS L1 C/A + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "hybrid_pvt_cc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "control_message_factory.h" +#include "gnss_synchro.h" +#include "concurrent_map.h" + +using google::LogMessage; + +extern concurrent_map global_galileo_ephemeris_map; +extern concurrent_map global_galileo_iono_map; +extern concurrent_map global_galileo_utc_model_map; + +hybrid_pvt_cc_sptr +hybrid_make_pvt_cc(unsigned int nchannels, boost::shared_ptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname) +{ + return hybrid_pvt_cc_sptr(new hybrid_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname)); +} + + +hybrid_pvt_cc::hybrid_pvt_cc(unsigned int nchannels, boost::shared_ptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname) : + gr::block("hybrid_pvt_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) +{ + + d_output_rate_ms = output_rate_ms; + d_display_rate_ms = display_rate_ms; + d_queue = queue; + d_dump = dump; + d_nchannels = nchannels; + d_dump_filename = dump_filename; + std::string dump_ls_pvt_filename = dump_filename; + + //initialize kml_printer + std::string kml_dump_filename; + kml_dump_filename = d_dump_filename; + kml_dump_filename.append(".kml"); + d_kml_dump.set_headers(kml_dump_filename); + + //initialize nmea_printer + d_nmea_printer = new Nmea_Printer(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname); + + d_dump_filename.append("_raw.dat"); + dump_ls_pvt_filename.append("_ls_pvt.dat"); + d_averaging_depth = averaging_depth; + d_flag_averaging = flag_averaging; + + d_ls_pvt = new galileo_e1_ls_pvt(nchannels, dump_ls_pvt_filename, d_dump); + d_ls_pvt->set_averaging_depth(d_averaging_depth); + + d_sample_counter = 0; + d_last_sample_nav_output = 0; + d_rx_time = 0.0; + + b_rinex_header_writen = false; + rp = new Rinex_Printer(); + + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "PVT dump enabled Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure& e) + { + LOG(WARNING) << "Exception opening PVT dump file " << e.what(); + } + } + } +} + + + +hybrid_pvt_cc::~hybrid_pvt_cc() +{ + d_kml_dump.close_file(); + delete d_ls_pvt; + delete rp; + delete d_nmea_printer; +} + + + +bool hybrid_pvt_cc::pseudoranges_pairCompare_min( std::pair a, std::pair b) +{ + return (a.second.Pseudorange_m) < (b.second.Pseudorange_m); +} + + + +int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + d_sample_counter++; + + std::map gnss_pseudoranges_map; + + Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; //Get the input pointer + + for (unsigned int i = 0; i < d_nchannels; i++) + { + if (in[i][0].Flag_valid_pseudorange == true) + { + gnss_pseudoranges_map.insert(std::pair(in[i][0].PRN, in[i][0])); // store valid pseudoranges in a map + d_rx_time = in[i][0].d_TOW_at_current_symbol; // all the channels have the same RX timestamp (common RX time pseudoranges) + } + } + + // ############ 1. READ EPHEMERIS/UTC_MODE/IONO FROM GLOBAL MAPS #### + + if (global_galileo_ephemeris_map.size() > 0) + { + d_ls_pvt->galileo_ephemeris_map = global_galileo_ephemeris_map.get_map_copy(); + } + + if (global_galileo_utc_model_map.size() > 0) + { + // UTC MODEL data is shared for all the Galileo satellites. Read always at ID=0 + global_galileo_utc_model_map.read(0, d_ls_pvt->galileo_utc_model); + } + + if (global_galileo_iono_map.size() > 0) + { + // IONO data is shared for all the Galileo satellites. Read always at ID=0 + global_galileo_iono_map.read(0, d_ls_pvt->galileo_iono); + } + + // ############ 2 COMPUTE THE PVT ################################ + if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->galileo_ephemeris_map.size() > 0) + { + // 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); + + + if (pvt_result == true) + { + d_kml_dump.print_position_galileo(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); + // + // if (!b_rinex_header_writen) // & we have utc data in nav message! + // { + // std::map::iterator gps_ephemeris_iter; + // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin(); + // if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) + // { + // rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second,d_rx_time); + // rp->rinex_nav_header(rp->navFile,d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + // b_rinex_header_writen = true; // do not write header anymore + // } + // } + // if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s) + // { + // // Limit the RINEX navigation output rate to 1/6 seg + // // Notice that d_sample_counter period is 1ms (for GPS correlators) + // if ((d_sample_counter-d_last_sample_nav_output)>=6000) + // { + // rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + // d_last_sample_nav_output=d_sample_counter; + // } + // std::map::iterator gps_ephemeris_iter; + // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin(); + // if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) + // { + // rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map); + // } + // } + } + } + + // DEBUG MESSAGE: Display position in console output + 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 + << " [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 + << " [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 = " + << d_ls_pvt->d_VDOP <<" TDOP = " << d_ls_pvt->d_TDOP + << " GDOP = " << d_ls_pvt->d_GDOP; + } + + // MULTIPLEXED FILE RECORDING - Record results to file + if(d_dump == true) + { + try + { + double tmp_double; + for (unsigned int i = 0; i < d_nchannels; i++) + { + tmp_double = in[i][0].Pseudorange_m; + d_dump_file.write((char*)&tmp_double, sizeof(double)); + tmp_double = 0; + d_dump_file.write((char*)&tmp_double, sizeof(double)); + d_dump_file.write((char*)&d_rx_time, sizeof(double)); + } + } + catch (const std::ifstream::failure& e) + { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + } + + consume_each(1); //one by one + return 0; +} + + diff --git a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h new file mode 100644 index 000000000..91cfccd9b --- /dev/null +++ b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h @@ -0,0 +1,122 @@ +/*! + * \file hybrid_pvt_cc.h + * \brief Interface of a Position Velocity and Time computation block for Galileo E1 + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_HYBRID_PVT_CC_H +#define GNSS_SDR_HYBRID_PVT_CC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "galileo_navigation_message.h" +#include "galileo_ephemeris.h" +#include "galileo_utc_model.h" +#include "galileo_iono.h" +#include "nmea_printer.h" +#include "kml_printer.h" +#include "rinex_printer.h" +#include "galileo_e1_ls_pvt.h" +#include "GPS_L1_CA.h" +#include "Galileo_E1.h" + +class hybrid_pvt_cc; + +typedef boost::shared_ptr hybrid_pvt_cc_sptr; + +hybrid_pvt_cc_sptr hybrid_make_pvt_cc(unsigned int n_channels, + boost::shared_ptr queue, + bool dump, + std::string dump_filename, + int averaging_depth, + bool flag_averaging, + int output_rate_ms, + int display_rate_ms, + bool flag_nmea_tty_port, + std::string nmea_dump_filename, + std::string nmea_dump_devname); + +/*! + * \brief This class implements a block that computes the PVT solution with Galileo E1 signals + */ +class hybrid_pvt_cc : public gr::block +{ +private: + friend hybrid_pvt_cc_sptr hybrid_make_pvt_cc(unsigned int nchannels, + boost::shared_ptr queue, + bool dump, + std::string dump_filename, + int averaging_depth, + bool flag_averaging, + int output_rate_ms, + int display_rate_ms, + bool flag_nmea_tty_port, + std::string nmea_dump_filename, + std::string nmea_dump_devname); + hybrid_pvt_cc(unsigned int nchannels, + boost::shared_ptr queue, + bool dump, std::string dump_filename, + int averaging_depth, + bool flag_averaging, + int output_rate_ms, + int display_rate_ms, + bool flag_nmea_tty_port, + std::string nmea_dump_filename, + std::string nmea_dump_devname); + boost::shared_ptr d_queue; + bool d_dump; + bool b_rinex_header_writen; + Rinex_Printer *rp; + unsigned int d_nchannels; + std::string d_dump_filename; + std::ofstream d_dump_file; + int d_averaging_depth; + bool d_flag_averaging; + int d_output_rate_ms; + int d_display_rate_ms; + long unsigned int d_sample_counter; + long unsigned int d_last_sample_nav_output; + Kml_Printer d_kml_dump; + Nmea_Printer *d_nmea_printer; + double d_rx_time; + galileo_e1_ls_pvt *d_ls_pvt; + bool pseudoranges_pairCompare_min(std::pair a, std::pair b); + +public: + ~hybrid_pvt_cc (); //!< Default destructor + + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); //!< PVT Signal Processing +}; + +#endif diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index 3b607eda4..b720ed53c 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -68,26 +68,26 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, // IMPORTANT: Do not change the order between set_doppler_max, set_doppler_step and set_threshold - unsigned int doppler_max = configuration->property("Acquisition" + boost::lexical_cast(channel_) + ".doppler_max", 0); - if(doppler_max == 0) doppler_max = configuration->property("Acquisition.doppler_max", 0); + unsigned int doppler_max = configuration->property("Acquisition_"+implementation_ + boost::lexical_cast(channel_) + ".doppler_max", 0); + if(doppler_max == 0) doppler_max = configuration->property("Acquisition_"+implementation_+".doppler_max", 0); DLOG(INFO) << "Channel "<< channel_ << " Doppler_max = " << doppler_max; acq_->set_doppler_max(doppler_max); - unsigned int doppler_step = configuration->property("Acquisition" + boost::lexical_cast(channel_) + ".doppler_step" ,0); - if(doppler_step == 0) doppler_step = configuration->property("Acquisition.doppler_step", 500); + unsigned int doppler_step = configuration->property("Acquisition_"+implementation_ + boost::lexical_cast(channel_) + ".doppler_step" ,0); + if(doppler_step == 0) doppler_step = configuration->property("Acquisition_"+implementation_+".doppler_step", 500); DLOG(INFO) << "Channel "<< channel_ << " Doppler_step = " << doppler_step; acq_->set_doppler_step(doppler_step); - float threshold = configuration->property("Acquisition" + boost::lexical_cast(channel_) + ".threshold", 0.0); - if(threshold == 0.0) threshold = configuration->property("Acquisition.threshold", 0.0); + float threshold = configuration->property("Acquisition_"+implementation_+ boost::lexical_cast(channel_) + ".threshold", 0.0); + if(threshold == 0.0) threshold = configuration->property("Acquisition_"+implementation_+".threshold", 0.0); acq_->set_threshold(threshold); acq_->init(); - repeat_ = configuration->property("Acquisition" + boost::lexical_cast(channel_) + ".repeat_satellite", false); + repeat_ = configuration->property("Acquisition_"+implementation_+ boost::lexical_cast(channel_) + ".repeat_satellite", false); DLOG(INFO) << "Channel " << channel_ << " satellite repeat = " << repeat_; acq_->set_channel_queue(&channel_internal_queue_); diff --git a/src/algorithms/channel/adapters/channel.h b/src/algorithms/channel/adapters/channel.h index e3a1238d8..2b30ebdbc 100644 --- a/src/algorithms/channel/adapters/channel.h +++ b/src/algorithms/channel/adapters/channel.h @@ -74,7 +74,7 @@ public: std::string role(){ return role_; } //! Returns "Channel" - std::string implementation(){ return "Channel"; } + std::string implementation(){ return implementation_; } size_t item_size(){ return 0; } Gnss_Signal get_signal() const { return gnss_signal_; } AcquisitionInterface* acquisition(){ return acq_; } diff --git a/src/algorithms/observables/adapters/CMakeLists.txt b/src/algorithms/observables/adapters/CMakeLists.txt index 6a724753f..b6db74d2a 100644 --- a/src/algorithms/observables/adapters/CMakeLists.txt +++ b/src/algorithms/observables/adapters/CMakeLists.txt @@ -19,6 +19,7 @@ set(OBS_ADAPTER_SOURCES gps_l1_ca_observables.cc galileo_e1_observables.cc + hybrid_observables.cc ) include_directories( diff --git a/src/algorithms/observables/adapters/hybrid_observables.cc b/src/algorithms/observables/adapters/hybrid_observables.cc new file mode 100644 index 000000000..d0496ce0d --- /dev/null +++ b/src/algorithms/observables/adapters/hybrid_observables.cc @@ -0,0 +1,101 @@ +/*! + * \file hybrid_observables.cc + * \brief Implementation of an adapter of a Galileo E1 observables block + * to a ObservablesInterface + * \author Javier Arribas, 2011. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "hybrid_observables.h" +#include "configuration_interface.h" +#include "hybrid_observables_cc.h" +#include + +using google::LogMessage; + +HybridObservables::HybridObservables(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams, + boost::shared_ptr queue) : + role_(role), + in_streams_(in_streams), + out_streams_(out_streams), + queue_(queue) +{ + int output_rate_ms; + output_rate_ms = configuration->property(role + ".output_rate_ms", 500); + std::string default_dump_filename = "./observables.dat"; + DLOG(INFO) << "role " << role; + bool flag_averaging; + flag_averaging = configuration->property(role + ".flag_averaging", false); + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); + observables_ = hybrid_make_observables_cc(in_streams_, queue_, dump_, dump_filename_, output_rate_ms, flag_averaging); + observables_->set_fs_in(fs_in_); + DLOG(INFO) << "pseudorange(" << observables_->unique_id() << ")"; +} + + + + +HybridObservables::~HybridObservables() +{} + + + + +void HybridObservables::connect(gr::top_block_sptr top_block) +{ + // Nothing to connect internally + DLOG(INFO) << "nothing to connect internally"; +} + + + +void HybridObservables::disconnect(gr::top_block_sptr top_block) +{ + // Nothing to disconnect +} + + + + +gr::basic_block_sptr HybridObservables::get_left_block() +{ + return observables_; +} + + + + +gr::basic_block_sptr HybridObservables::get_right_block() +{ + return observables_; +} + diff --git a/src/algorithms/observables/adapters/hybrid_observables.h b/src/algorithms/observables/adapters/hybrid_observables.h new file mode 100644 index 000000000..75c981824 --- /dev/null +++ b/src/algorithms/observables/adapters/hybrid_observables.h @@ -0,0 +1,93 @@ +/*! + * \file hybrid_observables.h + * \brief Implementation of an adapter of a Galileo E1 observables block + * to a ObservablesInterface + * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com + * \author Javier Arribas 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_hybrid_observables_H_ +#define GNSS_SDR_hybrid_observables_H_ + +#include +#include +#include "observables_interface.h" +#include "hybrid_observables_cc.h" + + +class ConfigurationInterface; + +/*! + * \brief This class implements an ObservablesInterface for Galileo E1B + */ +class HybridObservables : public ObservablesInterface +{ +public: + HybridObservables(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams, + boost::shared_ptr queue); + virtual ~HybridObservables(); + std::string role() + { + return role_; + } + + //! Returns "Hybrid_Observables" + std::string implementation() + { + return "Hybrid_Observables"; + } + void connect(gr::top_block_sptr top_block); + void disconnect(gr::top_block_sptr top_block); + gr::basic_block_sptr get_left_block(); + gr::basic_block_sptr get_right_block(); + void reset() + { + return; + } + + //! All blocks must have an item_size() function implementation + size_t item_size() + { + return sizeof(gr_complex); + } + +private: + hybrid_observables_cc_sptr observables_; + bool dump_; + unsigned int fs_in_; + std::string dump_filename_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + boost::shared_ptr queue_; +}; + +#endif diff --git a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt index 9dcdba1b3..935d76e7d 100644 --- a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt @@ -19,6 +19,7 @@ set(OBS_GR_BLOCKS_SOURCES gps_l1_ca_observables_cc.cc galileo_e1_observables_cc.cc + hybrid_observables_cc.cc ) include_directories( diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc new file mode 100644 index 000000000..f76681cef --- /dev/null +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -0,0 +1,215 @@ +/*! + * \file hybrid_observables_cc.cc + * \brief Implementation of the pseudorange computation block for Galileo E1 + * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com + * \author Javier Arribas 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "hybrid_observables_cc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "control_message_factory.h" +#include "gnss_synchro.h" + + +using google::LogMessage; + + +hybrid_observables_cc_sptr +hybrid_make_observables_cc(unsigned int nchannels, boost::shared_ptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) +{ + return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels, queue, dump, dump_filename, output_rate_ms, flag_averaging)); +} + + +hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, boost::shared_ptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) : + gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), + gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro))) +{ + // initialize internal vars + d_queue = queue; + d_dump = dump; + d_nchannels = nchannels; + d_output_rate_ms = output_rate_ms; + d_dump_filename = dump_filename; + d_flag_averaging = flag_averaging; + + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); + } + catch (std::ifstream::failure e) + { + LOG(WARNING) << "Exception opening observables dump file " << e.what(); + } + } + } +} + + + +hybrid_observables_cc::~hybrid_observables_cc() +{ + d_dump_file.close(); +} + + + +bool Hybrid_pairCompare_gnss_synchro_Prn_delay_ms( std::pair a, std::pair b) +{ + return (a.second.Prn_timestamp_ms) < (b.second.Prn_timestamp_ms); +} + + + +bool Hybrid_pairCompare_gnss_synchro_d_TOW_at_current_symbol( std::pair a, std::pair b) +{ + return (a.second.d_TOW_at_current_symbol) < (b.second.d_TOW_at_current_symbol); +} + + + +int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; // Get the input pointer + Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; // Get the output pointer + + Gnss_Synchro current_gnss_synchro[d_nchannels]; + std::map current_gnss_synchro_map; + std::map::iterator gnss_synchro_iter; + d_sample_counter++; //count for the processed samples + /* + * 1. Read the GNSS SYNCHRO objects from available channels + */ + for (unsigned int i = 0; i < d_nchannels; i++) + { + //Copy the telemetry decoder data to local copy + current_gnss_synchro[i] = in[i][0]; + /* + * 1.2 Assume no valid pseudoranges + */ + current_gnss_synchro[i].Flag_valid_pseudorange = false; + current_gnss_synchro[i].Pseudorange_m = 0.0; + if (current_gnss_synchro[i].Flag_valid_word) + { + //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])); + } + } + + /* + * 2. Compute RAW pseudoranges using COMMON RECEPTION TIME algorithm. Use only the valid channels (channels that are tracking a satellite) + */ + DLOG(INFO)<<"gnss_synchro set size="< 0) + { + /* + * 2.1 Use CURRENT set of measurements and find the nearest satellite + * common RX time algorithm + */ + // 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_at_current_symbol); +// double d_TOW_reference = gnss_synchro_iter->second.d_TOW_at_current_symbol; +// double d_ref_PRN_rx_time_ms = gnss_synchro_iter->second.Prn_timestamp_ms; + //int reference_channel= gnss_synchro_iter->second.Channel_ID; + + // Now compute RX time differences due to the PRN alignment in the correlators +// double traveltime_ms; +// double pseudorange_m; +// double delta_rx_time_ms; + for(gnss_synchro_iter = current_gnss_synchro_map.begin(); gnss_synchro_iter != current_gnss_synchro_map.end(); gnss_synchro_iter++) + { + + std::cout<<"CH "<second.Channel_ID<<" tracking GNSS System "<second.System<<" has PRN start at= "<second.Prn_timestamp_ms<<" [ms]"<second.Prn_timestamp_ms-d_ref_PRN_rx_time_ms; +// //compute the pseudorange +// traveltime_ms = (d_TOW_reference - gnss_synchro_iter->second.d_TOW_at_current_symbol)*1000.0 + delta_rx_time_ms + GALILEO_STARTOFFSET_ms; +// pseudorange_m = traveltime_ms * GALILEO_C_m_ms; // [m] +// // update the pseudorange object +// //current_gnss_synchro[gnss_synchro_iter->second.Channel_ID] = gnss_synchro_iter->second; +// current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Pseudorange_m = pseudorange_m; +// current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Flag_valid_pseudorange = true; +// current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].d_TOW_at_current_symbol = round(d_TOW_reference*1000)/1000 + GALILEO_STARTOFFSET_ms/1000.0; +// + } + std::cout<. + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_hybrid_observables_CC_H +#define GNSS_SDR_hybrid_observables_CC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "concurrent_queue.h" +#include "galileo_navigation_message.h" +#include "rinex_printer.h" +#include "Galileo_E1.h" +#include "gnss_synchro.h" + +class hybrid_observables_cc; + +typedef boost::shared_ptr hybrid_observables_cc_sptr; + +hybrid_observables_cc_sptr +hybrid_make_observables_cc(unsigned int n_channels, boost::shared_ptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging); + +/*! + * \brief This class implements a block that computes Galileo observables + */ +class hybrid_observables_cc : public gr::block +{ +public: + ~hybrid_observables_cc (); + void set_fs_in(unsigned long int fs_in) {d_fs_in = fs_in;}; + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + +private: + friend hybrid_observables_cc_sptr + hybrid_make_observables_cc(unsigned int nchannels, boost::shared_ptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging); + hybrid_observables_cc(unsigned int nchannels, boost::shared_ptr queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging); + + // class private vars + boost::shared_ptr d_queue; + bool d_dump; + bool d_flag_averaging; + long int d_sample_counter; + unsigned int d_nchannels; + unsigned long int d_fs_in; + int d_output_rate_ms; + std::string d_dump_filename; + std::ofstream d_dump_file; +}; + +#endif diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc index f408072ed..56e275dda 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc @@ -75,6 +75,10 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu telemetry_decoder_->set_iono_queue(&global_gps_iono_queue); telemetry_decoder_->set_almanac_queue(&global_gps_almanac_queue); telemetry_decoder_->set_utc_model_queue(&global_gps_utc_model_queue); + + //decimation factor + int decimation_factor=configuration->property(role + ".decimation_factor", 1); + telemetry_decoder_->set_decimation(decimation_factor); DLOG(INFO) << "global navigation message queue assigned to telemetry_decoder ("<< telemetry_decoder_->unique_id() << ")"; } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc index cae66432e..a7a3ec1c6 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc @@ -492,6 +492,8 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector } //3. Make the output (copy the object contents to the GNURadio reserved memory) *out[0] = current_synchro_data; + + //std::cout<<"Galileo TLM output on CH="<d_channel << " SAMPLE STAMP="< GNSSBlockFactory::GetObservables(std::shared std::string default_implementation = "GPS_L1_CA_Observables"; std::string implementation = configuration->property("Observables.implementation", default_implementation); LOG(INFO) << "Getting Observables with implementation " << implementation; - unsigned int channel_count = configuration->property("Channels.count", 12); - return GetBlock(configuration, "Observables", implementation, channel_count, channel_count, queue); + unsigned int Galileo_channels = configuration->property("Channels_Galileo.count", 12); + unsigned int GPS_channels = configuration->property("Channels_GPS.count", 12); + return GetBlock(configuration, "Observables", implementation, Galileo_channels + GPS_channels, Galileo_channels + GPS_channels, queue); } @@ -189,8 +192,9 @@ std::unique_ptr GNSSBlockFactory::GetPVT(std::shared_ptrproperty("PVT.implementation", default_implementation); LOG(INFO) << "Getting PVT with implementation " << implementation; - unsigned int channel_count = configuration->property("Channels.count", 12); - return GetBlock(configuration, "PVT", implementation, channel_count, 1, queue); + unsigned int Galileo_channels = configuration->property("Channels_Galileo.count", 12); + unsigned int GPS_channels = configuration->property("Channels_GPS.count", 12); + return GetBlock(configuration, "PVT", implementation, Galileo_channels + GPS_channels, 1, queue); } @@ -204,8 +208,8 @@ std::unique_ptr GNSSBlockFactory::GetOutputFilter(std::share return GetBlock(configuration, "OutputFilter", implementation, 1, 0, queue); } - -std::unique_ptr GNSSBlockFactory::GetChannel( +//********* GPS CHANNEL ***************** +std::unique_ptr GNSSBlockFactory::GetChannel_GPS( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, boost::shared_ptr queue) @@ -217,47 +221,108 @@ std::unique_ptr GNSSBlockFactory::GetChannel( << acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm; std::unique_ptr pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); - std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition", acq, 1, 1, queue); - std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking", trk, 1, 1, queue); - std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder", tlm, 1, 1, queue); + std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_GPS", acq, 1, 1, queue); + std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_GPS", trk, 1, 1, queue); + std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_GPS", tlm, 1, 1, queue); std::unique_ptr channel_(new Channel(configuration.get(), channel, pass_through_.release(), acq_.release(), trk_.release(), tlm_.release(), - "Channel", "Channel", queue)); + "Channel", "GPS", queue)); return channel_; } +//********* GALILEO CHANNEL ***************** +std::unique_ptr GNSSBlockFactory::GetChannel_Galileo( + std::shared_ptr configuration, + std::string acq, std::string trk, std::string tlm, int channel, + boost::shared_ptr queue) +{ + std::stringstream stream; + stream << channel; + std::string id = stream.str(); + LOG(INFO) << "Instantiating Channel " << id << " with Acquisition Implementation: " + << acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm; + + std::unique_ptr pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); + std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_Galileo", acq, 1, 1, queue); + std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_Galileo", trk, 1, 1, queue); + std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_Galileo", tlm, 1, 1, queue); + + std::unique_ptr channel_(new Channel(configuration.get(), channel, pass_through_.release(), + acq_.release(), + trk_.release(), + tlm_.release(), + "Channel", "Galileo", queue)); + + return channel_; +} std::unique_ptr>> GNSSBlockFactory::GetChannels( std::shared_ptr configuration, boost::shared_ptr queue) { std::string default_implementation = "Pass_Through"; - unsigned int channel_count = configuration->property("Channels.count", 12); - LOG(INFO) << "Getting " << channel_count << " channels"; + unsigned int channel_count; + std::string tracking; + std::string telemetry_decoder; + std::string acquisition_implementation; std::unique_ptr>> channels(new std::vector>()); - std::string tracking = configuration->property("Tracking.implementation", default_implementation); - std::string telemetry_decoder = configuration->property("TelemetryDecoder.implementation", default_implementation); - std::string acquisition_implementation = configuration->property("Acquisition.implementation", default_implementation); + unsigned int channel_absolute_id=0; + + //**************** GPS CHANNELS ********************** + channel_count= configuration->property("Channels_GPS.count", 12); + + LOG(INFO) << "Getting " << channel_count << " GPS channels"; + + tracking = configuration->property("Tracking_GPS.implementation", default_implementation); + telemetry_decoder = configuration->property("TelemetryDecoder_GPS.implementation", default_implementation); + acquisition_implementation = configuration->property("Acquisition_GPS.implementation", default_implementation); for (unsigned int i = 0; i < channel_count; i++) { std::string acquisition_implementation_specific = configuration->property( - "Acquisition" + boost::lexical_cast(i) + ".implementation", + "Acquisition_GPS" + boost::lexical_cast(i) + ".implementation", default_implementation); if(acquisition_implementation_specific.compare(default_implementation) != 0) { acquisition_implementation = acquisition_implementation_specific; } - channels->push_back(std::move(GetChannel(configuration, - acquisition_implementation, tracking, telemetry_decoder, i, queue))); + channels->push_back(std::move(GetChannel_GPS(configuration, + acquisition_implementation, tracking, telemetry_decoder, channel_absolute_id, queue))); + channel_absolute_id++; } + + //**************** GALILEO CHANNELS ********************** + channel_count= configuration->property("Channels_Galileo.count", 12); + + LOG(INFO) << "Getting " << channel_count << " Galileo channels"; + + tracking = configuration->property("Tracking_Galileo.implementation", default_implementation); + telemetry_decoder = configuration->property("TelemetryDecoder_Galileo.implementation", default_implementation); + acquisition_implementation = configuration->property("Acquisition_Galileo.implementation", default_implementation); + + for (unsigned int i = 0; i < channel_count; i++) + { + std::string acquisition_implementation_specific = configuration->property( + "Acquisition_Galileo" + boost::lexical_cast(i) + ".implementation", + default_implementation); + if(acquisition_implementation_specific.compare(default_implementation) != 0) + { + acquisition_implementation = acquisition_implementation_specific; + } + channels->push_back(std::move(GetChannel_Galileo(configuration, + acquisition_implementation, tracking, telemetry_decoder, channel_absolute_id, queue))); + channel_absolute_id++; + } + + + return channels; } @@ -526,7 +591,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams, queue)); block = std::move(block_); } - + else if (implementation.compare("Hybrid_Observables") == 0) + { + std::unique_ptr block_(new HybridObservables(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } // PVT ------------------------------------------------------------------------- else if (implementation.compare("GPS_L1_CA_PVT") == 0) { @@ -540,6 +610,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams, queue)); block = std::move(block_); } + else if (implementation.compare("Hybrid_PVT") == 0) + { + std::unique_ptr block_(new HybridPvt(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } // OUTPUT FILTERS -------------------------------------------------------------- else if (implementation.compare("Null_Sink_Output_Filter") == 0) { @@ -556,7 +632,7 @@ std::unique_ptr GNSSBlockFactory::GetBlock( else { // Log fatal. This causes execution to stop. - LOG(ERROR) << implementation << ": Undefined implementation for block"; + LOG(ERROR) << role<<"."< GNSSBlockFactory::GetAcqBlock( else { // Log fatal. This causes execution to stop. - LOG(ERROR) << implementation << ": Undefined implementation for block"; + LOG(ERROR) << role<<"."< GNSSBlockFactory::GetTrkBlock( else { // Log fatal. This causes execution to stop. - LOG(ERROR) << implementation << ": Undefined implementation for block"; + LOG(ERROR) << role<<"."< GNSSBlockFactory::GetTlmBlock( else { // Log fatal. This causes execution to stop. - LOG(ERROR) << implementation << ": Undefined implementation for block"; + LOG(ERROR) << role<<"."< GetOutputFilter(std::shared_ptr configuration, boost::shared_ptr queue); - std::unique_ptr GetChannel(std::shared_ptr configuration, + std::unique_ptr GetChannel_GPS(std::shared_ptr configuration, + std::string acq, std::string trk, std::string tlm, int channel, + boost::shared_ptr queue); + + std::unique_ptr GetChannel_Galileo(std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, boost::shared_ptr queue); diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 3c880e76d..00ff77b66 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -271,6 +271,13 @@ void GNSSFlowgraph::connect() return; } + //discriminate between systems + //TODO: add a specific string member to the channel template, and not re-use the implementation field! + while (channels_.at(i)->implementation()!= available_GNSS_signals_.front().get_satellite().get_system()) + { + available_GNSS_signals_.push_back(available_GNSS_signals_.front()); + available_GNSS_signals_.pop_front(); + } channels_.at(i)->set_signal(available_GNSS_signals_.front()); LOG(INFO) << "Channel " << i << " assigned to " << available_GNSS_signals_.front(); available_GNSS_signals_.pop_front(); @@ -325,9 +332,6 @@ void GNSSFlowgraph::connect() top_block_->dump(); } - - - void GNSSFlowgraph::wait() { if (!running_) @@ -340,10 +344,6 @@ void GNSSFlowgraph::wait() running_ = false; } - - - - /* * Applies an action to the flowgraph * @@ -493,16 +493,15 @@ void GNSSFlowgraph::set_signals_list() */ /* - * Read GNSS-SDR default GNSS system and signal + * Read GNSS-SDR default GNSS system */ std::string default_system = configuration_->property("Channel.system", std::string("GPS")); - std::string default_signal = configuration_->property("Channel.signal", std::string("1C")); /* * Loop to create the list of GNSS Signals * To add signals from other systems, add another loop 'for' */ - if (default_system.compare(std::string("GPS")) == 0) + if (default_system.find(std::string("GPS")) != std::string::npos) { /* * Loop to create GPS L1 C/A signals @@ -521,7 +520,7 @@ void GNSSFlowgraph::set_signals_list() } - if (default_system.compare(std::string("SBAS")) == 0) + if (default_system.find(std::string("SBAS")) != std::string::npos) { /* * Loop to create SBAS L1 C/A signals @@ -538,7 +537,7 @@ void GNSSFlowgraph::set_signals_list() } - if (default_system.compare(std::string("Galileo")) == 0) + if (default_system.find(std::string("Galileo")) != std::string::npos) { /* * Loop to create the list of Galileo E1 B signals @@ -559,6 +558,7 @@ void GNSSFlowgraph::set_signals_list() /* * Ordering the list of signals from configuration file */ + std::string default_signal = configuration_->property("Channel.signal", std::string("1C")); std::list::iterator gnss_it = available_GNSS_signals_.begin(); @@ -591,14 +591,14 @@ void GNSSFlowgraph::set_signals_list() } // **** FOR DEBUGGING THE LIST OF GNSS SIGNALS **** // - //std::cout<<"default_system="<