1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-16 13:10:35 +00:00

Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next

This commit is contained in:
Carles Fernandez 2018-07-21 12:41:08 +02:00
commit 71a23844f0
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
31 changed files with 580 additions and 169 deletions

View File

@ -62,12 +62,13 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4); acq_parameters.ms_per_code = 4;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
if ((acq_parameters.sampled_ms % 4) != 0) if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
{ {
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4"; LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4";
acq_parameters.sampled_ms = 4; acq_parameters.sampled_ms = acq_parameters.ms_per_code;
} }
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_; acq_parameters.bit_transition_flag = bit_transition_flag_;
@ -84,7 +85,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_; acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code (4 ms) ----------------- //--- Find number of samples per spreading code (4 ms) -----------------
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
float samples_per_ms = static_cast<float>(fs_in_) * 0.001; float samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_ms = samples_per_ms; acq_parameters.samples_per_ms = samples_per_ms;

View File

@ -103,6 +103,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GALILEO_E5a_CODE_PERIOD_MS); acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GALILEO_E5a_CODE_PERIOD_MS);
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);

View File

@ -101,6 +101,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD * 1000.0); acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD * 1000.0);
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);

View File

@ -100,6 +100,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD * 1000.0); acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD * 1000.0);
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);

View File

@ -71,6 +71,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.ms_per_code = 1;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_; acq_parameters.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
@ -83,15 +84,11 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
//--- Find number of samples per spreading code ------------------------- //--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
vector_length_ = code_length_ * sampled_ms_; acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
if (bit_transition_flag_)
{
vector_length_ *= 2;
}
vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1);
code_ = new gr_complex[vector_length_]; code_ = new gr_complex[vector_length_];
if (item_type_.compare("cshort") == 0) if (item_type_.compare("cshort") == 0)
@ -102,8 +99,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters); acquisition_ = pcps_make_acquisition(acq_parameters);

View File

@ -79,21 +79,17 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
acq_parameters.dump_filename = dump_filename_; acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code ------------------------- //--- Find number of samples per spreading code -------------------------
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 20); acq_parameters.ms_per_code = 20;
if ((acq_parameters.sampled_ms % 20) != 0) acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
{ {
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20"; LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20";
acq_parameters.sampled_ms = 20; acq_parameters.sampled_ms = acq_parameters.ms_per_code;
} }
code_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); code_length_ = acq_parameters.ms_per_code * acq_parameters.samples_per_ms;
vector_length_ = code_length_; vector_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
if (bit_transition_flag_)
{
vector_length_ *= 2;
}
code_ = new gr_complex[vector_length_]; code_ = new gr_complex[vector_length_];
@ -129,6 +125,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = 0; gnss_synchro_ = 0;
num_codes_ = acq_parameters.sampled_ms / acq_parameters.ms_per_code;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -217,9 +214,18 @@ void GpsL2MPcpsAcquisition::init()
void GpsL2MPcpsAcquisition::set_local_code() void GpsL2MPcpsAcquisition::set_local_code()
{ {
gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); std::complex<float>* code = new std::complex<float>[code_length_];
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
for (unsigned int i = 0; i < num_codes_; i++)
{
memcpy(&(code_[i * code_length_]), code,
sizeof(gr_complex) * code_length_);
}
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_);
delete[] code;
} }

View File

@ -160,6 +160,7 @@ private:
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
unsigned int num_codes_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -98,8 +98,10 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
} }
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L5i_PERIOD * 1000.0); acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L5i_PERIOD * 1000.0);
acq_parameters.ms_per_code = 1;
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
num_codes_ = acq_parameters.sampled_ms;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
@ -206,9 +208,18 @@ void GpsL5iPcpsAcquisition::init()
void GpsL5iPcpsAcquisition::set_local_code() void GpsL5iPcpsAcquisition::set_local_code()
{ {
gps_l5i_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); std::complex<float>* code = new std::complex<float>[code_length_];
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
for (unsigned int i = 0; i < num_codes_; i++)
{
memcpy(&(code_[i * code_length_]), code,
sizeof(gr_complex) * code_length_);
}
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_);
delete[] code;
} }

View File

@ -158,6 +158,7 @@ private:
std::complex<float>* code_; std::complex<float>* code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int num_codes_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;

View File

