1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-12 19:20:32 +00:00

reverting wrong commit

This commit is contained in:
Carles Fernandez 2016-03-09 15:56:07 +01:00
parent 59011a7772
commit 1e9a9d1a55
10 changed files with 325 additions and 140 deletions

View File

@ -19,7 +19,7 @@ ControlThread.wait_for_flowgraph=false
SignalSource.implementation=Nsr_File_Signal_Source SignalSource.implementation=Nsr_File_Signal_Source
;#filename: path to file with the captured GNSS signal samples to be processed ;#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. ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
SignalSource.item_type=byte SignalSource.item_type=byte
@ -150,7 +150,7 @@ Resampler.implementation=Pass_Through
;#count: Number of available GPS satellite channels. ;#count: Number of available GPS satellite channels.
Channels_1C.count=8 Channels_1C.count=8
;#count: Number of available Galileo satellite channels. ;#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 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
Channels.in_acquisition=1 Channels.in_acquisition=1
@ -193,14 +193,15 @@ Acquisition_1C.if=0
Acquisition_1C.sampled_ms=1 Acquisition_1C.sampled_ms=1
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] ;#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.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.use_CFAR_algorithm=false;
;#threshold: Acquisition threshold ;#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] ;#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 ;Acquisition_1C.pfa=0.01
;#doppler_max: Maximum expected Doppler shift [Hz] ;#doppler_max: Maximum expected Doppler shift [Hz]
Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_max=10000
;#doppler_max: Doppler step in the grid search [Hz] ;#doppler_max: Doppler step in the grid search [Hz]
Acquisition_1C.doppler_step=500 Acquisition_1C.doppler_step=250
;######### GALILEO ACQUISITION CONFIG ############ ;######### GALILEO ACQUISITION CONFIG ############
@ -229,7 +230,7 @@ Acquisition_1B.doppler_step=125
;######### TRACKING GPS CONFIG ############ ;######### 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] ;#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. ;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
Tracking_1C.item_type=gr_complex Tracking_1C.item_type=gr_complex
@ -237,19 +238,19 @@ Tracking_1C.item_type=gr_complex
Tracking_1C.if=0 Tracking_1C.if=0
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] ;#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. ;#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_ Tracking_1C.dump_filename=../data/epl_tracking_ch_
;#pll_bw_hz: PLL loop filter bandwidth [Hz] ;#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] ;#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] ;#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] ;#order: PLL/DLL loop filter order [2] or [3]
Tracking_1C.order=3; Tracking_1C.order=3;

View File

@ -125,6 +125,10 @@ void Channel::connect(gr::top_block_sptr top_block)
DLOG(INFO) << "pass_through_ -> tracking"; DLOG(INFO) << "pass_through_ -> tracking";
top_block->connect(trk_->get_right_block(), 0, nav_->get_left_block(), 0); top_block->connect(trk_->get_right_block(), 0, nav_->get_left_block(), 0);
DLOG(INFO) << "tracking -> telemetry_decoder"; 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; connected_ = true;
} }

View File

