diff --git a/conf/gnss-sdr_Galileo_E5a.conf b/conf/gnss-sdr_Galileo_E5a.conf
index 5ba2daa46..702c15cc7 100644
--- a/conf/gnss-sdr_Galileo_E5a.conf
+++ b/conf/gnss-sdr_Galileo_E5a.conf
@@ -7,7 +7,7 @@
;######### GLOBAL OPTIONS ##################
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
-GNSS-SDR.internal_fs_hz=12000000
+GNSS-SDR.internal_fs_hz=32000000
;######### CONTROL_THREAD CONFIG ############
ControlThread.wait_for_flowgraph=false
@@ -32,15 +32,15 @@ SignalSource.implementation=File_Signal_Source
;SignalSource.filename=/home/marc/E5a_acquisitions/signal_source_5X_primary.dat
;SignalSource.filename=/home/marc/E5a_acquisitions/galileo_E5_8M_r2_upsampled_12.dat
;SignalSource.filename=/home/marc/E5a_acquisitions/Tiered_sim_4sat_stup4_2s_up.dat
-SignalSource.filename=/home/marc/E5a_acquisitions/signal_source_sec21M_long.dat
-
+;SignalSource.filename=/home/marc/E5a_acquisitions/signal_source_sec21M_long.dat
+SignalSource.filename=/home/marc/E5a_acquisitions/32MS_complex.dat;
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
SignalSource.item_type=gr_complex
;#sampling_frequency: Original Signal sampling frequency in [Hz]
-SignalSource.sampling_frequency=12000000
+SignalSource.sampling_frequency=32000000
;#freq: RF front-end center frequency in [Hz]
SignalSource.freq=1176450000
@@ -151,7 +151,7 @@ InputFilter.grid_density=16
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
-InputFilter.sampling_frequency=12000000
+InputFilter.sampling_frequency=32000000
InputFilter.IF=0
@@ -246,7 +246,7 @@ Channel.system=Galileo
;# "6Q" COMPASS E6 Q
;# "6X" COMPASS E6 IQ
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
-Channel.signal=5Q
+Channel.signal=5X
;######### SPECIFIC CHANNELS CONFIG ######
;#The following options are specific to each channel and overwrite the generic options
@@ -254,29 +254,29 @@ Channel.signal=5Q
;######### CHANNEL 0 CONFIG ############
Channel0.system=Galileo
-Channel0.signal=5Q
+Channel0.signal=5X
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
-Channel0.satellite=11
+Channel0.satellite=19
;Channel0.repeat_satellite=true
;######### CHANNEL 1 CONFIG ############
-Channel1.system=Galileo
-Channel1.signal=5Q
-Channel1.satellite=12
+;Channel1.system=Galileo
+;Channel1.signal=5Q
+;Channel1.satellite=12
;######### CHANNEL 2 CONFIG ############
-Channel2.system=Galileo
-Channel2.signal=5Q
-Channel2.satellite=19
+;Channel2.system=Galileo
+;Channel2.signal=5Q
+;Channel2.satellite=11
;######### CHANNEL 3 CONFIG ############
-Channel3.system=Galileo
-Channel3.signal=5Q
-Channel3.satellite=20
+;Channel3.system=Galileo
+;Channel3.signal=5Q
+;Channel3.satellite=20
;######### ACQUISITION GLOBAL CONFIG ############
@@ -289,13 +289,13 @@ Acquisition.item_type=gr_complex
;#if: Signal intermediate frequency in [Hz]
Acquisition.if=0
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
-Acquisition.coherent_integration_time_ms=2
+Acquisition.coherent_integration_time_ms=1
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
-Acquisition.implementation=Galileo_E5a_3ms_Noncoherent_IQ_Acquisition
+Acquisition.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF
;#threshold: Acquisition threshold. It will be ignored if pfa is defined.
-Acquisition.threshold=0.0005
+Acquisition.threshold=0.001
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
-;Acquisition.pfa=0.0001
+Acquisition.pfa=0.0003
;#doppler_max: Maximum expected Doppler shift [Hz]
Acquisition.doppler_max=10000
;#doppler_max: Doppler step in the grid search [Hz]
@@ -304,7 +304,13 @@ Acquisition.doppler_step=250
;maximum test statistics. Only use with implementation: [GPS_L1_CA_PCPS_Acquisition] (should not be used for Galileo_E1_PCPS_Ambiguous_Acquisition])
Acquisition.bit_transition_flag=false
;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true
-Acquisition.max_dwells=2
+Acquisition.max_dwells=1
+
+;#CAF filter: Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated.
+Acquisition.CAF_window_hz=2000
+;#Zero_padding: Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions.
+;#If set to 1 it is ON, if set to 0 it is OFF.
+Acquisition.Zero_padding=0
;######### ACQUISITION CHANNELS CONFIG ######
;#The following options are specific to each channel and overwrite the generic options
@@ -343,8 +349,15 @@ Tracking.dump=true
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
Tracking.dump_filename=./tracking_ch_
+;#pll_bw_hz_init: PLL loop filter bandwidth during initialization [Hz]
+Tracking.pll_bw_hz_init=20.0;
+;#dll_bw_hz_init: DLL loop filter bandwidth during initialization [Hz]
+Tracking.dll_bw_hz_init=20.0;
+;#dll_ti_ms: loop filter integration time after initialization (secondary code delay search)[ms]
+Tracking.ti_ms=3;
+
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
-Tracking.pll_bw_hz=50.0;
+Tracking.pll_bw_hz=5.0;
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
Tracking.dll_bw_hz=2.0;
diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt
index 16dc96583..600ed7f6b 100644
--- a/src/algorithms/acquisition/adapters/CMakeLists.txt
+++ b/src/algorithms/acquisition/adapters/CMakeLists.txt
@@ -28,10 +28,7 @@ if(OPENCL_FOUND)
galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc
galileo_e1_pcps_tong_ambiguous_acquisition.cc
galileo_e1_pcps_8ms_ambiguous_acquisition.cc
- galileo_e5a_pcps_acquisition.cc
- galileo_e5a_pilot_3ms_acquisition.cc
- galileo_e5ax_2ms_pcps_acquisition.cc
- galileo_e5a_3ms_noncoherent_iq_acquisition.cc
+ galileo_e5a_noncoherent_iq_acquisition_caf.cc
)
else(OPENCL_FOUND)
set(ACQ_ADAPTER_SOURCES
@@ -44,10 +41,7 @@ else(OPENCL_FOUND)
galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc
galileo_e1_pcps_tong_ambiguous_acquisition.cc
galileo_e1_pcps_8ms_ambiguous_acquisition.cc
- galileo_e5a_pcps_acquisition.cc
- galileo_e5a_pilot_3ms_acquisition.cc
- galileo_e5ax_2ms_pcps_acquisition.cc
- galileo_e5a_3ms_noncoherent_iq_acquisition.cc
+ galileo_e5a_noncoherent_iq_acquisition_caf.cc
)
endif(OPENCL_FOUND)
diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_3ms_noncoherent_iq_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc
similarity index 63%
rename from src/algorithms/acquisition/adapters/galileo_e5a_3ms_noncoherent_iq_acquisition.cc
rename to src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc
index 9690e0282..9b1b531a1 100644
--- a/src/algorithms/acquisition/adapters/galileo_e5a_3ms_noncoherent_iq_acquisition.cc
+++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc
@@ -1,8 +1,14 @@
/*!
- * \file galileo_e5a_3ms_noncoherent_iq_acquisition.cc
+ * \file galileo_e5a_noncoherent_iq_acquisition_caf.cc
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E5a data and pilot Signals
* \author Marc Sales, 2014. marcsales92(at)gmail.com
+ * \based on work from:
+ *
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena@gmail.com
+ *
*
* -------------------------------------------------------------------------
*
@@ -29,7 +35,7 @@
* -------------------------------------------------------------------------
*/
-#include "galileo_e5a_3ms_noncoherent_iq_acquisition.h"
+#include "galileo_e5a_noncoherent_iq_acquisition_caf.h"
#include
#include
#include
@@ -39,11 +45,10 @@
#include "galileo_e5_signal_processing.h"
#include "Galileo_E5a.h"
#include "configuration_interface.h"
-//#include
using google::LogMessage;
-GalileoE5a3msNoncoherentIQAcquisition::GalileoE5a3msNoncoherentIQAcquisition(
+GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams,
boost::shared_ptr queue) :
@@ -58,24 +63,26 @@ GalileoE5a3msNoncoherentIQAcquisition::GalileoE5a3msNoncoherentIQAcquisition(
item_type_ = configuration_->property(role + ".item_type",
default_item_type);
- fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 21000000);
+ fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
if_ = configuration_->property(role + ".ifreq", 0);
dump_ = configuration_->property(role + ".dump", false);
shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
- sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 3);
- if (sampled_ms_ < 2)
- {
- sampled_ms_=2;
- DLOG(INFO) << "Coherent integration time should be 2 or 3 ms. Changing to 2ms ";
- std::cout<<"Too low coherent integration time. Changing to 2ms" << std::endl;
- }
- else if (sampled_ms_ > 3)
+ CAF_window_hz_ = configuration_->property(role + ".CAF_window_hz",0);
+ Zero_padding = configuration_->property(role + ".Zero_padding",0);
+ sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
+ if (sampled_ms_ > 3)
{
sampled_ms_=3;
- DLOG(INFO) << "Coherent integration time should be 2 or 3 ms. Changing to 3ms ";
- std::cout<<"Too low coherent integration time. Changing to 3ms" << std::endl;
+ DLOG(INFO) << "Coherent integration time should be 3 ms or less. Changing to 3ms ";
+ std::cout<<"Too high coherent integration time. Changing to 3ms" << std::endl;
}
- //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
+ if (Zero_padding > 0)
+ {
+ sampled_ms_ = 2;
+ DLOG(INFO) << "Zero padding activated. Changing to 1ms code + 1ms zero padding ";
+ std::cout<<"Zero padding activated. Changing to 1ms code + 1ms zero padding" << std::endl;
+ }
+
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
dump_filename_ = configuration_->property(role + ".dump_filename",
@@ -84,31 +91,23 @@ GalileoE5a3msNoncoherentIQAcquisition::GalileoE5a3msNoncoherentIQAcquisition(
//--- Find number of samples per spreading code (1ms)-------------------------
code_length_ = round(fs_in_/ Galileo_E5a_CODE_CHIP_RATE_HZ*Galileo_E5a_CODE_LENGTH_CHIPS);
- // WARNING: In presence of secondary codes, 2ms must be correlated with 1ms
- // of primary code and 1ms of padded zeros.
vector_length_=code_length_ * sampled_ms_;
-// vector_length_=15*code_length_;
-
- //std::cout << sampled_ms_ << " sampledms" << code_length_ << " cdelength" << std::endl;
-
- //if (posix_memalign((void**)&(code_), 16,vector_length_ * sizeof(gr_complex)) == 0){};
codeI_= new gr_complex[vector_length_];
codeQ_= new gr_complex[vector_length_];
+ both_signal_components = false;
+ std::string sig_ = configuration_->property("Channel.signal", std::string("5X"));
+ if (sig_.at(0) == '5' && sig_.at(1) == 'X')
+ {
+ both_signal_components = true;
+ }
if (item_type_.compare("gr_complex") == 0)
{
item_size_ = sizeof(gr_complex);
- acquisition_cc_ = galileo_e5a_3ms_noncoherentIQ_make_acquisition_cc(sampled_ms_, max_dwells_,
+ acquisition_cc_ = galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(sampled_ms_, max_dwells_,
shift_resolution_, if_, fs_in_, code_length_, code_length_,
- bit_transition_flag_, queue_, dump_, dump_filename_);
-
-// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
-//
-// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id()
-// << ")";
-// DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id()
-// << ")";
+ bit_transition_flag_, queue_, dump_, dump_filename_, both_signal_components, CAF_window_hz_);
}
else
{
@@ -118,13 +117,13 @@ GalileoE5a3msNoncoherentIQAcquisition::GalileoE5a3msNoncoherentIQAcquisition(
}
-GalileoE5a3msNoncoherentIQAcquisition::~GalileoE5a3msNoncoherentIQAcquisition()
+GalileoE5aNoncoherentIQAcquisitionCaf::~GalileoE5aNoncoherentIQAcquisitionCaf()
{
delete[] codeI_;
delete[] codeQ_;
}
-void GalileoE5a3msNoncoherentIQAcquisition::set_channel(unsigned int channel)
+void GalileoE5aNoncoherentIQAcquisitionCaf::set_channel(unsigned int channel)
{
channel_ = channel;
if (item_type_.compare("gr_complex") == 0)
@@ -133,7 +132,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_channel(unsigned int channel)
}
}
-void GalileoE5a3msNoncoherentIQAcquisition::set_threshold(float threshold)
+void GalileoE5aNoncoherentIQAcquisitionCaf::set_threshold(float threshold)
{
float pfa = configuration_->property(role_+ boost::lexical_cast(channel_) + ".pfa", 0.0);
@@ -158,7 +157,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_threshold(float threshold)
}
-void GalileoE5a3msNoncoherentIQAcquisition::set_doppler_max(unsigned int doppler_max)
+void GalileoE5aNoncoherentIQAcquisitionCaf::set_doppler_max(unsigned int doppler_max)
{
doppler_max_ = doppler_max;
@@ -168,7 +167,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_doppler_max(unsigned int doppler
}
}
-void GalileoE5a3msNoncoherentIQAcquisition::set_doppler_step(unsigned int doppler_step)
+void GalileoE5aNoncoherentIQAcquisitionCaf::set_doppler_step(unsigned int doppler_step)
{
doppler_step_ = doppler_step;
if (item_type_.compare("gr_complex") == 0)
@@ -177,7 +176,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_doppler_step(unsigned int dopple
}
}
-void GalileoE5a3msNoncoherentIQAcquisition::set_channel_queue(
+void GalileoE5aNoncoherentIQAcquisitionCaf::set_channel_queue(
concurrent_queue *channel_internal_queue)
{
channel_internal_queue_ = channel_internal_queue;
@@ -188,7 +187,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_channel_queue(
}
-void GalileoE5a3msNoncoherentIQAcquisition::set_gnss_synchro(
+void GalileoE5aNoncoherentIQAcquisitionCaf::set_gnss_synchro(
Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
@@ -199,7 +198,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_gnss_synchro(
}
-signed int GalileoE5a3msNoncoherentIQAcquisition::mag()
+signed int GalileoE5aNoncoherentIQAcquisitionCaf::mag()
{
if (item_type_.compare("gr_complex") == 0)
{
@@ -212,13 +211,13 @@ signed int GalileoE5a3msNoncoherentIQAcquisition::mag()
}
-void GalileoE5a3msNoncoherentIQAcquisition::init()
+void GalileoE5aNoncoherentIQAcquisitionCaf::init()
{
acquisition_cc_->init();
set_local_code();
}
-void GalileoE5a3msNoncoherentIQAcquisition::set_local_code()
+void GalileoE5aNoncoherentIQAcquisitionCaf::set_local_code()
{
if (item_type_.compare("gr_complex")==0)
{
@@ -226,28 +225,48 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_local_code()
std::complex* codeI = new std::complex[code_length_];
std::complex* codeQ = new std::complex[code_length_];
- std::cout << "ADAPTER E5a 3ms noncoherentIQ. SIGNAL = " << gnss_synchro_->Signal << " PRN = " << gnss_synchro_->PRN << std::endl;
-
- char a[3];
- strcpy(a,"5I");
- galileo_e5_a_code_gen_complex_sampled(codeI, a,
- gnss_synchro_->PRN, fs_in_, 0, false);
-
- strcpy(a,"5Q");
- galileo_e5_a_code_gen_complex_sampled(codeQ, a,
- gnss_synchro_->PRN, fs_in_, 0, false);
+ if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
+ {
+ char a[3];
+ strcpy(a,"5I");
+ galileo_e5_a_code_gen_complex_sampled(codeI, a,
+ gnss_synchro_->PRN, fs_in_, 0);
+ strcpy(a,"5Q");
+ galileo_e5_a_code_gen_complex_sampled(codeQ, a,
+ gnss_synchro_->PRN, fs_in_, 0);
+ }
+ else
+ {
+ galileo_e5_a_code_gen_complex_sampled(codeI, gnss_synchro_->Signal,
+ gnss_synchro_->PRN, fs_in_, 0);
+ }
// WARNING: 3ms are coherently integrated. Secondary sequence (1,1,1)
// is generated, and modulated in the 'block'.
- for (unsigned int i = 0; i < sampled_ms_; i++)
+ if (Zero_padding == 0) // if no zero_padding
{
- memcpy(&(codeI_[i*code_length_]), codeI,
- sizeof(gr_complex)*code_length_);
-
- memcpy(&(codeQ_[i*code_length_]), codeQ,
- sizeof(gr_complex)*code_length_);
+ for (unsigned int i = 0; i < sampled_ms_; i++)
+ {
+ memcpy(&(codeI_[i*code_length_]), codeI,
+ sizeof(gr_complex)*code_length_);
+ if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
+ {
+ memcpy(&(codeQ_[i*code_length_]), codeQ,
+ sizeof(gr_complex)*code_length_);
+ }
+ }
+ }
+ else
+ {
+ // 1ms code + 1ms zero padding
+ memcpy(&(codeI_[0]), codeI,
+ sizeof(gr_complex)*code_length_);
+ if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
+ {
+ memcpy(&(codeQ_[0]), codeQ,
+ sizeof(gr_complex)*code_length_);
+ }
}
-
acquisition_cc_->set_local_code(codeI_,codeQ_);
delete[] codeI;
@@ -257,7 +276,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::set_local_code()
}
-void GalileoE5a3msNoncoherentIQAcquisition::reset()
+void GalileoE5aNoncoherentIQAcquisitionCaf::reset()
{
if (item_type_.compare("gr_complex") == 0)
{
@@ -266,7 +285,7 @@ void GalileoE5a3msNoncoherentIQAcquisition::reset()
}
-float GalileoE5a3msNoncoherentIQAcquisition::calculate_threshold(float pfa)
+float GalileoE5aNoncoherentIQAcquisitionCaf::calculate_threshold(float pfa)
{
//Calculate the threshold
unsigned int frequency_bins = 0;
@@ -286,31 +305,24 @@ float GalileoE5a3msNoncoherentIQAcquisition::calculate_threshold(float pfa)
}
-void GalileoE5a3msNoncoherentIQAcquisition::connect(gr::top_block_sptr top_block)
+void GalileoE5aNoncoherentIQAcquisitionCaf::connect(gr::top_block_sptr top_block)
{
-// if (item_type_.compare("gr_complex") == 0)
-// {
-// top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
-// }
+ // Nothing to connect internally
}
-void GalileoE5a3msNoncoherentIQAcquisition::disconnect(gr::top_block_sptr top_block)
+void GalileoE5aNoncoherentIQAcquisitionCaf::disconnect(gr::top_block_sptr top_block)
{
-// if (item_type_.compare("gr_complex") == 0)
-// {
-// top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
-// }
+ // Nothing to disconnect internally
}
-gr::basic_block_sptr GalileoE5a3msNoncoherentIQAcquisition::get_left_block()
-{
- return acquisition_cc_;
- //return stream_to_vector_;
-}
-
-
-gr::basic_block_sptr GalileoE5a3msNoncoherentIQAcquisition::get_right_block()
+gr::basic_block_sptr GalileoE5aNoncoherentIQAcquisitionCaf::get_left_block()
+{
+ return acquisition_cc_;
+}
+
+
+gr::basic_block_sptr GalileoE5aNoncoherentIQAcquisitionCaf::get_right_block()
{
return acquisition_cc_;
}
diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_3ms_noncoherent_iq_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h
similarity index 78%
rename from src/algorithms/acquisition/adapters/galileo_e5a_3ms_noncoherent_iq_acquisition.h
rename to src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h
index c08361424..6d7f0d13c 100644
--- a/src/algorithms/acquisition/adapters/galileo_e5a_3ms_noncoherent_iq_acquisition.h
+++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h
@@ -1,8 +1,14 @@
/*!
- * \file galileo_e5a_3ms_noncoherent_iq_acquisition.h
+ * \file galileo_e5a_noncoherent_iq_acquisition_caf.h
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E5a data and pilot Signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
+ * \author Marc Sales, 2014. marcsales92(at)gmail.com
+ * \based on work from:
+ *
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena@gmail.com
+ *
*
* -------------------------------------------------------------------------
*
@@ -29,37 +35,37 @@
* -------------------------------------------------------------------------
*/
-#ifndef GALILEO_E5A_3MS_NONCOHERENT_IQ_ACQUISITION_H_
-#define GALILEO_E5A_3MS_NONCOHERENT_IQ_ACQUISITION_H_
+#ifndef GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
+#define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
#include
#include
#include
#include "gnss_synchro.h"
#include "acquisition_interface.h"
-#include "galileo_e5a_3ms_noncoherent_iq_acquisition_cc.h"
+#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
class ConfigurationInterface;
-class GalileoE5a3msNoncoherentIQAcquisition: public AcquisitionInterface
+class GalileoE5aNoncoherentIQAcquisitionCaf: public AcquisitionInterface
{
public:
- GalileoE5a3msNoncoherentIQAcquisition(ConfigurationInterface* configuration,
+ GalileoE5aNoncoherentIQAcquisitionCaf(ConfigurationInterface* configuration,
std::string role, unsigned int in_streams,
unsigned int out_streams, boost::shared_ptr queue);
- virtual ~GalileoE5a3msNoncoherentIQAcquisition();
+ virtual ~GalileoE5aNoncoherentIQAcquisitionCaf();
std::string role()
{
return role_;
}
/*!
- * \brief Returns "Galileo_E5a_3ms_Noncoherent_IQ_Acquisition"
+ * \brief Returns "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF"
*/
std::string implementation()
{
- return "Galileo_E5a_3ms_Noncoherent_IQ_Acquisition";
+ return "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF";
}
size_t item_size()
{
@@ -71,7 +77,6 @@ public:
gr::basic_block_sptr get_left_block();
gr::basic_block_sptr get_right_block();
-
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
@@ -126,7 +131,7 @@ public:
private:
ConfigurationInterface* configuration_;
- galileo_e5a_3ms_noncoherentIQ_acquisition_cc_sptr acquisition_cc_;
+ galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr acquisition_cc_;
gr::blocks::stream_to_vector::sptr stream_to_vector_;
size_t item_size_;
std::string item_type_;
@@ -144,8 +149,11 @@ private:
long if_;
bool dump_;
std::string dump_filename_;
+ int Zero_padding;
+ int CAF_window_hz_;
std::complex * codeI_;
std::complex * codeQ_;
+ bool both_signal_components;
Gnss_Synchro * gnss_synchro_;
std::string role_;
unsigned int in_streams_;
@@ -154,4 +162,4 @@ private:
concurrent_queue *channel_internal_queue_;
float calculate_threshold(float pfa);
};
-#endif /* GALILEO_E5A_3MS_NONCOHERENT_IQ_ACQUISITION_H_ */
+#endif /* GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_ */
diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc
deleted file mode 100644
index 12476b033..000000000
--- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-/*!
- * \file galileo_e5a_pcps_acquisition.cc
- * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
- * Galileo E5a data and pilot Signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "galileo_e5a_pcps_acquisition.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include "galileo_e5_signal_processing.h"
-#include "Galileo_E5a.h"
-#include "configuration_interface.h"
-//#include
-
-using google::LogMessage;
-
-GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(
- ConfigurationInterface* configuration, std::string role,
- unsigned int in_streams, unsigned int out_streams,
- boost::shared_ptr queue) :
- role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
-{
- configuration_ = configuration;
- std::string default_item_type = "gr_complex";
- std::string default_dump_filename = "../data/acquisition.dat";
-
- DLOG(INFO) << "role " << role;
-
- item_type_ = configuration_->property(role + ".item_type",
- default_item_type);
-
- fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 12000000);
- if_ = configuration_->property(role + ".ifreq", 0);
- dump_ = configuration_->property(role + ".dump", false);
- shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
- sampled_ms_ = 1; // try luck without zero padding to achieve better gain when bit transition coincides.
- bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
-
- if (!bit_transition_flag_)
- {
- max_dwells_ = configuration_->property(role + ".max_dwells", 1);
- }
- else
- {
- max_dwells_ = 2;
- }
-
- dump_filename_ = configuration_->property(role + ".dump_filename",
- default_dump_filename);
-
- //--- Find number of samples per spreading code (1ms)-------------------------
- code_length_ = round(fs_in_/ Galileo_E5a_CODE_CHIP_RATE_HZ*Galileo_E5a_CODE_LENGTH_CHIPS);
-
- // Several dwells will be needed without zero-padding. Only 1ms in this implementation.
- vector_length_=code_length_;// * sampled_ms_;
-
- //std::cout << sampled_ms_ << " sampledms" << code_length_ << " cdelength" << std::endl;
-
- //if (posix_memalign((void**)&(code_), 16,vector_length_ * sizeof(gr_complex)) == 0){};
-
- code_= new gr_complex[vector_length_];
-
- if (item_type_.compare("gr_complex") == 0)
- {
- item_size_ = sizeof(gr_complex);
- acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, max_dwells_,
- shift_resolution_, if_, fs_in_, code_length_, code_length_,
- bit_transition_flag_, queue_, dump_, dump_filename_);
-
- stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
-
- DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id()
- << ")";
- DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id()
- << ")";
- }
- else
- {
- LOG(WARNING) << item_type_
- << " unknown acquisition item type";
- }
-
-}
-
-GalileoE5aPcpsAcquisition::~GalileoE5aPcpsAcquisition()
-{
- delete[] code_;
-}
-
-void GalileoE5aPcpsAcquisition::set_channel(unsigned int channel)
-{
- channel_ = channel;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_channel(channel_);
- }
-}
-
-void GalileoE5aPcpsAcquisition::set_threshold(float threshold)
-{
-
- float pfa = configuration_->property(role_+ boost::lexical_cast(channel_) + ".pfa", 0.0);
-
- if(pfa==0.0) pfa = configuration_->property(role_+".pfa", 0.0);
-
- if(pfa==0.0)
- {
- threshold_ = threshold;
- }
- else
- {
- threshold_ = calculate_threshold(pfa);
- }
-
- DLOG(INFO) <<"Channel "<set_threshold(threshold_);
- }
-}
-
-
-void GalileoE5aPcpsAcquisition::set_doppler_max(unsigned int doppler_max)
-{
- doppler_max_ = doppler_max;
-
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_doppler_max(doppler_max_);
- }
-}
-
-void GalileoE5aPcpsAcquisition::set_doppler_step(unsigned int doppler_step)
-{
- doppler_step_ = doppler_step;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_doppler_step(doppler_step_);
- }
-}
-
-void GalileoE5aPcpsAcquisition::set_channel_queue(
- concurrent_queue *channel_internal_queue)
-{
- channel_internal_queue_ = channel_internal_queue;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_channel_queue(channel_internal_queue_);
- }
-}
-
-
-void GalileoE5aPcpsAcquisition::set_gnss_synchro(
- Gnss_Synchro* gnss_synchro)
-{
- gnss_synchro_ = gnss_synchro;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_gnss_synchro(gnss_synchro_);
- }
-}
-
-
-signed int GalileoE5aPcpsAcquisition::mag()
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- return acquisition_cc_->mag();
- }
- else
- {
- return 0;
- }
-}
-
-
-void GalileoE5aPcpsAcquisition::init()
-{
- acquisition_cc_->init();
- set_local_code();
-}
-
-void GalileoE5aPcpsAcquisition::set_local_code()
-{
- if (item_type_.compare("gr_complex")==0)
- {
-
- // WARNING: In presence of secondary codes, 2ms must be correlated with 1ms
- // of primary code and 1ms of padded zeros.
- //std::complex* code = new std::complex[2*code_length_];
-
- std::cout << "ADAPTER E5a. SIGNAL = " << gnss_synchro_->Signal << " PRN = " << gnss_synchro_->PRN << std::endl;
- galileo_e5_a_code_gen_complex_sampled(code_, gnss_synchro_->Signal,
- gnss_synchro_->PRN, fs_in_, 0, false);
-
- // WARNING: In presence of secondary codes, 2ms of input signal are required
- // which are correlated with 1ms of primary code and 1ms of zero padding
-// for (unsigned int i = 0; i < sampled_ms_; i++)
-// {
-// memcpy(&(code_[i*code_length_]), code,
-// sizeof(gr_complex)*code_length_);
-//
-// }
-
- acquisition_cc_->set_local_code(code_);
-
- //delete[] code;
- }
-
-}
-
-void GalileoE5aPcpsAcquisition::reset()
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_active(true);
- }
-}
-
-
-float GalileoE5aPcpsAcquisition::calculate_threshold(float pfa)
-{
- //Calculate the threshold
- unsigned int frequency_bins = 0;
- for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
- {
- frequency_bins++;
- }
- DLOG(INFO) << "Channel " << channel_<< " Pfa = " << pfa;
- unsigned int ncells = vector_length_*frequency_bins;
- double exponent = 1/(double)ncells;
- double val = pow(1.0 - pfa, exponent);
- double lambda = double(vector_length_);
- boost::math::exponential_distribution mydist (lambda);
- float threshold = (float)quantile(mydist,val);
-
- return threshold;
-}
-
-
-void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block)
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
- }
-}
-
-
-void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
- }
-}
-
-gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_left_block()
-{
- return stream_to_vector_;
-}
-
-
-gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_right_block()
-{
- return acquisition_cc_;
-}
-
-
-
diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h
deleted file mode 100644
index 3da5453ad..000000000
--- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*!
- * \file galileo_e5a_pcps_acquisition.cc
- * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
- * Galileo E5a data and pilot Signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#ifndef GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_H_
-#define GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_H_
-
-#include
-#include
-#include
-#include "gnss_synchro.h"
-#include "acquisition_interface.h"
-#include "pcps_acquisition_cc.h"
-
-class ConfigurationInterface;
-
-class GalileoE5aPcpsAcquisition: public AcquisitionInterface
-{
-public:
- GalileoE5aPcpsAcquisition(ConfigurationInterface* configuration,
- std::string role, unsigned int in_streams,
- unsigned int out_streams, boost::shared_ptr queue);
-
- virtual ~GalileoE5aPcpsAcquisition();
-
- std::string role()
- {
- return role_;
- }
- /*!
- * \brief Returns "Galileo_E5a_PCPS_Acquisition"
- */
- std::string implementation()
- {
- return "Galileo_E5a_PCPS_Acquisition";
- }
- size_t item_size()
- {
- return item_size_;
- }
-
- void connect(gr::top_block_sptr top_block);
- void disconnect(gr::top_block_sptr top_block);
- gr::basic_block_sptr get_left_block();
- gr::basic_block_sptr get_right_block();
-
-
- /*!
- * \brief Set acquisition/tracking common Gnss_Synchro object pointer
- * to efficiently exchange synchronization data between acquisition and
- * tracking blocks
- */
- void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
-
- /*!
- * \brief Set acquisition channel unique ID
- */
- void set_channel(unsigned int channel);
-
- /*!
- * \brief Set statistics threshold of PCPS algorithm
- */
- void set_threshold(float threshold);
-
- /*!
- * \brief Set maximum Doppler off grid search
- */
- void set_doppler_max(unsigned int doppler_max);
-
- /*!
- * \brief Set Doppler steps for the grid search
- */
- void set_doppler_step(unsigned int doppler_step);
-
- /*!
- * \brief Set tracking channel internal queue
- */
- void set_channel_queue(concurrent_queue *channel_internal_queue);
-
- /*!
- * \brief Initializes acquisition algorithm.
- */
- void init();
-
- /*!
- * \brief Sets local Galileo E5a (data or pilot) code for PCPS acquisition algorithm.
- */
- void set_local_code();
-
- /*!
- * \brief Returns the maximum peak of grid search
- */
- signed int mag();
-
- /*!
- * \brief Restart acquisition algorithm
- */
- void reset();
-
-private:
- ConfigurationInterface* configuration_;
- pcps_acquisition_cc_sptr acquisition_cc_;
- gr::blocks::stream_to_vector::sptr stream_to_vector_;
- size_t item_size_;
- std::string item_type_;
- unsigned int vector_length_;
- unsigned int code_length_;
- bool bit_transition_flag_;
- unsigned int channel_;
- float threshold_;
- unsigned int doppler_max_;
- unsigned int doppler_step_;
- unsigned int shift_resolution_;
- unsigned int sampled_ms_;
- unsigned int max_dwells_;
- long fs_in_;
- long if_;
- bool dump_;
- std::string dump_filename_;
- std::complex * code_;
- Gnss_Synchro * gnss_synchro_;
- std::string role_;
- unsigned int in_streams_;
- unsigned int out_streams_;
- boost::shared_ptr queue_;
- concurrent_queue *channel_internal_queue_;
- float calculate_threshold(float pfa);
-};
-
-#endif /* GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_H_ */
diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pilot_3ms_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pilot_3ms_acquisition.cc
deleted file mode 100644
index 1910237c0..000000000
--- a/src/algorithms/acquisition/adapters/galileo_e5a_pilot_3ms_acquisition.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-/*!
- * \file galileo_e5a_pcps_acquisition.cc
- * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
- * Galileo E5a data and pilot Signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "galileo_e5a_pilot_3ms_acquisition.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include "galileo_e5_signal_processing.h"
-#include "Galileo_E5a.h"
-#include "configuration_interface.h"
-//#include
-
-using google::LogMessage;
-
-GalileoE5aPilot_3msAcquisition::GalileoE5aPilot_3msAcquisition(
- ConfigurationInterface* configuration, std::string role,
- unsigned int in_streams, unsigned int out_streams,
- boost::shared_ptr queue) :
- role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
-{
- configuration_ = configuration;
- std::string default_item_type = "gr_complex";
- std::string default_dump_filename = "../data/acquisition.dat";
-
- DLOG(INFO) << "role " << role;
-
- item_type_ = configuration_->property(role + ".item_type",
- default_item_type);
-
- fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 12000000);
- if_ = configuration_->property(role + ".ifreq", 0);
- dump_ = configuration_->property(role + ".dump", false);
- shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
- sampled_ms_ = 3; // needed 3 ms of input in presence of secondary code.
-// sampled_ms_ = 15;
- //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
- max_dwells_ = configuration_->property(role + ".max_dwells", 1);
-
- dump_filename_ = configuration_->property(role + ".dump_filename",
- default_dump_filename);
-
- //--- Find number of samples per spreading code (1ms)-------------------------
- code_length_ = round(fs_in_/ Galileo_E5a_CODE_CHIP_RATE_HZ*Galileo_E5a_CODE_LENGTH_CHIPS);
-
- // WARNING: In presence of secondary codes, 2ms must be correlated with 1ms
- // of primary code and 1ms of padded zeros.
- vector_length_=3*code_length_;// * sampled_ms_;
-// vector_length_=15*code_length_;
-
- //std::cout << sampled_ms_ << " sampledms" << code_length_ << " cdelength" << std::endl;
-
- //if (posix_memalign((void**)&(code_), 16,vector_length_ * sizeof(gr_complex)) == 0){};
-
- code_= new gr_complex[vector_length_];
-
- if (item_type_.compare("gr_complex") == 0)
- {
- item_size_ = sizeof(gr_complex);
- acquisition_cc_ = galileo_e5a_pilot_3ms_make_acquisition_cc(max_dwells_,
- shift_resolution_, if_, fs_in_, code_length_, code_length_,
- bit_transition_flag_, queue_, dump_, dump_filename_);
-
- stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
-
- DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id()
- << ")";
- DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id()
- << ")";
- }
- else
- {
- LOG(WARNING) << item_type_
- << " unknown acquisition item type";
- }
-
-}
-
-GalileoE5aPilot_3msAcquisition::~GalileoE5aPilot_3msAcquisition()
-{
- delete[] code_;
-}
-
-void GalileoE5aPilot_3msAcquisition::set_channel(unsigned int channel)
-{
- channel_ = channel;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_channel(channel_);
- }
-}
-
-void GalileoE5aPilot_3msAcquisition::set_threshold(float threshold)
-{
-
- float pfa = configuration_->property(role_+ boost::lexical_cast(channel_) + ".pfa", 0.0);
-
- if(pfa==0.0) pfa = configuration_->property(role_+".pfa", 0.0);
-
- if(pfa==0.0)
- {
- threshold_ = threshold;
- }
- else
- {
- threshold_ = calculate_threshold(pfa);
- }
-
- DLOG(INFO) <<"Channel "<set_threshold(threshold_);
- }
-}
-
-
-void GalileoE5aPilot_3msAcquisition::set_doppler_max(unsigned int doppler_max)
-{
- doppler_max_ = doppler_max;
-
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_doppler_max(doppler_max_);
- }
-}
-
-void GalileoE5aPilot_3msAcquisition::set_doppler_step(unsigned int doppler_step)
-{
- doppler_step_ = doppler_step;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_doppler_step(doppler_step_);
- }
-}
-
-void GalileoE5aPilot_3msAcquisition::set_channel_queue(
- concurrent_queue *channel_internal_queue)
-{
- channel_internal_queue_ = channel_internal_queue;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_channel_queue(channel_internal_queue_);
- }
-}
-
-
-void GalileoE5aPilot_3msAcquisition::set_gnss_synchro(
- Gnss_Synchro* gnss_synchro)
-{
- gnss_synchro_ = gnss_synchro;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_gnss_synchro(gnss_synchro_);
- }
-}
-
-
-signed int GalileoE5aPilot_3msAcquisition::mag()
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- return acquisition_cc_->mag();
- }
- else
- {
- return 0;
- }
-}
-
-
-void GalileoE5aPilot_3msAcquisition::init()
-{
- acquisition_cc_->init();
- set_local_code();
-}
-
-void GalileoE5aPilot_3msAcquisition::set_local_code()
-{
- if (item_type_.compare("gr_complex")==0)
- {
-
- // WARNING: In presence of secondary codes, 2ms must be correlated with 1ms
- // of primary code and 1ms of padded zeros.
- std::complex* code = new std::complex[code_length_];
-
- std::cout << "ADAPTER E5a 3ms. SIGNAL = " << gnss_synchro_->Signal << " PRN = " << gnss_synchro_->PRN << std::endl;
-
- char a[3];
- strcpy(a,"5X");
- galileo_e5_a_code_gen_complex_sampled(code, a,
- gnss_synchro_->PRN, fs_in_, 0, false);
-
- // WARNING: 3ms are coherently integrated. Secondary sequence (1,1,1)
- // is generated, and modulated in the 'block'.
- for (unsigned int i = 0; i < 3; i++)
- {
- memcpy(&(code_[i*code_length_]), code,
- sizeof(gr_complex)*code_length_);
-
- }
-
- acquisition_cc_->set_local_code(code_);
-
- delete[] code;
- }
-
-}
-
-void GalileoE5aPilot_3msAcquisition::reset()
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_active(true);
- }
-}
-
-
-float GalileoE5aPilot_3msAcquisition::calculate_threshold(float pfa)
-{
- //Calculate the threshold
- unsigned int frequency_bins = 0;
- for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
- {
- frequency_bins++;
- }
- DLOG(INFO) << "Channel " << channel_<< " Pfa = " << pfa;
- unsigned int ncells = vector_length_*frequency_bins;
- double exponent = 1/(double)ncells;
- double val = pow(1.0 - pfa, exponent);
- double lambda = double(vector_length_);
- boost::math::exponential_distribution mydist (lambda);
- float threshold = (float)quantile(mydist,val);
-
- return threshold;
-}
-
-
-void GalileoE5aPilot_3msAcquisition::connect(gr::top_block_sptr top_block)
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
- }
-}
-
-
-void GalileoE5aPilot_3msAcquisition::disconnect(gr::top_block_sptr top_block)
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
- }
-}
-
-gr::basic_block_sptr GalileoE5aPilot_3msAcquisition::get_left_block()
-{
- return stream_to_vector_;
-}
-
-
-gr::basic_block_sptr GalileoE5aPilot_3msAcquisition::get_right_block()
-{
- return acquisition_cc_;
-}
-
diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pilot_3ms_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5a_pilot_3ms_acquisition.h
deleted file mode 100644
index 2474164d1..000000000
--- a/src/algorithms/acquisition/adapters/galileo_e5a_pilot_3ms_acquisition.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*!
- * \file galileo_e5a_pcps_acquisition.cc
- * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
- * Galileo E5a data and pilot Signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#ifndef GALILEO_E5A_PILOT_3MS_ACQUISITION_H_
-#define GALILEO_E5A_PILOT_3MS_ACQUISITION_H_
-
-#include
-#include
-#include
-#include "gnss_synchro.h"
-#include "acquisition_interface.h"
-#include "galileo_e5a_pilot_3ms_acquisition_cc.h"
-
-class ConfigurationInterface;
-
-class GalileoE5aPilot_3msAcquisition: public AcquisitionInterface
-{
-public:
- GalileoE5aPilot_3msAcquisition(ConfigurationInterface* configuration,
- std::string role, unsigned int in_streams,
- unsigned int out_streams, boost::shared_ptr queue);
-
- virtual ~GalileoE5aPilot_3msAcquisition();
-
- std::string role()
- {
- return role_;
- }
- /*!
- * \brief Returns "Galileo_E5a_Pilot_3ms_Acquisition"
- */
- std::string implementation()
- {
- return "Galileo_E5a_Pilot_3ms_Acquisition";
- }
- size_t item_size()
- {
- return item_size_;
- }
-
- void connect(gr::top_block_sptr top_block);
- void disconnect(gr::top_block_sptr top_block);
- gr::basic_block_sptr get_left_block();
- gr::basic_block_sptr get_right_block();
-
-
- /*!
- * \brief Set acquisition/tracking common Gnss_Synchro object pointer
- * to efficiently exchange synchronization data between acquisition and
- * tracking blocks
- */
- void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
-
- /*!
- * \brief Set acquisition channel unique ID
- */
- void set_channel(unsigned int channel);
-
- /*!
- * \brief Set statistics threshold of PCPS algorithm
- */
- void set_threshold(float threshold);
-
- /*!
- * \brief Set maximum Doppler off grid search
- */
- void set_doppler_max(unsigned int doppler_max);
-
- /*!
- * \brief Set Doppler steps for the grid search
- */
- void set_doppler_step(unsigned int doppler_step);
-
- /*!
- * \brief Set tracking channel internal queue
- */
- void set_channel_queue(concurrent_queue *channel_internal_queue);
-
- /*!
- * \brief Initializes acquisition algorithm.
- */
- void init();
-
- /*!
- * \brief Sets local Galileo E5a (pilot) code for PCPS acquisition algorithm.
- */
- void set_local_code();
-
- /*!
- * \brief Returns the maximum peak of grid search
- */
- signed int mag();
-
- /*!
- * \brief Restart acquisition algorithm
- */
- void reset();
-
-private:
- ConfigurationInterface* configuration_;
- galileo_e5a_pilot_3ms_acquisition_cc_sptr acquisition_cc_;
- gr::blocks::stream_to_vector::sptr stream_to_vector_;
- size_t item_size_;
- std::string item_type_;
- unsigned int vector_length_;
- unsigned int code_length_;
- bool bit_transition_flag_;
- unsigned int channel_;
- float threshold_;
- unsigned int doppler_max_;
- unsigned int doppler_step_;
- unsigned int shift_resolution_;
- unsigned int sampled_ms_;
- unsigned int max_dwells_;
- long fs_in_;
- long if_;
- bool dump_;
- std::string dump_filename_;
- std::complex * code_;
- Gnss_Synchro * gnss_synchro_;
- std::string role_;
- unsigned int in_streams_;
- unsigned int out_streams_;
- boost::shared_ptr queue_;
- concurrent_queue *channel_internal_queue_;
- float calculate_threshold(float pfa);
-};
-
-#endif /* GALILEO_E5A_PILOT_3MS_ACQUISITION_H_ */
diff --git a/src/algorithms/acquisition/adapters/galileo_e5ax_2ms_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5ax_2ms_pcps_acquisition.cc
deleted file mode 100644
index 33cac6aa2..000000000
--- a/src/algorithms/acquisition/adapters/galileo_e5ax_2ms_pcps_acquisition.cc
+++ /dev/null
@@ -1,297 +0,0 @@
- /*\file galileo_e5a_pcps_acquisition.cc
- * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
- * Galileo E5a data and pilot Signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "galileo_e5ax_2ms_pcps_acquisition.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include "galileo_e5_signal_processing.h"
-#include "Galileo_E5a.h"
-#include "configuration_interface.h"
-//#include
-
-using google::LogMessage;
-
-GalileoE5ax2msPcpsAcquisition::GalileoE5ax2msPcpsAcquisition(
- ConfigurationInterface* configuration, std::string role,
- unsigned int in_streams, unsigned int out_streams,
- boost::shared_ptr queue) :
- role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
-{
- configuration_ = configuration;
- std::string default_item_type = "gr_complex";
- std::string default_dump_filename = "../data/acquisition.dat";
-
- DLOG(INFO) << "role " << role;
-
- item_type_ = configuration_->property(role + ".item_type",
- default_item_type);
-
- fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 12000000);
- if_ = configuration_->property(role + ".ifreq", 0);
- dump_ = configuration_->property(role + ".dump", false);
- shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
- sampled_ms_ = 2; // needed 2 ms of input in presence of secondary code.
- //there is always bit transition in e5
- //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
-
- max_dwells_ = configuration_->property(role + ".max_dwells", 1);
-
-
- dump_filename_ = configuration_->property(role + ".dump_filename",
- default_dump_filename);
-
- //--- Find number of samples per spreading code (1ms)-------------------------
- code_length_ = round(fs_in_/ Galileo_E5a_CODE_CHIP_RATE_HZ*Galileo_E5a_CODE_LENGTH_CHIPS);
-
- // WARNING: In presence of secondary codes, 2ms must be correlated with 1ms
- // of primary code and 1ms of padded zeros.
- vector_length_=2*code_length_;// * sampled_ms_;
-
- //std::cout << sampled_ms_ << " sampledms" << code_length_ << " cdelength" << std::endl;
-
- //if (posix_memalign((void**)&(code_), 16,vector_length_ * sizeof(gr_complex)) == 0){};
-
- code_= new gr_complex[vector_length_];
-
- if (item_type_.compare("gr_complex") == 0)
- {
- item_size_ = sizeof(gr_complex);
- acquisition_cc_ = galileo_e5ax_2ms_pcps_make_acquisition_cc(max_dwells_,
- shift_resolution_, if_, fs_in_, code_length_, code_length_,
- bit_transition_flag_, queue_, dump_, dump_filename_);
-
- stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
-
- DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id()
- << ")";
- DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id()
- << ")";
- }
- else
- {
- LOG(WARNING) << item_type_
- << " unknown acquisition item type";
- }
-
-}
-
-GalileoE5ax2msPcpsAcquisition::~GalileoE5ax2msPcpsAcquisition()
-{
- delete[] code_;
-}
-
-void GalileoE5ax2msPcpsAcquisition::set_channel(unsigned int channel)
-{
- channel_ = channel;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_channel(channel_);
- }
-}
-
-void GalileoE5ax2msPcpsAcquisition::set_threshold(float threshold)
-{
-
- float pfa = configuration_->property(role_+ boost::lexical_cast(channel_) + ".pfa", 0.0);
-
- if(pfa==0.0) pfa = configuration_->property(role_+".pfa", 0.0);
-
- if(pfa==0.0)
- {
- threshold_ = threshold;
- }
- else
- {
- threshold_ = calculate_threshold(pfa);
- }
-
- DLOG(INFO) <<"Channel "<set_threshold(threshold_);
- }
-}
-
-
-void GalileoE5ax2msPcpsAcquisition::set_doppler_max(unsigned int doppler_max)
-{
- doppler_max_ = doppler_max;
-
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_doppler_max(doppler_max_);
- }
-}
-
-void GalileoE5ax2msPcpsAcquisition::set_doppler_step(unsigned int doppler_step)
-{
- doppler_step_ = doppler_step;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_doppler_step(doppler_step_);
- }
-}
-
-void GalileoE5ax2msPcpsAcquisition::set_channel_queue(
- concurrent_queue *channel_internal_queue)
-{
- channel_internal_queue_ = channel_internal_queue;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_channel_queue(channel_internal_queue_);
- }
-}
-
-
-void GalileoE5ax2msPcpsAcquisition::set_gnss_synchro(
- Gnss_Synchro* gnss_synchro)
-{
- gnss_synchro_ = gnss_synchro;
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_gnss_synchro(gnss_synchro_);
- }
-}
-
-
-signed int GalileoE5ax2msPcpsAcquisition::mag()
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- return acquisition_cc_->mag();
- }
- else
- {
- return 0;
- }
-}
-
-
-void GalileoE5ax2msPcpsAcquisition::init()
-{
- acquisition_cc_->init();
- set_local_code();
-}
-
-void GalileoE5ax2msPcpsAcquisition::set_local_code()
-{
- if (item_type_.compare("gr_complex")==0)
- {
-
- // WARNING: In presence of secondary codes, 2ms must be correlated with 1ms
- // of primary code and 1ms of padded zeros.
- //std::complex* code = new std::complex[2*code_length_];
-
- std::cout << "ADAPTER E5a. SIGNAL = " << gnss_synchro_->Signal << " PRN = " << gnss_synchro_->PRN << std::endl;
- char a[3];
- strcpy(a,"5X");
- galileo_e5_a_code_gen_complex_sampled(code_, a,
- gnss_synchro_->PRN, fs_in_, 0, false);
-
- // WARNING: In presence of secondary codes, 2ms of input signal are required
- // which are correlated with 1ms of primary code and 1ms of zero padding
-// for (unsigned int i = 0; i < sampled_ms_; i++)
-// {
-// memcpy(&(code_[i*code_length_]), code,
-// sizeof(gr_complex)*code_length_);
-//
-// }
-
- acquisition_cc_->set_local_code(code_);
-
- //delete[] code;
- }
-
-}
-
-void GalileoE5ax2msPcpsAcquisition::reset()
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- acquisition_cc_->set_active(true);
- }
-}
-
-
-float GalileoE5ax2msPcpsAcquisition::calculate_threshold(float pfa)
-{
- //Calculate the threshold
- unsigned int frequency_bins = 0;
- for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
- {
- frequency_bins++;
- }
- DLOG(INFO) << "Channel " << channel_<< " Pfa = " << pfa;
- unsigned int ncells = vector_length_*frequency_bins;
- double exponent = 1/(double)ncells;
- double val = pow(1.0 - pfa, exponent);
- double lambda = double(vector_length_);
- boost::math::exponential_distribution mydist (lambda);
- float threshold = (float)quantile(mydist,val);
-
- return threshold;
-}
-
-
-void GalileoE5ax2msPcpsAcquisition::connect(gr::top_block_sptr top_block)
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
- }
-}
-
-
-void GalileoE5ax2msPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
-{
- if (item_type_.compare("gr_complex") == 0)
- {
- top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
- }
-}
-
-gr::basic_block_sptr GalileoE5ax2msPcpsAcquisition::get_left_block()
-{
- return stream_to_vector_;
-}
-
-
-gr::basic_block_sptr GalileoE5ax2msPcpsAcquisition::get_right_block()
-{
- return acquisition_cc_;
-}
-
-
-
diff --git a/src/algorithms/acquisition/adapters/galileo_e5ax_2ms_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5ax_2ms_pcps_acquisition.h
deleted file mode 100644
index c89c545b5..000000000
--- a/src/algorithms/acquisition/adapters/galileo_e5ax_2ms_pcps_acquisition.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * galileo_e5ax_1ms_pcps_acquisition.h
- *
- * Created on: Jun 23, 2014
- * Author: marc
- */
-
-#ifndef GALILEO_E5AX_2MS_PCPS_ACQUISITION_H_
-#define GALILEO_E5AX_2MS_PCPS_ACQUISITION_H_
-
-
-#include
-#include
-#include
-#include "gnss_synchro.h"
-#include "acquisition_interface.h"
-#include "galileo_e5ax_2ms_pcps_acquisition_cc.h"
-
-class ConfigurationInterface;
-
-class GalileoE5ax2msPcpsAcquisition: public AcquisitionInterface
-{
-public:
- GalileoE5ax2msPcpsAcquisition(ConfigurationInterface* configuration,
- std::string role, unsigned int in_streams,
- unsigned int out_streams, boost::shared_ptr queue);
-
- virtual ~GalileoE5ax2msPcpsAcquisition();
-
- std::string role()
- {
- return role_;
- }
- /*!
- * \brief Returns "Galileo_E5ax_2ms_Pcps_Acquisition"
- */
- std::string implementation()
- {
- return "Galileo_E5ax_2ms_Pcps_Acquisition";
- }
- size_t item_size()
- {
- return item_size_;
- }
-
- void connect(gr::top_block_sptr top_block);
- void disconnect(gr::top_block_sptr top_block);
- gr::basic_block_sptr get_left_block();
- gr::basic_block_sptr get_right_block();
-
-
- /*!
- * \brief Set acquisition/tracking common Gnss_Synchro object pointer
- * to efficiently exchange synchronization data between acquisition and
- * tracking blocks
- */
- void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
-
- /*!
- * \brief Set acquisition channel unique ID
- */
- void set_channel(unsigned int channel);
-
- /*!
- * \brief Set statistics threshold of PCPS algorithm
- */
- void set_threshold(float threshold);
-
- /*!
- * \brief Set maximum Doppler off grid search
- */
- void set_doppler_max(unsigned int doppler_max);
-
- /*!
- * \brief Set Doppler steps for the grid search
- */
- void set_doppler_step(unsigned int doppler_step);
-
- /*!
- * \brief Set tracking channel internal queue
- */
- void set_channel_queue(concurrent_queue *channel_internal_queue);
-
- /*!
- * \brief Initializes acquisition algorithm.
- */
- void init();
-
- /*!
- * \brief Sets local Galileo E5a (pilot) code for PCPS acquisition algorithm.
- */
- void set_local_code();
-
- /*!
- * \brief Returns the maximum peak of grid search
- */
- signed int mag();
-
- /*!
- * \brief Restart acquisition algorithm
- */
- void reset();
-
-private:
- ConfigurationInterface* configuration_;
- galileo_e5ax_2ms_pcps_acquisition_cc_sptr acquisition_cc_;
- gr::blocks::stream_to_vector::sptr stream_to_vector_;
- size_t item_size_;
- std::string item_type_;
- unsigned int vector_length_;
- unsigned int code_length_;
- bool bit_transition_flag_;
- unsigned int channel_;
- float threshold_;
- unsigned int doppler_max_;
- unsigned int doppler_step_;
- unsigned int shift_resolution_;
- unsigned int sampled_ms_;
- unsigned int max_dwells_;
- long fs_in_;
- long if_;
- bool dump_;
- std::string dump_filename_;
- std::complex * code_;
- Gnss_Synchro * gnss_synchro_;
- std::string role_;
- unsigned int in_streams_;
- unsigned int out_streams_;
- boost::shared_ptr queue_;
- concurrent_queue *channel_internal_queue_;
- float calculate_threshold(float pfa);
-};
-#endif /* GALILEO_E5AX_2MS_PCPS_ACQUISITION_H_ */
diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
index f9dac7a74..466bfe6d4 100644
--- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
+++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
@@ -25,9 +25,7 @@ if(OPENCL_FOUND)
pcps_tong_acquisition_cc.cc
pcps_cccwsr_acquisition_cc.cc
galileo_pcps_8ms_acquisition_cc.cc
- galileo_e5a_pilot_3ms_acquisition_cc.cc
- galileo_e5ax_2ms_pcps_acquisition_cc.cc
- galileo_e5a_3ms_noncoherent_iq_acquisition_cc.cc
+ galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
pcps_opencl_acquisition_cc.cc # Needs OpenCL
)
else(OPENCL_FOUND)
@@ -39,9 +37,7 @@ else(OPENCL_FOUND)
pcps_tong_acquisition_cc.cc
pcps_cccwsr_acquisition_cc.cc
galileo_pcps_8ms_acquisition_cc.cc
- galileo_e5a_pilot_3ms_acquisition_cc.cc
- galileo_e5ax_2ms_pcps_acquisition_cc.cc
- galileo_e5a_3ms_noncoherent_iq_acquisition_cc.cc
+ galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
)
endif(OPENCL_FOUND)
diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_3ms_noncoherent_iq_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_3ms_noncoherent_iq_acquisition_cc.cc
deleted file mode 100644
index e28dd7a62..000000000
--- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_3ms_noncoherent_iq_acquisition_cc.cc
+++ /dev/null
@@ -1,592 +0,0 @@
-/*!
- * \file galileo_e5a_3ms_noncoherent_iq_acquisition_cc.cc
- * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
- * Galileo E5a data and pilot Signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "galileo_e5a_3ms_noncoherent_iq_acquisition_cc.h"
-#include
-#include
-#include
-#include
-#include
-#include "gnss_signal_processing.h"
-#include "control_message_factory.h"
-
-using google::LogMessage;
-
-galileo_e5a_3ms_noncoherentIQ_acquisition_cc_sptr galileo_e5a_3ms_noncoherentIQ_make_acquisition_cc(
- unsigned int sampled_ms,
- unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename)
-{
-
- return galileo_e5a_3ms_noncoherentIQ_acquisition_cc_sptr(
- new galileo_e5a_3ms_noncoherentIQ_acquisition_cc(sampled_ms, max_dwells, doppler_max, freq, fs_in, samples_per_ms,
- samples_per_code, bit_transition_flag, queue, dump, dump_filename));
-}
-
-galileo_e5a_3ms_noncoherentIQ_acquisition_cc::galileo_e5a_3ms_noncoherentIQ_acquisition_cc(
- unsigned int sampled_ms,
- unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename) :
- gr::block("galileo_e5a_3ms_noncoherentIQ_acquisition_cc",
- gr::io_signature::make(1, 1, sizeof(gr_complex)),
- gr::io_signature::make(0, 0, sizeof(gr_complex)))
- //gr::io_signature::make(1, 1, sizeof(gr_complex) * 3 * samples_per_ms),
- //gr::io_signature::make(0, 0, sizeof(gr_complex) * 3 * samples_per_ms))
-{
- //this->set_relative_rate(1.0/1*samples_per_ms);
- d_sample_counter = 0; // SAMPLE COUNTER
- d_active = false;
- d_state = 0;
- d_queue = queue;
- d_freq = freq;
- d_fs_in = fs_in;
- d_samples_per_ms = samples_per_ms;
- d_samples_per_code = samples_per_code;
- d_max_dwells = max_dwells;
- d_well_count = 0;
- d_doppler_max = doppler_max;
- d_fft_size = sampled_ms * d_samples_per_ms;
- d_mag = 0;
- d_input_power = 0.0;
- d_num_doppler_bins = 0;
- d_bit_transition_flag = bit_transition_flag;
- d_buffer_count=0;
- d_gr_stream_buffer = 7000; // number of samples entering each general work, arbitrary number. Works with all numbers below gnu radio maximum buffer
-
- //todo: do something if posix_memalign fails
- if (posix_memalign((void**)&d_inbuffer, 16, ceil((double)d_fft_size/(double)d_gr_stream_buffer)*d_gr_stream_buffer * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_I_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_I_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_Q_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_Q_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_magnitudeIA, 16, d_fft_size * sizeof(float)) == 0){};
- if (posix_memalign((void**)&d_magnitudeIB, 16, d_fft_size * sizeof(float)) == 0){};
- if (posix_memalign((void**)&d_magnitudeQA, 16, d_fft_size * sizeof(float)) == 0){};
- if (posix_memalign((void**)&d_magnitudeQB, 16, d_fft_size * sizeof(float)) == 0){};
-
- // Direct FFT
- d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
-
- // Inverse FFT
- d_ifft = new gr::fft::fft_complex(d_fft_size, false);
-// d_ifft = new gr::fft::fft_complex(d_fft_size, true);
-
- // For dumping samples into a file
- d_dump = dump;
- d_dump_filename = dump_filename;
-}
-
-galileo_e5a_3ms_noncoherentIQ_acquisition_cc::~galileo_e5a_3ms_noncoherentIQ_acquisition_cc()
-{
- if (d_num_doppler_bins > 0)
- {
- for (unsigned int i = 0; i < d_num_doppler_bins; i++)
- {
- free(d_grid_doppler_wipeoffs[i]);
- }
- delete[] d_grid_doppler_wipeoffs;
- }
-
- free(d_fft_code_I_A);
- free(d_fft_code_I_B);
- free(d_fft_code_Q_A);
- free(d_fft_code_Q_B);
- free(d_magnitudeIA);
- free(d_magnitudeIB);
- free(d_magnitudeQA);
- free(d_magnitudeQB);
-
-
- delete d_fft_if;
- delete d_ifft;
-
-
- if (d_dump)
- {
- d_dump_file.close();
- }
-}
-
-void galileo_e5a_3ms_noncoherentIQ_acquisition_cc::forecast (int noutput_items,
- gr_vector_int &ninput_items_required)
-{
- ninput_items_required[0] = d_gr_stream_buffer ; //set the required available samples in each call
-}
-
-void galileo_e5a_3ms_noncoherentIQ_acquisition_cc::set_local_code(std::complex * codeI, std::complex * codeQ )
-{
- // DATA SIGNAL
- // Three replicas of data primary code. CODE A: (1,1,1)
- memcpy(d_fft_if->get_inbuf(), codeI, sizeof(gr_complex)*d_fft_size);
-
- d_fft_if->execute(); // We need the FFT of local code
-
- //Conjugate the local code
- if (is_unaligned())
- {
- volk_32fc_conjugate_32fc_u(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
- }
- else
- {
- volk_32fc_conjugate_32fc_a(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
- }
-
- // CODE B: First replica is inverted (0,1,1)
- volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
- &codeI[0], gr_complex(-1,0),
- d_samples_per_code);
- d_fft_if->execute(); // We need the FFT of local code
-
- //Conjugate the local code
- if (is_unaligned())
- {
- volk_32fc_conjugate_32fc_u(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
- }
- else
- {
- volk_32fc_conjugate_32fc_a(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
- }
-
- // SAME FOR PILOT SIGNAL
- // Three replicas of pilot primary code. CODE A: (1,1,1)
- memcpy(d_fft_if->get_inbuf(), codeQ, sizeof(gr_complex)*d_fft_size);
-
- d_fft_if->execute(); // We need the FFT of local code
-
- //Conjugate the local code
- if (is_unaligned())
- {
- volk_32fc_conjugate_32fc_u(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
- }
- else
- {
- volk_32fc_conjugate_32fc_a(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
- }
-
- // CODE B: First replica is inverted (0,1,1)
- volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
- &codeQ[0], gr_complex(-1,0),
- d_samples_per_code);
- d_fft_if->execute(); // We need the FFT of local code
-
- //Conjugate the local code
- if (is_unaligned())
- {
- volk_32fc_conjugate_32fc_u(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
- }
- else
- {
- volk_32fc_conjugate_32fc_a(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
- }
-
-
-}
-
-void galileo_e5a_3ms_noncoherentIQ_acquisition_cc::init()
-{
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_mag = 0.0;
- d_input_power = 0.0;
-
- // Count the number of bins
- d_num_doppler_bins = 0;
- for (int doppler = (int)(-d_doppler_max);
- doppler <= (int)d_doppler_max;
- doppler += d_doppler_step)
- {
- d_num_doppler_bins++;
- }
-
- // Create the carrier Doppler wipeoff signals
- d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
- for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
- {
- if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
- d_fft_size * sizeof(gr_complex)) == 0){};
-
- int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
- complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
- d_freq + doppler, d_fs_in, d_fft_size);
- }
-}
-
-
-int galileo_e5a_3ms_noncoherentIQ_acquisition_cc::general_work(int noutput_items,
- gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- /*
- * By J.Arribas, L.Esteve, M.Molina and M.Sales
- * Acquisition strategy (Kay Borre book + CFAR threshold):
- * 1. Compute the input signal power estimation
- * 2. Doppler serial search loop
- * 3. Perform the FFT-based circular convolution (parallel time search)
- * 4. Record the maximum peak and the associated synchronization parameters
- * 5. Compute the test statistics and compare to the threshold
- * 6. Declare positive or negative acquisition using a message queue
- */
-
- int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
- /* States: 0 Reset and load first stream
- * 1 Load the buffer until it reaches fft_size
- * 2 Acquisition algorithm
- * 3 Positive acquisition
- * 4 Negative acquisition
- */
-
- d_sample_counter += d_gr_stream_buffer;
- std::cout << d_state <<" "<< d_sample_counter << std::endl;
- switch (d_state)
- {
- case 0:
- {
- if (d_active)
- {
- //restart acquisition variables
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_well_count = 0;
- d_mag = 0.0;
- d_input_power = 0.0;
- d_test_statistics = 0.0;
- d_state = 1;
- }
- const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
- memcpy(&d_inbuffer[d_buffer_count*d_gr_stream_buffer], in, sizeof(gr_complex)*d_gr_stream_buffer);
- d_buffer_count++;
- //d_sample_counter += ninput_items[0]; // sample counter
- //consume_each(ninput_items[0]);
- break;
- }
- case 1:
- {
- const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
- memcpy(&d_inbuffer[d_buffer_count*d_gr_stream_buffer], in, sizeof(gr_complex)*d_gr_stream_buffer);
- d_buffer_count++;
- if (d_buffer_count*d_gr_stream_buffer >= d_fft_size-d_gr_stream_buffer)
- {
- d_state=2;
- }
-// volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in,
-// d_grid_doppler_wipeoffs[0], d_fft_size);
- //consume_each(7000);
- break;
- }
- case 2:
- {
- // Fill last part of the buffer and reset counter
- const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
- memcpy(&d_inbuffer[d_buffer_count*d_gr_stream_buffer], in, sizeof(gr_complex)*d_gr_stream_buffer);
- d_buffer_count = 0;
- // initialize acquisition algorithm
- int doppler;
- unsigned int indext = 0;
- unsigned int indext_IA = 0;
- unsigned int indext_IB = 0;
- unsigned int indext_QA = 0;
- unsigned int indext_QB = 0;
- float magt = 0.0;
- float magt_IA = 0.0;
- float magt_IB = 0.0;
- float magt_QA = 0.0;
- float magt_QB = 0.0;
- //const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
- float fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
- d_input_power = 0.0;
- d_mag = 0.0;
- int comb = 0;
-
- //d_sample_counter += d_fft_size; // sample counter
-
- d_well_count++;
-
- DLOG(INFO) << "Channel: " << d_channel
- << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
- << " ,sample stamp: " << d_sample_counter << ", threshold: "
- << d_threshold << ", doppler_max: " << d_doppler_max
- << ", doppler_step: " << d_doppler_step;
-
- // 1- Compute the input signal power estimation
- volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_inbuffer, d_fft_size);
- volk_32f_accumulator_s32f_a(&d_input_power, d_magnitudeIA, d_fft_size);
- d_input_power /= (float)d_fft_size;
-
- // 2- Doppler frequency search loop
- for (unsigned int doppler_index=0;doppler_indexget_inbuf(), d_inbuffer,
- d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
-
- // 3- Perform the FFT-based convolution (parallel time search)
- // Compute the FFT of the carrier wiped--off incoming signal
- d_fft_if->execute();
-
- // CODE IA
- // Multiply carrier wiped--off, Fourier transformed incoming signal
- // with the local FFT'd code reference using SIMD operations with VOLK library
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_I_A, d_fft_size);
-
- // compute the inverse FFT
- d_ifft->execute();
-
- // Search maximum
- volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_IA, d_magnitudeIA, d_fft_size);
-
- // Normalize the maximum value to correct the scale factor introduced by FFTW
- magt_IA = d_magnitudeIA[indext_IA] / (fft_normalization_factor * fft_normalization_factor);
-
- // only 1 ms
- //magt=magt_A;
- //indext=indext_A;
-
-
- // REPEAT FOR ALL CODES. CODE_IB
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_I_B, d_fft_size);
- d_ifft->execute();
- volk_32fc_magnitude_squared_32f_a(d_magnitudeIB, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_IB, d_magnitudeIB, d_fft_size);
- magt_IB = d_magnitudeIB[indext_IB] / (fft_normalization_factor * fft_normalization_factor);
-
- // REPEAT FOR ALL CODES. CODE_QA
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_Q_A, d_fft_size);
- d_ifft->execute();
- volk_32fc_magnitude_squared_32f_a(d_magnitudeQA, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_QA, d_magnitudeQA, d_fft_size);
- magt_QA = d_magnitudeQA[indext_QA] / (fft_normalization_factor * fft_normalization_factor);
-
- // REPEAT FOR ALL CODES. CODE_QB
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_Q_B, d_fft_size);
- d_ifft->execute();
- volk_32fc_magnitude_squared_32f_a(d_magnitudeQB, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_QB, d_magnitudeQB, d_fft_size);
- magt_QB = d_magnitudeIB[indext_QB] / (fft_normalization_factor * fft_normalization_factor);
-
- // Integrate noncoherently the two best combinations (I² + Q²)
- // and store the result in the I channel.
- if (magt_IA >= magt_IB)
- {
- if (magt_QA >= magt_QB)
- {
- for (unsigned int i=0; i= magt_QB)
- {
- for (unsigned int i=0; iAcq_delay_samples = (double)(indext % d_samples_per_code);
- d_gnss_synchro->Acq_doppler_hz = (double)doppler;
- d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
-
- // 5- Compute the test statistics and compare to the threshold
- //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
- d_test_statistics = d_mag / d_input_power;
- }
- }
-
- // Record results to file if required
- if (d_dump)
- {
- std::stringstream filename;
- std::streamsize n = sizeof(float) * (d_fft_size); // noncomplex file write
- filename.str("");
- filename << "../data/test_statistics_" << d_gnss_synchro->System
- <<"_" << d_gnss_synchro->Signal << "_sat_"
- << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
- d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
- if (magt_IA >= magt_IB)
- {
- d_dump_file.write((char*)d_magnitudeIA, n);
- }
- else
- {
- d_dump_file.write((char*)d_magnitudeIB, n);
- }
- //d_dump_file.write((char*)d_magnitudeIA, n);
- d_dump_file.close();
- }
- }
-
- if (!d_bit_transition_flag)
- {
- if (d_test_statistics > d_threshold)
- {
- d_state = 3; // Positive acquisition
- }
- else if (d_well_count == d_max_dwells)
- {
- d_state = 4; // Negative acquisition
- }
- else
- {
- d_state = 2;
- }
- }
- else
- {
- if (d_well_count == d_max_dwells) // d_max_dwells = 2
- {
- if (d_test_statistics > d_threshold)
- {
- d_state = 3; // Positive acquisition
- }
- else
- {
- d_state = 4; // Negative acquisition
- }
- }
- else
- {
- d_state = 2;
- }
- }
-
- //consume_each(1);
- //consume_each(d_fft_size);
- break;
- }
- case 3:
- {
- // 6.1- Declare positive acquisition using a message queue
- DLOG(INFO) << "positive acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << d_test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << d_input_power;
-
- d_active = false;
- d_state = 0;
-
- //d_sample_counter += 7000;
- //d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- //consume_each(ninput_items[0]);
- //consume_each(d_fft_size);
- acquisition_message = 1;
- d_channel_internal_queue->push(acquisition_message);
- break;
- }
- case 4:
- {
- // 6.2- Declare negative acquisition using a message queue
- DLOG(INFO) << "negative acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << d_test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << d_input_power;
-
- d_active = false;
- d_state = 0;
-
- //d_sample_counter += 7000;
- //d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- //consume_each(ninput_items[0]);
- //consume_each(d_fft_size);
- acquisition_message = 2;
- d_channel_internal_queue->push(acquisition_message);
- break;
- }
- }
-
- consume_each(d_gr_stream_buffer);
- return 0;
-}
-
diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
new file mode 100644
index 000000000..28b334285
--- /dev/null
+++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
@@ -0,0 +1,771 @@
+/*!
+ * \file galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
+ * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
+ * Galileo E5a data and pilot Signals
+ * \author Marc Sales, 2014. marcsales92(at)gmail.com
+ * \based on work from:
+ *
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena@gmail.com
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
+#include
+#include
+#include
+#include
+#include
+#include "gnss_signal_processing.h"
+#include "control_message_factory.h"
+
+using google::LogMessage;
+
+galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
+ unsigned int sampled_ms,
+ unsigned int max_dwells,
+ unsigned int doppler_max, long freq, long fs_in,
+ int samples_per_ms, int samples_per_code,
+ bool bit_transition_flag,
+ gr::msg_queue::sptr queue, bool dump,
+ std::string dump_filename,
+ bool both_signal_components_,
+ int CAF_window_hz_)
+{
+
+ return galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr(
+ new galileo_e5a_noncoherentIQ_acquisition_caf_cc(sampled_ms, max_dwells, doppler_max, freq, fs_in, samples_per_ms,
+ samples_per_code, bit_transition_flag, queue, dump, dump_filename, both_signal_components_, CAF_window_hz_));
+}
+
+galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisition_caf_cc(
+ unsigned int sampled_ms,
+ unsigned int max_dwells,
+ unsigned int doppler_max, long freq, long fs_in,
+ int samples_per_ms, int samples_per_code,
+ bool bit_transition_flag,
+ gr::msg_queue::sptr queue, bool dump,
+ std::string dump_filename,
+ bool both_signal_components_,
+ int CAF_window_hz_) :
+ gr::block("galileo_e5a_noncoherentIQ_acquisition_caf_cc",
+ gr::io_signature::make(1, 1, sizeof(gr_complex)),
+ gr::io_signature::make(0, 0, sizeof(gr_complex)))
+{
+ d_sample_counter = 0; // SAMPLE COUNTER
+ d_active = false;
+ d_state = 0;
+ d_queue = queue;
+ d_freq = freq;
+ d_fs_in = fs_in;
+ d_samples_per_ms = samples_per_ms;
+ d_samples_per_code = samples_per_code;
+ d_max_dwells = max_dwells;
+ d_well_count = 0;
+ d_doppler_max = doppler_max;
+ d_fft_size = sampled_ms * d_samples_per_ms;
+ d_mag = 0;
+ d_input_power = 0.0;
+ d_num_doppler_bins = 0;
+ d_bit_transition_flag = bit_transition_flag;
+ d_buffer_count=0;
+ d_both_signal_components = both_signal_components_;
+// d_CAF_filter = true;
+// d_CAF_window_hz = 6000;
+ d_CAF_window_hz = CAF_window_hz_;
+
+ //todo: do something if posix_memalign fails
+ if (posix_memalign((void**)&d_inbuffer, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+ if (posix_memalign((void**)&d_fft_code_I_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+ if (posix_memalign((void**)&d_magnitudeIA, 16, d_fft_size * sizeof(float)) == 0){};
+
+ if (d_both_signal_components == true)
+ {
+ if (posix_memalign((void**)&d_fft_code_Q_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+ if (posix_memalign((void**)&d_magnitudeQA, 16, d_fft_size * sizeof(float)) == 0){};
+ }
+ // IF INTEGRATION TIME > 1
+ if (d_samples_per_ms != d_fft_size)
+ {
+ if (posix_memalign((void**)&d_fft_code_I_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+ if (posix_memalign((void**)&d_magnitudeIB, 16, d_fft_size * sizeof(float)) == 0){};
+ if (d_both_signal_components == true)
+ {
+ if (posix_memalign((void**)&d_fft_code_Q_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+ if (posix_memalign((void**)&d_magnitudeQB, 16, d_fft_size * sizeof(float)) == 0){};
+ }
+ }
+
+// if (posix_memalign((void**)&d_fft_code_Q_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+// if (posix_memalign((void**)&d_magnitudeQA, 16, d_fft_size * sizeof(float)) == 0){};
+// if (posix_memalign((void**)&d_fft_code_I_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+// if (posix_memalign((void**)&d_magnitudeIB, 16, d_fft_size * sizeof(float)) == 0){};
+// if (posix_memalign((void**)&d_fft_code_Q_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
+// if (posix_memalign((void**)&d_magnitudeQB, 16, d_fft_size * sizeof(float)) == 0){};
+
+ // Direct FFT
+ d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
+
+ // Inverse FFT
+ d_ifft = new gr::fft::fft_complex(d_fft_size, false);
+
+ // For dumping samples into a file
+ d_dump = dump;
+ d_dump_filename = dump_filename;
+}
+
+galileo_e5a_noncoherentIQ_acquisition_caf_cc::~galileo_e5a_noncoherentIQ_acquisition_caf_cc()
+{
+ if (d_num_doppler_bins > 0)
+ {
+ for (unsigned int i = 0; i < d_num_doppler_bins; i++)
+ {
+ free(d_grid_doppler_wipeoffs[i]);
+ }
+ delete[] d_grid_doppler_wipeoffs;
+ }
+
+ free(d_fft_code_I_A);
+ free(d_magnitudeIA);
+ if (d_both_signal_components == true)
+ {
+ free(d_fft_code_Q_A);
+ free(d_magnitudeQA);
+ }
+ // IF INTEGRATION TIME > 1
+ if (d_samples_per_ms != d_fft_size)
+ {
+ free(d_fft_code_I_B);
+ free(d_magnitudeIB);
+ if (d_both_signal_components == true)
+ {
+ free(d_fft_code_Q_B);
+ free(d_magnitudeQB);
+ }
+ }
+
+ delete d_fft_if;
+ delete d_ifft;
+
+
+ if (d_dump)
+ {
+ d_dump_file.close();
+ }
+}
+
+
+void galileo_e5a_noncoherentIQ_acquisition_caf_cc::set_local_code(std::complex * codeI, std::complex * codeQ )
+{
+ // DATA SIGNAL
+ // Three replicas of data primary code. CODE A: (1,1,1)
+ memcpy(d_fft_if->get_inbuf(), codeI, sizeof(gr_complex)*d_fft_size);
+
+ d_fft_if->execute(); // We need the FFT of local code
+
+ //Conjugate the local code
+ if (is_unaligned())
+ {
+ volk_32fc_conjugate_32fc_u(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ else
+ {
+ volk_32fc_conjugate_32fc_a(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ // SAME FOR PILOT SIGNAL
+ if (d_both_signal_components == true)
+ {
+ // Three replicas of pilot primary code. CODE A: (1,1,1)
+ memcpy(d_fft_if->get_inbuf(), codeQ, sizeof(gr_complex)*d_fft_size);
+
+ d_fft_if->execute(); // We need the FFT of local code
+
+ //Conjugate the local code
+ if (is_unaligned())
+ {
+ volk_32fc_conjugate_32fc_u(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ else
+ {
+ volk_32fc_conjugate_32fc_a(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ }
+ // IF INTEGRATION TIME > 1 code, we need to evaluate the other possible combination
+ // Note: max integration time allowed = 3ms (dealt in adapter)
+ if (d_samples_per_ms != d_fft_size)
+ {
+ // DATA CODE B: First replica is inverted (0,1,1)
+ volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
+ &codeI[0], gr_complex(-1,0),
+ d_samples_per_code);
+ d_fft_if->execute(); // We need the FFT of local code
+
+ //Conjugate the local code
+ if (is_unaligned())
+ {
+ volk_32fc_conjugate_32fc_u(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ else
+ {
+ volk_32fc_conjugate_32fc_a(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ if (d_both_signal_components == true)
+ {
+ // PILOT CODE B: First replica is inverted (0,1,1)
+ volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
+ &codeQ[0], gr_complex(-1,0),
+ d_samples_per_code);
+ d_fft_if->execute(); // We need the FFT of local code
+
+ //Conjugate the local code
+ if (is_unaligned())
+ {
+ volk_32fc_conjugate_32fc_u(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ else
+ {
+ volk_32fc_conjugate_32fc_a(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
+ }
+ }
+ }
+}
+
+void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init()
+{
+ d_gnss_synchro->Acq_delay_samples = 0.0;
+ d_gnss_synchro->Acq_doppler_hz = 0.0;
+ d_gnss_synchro->Acq_samplestamp_samples = 0;
+ d_mag = 0.0;
+ d_input_power = 0.0;
+
+ // Count the number of bins
+ d_num_doppler_bins = 0;
+ for (int doppler = (int)(-d_doppler_max);
+ doppler <= (int)d_doppler_max;
+ doppler += d_doppler_step)
+ {
+ d_num_doppler_bins++;
+ }
+
+ // Create the carrier Doppler wipeoff signals
+ d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
+ for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
+ {
+ if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
+ d_fft_size * sizeof(gr_complex)) == 0){};
+
+ int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
+ complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
+ d_freq + doppler, d_fs_in, d_fft_size);
+ }
+
+ /* CAF Filtering to resolve doppler ambiguity. Phase and quadrature must be processed
+ * separately before non-coherent integration */
+// if (d_CAF_filter)
+ if (d_CAF_window_hz > 0)
+ {
+ if (posix_memalign((void**)&d_CAF_vector, 16, d_num_doppler_bins * sizeof(float)) == 0){};
+ if (posix_memalign((void**)&d_CAF_vector_I, 16, d_num_doppler_bins * sizeof(float)) == 0){};
+ if (d_both_signal_components == true)
+ {
+ if (posix_memalign((void**)&d_CAF_vector_Q, 16, d_num_doppler_bins * sizeof(float)) == 0){};
+ }
+ }
+}
+
+
+int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items,
+ gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ /*
+ * By J.Arribas, L.Esteve, M.Molina and M.Sales
+ * Acquisition strategy (Kay Borre book + CFAR threshold):
+ * 1. Compute the input signal power estimation
+ * 2. Doppler serial search loop
+ * 3. Perform the FFT-based circular convolution (parallel time search)
+ * 4. OPTIONAL: CAF filter to avoid doppler ambiguity
+ * 5. Record the maximum peak and the associated synchronization parameters
+ * 6. Compute the test statistics and compare to the threshold
+ * 7. Declare positive or negative acquisition using a message queue
+ */
+
+ int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
+ /* States: 0 Stop Channel
+ * 1 Load the buffer until it reaches fft_size
+ * 2 Acquisition algorithm
+ * 3 Positive acquisition
+ * 4 Negative acquisition
+ */
+ switch (d_state)
+ {
+ case 0:
+ {
+ if (d_active)
+ {
+ //restart acquisition variables
+ d_gnss_synchro->Acq_delay_samples = 0.0;
+ d_gnss_synchro->Acq_doppler_hz = 0.0;
+ d_gnss_synchro->Acq_samplestamp_samples = 0;
+ d_well_count = 0;
+ d_mag = 0.0;
+ d_input_power = 0.0;
+ d_test_statistics = 0.0;
+ d_state = 1;
+ }
+ d_sample_counter += ninput_items[0]; // sample counter
+ consume_each(ninput_items[0]);
+
+ break;
+ }
+ case 1:
+ {
+ const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
+ unsigned int buff_increment;
+ if (ninput_items[0]+d_buffer_count <= d_fft_size)
+ {
+ buff_increment = ninput_items[0];
+ }
+ else
+ {
+ buff_increment = (d_fft_size-d_buffer_count);
+ }
+ memcpy(&d_inbuffer[d_buffer_count], in, sizeof(gr_complex)*buff_increment);
+ // If buffer will be full in next iteration
+ if (d_buffer_count >= d_fft_size-d_gr_stream_buffer)
+ {
+ d_state=2;
+ }
+ d_buffer_count += buff_increment;
+ d_sample_counter += buff_increment; // sample counter
+ consume_each(buff_increment);
+ break;
+ }
+ case 2:
+ {
+ // Fill last part of the buffer and reset counter
+ const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
+ if (d_buffer_count < d_fft_size)
+ {
+ memcpy(&d_inbuffer[d_buffer_count], in, sizeof(gr_complex)*(d_fft_size-d_buffer_count));
+ }
+ d_sample_counter += d_fft_size-d_buffer_count; // sample counter
+
+ // initialize acquisition algorithm
+ int doppler;
+ unsigned int indext = 0;
+ unsigned int indext_IA = 0;
+ unsigned int indext_IB = 0;
+ unsigned int indext_QA = 0;
+ unsigned int indext_QB = 0;
+ float magt = 0.0;
+ float magt_IA = 0.0;
+ float magt_IB = 0.0;
+ float magt_QA = 0.0;
+ float magt_QB = 0.0;
+ float fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
+ d_input_power = 0.0;
+ d_mag = 0.0;
+ d_well_count++;
+
+ DLOG(INFO) << "Channel: " << d_channel
+ << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
+ << " ,sample stamp: " << d_sample_counter << ", threshold: "
+ << d_threshold << ", doppler_max: " << d_doppler_max
+ << ", doppler_step: " << d_doppler_step;
+
+ // 1- Compute the input signal power estimation
+ volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_inbuffer, d_fft_size);
+ volk_32f_accumulator_s32f_a(&d_input_power, d_magnitudeIA, d_fft_size);
+ d_input_power /= (float)d_fft_size;
+
+ // 2- Doppler frequency search loop
+ for (unsigned int doppler_index=0;doppler_indexget_inbuf(), d_inbuffer,
+ d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
+
+ // 3- Perform the FFT-based convolution (parallel time search)
+ // Compute the FFT of the carrier wiped--off incoming signal
+ d_fft_if->execute();
+
+ // CODE IA
+ // Multiply carrier wiped--off, Fourier transformed incoming signal
+ // with the local FFT'd code reference using SIMD operations with VOLK library
+ volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
+ d_fft_if->get_outbuf(), d_fft_code_I_A, d_fft_size);
+
+ // compute the inverse FFT
+ d_ifft->execute();
+
+ // Search maximum
+ volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_ifft->get_outbuf(), d_fft_size);
+ volk_32f_index_max_16u_a(&indext_IA, d_magnitudeIA, d_fft_size);
+
+ // Normalize the maximum value to correct the scale factor introduced by FFTW
+ magt_IA = d_magnitudeIA[indext_IA] / (fft_normalization_factor * fft_normalization_factor);
+
+ if (d_both_signal_components == true)
+ {
+ // REPEAT FOR ALL CODES. CODE_QA
+ volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
+ d_fft_if->get_outbuf(), d_fft_code_Q_A, d_fft_size);
+ d_ifft->execute();
+ volk_32fc_magnitude_squared_32f_a(d_magnitudeQA, d_ifft->get_outbuf(), d_fft_size);
+ volk_32f_index_max_16u_a(&indext_QA, d_magnitudeQA, d_fft_size);
+ magt_QA = d_magnitudeQA[indext_QA] / (fft_normalization_factor * fft_normalization_factor);
+ }
+ if (d_samples_per_ms != d_fft_size) // If Integration time > 1 code
+ {
+ // REPEAT FOR ALL CODES. CODE_IB
+ volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
+ d_fft_if->get_outbuf(), d_fft_code_I_B, d_fft_size);
+ d_ifft->execute();
+ volk_32fc_magnitude_squared_32f_a(d_magnitudeIB, d_ifft->get_outbuf(), d_fft_size);
+ volk_32f_index_max_16u_a(&indext_IB, d_magnitudeIB, d_fft_size);
+ magt_IB = d_magnitudeIB[indext_IB] / (fft_normalization_factor * fft_normalization_factor);
+
+ if (d_both_signal_components == true)
+ {
+ // REPEAT FOR ALL CODES. CODE_QB
+ volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
+ d_fft_if->get_outbuf(), d_fft_code_Q_B, d_fft_size);
+ d_ifft->execute();
+ volk_32fc_magnitude_squared_32f_a(d_magnitudeQB, d_ifft->get_outbuf(), d_fft_size);
+ volk_32f_index_max_16u_a(&indext_QB, d_magnitudeQB, d_fft_size);
+ magt_QB = d_magnitudeIB[indext_QB] / (fft_normalization_factor * fft_normalization_factor);
+ }
+ }
+
+ // Integrate noncoherently the two best combinations (I² + Q²)
+ // and store the result in the I channel.
+ // If CAF filter to resolve doppler ambiguity is needed,
+ // peak is stored before non-coherent integration.
+ if (d_samples_per_ms != d_fft_size) // T_integration > 1 code
+ {
+ if (magt_IA >= magt_IB)
+ {
+// if (d_CAF_filter) {d_CAF_vector_I[doppler_index] = magt_IA;}
+ if (d_CAF_window_hz > 0) {d_CAF_vector_I[doppler_index] = d_magnitudeIA[indext_IA];}
+ if (d_both_signal_components)
+ {
+ // Integrate non-coherently I+Q
+ if (magt_QA >= magt_QB)
+ {
+// if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QA;}
+ if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQA[indext_QA];}
+ for (unsigned int i=0; i 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQB[indext_QB];}
+ for (unsigned int i=0; i 0) {d_CAF_vector_I[doppler_index] = d_magnitudeIB[indext_IB];}
+ if (d_both_signal_components)
+ {
+ // Integrate non-coherently I+Q
+ if (magt_QA >= magt_QB)
+ {
+ //if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QA;}
+ if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQA[indext_QA];}
+ for (unsigned int i=0; i 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQB[indext_QB];}
+ for (unsigned int i=0; i 0) {d_CAF_vector_I[doppler_index] = d_magnitudeIA[indext_IA];}
+ if (d_both_signal_components)
+ {
+// if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QA;}
+ if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQA[indext_QA];}
+ // NON-Coherent integration of only 1 code
+ for (unsigned int i=0; iAcq_delay_samples = (double)(indext % d_samples_per_code);
+ d_gnss_synchro->Acq_doppler_hz = (double)doppler;
+ d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
+
+ // 5- Compute the test statistics and compare to the threshold
+ d_test_statistics = d_mag / d_input_power;
+ }
+ }
+
+ // Record results to file if required
+ if (d_dump)
+ {
+ std::stringstream filename;
+ std::streamsize n = sizeof(float) * (d_fft_size); // noncomplex file write
+ filename.str("");
+ filename << "../data/test_statistics_E5a_sat_"
+ << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
+ d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
+ if (d_samples_per_ms != d_fft_size) // If integration time > 1 code
+ {
+ if (magt_IA >= magt_IB)
+ {
+ d_dump_file.write((char*)d_magnitudeIA, n);
+ }
+ else
+ {
+ d_dump_file.write((char*)d_magnitudeIB, n);
+ }
+ }
+ else
+ {
+ d_dump_file.write((char*)d_magnitudeIA, n);
+ }
+ d_dump_file.close();
+ }
+ }
+ std::cout << "d_mag " << d_mag << ".d_sample_counter " << d_sample_counter << std::endl;
+ // 6 OPTIONAL: CAF filter to avoid Doppler ambiguity in bit transition.
+ if (d_CAF_window_hz > 0)
+ {
+ int CAF_bins_half;
+ float* accum;
+// double* accum;
+ if (posix_memalign((void**)&accum, 16, sizeof(float)) == 0){};
+ CAF_bins_half = d_CAF_window_hz/(2*d_doppler_step);
+ std::cout << "CAF_bins_half " << CAF_bins_half << std::endl;
+ // Initialize first iterations
+ for (int doppler_index=0;doppler_indexAcq_doppler_hz = (double)doppler;
+ // Dump if required, appended at the end of the file
+ if (d_dump)
+ {
+ std::stringstream filename;
+ std::streamsize n = sizeof(float) * (d_num_doppler_bins); // noncomplex file write
+ filename.str("");
+ filename << "../data/test_statistics_E5a_sat_"
+ << d_gnss_synchro->PRN << "_CAF.dat";
+ d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
+ d_dump_file.write((char*)d_CAF_vector, n);
+ d_dump_file.close();
+ }
+ }
+
+ if (d_well_count == d_max_dwells)
+ {
+ if (d_test_statistics > d_threshold)
+ {
+ d_state = 3; // Positive acquisition
+ }
+ else
+ {
+ d_state = 4; // Negative acquisition
+ }
+ }
+ else
+ {
+ d_state = 1;
+ }
+
+ consume_each(d_fft_size-d_buffer_count);
+ d_buffer_count = 0;
+ break;
+ }
+ case 3:
+ {
+ // 7.1- Declare positive acquisition using a message queue
+ DLOG(INFO) << "positive acquisition";
+ DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
+ DLOG(INFO) << "sample_stamp " << d_sample_counter;
+ DLOG(INFO) << "test statistics value " << d_test_statistics;
+ DLOG(INFO) << "test statistics threshold " << d_threshold;
+ DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
+ DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
+ DLOG(INFO) << "magnitude " << d_mag;
+ DLOG(INFO) << "input signal power " << d_input_power;
+
+ d_active = false;
+ d_state = 0;
+
+
+ acquisition_message = 1;
+ d_channel_internal_queue->push(acquisition_message);
+ d_sample_counter += ninput_items[0]; // sample counter
+ consume_each(ninput_items[0]);
+ break;
+ }
+ case 4:
+ {
+ // 7.2- Declare negative acquisition using a message queue
+ DLOG(INFO) << "negative acquisition";
+ DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
+ DLOG(INFO) << "sample_stamp " << d_sample_counter;
+ DLOG(INFO) << "test statistics value " << d_test_statistics;
+ DLOG(INFO) << "test statistics threshold " << d_threshold;
+ DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
+ DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
+ DLOG(INFO) << "magnitude " << d_mag;
+ DLOG(INFO) << "input signal power " << d_input_power;
+
+ d_active = false;
+ d_state = 0;
+
+ d_sample_counter += ninput_items[0]; // sample counter
+ consume_each(ninput_items[0]);
+ acquisition_message = 2;
+ d_channel_internal_queue->push(acquisition_message);
+ break;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_3ms_noncoherent_iq_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.h
similarity index 79%
rename from src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_3ms_noncoherent_iq_acquisition_cc.h
rename to src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.h
index 11506f2ea..4b97831d6 100644
--- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_3ms_noncoherent_iq_acquisition_cc.h
+++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.h
@@ -1,8 +1,14 @@
/*!
- * \file galileo_e5a_3ms_noncoherent_iq_acquisition_cc.h
+ * \file galileo_e5a_noncoherent_iq_acquisition_caf_cc.h
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E5a data and pilot Signals
* \author Marc Sales, 2014. marcsales92(at)gmail.com
+ * \based on work from:
+ *
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena@gmail.com
+ *
*
* -------------------------------------------------------------------------
*
@@ -29,8 +35,8 @@
* -------------------------------------------------------------------------
*/
-#ifndef GALILEO_E5A_3MS_NONCOHERENT_IQ_ACQUISITION_CC_H_
-#define GALILEO_E5A_3MS_NONCOHERENT_IQ_ACQUISITION_CC_H_
+#ifndef GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_
+#define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_
#include
#include
@@ -44,18 +50,20 @@
#include "concurrent_queue.h"
#include "gnss_synchro.h"
-class galileo_e5a_3ms_noncoherentIQ_acquisition_cc;
+class galileo_e5a_noncoherentIQ_acquisition_caf_cc;
-typedef boost::shared_ptr galileo_e5a_3ms_noncoherentIQ_acquisition_cc_sptr;
+typedef boost::shared_ptr galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr;
-galileo_e5a_3ms_noncoherentIQ_acquisition_cc_sptr
-galileo_e5a_3ms_noncoherentIQ_make_acquisition_cc(unsigned int sampled_ms,
+galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr
+galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(unsigned int sampled_ms,
unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag,
gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
+ std::string dump_filename,
+ bool both_signal_components_,
+ int CAF_window_hz_);
/*!
* \brief This class implements a Parallel Code Phase Search Acquisition.
@@ -63,27 +71,31 @@ galileo_e5a_3ms_noncoherentIQ_make_acquisition_cc(unsigned int sampled_ms,
* Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
* Algorithm 1, for a pseudocode description of this implementation.
*/
-class galileo_e5a_3ms_noncoherentIQ_acquisition_cc: public gr::block
+class galileo_e5a_noncoherentIQ_acquisition_caf_cc: public gr::block
{
private:
- friend galileo_e5a_3ms_noncoherentIQ_acquisition_cc_sptr
- galileo_e5a_3ms_noncoherentIQ_make_acquisition_cc(
+ friend galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr
+ galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
unsigned int sampled_ms,
unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag,
gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
+ std::string dump_filename,
+ bool both_signal_components_,
+ int CAF_window_hz_);
- galileo_e5a_3ms_noncoherentIQ_acquisition_cc(
+ galileo_e5a_noncoherentIQ_acquisition_caf_cc(
unsigned int sampled_ms,
unsigned int max_dwells,
unsigned int doppler_max, long freq, long fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag,
gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
+ std::string dump_filename,
+ bool both_signal_components_,
+ int CAF_window_hz_);
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
int doppler_offset);
@@ -128,6 +140,15 @@ private:
bool d_active;
int d_state;
bool d_dump;
+ bool d_both_signal_components;
+// bool d_CAF_filter;
+ int d_CAF_window_hz;
+ float* d_CAF_vector;
+ float* d_CAF_vector_I;
+ float* d_CAF_vector_Q;
+// double* d_CAF_vector;
+// double* d_CAF_vector_I;
+// double* d_CAF_vector_Q;
unsigned int d_channel;
std::string d_dump_filename;
unsigned int d_buffer_count;
@@ -137,7 +158,7 @@ public:
/*!
* \brief Default destructor.
*/
- ~galileo_e5a_3ms_noncoherentIQ_acquisition_cc();
+ ~galileo_e5a_noncoherentIQ_acquisition_caf_cc();
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
@@ -232,6 +253,5 @@ public:
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
- void forecast (int noutput_items, gr_vector_int &ninput_items_required);
};
-#endif /* GALILEO_E5A_3MS_NONCOHERENT_IQ_ACQUISITION_CC_H_ */
+#endif /* GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_ */
diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_pilot_3ms_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_pilot_3ms_acquisition_cc.cc
deleted file mode 100644
index 254d2a7dd..000000000
--- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_pilot_3ms_acquisition_cc.cc
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * galileo_e5a_pilot_3ms_acquisition_cc.cc
- *
- * Created on: Jun 22, 2014
- * Author: marc
- */
-
-#include "galileo_e5a_pilot_3ms_acquisition_cc.h"
-#include
-#include
-#include
-#include
-#include
-#include "gnss_signal_processing.h"
-#include "control_message_factory.h"
-
-using google::LogMessage;
-
-galileo_e5a_pilot_3ms_acquisition_cc_sptr galileo_e5a_pilot_3ms_make_acquisition_cc(
- unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename)
-{
-
- return galileo_e5a_pilot_3ms_acquisition_cc_sptr(
- new galileo_e5a_pilot_3ms_acquisition_cc(max_dwells, doppler_max, freq, fs_in, samples_per_ms,
- samples_per_code, bit_transition_flag, queue, dump, dump_filename));
-}
-
-galileo_e5a_pilot_3ms_acquisition_cc::galileo_e5a_pilot_3ms_acquisition_cc(
- unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename) :
- gr::block("galileo_e5a_pilot_3ms_acquisition_cc",
- gr::io_signature::make(1, 1, sizeof(gr_complex) * 3 * samples_per_ms),
- gr::io_signature::make(0, 0, sizeof(gr_complex) * 3 * samples_per_ms))
-{
- //this->set_relative_rate(1.0/3*samples_per_ms);
- d_sample_counter = 0; // SAMPLE COUNTER
- d_active = false;
- d_state = 0;
- d_queue = queue;
- d_freq = freq;
- d_fs_in = fs_in;
- d_samples_per_ms = samples_per_ms;
- d_samples_per_code = samples_per_code;
- d_max_dwells = max_dwells;
- d_well_count = 0;
- d_doppler_max = doppler_max;
- d_fft_size = 3 * d_samples_per_ms;
- d_mag = 0;
- d_input_power = 0.0;
- d_num_doppler_bins = 0;
- d_bit_transition_flag = bit_transition_flag;
-
- //todo: do something if posix_memalign fails
- if (posix_memalign((void**)&d_fft_code_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_C, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_D, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
-
- // Direct FFT
- d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
-
- // Inverse FFT
- d_ifft = new gr::fft::fft_complex(d_fft_size, false);
-// d_ifft = new gr::fft::fft_complex(d_fft_size, true);
-
- // For dumping samples into a file
- d_dump = dump;
- d_dump_filename = dump_filename;
-}
-
-galileo_e5a_pilot_3ms_acquisition_cc::~galileo_e5a_pilot_3ms_acquisition_cc()
-{
- if (d_num_doppler_bins > 0)
- {
- for (unsigned int i = 0; i < d_num_doppler_bins; i++)
- {
- free(d_grid_doppler_wipeoffs[i]);
- }
- delete[] d_grid_doppler_wipeoffs;
- }
-
- free(d_fft_code_A);
- free(d_fft_code_B);
- free(d_fft_code_C);
- free(d_fft_code_D);
- free(d_magnitude);
-
- delete d_ifft;
- delete d_fft_if;
-
- if (d_dump)
- {
- d_dump_file.close();
- }
-}
-
-void galileo_e5a_pilot_3ms_acquisition_cc::set_local_code(std::complex * code)
-{
- // Three replicas of pilot primary code. CODE A: (1,1,1)
- memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size);
-
- d_fft_if->execute(); // We need the FFT of local code
-
- //Conjugate the local code
- if (is_unaligned())
- {
- volk_32fc_conjugate_32fc_u(d_fft_code_A,d_fft_if->get_outbuf(),d_fft_size);
- }
- else
- {
- volk_32fc_conjugate_32fc_a(d_fft_code_A,d_fft_if->get_outbuf(),d_fft_size);
- }
- // CODE B: First replica is inverted (0,1,1)
- volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
- &code[0], gr_complex(-1,0),
- d_samples_per_code);
- d_fft_if->execute(); // We need the FFT of local code
-
- //Conjugate the local code
- if (is_unaligned())
- {
- volk_32fc_conjugate_32fc_u(d_fft_code_B,d_fft_if->get_outbuf(),d_fft_size);
- }
- else
- {
- volk_32fc_conjugate_32fc_a(d_fft_code_B,d_fft_if->get_outbuf(),d_fft_size);
- }
-}
-
-void galileo_e5a_pilot_3ms_acquisition_cc::init()
-{
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_mag = 0.0;
- d_input_power = 0.0;
-
- // Count the number of bins
- d_num_doppler_bins = 0;
- for (int doppler = (int)(-d_doppler_max);
- doppler <= (int)d_doppler_max;
- doppler += d_doppler_step)
- {
- d_num_doppler_bins++;
- }
-
- // Create the carrier Doppler wipeoff signals
- d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
- for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
- {
- if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
- d_fft_size * sizeof(gr_complex)) == 0){};
-
- int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
- complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
- d_freq + doppler, d_fs_in, d_fft_size);
- }
-}
-
-int galileo_e5a_pilot_3ms_acquisition_cc::general_work(int noutput_items,
- gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- /*
- * By J.Arribas, L.Esteve and M.Molina
- * Acquisition strategy (Kay Borre book + CFAR threshold):
- * 1. Compute the input signal power estimation
- * 2. Doppler serial search loop
- * 3. Perform the FFT-based circular convolution (parallel time search)
- * 4. Record the maximum peak and the associated synchronization parameters
- * 5. Compute the test statistics and compare to the threshold
- * 6. Declare positive or negative acquisition using a message queue
- */
-
- int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
-
- switch (d_state)
- {
- case 0:
- {
- if (d_active)
- {
- //restart acquisition variables
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_well_count = 0;
- d_mag = 0.0;
- d_input_power = 0.0;
- d_test_statistics = 0.0;
-
- d_state = 1;
- }
-
- d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- consume_each(ninput_items[0]);
-
- break;
- }
-
- case 1:
- {
- // initialize acquisition algorithm
- int doppler;
- unsigned int indext = 0;
- unsigned int indext_A = 0;
- unsigned int indext_B = 0;
- float magt = 0.0;
- float magt_A = 0.0;
- float magt_B = 0.0;
- unsigned int sec_comb = 0; // secondary combination 0=(111), 1=(011)
- const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
- float fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
- d_input_power = 0.0;
- d_mag = 0.0;
-
- d_sample_counter += d_fft_size; // sample counter
-
- d_well_count++;
-
- DLOG(INFO) << "Channel: " << d_channel
- << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
- << " ,sample stamp: " << d_sample_counter << ", threshold: "
- << d_threshold << ", doppler_max: " << d_doppler_max
- << ", doppler_step: " << d_doppler_step;
-
- // 1- Compute the input signal power estimation
- volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
- volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
- d_input_power /= (float)d_fft_size;
-
- // 2- Doppler frequency search loop
- for (unsigned int doppler_index=0;doppler_indexget_inbuf(), in,
- d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
-
- // 3- Perform the FFT-based convolution (parallel time search)
- // Compute the FFT of the carrier wiped--off incoming signal
- d_fft_if->execute();
-
- // Multiply carrier wiped--off, Fourier transformed incoming signal
- // with the local FFT'd code reference using SIMD operations with VOLK library
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_A, d_fft_size);
-
- // compute the inverse FFT
- d_ifft->execute();
-
- // Search maximum
- volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_A, d_magnitude, d_fft_size);
-
- // Normalize the maximum value to correct the scale factor introduced by FFTW
- magt_A = d_magnitude[indext_A] / (fft_normalization_factor * fft_normalization_factor);
-
- // REPEAT FOR ALL CODES. CODE_B
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_B, d_fft_size);
- d_ifft->execute();
- volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_B, d_magnitude, d_fft_size);
- magt_B = d_magnitude[indext_B] / (fft_normalization_factor * fft_normalization_factor);
-
- //Choose the best correlation
- if (magt_A >= magt_B)
- {
- magt = magt_A;
- indext = indext_A;
- sec_comb = 0;
- }
- else
- {
- magt = magt_B;
- indext = indext_B;
- sec_comb = 1;
- }
- // 4- record the maximum peak and the associated synchronization parameters
- if (d_mag < magt)
- {
- d_mag = magt;
- std::cout << "ACQ_block_e5a_3ms secondary combination " << sec_comb << std::endl;
-
- // In case that d_bit_transition_flag = true, we compare the potentially
- // new maximum test statistics (d_mag/d_input_power) with the value in
- // d_test_statistics. When the second dwell is being processed, the value
- // of d_mag/d_input_power could be lower than d_test_statistics (i.e,
- // the maximum test statistics in the previous dwell is greater than
- // current d_mag/d_input_power). Note that d_test_statistics is not
- // restarted between consecutive dwells in multidwell operation.
- if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag)
- {
- d_gnss_synchro->Acq_delay_samples = (double)(indext % d_samples_per_code);
- d_gnss_synchro->Acq_doppler_hz = (double)doppler;
- d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
-
- // 5- Compute the test statistics and compare to the threshold
- //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
- d_test_statistics = d_mag / d_input_power;
- }
- }
-
- // Record results to file if required
- if (d_dump)
- {
- std::stringstream filename;
- std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
- filename.str("");
- filename << "../data/test_statistics_" << d_gnss_synchro->System
- <<"_" << d_gnss_synchro->Signal << "_sat_"
- << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
- d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
- d_dump_file.write((char*)d_ifft->get_outbuf(), n); //write directly |abs(x)|^2 in this Doppler bin?
- d_dump_file.close();
- }
- }
-
- if (!d_bit_transition_flag)
- {
- if (d_test_statistics > d_threshold)
- {
- d_state = 2; // Positive acquisition
- }
- else if (d_well_count == d_max_dwells)
- {
- d_state = 3; // Negative acquisition
- }
- }
- else
- {
- if (d_well_count == d_max_dwells) // d_max_dwells = 2
- {
- if (d_test_statistics > d_threshold)
- {
- d_state = 2; // Positive acquisition
- }
- else
- {
- d_state = 3; // Negative acquisition
- }
- }
- }
-
- consume_each(1);
-
- break;
- }
-
- case 2:
- {
- // 6.1- Declare positive acquisition using a message queue
- DLOG(INFO) << "positive acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << d_test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << d_input_power;
-
- d_active = false;
- d_state = 0;
-
- d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- consume_each(ninput_items[0]);
-
- acquisition_message = 1;
- d_channel_internal_queue->push(acquisition_message);
-
- break;
- }
-
- case 3:
- {
- // 6.2- Declare negative acquisition using a message queue
- DLOG(INFO) << "negative acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << d_test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << d_input_power;
-
- d_active = false;
- d_state = 0;
-
- d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- consume_each(ninput_items[0]);
-
- acquisition_message = 2;
- d_channel_internal_queue->push(acquisition_message);
-
- break;
- }
- }
-
- return 0;
-}
diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_pilot_3ms_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_pilot_3ms_acquisition_cc.h
deleted file mode 100644
index 632a24b08..000000000
--- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_pilot_3ms_acquisition_cc.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * galileo_e5a_pilot_3ms_acquisition_cc.h
- *
- * Created on: Jun 22, 2014
- * Author: marc
- */
-
-#ifndef GALILEO_E5A_PILOT_3MS_ACQUISITION_CC_H_
-#define GALILEO_E5A_PILOT_3MS_ACQUISITION_CC_H_
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "concurrent_queue.h"
-#include "gnss_synchro.h"
-
-class galileo_e5a_pilot_3ms_acquisition_cc;
-
-typedef boost::shared_ptr galileo_e5a_pilot_3ms_acquisition_cc_sptr;
-
-galileo_e5a_pilot_3ms_acquisition_cc_sptr
-galileo_e5a_pilot_3ms_make_acquisition_cc(unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
-
-/*!
- * \brief This class implements a Parallel Code Phase Search Acquisition.
- *
- * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
- * Algorithm 1, for a pseudocode description of this implementation.
- */
-class galileo_e5a_pilot_3ms_acquisition_cc: public gr::block
-{
-private:
- friend galileo_e5a_pilot_3ms_acquisition_cc_sptr
- galileo_e5a_pilot_3ms_make_acquisition_cc(unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
-
- galileo_e5a_pilot_3ms_acquisition_cc(unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
-
- void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
- int doppler_offset);
-
- long d_fs_in;
- long d_freq;
- int d_samples_per_ms;
- int d_samples_per_code;
- unsigned int d_doppler_resolution;
- float d_threshold;
- std::string d_satellite_str;
- unsigned int d_doppler_max;
- unsigned int d_doppler_step;
- unsigned int d_max_dwells;
- unsigned int d_well_count;
- unsigned int d_fft_size;
- unsigned long int d_sample_counter;
- gr_complex** d_grid_doppler_wipeoffs;
- unsigned int d_num_doppler_bins;
- gr_complex* d_fft_code_A;
- gr_complex* d_fft_code_B;
- gr_complex* d_fft_code_C;
- gr_complex* d_fft_code_D;
- gr::fft::fft_complex* d_fft_if;
- gr::fft::fft_complex* d_ifft;
- Gnss_Synchro *d_gnss_synchro;
- unsigned int d_code_phase;
- float d_doppler_freq;
- float d_mag;
- float* d_magnitude;
- float d_input_power;
- float d_test_statistics;
- bool d_bit_transition_flag;
- gr::msg_queue::sptr d_queue;
- concurrent_queue *d_channel_internal_queue;
- std::ofstream d_dump_file;
- bool d_active;
- int d_state;
- bool d_dump;
- unsigned int d_channel;
- std::string d_dump_filename;
-
-public:
- /*!
- * \brief Default destructor.
- */
- ~galileo_e5a_pilot_3ms_acquisition_cc();
-
- /*!
- * \brief Set acquisition/tracking common Gnss_Synchro object pointer
- * to exchange synchronization data between acquisition and tracking blocks.
- * \param p_gnss_synchro Satellite information shared by the processing blocks.
- */
- void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
- {
- d_gnss_synchro = p_gnss_synchro;
- }
-
- /*!
- * \brief Returns the maximum peak of grid search.
- */
- unsigned int mag()
- {
- return d_mag;
- }
-
- /*!
- * \brief Initializes acquisition algorithm.
- */
- void init();
-
- /*!
- * \brief Sets local code for PCPS acquisition algorithm.
- * \param code - Pointer to the PRN code.
- */
- void set_local_code(std::complex * code);
-
- /*!
- * \brief Starts acquisition algorithm, turning from standby mode to
- * active mode
- * \param active - bool that activates/deactivates the block.
- */
- void set_active(bool active)
- {
- d_active = active;
- }
-
- /*!
- * \brief Set acquisition channel unique ID
- * \param channel - receiver channel.
- */
- void set_channel(unsigned int channel)
- {
- d_channel = channel;
- }
-
- /*!
- * \brief Set statistics threshold of PCPS algorithm.
- * \param threshold - Threshold for signal detection (check \ref Navitec2012,
- * Algorithm 1, for a definition of this threshold).
- */
- void set_threshold(float threshold)
- {
- d_threshold = threshold;
- }
-
- /*!
- * \brief Set maximum Doppler grid search
- * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
- */
- void set_doppler_max(unsigned int doppler_max)
- {
- d_doppler_max = doppler_max;
- }
-
- /*!
- * \brief Set Doppler steps for the grid search
- * \param doppler_step - Frequency bin of the search grid [Hz].
- */
- void set_doppler_step(unsigned int doppler_step)
- {
- d_doppler_step = doppler_step;
- }
-
-
- /*!
- * \brief Set tracking channel internal queue.
- * \param channel_internal_queue - Channel's internal blocks information queue.
- */
- void set_channel_queue(concurrent_queue *channel_internal_queue)
- {
- d_channel_internal_queue = channel_internal_queue;
- }
-
- /*!
- * \brief Parallel Code Phase Search Acquisition signal processing.
- */
- int general_work(int noutput_items, gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* GALILEO_E5A_PILOT_3MS_ACQUISITION_CC_H_ */
diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5ax_2ms_pcps_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5ax_2ms_pcps_acquisition_cc.cc
deleted file mode 100644
index 30bbb6dac..000000000
--- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5ax_2ms_pcps_acquisition_cc.cc
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * galileo_e5ax_1ms_pcps_acquisition_cc.cc
- *
- * Created on: Jun 23, 2014
- * Author: marc
- */
-
-#include "galileo_e5ax_2ms_pcps_acquisition_cc.h"
-
-#include
-#include
-#include
-#include
-#include
-#include "gnss_signal_processing.h"
-#include "control_message_factory.h"
-
-using google::LogMessage;
-
-galileo_e5ax_2ms_pcps_acquisition_cc_sptr galileo_e5ax_2ms_pcps_make_acquisition_cc(
- unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename)
-{
-
- return galileo_e5ax_2ms_pcps_acquisition_cc_sptr(
- new galileo_e5ax_2ms_pcps_acquisition_cc(max_dwells, doppler_max, freq, fs_in, samples_per_ms,
- samples_per_code, bit_transition_flag, queue, dump, dump_filename));
-}
-
-galileo_e5ax_2ms_pcps_acquisition_cc::galileo_e5ax_2ms_pcps_acquisition_cc(
- unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename) :
- gr::block("galileo_e5ax_2ms_pcps_acquisition_cc",
- gr::io_signature::make(1, 1, sizeof(gr_complex) * 2 * samples_per_ms),
- gr::io_signature::make(0, 0, sizeof(gr_complex) * 2 * samples_per_ms))
-{
- //this->set_relative_rate(1.0/3*samples_per_ms);
- d_sample_counter = 0; // SAMPLE COUNTER
- d_active = false;
- d_state = 0;
- d_queue = queue;
- d_freq = freq;
- d_fs_in = fs_in;
- d_samples_per_ms = samples_per_ms;
- d_samples_per_code = samples_per_code;
- d_max_dwells = max_dwells;
- d_well_count = 0;
- d_doppler_max = doppler_max;
- d_fft_size = 2 * d_samples_per_ms;
- d_mag = 0;
- d_input_power = 0.0;
- d_num_doppler_bins = 0;
- //always bit transition in e5
- //d_bit_transition_flag = bit_transition_flag;
-
- //todo: do something if posix_memalign fails
- if (posix_memalign((void**)&d_fft_code_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_fft_code_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
-
- // Direct FFT
- d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
-
- // Inverse FFT
- d_ifft = new gr::fft::fft_complex(d_fft_size, false);
-
- // For dumping samples into a file
- d_dump = dump;
- d_dump_filename = dump_filename;
-}
-
-galileo_e5ax_2ms_pcps_acquisition_cc::~galileo_e5ax_2ms_pcps_acquisition_cc()
-{
- if (d_num_doppler_bins > 0)
- {
- for (unsigned int i = 0; i < d_num_doppler_bins; i++)
- {
- free(d_grid_doppler_wipeoffs[i]);
- }
- delete[] d_grid_doppler_wipeoffs;
- }
-
- free(d_fft_code_A);
- free(d_fft_code_B);
- free(d_magnitude);
-
- delete d_ifft;
- delete d_fft_if;
-
- if (d_dump)
- {
- d_dump_file.close();
- }
-}
-
-void galileo_e5ax_2ms_pcps_acquisition_cc::set_local_code(std::complex * code)
-{
- // Three replicas of pilot primary code. CODE A: (1,1)
- memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size);
-
- d_fft_if->execute(); // We need the FFT of local code
-
- //Conjugate the local code
- if (is_unaligned())
- {
- volk_32fc_conjugate_32fc_u(d_fft_code_A,d_fft_if->get_outbuf(),d_fft_size);
- // CODE B: First replica is inverted (0,1) by conjugating the code (I - Qi)
- volk_32fc_conjugate_32fc_u(d_fft_if->get_inbuf(),code,d_fft_size);
- d_fft_if->execute(); // We need the FFT of local code
- volk_32fc_conjugate_32fc_u(d_fft_code_B,d_fft_if->get_outbuf(),d_fft_size);
- }
- else
- {
- volk_32fc_conjugate_32fc_a(d_fft_code_A,d_fft_if->get_outbuf(),d_fft_size);
- // CODE B: First replica is inverted (0,1) by conjugating the code (I - Qi)
- volk_32fc_conjugate_32fc_a(d_fft_if->get_inbuf(),code,d_fft_size);
- d_fft_if->execute(); // We need the FFT of local code
- volk_32fc_conjugate_32fc_a(d_fft_code_B,d_fft_if->get_outbuf(),d_fft_size);
- }
-}
-
-void galileo_e5ax_2ms_pcps_acquisition_cc::init()
-{
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_mag = 0.0;
- d_input_power = 0.0;
-
- // Count the number of bins
- d_num_doppler_bins = 0;
- for (int doppler = (int)(-d_doppler_max);
- doppler <= (int)d_doppler_max;
- doppler += d_doppler_step)
- {
- d_num_doppler_bins++;
- }
-
- // Create the carrier Doppler wipeoff signals
- d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
- for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
- {
- if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
- d_fft_size * sizeof(gr_complex)) == 0){};
-
- int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
- complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
- d_freq + doppler, d_fs_in, d_fft_size);
- }
-}
-
-int galileo_e5ax_2ms_pcps_acquisition_cc::general_work(int noutput_items,
- gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- /*
- * By J.Arribas, L.Esteve and M.Molina
- * Acquisition strategy (Kay Borre book + CFAR threshold):
- * 1. Compute the input signal power estimation
- * 2. Doppler serial search loop
- * 3. Perform the FFT-based circular convolution (parallel time search)
- * 4. Record the maximum peak and the associated synchronization parameters
- * 5. Compute the test statistics and compare to the threshold
- * 6. Declare positive or negative acquisition using a message queue
- */
-
- int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
-
- switch (d_state)
- {
- case 0:
- {
- if (d_active)
- {
- //restart acquisition variables
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_well_count = 0;
- d_mag = 0.0;
- d_input_power = 0.0;
- d_test_statistics = 0.0;
-
- d_state = 1;
- }
-
- d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- consume_each(ninput_items[0]);
-
- break;
- }
-
- case 1:
- {
- // initialize acquisition algorithm
- int doppler;
- unsigned int indext = 0;
- unsigned int indext_A = 0;
- unsigned int indext_B = 0;
- float magt = 0.0;
- float magt_A = 0.0;
- float magt_B = 0.0;
- const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
- float fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
- d_input_power = 0.0;
- d_mag = 0.0;
-
- d_sample_counter += d_fft_size; // sample counter
-
- d_well_count++;
-
- DLOG(INFO) << "Channel: " << d_channel
- << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
- << " ,sample stamp: " << d_sample_counter << ", threshold: "
- << d_threshold << ", doppler_max: " << d_doppler_max
- << ", doppler_step: " << d_doppler_step;
-
- // 1- Compute the input signal power estimation
- volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
- volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
- d_input_power /= (float)d_fft_size;
-
- // 2- Doppler frequency search loop
- for (unsigned int doppler_index=0;doppler_indexget_inbuf(), in,
- d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
-
- // 3- Perform the FFT-based convolution (parallel time search)
- // Compute the FFT of the carrier wiped--off incoming signal
- d_fft_if->execute();
-
- // Multiply carrier wiped--off, Fourier transformed incoming signal
- // with the local FFT'd code reference using SIMD operations with VOLK library
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_A, d_fft_size);
-
- // compute the inverse FFT
- d_ifft->execute();
-
- // Search maximum
- volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_A, d_magnitude, d_fft_size);
-
- // Normalize the maximum value to correct the scale factor introduced by FFTW
- magt_A = d_magnitude[indext_A] / (fft_normalization_factor * fft_normalization_factor);
-
- // REPEAT FOR CODE_B
- volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
- d_fft_if->get_outbuf(), d_fft_code_B, d_fft_size);
- d_ifft->execute();
- volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
- volk_32f_index_max_16u_a(&indext_B, d_magnitude, d_fft_size);
- magt_B = d_magnitude[indext_B] / (fft_normalization_factor * fft_normalization_factor);
-
- //Choose the best correlation
- if (magt_A >= magt_B)
- {
- magt = magt_A;
- indext = indext_A;
- }
- else
- {
- magt = magt_B;
- indext = indext_B;
- }
- // 4- record the maximum peak and the associated synchronization parameters
- if (d_mag < magt)
- {
- d_mag = magt;
-
-
- // In case that d_bit_transition_flag = true, we compare the potentially
- // new maximum test statistics (d_mag/d_input_power) with the value in
- // d_test_statistics. When the second dwell is being processed, the value
- // of d_mag/d_input_power could be lower than d_test_statistics (i.e,
- // the maximum test statistics in the previous dwell is greater than
- // current d_mag/d_input_power). Note that d_test_statistics is not
- // restarted between consecutive dwells in multidwell operation.
- if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag)
- {
- d_gnss_synchro->Acq_delay_samples = (double)(indext % d_samples_per_code);
- d_gnss_synchro->Acq_doppler_hz = (double)doppler;
- d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
-
- // 5- Compute the test statistics and compare to the threshold
- //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
- d_test_statistics = d_mag / d_input_power;
- }
- }
-
- // Record results to file if required
- if (d_dump)
- {
- std::stringstream filename;
- std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
- filename.str("");
- filename << "../data/test_statistics_" << d_gnss_synchro->System
- <<"_" << d_gnss_synchro->Signal << "_sat_"
- << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
- d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
- d_dump_file.write((char*)d_ifft->get_outbuf(), n); //write directly |abs(x)|^2 in this Doppler bin?
- d_dump_file.close();
- }
- }
-
- if (!d_bit_transition_flag)
- {
- if (d_test_statistics > d_threshold)
- {
- d_state = 2; // Positive acquisition
- }
- else if (d_well_count == d_max_dwells)
- {
- d_state = 3; // Negative acquisition
- }
- }
- else
- {
- if (d_well_count == d_max_dwells) // d_max_dwells = 2
- {
- if (d_test_statistics > d_threshold)
- {
- d_state = 2; // Positive acquisition
- }
- else
- {
- d_state = 3; // Negative acquisition
- }
- }
- }
-
- consume_each(1);
-
- break;
- }
-
- case 2:
- {
- // 6.1- Declare positive acquisition using a message queue
- DLOG(INFO) << "positive acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << d_test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << d_input_power;
-
- d_active = false;
- d_state = 0;
-
- d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- consume_each(ninput_items[0]);
-
- acquisition_message = 1;
- d_channel_internal_queue->push(acquisition_message);
-
- break;
- }
-
- case 3:
- {
- // 6.2- Declare negative acquisition using a message queue
- DLOG(INFO) << "negative acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << d_test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << d_input_power;
-
- d_active = false;
- d_state = 0;
-
- d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
- consume_each(ninput_items[0]);
-
- acquisition_message = 2;
- d_channel_internal_queue->push(acquisition_message);
-
- break;
- }
- }
-
- return 0;
-}
diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5ax_2ms_pcps_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5ax_2ms_pcps_acquisition_cc.h
deleted file mode 100644
index 715f25804..000000000
--- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5ax_2ms_pcps_acquisition_cc.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * galileo_e5ax_1ms_pcps_acquisition_cc.h
- *
- * Created on: Jun 23, 2014
- * Author: marc
- */
-
-#ifndef GALILEO_E5AX_2MS_PCPS_ACQUISITION_CC_H_
-#define GALILEO_E5AX_2MS_PCPS_ACQUISITION_CC_H_
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "concurrent_queue.h"
-#include "gnss_synchro.h"
-
-class galileo_e5ax_2ms_pcps_acquisition_cc;
-
-typedef boost::shared_ptr galileo_e5ax_2ms_pcps_acquisition_cc_sptr;
-
-galileo_e5ax_2ms_pcps_acquisition_cc_sptr
-galileo_e5ax_2ms_pcps_make_acquisition_cc(unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
-
-/*!
- * \brief This class implements a Parallel Code Phase Search Acquisition.
- *
- * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
- * Algorithm 1, for a pseudocode description of this implementation.
- */
-class galileo_e5ax_2ms_pcps_acquisition_cc: public gr::block
-{
-private:
- friend galileo_e5ax_2ms_pcps_acquisition_cc_sptr
- galileo_e5ax_2ms_pcps_make_acquisition_cc(unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
-
- galileo_e5ax_2ms_pcps_acquisition_cc(unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in,
- int samples_per_ms, int samples_per_code,
- bool bit_transition_flag,
- gr::msg_queue::sptr queue, bool dump,
- std::string dump_filename);
-
- void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
- int doppler_offset);
-
- long d_fs_in;
- long d_freq;
- int d_samples_per_ms;
- int d_samples_per_code;
- unsigned int d_doppler_resolution;
- float d_threshold;
- std::string d_satellite_str;
- unsigned int d_doppler_max;
- unsigned int d_doppler_step;
- unsigned int d_max_dwells;
- unsigned int d_well_count;
- unsigned int d_fft_size;
- unsigned long int d_sample_counter;
- gr_complex** d_grid_doppler_wipeoffs;
- unsigned int d_num_doppler_bins;
- gr_complex* d_fft_code_A;
- gr_complex* d_fft_code_B;
- gr::fft::fft_complex* d_fft_if;
- gr::fft::fft_complex* d_ifft;
- Gnss_Synchro *d_gnss_synchro;
- unsigned int d_code_phase;
- float d_doppler_freq;
- float d_mag;
- float* d_magnitude;
- float d_input_power;
- float d_test_statistics;
- bool d_bit_transition_flag;
- gr::msg_queue::sptr d_queue;
- concurrent_queue *d_channel_internal_queue;
- std::ofstream d_dump_file;
- bool d_active;
- int d_state;
- bool d_dump;
- unsigned int d_channel;
- std::string d_dump_filename;
-
-public:
- /*!
- * \brief Default destructor.
- */
- ~galileo_e5ax_2ms_pcps_acquisition_cc();
-
- /*!
- * \brief Set acquisition/tracking common Gnss_Synchro object pointer
- * to exchange synchronization data between acquisition and tracking blocks.
- * \param p_gnss_synchro Satellite information shared by the processing blocks.
- */
- void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
- {
- d_gnss_synchro = p_gnss_synchro;
- }
-
- /*!
- * \brief Returns the maximum peak of grid search.
- */
- unsigned int mag()
- {
- return d_mag;
- }
-
- /*!
- * \brief Initializes acquisition algorithm.
- */
- void init();
-
- /*!
- * \brief Sets local code for PCPS acquisition algorithm.
- * \param code - Pointer to the PRN code.
- */
- void set_local_code(std::complex * code);
-
- /*!
- * \brief Starts acquisition algorithm, turning from standby mode to
- * active mode
- * \param active - bool that activates/deactivates the block.
- */
- void set_active(bool active)
- {
- d_active = active;
- }
-
- /*!
- * \brief Set acquisition channel unique ID
- * \param channel - receiver channel.
- */
- void set_channel(unsigned int channel)
- {
- d_channel = channel;
- }
-
- /*!
- * \brief Set statistics threshold of PCPS algorithm.
- * \param threshold - Threshold for signal detection (check \ref Navitec2012,
- * Algorithm 1, for a definition of this threshold).
- */
- void set_threshold(float threshold)
- {
- d_threshold = threshold;
- }
-
- /*!
- * \brief Set maximum Doppler grid search
- * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
- */
- void set_doppler_max(unsigned int doppler_max)
- {
- d_doppler_max = doppler_max;
- }
-
- /*!
- * \brief Set Doppler steps for the grid search
- * \param doppler_step - Frequency bin of the search grid [Hz].
- */
- void set_doppler_step(unsigned int doppler_step)
- {
- d_doppler_step = doppler_step;
- }
-
-
- /*!
- * \brief Set tracking channel internal queue.
- * \param channel_internal_queue - Channel's internal blocks information queue.
- */
- void set_channel_queue(concurrent_queue *channel_internal_queue)
- {
- d_channel_internal_queue = channel_internal_queue;
- }
-
- /*!
- * \brief Parallel Code Phase Search Acquisition signal processing.
- */
- int general_work(int noutput_items, gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-#endif /* GALILEO_E5AX_2MS_PCPS_ACQUISITION_CC_H_ */
diff --git a/src/algorithms/libs/galileo_e5_signal_processing.cc b/src/algorithms/libs/galileo_e5_signal_processing.cc
index e22445a0e..737a9794f 100644
--- a/src/algorithms/libs/galileo_e5_signal_processing.cc
+++ b/src/algorithms/libs/galileo_e5_signal_processing.cc
@@ -35,7 +35,6 @@
void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed int _prn, char _Signal[3])
{
- std::string _galileo_signal = _Signal;
unsigned int prn=_prn-1;
unsigned int index=0;
int a[4];
@@ -43,7 +42,7 @@ void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed in
{
return;
}
- if (_galileo_signal.rfind("5Q") != std::string::npos && _galileo_signal.length() >= 2)
+ if (_Signal[0]=='5' && _Signal[1]=='Q')
{
for (size_t i = 0; i < Galileo_E5a_Q_PRIMARY_CODE[prn].length()-1; i++)
{
@@ -61,7 +60,7 @@ void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed in
_dest[index]=std::complex(float(0.0),a[0]);
_dest[index+1]=std::complex(float(0.0),a[1]);
}
- else if (_galileo_signal.rfind("5I") != std::string::npos && _galileo_signal.length() >= 2)
+ else if (_Signal[0]=='5' && _Signal[1]=='I')
{
for (size_t i = 0; i < Galileo_E5a_I_PRIMARY_CODE[prn].length()-1; i++)
{
@@ -79,7 +78,7 @@ void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed in
_dest[index]=std::complex(float(a[0]),0.0);
_dest[index+1]=std::complex(float(a[1]),0.0);
}
- else if (_galileo_signal.rfind("5X") != std::string::npos && _galileo_signal.length() >= 2)
+ else if (_Signal[0]=='5' && _Signal[1]=='X')
{
int b[4];
for (size_t i = 0; i < Galileo_E5a_I_PRIMARY_CODE[prn].length()-1; i++)
@@ -104,74 +103,11 @@ void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed in
}
}
-void galileo_e5_a_code_gen_tiered(std::complex* _dest,std::complex* _primary ,unsigned int _prn, char _Signal[3])
-{
-
- std::string _galileo_signal = _Signal;
- unsigned int prn=_prn-1;
- // Note: always generates 100 ms of tiered code
- if (_galileo_signal.rfind("5Q") != std::string::npos && _galileo_signal.length() >= 2)
- {
- for (size_t i = 0; i < Galileo_E5a_Q_SECONDARY_CODE_LENGTH; i++)
- {
- for (size_t k=0; k< Galileo_E5a_CODE_LENGTH_CHIPS; k++)
- {
- //_dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k] = _primary[k];
- //_dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k] = new std::complex(0,0);
- _dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k].imag( _primary[k].imag() *
- (Galileo_E5a_Q_SECONDARY_CODE[prn].at(i)=='0' ? (float)1 : (float)-1));
-
- _dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k].real((float)0);
- }
- }
- }
- else if (_galileo_signal.rfind("5I") != std::string::npos && _galileo_signal.length() >= 2)
- {
- for (size_t i = 0; i < Galileo_E5a_Q_SECONDARY_CODE_LENGTH; i++)
- {
- for (size_t k=0; k< Galileo_E5a_CODE_LENGTH_CHIPS; k++)
- {
- //_dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k] = _primary[k];
- //_dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k] = new std::complex(0,0);
- // Modulo operator i%20 since i[0,99] and sec code[0,19]
- _dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k].real( _primary[k].real() *
- (Galileo_E5a_I_SECONDARY_CODE.at(i%20)=='0' ? (float)1 : (float)-1));
-
- _dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k].imag((float)0);
-
- }
- }
- }
- else if (_galileo_signal.rfind("5X") != std::string::npos && _galileo_signal.length() >= 2)
- {
- for (size_t i = 0; i < Galileo_E5a_Q_SECONDARY_CODE_LENGTH; i++)
- {
- for (size_t k=0; k< Galileo_E5a_CODE_LENGTH_CHIPS; k++)
- {
- //_dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k] = _primary[k];
- //_dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k] = new std::complex(0,0);
-
- _dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k].imag( _primary[k].imag() *
- (Galileo_E5a_Q_SECONDARY_CODE[prn].at(i)=='0' ? (float)1 : (float)-1));
-
- _dest[i*Galileo_E5a_CODE_LENGTH_CHIPS + k].real( _primary[k].real() *
- (Galileo_E5a_I_SECONDARY_CODE.at(i%20)=='0' ? (float)1 : (float)-1));
- }
- }
- }
- else
- {
- std::cout << "Signal doesn't correspond to E5a signal" << std::endl;
- }
-}
-
void galileo_e5_a_code_gen_complex_sampled(std::complex* _dest, char _Signal[3],
- unsigned int _prn, signed int _fs, unsigned int _chip_shift,
- bool _secondary_flag)
+ unsigned int _prn, signed int _fs, unsigned int _chip_shift)
{
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
- //std::string _galileo_signal = _Signal;
unsigned int _samplesPerCode;
unsigned int delay;
unsigned int _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS;
@@ -179,74 +115,31 @@ void galileo_e5_a_code_gen_complex_sampled(std::complex* _dest, char _Sig
std::complex* _code;
-// if (posix_memalign((void**)&_code, 16, _codeLength * sizeof(gr_complex)) == 0){};
_code=new std::complex[_codeLength];
- //std::complex primary_code_E5a_chips[(int)Galileo_E5a_CODE_LENGTH_CHIPS];
-
galileo_e5_a_code_gen_complex_primary(_code , _prn , _Signal);
- if (_secondary_flag)
- {
- std::complex* _tiered_code = new std::complex
- [Galileo_E5a_Q_SECONDARY_CODE_LENGTH * Galileo_E5a_CODE_LENGTH_CHIPS];
-
- _codeLength *= Galileo_E5a_Q_SECONDARY_CODE_LENGTH;
-// std::complex* _tiered_code;
-// if (posix_memalign((void**)&_tiered_code, 16, _codeLength * sizeof(gr_complex)) == 0){};
-// std::complex _tiered_code[Galileo_E5a_Q_SECONDARY_CODE_LENGTH * Galileo_E5a_CODE_LENGTH_CHIPS];
- //malloc(_tiered_code, )
- //std::cout << sizeof (&_tiered_code) << std::endl;
-
- galileo_e5_a_code_gen_tiered(_tiered_code, _code,_prn, _Signal);
-
- delete[] _code;
- //free(_code);
- //if (posix_memalign((void**)&_code, 16, _codeLength * sizeof(gr_complex)) == 0){};
- _code = _tiered_code;
-// delete[] _tiered_code;
- free(_tiered_code);
-
-
-
- }
-
_samplesPerCode = round(_fs / (_codeFreqBasis / _codeLength));
- // NOTE: if secondary, delay accounts for tiered code delay and samples/codesecondary
+
delay = ((_codeLength - _chip_shift)
% _codeLength) * _samplesPerCode / _codeLength;
- //std::cout << "check tiered code delay" << delay << std::endl;
- //std::cout << "check codelength" << _codeLength << std::endl;
if (_fs != _codeFreqBasis)
{
- std::complex* _resampled_signal;// = new std::complex[_codeLength];
+ std::complex* _resampled_signal;
if (posix_memalign((void**)&_resampled_signal, 16, _samplesPerCode * sizeof(gr_complex)) == 0){};
resampler(_code, _resampled_signal, _codeFreqBasis, _fs,
_codeLength, _samplesPerCode); //resamples code to fs
-
-// free(_code);
-// if (posix_memalign((void**)&_code, 16, _samplesPerCode * sizeof(gr_complex)) == 0){};
delete[] _code;
_code = _resampled_signal;
-// delete[] _resampled_signal;
- //free(_resampled_signal);
}
- //std::cout << _fs << "fs" << std::endl;
for (unsigned int i = 0; i < _samplesPerCode; i++)
{
_dest[(i+delay)%_samplesPerCode] = _code[i];
}
-// if (_code[0]==gr_complex(0,0))
-// {
-// std::cout <<"ERROR: first chip is 0. prn:"<< _prn << std::endl;
-// std::cout << _Signal << "signal" << std::endl;
-// }
-
- //std::cout << "no problem gen sampled code" <<_prn << " " << _code[0] <* _dest,std::complex
* bool _pilot generates E5aQ code if true and E5aI (data signal) if false.
*/
void galileo_e5_a_code_gen_complex_sampled(std::complex* _dest,
- char _Signal[3], unsigned int _prn, signed int _fs, unsigned int _chip_shift,
- bool _secondary_flag);
+ char _Signal[3], unsigned int _prn, signed int _fs, unsigned int _chip_shift);
#endif /* GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_ */
diff --git a/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc b/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc
index b703505c7..fb625a572 100644
--- a/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc
+++ b/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc
@@ -199,59 +199,22 @@ void signal_generator_c::generate_codes()
if(signal_[sat].at(0)=='5')
{
char signal[3];
-// strcpy(signal,"5I");
strcpy(signal,"5X");
if (posix_memalign((void**)&(sampled_code_data_[sat]), 16,
vector_length_ * sizeof(gr_complex)) == 0){};
-// galileo_e5_a_code_gen_complex_sampled(sampled_code_data_[sat] , signal, PRN_[sat], fs_in_,
-// (int)Galileo_E5a_Q_SECONDARY_CODE_LENGTH - delay_chips_[sat], true);
galileo_e5_a_code_gen_complex_sampled(sampled_code_data_[sat] , signal, PRN_[sat], fs_in_,
- (int)Galileo_E5a_CODE_LENGTH_CHIPS-delay_chips_[sat],false);
+ (int)Galileo_E5a_CODE_LENGTH_CHIPS-delay_chips_[sat]);
- std::cout << "PRN "<< PRN_[sat] << " first two bytes "<< sampled_code_data_[sat][0] << sampled_code_data_[sat][1] << sampled_code_data_[sat][2] << sampled_code_data_[sat][3] << sampled_code_data_[sat][4] << sampled_code_data_[sat][5] << sampled_code_data_[sat][6] << sampled_code_data_[sat][7] << std::endl;
- ///////////
- /*
- std::ofstream d_dump_file;
- std::stringstream filename;
- std::streamsize n = 2 * sizeof(float) * (Galileo_E5a_CODE_LENGTH_CHIPS); // complex file write
- filename.str("");
- filename << "../data/PRN11_Xcode_noiseless" << ".dat";
- d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
- d_dump_file.write((char*)&sampled_code_data_[sat][0], n);
- d_dump_file.close();
- */
- /////////////////////
- //// std::ofstream myfile;
-// //myfile.open ("example_sink_gencode.dat");
-// std::ofstream myfile("example_sink_gencode.bin",std::ios_base::binary);
-//// for (int k=0; k< vector_length_; k++)
-//// {
-// myfile.write((char*)&sampled_code_data_[sat],sizeof(gr_complex)*vector_length_);
-// //myfile << sampled_code_data_[sat][k];
-//// }
-//
-// myfile.close();
- //std::cout << "checking tiered code" << sampled_code_data_[sat][0] << sampled_code_data_[sat][1] << sampled_code_data_[sat][2] << sampled_code_data_[sat][3] << sampled_code_data_[sat][4] << sampled_code_data_[sat][1200000] << sampled_code_data_[sat][1200000-1] << std::endl;
-
- // PILOT
-// if (posix_memalign((void**)&(sampled_code_pilot_[sat]), 16,
-// vector_length_ * sizeof(gr_complex)) == 0){};
-//
-// strcpy(signal, "5Q");
-//
-// galileo_e5_a_code_gen_complex_sampled(sampled_code_pilot_[sat] , signal, PRN_[sat], fs_in_,
-// (int)Galileo_E5a_CODE_LENGTH_CHIPS - delay_chips_[sat], false);
//noise
if (noise_flag_)
{
for (unsigned int i = 0; i < vector_length_; i++)
{
sampled_code_data_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
- //sampled_code_pilot_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
}
}
@@ -389,7 +352,6 @@ gr_vector_void_star &output_items)
if(signal_[sat].at(0)=='5')
{
// EACH WORK outputs 1 modulated primary code
- //int codelen = (int)(Galileo_E5a_CODE_LENGTH_CHIPS * Galileo_E5a_Q_SECONDARY_CODE_LENGTH);
int codelen = (int)Galileo_E5a_CODE_LENGTH_CHIPS;
unsigned int delay_samples = (delay_chips_[sat] % codelen)
* samples_per_code_[sat] / codelen;
@@ -409,12 +371,6 @@ gr_vector_void_star &output_items)
data_modulation_[sat] = current_data_bit_int_[sat] * (Galileo_E5a_I_SECONDARY_CODE.at((ms_counter_[sat]+delay_sec_[sat])%20)=='0' ? 1 : -1);
pilot_modulation_[sat] = (Galileo_E5a_Q_SECONDARY_CODE[PRN_[sat]-1].at((ms_counter_[sat]+delay_sec_[sat])%100)=='0' ? 1 : -1);
-// if (work_counter_==1)
-// {
- //std::cout << "ms " << ms_counter_[sat] << " sat " << sat << " PRN" << PRN_[sat];
- //std::cout << " delay_secI " << (ms_counter_[sat]+delay_sec_[sat])%20 << " delay_secQ " << (ms_counter_[sat]+delay_sec_[sat])%100 << std::endl;//" pilot mod " << pilot_modulation_[sat] << " data bit " << current_data_bit_int_[sat] << " data mod " << data_modulation_[sat] << std::endl;
- //std::cout << "code 1st 2 byte " << out[0] << out[1] << out[2] << out[3] << out[4] << out[5] << out[6] << out[7] << std::endl;
-// }
ms_counter_[sat] = ms_counter_[sat] + (int)round(1e3*GALILEO_E5a_CODE_PERIOD);
for (k = delay_samples; k < samples_per_code_[sat]; k++)
@@ -425,8 +381,6 @@ gr_vector_void_star &output_items)
out_idx++;
}
-
-
}
else
{
@@ -473,19 +427,7 @@ gr_vector_void_star &output_items)
out[out_idx] += gr_complex(random_->gasdev(),random_->gasdev());
}
}
-/*
-if (work_counter_==1)
- {
- std::ofstream d_dump_file;
- std::stringstream filename;
- std::streamsize n = 2 * sizeof(float) * (samples_per_code_[0]); // complex file write
- filename.str("");
- filename << "../data/PRN11_Xcode_genwork" << ".dat";
- d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
- d_dump_file.write((char*)out, n);
- d_dump_file.close();
- }
-*/
+
// Tell runtime system how many output items we produced.
return 1;
}
diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc
index ec6735865..a85718987 100644
--- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc
+++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc
@@ -41,6 +41,7 @@
#include "galileo_fnav_message.h"
#include "gnss_synchro.h"
#include "convolutional.h"
+//#include
//#include "galileo_e1b_telemetry_decoder_cc.h"
#define CRC_ERROR_LIMIT 6
@@ -58,12 +59,14 @@ galileo_e5a_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, lo
void galileo_e5a_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
{
- ninput_items_required[0] = GALILEO_FNAV_SYMBOLS_PER_PAGE; // set the required sample history
+ //ninput_items_required[0] = GALILEO_FNAV_SAMPLES_PER_PAGE; // set the required sample history
+ ninput_items_required[0] = GALILEO_FNAV_CODES_PER_PREAMBLE;
}
void galileo_e5a_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits)
{
- int CodeLength = 240;
+// int CodeLength = 240;
+ int CodeLength = 488;
int DataLength;
int nn, KK, mm, max_states;
int g_encoder[2];
@@ -72,6 +75,8 @@ void galileo_e5a_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols
KK = 7; // Constraint Length
g_encoder[0] = 121; // Polynomial G1
g_encoder[1] = 91; // Polynomial G2
+// g_encoder[0] = 171; // Polynomial G1
+// g_encoder[1] = 133; // Polynomial G2
mm = KK - 1;
max_states = 1 << mm; // 2^mm
@@ -127,15 +132,14 @@ void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols,int fram
page_symbols_deint[i] = -page_symbols_deint[i];
}
}
- int page_part_bits[frame_length];
-
- viterbi_decoder(page_symbols_deint, page_part_bits);
+ int page_bits[frame_length/2];
+ galileo_e5a_telemetry_decoder_cc::viterbi_decoder(page_symbols_deint, page_bits);
// 3. Call the Galileo page decoder
std::string page_String;
for(int i = 0; i < frame_length; i++)
{
- if (page_part_bits[i] > 0)
+ if (page_bits[i] > 0)
{
page_String.push_back('1');
}
@@ -202,36 +206,49 @@ galileo_e5a_telemetry_decoder_cc::galileo_e5a_telemetry_decoder_cc(
d_fs_in = fs_in;
// set the preamble
- unsigned short int preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS] = GALILEO_INAV_PREAMBLE;
+ //unsigned short int preambles_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS] = GALILEO_FNAV_PREAMBLE;
+ for (int i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
+ {
+ if (GALILEO_FNAV_PREAMBLE.at(i) == '0')
+ {
+ d_preamble_bits[i] = 1;
+ }
+ else
+ {
+ d_preamble_bits[i] = -1;
+ }
+ }
- //d_symbols_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol;
+// memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GALILEO_FNAV_PREAMBLE_LENGTH_BITS*sizeof(unsigned short int));
- memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GALILEO_INAV_PREAMBLE_LENGTH_BITS*sizeof(unsigned short int));
-
- // preamble bits to sampled symbols
- d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * GALILEO_FNAV_SAMPLES_PER_PREAMBLE);
- int n = 0;
- for (int i = 0; i < GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++)
- {
- for (unsigned int j = 0; j < GALILEO_FNAV_SAMPLES_PER_SYMBOL; j++)
- {
- if (d_preambles_bits[i] == 1)
- {
- d_preambles_symbols[n] = 1;
- }
- else
- {
- d_preambles_symbols[n] = -1;
- }
- n++;
- }
- }
+// // preamble bits to sampled symbols
+// d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * GALILEO_FNAV_SAMPLES_PER_PREAMBLE);
+// int n = 0;
+// for (int i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
+// {
+// for (unsigned int j = 0; j < GALILEO_FNAV_SAMPLES_PER_SYMBOL; j++)
+// {
+// if (d_preambles_bits[i] == 1)
+// {
+// d_preambles_symbols[n] = 1;
+// }
+// else
+// {
+// d_preambles_symbols[n] = -1;
+// }
+// n++;
+// }
+// }
+//
d_sample_counter = 0;
- //d_stat = 0;
+ d_state = 0;
d_preamble_lock=false;
d_preamble_index = 0;
d_preamble_time_seconds = 0;
d_flag_frame_sync = false;
+ d_current_symbol_float = 0;
+ d_prompt_counter = 0;
+ d_symbol_counter = 0;
d_TOW_at_Preamble = 0;
d_TOW_at_current_symbol = 0;
@@ -241,222 +258,300 @@ galileo_e5a_telemetry_decoder_cc::galileo_e5a_telemetry_decoder_cc(
galileo_e5a_telemetry_decoder_cc::~galileo_e5a_telemetry_decoder_cc()
{
- delete d_preambles_symbols;
- d_dump_file.close();
+ delete d_preamble_bits;
+ d_dump_file.close();
}
int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
- int preamble_diff = 0;
- int corr_sign=0;
- bool corr_flag=true;
-
- Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
- d_sample_counter++; //count for the processed samples
-
- // ########### Output the tracking data to navigation and PVT ##########
+ //
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
+ Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
- d_flag_preamble = false;
- //******* frame sync ******************
- if (d_preamble_lock == false)
- {
- // d_preamble_lock tells if we have received a valid preamble and we are waiting
- // for the next one. Doesn't ensure frame sync yet.
- //******* preamble correlation ********
- // check if the preamble starts positive correlated or negative correlated
- if (in[0][0].Prompt_I < 0) // symbols clipping
- {
- corr_sign=d_preambles_symbols[0];
- }
- else
- {
- corr_sign=-d_preambles_symbols[0];
- }
- // the preamble is fully correlated only if maintains corr_sign along the whole sequence
- for (int i = 1; i < GALILEO_FNAV_SAMPLES_PER_PREAMBLE; i++)
- {
- if (in[0][i].Prompt_I < 0 && d_preambles_symbols[i]+corr_sign != 0)
- {
- //exit for
- corr_flag=false;
- break;
- }
- if (in[0][i].Prompt_I > 0 && d_preambles_symbols[i]+corr_sign == 0)
- {
- //exit for
- corr_flag=false;
- break;
- }
- }
- if (corr_flag==true)
- {
- d_preamble_index = d_sample_counter;//record the preamble sample stamp
- LOG(INFO) << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
- d_preamble_lock=true;
- }
- }
- // else, preamble_lock == true , we are waiting for the next preamble at a specific time
- else if (d_sample_counter == d_preamble_index + GALILEO_FNAV_SAMPLES_PER_PAGE)
- {
- // only correlate preamble at the right time
- //******* preamble correlation ********
- // check if the preamble starts positive correlated or negative correlated
- if (in[0][0].Prompt_I < 0) // symbols clipping
- {
- corr_sign = d_preambles_symbols[0];
- }
- else
- {
- corr_sign = -d_preambles_symbols[0];
- }
- // the preamble is fully correlated only if maintains corr_sign along the whole sequence
- for (int i = 1; i < GALILEO_FNAV_SAMPLES_PER_PREAMBLE; i++)
- {
- if (in[0][i].Prompt_I < 0 && d_preambles_symbols[i] + corr_sign != 0)
- {
- //exit for
- corr_flag = false;
- break;
- }
- if (in[0][i].Prompt_I > 0
- && d_preambles_symbols[i] + corr_sign == 0)
- {
- //exit for
- corr_flag = false;
- break;
- }
- }
- if (corr_flag == false) // lost preamble sync
- {
- d_preamble_lock = false;
- LOG(INFO)<< "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff;
- d_flag_frame_sync = false;
- flag_TOW_set = false;
- }
- else // NEW PAGE RECEIVED
- {
- // 1 - Obtain message symbols averaging samples (20 samples / symbol)
- int frame_length_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE
- - GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
- //int page_symbols[frame_length_symbols];
- double samples_to_bit_accumulator[frame_length_symbols];
- //int samples_to_bit_accumulator = 0;
- for (int i = 0; i < frame_length_symbols; i++)
- {
- samples_to_bit_accumulator[i]=0.0;
- for (int k = 0; k < GALILEO_FNAV_SAMPLES_PER_SYMBOL; k++)
- {
- samples_to_bit_accumulator[i] += in[0][k + i*GALILEO_FNAV_SAMPLES_PER_SYMBOL + GALILEO_FNAV_SAMPLES_PER_PREAMBLE].Prompt_I;
- // Reminder: corr_sign is negative if phase lock is at 180º
-// if (in[0][k + i*GALILEO_FNAV_SAMPLES_PER_SYMBOL + GALILEO_FNAV_SAMPLES_PER_PREAMBLE].Prompt_I
-// > 0)
-// {
-// samples_to_bit_accumulator += corr_sign;
-// }
-// else
-// {
-// samples_to_bit_accumulator -= corr_sign;
-// }
+ /* Terminology: Prompt: output from tracking Prompt correlator (Prompt samples)
+ * Symbol: encoded navigation bits. 1 symbol = 20 samples in E5a
+ * Bit: decoded navigation bits forming words as described in Galileo ICD
+ * States: 0 Receiving dummy samples.
+ * 1 Preamble not locked
+ * 3 Preamble lock
+ */
+ switch (d_state)
+ {
+ case 0:
+ {
+ if (in[0][0].Prompt_I != 0)
+ {
+ d_current_symbol_float += (float)in[0][0].Prompt_I;
+ if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
+ {
+ if (d_current_symbol_float > 0)
+ {
+ d_page_symbols[d_symbol_counter] = 1;
+ }
+ else
+ {
+ d_page_symbols[d_symbol_counter] = -1;
+ }
+ d_current_symbol_float = 0;
+ d_symbol_counter++;
+ d_prompt_counter = 0;
+ if (d_symbol_counter == GALILEO_FNAV_PREAMBLE_LENGTH_BITS-1)
+ {
+ d_state = 1;
+ }
+ }
+ else
+ {
+ d_prompt_counter++;
+ }
+ }
+ break;
+ }
+ case 1:
+ {
+ d_current_symbol_float += (float)in[0][0].Prompt_I;
+ if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
+ {
+ if (d_current_symbol_float > 0)
+ {
+ d_page_symbols[d_symbol_counter] = 1;
+ }
+ else
+ {
+ d_page_symbols[d_symbol_counter] = -1;
+ }
+// d_page_symbols[d_symbol_counter] = d_current_symbol_float/(float)GALILEO_FNAV_CODES_PER_SYMBOL;
+ d_current_symbol_float = 0;
+ d_symbol_counter++;
+ d_prompt_counter = 0;
+ // **** Attempt Preamble correlation ****
+ bool corr_flag=true;
+ int corr_sign = 0; // sequence can be found inverted
+// corr_sign = d_preamble_bits[0] * d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
+// for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
+// {
+// if ((d_preamble_bits[i] * d_page_symbols[i + d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS]) != corr_sign)
+// {
+// //exit for if one bit doesn't correlate
+// corr_flag=false;
+// break;
+// }
+// }
+ // check if the preamble starts positive correlated or negative correlated
+ if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS] < 0) // symbols clipping
+ {
+ corr_sign=-d_preamble_bits[0];
+ }
+ else
+ {
+ corr_sign=d_preamble_bits[0];
+ }
+ // the preamble is fully correlated only if maintains corr_sign along the whole sequence
+ for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
+ {
+ if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] < 0 && d_preamble_bits[i]+corr_sign != 0)
+ {
+ //exit for
+ corr_flag=false;
+ break;
+ }
+ if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] > 0 && d_preamble_bits[i]+corr_sign == 0)
+ {
+ //exit for
+ corr_flag=false;
+ break;
+ }
+ }
+ //
+ if (corr_flag==true) // preamble fully correlates
+ {
+ d_preamble_index = d_sample_counter - GALILEO_FNAV_CODES_PER_PREAMBLE;//record the preamble sample stamp. Remember correlation appears at the end of the preamble in this design
+ LOG(INFO) << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
+ d_symbol_counter = 0; // d_page_symbols start right after preamble and finish at the end of next preamble.
+ d_state = 2; // preamble lock
+ }
+ if (d_symbol_counter >= GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS)
+ {
+ d_symbol_counter = GALILEO_FNAV_PREAMBLE_LENGTH_BITS; // prevents overflow
+ }
+ }
+ else
+ {
+ d_prompt_counter++;
+ }
+ break;
+ }
+ case 2:
+ {
+ d_current_symbol_float += (float)in[0][0].Prompt_I;
+ if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
+ {
+ if (d_current_symbol_float > 0)
+ {
+ d_page_symbols[d_symbol_counter] = 1;
+ }
+ else
+ {
+ d_page_symbols[d_symbol_counter] = -1;
+ }
+// d_page_symbols[d_symbol_counter] = d_current_symbol_float/(float)GALILEO_FNAV_CODES_PER_SYMBOL;
+ d_current_symbol_float = 0;
+ d_symbol_counter++;
+ d_prompt_counter = 0;
+ // At the right sample stamp, check preamble synchro
+ if (d_sample_counter == d_preamble_index + GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE)
+ {
+ // **** Attempt Preamble correlation ****
+ bool corr_flag = true;
+ int corr_sign = 0; // sequence can be found inverted
+// corr_sign = d_preamble_bits[0] * d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
+// for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
+// {
+// if ((d_preamble_bits[i] * d_page_symbols[i + d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS]) != corr_sign)
+// {
+// //exit for if one bit doesn't correlate
+// corr_flag=false;
+// break;
+// }
+// }
+ // check if the preamble starts positive correlated or negative correlated
+ if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS] < 0) // symbols clipping
+ {
+ corr_sign=-d_preamble_bits[0];
+ }
+ else
+ {
+ corr_sign=d_preamble_bits[0];
+ }
+ // the preamble is fully correlated only if maintains corr_sign along the whole sequence
+ for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
+ {
+ if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] < 0 && d_preamble_bits[i]+corr_sign != 0)
+ {
+ //exit for
+ corr_flag=false;
+ break;
+ }
+ if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] > 0 && d_preamble_bits[i]+corr_sign == 0)
+ {
+ //exit for
+ corr_flag=false;
+ break;
+ }
+ }
+ //
+ if (corr_flag==true) // NEW PREAMBLE RECEIVED. DECODE PAGE
+ {
+ d_preamble_index = d_sample_counter - GALILEO_FNAV_CODES_PER_PREAMBLE;//record the preamble sample stamp
+ // Change sign if necessary
+// if (corr_sign < 0)
+// {
+// // NOTE: exists volk library for integers ???
+// for (int i = 0; i < d_symbol_counter; i++)
+// {
+// d_page_symbols[i] = -d_page_symbols[i];
+// }
+// }
+ // DECODE WORD
+ decode_word(d_page_symbols, GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS);
+ // CHECK CRC
+ if (d_nav.flag_CRC_test == true)
+ {
+ d_CRC_error_counter = 0;
+ d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
+ d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs - ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD); //record the PRN start sample index associated to the preamble start.
+ if (!d_flag_frame_sync)
+ {
+ d_flag_frame_sync = true;
+ LOG(INFO) <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]";
+ }
+ d_symbol_counter = 0; // d_page_symbols start right after preamble and finish at the end of next preamble.
+ }
+ else
+ {
+ d_CRC_error_counter++;
+ if (d_CRC_error_counter > CRC_ERROR_LIMIT)
+ {
+ LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
+ d_state = 1;
+ d_symbol_counter = GALILEO_FNAV_PREAMBLE_LENGTH_BITS; // prevents overflow
+ d_flag_frame_sync = false;
+ }
+ else
+ {
+ d_symbol_counter = 0; // d_page_symbols start right after preamble and finish at the end of next preamble.
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ d_prompt_counter++;
+ }
+ break;
+ }
+ }
+ consume_each(1);
- }
- samples_to_bit_accumulator[i] /= corr_sign*GALILEO_FNAV_SAMPLES_PER_SYMBOL;
-// if (samples_to_bit_accumulator > 0)
-// {
-// page_symbols[i] = 1; // because last symbol of the preamble is just received now!
-//
-// }
-// else
-// {
-// page_symbols[i] = -1; // because last symbol of the preamble is just received now!
-// }
- }
- // DECODE WORD
- decode_word(samples_to_bit_accumulator, frame_length_symbols);
- // CHECK CRC
- if (d_nav.flag_CRC_test == true)
- {
- d_CRC_error_counter = 0;
- d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
- 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
- if (!d_flag_frame_sync)
- {
- d_flag_frame_sync = true;
- LOG(INFO) <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]";
- }
- }
- else
- {
- d_CRC_error_counter++;
- d_preamble_index = d_sample_counter; //record the preamble sample stamp
- if (d_CRC_error_counter > CRC_ERROR_LIMIT)
- {
- LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
- d_flag_frame_sync = false;
- d_preamble_lock = false;
- }
- }
- }
- }
- consume_each(1); //one by one
// UPDATE GNSS SYNCHRO DATA
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
//1. Copy the current tracking output
current_synchro_data = in[0][0];
//2. Add the telemetry decoder information
if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true)
- //update TOW at the preamble instant
- //We expect a preamble each 10 seconds (FNAV page period)
- {
- Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
- if (d_nav.flag_TOW_1 == true)
- {
- d_TOW_at_Preamble = d_nav.FNAV_TOW_1;
- d_TOW_at_current_symbol = d_TOW_at_Preamble;
- d_nav.flag_TOW_1 = false;
- }
- if (d_nav.flag_TOW_2 == true)
- {
- d_TOW_at_Preamble = d_nav.FNAV_TOW_2;
- d_TOW_at_current_symbol = d_TOW_at_Preamble;
- d_nav.flag_TOW_2 = false;
- }
- if (d_nav.flag_TOW_3 == true)
- {
- d_TOW_at_Preamble = d_nav.FNAV_TOW_3;
- d_TOW_at_current_symbol = d_TOW_at_Preamble;
- d_nav.flag_TOW_3 = false;
- }
- if (d_nav.flag_TOW_4 == true)
- {
- d_TOW_at_Preamble = d_nav.FNAV_TOW_4;
- d_TOW_at_current_symbol = d_TOW_at_Preamble;
- d_nav.flag_TOW_4 = false;
- }
- else
- {
- //this page has no timming information
- d_TOW_at_Preamble = d_TOW_at_Preamble + GALILEO_FNAV_SECONDS_PER_PAGE;
- d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E5a_CODE_PERIOD;
- }
+ //update TOW at the preamble instant
+ //We expect a preamble each 10 seconds (FNAV page period)
+ {
+ Prn_timestamp_at_preamble_ms = d_preamble_time_seconds * 1000;
+ //Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
+ if (d_nav.flag_TOW_1 == true)
+ {
+ d_TOW_at_Preamble = d_nav.FNAV_TOW_1;
+ d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
+ d_nav.flag_TOW_1 = false;
+ }
+ if (d_nav.flag_TOW_2 == true)
+ {
+ d_TOW_at_Preamble = d_nav.FNAV_TOW_2;
+ d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
+ d_nav.flag_TOW_2 = false;
+ }
+ if (d_nav.flag_TOW_3 == true)
+ {
+ d_TOW_at_Preamble = d_nav.FNAV_TOW_3;
+ d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
+ d_nav.flag_TOW_3 = false;
+ }
+ if (d_nav.flag_TOW_4 == true)
+ {
+ d_TOW_at_Preamble = d_nav.FNAV_TOW_4;
+ d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
+ d_nav.flag_TOW_4 = false;
+ }
+ else
+ {
+ //this page has no timming information
+ d_TOW_at_Preamble = d_TOW_at_Preamble + GALILEO_FNAV_SECONDS_PER_PAGE;
+ d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E5a_CODE_PERIOD;
+ }
- }
+ }
else //if there is not a new preamble, we define the TOW of the current symbol
- {
- d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E5a_CODE_PERIOD;
- }
+ {
+ d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E5a_CODE_PERIOD;
+ }
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)
- {
- current_synchro_data.Flag_valid_word = true;
- }
+ {
+ current_synchro_data.Flag_valid_word = true;
+ }
else
- {
- current_synchro_data.Flag_valid_word = false;
- }
+ {
+ current_synchro_data.Flag_valid_word = false;
+ }
current_synchro_data.d_TOW = d_TOW_at_Preamble;
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
@@ -465,23 +560,24 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms;
if(d_dump == true)
- {
- // MULTIPLEXED FILE RECORDING - Record results to file
- try
- {
- double tmp_double;
- tmp_double = d_TOW_at_current_symbol;
- d_dump_file.write((char*)&tmp_double, sizeof(double));
- tmp_double = current_synchro_data.Prn_timestamp_ms;
- d_dump_file.write((char*)&tmp_double, sizeof(double));
- tmp_double = d_TOW_at_Preamble;
- d_dump_file.write((char*)&tmp_double, sizeof(double));
- }
- catch (const std::ifstream::failure& e)
- {
- LOG(WARNING) << "Exception writing observables dump file " << e.what();
- }
- }
+ {
+ // MULTIPLEXED FILE RECORDING - Record results to file
+ try
+ {
+ double tmp_double;
+ tmp_double = d_TOW_at_current_symbol;
+ d_dump_file.write((char*)&tmp_double, sizeof(double));
+ tmp_double = current_synchro_data.Prn_timestamp_ms;
+ d_dump_file.write((char*)&tmp_double, sizeof(double));
+ tmp_double = d_TOW_at_Preamble;
+ d_dump_file.write((char*)&tmp_double, sizeof(double));
+ }
+ catch (const std::ifstream::failure& e)
+ {
+ LOG(WARNING) << "Exception writing observables dump file " << e.what();
+ }
+ }
+ d_sample_counter++; //count for the processed samples
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_synchro_data;
return 1;
diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h
index 773a65d71..5f38cc09a 100644
--- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h
+++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h
@@ -96,15 +96,20 @@ private:
void decode_word(double *page_symbols,int frame_length);
- unsigned short int d_preambles_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
-
- signed int *d_preambles_symbols;
+ signed int d_preamble_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
+// signed int d_page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
+ double d_page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
+ signed int *d_preamble_symbols;
+ float d_current_symbol_float;
+ long unsigned int d_symbol_counter;
+ int d_prompt_counter;
long unsigned int d_sample_counter;
long unsigned int d_preamble_index;
bool d_preamble_lock;
bool d_flag_frame_sync;
+ int d_state;
bool d_flag_preamble;
int d_CRC_error_counter;
diff --git a/src/algorithms/telemetry_decoder/libs/convolutional.h b/src/algorithms/telemetry_decoder/libs/convolutional.h
index a225d2c2c..ed2a952b8 100644
--- a/src/algorithms/telemetry_decoder/libs/convolutional.h
+++ b/src/algorithms/telemetry_decoder/libs/convolutional.h
@@ -441,7 +441,7 @@ static void Viterbi(int output_u_int[],
for (t = 0; t < LL + mm; t++)
{
for (i = 0; i < nn; i++)
- rec_array[i] = (float)input_c[nn*t + i];
+ rec_array[i] = (float)input_c[nn*t + i];
/* precompute all possible branch metrics */
for (i = 0; i < number_symbols; i++)
diff --git a/src/algorithms/tracking/adapters/CMakeLists.txt b/src/algorithms/tracking/adapters/CMakeLists.txt
index 7415e5e1c..4db5df1db 100644
--- a/src/algorithms/tracking/adapters/CMakeLists.txt
+++ b/src/algorithms/tracking/adapters/CMakeLists.txt
@@ -24,7 +24,6 @@ set(TRACKING_ADAPTER_SOURCES
gps_l1_ca_dll_pll_optim_tracking.cc
gps_l1_ca_dll_pll_tracking.cc
gps_l1_ca_tcp_connector_tracking.cc
- galileo_e5a_dll_fll_pll_tracking.cc
galileo_e5a_dll_pll_tracking.cc
)
diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_fll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_fll_pll_tracking.cc
deleted file mode 100644
index 2caf9b3c2..000000000
--- a/src/algorithms/tracking/adapters/galileo_e5a_dll_fll_pll_tracking.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*!
- * \file galileo_e5a_dll_fll_pll_tracking_cc.h
- * \brief Adapts code DLL + carrier PLL aided with FLL
- * tracking block to TrackingInterface for Galileo E5a signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-#include "galileo_e5a_dll_fll_pll_tracking.h"
-#include
-#include "Galileo_E5a.h"
-#include "configuration_interface.h"
-
-using google::LogMessage;
-
-GalileoE5aDllFllPllTracking::GalileoE5aDllFllPllTracking(
- ConfigurationInterface* configuration,
- std::string role,
- unsigned int in_streams, unsigned int
- out_streams,
- boost::shared_ptr queue) :
- role_(role),
- in_streams_(in_streams),
- out_streams_(out_streams),
- queue_(queue)
-{
- DLOG(INFO) << "role " << role;
- //################# CONFIGURATION PARAMETERS ########################
- int fs_in;
- int vector_length;
- int f_if;
- bool dump;
- std::string dump_filename;
- std::string item_type;
- std::string default_item_type = "gr_complex";
- float pll_bw_hz;
- float fll_bw_hz;
- float dll_bw_hz;
- float early_late_space_chips;
- int order;
- item_type = configuration->property(role + ".item_type",default_item_type);
- //vector_length = configuration->property(role + ".vector_length", 2048);
- fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
- f_if = configuration->property(role + ".if", 0);
- dump = configuration->property(role + ".dump", false);
- order = configuration->property(role + ".order", 2);
- pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
- fll_bw_hz = configuration->property(role + ".fll_bw_hz", 100.0);
- dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
- early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
- std::string default_dump_filename = "./track_ch";
- dump_filename = configuration->property(role + ".dump_filename",
- default_dump_filename); //unused!
- vector_length = round(fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS));
-
- //################# MAKE TRACKING GNURadio object ###################
- if (item_type.compare("gr_complex") == 0)
- {
- item_size_ = sizeof(gr_complex);
- tracking_ = galileo_e5a_dll_fll_pll_make_tracking_cc(
- f_if,
- fs_in,
- vector_length,
- queue_,
- dump,
- dump_filename,
- order,
- fll_bw_hz,
- pll_bw_hz,
- dll_bw_hz,
- early_late_space_chips);
- }
- else
- {
- LOG(WARNING) << item_type << " unknown tracking item type.";
- }
-
- DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")";
-}
-
-
-GalileoE5aDllFllPllTracking::~GalileoE5aDllFllPllTracking()
-{}
-
-
-void GalileoE5aDllFllPllTracking::start_tracking()
-{
- tracking_->start_tracking();
-}
-
-void GalileoE5aDllFllPllTracking::set_channel(unsigned int channel)
-{
- channel_ = channel;
- tracking_->set_channel(channel);
-}
-
-void GalileoE5aDllFllPllTracking::set_channel_queue(
- concurrent_queue *channel_internal_queue)
-{
- channel_internal_queue_ = channel_internal_queue;
- tracking_->set_channel_queue(channel_internal_queue_);
-}
-
-void GalileoE5aDllFllPllTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
-{
- return tracking_->set_gnss_synchro(p_gnss_synchro);
-}
-
-void GalileoE5aDllFllPllTracking::connect(gr::top_block_sptr top_block)
-{
- //nothing to connect, now the tracking uses gr_sync_decimator
-}
-
-void GalileoE5aDllFllPllTracking::disconnect(gr::top_block_sptr top_block)
-{
- //nothing to disconnect, now the tracking uses gr_sync_decimator
-}
-
-gr::basic_block_sptr GalileoE5aDllFllPllTracking::get_left_block()
-{
- return tracking_;
-}
-
-gr::basic_block_sptr GalileoE5aDllFllPllTracking::get_right_block()
-{
- return tracking_;
-}
diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_fll_pll_tracking.h b/src/algorithms/tracking/adapters/galileo_e5a_dll_fll_pll_tracking.h
deleted file mode 100644
index 176b30779..000000000
--- a/src/algorithms/tracking/adapters/galileo_e5a_dll_fll_pll_tracking.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*!
- * \file galileo_e5a_dll_fll_pll_tracking_cc.h
- * \brief Adapts code DLL + carrier PLL aided with FLL
- * tracking block to TrackingInterface for Galileo E5a signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#ifndef GNSS_SDR_GALILEO_E5A_DLL_FLL_PLL_TRACKING_H_
-#define GNSS_SDR_GALILEO_E5A_DLL_FLL_PLL_TRACKING_H_
-
-#include
-#include
-#include "tracking_interface.h"
-#include "galileo_e5a_dll_fll_pll_tracking_cc.h"
-
-class ConfigurationInterface;
-
-class GalileoE5aDllFllPllTracking: public TrackingInterface
-{
-public:
-
- GalileoE5aDllFllPllTracking(ConfigurationInterface* configuration,
- std::string role,
- unsigned int in_streams,
- unsigned int out_streams,
- boost::shared_ptr queue);
-
- virtual ~GalileoE5aDllFllPllTracking();
-
- std::string role()
- {
- return role_;
- }
-
- //! Returns "Galileo_E5a_DLL_FLL_PLL_Tracking"
- std::string implementation()
- {
- return "Galileo_E5a_DLL_FLL_PLL_Tracking";
- }
- size_t item_size()
- {
- return item_size_;
- }
-
- void connect(gr::top_block_sptr top_block);
- void disconnect(gr::top_block_sptr top_block);
- gr::basic_block_sptr get_left_block();
- gr::basic_block_sptr get_right_block();
-
- void set_channel(unsigned int channel);
- void set_channel_queue(concurrent_queue *channel_internal_queue);
- void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
- void start_tracking();
-
-private:
- galileo_e5a_dll_fll_pll_tracking_cc_sptr tracking_;
- size_t item_size_;
- unsigned int channel_;
- std::string role_;
- unsigned int in_streams_;
- unsigned int out_streams_;
- boost::shared_ptr queue_;
- concurrent_queue *channel_internal_queue_;
-};
-
-#endif /* GNSS_SDR_GALILEO_E5A_DLL_FLL_PLL_TRACKING_H_ */
diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc
index 64ba9ba65..2cd33c004 100644
--- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc
+++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc
@@ -31,14 +31,21 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking(
std::string default_item_type = "gr_complex";
float pll_bw_hz;
float dll_bw_hz;
+ float pll_bw_init_hz;
+ float dll_bw_init_hz;
+ int ti_ms;
float early_late_space_chips;
item_type = configuration->property(role + ".item_type", default_item_type);
//vector_length = configuration->property(role + ".vector_length", 2048);
fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 12000000);
f_if = configuration->property(role + ".if", 0);
dump = configuration->property(role + ".dump", false);
- pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
+ pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0);
dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
+ pll_bw_init_hz = configuration->property(role + ".pll_bw_init_hz", 20.0);
+ dll_bw_init_hz = configuration->property(role + ".dll_bw_init_hz", 20.0);
+ ti_ms = configuration->property(role + ".ti_ms", 3);
+
early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
std::string default_dump_filename = "./track_ch";
dump_filename = configuration->property(role + ".dump_filename",
@@ -58,6 +65,9 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking(
dump_filename,
pll_bw_hz,
dll_bw_hz,
+ pll_bw_init_hz,
+ dll_bw_init_hz,
+ ti_ms,
early_late_space_chips);
}
else
diff --git a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt
index 70376a3f3..1a7e4be6e 100644
--- a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt
+++ b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt
@@ -23,7 +23,6 @@ set(TRACKING_GR_BLOCKS_SOURCES
gps_l1_ca_dll_pll_optim_tracking_cc.cc
gps_l1_ca_dll_pll_tracking_cc.cc
gps_l1_ca_tcp_connector_tracking_cc.cc
- galileo_e5a_dll_fll_pll_tracking_cc.cc
galileo_e5a_dll_pll_tracking_cc.cc
)
diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_fll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_fll_pll_tracking_cc.cc
deleted file mode 100644
index 1c1ab9f70..000000000
--- a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_fll_pll_tracking_cc.cc
+++ /dev/null
@@ -1,670 +0,0 @@
-/*!
- * \file galileo_e5a_dll_fll_pll_tracking_cc.h
- * \brief Implementation of a code DLL + carrier PLL aided with FLL
- * tracking block for Galileo E5a signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "galileo_e5a_dll_fll_pll_tracking_cc.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include "gnss_synchro.h"
-#include "galileo_e5_signal_processing.h"
-#include "Galileo_E5a.h"
-#include "Galileo_E1.h"
-#include "tracking_discriminators.h"
-#include "lock_detectors.h"
-#include "tracking_FLL_PLL_filter.h"
-#include "control_message_factory.h"
-#include "gnss_flowgraph.h"
-
-/*!
- * \todo Include in definition header file
- */
-#define CN0_ESTIMATION_SAMPLES 20
-#define MINIMUM_VALID_CN0 25
-#define MAXIMUM_LOCK_FAIL_COUNTER 50
-#define CARRIER_LOCK_THRESHOLD 0.85
-
-using google::LogMessage;
-
-galileo_e5a_dll_fll_pll_tracking_cc_sptr galileo_e5a_dll_fll_pll_make_tracking_cc(
- long if_freq,
- long fs_in,
- unsigned
- int vector_length,
- boost::shared_ptr queue,
- bool dump, std::string dump_filename,
- int order,
- float fll_bw_hz,
- float pll_bw_hz,
- float dll_bw_hz,
- float early_late_space_chips)
-{
-
- return galileo_e5a_dll_fll_pll_tracking_cc_sptr(new galileo_e5a_dll_fll_pll_tracking_cc(if_freq,
- fs_in, vector_length, queue, dump, dump_filename, order, fll_bw_hz, pll_bw_hz,dll_bw_hz,
- early_late_space_chips));
-}
-
-
-
-
-void galileo_e5a_dll_fll_pll_tracking_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
-{
- ninput_items_required[0] = d_vector_length*2; //set the required available samples in each call
-}
-
-
-galileo_e5a_dll_fll_pll_tracking_cc::galileo_e5a_dll_fll_pll_tracking_cc(
- long if_freq,
- long fs_in,
- unsigned int vector_length,
- boost::shared_ptr queue,
- bool dump,
- std::string dump_filename,
- int order,
- float fll_bw_hz,
- float pll_bw_hz,
- float dll_bw_hz,
- float early_late_space_chips) :
- gr::block("galileo_e5a_dll_fll_pll_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)),
- gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
-{
- this->set_relative_rate(1.0/vector_length);
- // initialize internal vars
- d_queue = queue;
- d_dump = dump;
-
- d_acquisition_gnss_synchro = NULL;
-
- d_if_freq = (double)if_freq;
- d_fs_in = (double)fs_in;
- d_vector_length = vector_length;
- d_early_late_spc_chips = (double)early_late_space_chips; // Define early-late offset (in chips)
- d_dump_filename = dump_filename;
-
- //d_sampled_codeLength = round(d_fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS));
- // Initialize tracking variables ==========================================
- d_carrier_loop_filter.set_params(fll_bw_hz, pll_bw_hz,order);
-
- d_code_loop_filter = Tracking_2nd_DLL_filter(GALILEO_E5a_CODE_PERIOD);
- d_code_loop_filter.set_DLL_BW(dll_bw_hz);
-
- // Get space for a vector with the C/A code replica sampled 1x/chip
- d_ca_code = new gr_complex[(int)Galileo_E5a_CODE_LENGTH_CHIPS + 2];
-
- /* If an array is partitioned for more than one thread to operate on,
- * having the sub-array boundaries unaligned to cache lines could lead
- * to performance degradation. Here we allocate memory
- * (gr_complex array of size 2*d_vector_length) aligned to cache of 16 bytes
- */
- // todo: do something if posix_memalign fails
- // Get space for the resampled early / prompt / late local replicas
- if (posix_memalign((void**)&d_early_code, 16, d_vector_length * sizeof(gr_complex) * 2) == 0){};
- if (posix_memalign((void**)&d_late_code, 16, d_vector_length * sizeof(gr_complex) * 2) == 0){};
- if (posix_memalign((void**)&d_prompt_code, 16, d_vector_length * sizeof(gr_complex) * 2) == 0){};
- // space for carrier wipeoff and signal baseband vectors
- if (posix_memalign((void**)&d_carr_sign, 16, d_vector_length * sizeof(gr_complex) * 2) == 0){};
- if (posix_memalign((void**)&d_Early, 16, sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_Prompt, 16, sizeof(gr_complex)) == 0){};
- if (posix_memalign((void**)&d_Late, 16, sizeof(gr_complex)) == 0){};
-
- // sample synchronization
- d_sample_counter = 0;
- d_acq_sample_stamp = 0;
- d_last_seg = 0;// this is for debug output only
- d_code_phase_samples = 0;
- d_enable_tracking = false;
- d_current_prn_length_samples = (int)d_vector_length;
-
- // CN0 estimation and lock detector buffers
- d_cn0_estimation_counter = 0;
- d_Prompt_buffer = new gr_complex[CN0_ESTIMATION_SAMPLES];
- d_carrier_lock_test = 1;
- d_CN0_SNV_dB_Hz = 0;
- d_carrier_lock_fail_counter = 0;
- d_carrier_lock_threshold = CARRIER_LOCK_THRESHOLD;
-
- systemName["G"] = std::string("GPS");
- systemName["R"] = std::string("GLONASS");
- systemName["S"] = std::string("SBAS");
- systemName["E"] = std::string("Galileo");
- systemName["C"] = std::string("Compass");
-}
-
-
-
-
-void galileo_e5a_dll_fll_pll_tracking_cc::start_tracking()
-{
- /*
- * correct the code phase according to the delay between acq and trk
- */
- d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples;
- d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz;
- d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples;
-
- long int acq_trk_diff_samples;
- float acq_trk_diff_seconds;
- acq_trk_diff_samples = (long int)d_sample_counter - (long int)d_acq_sample_stamp;
- acq_trk_diff_seconds = (double)acq_trk_diff_samples / d_fs_in;
- //doppler effect
- // Fd=(C/(C+Vr))*F
- double radial_velocity;
- radial_velocity = (Galileo_E5a_FREQ_HZ + d_acq_carrier_doppler_hz) / Galileo_E5a_FREQ_HZ;
- // new chip and prn sequence periods based on acq Doppler
- double T_chip_mod_seconds;
- double T_prn_mod_seconds;
- double T_prn_mod_samples;
- d_code_freq_hz = radial_velocity * Galileo_E5a_CODE_CHIP_RATE_HZ;
- T_chip_mod_seconds = 1 / d_code_freq_hz;
- T_prn_mod_seconds = T_chip_mod_seconds * Galileo_E5a_CODE_LENGTH_CHIPS;
- T_prn_mod_samples = T_prn_mod_seconds * d_fs_in;
- d_current_prn_length_samples = round(T_prn_mod_samples);
-
- double T_prn_true_seconds = Galileo_E5a_CODE_LENGTH_CHIPS / Galileo_E5a_CODE_CHIP_RATE_HZ;
- double T_prn_true_samples = T_prn_true_seconds * d_fs_in;
- double T_prn_diff_seconds;
- T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds;
- double N_prn_diff;
- N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds;
- double corrected_acq_phase_samples, delay_correction_samples;
- corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * d_fs_in), T_prn_true_samples);
-
- if (corrected_acq_phase_samples < 0)
- {
- corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples;
- }
- delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples;
- d_acq_code_phase_samples = corrected_acq_phase_samples;
-
- d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
- // DLL/PLL filter initialization
- d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz);
- d_FLL_wait = 1;
-
- // generate local reference ALWAYS starting at chip 1 (1 sample per chip)
- galileo_e5_a_code_gen_complex_sampled(&d_ca_code[1], d_acquisition_gnss_synchro->Signal, d_acquisition_gnss_synchro->PRN, d_fs_in,0,false);
-
- d_ca_code[0] = d_ca_code[(int)Galileo_E5a_CODE_LENGTH_CHIPS];
- d_ca_code[(int)Galileo_E5a_CODE_LENGTH_CHIPS + 1] = d_ca_code[1];
-
- d_carrier_lock_fail_counter = 0;
- d_Prompt_prev = 0;
- d_rem_code_phase_samples = 0;
- d_rem_carr_phase = 0;
- d_FLL_discriminator_hz = 0;
- d_rem_code_phase_samples = 0;
- d_acc_carrier_phase_rad = 0;
-
- std::string sys_ = &d_acquisition_gnss_synchro->System;
- sys = sys_.substr(0,1);
-
- // DEBUG OUTPUT
- std::cout << "Tracking start on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
- LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;
-
- // enable tracking Gnss_Satellite(systemName[&d_acquisition_gnss_synchro->System], d_acquisition_gnss_synchro->PRN)
- d_pull_in = true;
- d_enable_tracking = true;
-
- 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 << std::endl;
-}
-
-
-
-
-
-void galileo_e5a_dll_fll_pll_tracking_cc::update_local_code()
-{
- double tcode_chips;
- double rem_code_phase_chips;
- double code_phase_step_chips;
- int early_late_spc_samples;
- int epl_loop_length_samples;
-
- int associated_chip_index;
- int code_length_chips = (int)Galileo_E5a_CODE_LENGTH_CHIPS;
- code_phase_step_chips = d_code_freq_hz / d_fs_in;
- rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_hz / d_fs_in);
- // unified loop for E, P, L code vectors
- tcode_chips = -rem_code_phase_chips;
- // Alternative EPL code generation (40% of speed improvement!)
- early_late_spc_samples = round(d_early_late_spc_chips/code_phase_step_chips);
- epl_loop_length_samples = d_current_prn_length_samples + early_late_spc_samples*2;
- for (int i = 0; i < epl_loop_length_samples; i++)
- {
- associated_chip_index = 1 + round(fmod(tcode_chips - d_early_late_spc_chips, code_length_chips));
- d_early_code[i] = d_ca_code[associated_chip_index];
- tcode_chips = tcode_chips + code_phase_step_chips;
- }
-
- memcpy(d_prompt_code,&d_early_code[early_late_spc_samples],d_current_prn_length_samples* sizeof(gr_complex));
- memcpy(d_late_code,&d_early_code[early_late_spc_samples*2],d_current_prn_length_samples* sizeof(gr_complex));
-
- // for (int i=0; itelemetry_decoder
- Gnss_Synchro current_synchro_data;
- // Fill the acquisition data
- current_synchro_data = *d_acquisition_gnss_synchro;
- /*
- * Receiver signal alignment
- */
- if (d_pull_in == true)
- {
- int samples_offset;
- double acq_trk_shif_correction_samples;
- int acq_to_trk_delay_samples;
- acq_to_trk_delay_samples = d_sample_counter-d_acq_sample_stamp;
- acq_trk_shif_correction_samples = d_current_prn_length_samples - fmod((double)acq_to_trk_delay_samples, (double)d_current_prn_length_samples);
- samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples);
- // /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE
- d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples
- d_pull_in = false;
- consume_each(samples_offset); //shift input to perform alignment with local replica
-
- // make an output to not stop the rest of the processing blocks
- current_synchro_data.Prompt_I = 0.0;
- current_synchro_data.Prompt_Q = 0.0;
- current_synchro_data.Tracking_timestamp_secs = (double)d_sample_counter/d_fs_in;
- current_synchro_data.Carrier_phase_rads = 0.0;
- current_synchro_data.Code_phase_secs = 0.0;
- current_synchro_data.CN0_dB_hz = 0.0;
- current_synchro_data.Flag_valid_tracking = false;
-
- *out[0] = current_synchro_data;
-
- return 1;
- }
-
- update_local_code();
- update_local_carrier();
-
- // perform Early, Prompt and Late correlation
- d_correlator.Carrier_wipeoff_and_EPL_volk(d_current_prn_length_samples,
- in,
- d_carr_sign,
- d_early_code,
- d_prompt_code,
- d_late_code,
- d_Early,
- d_Prompt,
- d_Late,
- is_unaligned());
- // check for samples consistency (this should be done before in the receiver / here only if the source is a file)
- if (isnan((*d_Prompt).real()) == true or isnan((*d_Prompt).imag()) == true )// or std::isinf(in[i].real())==true or std::isinf(in[i].imag())==true)
- {
- const int samples_available = ninput_items[0];
- d_sample_counter = d_sample_counter + samples_available;
- LOG(WARNING) << "Detected NaN samples at sample number " << d_sample_counter;
- consume_each(samples_available);
-
- // make an output to not stop the rest of the processing blocks
- current_synchro_data.Prompt_I = 0.0;
- current_synchro_data.Prompt_Q = 0.0;
- current_synchro_data.Tracking_timestamp_secs = (double)d_sample_counter/d_fs_in;
- current_synchro_data.Carrier_phase_rads = 0.0;
- current_synchro_data.Code_phase_secs = 0.0;
- current_synchro_data.CN0_dB_hz = 0.0;
- current_synchro_data.Flag_valid_tracking = false;
-
- *out[0] =current_synchro_data;
-
- return 1;
- }
-
- /*
- * DLL, FLL, and PLL discriminators
- */
- // Compute DLL error
- code_error_chips = dll_nc_e_minus_l_normalized(*d_Early, *d_Late);
- // Compute DLL filtered error
- code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips);
-
- //compute FLL error
- correlation_time_s = ((double)d_current_prn_length_samples) / d_fs_in;
- if (d_FLL_wait == 1)
- {
- d_Prompt_prev = *d_Prompt;
- d_FLL_wait = 0;
- }
- else
- {
- d_FLL_discriminator_hz = fll_four_quadrant_atan(d_Prompt_prev, *d_Prompt, 0, correlation_time_s) / GPS_TWO_PI;
- d_Prompt_prev = *d_Prompt;
- d_FLL_wait = 1;
- }
-
- // Compute PLL error
- PLL_discriminator_hz = pll_cloop_two_quadrant_atan(*d_Prompt) / GPS_TWO_PI;
-
- /*
- * DLL and FLL+PLL filter and get current carrier Doppler and code frequency
- */
- carr_nco_hz = d_carrier_loop_filter.get_carrier_error(d_FLL_discriminator_hz, PLL_discriminator_hz, correlation_time_s);
- d_carrier_doppler_hz = d_if_freq + carr_nco_hz;
-
- d_code_freq_hz = Galileo_E5a_CODE_CHIP_RATE_HZ + (((d_carrier_doppler_hz + d_if_freq) * Galileo_E5a_CODE_CHIP_RATE_HZ) / Galileo_E5a_FREQ_HZ);
-
- /*!
- * \todo Improve the lock detection algorithm!
- */
- // ####### 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_Prompt;
- d_cn0_estimation_counter++;
- }
- else
- {
- d_cn0_estimation_counter = 0;
- //d_CN0_SNV_dB_Hz = gps_l1_ca_CN0_SNV(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in);
- d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, Galileo_E5a_CODE_LENGTH_CHIPS);
-
- d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
- // ###### TRACKING UNLOCK NOTIFICATION #####
- 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 << "!";
- ControlMessageFactory* cmf = new ControlMessageFactory();
- if (d_queue != gr::msg_queue::sptr())
- {
- d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
- }
- delete cmf;
- d_carrier_lock_fail_counter = 0;
- d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
- }
- }
-
- // ########## DEBUG OUTPUT
- /*!
- * \todo The stop timer has to be moved to the signal source!
- */
- // debug: Second counter in channel 0
- if (d_channel == 0)
- {
- if (floor(d_sample_counter/d_fs_in) != d_last_seg)
- {
- d_last_seg = floor(d_sample_counter/d_fs_in);
- std::cout << "Current input signal time = " << d_last_seg << " [s]" << std::endl;
- LOG(INFO) << "Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]";
- }
- }
- else
- {
- if (floor(d_sample_counter/d_fs_in) != d_last_seg)
- {
- d_last_seg = floor(d_sample_counter/d_fs_in);
- LOG(INFO) << "Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]";
- }
- }
-
- //predict the next loop PRN period length prediction
- double T_chip_seconds;
- double T_prn_seconds;
- double T_prn_samples;
- double K_blk_samples;
- T_chip_seconds = 1/d_code_freq_hz;
- T_prn_seconds = T_chip_seconds * Galileo_E5a_CODE_LENGTH_CHIPS;
- T_prn_samples = T_prn_seconds * d_fs_in;
-
- float code_error_filt_samples;
- code_error_filt_samples = T_prn_seconds*code_error_filt_chips*T_chip_seconds*(float)d_fs_in; //[seconds]
- d_acc_code_phase_samples = d_acc_code_phase_samples + code_error_filt_samples;
-
- K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_samples;
- d_current_prn_length_samples = round(K_blk_samples); //round to a discrete sample
- d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error
-
- // ########### Output the tracking data to navigation and PVT ##########
- current_synchro_data.Prompt_I = (double)(*d_Prompt).real();
- current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag();
- // Tracking_timestamp_secs is aligned with the PRN start sample
- current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + d_rem_code_phase_samples)/d_fs_in;
- // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, Code_phase_secs=0
- current_synchro_data.Code_phase_secs = 0;
- current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
- 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_tracking = true;
- *out[0] = current_synchro_data;
- }
- else
- {
- // ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
- /*!
- * \todo The stop timer has to be moved to the signal source!
- */
- // stream to collect cout calls to improve thread safety
- std::stringstream tmp_str_stream;
- if (floor(d_sample_counter / d_fs_in) != d_last_seg)
- {
- d_last_seg = floor(d_sample_counter / d_fs_in);
-
- if (d_channel == 0)
- {
- // debug: Second counter in channel 0
- tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
- std::cout << tmp_str_stream.rdbuf() << std::flush;
- }
- }
- *d_Early = gr_complex(0,0);
- *d_Prompt = gr_complex(0,0);
- *d_Late = gr_complex(0,0);
- Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; //block output streams pointer
- *out[0] = *d_acquisition_gnss_synchro;
- }
-
-
- if(d_dump)
- {
- // MULTIPLEXED FILE RECORDING - Record results to file
- float prompt_I;
- float prompt_Q;
- float tmp_E, tmp_P, tmp_L;
- float tmp_float;
- double tmp_double;
- prompt_I = (*d_Prompt).real();
- prompt_Q = (*d_Prompt).imag();
- tmp_E = std::abs(*d_Early);
- tmp_P = std::abs(*d_Prompt);
- tmp_L = std::abs(*d_Late);
- try
- {
- // EPR
- d_dump_file.write((char*)&tmp_E, sizeof(float));
- d_dump_file.write((char*)&tmp_P, sizeof(float));
- d_dump_file.write((char*)&tmp_L, sizeof(float));
- // PROMPT I and Q (to analyze navigation symbols)
- d_dump_file.write((char*)&prompt_I, sizeof(float));
- d_dump_file.write((char*)&prompt_Q, sizeof(float));
- // PRN start sample stamp
- d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int));
- // accumulated carrier phase
- tmp_float = (float)d_acc_carrier_phase_rad;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
-
- // carrier and code frequency
- tmp_float = (float)d_carrier_doppler_hz;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
- tmp_float = (float)d_code_freq_hz;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
-
- //PLL commands
- tmp_float = (float)PLL_discriminator_hz;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
- tmp_float = (float)carr_nco_hz;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
-
- //DLL commands
- tmp_float = (float)code_error_chips;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
- tmp_float = (float)code_error_filt_chips;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
-
- // CN0 and carrier lock test
- tmp_float = (float)d_CN0_SNV_dB_Hz;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
- tmp_float = (float)d_carrier_lock_test;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
-
- // AUX vars (for debug purposes)
- tmp_float = (float)d_rem_code_phase_samples;
- d_dump_file.write((char*)&tmp_float, sizeof(float));
- tmp_double = (double)(d_sample_counter + d_current_prn_length_samples);
- d_dump_file.write((char*)&tmp_double, sizeof(double));
- }
- catch (std::ifstream::failure e)
- {
- LOG(INFO) << "Exception writing trk dump file "<< e.what() << std::endl;
- }
- }
- consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates
- d_sample_counter += d_current_prn_length_samples; //count for the processed samples
- return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
-}
-
-
-void galileo_e5a_dll_fll_pll_tracking_cc::set_channel(unsigned int channel)
-{
- d_channel = channel;
- LOG(INFO) << "Tracking Channel set to " << d_channel;
- // ############# ENABLE DATA FILE LOG #################
- if (d_dump == true)
- {
- if (d_dump_file.is_open() == false)
- {
- try
- {
- d_dump_filename.append(boost::lexical_cast(d_channel));
- d_dump_filename.append(".dat");
- d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
- d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
- LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str();
- }
- catch (std::ifstream::failure e)
- {
- LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what();
- }
- }
- }
-}
-
-
-
-void galileo_e5a_dll_fll_pll_tracking_cc::set_channel_queue(concurrent_queue *channel_internal_queue)
-{
- d_channel_internal_queue = channel_internal_queue;
-}
-
-void galileo_e5a_dll_fll_pll_tracking_cc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
-{
- d_acquisition_gnss_synchro=p_gnss_synchro;
-}
diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_fll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_fll_pll_tracking_cc.h
deleted file mode 100644
index 3766bde0e..000000000
--- a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_fll_pll_tracking_cc.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*!
- * \file galileo_e5a_dll_fll_pll_tracking_cc.h
- * \brief Implementation of a code DLL + carrier PLL aided with FLL
- * tracking block for Galileo E5a signals
- * \author Marc Sales, 2014. marcsales92(at)gmail.com
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#ifndef GNSS_SDR_GALILEO_E5A_DLL_FLL_PLL_TRACKING_CC_H_
-#define GNSS_SDR_GALILEO_E5A_DLL_FLL_PLL_TRACKING_CC_H_
-
-#include
-#include
-#include