@ -52,8 +52,8 @@ pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_)
pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition", pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition",
gr::io_signature::make(1, 1, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)), gr::io_signature::make(1, 1, conf_.it_size * std::floor(conf_.sampled_ms * conf_.samples_per_ms) * (conf_.bit_transition_flag ? 2 : 1)),
gr::io_signature::make(0, 0, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1))) gr::io_signature::make(0, 0, conf_.it_size))
{ {
this->message_port_register_out(pmt::mp("events")); this->message_port_register_out(pmt::mp("events"));
@ -65,7 +65,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
d_old_freq = 0; d_old_freq = 0;
d_num_noncoherent_integrations_counter = 0; d_num_noncoherent_integrations_counter = 0;
d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
if (acq_parameters.sampled_ms == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms)) // if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
{ {
d_fft_size = d_consumed_samples; d_fft_size = d_consumed_samples;
} }
@ -205,7 +205,7 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
} }
else else
{ {
if (acq_parameters.sampled_ms == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms)) if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
{ {
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples); memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples);
} }
@ -798,7 +798,6 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
* 5. Compute the test statistics and compare to the threshold * 5. Compute the test statistics and compare to the threshold
* 6. Declare positive or negative acquisition using a message port * 6. Declare positive or negative acquisition using a message port
*/ */
gr::thread::scoped_lock lk(d_setlock); gr::thread::scoped_lock lk(d_setlock);
if (!d_active or d_worker_active) if (!d_active or d_worker_active)
{ {

View File

@ -35,6 +35,7 @@ Acq_Conf::Acq_Conf()
{ {
/* PCPS acquisition configuration */ /* PCPS acquisition configuration */
sampled_ms = 0; sampled_ms = 0;
ms_per_code = 0;
max_dwells = 0; max_dwells = 0;
samples_per_chip = 0; samples_per_chip = 0;
doppler_max = 0; doppler_max = 0;

View File

@ -40,6 +40,7 @@ class Acq_Conf
public: public:
/* PCPS Acquisition configuration */ /* PCPS Acquisition configuration */
unsigned int sampled_ms; unsigned int sampled_ms;
unsigned int ms_per_code;
unsigned int samples_per_chip; unsigned int samples_per_chip;
unsigned int max_dwells; unsigned int max_dwells;
unsigned int doppler_max; unsigned int doppler_max;

View File

@ -144,6 +144,7 @@ void gps_l1_ca_code_gen_complex(std::complex<float>* _dest, signed int _prn, uns
/* /*
* Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency * Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
* NOTICE: the number of samples is rounded towards zero (integer truncation)
*/ */
void gps_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs, unsigned int _chip_shift) void gps_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs, unsigned int _chip_shift)
{ {

View File

@ -200,7 +200,7 @@ function(VOLK_PYTHON_INSTALL)
add_custom_command( add_custom_command(
OUTPUT ${pyexefile} DEPENDS ${pyfile} OUTPUT ${pyexefile} DEPENDS ${pyfile}
COMMAND ${PYTHON_EXECUTABLE} -c COMMAND ${PYTHON_EXECUTABLE} -c
"open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())" "open('${pyexefile}','w').write(r'\#!${pyexe_native}'+'\\n'+open('${pyfile}').read())"
COMMENT "Shebangin ${pyfile_name}" COMMENT "Shebangin ${pyfile_name}"
VERBATIM VERBATIM
) )

View File

@ -238,4 +238,48 @@
<alignment>32</alignment> <alignment>32</alignment>
</arch> </arch>
<arch name="avx512f">
<!-- check for AVX512F -->
<check name="cpuid_count_x86_bit">
<param>7</param>
<param>0</param>
<param>1</param>
<param>16</param>
</check>
<!-- check to make sure that xgetbv is enabled in OS -->
<check name="cpuid_x86_bit">
<param>2</param>
<param>0x00000001</param>
<param>27</param>
</check>
<!-- check to see that the OS has enabled AVX512 -->
<check name="get_avx512_enabled"></check>
<flag compiler="gnu">-mavx512f</flag>
<flag compiler="clang">-mavx512f</flag>
<flag compiler="msvc">/arch:AVX512F</flag>
<alignment>64</alignment>
</arch>
<arch name="avx512cd">
<!-- check for AVX512CD -->
<check name="cpuid_count_x86_bit">
<param>7</param>
<param>0</param>
<param>1</param>
<param>28</param>
</check>
<!-- check to make sure that xgetbv is enabled in OS -->
<check name="cpuid_x86_bit">
<param>2</param>
<param>0x00000001</param>
<param>27</param>
</check>
<!-- check to see that the OS has enabled AVX512 -->
<check name="get_avx512_enabled"></check>
<flag compiler="gnu">-mavx512cd</flag>
<flag compiler="clang">-mavx512cd</flag>
<flag compiler="msvc">/arch:AVX512CD</flag>
<alignment>64</alignment>
</arch>
</grammar> </grammar>

View File

@ -51,4 +51,14 @@
<archs>generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx fma avx2 orc|</archs> <archs>generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx fma avx2 orc|</archs>
</machine> </machine>
<!-- trailing | bar means generate without either for MSVC -->
<machine name="avx512f">
<archs>generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx fma avx2 avx512f orc|</archs>
</machine>
<!-- trailing | bar means generate without either for MSVC -->
<machine name="avx512cd">
<archs>generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx fma avx2 avx512f avx512cd orc|</archs>
</machine>
</grammar> </grammar>

View File

@ -25,7 +25,7 @@ import six
archs = list() archs = list()
arch_dict = dict() arch_dict = dict()
class arch_class: class arch_class(object):
def __init__(self, flags, checks, **kwargs): def __init__(self, flags, checks, **kwargs):
for key, cast, failval in ( for key, cast, failval in (
('name', str, None), ('name', str, None),

View File

@ -118,10 +118,10 @@ def flatten_section_text(sections):
######################################################################## ########################################################################
# Extract kernel info from section, represent as an implementation # Extract kernel info from section, represent as an implementation
######################################################################## ########################################################################
class impl_class: class impl_class(object):
def __init__(self, kern_name, header, body): def __init__(self, kern_name, header, body):
#extract LV_HAVE_* #extract LV_HAVE_*
self.deps = set(map(str.lower, re.findall('LV_HAVE_(\w+)', header))) self.deps = set(res.lower() for res in re.findall('LV_HAVE_(\w+)', header))
#extract function suffix and args #extract function suffix and args
body = flatten_section_text(body) body = flatten_section_text(body)
try: try:
@ -153,18 +153,18 @@ def extract_lv_haves(code):
haves = list() haves = list()
for line in code.splitlines(): for line in code.splitlines():
if not line.strip().startswith('#'): continue if not line.strip().startswith('#'): continue
have_set = set(map(str.lower, re.findall('LV_HAVE_(\w+)', line))) have_set = set(res.lower() for res in re.findall('LV_HAVE_(\w+)', line))
if have_set: haves.append(have_set) if have_set: haves.append(have_set)
return haves return haves
######################################################################## ########################################################################
# Represent a processing kernel, parse from file # Represent a processing kernel, parse from file
######################################################################## ########################################################################
class kernel_class: class kernel_class(object):
def __init__(self, kernel_file): def __init__(self, kernel_file):
self.name = os.path.splitext(os.path.basename(kernel_file))[0] self.name = os.path.splitext(os.path.basename(kernel_file))[0]
self.pname = self.name.replace('volk_gnsssdr_', 'p_') self.pname = self.name.replace('volk_gnsssdr_', 'p_')
code = open(kernel_file, 'r').read() code = open(kernel_file, 'rb').read().decode("utf-8")
code = comment_remover(code) code = comment_remover(code)
sections = split_into_nested_ifdef_sections(code) sections = split_into_nested_ifdef_sections(code)
self._impls = list() self._impls = list()

View File

@ -26,7 +26,7 @@ from volk_gnsssdr_arch_defs import arch_dict
machines = list() machines = list()
machine_dict = dict() machine_dict = dict()
class machine_class: class machine_class(object):
def __init__(self, name, archs): def __init__(self, name, archs):
self.name = name self.name = name
self.archs = list() self.archs = list()
@ -36,7 +36,7 @@ class machine_class:
arch = arch_dict[arch_name] arch = arch_dict[arch_name]
self.archs.append(arch) self.archs.append(arch)
self.arch_names.append(arch_name) self.arch_names.append(arch_name)
self.alignment = max(map(lambda a: a.alignment, self.archs)) self.alignment = max([a.alignment for a in self.archs])
def __repr__(self): return self.name def __repr__(self): return self.name

View File

@ -179,6 +179,73 @@ static inline void volk_gnsssdr_16ic_convert_32fc_a_axv(lv_32fc_t* outputVector,
} }
#endif /* LV_HAVE_AVX */ #endif /* LV_HAVE_AVX */
#ifdef LV_HAVE_AVX2
#include <immintrin.h>
static inline void volk_gnsssdr_16ic_convert_32fc_a_avx2(lv_32fc_t* outputVector, const lv_16sc_t* inputVector, unsigned int num_points)
{
const unsigned int avx_iters = num_points / 8;
unsigned int number = 0;
const int16_t* complexVectorPtr = (int16_t*)inputVector;
float* outputVectorPtr = (float*)outputVector;
__m256 outVal;
__m256i outValInt;
__m128i cplxValue;
for (number = 0; number < avx_iters; number++)
{
cplxValue = _mm_load_si128((__m128i*)complexVectorPtr);
complexVectorPtr += 8;
outValInt = _mm256_cvtepi16_epi32(cplxValue);
outVal = _mm256_cvtepi32_ps(outValInt);
_mm256_store_ps((float*)outputVectorPtr, outVal);
outputVectorPtr += 8;
}
number = avx_iters * 8;
for (; number < num_points * 2; number++)
{
*outputVectorPtr++ = (float)*complexVectorPtr++;
}
}
#endif /* LV_HAVE_AVX2 */
#ifdef LV_HAVE_AVX2
#include <immintrin.h>
static inline void volk_gnsssdr_16ic_convert_32fc_u_avx2(lv_32fc_t* outputVector, const lv_16sc_t* inputVector, unsigned int num_points)
{
const unsigned int avx_iters = num_points / 8;
unsigned int number = 0;
const int16_t* complexVectorPtr = (int16_t*)inputVector;
float* outputVectorPtr = (float*)outputVector;
__m256 outVal;
__m256i outValInt;
__m128i cplxValue;
for (number = 0; number < avx_iters; number++)
{
cplxValue = _mm_loadu_si128((__m128i*)complexVectorPtr);
complexVectorPtr += 8;
outValInt = _mm256_cvtepi16_epi32(cplxValue);
outVal = _mm256_cvtepi32_ps(outValInt);
_mm256_storeu_ps((float*)outputVectorPtr, outVal);
outputVectorPtr += 8;
}
number = avx_iters * 8;
for (; number < num_points * 2; number++)
{
*outputVectorPtr++ = (float)*complexVectorPtr++;
}
}
#endif /* LV_HAVE_AVX2 */
#ifdef LV_HAVE_NEONV7 #ifdef LV_HAVE_NEONV7
#include <arm_neon.h> #include <arm_neon.h>

View File

@ -19,5 +19,5 @@
# #
# #
from cfg import volk_gnsssdr_modtool_config from .cfg import volk_gnsssdr_modtool_config
from volk_gnsssdr_modtool_generate import volk_gnsssdr_modtool from .volk_gnsssdr_modtool_generate import volk_gnsssdr_modtool

View File

@ -21,14 +21,13 @@
from __future__ import print_function from __future__ import print_function
import ConfigParser
import sys import sys
import os import os
import exceptions
import re import re
from six.moves import configparser, input
class volk_gnsssdr_modtool_config: class volk_gnsssdr_modtool_config(object):
def key_val_sub(self, num, stuff, section): def key_val_sub(self, num, stuff, section):
return re.sub('\$' + 'k' + str(num), stuff[num][0], (re.sub('\$' + str(num), stuff[num][1], section[1][num]))); return re.sub('\$' + 'k' + str(num), stuff[num][0], (re.sub('\$' + str(num), stuff[num][1], section[1][num])));
@ -46,11 +45,11 @@ class volk_gnsssdr_modtool_config:
try: try:
val = eval(self.key_val_sub(i, stuff, section)) val = eval(self.key_val_sub(i, stuff, section))
if val == False: if val == False:
raise exceptions.ValueError raise ValueError
except ValueError: except ValueError:
raise exceptions.ValueError('Verification function returns False... key:%s, val:%s'%(stuff[i][0], stuff[i][1])) raise ValueError('Verification function returns False... key:%s, val:%s'%(stuff[i][0], stuff[i][1]))
except: except:
raise exceptions.IOError('bad configuration... key:%s, val:%s'%(stuff[i][0], stuff[i][1])) raise IOError('bad configuration... key:%s, val:%s'%(stuff[i][0], stuff[i][1]))
def __init__(self, cfg=None): def __init__(self, cfg=None):
@ -66,7 +65,7 @@ class volk_gnsssdr_modtool_config:
self.remapification = [(self.config_name, self.config_defaults_remap)] self.remapification = [(self.config_name, self.config_defaults_remap)]
self.verification = [(self.config_name, self.config_defaults_verify)] self.verification = [(self.config_name, self.config_defaults_verify)]
default = os.path.join(os.getcwd(), 'volk_gnsssdr_modtool.cfg') default = os.path.join(os.getcwd(), 'volk_gnsssdr_modtool.cfg')
icfg = ConfigParser.RawConfigParser() icfg = configparser.RawConfigParser()
if cfg: if cfg:
icfg.read(cfg) icfg.read(cfg)
elif os.path.exists(default): elif os.path.exists(default):
@ -75,7 +74,7 @@ class volk_gnsssdr_modtool_config:
print("Initializing config file...") print("Initializing config file...")
icfg.add_section(self.config_name) icfg.add_section(self.config_name)
for kn in self.config_defaults: for kn in self.config_defaults:
rv = raw_input("%s: "%(kn)) rv = input("%s: "%(kn))
icfg.set(self.config_name, kn, rv) icfg.set(self.config_name, kn, rv)
self.cfg = icfg self.cfg = icfg
self.remap() self.remap()

View File

@ -18,10 +18,10 @@
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. # along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
# #
from __future__ import print_function
from volk_gnsssdr_modtool import volk_gnsssdr_modtool, volk_gnsssdr_modtool_config from volk_gnsssdr_modtool import volk_gnsssdr_modtool, volk_gnsssdr_modtool_config
from optparse import OptionParser, OptionGroup from optparse import OptionParser, OptionGroup
import exceptions
import os import os
import sys import sys
@ -57,12 +57,12 @@ if __name__ == '__main__':
parser.print_help() parser.print_help()
elif options.moo: elif options.moo:
print " (__) " print(" (__) ")
print " (oo) " print(" (oo) ")
print " /------\/ " print(" /------\/ ")
print " / | || " print(" / | || ")
print " * /\---/\ " print(" * /\---/\ ")
print " ~~ ~~ " print(" ~~ ~~ ")
else: else:
my_cfg = volk_gnsssdr_modtool_config(options.config_file); my_cfg = volk_gnsssdr_modtool_config(options.config_file);
@ -77,7 +77,7 @@ if __name__ == '__main__':
if options.add_kernel: if options.add_kernel:
if not options.kernel_name: if not options.kernel_name:
raise exceptions.IOError("This action requires the -n option."); raise IOError("This action requires the -n option.");
else: else:
name = options.kernel_name; name = options.kernel_name;
if options.base_path: if options.base_path:
@ -88,7 +88,7 @@ if __name__ == '__main__':
if options.remove_kernel: if options.remove_kernel:
if not options.kernel_name: if not options.kernel_name:
raise exceptions.IOError("This action requires the -n option."); raise IOError("This action requires the -n option.");
else: else:
name = options.kernel_name; name = options.kernel_name;
my_modtool.remove_kernel(name); my_modtool.remove_kernel(name);
@ -105,17 +105,17 @@ if __name__ == '__main__':
if options.remote_list: if options.remote_list:
if not options.base_path: if not options.base_path:
raise exceptions.IOError("This action requires the -b option. Try -l or -k for listing kernels in the base or the module.") raise IOError("This action requires the -b option. Try -l or -k for listing kernels in the base or the module.")
else: else:
base = options.base_path; base = options.base_path;
kernelset = my_modtool.get_current_kernels(base); kernelset = my_modtool.get_current_kernels(base);
for i in kernelset: for i in kernelset:
print i; print(i);
if options.list: if options.list:
kernelset = my_modtool.get_current_kernels(); kernelset = my_modtool.get_current_kernels();
for i in kernelset: for i in kernelset:
print i; print(i);
if options.kernels: if options.kernels:
dest = my_cfg.cfg.get(my_cfg.config_name, 'destination'); dest = my_cfg.cfg.get(my_cfg.config_name, 'destination');
@ -123,4 +123,4 @@ if __name__ == '__main__':
base = os.path.join(dest, 'volk_gnsssdr_' + name); base = os.path.join(dest, 'volk_gnsssdr_' + name);
kernelset = my_modtool.get_current_kernels(base); kernelset = my_modtool.get_current_kernels(base);
for i in kernelset: for i in kernelset:
print i; print(i);

View File

@ -21,15 +21,10 @@
from __future__ import print_function from __future__ import print_function
import os import os
import glob
import sys
import re import re
import glob import glob
import shutil
import exceptions
from sets import Set
class volk_gnsssdr_modtool: class volk_gnsssdr_modtool(object):
def __init__(self, cfg): def __init__(self, cfg):
self.volk_gnsssdr = re.compile('volk_gnsssdr'); self.volk_gnsssdr = re.compile('volk_gnsssdr');
self.remove_after_underscore = re.compile("_.*"); self.remove_after_underscore = re.compile("_.*");
@ -96,7 +91,7 @@ class volk_gnsssdr_modtool:
dest = os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name']) dest = os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name'])
if os.path.exists(dest): if os.path.exists(dest):
raise exceptions.IOError("Destination %s already exits!"%(dest)); raise IOError("Destination %s already exits!" % (dest));
if not os.path.exists(os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name'], 'kernels/volk_gnsssdr_' + self.my_dict['name'])): if not os.path.exists(os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name'], 'kernels/volk_gnsssdr_' + self.my_dict['name'])):
os.makedirs(os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name'], 'kernels/volk_gnsssdr_' + self.my_dict['name'])) os.makedirs(os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name'], 'kernels/volk_gnsssdr_' + self.my_dict['name']))
@ -108,7 +103,7 @@ class volk_gnsssdr_modtool:
for root, dirnames, filenames in os.walk(self.my_dict['base']): for root, dirnames, filenames in os.walk(self.my_dict['base']):
for name in filenames: for name in filenames:
t_table = map(lambda a: re.search(a, name), current_kernel_names); t_table = [re.search(a, name) for a in current_kernel_names]
t_table = set(t_table); t_table = set(t_table);
if t_table == set([None]): if t_table == set([None]):
infile = os.path.join(root, name); infile = os.path.join(root, name);
@ -188,16 +183,11 @@ class volk_gnsssdr_modtool:
base = os.path.join(self.my_dict['destination'], top[:-1]) ; base = os.path.join(self.my_dict['destination'], top[:-1]) ;
if not name in self.get_current_kernels(): if not name in self.get_current_kernels():
raise IOError("Requested kernel %s is not in module %s" % (name,base));
raise exceptions.IOError("Requested kernel %s is not in module %s"%(name,base));
inpath = os.path.abspath(base); inpath = os.path.abspath(base);
kernel = re.compile(name) kernel = re.compile(name)
search_kernels = Set([kernel]) search_kernels = set([kernel])
profile = re.compile('^\s*VOLK_PROFILE') profile = re.compile('^\s*VOLK_PROFILE')
puppet = re.compile('^\s*VOLK_PUPPET') puppet = re.compile('^\s*VOLK_PUPPET')
src_dest = os.path.join(inpath, 'apps/', top[:-1] + '_profile.cc'); src_dest = os.path.join(inpath, 'apps/', top[:-1] + '_profile.cc');
@ -253,7 +243,7 @@ class volk_gnsssdr_modtool:
else: else:
basename = self.get_basename(base); basename = self.get_basename(base);
if not name in self.get_current_kernels(base): if not name in self.get_current_kernels(base):
raise exceptions.IOError("Requested kernel %s is not in module %s"%(name,base)); raise IOError("Requested kernel %s is not in module %s" % (name, base));
inpath = os.path.abspath(base); inpath = os.path.abspath(base);
if len(basename) > 0: if len(basename) > 0:
@ -265,7 +255,7 @@ class volk_gnsssdr_modtool:
self.convert_kernel(oldvolk_gnsssdr, name, base, inpath, top); self.convert_kernel(oldvolk_gnsssdr, name, base, inpath, top);
kernel = re.compile(name) kernel = re.compile(name)
search_kernels = Set([kernel]) search_kernels = set([kernel])
profile = re.compile('^\s*VOLK_PROFILE') profile = re.compile('^\s*VOLK_PROFILE')
puppet = re.compile('^\s*VOLK_PUPPET') puppet = re.compile('^\s*VOLK_PUPPET')

