[hamradio-commits] [gnss-sdr] 74/236: Experimental extended correlation for GPS L1 CA C_Aid tracking

Carles Fernandez carles_fernandez-guest at moszumanska.debian.org
Tue Apr 26 16:02:33 UTC 2016


This is an automated email from the git hooks/post-receive script.

carles_fernandez-guest pushed a commit to branch next
in repository gnss-sdr.

commit d664dc63b3f4332d6ef342fb7d65d8c8188834b4
Author: Javier Arribas <javiarribas at gmail.com>
Date:   Tue Mar 8 18:30:56 2016 +0100

    Experimental extended correlation for GPS L1 CA C_Aid tracking
---
 conf/gnss-sdr_Hybrid_nsr.conf                      |  19 +-
 src/algorithms/channel/adapters/channel.cc         |   4 +
 .../gps_l1_ca_telemetry_decoder_cc.cc              |  74 ++++-
 .../gps_l1_ca_dll_pll_c_aid_tracking_cc.cc         | 341 ++++++++++++++-------
 .../gps_l1_ca_dll_pll_c_aid_tracking_cc.h          |  16 +
 src/core/receiver/gnss_flowgraph.cc                |  12 +-
 src/core/system_parameters/GPS_L1_CA.h             |   1 +
 src/core/system_parameters/gnss_synchro.h          |   2 +
 8 files changed, 327 insertions(+), 142 deletions(-)

diff --git a/conf/gnss-sdr_Hybrid_nsr.conf b/conf/gnss-sdr_Hybrid_nsr.conf
index f58d543..1609800 100644
--- a/conf/gnss-sdr_Hybrid_nsr.conf
+++ b/conf/gnss-sdr_Hybrid_nsr.conf
@@ -19,7 +19,7 @@ ControlThread.wait_for_flowgraph=false
 SignalSource.implementation=Nsr_File_Signal_Source
 
 ;#filename: path to file with the captured GNSS signal samples to be processed
-SignalSource.filename=/datalogger/signals/ifen/E1L1_FE0_Band0.stream
+SignalSource.filename=/media/javier/SISTEMA/signals/ifen/E1L1_FE0_Band0.stream
 
 ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
 SignalSource.item_type=byte
@@ -150,7 +150,7 @@ Resampler.implementation=Pass_Through
 ;#count: Number of available GPS satellite channels.
 Channels_1C.count=8
 ;#count: Number of available Galileo satellite channels.
-Channels_1B.count=8
+Channels_1B.count=0
 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
 Channels.in_acquisition=1
 
@@ -193,14 +193,15 @@ Acquisition_1C.if=0
 Acquisition_1C.sampled_ms=1
 ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
 Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
+Acquisition_1C.use_CFAR_algorithm=false;
 ;#threshold: Acquisition threshold
-Acquisition_1C.threshold=0.0075
+Acquisition_1C.threshold=40
 ;#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_1C.pfa=0.01
 ;#doppler_max: Maximum expected Doppler shift [Hz]
 Acquisition_1C.doppler_max=10000
 ;#doppler_max: Doppler step in the grid search [Hz]
-Acquisition_1C.doppler_step=500
+Acquisition_1C.doppler_step=250
 
 
 ;######### GALILEO ACQUISITION CONFIG ############
@@ -229,7 +230,7 @@ Acquisition_1B.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_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
+Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking
 ;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
 Tracking_1C.item_type=gr_complex
 
@@ -237,19 +238,19 @@ Tracking_1C.item_type=gr_complex
 Tracking_1C.if=0
 
 ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
-Tracking_1C.dump=false
+Tracking_1C.dump=true
 
 ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
 Tracking_1C.dump_filename=../data/epl_tracking_ch_
 
 ;#pll_bw_hz: PLL loop filter bandwidth [Hz]
-Tracking_1C.pll_bw_hz=45.0;
+Tracking_1C.pll_bw_hz=40;
 
 ;#dll_bw_hz: DLL loop filter bandwidth [Hz]
-Tracking_1C.dll_bw_hz=2.0;
+Tracking_1C.dll_bw_hz=2.5;
 
 ;#fll_bw_hz: FLL loop filter bandwidth [Hz]
-Tracking_1C.fll_bw_hz=10.0;
+Tracking_1C.fll_bw_hz=2.0;
 
 ;#order: PLL/DLL loop filter order [2] or [3]
 Tracking_1C.order=3;
diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc
index 6269bc8..30d8515 100644
--- a/src/algorithms/channel/adapters/channel.cc
+++ b/src/algorithms/channel/adapters/channel.cc
@@ -125,6 +125,10 @@ void Channel::connect(gr::top_block_sptr top_block)
     DLOG(INFO) << "pass_through_ -> tracking";
     top_block->connect(trk_->get_right_block(), 0, nav_->get_left_block(), 0);
     DLOG(INFO) << "tracking -> telemetry_decoder";
+
+    top_block->msg_connect(nav_->get_left_block(),pmt::mp("preamble_index"),trk_->get_right_block(),pmt::mp("preamble_index"));
+    DLOG(INFO) << "MSG FEEDBACK CHANNEL telemetry_decoder -> tracking";
+
     connected_ = true;
 }
 
diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc
index 5e4a6d5..e99b489 100644
--- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc
+++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc
@@ -38,6 +38,7 @@
 #include <iostream>
 #include <boost/lexical_cast.hpp>
 #include <gnuradio/io_signature.h>
+#include <pmt/pmt.h>
 #include <glog/logging.h>
 #include "control_message_factory.h"
 #include "gnss_synchro.h"
@@ -78,6 +79,9 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
         gr::block("gps_navigation_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
         gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
 {
+	// create asynchronous message ports
+	this->message_port_register_out(pmt::mp("preamble_index"));
+
     // initialize internal vars
     d_queue = queue;
     d_dump = dump;
@@ -178,6 +182,8 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
     const Gnss_Synchro **in = (const Gnss_Synchro **)  &input_items[0]; //Get the input samples pointer
 
     // TODO Optimize me!
+    if (in[0][d_samples_per_bit*8 - 1].symbol_integration_enabled==false)
+    {
     //******* preamble correlation ********
     for (unsigned int i = 0; i < d_samples_per_bit*8; i++)
         {
@@ -190,20 +196,37 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
                     corr_value += d_preambles_symbols[i];
                 }
         }
+    }else{
+        //******* preamble correlation ********
+        for (unsigned int i = 0; i < d_samples_per_bit*8; i++)
+            {
+        		if (in[0][i].Flag_valid_symbol_output==true)
+        		{
+					if (in[0][i].Prompt_I < 0)	// symbols clipping
+						{
+							corr_value -= d_preambles_symbols[i]*d_samples_per_bit;
+						}
+					else
+						{
+							corr_value += d_preambles_symbols[i]*d_samples_per_bit;
+						}
+        		}
+            }
+    }
     d_flag_preamble = false;
 
     //******* frame sync ******************
-    if (abs(corr_value) >= 160)
+    if (abs(corr_value) == 160)
         {
             //TODO: Rewrite with state machine
             if (d_stat == 0)
                 {
                     d_GPS_FSM.Event_gps_word_preamble();
                     d_preamble_index = d_sample_counter;//record the preamble sample stamp
-                    LOG(INFO) << "Preamble detection for SAT " << this->d_satellite;
+                    DLOG(INFO)  << "Preamble detection for SAT " << this->d_satellite;
                     d_symbol_accumulator = 0; //sync the symbol to bits integrator
                     d_symbol_accumulator_counter = 0;
-                    d_frame_bit_index = 8;
+                    d_frame_bit_index = 7;
                     d_stat = 1; // enter into frame pre-detection status
                 }
             else if (d_stat == 1) //check 6 seconds of preamble separation
@@ -215,20 +238,24 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
                             d_flag_preamble = true;
                             d_preamble_index = d_sample_counter;  //record the preamble sample stamp (t_P)
                             d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs;// - d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
-
+                            d_frame_bit_index = 7;
                             if (!d_flag_frame_sync)
                                 {
+                            	//send asynchronous message to tracking to inform of frame sync and extend correlation time
+                                pmt::pmt_t value = pmt::from_long(d_preamble_index-1);
+                                this->message_port_pub(pmt::mp("preamble_index"),value);
+
                                     d_flag_frame_sync = true;
                                     if (corr_value < 0)
                                         {
                                             flag_PLL_180_deg_phase_locked = true; //PLL is locked to opposite phase!
-                                            LOG(INFO) << " PLL in opposite phase for Sat "<< this->d_satellite.get_PRN();
+                                            DLOG(INFO)  << " PLL in opposite phase for Sat "<< this->d_satellite.get_PRN();
                                         }
                                     else
                                         {
                                             flag_PLL_180_deg_phase_locked = false;
                                         }
-                                    LOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]";
+                                    DLOG(INFO)  << " Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]";
                                 }
                         }
                 }
