1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-15 12:40:35 +00:00
This commit is contained in:
Carles Fernandez 2018-12-10 15:36:35 +01:00
commit 97c964b59e
55 changed files with 953 additions and 248 deletions

View File

@ -131,6 +131,9 @@ public:
void set_state(int state __attribute__((unused))) override{};
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
galileo_pcps_8ms_acquisition_cc_sptr acquisition_cc_;

View File

@ -37,6 +37,7 @@
#include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <utility>
using google::LogMessage;
@ -44,13 +45,12 @@ using google::LogMessage;
GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams) : role_(role),
unsigned int out_streams) : role_(std::move(role)),
in_streams_(in_streams),
out_streams_(out_streams)
{
Acq_Conf acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
@ -61,41 +61,67 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
acq_parameters_.fs_in = fs_in_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
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_;
if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
acq_parameters_.doppler_max = doppler_max_;
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_;
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";
acq_parameters.sampled_ms = acq_parameters.ms_per_code;
acq_parameters_.sampled_ms = acq_parameters_.ms_per_code;
}
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
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
acq_parameters_.max_dwells = max_dwells_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
acq_parameters_.blocking = blocking_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
acq_parameters_.dump_filename = dump_filename_;
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex")
{
LOG(WARNING) << "Galileo E1 acqisition disabled the automatic resampler feature because its item_type is not set to gr_complex";
acq_parameters_.use_automatic_resampler = false;
}
if (acq_parameters_.use_automatic_resampler)
{
if (acq_parameters_.fs_in > Galileo_E1_OPT_ACQ_FS_HZ)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / Galileo_E1_OPT_ACQ_FS_HZ);
uint32_t decimation = acq_parameters_.fs_in / Galileo_E1_OPT_ACQ_FS_HZ;
while (acq_parameters_.fs_in % decimation > 0)
{
decimation--;
};
acq_parameters_.resampler_ratio = decimation;
acq_parameters_.resampled_fs = acq_parameters_.fs_in / static_cast<int>(acq_parameters_.resampler_ratio);
}
//--- Find number of samples per spreading code (4 ms) -----------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters_.resampled_fs)));
}
else
{
//--- Find number of samples per spreading code (4 ms) -----------------
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)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
}
float samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_ms = samples_per_ms;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS);
vector_length_ = sampled_ms_ * samples_per_ms;
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS);
vector_length_ = sampled_ms_ * acq_parameters_.samples_per_ms;
if (bit_transition_flag_)
{
vector_length_ *= 2;
@ -111,12 +137,12 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
{
item_size_ = sizeof(gr_complex);
}
acq_parameters.it_size = item_size_;
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.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
acq_parameters_.it_size = item_size_;
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_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte")
@ -227,14 +253,30 @@ void GalileoE1PcpsAmbiguousAcquisition::set_local_code()
{
//set local signal generator to Galileo E1 pilot component (1C)
char pilot_signal[3] = "1C";
if (acq_parameters_.use_automatic_resampler)
{
galileo_e1_code_gen_complex_sampled(code, pilot_signal,
cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false);
}
else
{
galileo_e1_code_gen_complex_sampled(code, pilot_signal,
cboc, gnss_synchro_->PRN, fs_in_, 0, false);
}
}
else
{
if (acq_parameters_.use_automatic_resampler)
{
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal,
cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false);
}
else
{
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal,
cboc, gnss_synchro_->PRN, fs_in_, 0, false);
}
}
for (unsigned int i = 0; i < sampled_ms_ / 4; i++)
@ -352,3 +394,8 @@ gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisition::get_right_block()
{
return acquisition_;
}
void GalileoE1PcpsAmbiguousAcquisition::set_resampler_latency(uint32_t latency_samples)
{
acquisition_->set_resampler_latency(latency_samples);
}

View File