View File

@ -123,6 +123,15 @@ static inline unsigned int get_avx2_enabled(void)
#endif #endif
} }
static inline unsigned int get_avx512_enabled(void)
{
#if defined(VOLK_CPU_x86)
return __xgetbv() & 0xE6; //check for zmm, xmm and ymm regs
#else
return 0;
#endif
}
//neon detection is linux specific //neon detection is linux specific
#if defined(__arm__) && defined(__linux__) #if defined(__arm__) && defined(__linux__)
#include <asm/hwcap.h> #include <asm/hwcap.h>

View File

@ -34,9 +34,15 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <limits> #include <limits>
DEFINE_string(trk_test_implementation, std::string("GPS_L1_CA_DLL_PLL_Tracking"), "Tracking block implementation under test, defaults to GPS_L1_CA_DLL_PLL_Tracking");
// Input signal configuration // Input signal configuration
DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator"); DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator");
DEFINE_int32(external_signal_acquisition_threshold, 2.0, "Threshold for satellite acquisition when external file is used"); DEFINE_double(external_signal_acquisition_threshold, 2.5, "Threshold for satellite acquisition when external file is used");
DEFINE_int32(external_signal_acquisition_dwells, 5, "Maximum dwells count for satellite acquisition when external file is used");
DEFINE_double(external_signal_acquisition_doppler_max_hz, 5000.0, "Doppler max for satellite acquisition when external file is used");
DEFINE_double(external_signal_acquisition_doppler_step_hz, 125, "Doppler step for satellite acquisition when external file is used");
DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file"); DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file");
DEFINE_double(CN0_dBHz_start, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); DEFINE_double(CN0_dBHz_start, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]");
DEFINE_double(CN0_dBHz_stop, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); DEFINE_double(CN0_dBHz_stop, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]");

