From b8d3f293f16dcf1dfd7a7ff907c0384ddb0f5117 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 5 Jun 2015 18:46:00 +0200 Subject: [PATCH] GPS L2C bug fixes. Added skeleton for a Mixed (multi-frequency and multi-system) observables block. --- ...el_GPS_L2_M_Flexiband_bin_file_III_1a.conf | 2 +- ...el_GPS_L2_M_Flexiband_bin_file_III_1b.conf | 216 ++++++------- .../observables/adapters/CMakeLists.txt | 1 + .../gnuradio_blocks/CMakeLists.txt | 1 + .../adapters/gps_l2_m_telemetry_decoder.cc | 12 +- .../gps_l2_m_telemetry_decoder_cc.cc | 296 ++++++++++-------- .../gps_l2_m_telemetry_decoder_cc.h | 22 +- .../gps_l2_m_dll_pll_tracking_cc.cc | 3 +- src/core/receiver/gnss_block_factory.cc | 7 + src/core/system_parameters/GPS_L2C.h | 3 + .../system_parameters/gps_cnav_ephemeris.cc | 3 + .../gps_cnav_navigation_message.cc | 98 +++--- .../gps_cnav_navigation_message.h | 19 +- src/main/main.cc | 10 +- src/tests/test_main.cc | 10 +- src/utils/front-end-cal/front_end_cal.cc | 2 + src/utils/front-end-cal/main.cc | 8 + 17 files changed, 390 insertions(+), 323 deletions(-) diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1a.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1a.conf index 7853617c2..4b26ea9e4 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1a.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1a.conf @@ -28,7 +28,7 @@ GNSS-SDR.SUPL_CI=0x31b0 ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) SignalSource.implementation=Flexiband_Signal_Source -SignalSource.flag_read_file=true +SignalSource.flag_read_file=false ;SignalSource.signal_file=/datalogger/captures/eclipse/eclipse_IIIa_2.bin SignalSource.signal_file=/datalogger/signals/Fraunhofer/L125_III1b_210s.usb diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf index c8d61999e..1be430897 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf @@ -267,12 +267,12 @@ Resampler2.implementation=Pass_Through ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. -Channels_1C.count=8 -Channels_2S.count=8 +Channels_1C.count=1 +Channels_2S.count=4 ;#count: Number of available Galileo satellite channels. ;Channels_Galileo.count=0 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver -Channels.in_acquisition=2 +Channels.in_acquisition=1 ;#signal: @@ -286,17 +286,17 @@ Channels.in_acquisition=2 Channel0.RF_channel_ID=0 Channel0.signal=1C -Channel1.RF_channel_ID=0 -Channel1.signal=1C +Channel1.RF_channel_ID=1 +Channel1.signal=2S -Channel2.RF_channel_ID=0 -Channel2.signal=1C +Channel2.RF_channel_ID=1 +Channel2.signal=2S -Channel3.RF_channel_ID=0 -Channel3.signal=1C +Channel3.RF_channel_ID=1 +Channel3.signal=2S -Channel4.RF_channel_ID=0 -Channel4.signal=1C +Channel4.RF_channel_ID=1 +Channel4.signal=2S Channel5.RF_channel_ID=0 Channel5.signal=1C @@ -443,53 +443,53 @@ Acquisition_1C7.max_dwells=2 ;# GPS L2C M -Acquisition_2S8.dump=false -Acquisition_2S8.dump_filename=./acq_dump.dat -Acquisition_2S8.item_type=gr_complex -Acquisition_2S8.if=0 -Acquisition_2S8.implementation=GPS_L2_M_PCPS_Acquisition -Acquisition_2S8.threshold=0.0005 -;Acquisition_2S8.pfa=0.001 -Acquisition_2S8.doppler_max=5000 -Acquisition_2S8.doppler_min=-5000 -Acquisition_2S8.doppler_step=100 -Acquisition_2S8.max_dwells=1 +Acquisition_2S1.dump=false +Acquisition_2S1.dump_filename=./acq_dump.dat +Acquisition_2S1.item_type=gr_complex +Acquisition_2S1.if=0 +Acquisition_2S1.implementation=GPS_L2_M_PCPS_Acquisition +Acquisition_2S1.threshold=0.0007 +;Acquisition_2S1.pfa=0.001 +Acquisition_2S1.doppler_max=5000 +Acquisition_2S1.doppler_min=-5000 +Acquisition_2S1.doppler_step=10 +Acquisition_2S1.max_dwells=1 -Acquisition_2S9.dump=false -Acquisition_2S9.dump_filename=./acq_dump.dat -Acquisition_2S9.item_type=gr_complex -Acquisition_2S9.if=0 -Acquisition_2S9.implementation=GPS_L2_M_PCPS_Acquisition -Acquisition_2S9.threshold=0.0005 -;Acquisition_2S9.pfa=0.001 -Acquisition_2S9.doppler_max=5000 -Acquisition_2S9.doppler_min=-5000 -Acquisition_2S9.doppler_step=100 -Acquisition_2S9.max_dwells=1 +Acquisition_2S2.dump=false +Acquisition_2S2.dump_filename=./acq_dump.dat +Acquisition_2S2.item_type=gr_complex +Acquisition_2S2.if=0 +Acquisition_2S2.implementation=GPS_L2_M_PCPS_Acquisition +Acquisition_2S2.threshold=0.0005 +;Acquisition_2S2.pfa=0.001 +Acquisition_2S2.doppler_max=5000 +Acquisition_2S2.doppler_min=-5000 +Acquisition_2S2.doppler_step=100 +Acquisition_2S2.max_dwells=1 -Acquisition_2S10.dump=false -Acquisition_2S10.dump_filename=./acq_dump.dat -Acquisition_2S10.item_type=gr_complex -Acquisition_2S10.if=0 -Acquisition_2S10.implementation=GPS_L2_M_PCPS_Acquisition -Acquisition_2S10.threshold=0.0005 -;Acquisition_2S10.pfa=0.001 -Acquisition_2S10.doppler_max=5000 -Acquisition_2S10.doppler_min=-5000 -Acquisition_2S10.doppler_step=100 -Acquisition_2S10.max_dwells=1 +Acquisition_2S3.dump=false +Acquisition_2S3.dump_filename=./acq_dump.dat +Acquisition_2S3.item_type=gr_complex +Acquisition_2S3.if=0 +Acquisition_2S3.implementation=GPS_L2_M_PCPS_Acquisition +Acquisition_2S3.threshold=0.0005 +;Acquisition_2S3.pfa=0.001 +Acquisition_2S3.doppler_max=5000 +Acquisition_2S3.doppler_min=-5000 +Acquisition_2S3.doppler_step=100 +Acquisition_2S3.max_dwells=1 -Acquisition_2S11.dump=false -Acquisition_2S11.dump_filename=./acq_dump.dat -Acquisition_2S11.item_type=gr_complex -Acquisition_2S11.if=0 -Acquisition_2S11.implementation=GPS_L2_M_PCPS_Acquisition -Acquisition_2S11.threshold=0.0005 -;Acquisition_2S11.pfa=0.001 -Acquisition_2S11.doppler_max=5000 -Acquisition_2S11.doppler_min=-5000 -Acquisition_2S11.doppler_step=100 -Acquisition_2S11.max_dwells=1 +Acquisition_2S4.dump=false +Acquisition_2S4.dump_filename=./acq_dump.dat +Acquisition_2S4.item_type=gr_complex +Acquisition_2S4.if=0 +Acquisition_2S4.implementation=GPS_L2_M_PCPS_Acquisition +Acquisition_2S4.threshold=0.0005 +;Acquisition_2S4.pfa=0.001 +Acquisition_2S4.doppler_max=5000 +Acquisition_2S4.doppler_min=-5000 +Acquisition_2S4.doppler_step=100 +Acquisition_2S4.max_dwells=1 Acquisition_2S12.dump=false Acquisition_2S12.dump_filename=./acq_dump.dat @@ -636,49 +636,49 @@ Tracking_1C7.order=3; Tracking_1C7.early_late_space_chips=0.5; ;######### TRACKING CHANNEL 8 CONFIG ############ -Tracking_2S8.implementation=GPS_L2_M_DLL_PLL_Tracking -Tracking_2S8.item_type=gr_complex -Tracking_2S8.if=0 -Tracking_2S8.dump=false -Tracking_2S8.dump_filename=./tracking_ch_ -Tracking_2S8.pll_bw_hz=2.0; -Tracking_2S8.dll_bw_hz=0.5; -Tracking_2S8.fll_bw_hz=2.0; -Tracking_2S8.order=2; -Tracking_2S8.early_late_space_chips=0.5; +Tracking_2S1.implementation=GPS_L2_M_DLL_PLL_Tracking +Tracking_2S1.item_type=gr_complex +Tracking_2S1.if=0 +Tracking_2S1.dump=true +Tracking_2S1.dump_filename=./tracking_ch_ +Tracking_2S1.pll_bw_hz=3.0; +Tracking_2S1.dll_bw_hz=2; +Tracking_2S1.fll_bw_hz=2.0; +Tracking_2S1.order=3; +Tracking_2S1.early_late_space_chips=0.5; ;######### TRACKING CHANNEL 9 CONFIG ############ -Tracking_2S9.implementation=GPS_L2_M_DLL_PLL_Tracking -Tracking_2S9.item_type=gr_complex -Tracking_2S9.if=0 -Tracking_2S9.dump=false -Tracking_2S9.dump_filename=./tracking_ch_ -Tracking_2S9.pll_bw_hz=2.0; -Tracking_2S9.dll_bw_hz=0.5; -Tracking_2S9.fll_bw_hz=2.0; -Tracking_2S9.order=2; -Tracking_2S9.early_late_space_chips=0.5; +Tracking_2S2.implementation=GPS_L2_M_DLL_PLL_Tracking +Tracking_2S2.item_type=gr_complex +Tracking_2S2.if=0 +Tracking_2S2.dump=true +Tracking_2S2.dump_filename=./tracking_ch_ +Tracking_2S2.pll_bw_hz=3.0; +Tracking_2S2.dll_bw_hz=1; +Tracking_2S2.fll_bw_hz=2.0; +Tracking_2S2.order=3; +Tracking_2S2.early_late_space_chips=0.5; ;######### TRACKING CHANNEL 10 CONFIG ############ -Tracking_2S10.implementation=GPS_L2_M_DLL_PLL_Tracking -Tracking_2S10.item_type=gr_complex -Tracking_2S10.if=0 -Tracking_2S10.dump=false -Tracking_2S10.dump_filename=./tracking_ch_ -Tracking_2S10.pll_bw_hz=2.0; -Tracking_2S10.dll_bw_hz=0.5; -Tracking_2S10.fll_bw_hz=2.0; -Tracking_2S10.order=2; -Tracking_2S10.early_late_space_chips=0.5; +Tracking_2S3.implementation=GPS_L2_M_DLL_PLL_Tracking +Tracking_2S3.item_type=gr_complex +Tracking_2S3.if=0 +Tracking_2S3.dump=true +Tracking_2S3.dump_filename=./tracking_ch_ +Tracking_2S3.pll_bw_hz=3.0; +Tracking_2S3.dll_bw_hz=1; +Tracking_2S3.fll_bw_hz=2.0; +Tracking_2S3.order=3; +Tracking_2S3.early_late_space_chips=0.5; ;######### TRACKING CHANNEL 11 CONFIG ############ -Tracking_2S11.implementation=GPS_L2_M_DLL_PLL_Tracking -Tracking_2S11.item_type=gr_complex -Tracking_2S11.if=0 -Tracking_2S11.dump=false -Tracking_2S11.dump_filename=./tracking_ch_ -Tracking_2S11.pll_bw_hz=2.0; -Tracking_2S11.dll_bw_hz=0.5; -Tracking_2S11.fll_bw_hz=2.0; -Tracking_2S11.order=2; -Tracking_2S11.early_late_space_chips=0.5; +Tracking_2S4.implementation=GPS_L2_M_DLL_PLL_Tracking +Tracking_2S4.item_type=gr_complex +Tracking_2S4.if=0 +Tracking_2S4.dump=true +Tracking_2S4.dump_filename=./tracking_ch_ +Tracking_2S4.pll_bw_hz=3.0; +Tracking_2S4.dll_bw_hz=1; +Tracking_2S4.fll_bw_hz=2.0; +Tracking_2S4.order=3; +Tracking_2S4.early_late_space_chips=0.5; ;######### TRACKING CHANNEL 12 CONFIG ############ Tracking_2S12.implementation=GPS_L2_M_DLL_PLL_Tracking @@ -764,21 +764,21 @@ TelemetryDecoder_1C7.dump=false TelemetryDecoder_1C7.decimation_factor=20; -TelemetryDecoder_2S8.implementation=GPS_L2_M_Telemetry_Decoder -TelemetryDecoder_2S8.dump=false -TelemetryDecoder_2S8.decimation_factor=1; +TelemetryDecoder_2S1.implementation=GPS_L2_M_Telemetry_Decoder +TelemetryDecoder_2S1.dump=false +TelemetryDecoder_2S1.decimation_factor=1; -TelemetryDecoder_2S9.implementation=GPS_L2_M_Telemetry_Decoder -TelemetryDecoder_2S9.dump=false -TelemetryDecoder_2S9.decimation_factor=1; +TelemetryDecoder_2S2.implementation=GPS_L2_M_Telemetry_Decoder +TelemetryDecoder_2S2.dump=false +TelemetryDecoder_2S2.decimation_factor=1; -TelemetryDecoder_2S10.implementation=GPS_L2_M_Telemetry_Decoder -TelemetryDecoder_2S10.dump=false -TelemetryDecoder_2S10.decimation_factor=1; +TelemetryDecoder_2S3.implementation=GPS_L2_M_Telemetry_Decoder +TelemetryDecoder_2S3.dump=false +TelemetryDecoder_2S3.decimation_factor=1; -TelemetryDecoder_2S11.implementation=GPS_L2_M_Telemetry_Decoder -TelemetryDecoder_2S11.dump=false -TelemetryDecoder_2S11.decimation_factor=1; +TelemetryDecoder_2S4.implementation=GPS_L2_M_Telemetry_Decoder +TelemetryDecoder_2S4.dump=false +TelemetryDecoder_2S4.decimation_factor=1; TelemetryDecoder_2S12.implementation=GPS_L2_M_Telemetry_Decoder TelemetryDecoder_2S12.dump=false @@ -798,7 +798,7 @@ TelemetryDecoder_2S15.decimation_factor=1; ;######### OBSERVABLES CONFIG ############ -;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A. +;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.Mixed_Observables Observables.implementation=GPS_L1_CA_Observables ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] diff --git a/src/algorithms/observables/adapters/CMakeLists.txt b/src/algorithms/observables/adapters/CMakeLists.txt index 0969dc22e..6f526dc4c 100644 --- a/src/algorithms/observables/adapters/CMakeLists.txt +++ b/src/algorithms/observables/adapters/CMakeLists.txt @@ -20,6 +20,7 @@ set(OBS_ADAPTER_SOURCES gps_l1_ca_observables.cc galileo_e1_observables.cc hybrid_observables.cc + mixed_observables.cc ) include_directories( diff --git a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt index d22e7a0dd..27c266fb9 100644 --- a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt @@ -20,6 +20,7 @@ set(OBS_GR_BLOCKS_SOURCES gps_l1_ca_observables_cc.cc galileo_e1_observables_cc.cc hybrid_observables_cc.cc + mixed_observables_cc.cc ) include_directories( diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l2_m_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l2_m_telemetry_decoder.cc index 4c77b4629..ae71fa922 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l2_m_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l2_m_telemetry_decoder.cc @@ -40,10 +40,10 @@ #include "configuration_interface.h" #include "concurrent_queue.h" -extern concurrent_queue global_gps_ephemeris_queue; -extern concurrent_queue global_gps_iono_queue; -extern concurrent_queue global_gps_utc_model_queue; -extern concurrent_queue global_gps_almanac_queue; +extern concurrent_queue global_gps_cnav_ephemeris_queue; +extern concurrent_queue global_gps_cnav_iono_queue; +//extern concurrent_queue global_gps_utc_model_queue; +//extern concurrent_queue global_gps_almanac_queue; using google::LogMessage; @@ -71,8 +71,8 @@ GpsL2MTelemetryDecoder::GpsL2MTelemetryDecoder(ConfigurationInterface* configura telemetry_decoder_ = gps_l2_m_make_telemetry_decoder_cc(satellite_, 0, (long)fs_in, vector_length_, queue_, dump_); // TODO fix me DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; // set the navigation msg queue; - //telemetry_decoder_->set_ephemeris_queue(&global_gps_ephemeris_queue); - //telemetry_decoder_->set_iono_queue(&global_gps_iono_queue); + telemetry_decoder_->set_ephemeris_queue(&global_gps_cnav_ephemeris_queue); + telemetry_decoder_->set_iono_queue(&global_gps_cnav_iono_queue); //telemetry_decoder_->set_almanac_queue(&global_gps_almanac_queue); //telemetry_decoder_->set_utc_model_queue(&global_gps_utc_model_queue); diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.cc index 38586a528..6f1d90cf7 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.cc @@ -34,7 +34,6 @@ #include #include #include -#include "control_message_factory.h" #include "gnss_synchro.h" #include "gps_l2_m_telemetry_decoder_cc.h" @@ -75,13 +74,18 @@ gps_l2_m_telemetry_decoder_cc::gps_l2_m_telemetry_decoder_cc( d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); LOG(INFO) << "GPS L2C M TELEMETRY PROCESSING: satellite " << d_satellite; d_fs_in = fs_in; - d_block_size = d_samples_per_symbol * d_symbols_per_bit * d_block_size_in_bits*2; // two CNAV frames + d_block_size = GPS_L2_SAMPLES_PER_SYMBOL * GPS_L2_SYMBOLS_PER_BIT * GPS_L2_CNAV_DATA_PAGE_BITS*2; // two CNAV frames d_decimation_output_factor=0; //set_output_multiple (1); d_average_count=0; d_flag_invert_buffer_symbols=false; d_flag_invert_input_symbols=false; d_channel=0; + d_iono_queue=0; + d_ephemeris_queue=0; + d_flag_valid_word=false; + d_TOW_at_current_symbol=0; + d_TOW_at_Preamble=0; //set_history(d_samples_per_bit*8); // At least a history of 8 bits are needed to correlate with the preamble } @@ -118,6 +122,8 @@ int gps_l2_m_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_in // store the time stamp of the first sample in the processed sample block double sample_stamp = in[0].Tracking_timestamp_secs; + bool flag_new_cnav_frame=false; + int last_frame_preamble_start=0; // copy correlation samples into samples vector //for (int i = 0; i < noutput_items; i++) /// { @@ -132,118 +138,148 @@ int gps_l2_m_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_in // decode only if enough samples in buffer if(d_sample_buf.size() >= d_block_size) { - d_flag_invert_buffer_symbols=false; - while (true) + if (in[0].Flag_valid_tracking==false) // check if the tracking is locked { - - if (d_flag_invert_buffer_symbols==true) + //LOG(INFO)<< "Discarting channel "<::iterator symbol_it = d_sample_buf.begin(); symbol_it != d_sample_buf.end(); symbol_it++) - { - *symbol_it = -(*symbol_it); - } - LOG(INFO)<<"Inverting buffer symbols"; - } - //debug - std::stringstream ss2; - for (std::vector::const_iterator symbol_it = d_sample_buf.begin(); symbol_it < d_sample_buf.end(); ++symbol_it) + if (d_flag_invert_buffer_symbols==true) { - if(*symbol_it>=0) +// for (int m=0;m::iterator symbol_it = d_sample_buf.begin(); symbol_it != d_sample_buf.end(); symbol_it++) { - ss2<<'1'; - }else{ - ss2<<'0'; + *symbol_it = -(*symbol_it); } - } - LOG(INFO)<<"get_symbols="< bits; - bool symbol_alignment = d_symbol_aligner_and_decoder.get_bits(d_sample_buf, bits); - - std::stringstream ss; - - for (std::vector::const_iterator bit_it = bits.begin(); bit_it < bits.end(); ++bit_it) - { - ss << *bit_it; + //LOG(INFO)<<"Inverting buffer symbols"; } - LOG(INFO)<<"get_bits="< msg_candidates; - d_frame_detector.get_frame_candidates(bits, msg_candidates); + //debug +// std::stringstream ss2; +// for (std::vector::const_iterator symbol_it = d_sample_buf.begin(); symbol_it < d_sample_buf.end(); ++symbol_it) +// { +// +// ss2<<*symbol_it<<","; +// if(*symbol_it>=0) +// { +// ss2<<'1'; +// }else{ +// ss2<<'0'; +// } +// } + //LOG(INFO)<<"get_symbols="< valid_msgs; - d_crc_verifier.get_valid_frames(msg_candidates, valid_msgs); - if (valid_msgs.size()==0) - { - if (d_flag_invert_buffer_symbols==false) + + // align symbols in pairs + // and obtain the bits by decoding the symbols (viterbi decoder) + // they can be already aligned or shifted by one position + std::vector bits; + bool symbol_alignment = d_symbol_aligner_and_decoder.get_bits(d_sample_buf, bits); + + std::stringstream ss; + + for (std::vector::const_iterator bit_it = bits.begin(); bit_it < bits.end(); ++bit_it) + { + ss << *bit_it; + } + +// LOG(INFO)<<"get_bits="< msg_candidates; + d_frame_detector.get_frame_candidates(bits, msg_candidates); + + // verify checksum + // and return the valid messages + std::vector valid_msgs; + d_crc_verifier.get_valid_frames(msg_candidates, valid_msgs); + if (valid_msgs.size()==0) { - d_flag_invert_buffer_symbols=true; - }else{//already tested the symbol inversion but CRC still fail - LOG(INFO)<<"Discarting this buffer, no CNAV frames detected"; + if (d_flag_invert_buffer_symbols==d_flag_invert_input_symbols) + { + d_flag_invert_buffer_symbols=not d_flag_invert_buffer_symbols; + }else{//already tested the symbol inversion but CRC still fail + LOG(INFO)<<"Discarting this buffer, no CNAV frames detected CH "<d_channel; + break; + } + }else{ //at least one frame has good CRC, keep the invert sign for the next frames + d_flag_invert_input_symbols=d_flag_invert_buffer_symbols; + std::vector tmp_msg; + std::string msg; + LOG(INFO)<d_channel; + for (unsigned int i=0;ipush(ephemeris); + } + if (d_CNAV_Message.have_new_iono() == true) + { + Gps_CNAV_Iono iono= d_CNAV_Message.get_iono(); //notice that the read operation will clear the valid flag + std::cout<<"New GPS CNAV IONO model received for SV "<push(iono); + } + } break; } - }else{ //at least one frame has good CRC, keep the invert sign for the next frames - d_flag_invert_input_symbols=d_flag_invert_buffer_symbols; - std::vector tmp_msg; - std::string msg; - LOG(INFO)< sbas_raw_msgs; -// for(std::vector::const_iterator it = valid_msgs.begin(); -// it != valid_msgs.end(); ++it) -// { -// int message_sample_offset = -// (sample_alignment ? 0 : -1) -// + d_samples_per_symbol*(symbol_alignment ? -1 : 0) -// + d_samples_per_symbol * d_symbols_per_bit * it->first; -// double message_sample_stamp = sample_stamp + ((double)message_sample_offset)/1000; -// VLOG(EVENT) << "message_sample_stamp=" << message_sample_stamp -// << " (sample_stamp=" << sample_stamp -// << " sample_alignment=" << sample_alignment -// << " symbol_alignment=" << symbol_alignment -// << " relative_preamble_start=" << it->first -// << " message_sample_offset=" << message_sample_offset -// << ")"; -// Sbas_Raw_Msg sbas_raw_msg(message_sample_stamp, this->d_satellite.get_PRN(), it->second); -// sbas_raw_msgs.push_back(sbas_raw_msg); -// } -// -// // parse messages -// // and send them to the SBAS raw message queue -// for(std::vector::iterator it = sbas_raw_msgs.begin(); it != sbas_raw_msgs.end(); it++) -// { -// std::cout << "SBAS message type " << it->get_msg_type() << " from PRN" << it->get_prn() << " received" << std::endl; -// sbas_telemetry_data.update(*it); -// } - // clear all processed samples in the input buffer d_sample_buf.clear(); } // UPDATE GNSS SYNCHRO DATA Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block - //1. Copy the current tracking output - current_synchro_data = in[0]; - //2. Add the telemetry decoder information - current_synchro_data.Flag_valid_word = false; // indicate to observable block that this synchro object isn't valid for pseudorange computation + + //1. Copy the current tracking output + current_synchro_data = in[0]; + + + if (d_flag_valid_word==true) + { + double Prn_timestamp_at_preamble_ms=0; + //2. Add the telemetry decoder information + if (flag_new_cnav_frame==true) + { + //update TOW at the preamble instant + Prn_timestamp_at_preamble_ms = (in[0].Tracking_timestamp_secs * 1000.0)-(d_block_size-last_frame_preamble_start)*GPS_L2_M_PERIOD; + d_TOW_at_Preamble = d_CNAV_Message.d_TOW - GPS_L2_CNAV_DATA_PAGE_DURATION_S; + d_TOW_at_current_symbol = d_TOW_at_Preamble + (d_block_size-last_frame_preamble_start)*GPS_L2_M_PERIOD; + 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; + current_synchro_data.Flag_preamble = false; + current_synchro_data.Prn_timestamp_ms = in[0].Tracking_timestamp_secs * 1000.0; + current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms; + }else{ + d_TOW_at_current_symbol = d_TOW_at_Preamble + (d_block_size-last_frame_preamble_start)*GPS_L2_M_PERIOD; + 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; + current_synchro_data.Flag_preamble = false; + current_synchro_data.Prn_timestamp_ms = in[0].Tracking_timestamp_secs * 1000.0; + current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms; + } + current_synchro_data.Flag_valid_word = true; + }else{ + current_synchro_data.Flag_valid_word = false; + } d_average_count++; if (d_average_count == d_decimation_output_factor) @@ -311,7 +347,7 @@ void gps_l2_m_telemetry_decoder_cc::symbol_aligner_and_decoder::reset() bool gps_l2_m_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const std::vector symbols, std::vector &bits) { const int traceback_depth = 5*d_KK; - int nbits_requested = symbols.size()/d_symbols_per_bit; + int nbits_requested = symbols.size()/GPS_L2_SYMBOLS_PER_BIT; int nbits_decoded; // fill two vectors with the two possible symbol alignments std::vector symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector @@ -327,7 +363,7 @@ bool gps_l2_m_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const s // decode float metric_vd1 = d_vd1->decode_continuous(symbols_vd1.data(), traceback_depth, bits_vd1, nbits_requested, nbits_decoded); float metric_vd2 = d_vd2->decode_continuous(symbols_vd2.data(), traceback_depth, bits_vd2, nbits_requested, nbits_decoded); - LOG(INFO)<<"metric_vd1="<::const_iterator bit_it = bits.begin(); bit_it < bits.end(); ++bit_it) { d_buffer.push_back(*bit_it); - ss << *bit_it; + //ss << *bit_it; count++; } //LOG(INFO) << ss.str() << " into working buffer (" << count << " bits)"; int relative_preamble_start = 0; - while(d_buffer.size() >= sbas_msg_length) + while(d_buffer.size() >= cnav_msg_length) { // compare with all preambles for (std::vector>::iterator preample_it = preambles.begin(); preample_it < preambles.end(); ++preample_it) @@ -388,7 +424,7 @@ void gps_l2_m_telemetry_decoder_cc::frame_detector::get_frame_candidates(const s { // copy candidate std::vector candidate; - std::copy(d_buffer.begin(), d_buffer.begin() + sbas_msg_length, std::back_inserter(candidate)); + std::copy(d_buffer.begin(), d_buffer.begin() + cnav_msg_length, std::back_inserter(candidate)); if(inv_preamble_detected) { // invert bits @@ -396,10 +432,10 @@ void gps_l2_m_telemetry_decoder_cc::frame_detector::get_frame_candidates(const s *candidate_bit_it = *candidate_bit_it == 0 ? 1 : 0; } msg_candidates.push_back(std::pair>(relative_preamble_start, candidate)); - ss.str(""); - ss << "preamble " << preample_it - preambles.begin() << (inv_preamble_detected?" inverted":" normal") << " detected! candidate="; - for (std::vector::iterator bit_it = candidate.begin(); bit_it < candidate.end(); ++bit_it) - ss << *bit_it; + //ss.str(""); + //ss << "preamble " << preample_it - preambles.begin() << (inv_preamble_detected?" inverted":" normal") << " detected! candidate="; + //for (std::vector::iterator bit_it = candidate.begin(); bit_it < candidate.end(); ++bit_it) + // ss << *bit_it; //LOG(INFO) << ss.str(); } } @@ -432,8 +468,8 @@ void gps_l2_m_telemetry_decoder_cc::crc_verifier::get_valid_frames(const std::ve d_checksum_agent.reset(0); d_checksum_agent.process_bytes(candidate_bytes.data(), candidate_bytes.size()); unsigned int crc = d_checksum_agent.checksum(); - LOG(INFO) << "candidate " << ": final crc remainder= " << std::hex << crc - << std::setfill(' ') << std::resetiosflags(std::ios::hex); + //LOG(INFO) << "candidate " << ": final crc remainder= " << std::hex << crc + // << std::setfill(' ') << std::resetiosflags(std::ios::hex); // the final remainder must be zero for a valid message, because the CRC is done over the received CRC value if (crc == 0) { @@ -480,7 +516,7 @@ void gps_l2_m_telemetry_decoder_cc::crc_verifier::zerropad_front_and_convert_to_ const size_t bits_per_byte = 8; unsigned char byte = 0; int idx_bit = 6; // insert 6 zeros at the front to fit the 250bits into a multiple of bytes - LOG(INFO) << "zerropad_front_and_convert_to_bytes():" << byte; + //LOG(INFO) << "zerropad_front_and_convert_to_bytes():" << byte; for (std::vector::const_iterator candidate_bit_it = msg_candidate.begin(); candidate_bit_it < msg_candidate.end(); ++candidate_bit_it) { int bit_pos_in_current_byte = (bits_per_byte - 1) - (idx_bit % bits_per_byte); @@ -489,37 +525,23 @@ void gps_l2_m_telemetry_decoder_cc::crc_verifier::zerropad_front_and_convert_to_ if (idx_bit % bits_per_byte == bits_per_byte - 1) { bytes.push_back(byte); - LOG(INFO) << ss.str() << " -> byte=" << std::setw(2) - << std::setfill('0') << std::hex << (unsigned int)byte; ss.str(""); + //LOG(INFO) << ss.str() << " -> byte=" << std::setw(2) + // << std::setfill('0') << std::hex << (unsigned int)byte; ss.str(""); byte = 0; } idx_bit++; } - LOG(INFO) << " -> byte=" << std::setw(2) - << std::setfill('0') << std::hex << (unsigned int)byte - << std::setfill(' ') << std::resetiosflags(std::ios::hex); + //LOG(INFO) << " -> byte=" << std::setw(2) + // << std::setfill('0') << std::hex << (unsigned int)byte + // << std::setfill(' ') << std::resetiosflags(std::ios::hex); } -// -//void gps_l2_m_telemetry_decoder_cc::set_raw_msg_queue(concurrent_queue *raw_msg_queue) -//{ -// sbas_telemetry_data.set_raw_msg_queue(raw_msg_queue); -//} -// -// -//void gps_l2_m_telemetry_decoder_cc::set_iono_queue(concurrent_queue *iono_queue) -//{ -// sbas_telemetry_data.set_iono_queue(iono_queue); -//} -// -// -//void gps_l2_m_telemetry_decoder_cc::set_sat_corr_queue(concurrent_queue *sat_corr_queue) -//{ -// sbas_telemetry_data.set_sat_corr_queue(sat_corr_queue); -//} -// -// -//void gps_l2_m_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue *ephemeris_queue) -//{ -// sbas_telemetry_data.set_ephemeris_queue(ephemeris_queue); -//} +void gps_l2_m_telemetry_decoder_cc::set_iono_queue(concurrent_queue *iono_queue) +{ + d_iono_queue=iono_queue; +} + +void gps_l2_m_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue *ephemeris_queue) +{ + d_ephemeris_queue=ephemeris_queue; +} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.h index d66916fbb..f540b63e1 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2_m_telemetry_decoder_cc.h @@ -43,6 +43,10 @@ #include "gnss_satellite.h" #include "viterbi_decoder.h" #include "gps_cnav_navigation_message.h" +#include "gps_cnav_ephemeris.h" +#include "gps_cnav_iono.h" +#include "concurrent_queue.h" +#include "GPS_L2C.h" class gps_l2_m_telemetry_decoder_cc; @@ -63,11 +67,9 @@ public: void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN void set_channel(int channel); //!< Set receiver's channel - // queues to communicate broadcasted SBAS data to other blocks of GNSS-SDR - //void set_raw_msg_queue(concurrent_queue *raw_msg_queue); //!< Set raw msg queue - //void set_iono_queue(concurrent_queue *iono_queue); //!< Set iono queue - //void set_sat_corr_queue(concurrent_queue *sat_corr_queue); //!< Set sat correction queue - //void set_ephemeris_queue(concurrent_queue *ephemeris_queue); //!< Set SBAS ephemeis queue + // queues to communicate broadcasted CNAV data to other blocks of GNSS-SDR + void set_iono_queue(concurrent_queue *iono_queue); //!< Set iono queue + void set_ephemeris_queue(concurrent_queue *ephemeris_queue); //!< Set ephemeris queue void set_decimation(int decimation); /*! * \brief This is where all signal processing takes place @@ -91,10 +93,8 @@ private: void viterbi_decoder(double *page_part_symbols, int *page_part_bits); void align_samples(); - static const int d_samples_per_symbol = 1; - static const int d_symbols_per_bit = 2; - static const int d_block_size_in_bits = 300; - + concurrent_queue *d_iono_queue; + concurrent_queue *d_ephemeris_queue; long d_fs_in; bool d_dump; @@ -104,6 +104,10 @@ private: std::string d_dump_filename; std::ofstream d_dump_file; + double d_TOW_at_current_symbol; + double d_TOW_at_Preamble; + bool d_flag_valid_word; + bool d_flag_invert_input_symbols; bool d_flag_invert_buffer_symbols; int d_decimation_output_factor; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc index b0ae84044..abd8bd256 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc @@ -366,6 +366,7 @@ int gps_l2_m_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int //std::cout<<" samples_offset="<(d_acc_carrier_phase_rad); current_synchro_data.Carrier_Doppler_hz = static_cast(d_carrier_doppler_hz); current_synchro_data.CN0_dB_hz = static_cast(d_CN0_SNV_dB_Hz); - current_synchro_data.Flag_valid_pseudorange = false; + current_synchro_data.Flag_valid_tracking = true; *out[0] = current_synchro_data; // ########## DEBUG OUTPUT diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 197357b4d..1fbc3afea 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -92,6 +92,7 @@ #include "gps_l1_ca_observables.h" #include "galileo_e1_observables.h" #include "hybrid_observables.h" +#include "mixed_observables.h" #include "gps_l1_ca_pvt.h" #include "galileo_e1_pvt.h" #include "hybrid_pvt.h" @@ -1362,6 +1363,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams, queue)); block = std::move(block_); } + else if (implementation.compare("Mixed_Observables") == 0) + { + std::unique_ptr block_(new MixedObservables(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } // PVT ------------------------------------------------------------------------- else if (implementation.compare("GPS_L1_CA_PVT") == 0) { diff --git a/src/core/system_parameters/GPS_L2C.h b/src/core/system_parameters/GPS_L2C.h index f0bea0300..5e8041efe 100644 --- a/src/core/system_parameters/GPS_L2C.h +++ b/src/core/system_parameters/GPS_L2C.h @@ -97,6 +97,9 @@ const int32_t GPS_L2C_M_INIT_REG[115] = #define GPS_CNAV_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1} const int GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits] +const int GPS_L2_SYMBOLS_PER_BIT = 2; +const int GPS_L2_SAMPLES_PER_SYMBOL = 1; +const int GPS_L2_CNAV_DATA_PAGE_DURATION_S=12; const int GPS_L2_CNAV_DATA_PAGE_BITS_EXTENDED_BYTES = 304; //!< GPS L2 CNAV page length, including preamble and CRC [bits] // common to all messages diff --git a/src/core/system_parameters/gps_cnav_ephemeris.cc b/src/core/system_parameters/gps_cnav_ephemeris.cc index de1fe4ff4..54520a6ab 100644 --- a/src/core/system_parameters/gps_cnav_ephemeris.cc +++ b/src/core/system_parameters/gps_cnav_ephemeris.cc @@ -36,6 +36,9 @@ Gps_CNAV_Ephemeris::Gps_CNAV_Ephemeris() { i_satellite_PRN = 0; + d_Toe1=-1; + d_Toe2=-1; + d_TOW = 0; d_Crs = 0; d_M_0 = 0; diff --git a/src/core/system_parameters/gps_cnav_navigation_message.cc b/src/core/system_parameters/gps_cnav_navigation_message.cc index 3c7e93e28..121e8a8ed 100644 --- a/src/core/system_parameters/gps_cnav_navigation_message.cc +++ b/src/core/system_parameters/gps_cnav_navigation_message.cc @@ -38,7 +38,9 @@ void Gps_CNAV_Navigation_Message::reset() { - b_valid_ephemeris_set_flag = false; + b_flag_ephemeris_1=false; + b_flag_ephemeris_2=false; + b_flag_iono_valid=false; // satellite positions d_satpos_X = 0; @@ -63,7 +65,7 @@ Gps_CNAV_Navigation_Message::Gps_CNAV_Navigation_Message() { satelliteBlock[prn_] = gnss_satellite_.what_block("GPS", prn_); } - flag_iono_valid = false; + b_flag_iono_valid = false; } void Gps_CNAV_Navigation_Message::print_gps_word_bytes(unsigned int GPS_word) @@ -198,17 +200,23 @@ void Gps_CNAV_Navigation_Message::decode_page(std::vector data) int PRN; int page_type; - double TOW; + bool alert_flag; // common to all messages PRN = static_cast(read_navigation_unsigned(data_bits, CNAV_PRN)); - TOW = static_cast(read_navigation_unsigned(data_bits, CNAV_TOW)); - TOW=TOW*CNAV_TOW_LSB; + ephemeris_record.i_satellite_PRN=PRN; + + d_TOW = static_cast(read_navigation_unsigned(data_bits, CNAV_TOW)); + d_TOW=d_TOW*CNAV_TOW_LSB; + ephemeris_record.d_TOW=d_TOW; + alert_flag= static_cast(read_navigation_bool(data_bits, CNAV_ALERT_FLAG)); + ephemeris_record.b_alert_flag=alert_flag; + page_type = static_cast(read_navigation_unsigned(data_bits, CNAV_MSG_TYPE)); - std::cout<<"PRN= "< satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus @@ -97,7 +99,10 @@ public: * \brief Obtain a GPS SV Ephemeris class filled with current SV data */ Gps_CNAV_Ephemeris get_ephemeris(); - + /*! + * \brief Check if we have a new iono record stored in the galileo navigation class + */ + bool have_new_iono(); /*! * \brief Obtain a GPS ionospheric correction parameters class filled with current SV data */ @@ -108,10 +113,10 @@ public: */ Gps_CNAV_Utc_Model get_utc_model(); - - bool satellite_validation(); - - bool have_new_ephemeris(); //Check if we have a new ephemeris stored in the galileo navigation class + /*! + * \brief Check if we have a new ephemeris stored in the galileo navigation class + */ + bool have_new_ephemeris(); /*! * Default constructor diff --git a/src/main/main.cc b/src/main/main.cc index 2a9ddc381..4659034fb 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -53,8 +53,10 @@ #include "concurrent_queue.h" #include "concurrent_map.h" #include "gps_ephemeris.h" +#include "gps_cnav_ephemeris.h" #include "gps_almanac.h" #include "gps_iono.h" +#include "gps_cnav_iono.h" #include "gps_utc_model.h" #include "galileo_ephemeris.h" #include "galileo_almanac.h" @@ -80,7 +82,7 @@ DECLARE_string(log_dir); * to the Observables modules */ -// For GPS NAVIGATION +// For GPS NAVIGATION (L1) concurrent_queue global_gps_ephemeris_queue; concurrent_queue global_gps_iono_queue; concurrent_queue global_gps_utc_model_queue; @@ -97,6 +99,12 @@ concurrent_map global_gps_acq_assist_map; concurrent_map global_gps_ref_time_map; concurrent_map global_gps_ref_location_map; +// For GPS NAVIGATION (L2) +concurrent_queue global_gps_cnav_ephemeris_queue; +concurrent_map global_gps_cnav_ephemeris_map; +concurrent_queue global_gps_cnav_iono_queue; +concurrent_map global_gps_cnav_iono_map; + // For GALILEO NAVIGATION concurrent_queue global_galileo_ephemeris_queue; concurrent_queue global_galileo_iono_queue; diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index 521fde278..714955a6d 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -45,8 +45,10 @@ #include "gps_navigation_message.h" #include "gps_ephemeris.h" +#include "gps_cnav_ephemeris.h" #include "gps_almanac.h" #include "gps_iono.h" +#include "gps_cnav_iono.h" #include "gps_utc_model.h" #include "galileo_ephemeris.h" @@ -110,7 +112,7 @@ DECLARE_string(log_dir); #include "gnss_block/gps_l2_m_dll_pll_tracking_test.cc" - +// For GPS NAVIGATION (L1) concurrent_queue global_gps_ephemeris_queue; concurrent_queue global_gps_iono_queue; concurrent_queue global_gps_utc_model_queue; @@ -127,6 +129,12 @@ concurrent_map global_gps_acq_assist_map; concurrent_map global_gps_ref_location_map; concurrent_map global_gps_ref_time_map; +// For GPS NAVIGATION (L2) +concurrent_queue global_gps_cnav_ephemeris_queue; +concurrent_map global_gps_cnav_ephemeris_map; +concurrent_queue global_gps_cnav_iono_queue; +concurrent_map global_gps_cnav_iono_map; + // For GALILEO NAVIGATION concurrent_queue global_galileo_ephemeris_queue; concurrent_queue global_galileo_iono_queue; diff --git a/src/utils/front-end-cal/front_end_cal.cc b/src/utils/front-end-cal/front_end_cal.cc index db12a9586..a3d0cf04d 100644 --- a/src/utils/front-end-cal/front_end_cal.cc +++ b/src/utils/front-end-cal/front_end_cal.cc @@ -42,8 +42,10 @@ #include #include "gps_navigation_message.h" #include "gps_ephemeris.h" +#include "gps_cnav_ephemeris.h" #include "gps_almanac.h" #include "gps_iono.h" +#include "gps_cnav_iono.h" #include "gps_utc_model.h" #include "gnss_sdr_supl_client.h" diff --git a/src/utils/front-end-cal/main.cc b/src/utils/front-end-cal/main.cc index 53ab60c82..8d9ac3922 100644 --- a/src/utils/front-end-cal/main.cc +++ b/src/utils/front-end-cal/main.cc @@ -58,8 +58,10 @@ #include "gnss_block_factory.h" #include "gps_navigation_message.h" #include "gps_ephemeris.h" +#include "gps_cnav_ephemeris.h" #include "gps_almanac.h" #include "gps_iono.h" +#include "gps_cnav_iono.h" #include "gps_utc_model.h" #include "galileo_ephemeris.h" #include "galileo_almanac.h" @@ -98,6 +100,12 @@ concurrent_map global_gps_utc_model_map; concurrent_map global_gps_almanac_map; concurrent_map global_gps_acq_assist_map; +// For GPS NAVIGATION (L2) +concurrent_queue global_gps_cnav_ephemeris_queue; +concurrent_map global_gps_cnav_ephemeris_map; +concurrent_queue global_gps_cnav_iono_queue; +concurrent_map global_gps_cnav_iono_map; + // For GALILEO NAVIGATION concurrent_queue global_galileo_ephemeris_queue; concurrent_queue global_galileo_iono_queue;