@ -32,6 +32,7 @@
#ifndef GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_H_
#define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_H_
#include "acq_conf.h"
#include "acquisition_interface.h"
#include "complex_byte_to_float_x2.h"
#include "gnss_synchro.h"
@ -51,7 +52,7 @@ class GalileoE1PcpsAmbiguousAcquisition : public AcquisitionInterface
{
public:
GalileoE1PcpsAmbiguousAcquisition(ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams);
@ -137,8 +138,16 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/
void set_resampler_latency(uint32_t latency_samples) override;
private:
ConfigurationInterface* configuration_;
Acq_Conf acq_parameters_;
pcps_acquisition_sptr acquisition_;
gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;

View File

@ -142,6 +142,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
//pcps_acquisition_sptr acquisition_;

View File

@ -131,6 +131,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_cccwsr_acquisition_cc_sptr acquisition_cc_;

View File

@ -135,6 +135,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_quicksync_acquisition_cc_sptr acquisition_cc_;

View File

@ -134,6 +134,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_tong_acquisition_cc_sptr acquisition_cc_;

View File

@ -137,6 +137,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr acquisition_cc_;

View File

@ -49,7 +49,6 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
in_streams_(in_streams),
out_streams_(out_streams)
{
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
@ -60,8 +59,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E5a_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
acq_parameters_.fs_in = fs_in_;
acq_pilot_ = configuration_->property(role + ".acquire_pilot", false);
acq_iq_ = configuration_->property(role + ".acquire_iq", false);
if (acq_iq_)
@ -69,22 +67,58 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
acq_pilot_ = false;
}
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
acq_parameters_.doppler_max = doppler_max_;
sampled_ms_ = 1;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
acq_parameters_.dump_filename = dump_filename_;
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_ = configuration_->property(role + ".use_CFAR_algorithm", false);
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_;
acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_;
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
acq_parameters_.blocking = blocking_;
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex")
{
LOG(WARNING) << "Galileo E5a acquisition disabled the automatic resampler feature because its item_type is not set to gr_complex";
acq_parameters_.use_automatic_resampler = false;
}
if (acq_parameters_.use_automatic_resampler)
{
if (acq_parameters_.fs_in > Galileo_E5a_OPT_ACQ_FS_HZ)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / Galileo_E5a_OPT_ACQ_FS_HZ);
uint32_t decimation = acq_parameters_.fs_in / Galileo_E5a_OPT_ACQ_FS_HZ;
while (acq_parameters_.fs_in % decimation > 0)
{
decimation--;
};
acq_parameters_.resampler_ratio = decimation;
acq_parameters_.resampled_fs = acq_parameters_.fs_in / static_cast<int>(acq_parameters_.resampler_ratio);
}
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E5a_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters_.resampled_fs)));
}
else
{
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E5a_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
}
//--- Find number of samples per spreading code (1ms)-------------------------
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / Galileo_E5a_CODE_CHIP_RATE_HZ * static_cast<double>(Galileo_E5a_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
@ -104,16 +138,15 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
item_size_ = sizeof(gr_complex);
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
acq_parameters.it_size = item_size_;
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
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.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
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.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
acq_parameters_.it_size = item_size_;
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_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
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_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters_);
channel_ = 0;
threshold_ = 0.0;
@ -224,7 +257,14 @@ void GalileoE5aPcpsAcquisition::set_local_code()
strcpy(signal_, "5I");
}
if (acq_parameters_.use_automatic_resampler)
{
galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0);
}
else
{
galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0);
}
for (unsigned int i = 0; i < sampled_ms_; i++)
{
@ -311,3 +351,8 @@ gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_right_block()
{
return acquisition_;
}
void GalileoE5aPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
{
acquisition_->set_resampler_latency(latency_samples);
}

View File

@ -128,13 +128,19 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/
void set_resampler_latency(uint32_t latency_samples) override;
private:
float calculate_threshold(float pfa);
ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_;
Acq_Conf acq_parameters_;
size_t item_size_;
std::string item_type_;

View File

@ -130,6 +130,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
//float calculate_threshold(float pfa);

View File

@ -137,6 +137,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_;

View File

@ -136,6 +136,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_;

View File

@ -41,6 +41,7 @@
#include "gps_sdr_signal_processing.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <utility>
using google::LogMessage;
@ -48,13 +49,12 @@ using google::LogMessage;
GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams) : role_(role),
unsigned int out_streams) : role_(std::move(role)),
in_streams_(in_streams),
out_streams_(out_streams)
{
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
@ -64,36 +64,64 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
acq_parameters_.fs_in = fs_in_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
acq_parameters_.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
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", 1);
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.ms_per_code = 1;
acq_parameters_.sampled_ms = sampled_ms_;
acq_parameters_.ms_per_code = 1;
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
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
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.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.dump_filename = dump_filename_;
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_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex")
{
LOG(WARNING) << "GPS L1 CA acquisition disabled the automatic resampler feature because its item_type is not set to gr_complex";
acq_parameters_.use_automatic_resampler = false;
}
if (acq_parameters_.use_automatic_resampler)
{
if (acq_parameters_.fs_in > GPS_L1_CA_OPT_ACQ_FS_HZ)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L1_CA_OPT_ACQ_FS_HZ);
uint32_t decimation = acq_parameters_.fs_in / GPS_L1_CA_OPT_ACQ_FS_HZ;
while (acq_parameters_.fs_in % decimation > 0)
{
decimation--;
};
acq_parameters_.resampler_ratio = decimation;
acq_parameters_.resampled_fs = acq_parameters_.fs_in / static_cast<int>(acq_parameters_.resampler_ratio);
}
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters_.resampled_fs)));
}
else
{
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
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;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters_.fs_in)));
}
vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1);
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
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_];
if (item_type_ == "cshort")
@ -105,9 +133,9 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
item_size_ = sizeof(gr_complex);
}
acq_parameters.it_size = item_size_;
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
acq_parameters_.it_size = item_size_;
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte")
@ -208,8 +236,14 @@ void GpsL1CaPcpsAcquisition::set_local_code()
{
auto* code = new std::complex<float>[code_length_];
if (acq_parameters_.use_automatic_resampler)
{
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0);
}
else
{
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0);
}
for (unsigned int i = 0; i < sampled_ms_; i++)
{
memcpy(&(code_[i * code_length_]), code,
@ -325,3 +359,8 @@ gr::basic_block_sptr GpsL1CaPcpsAcquisition::get_right_block()
{
return acquisition_;
}
void GpsL1CaPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
{
acquisition_->set_resampler_latency(latency_samples);
}

View File

@ -36,6 +36,7 @@
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H_
#define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H_
#include "acq_conf.h"
#include "acquisition_interface.h"
#include "complex_byte_to_float_x2.h"
#include "gnss_synchro.h"
@ -55,7 +56,7 @@ class GpsL1CaPcpsAcquisition : public AcquisitionInterface
{
public:
GpsL1CaPcpsAcquisition(ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams);
@ -141,9 +142,17 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/
void set_resampler_latency(uint32_t latency_samples) override;
private:
ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_;
Acq_Conf acq_parameters_;
gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_;

View File

@ -132,6 +132,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
pcps_acquisition_fine_doppler_cc_sptr acquisition_cc_;
size_t item_size_;

View File

@ -140,6 +140,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_;

View File

@ -128,6 +128,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
pcps_assisted_acquisition_cc_sptr acquisition_cc_;
size_t item_size_;

View File

@ -130,6 +130,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_opencl_acquisition_cc_sptr acquisition_cc_;

View File

@ -136,6 +136,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_quicksync_acquisition_cc_sptr acquisition_cc_;

View File

@ -135,6 +135,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
pcps_tong_acquisition_cc_sptr acquisition_cc_;

View File

@ -39,6 +39,7 @@
#include "gps_l2c_signal.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <utility>
using google::LogMessage;
@ -46,13 +47,12 @@ using google::LogMessage;
GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams) : role_(role),
unsigned int out_streams) : role_(std::move(role)),
in_streams_(in_streams),
out_streams_(out_streams)
{
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
@ -60,42 +60,73 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
LOG(INFO) << "role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type);
//float pfa = configuration_->property(role + ".pfa", 0.0);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L2_M_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
acq_parameters_.fs_in = fs_in_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
acq_parameters_.blocking = blocking_;
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
acq_parameters_.doppler_max = doppler_max_;
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
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code -------------------------
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.ms_per_code = 20;
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)
acq_parameters_.dump_filename = dump_filename_;
acq_parameters_.ms_per_code = 20;
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";
acq_parameters.sampled_ms = acq_parameters.ms_per_code;
acq_parameters_.sampled_ms = acq_parameters_.ms_per_code;
}
code_length_ = acq_parameters.ms_per_code * acq_parameters.samples_per_ms;
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_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex")
{
LOG(WARNING) << "GPS L2CM acquisition disabled the automatic resampler feature because its item_type is not set to gr_complex";
acq_parameters_.use_automatic_resampler = false;
}
if (acq_parameters_.use_automatic_resampler)
{
if (acq_parameters_.fs_in > GPS_L2C_OPT_ACQ_FS_HZ)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L2C_OPT_ACQ_FS_HZ);
uint32_t decimation = acq_parameters_.fs_in / GPS_L2C_OPT_ACQ_FS_HZ;
while (acq_parameters_.fs_in % decimation > 0)
{
decimation--;
};
acq_parameters_.resampler_ratio = decimation;
acq_parameters_.resampled_fs = acq_parameters_.fs_in / static_cast<int>(acq_parameters_.resampler_ratio);
}
vector_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L2_M_CODE_RATE_HZ / GPS_L2_M_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L2_M_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.resampled_fs)));
}
else
{
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / GPS_L2_M_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L2_M_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
}
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD * 1000.0);
vector_length_ = acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = new gr_complex[vector_length_];
if (item_type_ == "cshort")
@ -107,14 +138,8 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
item_size_ = sizeof(gr_complex);
}
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD * 1000.0);
acq_parameters.it_size = item_size_;
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.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
acq_parameters_.it_size = item_size_;
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte")
@ -127,7 +152,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
threshold_ = 0.0;
doppler_step_ = 0;
gnss_synchro_ = nullptr;
num_codes_ = acq_parameters.sampled_ms / acq_parameters.ms_per_code;
num_codes_ = acq_parameters_.sampled_ms / acq_parameters_.ms_per_code;
if (in_streams_ > 1)
{
LOG(ERROR) << "This implementation only supports one input stream";
@ -223,7 +248,16 @@ void GpsL2MPcpsAcquisition::set_local_code()
{
auto* code = new std::complex<float>[code_length_];
if (acq_parameters_.use_automatic_resampler)
{
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs);
}
else
{
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
}
for (unsigned int i = 0; i < num_codes_; i++)
{
@ -339,3 +373,7 @@ gr::basic_block_sptr GpsL2MPcpsAcquisition::get_right_block()
{
return acquisition_;
}
void GpsL2MPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
{
acquisition_->set_resampler_latency(latency_samples);
}

View File

@ -53,7 +53,7 @@ class GpsL2MPcpsAcquisition : public AcquisitionInterface
{
public:
GpsL2MPcpsAcquisition(ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams);
@ -139,9 +139,17 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/
void set_resampler_latency(uint32_t latency_samples) override;
private:
ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_;
Acq_Conf acq_parameters_;
gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_;

View File

@ -140,6 +140,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
//pcps_acquisition_sptr acquisition_;

View File

@ -39,6 +39,7 @@
#include "gps_l5_signal.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <utility>
using google::LogMessage;
@ -46,13 +47,12 @@ using google::LogMessage;
GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams) : role_(role),
unsigned int out_streams) : role_(std::move(role)),
in_streams_(in_streams),
out_streams_(out_streams)
{
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
@ -63,32 +63,24 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_;
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L5i_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
acq_parameters_.fs_in = fs_in_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_;
acq_parameters_.blocking = blocking_;
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
acq_parameters_.doppler_max = doppler_max_;
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
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_;
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L5i_CODE_RATE_HZ / GPS_L5i_CODE_LENGTH_CHIPS)));
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);
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_];
acq_parameters_.dump_filename = dump_filename_;
acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
if (item_type_ == "cshort")
{
@ -99,14 +91,51 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
item_size_ = sizeof(gr_complex);
}
acq_parameters.ms_per_code = 1;
acq_parameters.it_size = item_size_;
num_codes_ = acq_parameters.sampled_ms;
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.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
acq_parameters_.ms_per_code = 1;
acq_parameters_.it_size = item_size_;
num_codes_ = acq_parameters_.sampled_ms;
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_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex")
{
LOG(WARNING) << "GPS L5 acquisition disabled the automatic resampler feature because its item_type is not set to gr_complex";
acq_parameters_.use_automatic_resampler = false;
}
if (acq_parameters_.use_automatic_resampler)
{
if (acq_parameters_.fs_in > GPS_L5_OPT_ACQ_FS_HZ)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L5_OPT_ACQ_FS_HZ);
uint32_t decimation = acq_parameters_.fs_in / GPS_L5_OPT_ACQ_FS_HZ;
while (acq_parameters_.fs_in % decimation > 0)
{
decimation--;
};
acq_parameters_.resampler_ratio = decimation;
acq_parameters_.resampled_fs = acq_parameters_.fs_in / static_cast<int>(acq_parameters_.resampler_ratio);
}
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L5i_CODE_RATE_HZ / GPS_L5i_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L5i_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.resampled_fs)));
}
else
{
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L5i_CODE_RATE_HZ / GPS_L5i_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L5i_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
}
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L5i_PERIOD * 1000.0);
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_];
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte")
@ -114,6 +143,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
float_to_complex_ = gr::blocks::float_to_complex::make();
}
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
@ -211,7 +241,15 @@ void GpsL5iPcpsAcquisition::set_local_code()
{
auto* code = new std::complex<float>[code_length_];
if (acq_parameters_.use_automatic_resampler)
{
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs);
}
else
{
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
}
for (unsigned int i = 0; i < num_codes_; i++)
{
@ -327,3 +365,8 @@ gr::basic_block_sptr GpsL5iPcpsAcquisition::get_right_block()
{
return acquisition_;
}
void GpsL5iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
{
acquisition_->set_resampler_latency(latency_samples);
}

View File

@ -53,7 +53,7 @@ class GpsL5iPcpsAcquisition : public AcquisitionInterface
{
public:
GpsL5iPcpsAcquisition(ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams);
@ -139,9 +139,16 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/
void set_resampler_latency(uint32_t latency_samples) override;
private:
ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_;
Acq_Conf acq_parameters_;
gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_;

View File

@ -140,6 +140,8 @@ public:
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
ConfigurationInterface* configuration_;
//pcps_acquisition_sptr acquisition_;

View File

@ -221,6 +221,12 @@ pcps_acquisition::~pcps_acquisition()
}
void pcps_acquisition::set_resampler_latency(uint32_t latency_samples)
{
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
acq_parameters.resampler_latency_samples = latency_samples;
}
void pcps_acquisition::set_local_code(std::complex<float>* code)
{
// reset the intermediate frequency
@ -280,7 +286,15 @@ bool pcps_acquisition::is_fdma()
void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq)
{
float phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(acq_parameters.fs_in);
float phase_step_rad;
if (acq_parameters.use_automatic_resampler)
{
phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(acq_parameters.resampled_fs);
}
else
{
phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(acq_parameters.fs_in);
}
float _phase[1];
_phase[0] = 0.0;
volk_gnsssdr_s32f_sincos_32fc(carrier_vector, -phase_step_rad, _phase, correlator_length_samples);
@ -716,10 +730,21 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
{
d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
}
if (acq_parameters.use_automatic_resampler)
{
//take into account the acquisition resampler ratio
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio;
d_gnss_synchro->Acq_delay_samples -= static_cast<double>(acq_parameters.resampler_latency_samples); //account the resampler filter latency
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(samp_count) * acq_parameters.resampler_ratio);
}
else
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
}
}
else
{
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
@ -762,11 +787,24 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
{
d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins_step2, static_cast<int32_t>(d_doppler_center_step_two - (static_cast<float>(d_num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2);
}
if (acq_parameters.use_automatic_resampler)
{
//take into account the acquisition resampler ratio
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio;
d_gnss_synchro->Acq_delay_samples -= static_cast<double>(acq_parameters.resampler_latency_samples); //account the resampler filter latency
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(samp_count) * acq_parameters.resampler_ratio);
d_gnss_synchro->Acq_doppler_step = acq_parameters.doppler_step2;
}
else
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
d_gnss_synchro->Acq_doppler_step = acq_parameters.doppler_step2;
}
}
lk.lock();
if (!acq_parameters.bit_transition_flag)
@ -865,6 +903,12 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
}
}
// Called by gnuradio to enable drivers, etc for i/o devices.
bool pcps_acquisition::start()
{
d_sample_counter = 0ULL;
return true;
}
int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
gr_vector_int& ninput_items, gr_vector_const_void_star& input_items,