View File

@ -148,7 +148,7 @@ DECLARE_string(log_dir);
#include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc"
#include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" #include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc"
#include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc"
#endif #endif

View File

@ -45,6 +45,7 @@
#include "true_observables_reader.h" #include "true_observables_reader.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <gnuradio/top_block.h> #include <gnuradio/top_block.h>
#include <gnuradio/blocks/skiphead.h>
DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test."); DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test.");
@ -78,6 +79,7 @@ DEFINE_int32(acq_test_fake_PRN, 33, "PRN number of a non-present satellite");
DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)"); DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)");
DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available"); DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available");
DEFINE_int32(acq_test_skiphead, 0, "Number of samples to skip in the input file");
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class AcqPerfTest_msg_rx; class AcqPerfTest_msg_rx;
@ -551,6 +553,7 @@ int AcquisitionPerformanceTest::run_receiver()
top_block = gr::make_top_block("Acquisition test"); top_block = gr::make_top_block("Acquisition test");
boost::shared_ptr<AcqPerfTest_msg_rx> msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue); boost::shared_ptr<AcqPerfTest_msg_rx> msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue);
gr::blocks::skiphead::sptr skiphead = gr::blocks::skiphead::make(sizeof(gr_complex), FLAGS_acq_test_skiphead);
queue = gr::msg_queue::make(0); queue = gr::msg_queue::make(0);
gnss_synchro = Gnss_Synchro(); gnss_synchro = Gnss_Synchro();
@ -609,7 +612,8 @@ int AcquisitionPerformanceTest::run_receiver()
acquisition->reset(); acquisition->reset();
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
top_block->connect(gr_interleaved_char_to_complex, 0, valve, 0); top_block->connect(gr_interleaved_char_to_complex, 0, skiphead, 0);
top_block->connect(skiphead, 0, valve, 0);
top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0);
top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));

View File