@@ -240,7 +267,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
                     preamble_diff = d_sample_counter - d_preamble_index;
                     if (preamble_diff > 6001)
                         {
-                            LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff;
+                            DLOG(INFO)  << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff;
                             d_stat = 0; //lost of frame sync
                             d_flag_frame_sync = false;
                             flag_TOW_set = false;
@@ -249,16 +276,29 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
         }
 
     //******* SYMBOL TO BIT *******
-    d_symbol_accumulator += in[0][d_samples_per_bit*8 - 1].Prompt_I; // accumulate the input value in d_symbol_accumulator
-    d_symbol_accumulator_counter++;
-    if (d_symbol_accumulator_counter == 20)
+    if (in[0][d_samples_per_bit*8 - 1].Flag_valid_symbol_output==true)
+    {
+	    if (in[0][d_samples_per_bit*8 - 1].symbol_integration_enabled==true)
+	    {
+	    	// extended correlation to bit period is enabled in tracking!
+	    	// 1 symbol = 1 bit
+		    d_symbol_accumulator = in[0][d_samples_per_bit*8 - 1].Prompt_I; // accumulate the input value in d_symbol_accumulator
+	    	d_symbol_accumulator_counter=20;
+	    }else{
+	    	// 20 symbols = 1 bit: do symbols integration in telemetry decoder
+		    d_symbol_accumulator += in[0][d_samples_per_bit*8 - 1].Prompt_I; // accumulate the input value in d_symbol_accumulator
+	    	d_symbol_accumulator_counter++;
+	    }
+    }
+
+    if (d_symbol_accumulator_counter == 20 )
         {
-            if (d_symbol_accumulator > 0)
-                { //symbol to bit
-                    d_GPS_frame_4bytes += 1; //insert the telemetry bit in LSB
-                }
-            d_symbol_accumulator = 0;
-            d_symbol_accumulator_counter = 0;
+			if (d_symbol_accumulator > 0)
+				{ //symbol to bit
+					d_GPS_frame_4bytes += 1; //insert the telemetry bit in LSB
+				}
+			d_symbol_accumulator = 0;
+			d_symbol_accumulator_counter = 0;
             //******* bits to words ******
             d_frame_bit_index++;
             if (d_frame_bit_index == 30)
@@ -302,6 +342,8 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
                 {
                     d_GPS_frame_4bytes <<= 1; //shift 1 bit left the telemetry word
                 }
+
+
         }
     // output the frame
     consume_each(1); //one by one
diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc
index ecc4e89..b730451 100644
--- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc
+++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc
@@ -34,7 +34,9 @@
 #include <memory>
 #include <sstream>
 #include <boost/lexical_cast.hpp>
+#include <boost/bind.hpp>
 #include <gnuradio/io_signature.h>
+#include <pmt/pmt.h>
 #include <volk/volk.h>
 #include <glog/logging.h>
 #include "gps_sdr_signal_processing.h"
@@ -82,6 +84,17 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::forecast (int noutput_items,
         }
 }
 