@ -103,7 +103,6 @@ static inline void volk_gnsssdr_16ic_s32fc_x2_rotator_16ic_a_sse3(lv_16sc_t* out
for(unsigned int number = 0; number < sse_iters; number++) for(unsigned int number = 0; number < sse_iters; number++)
{ {
a = _mm_set_ps((float)(lv_cimag(_in[1])), (float)(lv_creal(_in[1])), (float)(lv_cimag(_in[0])), (float)(lv_creal(_in[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg a = _mm_set_ps((float)(lv_cimag(_in[1])), (float)(lv_creal(_in[1])), (float)(lv_cimag(_in[0])), (float)(lv_creal(_in[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg
__builtin_prefetch(_in + 8);
//complex 32fc multiplication b=a*two_phase_acc_reg //complex 32fc multiplication b=a*two_phase_acc_reg
yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr
yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di
@ -150,7 +149,7 @@ static inline void volk_gnsssdr_16ic_s32fc_x2_rotator_16ic_a_sse3(lv_16sc_t* out
_out += 4; _out += 4;
} }
_mm_store_ps((float*)two_phase_acc, two_phase_acc_reg); _mm_storeu_ps((float*)two_phase_acc, two_phase_acc_reg);
(*phase) = two_phase_acc[0]; (*phase) = two_phase_acc[0];
for (unsigned int i = sse_iters * 4; i < num_points; ++i) for (unsigned int i = sse_iters * 4; i < num_points; ++i)
@ -200,7 +199,6 @@ static inline void volk_gnsssdr_16ic_s32fc_x2_rotator_16ic_u_sse3(lv_16sc_t* out
for(unsigned int number = 0; number < sse_iters; number++) for(unsigned int number = 0; number < sse_iters; number++)
{ {
a = _mm_set_ps((float)(lv_cimag(_in[1])), (float)(lv_creal(_in[1])), (float)(lv_cimag(_in[0])), (float)(lv_creal(_in[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg a = _mm_set_ps((float)(lv_cimag(_in[1])), (float)(lv_creal(_in[1])), (float)(lv_cimag(_in[0])), (float)(lv_creal(_in[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg
__builtin_prefetch(_in + 8);
//complex 32fc multiplication b=a*two_phase_acc_reg //complex 32fc multiplication b=a*two_phase_acc_reg
yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr
yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di
@ -221,6 +219,7 @@ static inline void volk_gnsssdr_16ic_s32fc_x2_rotator_16ic_u_sse3(lv_16sc_t* out
//next two samples //next two samples
_in += 2; _in += 2;
a = _mm_set_ps((float)(lv_cimag(_in[1])), (float)(lv_creal(_in[1])), (float)(lv_cimag(_in[0])), (float)(lv_creal(_in[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg a = _mm_set_ps((float)(lv_cimag(_in[1])), (float)(lv_creal(_in[1])), (float)(lv_cimag(_in[0])), (float)(lv_creal(_in[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg
__builtin_prefetch(_in + 8);
//complex 32fc multiplication b=a*two_phase_acc_reg //complex 32fc multiplication b=a*two_phase_acc_reg
yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr
yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di

View File

@ -140,7 +140,6 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_a_sse3(lv_16sc_
// Phase rotation on operand in_common starts here: // Phase rotation on operand in_common starts here:
//printf("generic phase %i: %f,%f\n", n*4,lv_creal(*phase),lv_cimag(*phase)); //printf("generic phase %i: %f,%f\n", n*4,lv_creal(*phase),lv_cimag(*phase));
pa = _mm_set_ps((float)(lv_cimag(_in_common[1])), (float)(lv_creal(_in_common[1])), (float)(lv_cimag(_in_common[0])), (float)(lv_creal(_in_common[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg pa = _mm_set_ps((float)(lv_cimag(_in_common[1])), (float)(lv_creal(_in_common[1])), (float)(lv_cimag(_in_common[0])), (float)(lv_creal(_in_common[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg
__builtin_prefetch(_in_common + 8);
//complex 32fc multiplication b=a*two_phase_acc_reg //complex 32fc multiplication b=a*two_phase_acc_reg
yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr yl = _mm_moveldup_ps(two_phase_acc_reg); // Load yl with cr,cr,dr,dr
yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di yh = _mm_movehdup_ps(two_phase_acc_reg); // Load yh with ci,ci,di,di
@ -304,6 +303,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_u_sse3(lv_16sc_
for(unsigned int number = 0; number < sse_iters; number++) for(unsigned int number = 0; number < sse_iters; number++)
{ {
// Phase rotation on operand in_common starts here: // Phase rotation on operand in_common starts here:
pa = _mm_set_ps((float)(lv_cimag(_in_common[1])), (float)(lv_creal(_in_common[1])), (float)(lv_cimag(_in_common[0])), (float)(lv_creal(_in_common[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg pa = _mm_set_ps((float)(lv_cimag(_in_common[1])), (float)(lv_creal(_in_common[1])), (float)(lv_cimag(_in_common[0])), (float)(lv_creal(_in_common[0]))); // //load (2 byte imag, 2 byte real) x 2 into 128 bits reg
__builtin_prefetch(_in_common + 8); __builtin_prefetch(_in_common + 8);
//complex 32fc multiplication b=a*two_phase_acc_reg //complex 32fc multiplication b=a*two_phase_acc_reg
@ -378,7 +378,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_u_sse3(lv_16sc_
a = _mm_or_si128(realcacc[n_vec], imagcacc[n_vec]); a = _mm_or_si128(realcacc[n_vec], imagcacc[n_vec]);
_mm_store_si128((__m128i*)dotProductVector, a); // Store the results back into the dot product vector _mm_storeu_si128((__m128i*)dotProductVector, a); // Store the results back into the dot product vector
dotProduct = lv_cmake(0,0); dotProduct = lv_cmake(0,0);
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
@ -390,9 +390,10 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_u_sse3(lv_16sc_
free(realcacc); free(realcacc);
free(imagcacc); free(imagcacc);
_mm_store_ps((float*)two_phase_acc, two_phase_acc_reg); _mm_storeu_ps((float*)two_phase_acc, two_phase_acc_reg);
(*phase) = two_phase_acc[0]; (*phase) = two_phase_acc[0];
for(unsigned int n = sse_iters * 4; n < num_points; n++) for(unsigned int n = sse_iters * 4; n < num_points; n++)
{ {
tmp16 = in_common[n]; tmp16 = in_common[n];

View File

@ -38,6 +38,7 @@
#include <iostream> #include <iostream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <pmt/pmt.h>
#include <glog/logging.h> #include <glog/logging.h>
#include "control_message_factory.h" #include "control_message_factory.h"
#include "gnss_synchro.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::block("gps_navigation_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
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 // initialize internal vars
d_queue = queue; d_queue = queue;
d_dump = dump; 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 const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
// TODO Optimize me! // TODO Optimize me!
if (in[0][d_samples_per_bit*8 - 1].symbol_integration_enabled==false)
{
//******* preamble correlation ******** //******* preamble correlation ********
for (unsigned int i = 0; i < d_samples_per_bit*8; i++) 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]; 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; d_flag_preamble = false;
//******* frame sync ****************** //******* frame sync ******************
if (abs(corr_value) >= 160) if (abs(corr_value) == 160)
{ {
//TODO: Rewrite with state machine //TODO: Rewrite with state machine
if (d_stat == 0) if (d_stat == 0)
{ {
d_GPS_FSM.Event_gps_word_preamble(); d_GPS_FSM.Event_gps_word_preamble();
d_preamble_index = d_sample_counter;//record the preamble sample stamp 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 = 0; //sync the symbol to bits integrator
d_symbol_accumulator_counter = 0; d_symbol_accumulator_counter = 0;
d_frame_bit_index = 8; d_frame_bit_index = 7;
d_stat = 1; // enter into frame pre-detection status d_stat = 1; // enter into frame pre-detection status
} }
else if (d_stat == 1) //check 6 seconds of preamble separation 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_flag_preamble = true;
d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P) 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_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) 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; d_flag_frame_sync = true;
if (corr_value < 0) if (corr_value < 0)
{ {
flag_PLL_180_deg_phase_locked = true; //PLL is locked to opposite phase! 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 else
{ {
flag_PLL_180_deg_phase_locked = false; 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; preamble_diff = d_sample_counter - d_preamble_index;
if (preamble_diff > 6001) 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_stat = 0; //lost of frame sync
d_flag_frame_sync = false; d_flag_frame_sync = false;
flag_TOW_set = 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 ******* //******* SYMBOL TO BIT *******
d_symbol_accumulator += in[0][d_samples_per_bit*8 - 1].Prompt_I; // accumulate the input value in d_symbol_accumulator if (in[0][d_samples_per_bit*8 - 1].Flag_valid_symbol_output==true)
d_symbol_accumulator_counter++; {
if (d_symbol_accumulator_counter == 20) 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) if (d_symbol_accumulator > 0)
{ //symbol to bit { //symbol to bit
d_GPS_frame_4bytes += 1; //insert the telemetry bit in LSB d_GPS_frame_4bytes += 1; //insert the telemetry bit in LSB
} }
d_symbol_accumulator = 0; d_symbol_accumulator = 0;
d_symbol_accumulator_counter = 0; d_symbol_accumulator_counter = 0;
//******* bits to words ****** //******* bits to words ******
d_frame_bit_index++; d_frame_bit_index++;
if (d_frame_bit_index == 30) 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 d_GPS_frame_4bytes <<= 1; //shift 1 bit left the telemetry word
} }
} }
// output the frame // output the frame
consume_each(1); //one by one consume_each(1); //one by one

View File

@ -34,7 +34,9 @@
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <pmt/pmt.h>
#include <volk/volk.h> #include <volk/volk.h>
#include <glog/logging.h> #include <glog/logging.h>
#include "gps_sdr_signal_processing.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( 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::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))) 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 // initialize internal vars
d_queue = queue; d_queue = queue;
d_dump = dump; 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); d_correlation_length_samples = static_cast<int>(d_vector_length);
// Initialize tracking ========================================== // Initialize tracking ==========================================
d_code_loop_filter.set_DLL_BW(dll_bw_hz); d_pll_bw_hz=pll_bw_hz;
d_carrier_loop_filter.set_params(10.0, pll_bw_hz,2); 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 -------------------------------------------------------- //--- DLL variables --------------------------------------------------------
d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) 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; d_rem_carrier_phase_rad = 0.0;
// sample synchronization // 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_sample_counter_seconds = 0;
d_acq_sample_stamp = 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_rem_code_phase_chips = 0.0;
d_code_phase_step_chips = 0.0; d_code_phase_step_chips = 0.0;
d_carrier_phase_step_rad = 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); //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 // enable tracking
d_pull_in = true; d_pull_in = true;
d_enable_tracking = true; d_enable_tracking = true;
d_enable_20ms_integration=false;
d_preamble_synchronized=false;
LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
<< " Code Phase correction [samples]=" << delay_correction_samples << " Code Phase correction [samples]=" << delay_correction_samples
<< " PULL-IN Code Phase [samples]=" << d_acq_code_phase_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; current_synchro_data = *d_acquisition_gnss_synchro;
*out[0] = current_synchro_data; *out[0] = current_synchro_data;
consume_each(samples_offset); //shift input to perform alignment with local replica consume_each(samples_offset); //shift input to perform alignment with local replica
d_symbol_counter++;
return 1; 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.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); 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 // ####### 20ms coherent intergration extension (experimental)
CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in); // 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
// ################## PLL ########################################################## if (d_P_history.size()>GPS_CA_TELEMETRY_SYMBOLS_PER_BIT)
// 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 d_E_history.pop_front();
// Carrier discriminator filter d_P_history.pop_front();
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan d_L_history.pop_front();
//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 ########################################################## bool enable_dll_pll;
// DLL discriminator if (d_enable_20ms_integration==true)
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 long int symbol_diff=d_symbol_counter-d_preamble_index;
code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips_Ti); //input [chips/Ti] -> output [chips/second] if (symbol_diff % GPS_CA_TELEMETRY_SYMBOLS_PER_BIT == 0)
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] // compute coherent integration and enable tracking loop
// TODO: PLL carrier aid to DLL is disabled. Re-enable it and measure performance // perform coherent integration using correlator output history
dll_code_error_secs_Ti = - code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti; //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);
}
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### if (d_preamble_synchronized==false)
// keep alignment parameters for the next input buffer {
double T_chip_seconds; d_preamble_synchronized=true;
double T_prn_seconds; }
double T_prn_samples; current_synchro_data.symbol_integration_enabled=true;
double K_blk_samples; // UPDATE INTEGRATION TIME
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation CURRENT_INTEGRATION_TIME_S = static_cast<double>(GPS_CA_TELEMETRY_SYMBOLS_PER_BIT)*GPS_L1_CA_CODE_PERIOD;
T_chip_seconds = 1 / d_code_freq_chips; d_code_loop_filter.set_DLL_BW(d_dll_bw_hz);
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; d_carrier_loop_filter.set_params(10.0, d_pll_bw_hz/5,2);
T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in); enable_dll_pll=true;
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 }else{
old_d_rem_code_phase_samples=d_rem_code_phase_samples; current_synchro_data.symbol_integration_enabled=false;
d_rem_code_phase_samples = K_blk_samples - static_cast<double>(d_correlation_length_samples); //rounding error < 1 sample 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;
}
// UPDATE REMNANT CARRIER PHASE // ###### end 20ms correlation extension
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 ################################################# if (enable_dll_pll==true)
//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); // ################## 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 COMMANDS ################################################# // ################## DLL ##########################################################
//code phase step (Code resampler phase increment per sample) [chips/sample] // DLL discriminator
d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in); code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); //[chips/Ti] //early and late
//remnant code phase [chips] // Code discriminator filter
d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in)); 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;
// ####### CN0 ESTIMATION AND LOCK DETECTORS ####################################### // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
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 ########## // keep alignment parameters for the next input buffer
current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs[1]).real()); double T_chip_seconds;
current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs[1]).imag()); double T_prn_seconds;
// Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) double T_prn_samples;
current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + old_d_rem_code_phase_samples) / static_cast<double>(d_fs_in); double K_prn_samples;
// This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0 // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
current_synchro_data.Code_phase_secs = 0; T_chip_seconds = 1 / d_code_freq_chips;
current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; K_prn_samples = round(T_prn_samples);
current_synchro_data.Flag_valid_pseudorange = false; double K_T_prn_error_samples=K_prn_samples-T_prn_samples;
*out[0] = current_synchro_data;
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 // ########## 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"; LOG(WARNING) << "noutput_items = 0";
} }
d_symbol_counter++;
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
} }

View File

@ -39,9 +39,11 @@
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <deque>
#include <string> #include <string>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <gnuradio/msg_queue.h> #include <gnuradio/msg_queue.h>
#include <pmt/pmt.h>
#include "concurrent_queue.h" #include "concurrent_queue.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "tracking_2nd_DLL_filter.h" #include "tracking_2nd_DLL_filter.h"
@ -130,6 +132,7 @@ private:
double d_rem_code_phase_samples; double d_rem_code_phase_samples;
double d_rem_code_phase_chips; double d_rem_code_phase_chips;
double d_rem_carrier_phase_rad; double d_rem_carrier_phase_rad;
int d_rem_code_phase_integer_samples;
// PLL and DLL filter library // PLL and DLL filter library
Tracking_2nd_DLL_filter d_code_loop_filter; Tracking_2nd_DLL_filter d_code_loop_filter;
@ -140,6 +143,8 @@ private:
double d_acq_carrier_doppler_hz; double d_acq_carrier_doppler_hz;
// tracking vars // tracking vars
float d_dll_bw_hz;
float d_pll_bw_hz;
double d_code_freq_chips; double d_code_freq_chips;
double d_code_phase_step_chips; double d_code_phase_step_chips;
double d_carrier_doppler_hz; double d_carrier_doppler_hz;
@ -148,6 +153,17 @@ private:
double d_code_phase_samples; double d_code_phase_samples;
double d_pll_to_dll_assist_secs_Ti; 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 //Integration period in samples
int d_correlation_length_samples; int d_correlation_length_samples;

View File

@ -390,12 +390,12 @@ void GNSSFlowgraph::wait()
*/ */
void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
{ {
DLOG(INFO) << "received " << what << " from " << who; DLOG(INFO) << "received " << what << " from " << who;
switch (what) switch (what)
{ {
case 0: 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()); available_GNSS_signals_.push_back(channels_.at(who)->get_signal());
//TODO: Optimize the channel and signal matching! //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_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front(); available_GNSS_signals_.pop_front();
std::cout << "loop"<<std::endl;
} }
channels_.at(who)->set_signal(available_GNSS_signals_.front()); channels_.at(who)->set_signal(available_GNSS_signals_.front());
available_GNSS_signals_.pop_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 //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 // 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 // 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 // TODO: Tracking messages
case 1: 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; channels_state_[who] = 2;
acq_channels_count_--; acq_channels_count_--;
if (!available_GNSS_signals_.empty() && acq_channels_count_ < max_acq_channels_) 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; break;
case 2: 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_) if (acq_channels_count_ < max_acq_channels_)
{ {
channels_state_[who] = 1; channels_state_[who] = 1;
@ -468,7 +470,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
default: default:
break; break;
} }
DLOG(INFO) << "Number of available signals: " << available_GNSS_signals_.size(); DLOG(INFO) << "Number of available signals: " << available_GNSS_signals_.size();
} }

View File

@ -75,6 +75,7 @@ const int GPS_L1_CA_HISTORY_DEEP = 100;
#define GPS_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1} #define GPS_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1}
const int GPS_CA_PREAMBLE_LENGTH_BITS = 8; 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_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_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_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 const int GPS_SUBFRAME_LENGTH = 40; //!< GPS_WORD_LENGTH x 10 = 40 bytes

View File

@ -60,6 +60,8 @@ public:
double Code_phase_secs; //!< Set by Tracking processing block double Code_phase_secs; //!< Set by Tracking processing block
double Tracking_timestamp_secs; //!< Set by Tracking processing block double Tracking_timestamp_secs; //!< Set by Tracking processing block
bool Flag_valid_tracking; bool Flag_valid_tracking;
bool Flag_valid_symbol_output;
bool symbol_integration_enabled; //!< Set by Tracking processing block
//Telemetry Decoder //Telemetry Decoder
double Prn_timestamp_ms; //!< Set by Telemetry Decoder processing block double Prn_timestamp_ms; //!< Set by Telemetry Decoder processing block