@ -58,6 +58,8 @@
#include "signal_generator_flags.h" #include "signal_generator_flags.h"
#include "gnss_sdr_sample_counter.h" #include "gnss_sdr_sample_counter.h"
#include <matio.h> #include <matio.h>
#include "test_flags.h"
#include "gnuplot_i.h"
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES ######### // ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES #########
@ -183,6 +185,7 @@ public:
int configure_generator(); int configure_generator();
int generate_signal(); int generate_signal();
bool save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename);
void check_results_carrier_phase( void check_results_carrier_phase(
arma::mat& true_ch0, arma::mat& true_ch0,
arma::mat& true_ch1, arma::mat& true_ch1,
@ -283,10 +286,12 @@ void HybridObservablesTest::configure_receiver()
config->set_property("Tracking_1C.item_type", "gr_complex"); config->set_property("Tracking_1C.item_type", "gr_complex");
config->set_property("Tracking_1C.dump", "true"); config->set_property("Tracking_1C.dump", "true");
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_");
config->set_property("Tracking_1C.pll_bw_hz", "35.0"); config->set_property("Tracking_1C.pll_bw_hz", "5.0");
config->set_property("Tracking_1C.dll_bw_hz", "0.5"); config->set_property("Tracking_1C.dll_bw_hz", "0.20");
config->set_property("Tracking_1C.pll_bw_narrow_hz", "1.0");
config->set_property("Tracking_1C.dll_bw_narrow_hz", "0.1");
config->set_property("Tracking_1C.extend_correlation_symbols", "20");
config->set_property("Tracking_1C.early_late_space_chips", "0.5"); config->set_property("Tracking_1C.early_late_space_chips", "0.5");
config->set_property("Tracking_1C.unified", "true");
config->set_property("TelemetryDecoder_1C.dump", "true"); config->set_property("TelemetryDecoder_1C.dump", "true");
config->set_property("Observables.dump", "true"); config->set_property("Observables.dump", "true");
@ -384,6 +389,41 @@ void HybridObservablesTest::check_results_carrier_phase(
} }
bool HybridObservablesTest::save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename)
{
try
{
// WRITE MAT FILE
mat_t* matfp;
matvar_t* matvar;
filename.append(".mat");
std::cout << "save_mat_xy write " << filename << std::endl;
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5);
if (reinterpret_cast<long*>(matfp) != NULL)
{
size_t dims[2] = {1, x.size()};
matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
}
else
{
std::cout << "save_mat_xy: error creating file" << std::endl;
}
Mat_Close(matfp);
return true;
}
catch (const std::exception& ex)
{
std::cout << "save_mat_xy: " << ex.what() << std::endl;
return false;
}
}
void HybridObservablesTest::check_results_code_psudorange( void HybridObservablesTest::check_results_code_psudorange(
arma::mat& true_ch0, arma::mat& true_ch0,
arma::mat& true_ch1, arma::mat& true_ch1,
@ -397,7 +437,12 @@ void HybridObservablesTest::check_results_code_psudorange(
int size1 = measured_ch0.col(0).n_rows; int size1 = measured_ch0.col(0).n_rows;
int size2 = measured_ch1.col(0).n_rows; int size2 = measured_ch1.col(0).n_rows;
double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0)); double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0));
arma::vec t = arma::linspace<arma::vec>(t0, t1, floor((t1 - t0) * 1e3)); arma::vec t = arma::linspace<arma::vec>(t0, t1, floor((t1 - t0) * 1e3));
//conversion between arma::vec and std:vector
arma::vec t_from_start = arma::linspace<arma::vec>(0, t1 - t0, floor((t1 - t0) * 1e3));
std::vector<double> time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows);
arma::vec true_ch0_dist_interp; arma::vec true_ch0_dist_interp;
arma::vec true_ch1_dist_interp; arma::vec true_ch1_dist_interp;
@ -438,6 +483,31 @@ void HybridObservablesTest::check_results_code_psudorange(
<< " [meters]" << std::endl; << " [meters]" << std::endl;
std::cout.precision(ss); std::cout.precision(ss);
//plots
Gnuplot g3("linespoints");
g3.set_title("Delta Pseudorange error [m]");
g3.set_grid();
g3.set_xlabel("Time [s]");
g3.set_ylabel("Pseudorange error [m]");
//conversion between arma::vec and std:vector
std::vector<double> range_error_m(err.colptr(0), err.colptr(0) + err.n_rows);
g3.cmd("set key box opaque");
g3.plot_xy(time_vector, range_error_m,
"Delta pseudorrange error");
g3.set_legend();
g3.savetops("Delta_pseudorrange_error");
g3.savetopdf("Delta_pseudorrange_error", 18);
if (FLAGS_show_plots)
{
g3.showonscreen(); // window output
}
else
{
g3.disablescreen();
}
//check results against the test tolerance
ASSERT_LT(rmse, 0.5); ASSERT_LT(rmse, 0.5);
ASSERT_LT(error_mean, 0.5); ASSERT_LT(error_mean, 0.5);
ASSERT_GT(error_mean, -0.5); ASSERT_GT(error_mean, -0.5);
@ -468,7 +538,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
tracking_true_obs_reader true_obs_data_ch1; tracking_true_obs_reader true_obs_data_ch1;
int test_satellite_PRN = FLAGS_test_satellite_PRN; int test_satellite_PRN = FLAGS_test_satellite_PRN;
int test_satellite_PRN2 = FLAGS_test_satellite_PRN2; int test_satellite_PRN2 = FLAGS_test_satellite_PRN2;
std::cout << "Testing satellite PRNs " << test_satellite_PRN << "," << test_satellite_PRN << std::endl; std::cout << "Testing satellite PRNs " << test_satellite_PRN << "," << test_satellite_PRN2 << std::endl;
std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); std::string true_obs_file = std::string("./gps_l1_ca_obs_prn");
true_obs_file.append(std::to_string(test_satellite_PRN)); true_obs_file.append(std::to_string(test_satellite_PRN));
true_obs_file.append(".dat"); true_obs_file.append(".dat");
@ -700,6 +770,21 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
} }
//Cut measurement initial transitory of the measurements //Cut measurement initial transitory of the measurements
double initial_transitory_s = 30.0;
index = arma::find(measured_ch0.col(0) >= (measured_ch0(0, 0) + initial_transitory_s), 1, "first");
if ((index.size() > 0) and (index(0) > 0))
{
measured_ch0.shed_rows(0, index(0));
}
index = arma::find(measured_ch1.col(0) >= (measured_ch1(0, 0) + initial_transitory_s), 1, "first");
if ((index.size() > 0) and (index(0) > 0))
{
measured_ch1.shed_rows(0, index(0));
}
index = arma::find(measured_ch0.col(0) >= true_ch0(0, 0), 1, "first"); index = arma::find(measured_ch0.col(0) >= true_ch0(0, 0), 1, "first");
if ((index.size() > 0) and (index(0) > 0)) if ((index.size() > 0) and (index(0) > 0))
{ {

View File

@ -339,7 +339,8 @@ std::vector<double> GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a
// 2. RMSE // 2. RMSE
arma::vec err; arma::vec err;
err = meas_value - true_value_interp; //it is required to remove the initial offset in the accumulated carrier phase error
err = (meas_value - meas_value(0)) - (true_value_interp - true_value_interp(0));
arma::vec err2 = arma::square(err); arma::vec err2 = arma::square(err);
//conversion between arma::vec and std:vector //conversion between arma::vec and std:vector
std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows); std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows);
@ -539,6 +540,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
std::vector<std::vector<double>> doppler_error_sweep; std::vector<std::vector<double>> doppler_error_sweep;
std::vector<std::vector<double>> code_phase_error_sweep; std::vector<std::vector<double>> code_phase_error_sweep;
std::vector<std::vector<double>> code_phase_error_meters_sweep;
std::vector<std::vector<double>> acc_carrier_phase_error_sweep; std::vector<std::vector<double>> acc_carrier_phase_error_sweep;
std::vector<double> mean_doppler_error; std::vector<double> mean_doppler_error;
@ -696,6 +698,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
{ {
std::vector<double> doppler_error_hz; std::vector<double> doppler_error_hz;
std::vector<double> code_phase_error_chips; std::vector<double> code_phase_error_chips;
std::vector<double> code_phase_error_meters;
std::vector<double> acc_carrier_phase_hz; std::vector<double> acc_carrier_phase_hz;
try try
@ -744,6 +747,10 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
rmse_doppler.push_back(rmse); rmse_doppler.push_back(rmse);
code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error, rmse); code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error, rmse);
for (unsigned int ii = 0; ii < code_phase_error_chips.size(); ii++)
{
code_phase_error_meters.push_back(GPS_L1_CA_CHIP_PERIOD * code_phase_error_chips.at(ii) * GPS_C_m_s);
}
mean_code_phase_error.push_back(mean_error); mean_code_phase_error.push_back(mean_error);
std_dev_code_phase_error.push_back(std_dev_error); std_dev_code_phase_error.push_back(std_dev_error);
rmse_code_phase.push_back(rmse); rmse_code_phase.push_back(rmse);
@ -759,6 +766,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
doppler_error_sweep.push_back(doppler_error_hz); doppler_error_sweep.push_back(doppler_error_hz);
code_phase_error_sweep.push_back(code_phase_error_chips); code_phase_error_sweep.push_back(code_phase_error_chips);
code_phase_error_meters_sweep.push_back(code_phase_error_meters);
acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz);
} }
else else
@ -920,13 +928,48 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
} }
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
code_phase_error_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx),
"Code_error_" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + "Code_error_chips" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
} }
g5.set_legend(); g5.set_legend();
g5.set_legend(); g5.set_legend();
g5.savetops("Code_error_output"); g5.savetops("Code_error_chips");
g5.savetopdf("Code_error_output", 18); g5.savetopdf("Code_error_chips", 18);
Gnuplot g5b("points");
if (FLAGS_show_plots)
{
g5b.showonscreen(); // window output
}
else
{
g5b.disablescreen();
}
g5b.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
g5b.set_grid();
g5b.set_xlabel("Time [s]");
g5b.set_ylabel("Code delay error [meters]");
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++)
{
try
{
g5b.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_meters_sweep.at(current_cn0_idx),
std::to_string(static_cast<int>(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz]", decimate);
}
catch (const GnuplotException& ge)
{
}
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
code_phase_error_sweep.at(current_cn0_idx),
"Code_error_meters" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
}
g5b.set_legend();
g5b.set_legend();
g5b.savetops("Code_error_meters");
g5b.savetopdf("Code_error_meters", 18);
Gnuplot g6("points"); Gnuplot g6("points");
@ -956,13 +999,13 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
} }
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
acc_carrier_phase_error_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx),
"Carrier_phase_error_output" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + "Carrier_phase_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
} }
g6.set_legend(); g6.set_legend();
g6.set_legend(); g6.set_legend();
g6.savetops("Carrier_phase_error_output"); g6.savetops("Acc_carrier_phase_error_cycles");
g6.savetopdf("Carrier_phase_error_output", 18); g6.savetopdf("Acc_carrier_phase_error_cycles", 18);
Gnuplot g4("points"); Gnuplot g4("points");
if (FLAGS_show_plots) if (FLAGS_show_plots)
@ -994,12 +1037,12 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
doppler_error_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx),
"Doppler_error_output" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + "Doppler_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
} }
g4.unset_multiplot(); g4.unset_multiplot();
g4.savetops("Doppler_error_output"); g4.savetops("Doppler_error_hz");
g4.savetopdf("Doppler_error_output", 18); g4.savetopdf("Doppler_error_hz", 18);
} }
} }
} }
@ -1039,7 +1082,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
for (unsigned int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) for (unsigned int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++)
{ {
g7.plot_xy_err(generator_CN0_values_sweep_copy.at(config_sweep_idx), g7.plot_xy_err(generator_CN0_values_sweep_copy.at(config_sweep_idx),
generator_CN0_values_sweep_copy.at(config_sweep_idx), mean_doppler_error_sweep.at(config_sweep_idx),
std_dev_doppler_error_sweep.at(config_sweep_idx), std_dev_doppler_error_sweep.at(config_sweep_idx),
"PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
+"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz");

View File

@ -1,5 +1,5 @@
/*! /*!
* \file gps_l1_ca_dll_pll_tracking_test.cc * \file tracking_test.cc
* \brief This class implements a tracking Pull-In test for GPS_L1_CA_DLL_PLL_Tracking * \brief This class implements a tracking Pull-In test for GPS_L1_CA_DLL_PLL_Tracking
* implementation based on some input parameters. * implementation based on some input parameters.
* \author Javier Arribas, 2018. jarribas(at)cttc.es * \author Javier Arribas, 2018. jarribas(at)cttc.es
@ -45,8 +45,12 @@
#include "GPS_L1_CA.h" #include "GPS_L1_CA.h"
#include "gnss_block_factory.h" #include "gnss_block_factory.h"
#include "tracking_interface.h" #include "tracking_interface.h"
#include "gps_l2_m_pcps_acquisition.h"
#include "gps_l1_ca_pcps_acquisition.h" #include "gps_l1_ca_pcps_acquisition.h"
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h" #include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
#include "galileo_e5a_noncoherent_iq_acquisition_caf.h"
#include "galileo_e5a_pcps_acquisition.h"
#include "gps_l5i_pcps_acquisition.h"
#include "in_memory_configuration.h" #include "in_memory_configuration.h"
#include "tracking_true_obs_reader.h" #include "tracking_true_obs_reader.h"
#include "tracking_dump_reader.h" #include "tracking_dump_reader.h"
@ -110,32 +114,32 @@ Acquisition_msg_rx::Acquisition_msg_rx() : gr::block("Acquisition_msg_rx", gr::i
Acquisition_msg_rx::~Acquisition_msg_rx() {} Acquisition_msg_rx::~Acquisition_msg_rx() {}
// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER ######### // ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER #########
class GpsL1CADllPllTrackingPullInTest_msg_rx; class TrackingPullInTest_msg_rx;
typedef boost::shared_ptr<GpsL1CADllPllTrackingPullInTest_msg_rx> GpsL1CADllPllTrackingPullInTest_msg_rx_sptr; typedef boost::shared_ptr<TrackingPullInTest_msg_rx> TrackingPullInTest_msg_rx_sptr;
GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make(); TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make();
class GpsL1CADllPllTrackingPullInTest_msg_rx : public gr::block class TrackingPullInTest_msg_rx : public gr::block
{ {
private: private:
friend GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make(); friend TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make();
void msg_handler_events(pmt::pmt_t msg); void msg_handler_events(pmt::pmt_t msg);
GpsL1CADllPllTrackingPullInTest_msg_rx(); TrackingPullInTest_msg_rx();
public: public:
int rx_message; int rx_message;
~GpsL1CADllPllTrackingPullInTest_msg_rx(); //!< Default destructor ~TrackingPullInTest_msg_rx(); //!< Default destructor
}; };
GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make() TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make()
{ {
return GpsL1CADllPllTrackingPullInTest_msg_rx_sptr(new GpsL1CADllPllTrackingPullInTest_msg_rx()); return TrackingPullInTest_msg_rx_sptr(new TrackingPullInTest_msg_rx());
} }
void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg) void TrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
{ {
try try
{ {
@ -151,22 +155,22 @@ void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
} }
GpsL1CADllPllTrackingPullInTest_msg_rx::GpsL1CADllPllTrackingPullInTest_msg_rx() : gr::block("GpsL1CADllPllTrackingPullInTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) TrackingPullInTest_msg_rx::TrackingPullInTest_msg_rx() : gr::block("TrackingPullInTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0))
{ {
this->message_port_register_in(pmt::mp("events")); this->message_port_register_in(pmt::mp("events"));
this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events, this, _1)); this->set_msg_handler(pmt::mp("events"), boost::bind(&TrackingPullInTest_msg_rx::msg_handler_events, this, _1));
rx_message = 0; rx_message = 0;
} }
GpsL1CADllPllTrackingPullInTest_msg_rx::~GpsL1CADllPllTrackingPullInTest_msg_rx() TrackingPullInTest_msg_rx::~TrackingPullInTest_msg_rx()
{ {
} }
// ########################################################### // ###########################################################
class GpsL1CADllPllTrackingPullInTest : public ::testing::Test class TrackingPullInTest : public ::testing::Test
{ {
public: public:
std::string generator_binary; std::string generator_binary;
@ -176,7 +180,7 @@ public:
std::string p4; std::string p4;
std::string p5; std::string p5;
std::string p6; std::string p6;
std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking"; //"GPS_L1_CA_DLL_PLL_C_Aid_Tracking"; std::string implementation = FLAGS_trk_test_implementation;
const int baseband_sampling_freq = FLAGS_fs_gen_sps; const int baseband_sampling_freq = FLAGS_fs_gen_sps;
@ -208,7 +212,7 @@ public:
double& mean_error, double& mean_error,
double& std_dev_error); double& std_dev_error);
GpsL1CADllPllTrackingPullInTest() TrackingPullInTest()
{ {
factory = std::make_shared<GNSSBlockFactory>(); factory = std::make_shared<GNSSBlockFactory>();
config = std::make_shared<InMemoryConfiguration>(); config = std::make_shared<InMemoryConfiguration>();
@ -216,7 +220,7 @@ public:
gnss_synchro = Gnss_Synchro(); gnss_synchro = Gnss_Synchro();
} }
~GpsL1CADllPllTrackingPullInTest() ~TrackingPullInTest()
{ {
} }
@ -235,7 +239,7 @@ public:
}; };
int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx) int TrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx)
{ {
// Configure signal generator // Configure signal generator
generator_binary = FLAGS_generator_binary; generator_binary = FLAGS_generator_binary;
@ -257,7 +261,7 @@ int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int fi
} }
int GpsL1CADllPllTrackingPullInTest::generate_signal() int TrackingPullInTest::generate_signal()
{ {
int child_status; int child_status;
@ -280,48 +284,104 @@ int GpsL1CADllPllTrackingPullInTest::generate_signal()
} }
void GpsL1CADllPllTrackingPullInTest::configure_receiver( void TrackingPullInTest::configure_receiver(
double PLL_wide_bw_hz, double PLL_wide_bw_hz,
double DLL_wide_bw_hz, double DLL_wide_bw_hz,
double PLL_narrow_bw_hz, double PLL_narrow_bw_hz,
double DLL_narrow_bw_hz, double DLL_narrow_bw_hz,
int extend_correlation_symbols) int extend_correlation_symbols)
{ {
gnss_synchro.Channel_ID = 0;
gnss_synchro.System = 'G';
std::string signal = "1C";
signal.copy(gnss_synchro.Signal, 2, 0);
gnss_synchro.PRN = FLAGS_test_satellite_PRN;
config = std::make_shared<InMemoryConfiguration>(); config = std::make_shared<InMemoryConfiguration>();
config->set_property("Tracking.dump", "true");
config->set_property("Tracking.dump_filename", "./tracking_ch_");
config->set_property("Tracking.implementation", implementation);
config->set_property("Tracking.item_type", "gr_complex");
config->set_property("Tracking.pll_bw_hz", std::to_string(PLL_wide_bw_hz));
config->set_property("Tracking.dll_bw_hz", std::to_string(DLL_wide_bw_hz));
config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols));
config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz));
config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz));
gnss_synchro.PRN = FLAGS_test_satellite_PRN;
gnss_synchro.Channel_ID = 0;
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
// Set Tracking
config->set_property("Tracking_1C.implementation", implementation); std::string System_and_Signal;
config->set_property("Tracking_1C.item_type", "gr_complex"); if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0)
config->set_property("Tracking_1C.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); {
config->set_property("Tracking_1C.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); gnss_synchro.System = 'G';
config->set_property("Tracking_1C.early_late_space_chips", "0.5"); std::string signal = "1C";
config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); System_and_Signal = "GPS L1 CA";
config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); signal.copy(gnss_synchro.Signal, 2, 0);
config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); config->set_property("Tracking.early_late_space_chips", "0.5");
config->set_property("Tracking_1C.early_late_space_narrow_chips", "0.5"); config->set_property("Tracking.early_late_space_narrow_chips", "0.5");
config->set_property("Tracking_1C.dump", "true"); }
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
{
gnss_synchro.System = 'E';
std::string signal = "1B";
System_and_Signal = "Galileo E1B";
signal.copy(gnss_synchro.Signal, 2, 0);
config->set_property("Tracking.early_late_space_chips", "0.15");
config->set_property("Tracking.very_early_late_space_chips", "0.6");
config->set_property("Tracking.early_late_space_narrow_chips", "0.15");
config->set_property("Tracking.very_early_late_space_narrow_chips", "0.6");
config->set_property("Tracking.track_pilot", "true");
}
else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0)
{
gnss_synchro.System = 'G';
std::string signal = "2S";
System_and_Signal = "GPS L2CM";
signal.copy(gnss_synchro.Signal, 2, 0);
config->set_property("Tracking.early_late_space_chips", "0.5");
config->set_property("Tracking.track_pilot", "false");
}
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0 or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
{
gnss_synchro.System = 'E';
std::string signal = "5X";
System_and_Signal = "Galileo E5a";
signal.copy(gnss_synchro.Signal, 2, 0);
if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
{
config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking"));
}
config->set_property("Tracking.early_late_space_chips", "0.5");
config->set_property("Tracking.track_pilot", "false");
config->set_property("Tracking.order", "2");
}
else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)
{
gnss_synchro.System = 'G';
std::string signal = "L5";
System_and_Signal = "GPS L5I";
signal.copy(gnss_synchro.Signal, 2, 0);
config->set_property("Tracking.early_late_space_chips", "0.5");
config->set_property("Tracking.track_pilot", "false");
config->set_property("Tracking.order", "2");
}
else
{
std::cout << "The test can not run with the selected tracking implementation\n ";
throw(std::exception());
}
std::cout << "*****************************************\n"; std::cout << "*****************************************\n";
std::cout << "*** Tracking configuration parameters ***\n"; std::cout << "*** Tracking configuration parameters ***\n";
std::cout << "*****************************************\n"; std::cout << "*****************************************\n";
std::cout << "pll_bw_hz: " << config->property("Tracking_1C.pll_bw_hz", 0.0) << " Hz\n"; std::cout << "Signal: " << System_and_Signal << "\n";
std::cout << "dll_bw_hz: " << config->property("Tracking_1C.dll_bw_hz", 0.0) << " Hz\n"; std::cout << "implementation: " << config->property("Tracking.implementation", std::string("undefined")) << " \n";
std::cout << "pll_bw_narrow_hz: " << config->property("Tracking_1C.pll_bw_narrow_hz", 0.0) << " Hz\n"; std::cout << "pll_bw_hz: " << config->property("Tracking.pll_bw_hz", 0.0) << " Hz\n";
std::cout << "dll_bw_narrow_hz: " << config->property("Tracking_1C.dll_bw_narrow_hz", 0.0) << " Hz\n"; std::cout << "dll_bw_hz: " << config->property("Tracking.dll_bw_hz", 0.0) << " Hz\n";
std::cout << "extend_correlation_symbols: " << config->property("Tracking_1C.extend_correlation_symbols", 0) << " Symbols\n"; std::cout << "pll_bw_narrow_hz: " << config->property("Tracking.pll_bw_narrow_hz", 0.0) << " Hz\n";
std::cout << "dll_bw_narrow_hz: " << config->property("Tracking.dll_bw_narrow_hz", 0.0) << " Hz\n";
std::cout << "extend_correlation_symbols: " << config->property("Tracking.extend_correlation_symbols", 0) << " Symbols\n";
std::cout << "*****************************************\n"; std::cout << "*****************************************\n";
std::cout << "*****************************************\n"; std::cout << "*****************************************\n";
} }
bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
{ {
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
gr::top_block_sptr top_block; gr::top_block_sptr top_block;
@ -330,45 +390,110 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
// Satellite signal definition // Satellite signal definition
Gnss_Synchro tmp_gnss_synchro; Gnss_Synchro tmp_gnss_synchro;
tmp_gnss_synchro.Channel_ID = 0; tmp_gnss_synchro.Channel_ID = 0;
tmp_gnss_synchro.System = 'G';
std::string signal = "1C";
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
tmp_gnss_synchro.PRN = SV_ID;
config = std::make_shared<InMemoryConfiguration>(); config = std::make_shared<InMemoryConfiguration>();
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
config->set_property("Acquisition.max_dwells", "10");
config->set_property("Acquisition.blocking_on_standby", "true"); config->set_property("Acquisition.blocking_on_standby", "true");
config->set_property("Acquisition.dump", "true"); config->set_property("Acquisition.blocking", "true");
config->set_property("Acquisition.dump", "false");
config->set_property("Acquisition.dump_filename", "./data/acquisition.dat"); config->set_property("Acquisition.dump_filename", "./data/acquisition.dat");
config->set_property("Acquisition.use_CFAR_algorithm", "false"); config->set_property("Acquisition.use_CFAR_algorithm", "false");
GpsL1CaPcpsAcquisitionFineDoppler* acquisition;
acquisition = new GpsL1CaPcpsAcquisitionFineDoppler(config.get(), "Acquisition", 1, 0);
//GpsL1CaPcpsAcquisition* acquisition; std::shared_ptr<AcquisitionInterface> acquisition;
//acquisition = new GpsL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 0);
std::string System_and_Signal;
//create the correspondign acquisition block according to the desired tracking signal
if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'G';
std::string signal = "1C";
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
tmp_gnss_synchro.PRN = SV_ID;
System_and_Signal = "GPS L1 CA";
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFineDoppler>(config.get(), "Acquisition", 1, 0);
}
else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "1B";
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
tmp_gnss_synchro.PRN = SV_ID;
System_and_Signal = "Galileo E1B";
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisition>(config.get(), "Acquisition", 1, 0);
}
else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'G';
std::string signal = "2S";
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
tmp_gnss_synchro.PRN = SV_ID;
System_and_Signal = "GPS L2CM";
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
acquisition = std::make_shared<GpsL2MPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
}
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "5X";
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
tmp_gnss_synchro.PRN = SV_ID;
System_and_Signal = "Galileo E5a";
config->set_property("Acquisition_5X.coherent_integration_time_ms", "1");
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
config->set_property("Acquisition.CAF_window_hz", "0"); // **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz
config->set_property("Acquisition.Zero_padding", "0"); //**Only for E5a** 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.
config->set_property("Acquisition.bit_transition_flag", "false");
acquisition = std::make_shared<GalileoE5aNoncoherentIQAcquisitionCaf>(config.get(), "Acquisition", 1, 0);
}
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "5X";
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
tmp_gnss_synchro.PRN = SV_ID;
System_and_Signal = "Galileo E5a";
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
acquisition = std::make_shared<GalileoE5aPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
}
else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'G';
std::string signal = "L5";
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
tmp_gnss_synchro.PRN = SV_ID;
System_and_Signal = "GPS L5I";
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
acquisition = std::make_shared<GpsL5iPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
}
else
{
std::cout << "The test can not run with the selected tracking implementation\n ";
throw(std::exception());
}
acquisition->set_channel(1);
acquisition->set_gnss_synchro(&tmp_gnss_synchro); acquisition->set_gnss_synchro(&tmp_gnss_synchro);
acquisition->set_channel(0);
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz));
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz));
acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold));
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 25000)); acquisition->init();
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); acquisition->set_local_code();
acquisition->set_state(1); // Ensure that acquisition starts at the first sample
acquisition->connect(top_block); acquisition->connect(top_block);
gr::blocks::file_source::sptr file_source; gr::blocks::file_source::sptr file_source;
std::string file = FLAGS_signal_file; std::string file = FLAGS_signal_file;
const char* file_name = file.c_str(); const char* file_name = file.c_str();
file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false);
file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample
gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make();
gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); //gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration);
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
top_block->connect(gr_interleaved_char_to_complex, 0, head_samples, 0); top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
top_block->connect(head_samples, 0, acquisition->get_left_block(), 0); //top_block->connect(head_samples, 0, acquisition->get_left_block(), 0);
boost::shared_ptr<Acquisition_msg_rx> msg_rx; boost::shared_ptr<Acquisition_msg_rx> msg_rx;
try try
@ -411,7 +536,7 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
if (start_msg == true) if (start_msg == true)
{ {
std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl;
std::cout << "Searching for GPS Satellites in L1 band..." << std::endl; std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl;
std::cout << "["; std::cout << "[";
start_msg = false; start_msg = false;
} }
@ -432,7 +557,6 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
} }
top_block->stop(); top_block->stop();
file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample
head_samples.reset();
std::cout.flush(); std::cout.flush();
} }
std::cout << "]" << std::endl; std::cout << "]" << std::endl;
@ -440,7 +564,7 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
for (auto& x : doppler_measurements_map) for (auto& x : doppler_measurements_map)
{ {
std::cout << "DETECTED PRN: " << x.first << " with Doppler: " << x.second << " [Hz], code phase: " << code_delay_measurements_map.at(x.first) << " [samples] at signal SampleStamp " << acq_samplestamp_map.at(x.first) << "\n"; std::cout << "DETECTED SATELLITE " << System_and_Signal << " PRN: " << x.first << " with Doppler: " << x.second << " [Hz], code phase: " << code_delay_measurements_map.at(x.first) << " [samples] at signal SampleStamp " << acq_samplestamp_map.at(x.first) << "\n";
} }
// report the elapsed time // report the elapsed time
@ -452,7 +576,7 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
return true; return true;
} }
TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) TEST_F(TrackingPullInTest, ValidationOfResults)
{ {
//************************************************* //*************************************************
//***** STEP 1: Prepare the parameters sweep ****** //***** STEP 1: Prepare the parameters sweep ******
@ -582,9 +706,9 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
//create flowgraph //create flowgraph
top_block = gr::make_top_block("Tracking test"); top_block = gr::make_top_block("Tracking test");
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking", config->property("Tracking.implementation", std::string("undefined")), 1, 1);
std::shared_ptr<TrackingInterface> tracking = std::dynamic_pointer_cast<TrackingInterface>(trk_); std::shared_ptr<TrackingInterface> tracking = std::dynamic_pointer_cast<TrackingInterface>(trk_);
boost::shared_ptr<GpsL1CADllPllTrackingPullInTest_msg_rx> msg_rx = GpsL1CADllPllTrackingPullInTest_msg_rx_make(); boost::shared_ptr<TrackingPullInTest_msg_rx> msg_rx = TrackingPullInTest_msg_rx_make();
ASSERT_NO_THROW({ ASSERT_NO_THROW({
@ -661,6 +785,8 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
std::vector<double> prompt; std::vector<double> prompt;
std::vector<double> early; std::vector<double> early;
std::vector<double> late; std::vector<double> late;
std::vector<double> v_early;
std::vector<double> v_late;
std::vector<double> promptI; std::vector<double> promptI;
std::vector<double> promptQ; std::vector<double> promptQ;
std::vector<double> CN0_dBHz; std::vector<double> CN0_dBHz;
@ -678,6 +804,8 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
prompt.push_back(trk_dump.abs_P); prompt.push_back(trk_dump.abs_P);
early.push_back(trk_dump.abs_E); early.push_back(trk_dump.abs_E);
late.push_back(trk_dump.abs_L); late.push_back(trk_dump.abs_L);
v_early.push_back(trk_dump.abs_VE);
v_late.push_back(trk_dump.abs_VL);
promptI.push_back(trk_dump.prompt_I); promptI.push_back(trk_dump.prompt_I);
promptQ.push_back(trk_dump.prompt_Q); promptQ.push_back(trk_dump.prompt_Q);
CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz);
@ -723,6 +851,11 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
g1.plot_xy(trk_timestamp_s, prompt, "Prompt", decimate); g1.plot_xy(trk_timestamp_s, prompt, "Prompt", decimate);
g1.plot_xy(trk_timestamp_s, early, "Early", decimate); g1.plot_xy(trk_timestamp_s, early, "Early", decimate);
g1.plot_xy(trk_timestamp_s, late, "Late", decimate); g1.plot_xy(trk_timestamp_s, late, "Late", decimate);
if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
{
g1.plot_xy(trk_timestamp_s, v_early, "Very Early", decimate);
g1.plot_xy(trk_timestamp_s, v_late, "Very Late", decimate);
}
g1.set_legend(); g1.set_legend();
//g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); //g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)));
//g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); //g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18);