+void gps_l1_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index(pmt::pmt_t msg)
+{
+  //pmt::print(msg);
+  DLOG(INFO) << "Extended correlation for Tracking CH " << d_channel <<  ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN)<< std::endl;
+  if (d_enable_20ms_integration==false) //avoid re-setting preamble indicator
+  {
+	  d_preamble_index=pmt::to_long(msg);
+	  d_enable_20ms_integration=true;
+	  d_preamble_synchronized=false;
+  }
+}
 
 
 gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc(
@@ -97,6 +110,13 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc(
         gr::block("gps_l1_ca_dll_pll_c_aid_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)),
                 gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
 {
+	// create asynchronous message ports
+	this->message_port_register_in(pmt::mp("preamble_index"));
+
+	this->set_msg_handler(pmt::mp("preamble_index"),
+			boost::bind(&gps_l1_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index, this, _1));
+
+
     // initialize internal vars
     d_queue = queue;
     d_dump = dump;
@@ -107,8 +127,10 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc(
     d_correlation_length_samples = static_cast<int>(d_vector_length);
 
     // Initialize tracking  ==========================================
-    d_code_loop_filter.set_DLL_BW(dll_bw_hz);
-    d_carrier_loop_filter.set_params(10.0, pll_bw_hz,2);
+    d_pll_bw_hz=pll_bw_hz;
+    d_dll_bw_hz=dll_bw_hz;
+    d_code_loop_filter.set_DLL_BW(d_dll_bw_hz);
+    d_carrier_loop_filter.set_params(10.0, d_pll_bw_hz,2);
 
     //--- DLL variables --------------------------------------------------------
     d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips)
@@ -141,7 +163,9 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc(
     d_rem_carrier_phase_rad = 0.0;
 
     // sample synchronization
-    d_sample_counter = 0;
+    d_sample_counter = 0; //(from trk to tlm)
+    // symbol synchronization (from tlm to trk)
+    d_symbol_counter =0;
     //d_sample_counter_seconds = 0;
     d_acq_sample_stamp = 0;
 
@@ -175,6 +199,8 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc(
     d_rem_code_phase_chips = 0.0;
     d_code_phase_step_chips = 0.0;
     d_carrier_phase_step_rad = 0.0;
+    d_enable_20ms_integration=false;
+    d_preamble_synchronized=false;
     //set_min_output_buffer((long int)300);
 }
 
@@ -258,7 +284,8 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking()
     // enable tracking
     d_pull_in = true;
     d_enable_tracking = true;
-
+    d_enable_20ms_integration=false;
+    d_preamble_synchronized=false;
     LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
             << " Code Phase correction [samples]=" << delay_correction_samples
             << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples;
@@ -315,6 +342,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec
                     current_synchro_data = *d_acquisition_gnss_synchro;
                     *out[0] = current_synchro_data;
                     consume_each(samples_offset); //shift input to perform alignment with local replica
+                    d_symbol_counter++;
                     return 1;
                 }
 
@@ -326,115 +354,203 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec
             multicorrelator_cpu.set_input_output_vectors(d_correlator_outs,in);
             multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad, d_carrier_phase_step_rad, d_rem_code_phase_chips, d_code_phase_step_chips, d_correlation_length_samples);
 
-            // UPDATE INTEGRATION TIME
-            CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in);
-
-            // ################## PLL ##########################################################
-            // Update PLL discriminator [rads/Ti -> Secs/Ti]
-            carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GPS_TWO_PI; //prompt output
-            // Carrier discriminator filter
-            // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
-            //d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_phase_error_filt_secs_ti/INTEGRATION_TIME;
-            // Input [s/Ti] -> output [Hz]
-            d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, carr_phase_error_secs_Ti, CURRENT_INTEGRATION_TIME_S);
-            // PLL to DLL assistance [Secs/Ti]
-            d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / GPS_L1_FREQ_HZ;
-            // code Doppler frequency update
-            d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ);
-
-            // ################## DLL ##########################################################
-            // DLL discriminator
-            code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); //[chips/Ti] //early and late
-            // Code discriminator filter
-            code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips_Ti); //input [chips/Ti] -> output [chips/second]
-            code_error_filt_secs_Ti = code_error_filt_chips*CURRENT_INTEGRATION_TIME_S/d_code_freq_chips; // [s/Ti]
-            // DLL code error estimation [s/Ti]
-            // TODO: PLL carrier aid to DLL is disabled. Re-enable it and measure performance
-            dll_code_error_secs_Ti = - code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti;
-
-            // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
-            // keep alignment parameters for the next input buffer
-            double T_chip_seconds;
-            double T_prn_seconds;
-            double T_prn_samples;
-            double K_blk_samples;
-            // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
-            T_chip_seconds = 1 / d_code_freq_chips;
-            T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
-            T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
-            K_blk_samples = T_prn_samples + d_rem_code_phase_samples - dll_code_error_secs_Ti * static_cast<double>(d_fs_in);
-
-            d_correlation_length_samples = round(K_blk_samples); //round to a discrete samples
-            old_d_rem_code_phase_samples=d_rem_code_phase_samples;
-            d_rem_code_phase_samples = K_blk_samples - static_cast<double>(d_correlation_length_samples); //rounding error < 1 sample
-
-            // UPDATE REMNANT CARRIER PHASE
-            CORRECTED_INTEGRATION_TIME_S=(static_cast<double>(d_correlation_length_samples)/static_cast<double>(d_fs_in));
-            //remnant carrier phase [rad]
-            d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GPS_TWO_PI);
-            // UPDATE CARRIER PHASE ACCUULATOR
-            //carrier phase accumulator prior to update the PLL estimators (accumulated carrier in this loop depends on the old estimations!)
-            d_acc_carrier_phase_cycles -= d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S;
-
-            //################### PLL COMMANDS #################################################
-            //carrier phase step (NCO phase increment per sample) [rads/sample]
-            d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
-
-            //################### DLL COMMANDS #################################################
-            //code phase step (Code resampler phase increment per sample) [chips/sample]
-            d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in);
-            //remnant code phase [chips]
-            d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
-
-            // ####### CN0 ESTIMATION AND LOCK DETECTORS #######################################
-            if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
-                {
-                    // fill buffer with prompt correlator output values
-                    d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt
-                    d_cn0_estimation_counter++;
-                }
-            else
-                {
-                    d_cn0_estimation_counter = 0;
-                    // Code lock indicator
-                    d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GPS_L1_CA_CODE_LENGTH_CHIPS);
-                    // Carrier lock indicator
-                    d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
-                    // Loss of lock detection
-                    if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0)
-                        {
-                            d_carrier_lock_fail_counter++;
-                        }
-                    else
-                        {
-                            if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--;
-                        }
-                    if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER)
-                        {
-                            std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
-                            LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
-                            std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
-                            if (d_queue != gr::msg_queue::sptr())
-                                {
-                                    d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
-                                }
-                            d_carrier_lock_fail_counter = 0;
-                            d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
-                        }
-                }
+            // ####### 20ms coherent intergration extension (experimental)
+            // keep the last 40 symbols (2 bits to detect transitions)
+            d_E_history.push_back(d_correlator_outs[0]); // save early output
+            d_P_history.push_back(d_correlator_outs[1]); // save prompt output
+            d_L_history.push_back(d_correlator_outs[2]); // save late output
 