View File

@ -98,6 +98,9 @@ private:
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
bool start();
Acq_Conf acq_parameters;
bool d_active;
bool d_worker_active;
@ -233,6 +236,9 @@ public:
d_doppler_step = doppler_step;
}
void set_resampler_latency(uint32_t latency_samples);
/*!
* \brief Parallel Code Phase Search Acquisition signal processing.
*/

View File

@ -53,4 +53,8 @@ Acq_Conf::Acq_Conf()
dump_channel = 0U;
it_size = sizeof(char);
blocking_on_standby = false;
use_automatic_resampler = false;
resampler_ratio = 1.0;
resampled_fs = 0LL;
resampler_latency_samples = 0U;
}

View File

@ -56,6 +56,10 @@ public:
bool blocking;
bool blocking_on_standby; // enable it only for unit testing to avoid sample consume on idle status
bool make_2_steps;
bool use_automatic_resampler;
float resampler_ratio;
int64_t resampled_fs;
uint32_t resampler_latency_samples;
std::string dump_filename;
uint32_t dump_channel;
size_t it_size;

View File

@ -38,12 +38,10 @@
using google::LogMessage;
// Constructor
Channel::Channel(ConfigurationInterface* configuration, uint32_t channel,
std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq,
Channel::Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr<AcquisitionInterface> acq,
std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> nav,
std::string role, std::string implementation, gr::msg_queue::sptr queue)
{
pass_through_ = std::move(pass_through);
acq_ = std::move(acq);
trk_ = std::move(trk);
nav_ = std::move(nav);
@ -112,32 +110,15 @@ Channel::~Channel() = default;
void Channel::connect(gr::top_block_sptr top_block)
{
if (connected_)
{
LOG(WARNING) << "channel already connected internally";
return;
}
if (flag_enable_fpga == false)
{
pass_through_->connect(top_block);
}
acq_->connect(top_block);
trk_->connect(top_block);
nav_->connect(top_block);
//Synchronous ports
if (flag_enable_fpga == false)
{
top_block->connect(pass_through_->get_right_block(), 0, acq_->get_left_block(), 0);
DLOG(INFO) << "pass_through_ -> acquisition";
top_block->connect(pass_through_->get_right_block(), 0, trk_->get_left_block(), 0);
DLOG(INFO) << "pass_through_ -> tracking";
}
top_block->connect(trk_->get_right_block(), 0, nav_->get_left_block(), 0);
DLOG(INFO) << "tracking -> telemetry_decoder";
// Message ports
top_block->msg_connect(acq_->get_right_block(), pmt::mp("events"), channel_msg_rx, pmt::mp("events"));
top_block->msg_connect(trk_->get_right_block(), pmt::mp("events"), channel_msg_rx, pmt::mp("events"));
@ -153,17 +134,8 @@ void Channel::disconnect(gr::top_block_sptr top_block)
return;
}
if (flag_enable_fpga == false)
{
top_block->disconnect(pass_through_->get_right_block(), 0, acq_->get_left_block(), 0);
top_block->disconnect(pass_through_->get_right_block(), 0, trk_->get_left_block(), 0);
}
top_block->disconnect(trk_->get_right_block(), 0, nav_->get_left_block(), 0);
if (flag_enable_fpga == false)
{
pass_through_->disconnect(top_block);
}
acq_->disconnect(top_block);
trk_->disconnect(top_block);
nav_->disconnect(top_block);
@ -173,9 +145,19 @@ void Channel::disconnect(gr::top_block_sptr top_block)
gr::basic_block_sptr Channel::get_left_block()
{
return pass_through_->get_left_block();
LOG(ERROR) << "Deprecated call to get_left_block() in channel interface";
return nullptr;
}
gr::basic_block_sptr Channel::get_left_block_trk()
{
return trk_->get_left_block();
}
gr::basic_block_sptr Channel::get_left_block_acq()
{
return acq_->get_left_block();
}
gr::basic_block_sptr Channel::get_right_block()
{

View File

@ -60,16 +60,17 @@ class Channel : public ChannelInterface
{
public:
//! Constructor
Channel(ConfigurationInterface* configuration, uint32_t channel,
std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq,
Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr<AcquisitionInterface> acq,
std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> nav,
std::string role, std::string implementation, gr::msg_queue::sptr queue);
//! Virtual destructor
virtual ~Channel();
void connect(gr::top_block_sptr top_block) override;
void connect(gr::top_block_sptr top_block) override; //!< connects the tracking block to the top_block and to the telemetry
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_left_block() override; //!< gets the gnuradio tracking block pointer
gr::basic_block_sptr get_left_block_trk() override; //!< gets the gnuradio tracking block pointer
gr::basic_block_sptr get_left_block_acq() override; //!< gets the gnuradio tracking block pointer
gr::basic_block_sptr get_right_block() override;
inline std::string role() override { return role_; }
@ -88,7 +89,6 @@ public:
private:
channel_msg_receiver_cc_sptr channel_msg_rx;
std::shared_ptr<GNSSBlockInterface> pass_through_;
std::shared_ptr<AcquisitionInterface> acq_;
std::shared_ptr<TrackingInterface> trk_;
std::shared_ptr<TelemetryDecoderInterface> nav_;

View File

@ -69,7 +69,7 @@ MmseResamplerConditioner::MmseResamplerConditioner(
std::vector<float> taps = gr::filter::firdes::low_pass(1.0,
sample_freq_in_,
sample_freq_out_ / 2.1,
sample_freq_out_ / 10,
sample_freq_out_ / 5,
gr::filter::firdes::win_type::WIN_HAMMING);
std::cout << "Enabled fractional resampler low pass filter with " << taps.size() << " taps" << std::endl;
fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(1, taps);

View File

@ -42,14 +42,15 @@
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include <glog/logging.h>
#include <utility>
using google::LogMessage;
GlonassL1CaDllPllCAidTracking::GlonassL1CaDllPllCAidTracking(
ConfigurationInterface* configuration, const std::string& role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(std::move(role)), in_streams_(in_streams), out_streams_(out_streams)
{
DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ########################

View File

@ -54,7 +54,7 @@ class GlonassL1CaDllPllCAidTracking : public TrackingInterface
{
public:
GlonassL1CaDllPllCAidTracking(ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams);

View File

@ -40,14 +40,15 @@
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include <glog/logging.h>
#include <utility>
using google::LogMessage;
GlonassL2CaDllPllCAidTracking::GlonassL2CaDllPllCAidTracking(
ConfigurationInterface* configuration, const std::string& role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(std::move(role)), in_streams_(in_streams), out_streams_(out_streams)
{
DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ########################

View File

@ -52,7 +52,7 @@ class GlonassL2CaDllPllCAidTracking : public TrackingInterface
{
public:
GlonassL2CaDllPllCAidTracking(ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams);

View File

@ -41,14 +41,15 @@
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include <glog/logging.h>
#include <utility>
using google::LogMessage;
GpsL1CaDllPllCAidTracking::GpsL1CaDllPllCAidTracking(
ConfigurationInterface* configuration, const std::string& role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(std::move(role)), in_streams_(in_streams), out_streams_(out_streams)
{
DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ########################

View File

@ -53,7 +53,7 @@ class GpsL1CaDllPllCAidTracking : public TrackingInterface
{
public:
GpsL1CaDllPllCAidTracking(ConfigurationInterface* configuration,
const std::string& role,
std::string role,
unsigned int in_streams,
unsigned int out_streams);

View File

@ -65,6 +65,7 @@ public:
virtual signed int mag() = 0;
virtual void reset() = 0;
virtual void stop_acquisition() = 0;
virtual void set_resampler_latency(uint32_t latency_samples) = 0;
};
#endif /* GNSS_SDR_ACQUISITION_INTERFACE */

View File

@ -51,6 +51,10 @@
class ChannelInterface : public GNSSBlockInterface
{
public:
virtual gr::basic_block_sptr get_left_block_trk() = 0;
virtual gr::basic_block_sptr get_left_block_acq() = 0;
virtual gr::basic_block_sptr get_left_block() = 0;
virtual gr::basic_block_sptr get_right_block() = 0;
virtual Gnss_Signal get_signal() const = 0;
virtual void start_acquisition() = 0;
virtual void stop_channel() = 0;

View File

@ -360,12 +360,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_1C(
}
config->set_property("Channel.item_type", acq_item_type);
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_1C" + appendix1, acq, 1, 0);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_1C" + appendix2, trk, 1, 1);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1C" + appendix3, tlm, 1, 1);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
std::move(acq_),
std::move(trk_),
std::move(tlm_),
@ -425,12 +424,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_2S(
}
config->set_property("Channel.item_type", acq_item_type);
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_2S" + appendix1, acq, 1, 0);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_2S" + appendix2, trk, 1, 1);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_2S" + appendix3, tlm, 1, 1);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
std::move(acq_),
std::move(trk_),
std::move(tlm_),
@ -493,12 +491,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_1B(
}
config->set_property("Channel.item_type", acq_item_type);
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_1B" + appendix1, acq, 1, 0);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_1B" + appendix2, trk, 1, 1);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1B" + appendix3, tlm, 1, 1);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
std::move(acq_),
std::move(trk_),
std::move(tlm_),
@ -561,12 +558,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_5X(
}
config->set_property("Channel.item_type", acq_item_type);
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_5X" + appendix1, acq, 1, 0);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_5X" + appendix2, trk, 1, 1);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_5X" + appendix3, tlm, 1, 1);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
std::move(acq_),
std::move(trk_),
std::move(tlm_),
@ -630,12 +626,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_1G(
}
config->set_property("Channel.item_type", acq_item_type);
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_1G" + appendix1, acq, 1, 0);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_1G" + appendix2, trk, 1, 1);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1G" + appendix3, tlm, 1, 1);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
std::move(acq_),
std::move(trk_),
std::move(tlm_),
@ -699,12 +694,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_2G(
}
config->set_property("Channel.item_type", acq_item_type);
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_2G" + appendix1, acq, 1, 0);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_2G" + appendix2, trk, 1, 1);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_2G" + appendix3, tlm, 1, 1);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
std::move(acq_),
std::move(trk_),
std::move(tlm_),
@ -767,12 +761,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_L5(
}
config->set_property("Channel.item_type", acq_item_type);
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_L5" + appendix1, acq, 1, 0);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_L5" + appendix2, trk, 1, 1);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_L5" + appendix3, tlm, 1, 1);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
std::move(acq_),
std::move(trk_),
std::move(tlm_),

View File

@ -33,18 +33,28 @@
*/
#include "gnss_flowgraph.h"
#include "GPS_L1_CA.h"
#include "GPS_L2C.h"
#include "GPS_L5.h"
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "channel.h"
#include "channel_interface.h"
#include "configuration_interface.h"
#include "gnss_block_factory.h"
#include "gnss_block_interface.h"
#include "gnss_synchro.h"
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <glog/logging.h>
#include <gnuradio/filter/firdes.h>
#include <algorithm>
#include <exception>
#include <iostream>
#include <set>
#ifdef GR_GREATER_38
#include <gnuradio/filter/fir_filter_blk.h>
#else
#include <gnuradio/filter/fir_filter_ccf.h>
#endif
#define GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS 8
@ -343,6 +353,8 @@ void GNSSFlowgraph::connect()
#endif
// Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID)
int selected_signal_conditioner_ID = 0;
bool use_acq_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
uint32_t fs = configuration_->property("GNSS-SDR.internal_fs_sps", 0);
for (unsigned int i = 0; i < channels_count_; i++)
{
if (FPGA_enabled == false)
@ -356,9 +368,120 @@ void GNSSFlowgraph::connect()
LOG(WARNING) << e.what();
}
try
{
// Enable automatic resampler for the acquisition, if required
if (use_acq_resampler == true)
{
//create acquisition resamplers if required
double resampler_ratio = 1.0;
double acq_fs = fs;
//find the signal associated to this channel
switch (mapStringValues_[channels_.at(i)->implementation()])
{
case evGPS_1C:
acq_fs = GPS_L1_CA_OPT_ACQ_FS_HZ;
break;
case evGPS_2S:
acq_fs = GPS_L2C_OPT_ACQ_FS_HZ;
break;
case evGPS_L5:
acq_fs = GPS_L5_OPT_ACQ_FS_HZ;
break;
case evSBAS_1C:
acq_fs = GPS_L1_CA_OPT_ACQ_FS_HZ;
break;
case evGAL_1B:
acq_fs = Galileo_E1_OPT_ACQ_FS_HZ;
break;
case evGAL_5X:
acq_fs = Galileo_E5a_OPT_ACQ_FS_HZ;
break;
case evGLO_1G:
acq_fs = fs;
break;
case evGLO_2G:
acq_fs = fs;
break;
}
if (acq_fs < fs)
{
//check if the resampler is already created for the channel system/signal and for the specific RF Channel
std::string map_key = channels_.at(i)->implementation() + std::to_string(selected_signal_conditioner_ID);
resampler_ratio = static_cast<double>(fs) / acq_fs;
int decimation = floor(resampler_ratio);
while (fs % decimation > 0)
{
decimation--;
};
double acq_fs = fs / decimation;
if (decimation > 1)
{
//create a FIR low pass filter
std::vector<float> taps;
taps = gr::filter::firdes::low_pass(1.0,
fs,
acq_fs / 2.1,
acq_fs / 10,
gr::filter::firdes::win_type::WIN_HAMMING);
gr::basic_block_sptr fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(decimation, taps);
std::pair<std::map<std::string, gr::basic_block_sptr>::iterator, bool> ret;
ret = acq_resamplers_.insert(std::pair<std::string, gr::basic_block_sptr>(map_key, fir_filter_ccf_));
if (ret.second == true)
{
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block(), 0);
acq_resamplers_.at(map_key), 0);
LOG(INFO) << "Created "
<< channels_.at(i)->implementation()
<< " acquisition resampler for RF channel " << std::to_string(signal_conditioner_ID) << " with " << taps.size() << " taps and decimation factor of " << decimation;
}
else
{
LOG(INFO) << "Found existing "
<< channels_.at(i)->implementation()
<< " acquisition resampler for RF channel " << std::to_string(signal_conditioner_ID) << " with " << taps.size() << " taps and decimation factor of " << decimation;
}
top_block_->connect(acq_resamplers_.at(map_key), 0,
channels_.at(i)->get_left_block_acq(), 0);
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block_trk(), 0);
std::shared_ptr<Channel> channel_ptr;
channel_ptr = std::dynamic_pointer_cast<Channel>(channels_.at(i));
channel_ptr->acquisition()->set_resampler_latency((taps.size() - 1) / 2);
}
else
{
LOG(INFO) << "Disabled acquisition resampler because the input sampling frequency is too low";
//resampler not required!
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block_acq(), 0);
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block_trk(), 0);
}
}
else
{
LOG(INFO) << "Disabled acquisition resampler because the input sampling frequency is too low";
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block_acq(), 0);
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block_trk(), 0);
}
}
else
{
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block_acq(), 0);
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block_trk(), 0);
}
}
catch (const std::exception& e)
{
@ -678,7 +801,7 @@ void GNSSFlowgraph::disconnect()
try
{
top_block_->disconnect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block(), 0);
channels_.at(i)->get_left_block_trk(), 0);
}
catch (const std::exception& e)
{

View File

@ -166,6 +166,7 @@ private:
std::shared_ptr<GNSSBlockInterface> observables_;
std::shared_ptr<GNSSBlockInterface> pvt_;
std::map<std::string, gr::basic_block_sptr> acq_resamplers_;
std::vector<std::shared_ptr<ChannelInterface>> channels_;
gnss_sdr_sample_counter_sptr ch_out_sample_counter;
#if ENABLE_FPGA

View File

@ -57,6 +57,9 @@ const double GPS_L1_CA_CODE_PERIOD = 0.001; //!< GPS L1 C/A code period
const uint32_t GPS_L1_CA_CODE_PERIOD_MS = 1U; //!< GPS L1 C/A code period [ms]
const double GPS_L1_CA_CHIP_PERIOD = 9.7752e-07; //!< GPS L1 C/A chip period [seconds]
//optimum parameters
const uint32_t GPS_L1_CA_OPT_ACQ_FS_HZ = 1000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate
/*!
* \brief Maximum Time-Of-Arrival (TOA) difference between satellites for a receiver operated on Earth surface is 20 ms
*

View File

@ -63,6 +63,10 @@ const double GPS_L2_L_PERIOD = 1.5; //!< GPS L2 L code period [s
const int32_t GPS_L2C_HISTORY_DEEP = 5;
//optimum parameters
const uint32_t GPS_L2C_OPT_ACQ_FS_HZ = 1000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate
const int32_t GPS_L2C_M_INIT_REG[115] =
{0742417664, 0756014035, 0002747144, 0066265724, // 1:4
0601403471, 0703232733, 0124510070, 0617316361, // 5:8

View File

@ -64,6 +64,9 @@ const double GPS_L5q_PERIOD = 0.001; //!< GPS L5 code period [secon
const int32_t GPS_L5_HISTORY_DEEP = 5;
//optimum parameters
const uint32_t GPS_L5_OPT_ACQ_FS_HZ = 10000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate
const int32_t GPS_L5i_INIT_REG[210] =
{266, 365, 804, 1138,
1509, 1559, 1756, 2084,

View File

@ -63,6 +63,11 @@ const int32_t Galileo_E1_B_SAMPLES_PER_SYMBOL = 1; //!< (Galileo_E1_CODE_
const int32_t Galileo_E1_C_SECONDARY_CODE_LENGTH = 25; //!< Galileo E1-C secondary code length [chips]
const int32_t Galileo_E1_NUMBER_OF_CODES = 50;
//optimum parameters
const uint32_t Galileo_E1_OPT_ACQ_FS_HZ = 2000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate
const double GALILEO_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here)

View File

@ -57,6 +57,9 @@ const int32_t Galileo_E5a_NUMBER_OF_CODES = 50;
const int32_t GALILEO_E5A_HISTORY_DEEP = 20;
const int32_t GALILEO_E5A_CRC_ERROR_LIMIT = 6;
//optimum parameters
const uint32_t Galileo_E5a_OPT_ACQ_FS_HZ = 10000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate
// F/NAV message structure
const int32_t GALILEO_FNAV_PREAMBLE_LENGTH_BITS = 12;

View File

@ -42,6 +42,7 @@ DEFINE_double(external_signal_acquisition_threshold, 2.5, "Threshold for satelli
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.0, "Doppler step for satellite acquisition when external file is used");
DEFINE_bool(use_acquisition_resampler, false, "Reduce the sampling rate of the input signal for the acquisition in order to optimize the SNR and decrease the processor load");
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]");

View File

@ -45,6 +45,7 @@
#include "signal_generator_flags.h"
#include "spirent_motion_csv_dump_reader.h"
#include "test_flags.h"
#include "tracking_tests_flags.h" //acquisition resampler
#include <armadillo>
#include <boost/filesystem.hpp>
#include <glog/logging.h>
@ -183,6 +184,11 @@ int PositionSystemTest::configure_receiver()
const int output_rate_ms = 100;
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal));
// Enable automatic resampler for the acquisition, if required
if (FLAGS_use_acquisition_resampler == true)
{
config->set_property("GNSS-SDR.use_acquisition_resampler", "true");
}
// Set the assistance system parameters
config->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false");

View File

@ -233,14 +233,14 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid()
}
TEST_F(GpsL1CaPcpsAcquisitionTest, Instantiate)
TEST_F(GpsL1CaPcpsAcquisitionTest /*unused*/, Instantiate /*unused*/)
{
init();
boost::shared_ptr<GpsL1CaPcpsAcquisition> acquisition = boost::make_shared<GpsL1CaPcpsAcquisition>(config.get(), "Acquisition_1C", 1, 0);
}
TEST_F(GpsL1CaPcpsAcquisitionTest, ConnectAndRun)
TEST_F(GpsL1CaPcpsAcquisitionTest /*unused*/, ConnectAndRun /*unused*/)
{
int fs_in = 4000000;
int nsamples = 4000;
@ -273,7 +273,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ConnectAndRun)
}
TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults)
TEST_F(GpsL1CaPcpsAcquisitionTest /*unused*/, ValidationOfResults /*unused*/)
{
std::chrono::time_point<std::chrono::system_clock> start, end;
std::chrono::duration<double> elapsed_seconds(0.0);

View File

@ -31,6 +31,10 @@
*/
#include "GPS_L1_CA.h"
#include "GPS_L2C.h"
#include "GPS_L5.h"
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "acquisition_msg_rx.h"
#include "galileo_e1_pcps_ambiguous_acquisition.h"
#include "galileo_e5a_noncoherent_iq_acquisition_caf.h"
@ -64,6 +68,7 @@
#include <gnuradio/blocks/file_source.h>
#include <gnuradio/blocks/interleaved_char_to_complex.h>
#include <gnuradio/blocks/null_sink.h>
#include <gnuradio/filter/firdes.h>
#include <gnuradio/top_block.h>
#include <gtest/gtest.h>
#include <matio.h>
@ -75,6 +80,11 @@
#include <gpstk/Rinex3ObsStream.hpp>
#include <gpstk/RinexUtilities.hpp>
#include <unistd.h>
#ifdef GR_GREATER_38
#include <gnuradio/filter/fir_filter_blk.h>
#else
#include <gnuradio/filter/fir_filter_ccf.h>
#endif
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES #########
@ -186,6 +196,19 @@ HybridObservablesTest_tlm_msg_rx::~HybridObservablesTest_tlm_msg_rx()
class HybridObservablesTest : public ::testing::Test
{
public:
enum StringValue
{
evGPS_1C,
evGPS_2S,
evGPS_L5,
evSBAS_1C,
evGAL_1B,
evGAL_5X,
evGLO_1G,
evGLO_2G
};
std::map<std::string, StringValue> mapStringValues_;
std::string generator_binary;
std::string p1;
std::string p2;
@ -247,6 +270,13 @@ public:
factory = std::make_shared<GNSSBlockFactory>();
config = std::make_shared<InMemoryConfiguration>();
item_size = sizeof(gr_complex);
mapStringValues_["1C"] = evGPS_1C;
mapStringValues_["2S"] = evGPS_2S;
mapStringValues_["L5"] = evGPS_L5;
mapStringValues_["1B"] = evGAL_1B;
mapStringValues_["5X"] = evGAL_5X;
mapStringValues_["1G"] = evGLO_1G;
mapStringValues_["2G"] = evGLO_2G;
}
~HybridObservablesTest()
@ -328,6 +358,11 @@ bool HybridObservablesTest::acquire_signal()
tmp_gnss_synchro.Channel_ID = 0;
config = std::make_shared<InMemoryConfiguration>();
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
// Enable automatic resampler for the acquisition, if required
if (FLAGS_use_acquisition_resampler == true)
{
config->set_property("GNSS-SDR.use_acquisition_resampler", "true");
}
config->set_property("Acquisition.blocking_on_standby", "true");
config->set_property("Acquisition.blocking", "true");
config->set_property("Acquisition.dump", "false");
@ -337,11 +372,12 @@ bool HybridObservablesTest::acquire_signal()
std::shared_ptr<AcquisitionInterface> acquisition;
std::string System_and_Signal;
std::string 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 = "1C";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -353,7 +389,7 @@ bool HybridObservablesTest::acquire_signal()
else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "1B";
signal = "1B";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -364,7 +400,7 @@ bool HybridObservablesTest::acquire_signal()
else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'G';
std::string signal = "2S";
signal = "2S";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -375,7 +411,7 @@ bool HybridObservablesTest::acquire_signal()
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "5X";
signal = "5X";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -391,7 +427,7 @@ bool HybridObservablesTest::acquire_signal()
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "5X";
signal = "5X";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -402,7 +438,7 @@ bool HybridObservablesTest::acquire_signal()
else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'G';
std::string signal = "L5";
signal = "L5";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -433,10 +469,88 @@ bool HybridObservablesTest::acquire_signal()
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::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration);
//top_block->connect(head_samples, 0, acquisition->get_left_block(), 0);
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
// Enable automatic resampler for the acquisition, if required
if (FLAGS_use_acquisition_resampler == true)
{
//create acquisition resamplers if required
double resampler_ratio = 1.0;
double opt_fs = baseband_sampling_freq;
//find the signal associated to this channel
switch (mapStringValues_[signal])
{
case evGPS_1C:
opt_fs = GPS_L1_CA_OPT_ACQ_FS_HZ;
break;
case evGPS_2S:
opt_fs = GPS_L2C_OPT_ACQ_FS_HZ;
break;
case evGPS_L5:
opt_fs = GPS_L5_OPT_ACQ_FS_HZ;
break;
case evSBAS_1C:
opt_fs = GPS_L1_CA_OPT_ACQ_FS_HZ;
break;
case evGAL_1B:
opt_fs = Galileo_E1_OPT_ACQ_FS_HZ;
break;
case evGAL_5X:
opt_fs = Galileo_E5a_OPT_ACQ_FS_HZ;
break;
case evGLO_1G:
opt_fs = baseband_sampling_freq;
break;
case evGLO_2G:
opt_fs = baseband_sampling_freq;
break;
}
if (opt_fs < baseband_sampling_freq)
{
resampler_ratio = baseband_sampling_freq / opt_fs;
int decimation = floor(resampler_ratio);
while (baseband_sampling_freq % decimation > 0)
{
decimation--;
};
double acq_fs = baseband_sampling_freq / decimation;
if (decimation > 1)
{
//create a FIR low pass filter
std::vector<float> taps;
taps = gr::filter::firdes::low_pass(1.0,
baseband_sampling_freq,
acq_fs / 2.1,
acq_fs / 10,
gr::filter::firdes::win_type::WIN_HAMMING);
std::cout << "Enabled decimation low pass filter with " << taps.size() << " taps and decimation factor of " << decimation << std::endl;
acquisition->set_resampler_latency((taps.size() - 1) / 2);
gr::basic_block_sptr fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(decimation, taps);
top_block->connect(gr_interleaved_char_to_complex, 0, fir_filter_ccf_, 0);
top_block->connect(fir_filter_ccf_, 0, acquisition->get_left_block(), 0);
}
else
{
std::cout << "Disabled acquisition resampler because the input sampling frequency is too low\n";
top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
}
}
else
{
std::cout << "Disabled acquisition resampler because the input sampling frequency is too low\n";
top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
}
}
else
{
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);
}
boost::shared_ptr<Acquisition_msg_rx> msg_rx;
try