-            // ########### Output the tracking data to navigation and PVT ##########
-            current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs[1]).real());
-            current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs[1]).imag());
-            // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!)
-            current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + old_d_rem_code_phase_samples) / static_cast<double>(d_fs_in);
-            // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0
-            current_synchro_data.Code_phase_secs = 0;
-            current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles;
-            current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
-            current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
-            current_synchro_data.Flag_valid_pseudorange = false;
-            *out[0] = current_synchro_data;
+            if (d_P_history.size()>GPS_CA_TELEMETRY_SYMBOLS_PER_BIT)
+            {
+            	d_E_history.pop_front();
+            	d_P_history.pop_front();
+            	d_L_history.pop_front();
+            }
+
+            bool enable_dll_pll;
+			if (d_enable_20ms_integration==true)
+			{
+				long int symbol_diff=d_symbol_counter-d_preamble_index;
+				if (symbol_diff % GPS_CA_TELEMETRY_SYMBOLS_PER_BIT == 0)
+				{
+					// compute coherent integration and enable tracking loop
+		            // perform coherent integration using correlator output history
+					//gr_complex d_correlator_outs_2[3];
+					//std::cout<<"##### RESET COHERENT INTEGRATION ####"<<std::endl;
+                    d_correlator_outs[0]=gr_complex(0.0,0.0);
+				    d_correlator_outs[1]=gr_complex(0.0,0.0);
+					d_correlator_outs[2]=gr_complex(0.0,0.0);
+		            for (int n=0;n<GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;n++)
+		            {
+		            	d_correlator_outs[0]+=d_E_history.at(n);
+		            	d_correlator_outs[1]+=d_P_history.at(n);
+		            	d_correlator_outs[2]+=d_L_history.at(n);
+		            }
+
+		            if (d_preamble_synchronized==false)
+		            {
+		            		d_preamble_synchronized=true;
+		            }
+					current_synchro_data.symbol_integration_enabled=true;
+					// UPDATE INTEGRATION TIME
+	            	CURRENT_INTEGRATION_TIME_S = static_cast<double>(GPS_CA_TELEMETRY_SYMBOLS_PER_BIT)*GPS_L1_CA_CODE_PERIOD;
+				    d_code_loop_filter.set_DLL_BW(d_dll_bw_hz);
+				    d_carrier_loop_filter.set_params(10.0, d_pll_bw_hz/5,2);
+					enable_dll_pll=true;
+
+				}else{
+					current_synchro_data.symbol_integration_enabled=false;
+					if(d_preamble_synchronized==true)
+					{
+						// continue extended coherent correlation
+						d_correlation_length_samples=d_correlation_length_samples-d_rem_code_phase_integer_samples;
+						d_rem_code_phase_integer_samples=0;
+						d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + d_carrier_phase_step_rad * d_correlation_length_samples, GPS_TWO_PI);
+						d_rem_code_phase_chips = fmod(d_rem_code_phase_chips + d_code_phase_step_chips*d_correlation_length_samples,GPS_L1_CA_CODE_LENGTH_CHIPS);
+						// disable tracking loop and inform telemetry decoder
+						enable_dll_pll=false;
+					}else{
+						//  perform basic (1ms) correlation
+			            // UPDATE INTEGRATION TIME
+			            CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in);
+			            enable_dll_pll=true;
+					}
+				}
+			}else{
+				current_synchro_data.symbol_integration_enabled=false;
+	            // UPDATE INTEGRATION TIME
+	            CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in);
+	            enable_dll_pll=true;
+			}
+
+            // ###### end 20ms correlation extension
+
+			if (enable_dll_pll==true)
+			{
+				// ################## PLL ##########################################################
+				// Update PLL discriminator [rads/Ti -> Secs/Ti]
+				carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GPS_TWO_PI; //prompt output
+				// Carrier discriminator filter
+				// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
+				//d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_phase_error_filt_secs_ti/INTEGRATION_TIME;
+				// Input [s/Ti] -> output [Hz]
+				d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, carr_phase_error_secs_Ti, CURRENT_INTEGRATION_TIME_S);
+				// PLL to DLL assistance [Secs/Ti]
+				d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / GPS_L1_FREQ_HZ;
+				// code Doppler frequency update
+				d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ);
+
+				// ################## DLL ##########################################################
+				// DLL discriminator
+				code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); //[chips/Ti] //early and late
+				// Code discriminator filter
+				code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips_Ti); //input [chips/Ti] -> output [chips/second]
+				code_error_filt_secs_Ti = code_error_filt_chips*CURRENT_INTEGRATION_TIME_S/d_code_freq_chips; // [s/Ti]
+				// DLL code error estimation [s/Ti]
+				dll_code_error_secs_Ti = - code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti;
+
+				// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
+
+				// keep alignment parameters for the next input buffer
+				double T_chip_seconds;
+				double T_prn_seconds;
+				double T_prn_samples;
+				double K_prn_samples;
+				// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
+				T_chip_seconds = 1 / d_code_freq_chips;
+				T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
+				T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
+				K_prn_samples = round(T_prn_samples);
+				double K_T_prn_error_samples=K_prn_samples-T_prn_samples;
+
+				old_d_rem_code_phase_samples=d_rem_code_phase_samples;
+				d_rem_code_phase_samples= d_rem_code_phase_samples - K_T_prn_error_samples -dll_code_error_secs_Ti * static_cast<double>(d_fs_in);
+				d_rem_code_phase_integer_samples=round(d_rem_code_phase_samples);
+				d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; //round to a discrete samples
+				d_rem_code_phase_samples=d_rem_code_phase_samples-d_rem_code_phase_integer_samples;
+
+				// UPDATE REMNANT CARRIER PHASE
+				CORRECTED_INTEGRATION_TIME_S=(static_cast<double>(d_correlation_length_samples)/static_cast<double>(d_fs_in));
+				//remnant carrier phase [rad]
+				d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GPS_TWO_PI);
+				// UPDATE CARRIER PHASE ACCUULATOR
+				//carrier phase accumulator prior to update the PLL estimators (accumulated carrier in this loop depends on the old estimations!)
+				d_acc_carrier_phase_cycles -= d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S;
+
+				//################### PLL COMMANDS #################################################
+				//carrier phase step (NCO phase increment per sample) [rads/sample]
+				d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
+
+				//################### DLL COMMANDS #################################################
+				//code phase step (Code resampler phase increment per sample) [chips/sample]
+				d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in);
+				//remnant code phase [chips]
+				d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
+
+				// ####### CN0 ESTIMATION AND LOCK DETECTORS #######################################
+				if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
+					{
+						// fill buffer with prompt correlator output values
+						d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt
+						d_cn0_estimation_counter++;
+					}
+				else
+					{
+						d_cn0_estimation_counter = 0;
+						// Code lock indicator
+						d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GPS_L1_CA_CODE_LENGTH_CHIPS);
+						// Carrier lock indicator
+						d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
+						// Loss of lock detection
+						if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0)
+							{
+								d_carrier_lock_fail_counter++;
+							}
+						else
+							{
+								if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--;
+							}
+						if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER)
+							{
+								std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
+								LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
+								std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
+								if (d_queue != gr::msg_queue::sptr())
+									{
+										d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
+									}
+								d_carrier_lock_fail_counter = 0;
+								d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
+							}
+					}
+	            // ########### Output the tracking data to navigation and PVT ##########
+	            current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs[1]).real());
+	            current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs[1]).imag());
+	            // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!)
+	            current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + old_d_rem_code_phase_samples) / static_cast<double>(d_fs_in);
+	            // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0
+	            current_synchro_data.Code_phase_secs = 0;
+	            current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles;
+	            current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
+	            current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
+	            current_synchro_data.Flag_valid_pseudorange = false;
+	            current_synchro_data.Flag_valid_symbol_output = true;
+	            *out[0] = current_synchro_data;
+			}else{
+				//todo: fill synchronization data to produce output while coherent integration is running
+	            current_synchro_data.Flag_valid_symbol_output = false;
+	            current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs[1]).real());
+	            current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs[1]).imag());
+	            // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!)
+	            current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + d_rem_code_phase_samples) / static_cast<double>(d_fs_in);
+	            // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0
+	            current_synchro_data.Code_phase_secs = 0;
+	            current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; // todo: project the acc carrier phase
+	            current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;// todo: project the carrier doppler
+	            current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
+	            current_synchro_data.Flag_valid_pseudorange = false;
+	            *out[0] = current_synchro_data;
+			}
 
             // ########## DEBUG OUTPUT
             /*!
@@ -553,6 +669,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec
         {
             LOG(WARNING) << "noutput_items = 0";
         }
+    d_symbol_counter++;
     return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
 }
 
diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h
index 6a212bd..3d4cf32 100644
--- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h
+++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h
@@ -39,9 +39,11 @@
 
 #include <fstream>
 #include <map>
+#include <deque>
 #include <string>
 #include <gnuradio/block.h>
 #include <gnuradio/msg_queue.h>
+#include <pmt/pmt.h>
 #include "concurrent_queue.h"
 #include "gnss_synchro.h"
 #include "tracking_2nd_DLL_filter.h"
@@ -130,6 +132,7 @@ private:
     double d_rem_code_phase_samples;
     double d_rem_code_phase_chips;
     double d_rem_carrier_phase_rad;
+    int d_rem_code_phase_integer_samples;
 
     // PLL and DLL filter library
     Tracking_2nd_DLL_filter d_code_loop_filter;
@@ -140,6 +143,8 @@ private:
     double d_acq_carrier_doppler_hz;
 
     // tracking vars
+    float d_dll_bw_hz;
+    float d_pll_bw_hz;
     double d_code_freq_chips;
     double d_code_phase_step_chips;
     double d_carrier_doppler_hz;
@@ -148,6 +153,17 @@ private:
     double d_code_phase_samples;
     double d_pll_to_dll_assist_secs_Ti;
 
+    // symbol history to detect bit transition
+    std::deque<gr_complex> d_E_history;
+    std::deque<gr_complex> d_P_history;
+    std::deque<gr_complex> d_L_history;
+    long int d_preamble_index;
+    long int d_symbol_counter;
+    bool d_enable_20ms_integration;
+    bool d_preamble_synchronized;
+    int d_correlation_symbol_counter;
+    void msg_handler_preamble_index(pmt::pmt_t msg);
+
     //Integration period in samples
     int d_correlation_length_samples;
 
diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc
index f15398f..5989b34 100644
--- a/src/core/receiver/gnss_flowgraph.cc
+++ b/src/core/receiver/gnss_flowgraph.cc
@@ -390,12 +390,12 @@ void GNSSFlowgraph::wait()
  */
 void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
 {
-    DLOG(INFO) << "received " << what << " from " << who;
+	DLOG(INFO) << "received " << what << " from " << who;
 
     switch (what)
     {
     case 0:
-        LOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str();
+    	DLOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str();
         available_GNSS_signals_.push_back(channels_.at(who)->get_signal());
 
         //TODO: Optimize the channel and signal matching!
@@ -403,9 +403,11 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
             {
                 available_GNSS_signals_.push_back(available_GNSS_signals_.front());
                 available_GNSS_signals_.pop_front();
+                std::cout << "loop"<<std::endl;
             }
         channels_.at(who)->set_signal(available_GNSS_signals_.front());
         available_GNSS_signals_.pop_front();
+
         //todo: This is a provisional bug fix to avoid random channel state machine deadlock caused by an incorrect sequence of events
         //      Correct sequence: start_acquisition() is triggered after the negative acquisition driven by the process_channel_messages() thread inside channel class
         //      Incorrect sequence: due to thread concurrency, some times start_acquisition is triggered BEFORE the last negative_acquisition notification, thus producing a deadlock
@@ -417,7 +419,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
         // TODO: Tracking messages
 
     case 1:
-        LOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite();
+    	DLOG(INFO)  << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite();
         channels_state_[who] = 2;
         acq_channels_count_--;
         if (!available_GNSS_signals_.empty() && acq_channels_count_ < max_acq_channels_)
@@ -445,7 +447,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
         break;
 
     case 2:
-        LOG(INFO) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite();
+    	DLOG(INFO)  << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite();
         if (acq_channels_count_ < max_acq_channels_)
             {
                 channels_state_[who] = 1;
@@ -468,7 +470,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
     default:
         break;
     }
-    DLOG(INFO) << "Number of available signals: " << available_GNSS_signals_.size();
+    DLOG(INFO)  << "Number of available signals: " << available_GNSS_signals_.size();
 }
 
 
diff --git a/src/core/system_parameters/GPS_L1_CA.h b/src/core/system_parameters/GPS_L1_CA.h
index 2c9e041..bbe96db 100644
--- a/src/core/system_parameters/GPS_L1_CA.h
+++ b/src/core/system_parameters/GPS_L1_CA.h
@@ -75,6 +75,7 @@ const int GPS_L1_CA_HISTORY_DEEP = 100;
 #define GPS_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1}
 const int GPS_CA_PREAMBLE_LENGTH_BITS = 8;
 const int GPS_CA_TELEMETRY_RATE_BITS_SECOND = 50;   //!< NAV message bit rate [bits/s]
+const int GPS_CA_TELEMETRY_SYMBOLS_PER_BIT = 20;
 const int GPS_CA_TELEMETRY_RATE_SYMBOLS_SECOND = GPS_CA_TELEMETRY_RATE_BITS_SECOND*20;   //!< NAV message bit rate [symbols/s]
 const int GPS_WORD_LENGTH = 4;                      //!< CRC + GPS WORD (-2 -1 0 ... 29) Bits = 4 bytes
 const int GPS_SUBFRAME_LENGTH = 40;                 //!< GPS_WORD_LENGTH x 10 = 40 bytes
diff --git a/src/core/system_parameters/gnss_synchro.h b/src/core/system_parameters/gnss_synchro.h
index 27c1d6b..d70c21b 100644
--- a/src/core/system_parameters/gnss_synchro.h
+++ b/src/core/system_parameters/gnss_synchro.h
@@ -60,6 +60,8 @@ public:
     double Code_phase_secs;         //!< Set by Tracking processing block
     double Tracking_timestamp_secs; //!< Set by Tracking processing block
     bool Flag_valid_tracking;
+    bool Flag_valid_symbol_output;
+    bool symbol_integration_enabled; //!< Set by Tracking processing block
 
     //Telemetry Decoder
     double Prn_timestamp_ms;             //!< Set by Telemetry Decoder processing block

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/gnss-sdr.git



More information about the pkg-hamradio-commits mailing list