View File

@ -32,6 +32,10 @@
#include "GPS_L1_CA.h"
#include "GPS_L2C.h"
#include "GPS_L5.h"
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "acquisition_msg_rx.h"
#include "control_message_factory.h"
#include "galileo_e1_pcps_ambiguous_acquisition.h"
@ -58,12 +62,18 @@
#include <gnuradio/blocks/interleaved_char_to_complex.h>
#include <gnuradio/blocks/null_sink.h>
#include <gnuradio/blocks/skiphead.h>
#include <gnuradio/filter/firdes.h>
#include <gnuradio/msg_queue.h>
#include <gnuradio/top_block.h>
#include <gtest/gtest.h>
#include <chrono>
#include <cstdint>
#include <vector>
#ifdef GR_GREATER_38
#include <gnuradio/filter/fir_filter_blk.h>
#else
#include <gnuradio/filter/fir_filter_ccf.h>
#endif
// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER #########
@ -126,6 +136,19 @@ TrackingPullInTest_msg_rx::~TrackingPullInTest_msg_rx()
class TrackingPullInTest : public ::testing::Test
{
public:
enum StringValue
{
evGPS_1C,
evGPS_2S,
evGPS_L5,
evSBAS_1C,
evGAL_1B,
evGAL_5X,
evGLO_1G,
evGLO_2G
};
std::map<std::string, StringValue> mapStringValues_;
std::string generator_binary;
std::string p1;
std::string p2;
@ -171,6 +194,13 @@ public:
config = std::make_shared<InMemoryConfiguration>();
item_size = sizeof(gr_complex);
gnss_synchro = Gnss_Synchro();
mapStringValues_["1C"] = evGPS_1C;
mapStringValues_["2S"] = evGPS_2S;
mapStringValues_["L5"] = evGPS_L5;
mapStringValues_["1B"] = evGAL_1B;
mapStringValues_["5X"] = evGAL_5X;
mapStringValues_["1G"] = evGLO_1G;
mapStringValues_["2G"] = evGLO_2G;
}
~TrackingPullInTest()
@ -289,7 +319,7 @@ void TrackingPullInTest::configure_receiver(
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");
config->set_property("Tracking.track_pilot", "true");
}
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0 or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
{
@ -302,7 +332,7 @@ void TrackingPullInTest::configure_receiver(
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.track_pilot", "true");
config->set_property("Tracking.order", "2");
}
else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)
@ -312,7 +342,7 @@ void TrackingPullInTest::configure_receiver(
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.track_pilot", "true");
config->set_property("Tracking.order", "2");
}
else
@ -345,8 +375,15 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
// Satellite signal definition
Gnss_Synchro tmp_gnss_synchro;
tmp_gnss_synchro.Channel_ID = 0;
config = std::make_shared<InMemoryConfiguration>();
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
// Enable automatic resampler for the acquisition, if required
if (FLAGS_use_acquisition_resampler == true)
{
config->set_property("GNSS-SDR.use_acquisition_resampler", "true");
}
config->set_property("Acquisition.blocking_on_standby", "true");
config->set_property("Acquisition.blocking", "true");
config->set_property("Acquisition.dump", "false");
@ -356,11 +393,12 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
std::shared_ptr<AcquisitionInterface> acquisition;
std::string System_and_Signal;
std::string 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 = "1C";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -372,7 +410,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "1B";
signal = "1B";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -383,7 +421,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'G';
std::string signal = "2S";
signal = "2S";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -394,7 +432,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "5X";
signal = "5X";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -410,7 +448,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'E';
std::string signal = "5X";
signal = "5X";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -421,7 +459,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)
{
tmp_gnss_synchro.System = 'G';
std::string signal = "L5";
signal = "L5";
const char* str = signal.c_str(); // get a C style null terminated string
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
tmp_gnss_synchro.PRN = SV_ID;
@ -449,13 +487,90 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
std::string file = FLAGS_signal_file;
const char* file_name = file.c_str();
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, SEEK_SET); //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::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);
// Enable automatic resampler for the acquisition, if required
if (FLAGS_use_acquisition_resampler == true)
{
//create acquisition resamplers if required
double resampler_ratio = 1.0;
double opt_fs = baseband_sampling_freq;
//find the signal associated to this channel
switch (mapStringValues_[signal])
{
case evGPS_1C:
opt_fs = GPS_L1_CA_OPT_ACQ_FS_HZ;
break;
case evGPS_2S:
opt_fs = GPS_L2C_OPT_ACQ_FS_HZ;
break;
case evGPS_L5:
opt_fs = GPS_L5_OPT_ACQ_FS_HZ;
break;
case evSBAS_1C:
opt_fs = GPS_L1_CA_OPT_ACQ_FS_HZ;
break;
case evGAL_1B:
opt_fs = Galileo_E1_OPT_ACQ_FS_HZ;
break;
case evGAL_5X:
opt_fs = Galileo_E5a_OPT_ACQ_FS_HZ;
break;
case evGLO_1G:
opt_fs = baseband_sampling_freq;
break;
case evGLO_2G:
opt_fs = baseband_sampling_freq;
break;
}
if (opt_fs < baseband_sampling_freq)
{
resampler_ratio = baseband_sampling_freq / opt_fs;
int decimation = floor(resampler_ratio);
while (baseband_sampling_freq % decimation > 0)
{
decimation--;
};
double acq_fs = baseband_sampling_freq / decimation;
if (decimation > 1)
{
//create a FIR low pass filter
std::vector<float> taps;
taps = gr::filter::firdes::low_pass(1.0,
baseband_sampling_freq,
acq_fs / 2.1,
acq_fs / 10,
gr::filter::firdes::win_type::WIN_HAMMING);
std::cout << "Enabled decimation low pass filter with " << taps.size() << " taps and decimation factor of " << decimation << std::endl;
acquisition->set_resampler_latency((taps.size() - 1) / 2);
gr::basic_block_sptr fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(decimation, taps);
top_block->connect(gr_interleaved_char_to_complex, 0, fir_filter_ccf_, 0);
top_block->connect(fir_filter_ccf_, 0, acquisition->get_left_block(), 0);
}
else
{
std::cout << "Disabled acquisition resampler because the input sampling frequency is too low\n";
top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
}
}
else
{
std::cout << "Disabled acquisition resampler because the input sampling frequency is too low\n";
top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
}
}
else
{
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);
}
boost::shared_ptr<Acquisition_msg_rx> msg_rx;
try
@ -531,7 +646,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID)
std::cout << " . ";
}
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, SEEK_SET); //skip head. ibyte, two bytes per complex sample
std::cout.flush();
}
std::cout << "]" << std::endl;