1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-04-08 11:46:46 +00:00
This commit is contained in:
Carles Fernandez 2019-11-24 21:48:37 +01:00
commit 5bddb4e8c8
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
40 changed files with 1175 additions and 1137 deletions

View File

@ -663,14 +663,15 @@ endif()
if(UNIX AND EXISTS "/usr/lib64")
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") # Fedora 64-bit fix
endif()
# Boost_ADDITIONAL_VERSIONS is only used internally by cmake to know the
# formation of newer versions. No need to increase, not used anymore since newer
# Boost provides its own CMake configuration files.
set(Boost_ADDITIONAL_VERSIONS
"1.53.0" "1.53" "1.54.0" "1.54"
"1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
"1.70.0" "1.70" "1.71.0" "1.71" "1.72.0" "1.72" "1.73.0" "1.73" "1.74.0" "1.74"
"1.75.0" "1.75" "1.76.0" "1.76" "1.77.0" "1.77" "1.78.0" "1.78" "1.79.0" "1.79"
"1.80.0" "1.80" "1.81.0" "1.81" "1.82.0" "1.82" "1.83.0" "1.83" "1.84.0" "1.84"
"1.70.0" "1.70" "1.71.0" "1.71"
)
set(Boost_USE_MULTITHREAD ON)
set(Boost_USE_STATIC_LIBS OFF)

View File

@ -5,6 +5,11 @@
- Improved accuracy of the CN0 estimator.
### Improvements in Availability:
- Fixed computation of acquisition threshold when using the pfa configuration parameter, including non-coherent accumulation (max_dwells > 1).
### Improvements in Efficiency:
- Faster implementation of the Viterbi decoder for Galileo navigation messages.
@ -29,6 +34,7 @@
### Improvements in Maintainability:
- Rewriting of acquisition adapters avoiding a lot of code duplication.
- New CMake option ENABLE_ARMA_NO_DEBUG defines the macro ARMA_NO_DEBUG, which disables all run-time checks, such as bounds checking, in the Armadillo library. This will result in faster code. This option is disabled by default during development, but automatically set to ON if the option ENABLE_PACKAGING is set to ON.
- Apply more clang-tidy checks related to readability: readability-avoid-const-params-in-decls, readability-braces-around-statements, readability-isolate-declaration, readability-redundant-control-flow, readability-uppercase-literal-suffix. Fixed raised warnings.
- Fixed cpplint.py build/include_what_you_use, whitespace/tab, whitespace/blank_line errors.

View File

@ -28,6 +28,7 @@
* -------------------------------------------------------------------------
*/
#include "rtklib_pvt_gs.h"
#include "MATH_CONSTANTS.h"
#include "beidou_dnav_almanac.h"
#include "beidou_dnav_ephemeris.h"
@ -60,7 +61,6 @@
#include "pvt_conf.h"
#include "rinex_printer.h"
#include "rtcm_printer.h"
#include "rtklib_pvt_gs.h"
#include "rtklib_solver.h"
#include <boost/any.hpp> // for any_cast, any
#include <boost/archive/xml_iarchive.hpp> // for xml_iarchive
@ -1921,11 +1921,11 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
{
if (in[i][epoch].Flag_valid_pseudorange)
{
std::map<int, Gps_Ephemeris>::const_iterator tmp_eph_iter_gps = d_internal_pvt_solver->gps_ephemeris_map.find(in[i][epoch].PRN);
std::map<int, Galileo_Ephemeris>::const_iterator tmp_eph_iter_gal = d_internal_pvt_solver->galileo_ephemeris_map.find(in[i][epoch].PRN);
std::map<int, Gps_CNAV_Ephemeris>::const_iterator tmp_eph_iter_cnav = d_internal_pvt_solver->gps_cnav_ephemeris_map.find(in[i][epoch].PRN);
std::map<int, Glonass_Gnav_Ephemeris>::const_iterator tmp_eph_iter_glo_gnav = d_internal_pvt_solver->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN);
std::map<int, Beidou_Dnav_Ephemeris>::const_iterator tmp_eph_iter_bds_dnav = d_internal_pvt_solver->beidou_dnav_ephemeris_map.find(in[i][epoch].PRN);
auto tmp_eph_iter_gps = d_internal_pvt_solver->gps_ephemeris_map.find(in[i][epoch].PRN);
auto tmp_eph_iter_gal = d_internal_pvt_solver->galileo_ephemeris_map.find(in[i][epoch].PRN);
auto tmp_eph_iter_cnav = d_internal_pvt_solver->gps_cnav_ephemeris_map.find(in[i][epoch].PRN);
auto tmp_eph_iter_glo_gnav = d_internal_pvt_solver->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN);
auto tmp_eph_iter_bds_dnav = d_internal_pvt_solver->beidou_dnav_ephemeris_map.find(in[i][epoch].PRN);
bool store_valid_observable = false;

View File

@ -53,6 +53,7 @@ Pvt_Solution::Pvt_Solution()
d_valid_observations = 0;
d_rx_pos = arma::zeros(3, 1);
d_rx_dt_s = 0.0;
d_rx_clock_drift_ppm = 0.0;
d_pre_2009_file = false; // disabled by default
}

View File

@ -37,7 +37,6 @@
#include "beidou_b1i_signal_processing.h"
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <algorithm>
#include <memory>
@ -52,65 +51,26 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
out_streams_(out_streams)
{
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
acq_parameters_.ms_per_code = 1;
acq_parameters_.SetFromConfiguration(configuration_, role, BEIDOU_B1I_CODE_RATE_CPS, 10e6);
LOG(INFO) << "role " << role;
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_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
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 = FLAGS_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_;
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
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);
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
fs_in_ = acq_parameters_.fs_in;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
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);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
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_) / (BEIDOU_B1I_CODE_RATE_CPS / BEIDOU_B1I_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 / BEIDOU_B1I_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in)));
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B1I_CODE_PERIOD_S * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
@ -122,7 +82,6 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
gnss_synchro_ = nullptr;
if (in_streams_ > 1)
@ -143,18 +102,7 @@ void BeidouB1iPcpsAcquisition::stop_acquisition()
void BeidouB1iPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + ".pfa", 0.0);
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -225,23 +173,6 @@ void BeidouB1iPcpsAcquisition::set_state(int state)
}
float BeidouB1iPcpsAcquisition::calculate_threshold(float pfa)
{
// Calculate the threshold
uint32_t frequency_bins = 0;
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
uint32_t ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void BeidouB1iPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")

View File

@ -170,17 +170,12 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
@ -188,7 +183,6 @@ private:
unsigned int num_codes_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H_ */

View File

@ -35,7 +35,6 @@
#include "beidou_b3i_signal_processing.h"
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <algorithm>
@ -50,65 +49,26 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
out_streams_(out_streams)
{
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
acq_parameters_.ms_per_code = 1;
acq_parameters_.SetFromConfiguration(configuration_, role, BEIDOU_B3I_CODE_RATE_CPS, 100e6);
LOG(INFO) << "role " << role;
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_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
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 = FLAGS_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_;
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
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);
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
fs_in_ = acq_parameters_.fs_in;
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
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);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
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_) / (BEIDOU_B3I_CODE_RATE_CPS / BEIDOU_B3I_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 / BEIDOU_B3I_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in)));
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B3I_CODE_PERIOD_S * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
@ -120,7 +80,6 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
gnss_synchro_ = nullptr;
if (in_streams_ > 1)
@ -141,22 +100,7 @@ void BeidouB3iPcpsAcquisition::stop_acquisition()
void BeidouB3iPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -226,23 +170,6 @@ void BeidouB3iPcpsAcquisition::set_state(int state)
}
float BeidouB3iPcpsAcquisition::calculate_threshold(float pfa)
{
// Calculate the threshold
unsigned int frequency_bins = 0;
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1.0 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void BeidouB3iPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")

View File

@ -169,17 +169,12 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
@ -187,7 +182,6 @@ private:
unsigned int num_codes_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_BEIDOU_B3I_PCPS_ACQUISITION_H_ */

View File

@ -49,99 +49,28 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
out_streams_(out_streams)
{
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
acq_parameters_.ms_per_code = 4;
acq_parameters_.SetFromConfiguration(configuration_, role, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_OPT_ACQ_FS_SPS);
DLOG(INFO) << "role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type);
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_;
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)
{
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;
}
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
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_;
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_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters_.blocking = blocking_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_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_SPS)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GALILEO_E1_OPT_ACQ_FS_SPS);
uint32_t decimation = acq_parameters_.fs_in / GALILEO_E1_OPT_ACQ_FS_SPS;
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_CPS / 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_CPS) * 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_CPS / 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_CPS) * static_cast<float>(acq_parameters_.fs_in)));
}
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;
acq_parameters_.doppler_max = FLAGS_doppler_max;
}
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
fs_in_ = acq_parameters_.fs_in;
acquire_pilot_ = configuration->property(role + ".acquire_pilot", false);
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS)));
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
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);
sampled_ms_ = acq_parameters_.sampled_ms;
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
@ -153,7 +82,6 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
doppler_center_ = 0;
gnss_synchro_ = nullptr;
@ -175,23 +103,7 @@ void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition()
void GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -303,27 +215,6 @@ void GalileoE1PcpsAmbiguousAcquisition::set_state(int state)
}
float GalileoE1PcpsAmbiguousAcquisition::calculate_threshold(float pfa)
{
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
{
frequency_bins++;
}
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GalileoE1PcpsAmbiguousAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")

View File

@ -173,8 +173,6 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
bool acquire_pilot_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
@ -183,17 +181,13 @@ private:
unsigned int doppler_step_;
int doppler_center_;
unsigned int sampled_ms_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_H_ */

View File

@ -34,7 +34,6 @@
#include "configuration_interface.h"
#include "galileo_e5_signal_processing.h"
#include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr_complex.h>
#include <algorithm>
@ -48,109 +47,40 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
out_streams_(out_streams)
{
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
acq_parameters_.ms_per_code = 1;
acq_parameters_.SetFromConfiguration(configuration_, role, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_OPT_ACQ_FS_SPS);
DLOG(INFO) << "Role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type);
if (FLAGS_doppler_max != 0)
{
acq_parameters_.doppler_max = FLAGS_doppler_max;
}
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
fs_in_ = acq_parameters_.fs_in;
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_pilot_ = configuration_->property(role + ".acquire_pilot", false);
acq_iq_ = configuration_->property(role + ".acquire_iq", false);
if (acq_iq_)
{
acq_pilot_ = false;
}
dump_ = configuration_->property(role + ".dump", false);
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_;
sampled_ms_ = 1;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_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_;
use_CFAR_ = configuration_->property(role + ".use_CFAR_algorithm", false);
acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_;
blocking_ = configuration_->property(role + ".blocking", true);
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_SPS)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GALILEO_E5A_OPT_ACQ_FS_SPS);
uint32_t decimation = acq_parameters_.fs_in / GALILEO_E5A_OPT_ACQ_FS_SPS;
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_CPS / 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_CPS) * 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_CPS / 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_CPS) * 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_CPS * static_cast<double>(GALILEO_E5A_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS)));
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex")
{
item_size_ = sizeof(gr_complex);
}
else if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
item_size_ = sizeof(gr_complex);
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
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);
sampled_ms_ = acq_parameters_.sampled_ms;
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
doppler_center_ = 0;
gnss_synchro_ = nullptr;
@ -172,24 +102,7 @@ void GalileoE5aPcpsAcquisition::stop_acquisition()
void GalileoE5aPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -280,25 +193,6 @@ void GalileoE5aPcpsAcquisition::reset()
}
float GalileoE5aPcpsAcquisition::calculate_threshold(float pfa)
{
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
{
frequency_bins++;
}
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GalileoE5aPcpsAcquisition::set_state(int state)
{
acquisition_->set_state(state);

View File

@ -154,7 +154,6 @@ public:
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_;
@ -162,11 +161,7 @@ private:
std::string item_type_;
std::string dump_filename_;
std::string role_;
bool bit_transition_flag_;
bool dump_;
bool acq_pilot_;
bool use_CFAR_;
bool blocking_;
bool acq_iq_;
unsigned int vector_length_;
unsigned int code_length_;
@ -176,7 +171,6 @@ private:
unsigned int doppler_step_;
int doppler_center_;
unsigned int sampled_ms_;
unsigned int max_dwells_;
unsigned int in_streams_;
unsigned int out_streams_;
int64_t fs_in_;

View File

@ -37,7 +37,6 @@
#include "configuration_interface.h"
#include "glonass_l1_signal_processing.h"
#include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <algorithm>
@ -50,70 +49,29 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
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 = "./data/acquisition.dat";
acq_parameters_.ms_per_code = 1;
acq_parameters_.SetFromConfiguration(configuration_, role, GLONASS_L1_CA_CODE_RATE_CPS, 100e6);
DLOG(INFO) << "role " << role;
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(GLONASS_L1_CA_CHIP_PERIOD_S * static_cast<float>(acq_parameters.fs_in)));
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
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_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
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 -------------------------
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GLONASS_L1_CA_CODE_RATE_CPS / GLONASS_L1_CA_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
if (bit_transition_flag_)
{
vector_length_ *= 2;
acq_parameters_.doppler_max = FLAGS_doppler_max;
}
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
fs_in_ = acq_parameters_.fs_in;
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GLONASS_L1_CA_CODE_RATE_CPS / GLONASS_L1_CA_CODE_LENGTH_CHIPS)));
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
item_size_ = sizeof(gr_complex);
}
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD_S * 1000.0);
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);
sampled_ms_ = acq_parameters_.sampled_ms;
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte")
@ -145,18 +103,7 @@ void GlonassL1CaPcpsAcquisition::stop_acquisition()
void GlonassL1CaPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + ".pfa", 0.0);
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -228,31 +175,6 @@ void GlonassL1CaPcpsAcquisition::set_state(int state)
}
float GlonassL1CaPcpsAcquisition::calculate_threshold(float pfa)
{
// Calculate the threshold
unsigned int frequency_bins = 0;
/*
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
{
frequency_bins++;
}
*/
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GlonassL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")

View File

@ -34,6 +34,7 @@
#ifndef GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_
#define GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_
#include "acq_conf.h"
#include "channel_fsm.h"
#include "complex_byte_to_float_x2.h"
#include "gnss_synchro.h"
@ -156,6 +157,7 @@ public:
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_;
@ -163,25 +165,19 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ */

View File

@ -36,7 +36,6 @@
#include "configuration_interface.h"
#include "glonass_l2_signal_processing.h"
#include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <algorithm>
@ -49,70 +48,29 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
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 = "./data/acquisition.dat";
acq_parameters_.ms_per_code = 1;
acq_parameters_.SetFromConfiguration(configuration_, role, GLONASS_L2_CA_CODE_RATE_CPS, 100e6);
DLOG(INFO) << "role " << role;
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(GLONASS_L2_CA_CHIP_PERIOD_S * static_cast<float>(acq_parameters.fs_in)));
dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_;
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
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_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
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 -------------------------
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GLONASS_L2_CA_CODE_RATE_CPS / GLONASS_L2_CA_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
if (bit_transition_flag_)
{
vector_length_ *= 2;
acq_parameters_.doppler_max = FLAGS_doppler_max;
}
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
fs_in_ = acq_parameters_.fs_in;
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GLONASS_L2_CA_CODE_RATE_CPS / GLONASS_L2_CA_CODE_LENGTH_CHIPS)));
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
item_size_ = sizeof(gr_complex);
}
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD_S * 1000.0);
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);
sampled_ms_ = acq_parameters_.sampled_ms;
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte")
@ -144,18 +102,7 @@ void GlonassL2CaPcpsAcquisition::stop_acquisition()
void GlonassL2CaPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + ".pfa", 0.0);
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -227,31 +174,6 @@ void GlonassL2CaPcpsAcquisition::set_state(int state)
}
float GlonassL2CaPcpsAcquisition::calculate_threshold(float pfa)
{
// Calculate the threshold
unsigned int frequency_bins = 0;
/*
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
{
frequency_bins++;
}
*/
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GlonassL2CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")

View File

@ -33,6 +33,7 @@
#ifndef GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_
#define GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_
#include "acq_conf.h"
#include "channel_fsm.h"
#include "complex_byte_to_float_x2.h"
#include "gnss_synchro.h"
@ -155,6 +156,7 @@ public:
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_;
@ -162,25 +164,19 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ */

View File

@ -39,7 +39,6 @@
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include "gps_sdr_signal_processing.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <gsl/gsl>
#include <algorithm>
@ -54,88 +53,27 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
out_streams_(out_streams)
{
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
acq_parameters_.ms_per_code = 1;
acq_parameters_.SetFromConfiguration(configuration_, role, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_OPT_ACQ_FS_SPS);
DLOG(INFO) << "role " << role;
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_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
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_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 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_;
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
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_.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_SPS)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L1_CA_OPT_ACQ_FS_SPS);
uint32_t decimation = acq_parameters_.fs_in / GPS_L1_CA_OPT_ACQ_FS_SPS;
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_CPS / 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_S * 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_CPS / GPS_L1_CA_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(GPS_L1_CA_CHIP_PERIOD_S * static_cast<float>(acq_parameters_.fs_in)));
acq_parameters_.doppler_max = FLAGS_doppler_max;
}
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD_S * 1000.0);
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS)));
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
item_size_ = sizeof(gr_complex);
}
sampled_ms_ = acq_parameters_.sampled_ms;
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() << ")";
@ -147,7 +85,6 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
doppler_center_ = 0;
gnss_synchro_ = nullptr;
@ -169,18 +106,7 @@ void GpsL1CaPcpsAcquisition::stop_acquisition()
void GpsL1CaPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + ".pfa", 0.0);
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -240,7 +166,7 @@ void GpsL1CaPcpsAcquisition::set_local_code()
}
else
{
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0);
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.fs_in, 0);
}
gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_; i++)
@ -264,26 +190,6 @@ void GpsL1CaPcpsAcquisition::set_state(int state)
}
float GpsL1CaPcpsAcquisition::calculate_threshold(float pfa)
{
// Calculate the threshold
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
{
frequency_bins++;
}
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
@ -304,7 +210,7 @@ void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
}
else
{
LOG(WARNING) << item_type_ << " unknown acquisition item type";
LOG(WARNING) << item_type_ << " unknown acquisition item type: " << item_type_;
}
}
@ -327,7 +233,7 @@ void GpsL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
}
else
{
LOG(WARNING) << item_type_ << " unknown acquisition item type";
LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_;
}
}
@ -347,7 +253,7 @@ gr::basic_block_sptr GpsL1CaPcpsAcquisition::get_left_block()
return cbyte_to_float_x2_;
}
LOG(WARNING) << item_type_ << " unknown acquisition item type";
LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_;
return nullptr;
}

View File

@ -177,8 +177,6 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
@ -186,17 +184,12 @@ private:
unsigned int doppler_step_;
int doppler_center_;
unsigned int sampled_ms_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H_ */

View File

@ -37,7 +37,6 @@
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include "gps_l2c_signal.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <algorithm>
@ -51,94 +50,25 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
out_streams_(out_streams)
{
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
acq_parameters_.ms_per_code = 20;
acq_parameters_.SetFromConfiguration(configuration_, role, GPS_L2_M_CODE_RATE_CPS, GPS_L2C_OPT_ACQ_FS_SPS);
LOG(INFO) << "role " << role;
DLOG(INFO) << "Role " << role;
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_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
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_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
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_.doppler_max = FLAGS_doppler_max;
}
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
fs_in_ = acq_parameters_.fs_in;
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_SPS)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L2C_OPT_ACQ_FS_SPS);
uint32_t decimation = acq_parameters_.fs_in / GPS_L2C_OPT_ACQ_FS_SPS;
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_L2_M_CODE_RATE_CPS / 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_CPS) * 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_CPS / 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_CPS) * static_cast<float>(acq_parameters_.fs_in)));
}
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD_S * 1000.0);
vector_length_ = acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L2_M_CODE_RATE_CPS / GPS_L2_M_CODE_LENGTH_CHIPS)));
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
item_size_ = sizeof(gr_complex);
}
acq_parameters_.it_size = item_size_;
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
@ -150,7 +80,6 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
doppler_center_ = 0;
gnss_synchro_ = nullptr;
@ -173,22 +102,7 @@ void GpsL2MPcpsAcquisition::stop_acquisition()
void GpsL2MPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -275,26 +189,6 @@ void GpsL2MPcpsAcquisition::set_state(int state)
}
float GpsL2MPcpsAcquisition::calculate_threshold(float pfa)
{
// Calculate the threshold
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
{
frequency_bins++;
}
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1.0 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GpsL2MPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")

View File

@ -174,18 +174,13 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
int doppler_center_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
@ -193,7 +188,6 @@ private:
unsigned int in_streams_;
unsigned int out_streams_;
unsigned int num_codes_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_H_ */

View File

@ -37,7 +37,6 @@
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include "gps_l5_signal.h"
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#include <algorithm>
@ -51,90 +50,28 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
out_streams_(out_streams)
{
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat";
acq_parameters_.ms_per_code = 1;
acq_parameters_.SetFromConfiguration(configuration_, role, GPS_L5I_CODE_RATE_CPS, GPS_L5_OPT_ACQ_FS_SPS);
LOG(INFO) << "role " << role;
DLOG(INFO) << "role " << role;
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_;
dump_ = configuration_->property(role + ".dump", false);
acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true);
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_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
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);
if (item_type_ == "cshort")
{
item_size_ = sizeof(lv_16sc_t);
}
else
{
item_size_ = sizeof(gr_complex);
acq_parameters_.doppler_max = FLAGS_doppler_max;
}
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_SPS)
{
acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L5_OPT_ACQ_FS_SPS);
uint32_t decimation = acq_parameters_.fs_in / GPS_L5_OPT_ACQ_FS_SPS;
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);
}
doppler_max_ = acq_parameters_.doppler_max;
doppler_step_ = acq_parameters_.doppler_step;
item_type_ = acq_parameters_.item_type;
item_size_ = acq_parameters_.it_size;
// -- 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_CPS / 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_CPS) * 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_CPS / 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_CPS) * static_cast<float>(acq_parameters_.fs_in)));
}
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L5I_PERIOD_S * 1000.0);
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS)));
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
fs_in_ = acq_parameters_.fs_in;
num_codes_ = acq_parameters_.sampled_ms;
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
@ -146,7 +83,6 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
channel_ = 0;
threshold_ = 0.0;
doppler_step_ = 0;
doppler_center_ = 0;
gnss_synchro_ = nullptr;
@ -168,22 +104,7 @@ void GpsL5iPcpsAcquisition::stop_acquisition()
void GpsL5iPcpsAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
threshold_ = threshold;
acquisition_->set_threshold(threshold_);
}
@ -270,26 +191,6 @@ void GpsL5iPcpsAcquisition::set_state(int state)
}
float GpsL5iPcpsAcquisition::calculate_threshold(float pfa)
{
// Calculate the threshold
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
{
frequency_bins++;
}
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1.0 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val));
return threshold;
}
void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
@ -310,7 +211,7 @@ void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block)
}
else
{
LOG(WARNING) << item_type_ << " unknown acquisition item type";
LOG(WARNING) << item_type_ << " unknown acquisition item type: " << item_type_;
}
}
@ -333,7 +234,7 @@ void GpsL5iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
}
else
{
LOG(WARNING) << item_type_ << " unknown acquisition item type";
LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_;
}
}
@ -353,7 +254,7 @@ gr::basic_block_sptr GpsL5iPcpsAcquisition::get_left_block()
return cbyte_to_float_x2_;
}
LOG(WARNING) << item_type_ << " unknown acquisition item type";
LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_;
return nullptr;
}

View File

@ -174,18 +174,13 @@ private:
std::string item_type_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
int doppler_center_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
std::string dump_filename_;
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
@ -193,7 +188,6 @@ private:
unsigned int num_codes_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};
#endif /* GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H_ */

View File

@ -48,6 +48,7 @@
#else
#include <boost/filesystem/path.hpp>
#endif
#include <boost/math/special_functions/gamma.hpp>
#include <gnuradio/io_signature.h>
#include <matio.h>
#include <pmt/pmt.h> // for from_long
@ -105,7 +106,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
d_input_power = 0.0;
d_num_doppler_bins = 0U;
d_threshold = 0.0;
d_doppler_step = 0U;
d_doppler_step = acq_parameters.doppler_step;
d_doppler_center = 0U;
d_doppler_center_step_two = 0.0;
d_test_statistics = 0.0;
@ -129,11 +130,11 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
//
// We can avoid this by doing linear correlation, effectively doubling the
// size of the input buffer and padding the code with zeros.
if (acq_parameters.bit_transition_flag)
{
d_fft_size = d_consumed_samples * 2;
acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells
}
//if (acq_parameters.bit_transition_flag)
//{
//d_fft_size = d_consumed_samples * 2;
//acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells
//}
d_tmp_buffer = volk_gnsssdr::vector<float>(d_fft_size);
d_fft_codes = volk_gnsssdr::vector<std::complex<float>>(d_fft_size);
@ -160,14 +161,14 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
d_samplesPerChip = acq_parameters.samples_per_chip;
d_buffer_count = 0U;
// todo: CFAR statistic not available for non-coherent integration
if (acq_parameters.max_dwells == 1)
{
d_use_CFAR_algorithm_flag = acq_parameters.use_CFAR_algorithm_flag;
}
else
{
d_use_CFAR_algorithm_flag = false;
}
//if (acq_parameters.max_dwells == 1)
//{
d_use_CFAR_algorithm_flag = acq_parameters.use_CFAR_algorithm_flag;
//}
//else
//{
//d_use_CFAR_algorithm_flag = false;
//}
d_dump_number = 0LL;
d_dump_channel = acq_parameters.dump_channel;
d_dump = acq_parameters.dump;
@ -364,7 +365,6 @@ void pcps_acquisition::set_state(int32_t state)
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
d_gnss_synchro->Acq_doppler_step = 0U;
d_mag = 0.0;
d_input_power = 0.0;
d_test_statistics = 0.0;
d_active = true;
}
@ -382,16 +382,16 @@ void pcps_acquisition::send_positive_acquisition()
{
// Declare positive acquisition using a message port
// 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
DLOG(INFO) << "positive acquisition"
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< ", sample_stamp " << d_sample_counter
<< ", test statistics value " << d_test_statistics
<< ", test statistics threshold " << d_threshold
<< ", code phase " << d_gnss_synchro->Acq_delay_samples
<< ", doppler " << d_gnss_synchro->Acq_doppler_hz
<< ", magnitude " << d_mag
<< ", input signal power " << d_input_power
<< ", Assist doppler_center " << d_doppler_center;
LOG(INFO) << "positive acquisition"
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< ", sample_stamp " << d_sample_counter
<< ", test statistics value " << d_test_statistics
<< ", test statistics threshold " << d_threshold
<< ", code phase " << d_gnss_synchro->Acq_delay_samples
<< ", doppler " << d_gnss_synchro->Acq_doppler_hz
<< ", magnitude " << d_mag
<< ", input signal power " << d_input_power
<< ", Assist doppler_center " << d_doppler_center;
d_positive_acq = 1;
if (!d_channel_fsm.expired())
@ -410,15 +410,15 @@ void pcps_acquisition::send_negative_acquisition()
{
// Declare negative acquisition using a message port
// 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
DLOG(INFO) << "negative acquisition"
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< ", sample_stamp " << d_sample_counter
<< ", test statistics value " << d_test_statistics
<< ", test statistics threshold " << d_threshold
<< ", code phase " << d_gnss_synchro->Acq_delay_samples
<< ", doppler " << d_gnss_synchro->Acq_doppler_hz
<< ", magnitude " << d_mag
<< ", input signal power " << d_input_power;
LOG(INFO) << "negative acquisition"
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< ", sample_stamp " << d_sample_counter
<< ", test statistics value " << d_test_statistics
<< ", test statistics threshold " << d_threshold
<< ", code phase " << d_gnss_synchro->Acq_delay_samples
<< ", doppler " << d_gnss_synchro->Acq_doppler_hz
<< ", magnitude " << d_mag
<< ", input signal power " << d_input_power;
d_positive_acq = 0;
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
}
@ -527,18 +527,18 @@ void pcps_acquisition::dump_results(int32_t effective_fft_size)
}
float pcps_acquisition::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)
float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step)
{
float grid_maximum = 0.0;
uint32_t index_doppler = 0U;
uint32_t tmp_intex_t = 0U;
uint32_t index_time = 0U;
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
int32_t effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
// Find the correlation peak and the carrier frequency
for (uint32_t i = 0; i < num_doppler_bins; i++)
{
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i].data(), d_fft_size);
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i].data(), effective_fft_size);
if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum)
{
grid_maximum = d_magnitude_grid[i][tmp_intex_t];
@ -549,6 +549,8 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t&
indext = index_time;
if (!d_step_two)
{
int index_opp = (index_doppler + d_num_doppler_bins / 2) % d_num_doppler_bins;
d_input_power = std::accumulate(d_magnitude_grid[index_opp].data(), d_magnitude_grid[index_opp].data() + effective_fft_size, 0.0) / effective_fft_size / 2.0 / d_num_noncoherent_integrations_counter;
doppler = -static_cast<int32_t>(doppler_max) + d_doppler_center + doppler_step * static_cast<int32_t>(index_doppler);
}
else
@ -556,8 +558,7 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t&
doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2);
}
float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor);
return magt / input_power;
return grid_maximum / d_input_power;
}
@ -652,7 +653,6 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
}
const gr_complex* in = d_input_signal.data(); // Get the input samples pointer
d_input_power = 0.0;
d_mag = 0.0;
d_num_noncoherent_integrations_counter++;
@ -665,14 +665,6 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
lk.unlock();
if (d_use_CFAR_algorithm_flag or acq_parameters.bit_transition_flag)
{
// Compute the input signal power estimation
volk_32fc_magnitude_squared_32f(d_tmp_buffer.data(), in, d_fft_size);
volk_32f_accumulator_s32f(&d_input_power, d_tmp_buffer.data(), d_fft_size);
d_input_power /= static_cast<float>(d_fft_size);
}
// Doppler frequency grid loop
if (!d_step_two)
{
@ -712,7 +704,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
// Compute the test statistic
if (d_use_CFAR_algorithm_flag)
{
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
}
else
{
@ -769,7 +761,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
// Compute the test statistic
if (d_use_CFAR_algorithm_flag)
{
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, 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);
d_test_statistics = max_to_input_power_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);
}
else
{
@ -815,6 +807,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
d_positive_acq = 0;
d_state = 0;
}
calculate_threshold();
}
else
{
@ -836,7 +829,12 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
}
d_state = 0;
d_active = false;
bool was_step_two = d_step_two;
d_step_two = false;
if (was_step_two)
{
calculate_threshold();
}
}
}
else
@ -858,6 +856,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
d_num_noncoherent_integrations_counter = 0U;
d_state = 0;
}
calculate_threshold();
}
else
{
@ -868,7 +867,12 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
else
{
d_state = 0; // Negative acquisition
bool was_step_two = d_step_two;
d_step_two = false;
if (was_step_two)
{
calculate_threshold();
}
send_negative_acquisition();
}
}
@ -899,10 +903,29 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
bool pcps_acquisition::start()
{
d_sample_counter = 0ULL;
calculate_threshold();
return true;
}
void pcps_acquisition::calculate_threshold()
{
float pfa = (d_step_two ? acq_parameters.pfa2 : acq_parameters.pfa);
if (pfa <= 0.0)
{
return;
}
int effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size);
int num_doppler_bins = (d_step_two ? d_num_doppler_bins_step2 : d_num_doppler_bins);
int num_bins = effective_fft_size * num_doppler_bins;
d_threshold = 2.0 * boost::math::gamma_p_inv(2.0 * acq_parameters.max_dwells, std::pow(1.0 - pfa, 1.0 / static_cast<float>(num_bins)));
}
int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
@ -946,8 +969,6 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
d_gnss_synchro->Acq_doppler_step = 0U;
d_mag = 0.0;
d_input_power = 0.0;
d_test_statistics = 0.0;
d_state = 1;
d_buffer_count = 0U;
if (!acq_parameters.blocking_on_standby)

View File

@ -267,8 +267,9 @@ private:
void dump_results(int32_t effective_fft_size);
bool is_fdma();
bool start();
void calculate_threshold(void);
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);
float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
};
#endif /* GNSS_SDR_PCPS_ACQUISITION_H_*/

View File

@ -30,31 +30,135 @@
*/
#include "acq_conf.h"
#include "item_type_helpers.h"
#include <glog/logging.h>
#include <gnuradio/gr_complex.h>
Acq_Conf::Acq_Conf()
{
/* PCPS acquisition configuration */
sampled_ms = 0U;
ms_per_code = 0U;
max_dwells = 0U;
samples_per_chip = 0U;
doppler_max = 0U;
num_doppler_bins_step2 = 0U;
doppler_step2 = 0.0;
fs_in = 0LL;
sampled_ms = 1U;
ms_per_code = 1U;
max_dwells = 1U;
samples_per_chip = 2U;
chips_per_second = 1023000;
doppler_max = 5000;
doppler_min = -5000;
doppler_step = 250.0;
num_doppler_bins_step2 = 4U;
doppler_step2 = 125.0;
pfa = 0.0;
pfa2 = 0.0;
fs_in = 4000000;
samples_per_ms = 0.0;
samples_per_code = 0.0;
bit_transition_flag = false;
use_CFAR_algorithm_flag = false;
use_CFAR_algorithm_flag = true;
dump = false;
blocking = false;
blocking = true;
make_2_steps = false;
dump_filename = "";
dump_channel = 0U;
it_size = sizeof(char);
it_size = sizeof(gr_complex);
item_type = "gr_complex";
blocking_on_standby = false;
use_automatic_resampler = false;
resampler_ratio = 1.0;
resampled_fs = 0LL;
resampler_latency_samples = 0U;
}
void Acq_Conf::SetFromConfiguration(ConfigurationInterface *configuration,
const std::string &role, double chip_rate, double opt_freq)
{
item_type = configuration->property(role + ".item_type", item_type);
if (!item_type_valid(item_type))
{
throw std::invalid_argument("Unknown item type: " + item_type);
}
chips_per_second = chip_rate;
int64_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", fs_in);
fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
doppler_max = configuration->property(role + ".doppler_max", doppler_max);
sampled_ms = configuration->property(role + ".coherent_integration_time_ms", sampled_ms);
bit_transition_flag = configuration->property(role + ".bit_transition_flag", bit_transition_flag);
max_dwells = configuration->property(role + ".max_dwells", max_dwells);
dump = configuration->property(role + ".dump", dump);
dump_channel = configuration->property(role + ".dump_channel", dump_channel);
blocking = configuration->property(role + ".blocking", blocking);
dump_filename = configuration->property(role + ".dump_filename", dump_filename);
use_automatic_resampler = configuration->property("GNSS-SDR.use_acquisition_resampler", use_automatic_resampler);
if ((sampled_ms % ms_per_code) != 0)
{
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of "
<< ms_per_code << ". Setting it to " << ms_per_code;
sampled_ms = ms_per_code;
}
resampled_fs = fs_in;
if (use_automatic_resampler)
{
ConfigureAutomaticResampler(opt_freq);
}
it_size = item_type_size(item_type);
num_doppler_bins_step2 = configuration->property(role + ".second_nbins", num_doppler_bins_step2);
doppler_step2 = configuration->property(role + ".second_doppler_step", doppler_step2);
doppler_step = configuration->property(role + ".doppler_step", doppler_step);
pfa = configuration->property(role + ".pfa", pfa);
if ((pfa < 0.0) or (pfa > 1.0))
{
LOG(WARNING) << "Parameter pfa should between 0.0 and 1.0. Setting it to 0.0";
pfa = 0.0;
}
pfa2 = configuration->property(role + ".pfa_second_step", pfa2);
if ((pfa2 <= 0.0) or (pfa2 > 1.0))
{
pfa2 = pfa;
}
make_2_steps = configuration->property(role + ".make_two_steps", make_2_steps);
blocking_on_standby = configuration->property(role + ".blocking_on_standby", blocking_on_standby);
if (pfa <= 0.0)
{
// if pfa is not set, we use the first_vs_second_peak_statistic metric
use_CFAR_algorithm_flag = false;
}
SetDerivedParams();
}
void Acq_Conf::ConfigureAutomaticResampler(double opt_freq)
{
if (use_automatic_resampler)
{
if (fs_in > opt_freq)
{
resampler_ratio = floor(static_cast<float>(fs_in) / opt_freq);
uint32_t decimation = fs_in / opt_freq;
while (fs_in % decimation > 0)
{
decimation--;
};
resampler_ratio = decimation;
resampled_fs = fs_in / static_cast<int>(resampler_ratio);
}
// --- Find number of samples per spreading code -------------------
SetDerivedParams();
}
}
void Acq_Conf::SetDerivedParams()
{
samples_per_ms = static_cast<float>(resampled_fs) * 0.001;
samples_per_chip = static_cast<unsigned int>(ceil(static_cast<float>(resampled_fs) / chips_per_second));
samples_per_code = samples_per_ms * ms_per_code;
}

View File

@ -32,6 +32,7 @@
#ifndef GNSS_SDR_ACQ_CONF_H_
#define GNSS_SDR_ACQ_CONF_H_
#include "configuration_interface.h"
#include <cstddef>
#include <cstdint>
#include <string>
@ -43,10 +44,15 @@ public:
uint32_t sampled_ms;
uint32_t ms_per_code;
uint32_t samples_per_chip;
uint32_t chips_per_second;
uint32_t max_dwells;
uint32_t doppler_max;
int32_t doppler_max;
int32_t doppler_min;
float doppler_step;
uint32_t num_doppler_bins_step2;
float doppler_step2;
float pfa;
float pfa2;
int64_t fs_in;
float samples_per_ms;
float samples_per_code;
@ -63,8 +69,16 @@ public:
std::string dump_filename;
uint32_t dump_channel;
size_t it_size;
std::string item_type;
Acq_Conf();
void SetFromConfiguration(ConfigurationInterface *configuration, const std::string &role, double chip_rate, double opt_freq);
private:
void SetDerivedParams();
void ConfigureAutomaticResampler(double opt_freq);
};
#endif

View File

@ -40,6 +40,7 @@ set(GNSS_SPLIBS_SOURCES
conjugate_ic.cc
gnss_sdr_create_directory.cc
geofunctions.cc
item_type_helpers.cc
)
set(GNSS_SPLIBS_HEADERS
@ -65,6 +66,7 @@ set(GNSS_SPLIBS_HEADERS
gnss_sdr_create_directory.h
gnss_circular_deque.h
geofunctions.h
item_type_helpers.h
)
if(ENABLE_OPENCL)
@ -133,6 +135,30 @@ target_compile_definitions(algorithms_libs
PUBLIC -DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}"
)
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1")
target_compile_definitions(algorithms_libs
PRIVATE -DOLDCOMPILER=1
)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CLANG_VERSION VERSION_LESS "600")
target_compile_definitions(algorithms_libs
PRIVATE -DOLDCOMPILER=1
)
endif()
else()
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0")
target_compile_definitions(algorithms_libs
PRIVATE -DOLDCOMPILER=1
)
endif()
endif()
endif()
set_property(TARGET algorithms_libs
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>

View File

@ -0,0 +1,409 @@
/*!
* \file item_type_helpers.cc
* \brief Utility functions for converting between item types
* \authors <ul>
* <li> Cillian O'Driscoll, 2019. cillian.odriscoll(at)gmail.com
* </ul>
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "item_type_helpers.h"
#include <volk/volk.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <cstring> // memcpy
bool item_type_valid(const std::string &item_type)
{
if (item_type != "byte" and item_type != "cbyte" and item_type != "ibyte" and
item_type != "short" and item_type != "cshort" and item_type != "ishort" and
item_type != "float" and item_type != "gr_complex")
{
return false;
}
return true;
}
size_t item_type_size(const std::string &item_type)
{
if (item_type == "byte" or item_type == "ibyte")
{
return sizeof(int8_t);
}
else if (item_type == "cbyte")
{
return 2 * sizeof(int8_t);
}
else if (item_type == "short" or item_type == "ishort")
{
return sizeof(int16_t);
}
else if (item_type == "cshort")
{
return 2 * sizeof(int16_t);
}
else if (item_type == "float")
{
return sizeof(float);
}
else if (item_type == "gr_complex")
{
return 2 * sizeof(float);
}
else
{
return 0;
}
}
bool item_type_is_complex(const std::string &item_type)
{
return (item_type == "ibyte") or (item_type == "cbyte") or (item_type == "ishort") or (item_type == "cshort") or (item_type == "gr_complex");
}
void copy_converter(void *dest, const void *src, unsigned int num_items, size_t item_size)
{
std::memcpy(dest, src, num_items * item_size);
}
void convert_8i_16i(void *dest, const void *src, unsigned int num_items)
{
volk_8i_convert_16i(reinterpret_cast<int16_t *>(dest),
reinterpret_cast<const int8_t *>(src), num_items);
}
void convert_8i_32f(void *dest, const void *src, unsigned int num_items)
{
volk_8i_s32f_convert_32f(reinterpret_cast<float *>(dest),
reinterpret_cast<const int8_t *>(src), 1.0F, num_items);
}
void convert_8ic_16ic(void *dest, const void *src, unsigned int num_items)
{
volk_8i_convert_16i(reinterpret_cast<int16_t *>(dest),
reinterpret_cast<const int8_t *>(src), 2 * num_items);
}
void convert_8ic_32fc(void *dest, const void *src, unsigned int num_items)
{
volk_8i_s32f_convert_32f(reinterpret_cast<float *>(dest),
reinterpret_cast<const int8_t *>(src), 1.0F, 2 * num_items);
}
void convert_16i_8i(void *dest, const void *src, unsigned int num_items)
{
volk_16i_convert_8i(reinterpret_cast<int8_t *>(dest),
reinterpret_cast<const int16_t *>(src), num_items);
}
void convert_16i_32f(void *dest, const void *src, unsigned int num_items)
{
volk_16i_s32f_convert_32f(reinterpret_cast<float *>(dest),
reinterpret_cast<const int16_t *>(src), 1.0F, num_items);
}
void convert_16ic_8ic(void *dest, const void *src, unsigned int num_items)
{
volk_16i_convert_8i(reinterpret_cast<int8_t *>(dest),
reinterpret_cast<const int16_t *>(src), 2 * num_items);
}
void convert_16ic_32fc(void *dest, const void *src, unsigned int num_items)
{
volk_16i_s32f_convert_32f(reinterpret_cast<float *>(dest),
reinterpret_cast<const int16_t *>(src), 1.0F, 2 * num_items);
}
void convert_32f_8i(void *dest, const void *src, unsigned int num_items)
{
volk_32f_s32f_convert_8i(reinterpret_cast<int8_t *>(dest),
reinterpret_cast<const float *>(src), 1.0F, num_items);
}
void convert_32f_16i(void *dest, const void *src, unsigned int num_items)
{
volk_32f_s32f_convert_16i(reinterpret_cast<int16_t *>(dest),
reinterpret_cast<const float *>(src), 1.0F, num_items);
}
void convert_32fc_8ic(void *dest, const void *src, unsigned int num_items)
{
volk_32f_s32f_convert_8i(reinterpret_cast<int8_t *>(dest),
reinterpret_cast<const float *>(src), 1.0F, 2 * num_items);
}
void convert_32fc_16ic(void *dest, const void *src, unsigned int num_items)
{
volk_32f_s32f_convert_16i(reinterpret_cast<int16_t *>(dest),
reinterpret_cast<const float *>(src), 1.0F, 2 * num_items);
}
item_type_converter_t make_vector_converter(const std::string &input_type,
const std::string &output_type)
{
if (not item_type_valid(input_type) or not item_type_valid(output_type))
{
throw std::runtime_error("make_vector_converter: invalid item types : " + input_type + " " + output_type);
}
if (input_type == output_type)
{
size_t input_size = item_type_size(input_type);
#ifdef OLDCOMPILER
return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, input_size);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); };
#endif
}
if (input_type == "byte")
{
if (output_type == "short")
{
#ifdef OLDCOMPILER
return std::bind(convert_8i_16i, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_16i(arg1, arg2, arg3); };
#endif
}
else if (output_type == "float")
{
#ifdef OLDCOMPILER
return std::bind(convert_8i_32f, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_32f(arg1, arg2, arg3); };
#endif
}
}
else if (input_type == "cbyte")
{
if (output_type == "ibyte")
{
size_t input_size = item_type_size(input_type);
#ifdef OLDCOMPILER
return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, input_size);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); };
#endif
}
if (output_type == "cshort" or output_type == "ishort")
{
#ifdef OLDCOMPILER
return std::bind(convert_8ic_16ic, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8ic_16ic(arg1, arg2, arg3); };
#endif
}
else if (output_type == "gr_complex")
{
#ifdef OLDCOMPILER
return std::bind(convert_8ic_32fc, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8ic_32fc(arg1, arg2, arg3); };
#endif
}
}
else if (input_type == "ibyte")
{
if (output_type == "cbyte")
{
size_t input_size = item_type_size(input_type);
#ifdef OLDCOMPILER
return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, input_size);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); };
#endif
}
else if (output_type == "cshort" or output_type == "ishort")
{
#ifdef OLDCOMPILER
return std::bind(convert_8i_16i, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_16i(arg1, arg2, arg3); };
#endif
}
else if (output_type == "gr_complex")
{
#ifdef OLDCOMPILER
return std::bind(convert_8i_32f, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_32f(arg1, arg2, arg3); };
#endif
}
}
else if (input_type == "short")
{
if (output_type == "byte")
{
#ifdef OLDCOMPILER
return std::bind(convert_16i_8i, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_8i(arg1, arg2, arg3); };
#endif
}
else if (output_type == "float")
{
#ifdef OLDCOMPILER
return std::bind(convert_16i_32f, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_32f(arg1, arg2, arg3); };
#endif
}
}
else if (input_type == "cshort")
{
if (output_type == "cbyte" or output_type == "ibyte")
{
#ifdef OLDCOMPILER
return std::bind(convert_16ic_8ic, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16ic_8ic(arg1, arg2, arg3); };
#endif
}
if (output_type == "ishort")
{
size_t input_size = item_type_size(input_type);
#ifdef OLDCOMPILER
return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, input_size);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); };
#endif
}
else if (output_type == "gr_complex")
{
#ifdef OLDCOMPILER
return std::bind(convert_16ic_32fc, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16ic_32fc(arg1, arg2, arg3); };
#endif
}
}
else if (input_type == "ishort")
{
if (output_type == "cbyte" or output_type == "ibyte")
{
#ifdef OLDCOMPILER
return std::bind(convert_16i_8i, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_8i(arg1, arg2, arg3); };
#endif
}
if (output_type == "cshort")
{
size_t input_size = item_type_size(input_type);
#ifdef OLDCOMPILER
return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, input_size);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); };
#endif
}
else if (output_type == "gr_complex")
{
#ifdef OLDCOMPILER
return std::bind(convert_16i_32f, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_32f(arg1, arg2, arg3); };
#endif
}
}
else if (input_type == "float")
{
if (output_type == "byte")
{
#ifdef OLDCOMPILER
return std::bind(convert_32f_8i, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32f_8i(arg1, arg2, arg3); };
#endif
}
else if (output_type == "short")
{
#ifdef OLDCOMPILER
return std::bind(convert_32f_16i, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32f_16i(arg1, arg2, arg3); };
#endif
}
}
else if (input_type == "gr_complex")
{
if (output_type == "cbyte" or output_type == "ibyte")
{
#ifdef OLDCOMPILER
return std::bind(convert_32fc_8ic, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32fc_8ic(arg1, arg2, arg3); };
#endif
}
else if (output_type == "cshort" or output_type == "ishort")
{
#ifdef OLDCOMPILER
return std::bind(convert_32fc_16ic, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
#else
return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32fc_16ic(arg1, arg2, arg3); };
#endif
}
}
throw std::runtime_error("make_vector_converter: invalid conversion : " + input_type + " to " + output_type);
}

View File

@ -0,0 +1,88 @@
/*!
* \file item_type_helpers.h
* \brief Utility functions for converting between item types
* \authors <ul>
* <li> Cillian O'Driscoll, 2019. cillian.odriscoll(at)gmail.com
* </ul>
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_ITEM_TYPE_HELPERS_H_
#define GNSS_SDR_ITEM_TYPE_HELPERS_H_
#include <functional>
#include <string>
using item_type_converter_t = std::function<void(void *, const void *, unsigned)>;
/*!
* \brief Check if a string is a valid item type
*
* \description Valid item types include:
* "byte", "short", "float", "ibyte", "ishort", "cbyte", "cshort", "gr_complex"
*
*/
bool item_type_valid(const std::string &item_type);
/*!
* \brief Return the size of the given item type, or zero if unknown
*/
size_t item_type_size(const std::string &item_type);
/*!
* \brief Determine if an item_type is complex
*/
bool item_type_is_complex(const std::string &item_type);
/*!
* \brief Create a function to convert an array of input_type to an array of output_type
*
* \description Provides a generic interface to generate conversion functions for mapping
* arrays of items.
*
* \param input_type - String representation of the input item type
* \param output_type - String representation of the output item type
*
* The item types accepted are:
*
* 1. "byte" for 8 bit integers
* 2. "cbyte" for complex (interleaved) 8 bit integers
* 4. "ibyte" for complex (interleaved) 8 bit integers
* 4. "short" for 16 bit integers
* 5. "cshort" for complex (interleaved) 16 bit integers
* 6. "ishort" for complex (interleaved) 16 bit integers
* 7. "float" for 32 bit floating point values
* 8. "gr_complex" for complex (interleaved) 32 bit floating point values
*
* \returns A function object with the following prototype:
* void convert_fun( void *dest, void *src, int num_items );
*
*/
item_type_converter_t make_vector_converter(const std::string &input_type,
const std::string &output_type);
#endif

View File

@ -5722,7 +5722,7 @@ inline VECTOR_CLASS<char*> cl::Program::getInfo<CL_PROGRAM_BINARIES>(cl_int* err
{
VECTOR_CLASS< ::size_t> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>();
VECTOR_CLASS<char*> binaries;
for (unsigned long & size : sizes)
for (unsigned long& size : sizes)
{
char* ptr = nullptr;
if (size != 0)

View File

@ -47,48 +47,19 @@ if(MSVC)
endif()
endif()
find_package(Boost "1.35" COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
# This does not allow us to disable specific versions. It is used
# internally by cmake to know the formation newer versions. As newer
# Boost version beyond what is shown here are produced, we must extend
# this list. To disable Boost versions, see below.
# This does not allow us to disable specific versions. It is used internally by
# cmake to know the formation of newer versions. No need to increase, not used
# anymore since newer Boost provides its own CMake configuration files.
set(Boost_ADDITIONAL_VERSIONS
"1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39"
"1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
"1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
"1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54"
"1.53.0" "1.53" "1.54.0" "1.54"
"1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
"1.70.0" "1.70" "1.71.0" "1.71" "1.72.0" "1.72" "1.73.0" "1.73" "1.74.0" "1.74"
"1.75.0" "1.75" "1.76.0" "1.76" "1.77.0" "1.77" "1.78.0" "1.78" "1.79.0" "1.79"
"1.70.0" "1.70" "1.71.0" "1.71"
)
# Boost 1.52 disabled, see https://svn.boost.org/trac/boost/ticket/7669
# Similar problems with Boost 1.46 and 1.47.
option(ENABLE_BAD_BOOST "Enable known bad versions of Boost" OFF)
if(ENABLE_BAD_BOOST)
message(STATUS "Enabling use of known bad versions of Boost.")
endif()
set(Boost_NOGO_VERSIONS
"1.46.0" "1.46.1" "1.47.0" "1.52.0"
)
find_package(Boost "1.53" COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
if(CMAKE_VERSION VERSION_LESS 3.14)
set(Boost_VERSION_STRING "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
endif()
foreach(ver ${Boost_NOGO_VERSIONS})
if("${Boost_VERSION_STRING}" STREQUAL "${ver}")
if(NOT ENABLE_BAD_BOOST)
message(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION_STRING}). Disabling.")
set(Boost_FOUND FALSE)
else()
message(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION_STRING}). Continuing anyway.")
set(Boost_FOUND TRUE)
endif()
endif()
endforeach()

View File

@ -43,6 +43,7 @@ target_link_libraries(resampler_gr_blocks
PUBLIC
Gnuradio::runtime
Volk::volk
Boost::headers # Fix for homebrew
)
if(ENABLE_CLANG_TIDY)

View File

@ -196,10 +196,9 @@ int PositionSystemTest::configure_receiver()
const float threshold = 2.5;
const float doppler_max = 5000.0;
const float doppler_step = 250.0;
const float pfa = 0.0;
const float pfa_second_step = 0.0;
const int max_dwells = 10;
const int tong_init_val = 2;
const int tong_max_val = 10;
const int tong_max_dwells = 30;
const int coherent_integration_time_ms = 1;
const float pll_bw_hz = 35.0;
@ -279,13 +278,15 @@ int PositionSystemTest::configure_receiver()
config->set_property("Acquisition_1C.item_type", "gr_complex");
config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms));
config->set_property("Acquisition_1C.threshold", std::to_string(threshold));
config->set_property("Acquisition_1C.pfa", std::to_string(pfa));
config->set_property("Acquisition_1C.pfa_second_step", std::to_string(pfa_second_step));
config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max));
config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step));
config->set_property("Acquisition_1C.bit_transition_flag", "false");
config->set_property("Acquisition_1C.max_dwells", std::to_string(max_dwells));
config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val));
config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val));
config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells));
config->set_property("Acquisition_1C.make_two_steps", "false");
config->set_property("Acquisition_1C.second_nbins", "8");
config->set_property("Acquisition_1C.second_doppler_step", "125");
config->set_property("Acquisition_1C.dump", "false");
config->set_property("Acquisition_1C.dump_filename", "./acquisition");
config->set_property("Acquisition_1C.dump_channel", "1");

View File

@ -92,6 +92,7 @@ DECLARE_string(log_dir);
#include "unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc"
#include "unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc"
// #include "unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc"
#include "unit-tests/signal-processing-blocks/libs/item_type_helpers.cc"
#if OPENCL_BLOCKS_TEST
#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc"

View File

@ -249,7 +249,8 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::config_1()
std::to_string(integration_time_ms));
config->set_property("Acquisition_1B.max_dwells", "1");
config->set_property("Acquisition_1B.bit_transition_flag", "false");
config->set_property("Acquisition_1B.threshold", "0.1");
//config->set_property("Acquisition_1B.threshold", "0.1");
config->set_property("Acquisition_1B.pfa", "0.0001");
config->set_property("Acquisition_1B.doppler_max", "10000");
config->set_property("Acquisition_1B.doppler_step", "250");
config->set_property("Acquisition_1B.dump", "false");
@ -338,7 +339,7 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::config_2()
std::to_string(integration_time_ms));
config->set_property("Acquisition_1B.max_dwells", "1");
config->set_property("Acquisition_1B.bit_transition_flag", "false");
config->set_property("Acquisition_1B.pfa", "0.1");
config->set_property("Acquisition_1B.pfa", "0.0001");
config->set_property("Acquisition_1B.doppler_max", "10000");
config->set_property("Acquisition_1B.doppler_step", "250");
config->set_property("Acquisition_1B.dump", "false");
@ -487,10 +488,6 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResults)
acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500));
}) << "Failure setting doppler_step.";
ASSERT_NO_THROW({
acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0));
}) << "Failure setting threshold.";
ASSERT_NO_THROW({
acquisition->connect(top_block);
}) << "Failure connecting acquisition to the top_block.";
@ -519,7 +516,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResults)
}
else if (i == 1)
{
gnss_synchro.PRN = 20; // This satellite is not visible
gnss_synchro.PRN = 36; // This satellite is not visible
}
acquisition->set_local_code();
@ -572,10 +569,6 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProbabi
acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500));
}) << "Failure setting doppler_step.";
ASSERT_NO_THROW({
acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0));
}) << "Failure setting threshold.";
ASSERT_NO_THROW({
acquisition->connect(top_block);
}) << "Failure connecting acquisition to the top_block.";

View File

@ -166,7 +166,8 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoCTest::init()
config->set_property("Acquisition_1B.item_type", "gr_complex");
config->set_property("Acquisition_1B.coherent_integration_time_ms", "4");
config->set_property("Acquisition_1B.dump", "false");
config->set_property("Acquisition_1B.threshold", "0.1");
//config->set_property("Acquisition_1B.threshold", "0.1");
config->set_property("Acquisition_1B.pfa", "0.001");
config->set_property("Acquisition_1B.doppler_max", "10000");
config->set_property("Acquisition_1B.doppler_step", "125");
config->set_property("Acquisition_1B.repeat_satellite", "false");
@ -253,7 +254,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ValidationOfResults)
top_block = gr::make_top_block("Acquisition test");
init();
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 0);
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 0);
std::shared_ptr<GalileoE1PcpsAmbiguousAcquisition> acquisition = std::dynamic_pointer_cast<GalileoE1PcpsAmbiguousAcquisition>(acq_);
boost::shared_ptr<GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx> msg_rx = GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx_make(channel_internal_queue);

View File

@ -177,7 +177,8 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::init()
config->set_property("Acquisition_1B.dump", "false");
}
config->set_property("Acquisition_1B.dump_filename", "./tmp-acq-gal1/acquisition");
config->set_property("Acquisition_1B.threshold", "0.0001");
//config->set_property("Acquisition_1B.threshold", "0.0001");
config->set_property("Acquisition_1B.pfa", "0.001");
config->set_property("Acquisition_1B.doppler_max", std::to_string(doppler_max));
config->set_property("Acquisition_1B.doppler_step", std::to_string(doppler_step));
config->set_property("Acquisition_1B.repeat_satellite", "false");

View File

@ -254,7 +254,8 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_1()
std::to_string(integration_time_ms));
config->set_property("Acquisition.max_dwells", "1");
config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition");
config->set_property("Acquisition.threshold", "0.8");
//config->set_property("Acquisition.threshold", "0.8");
config->set_property("Acquisition.pfa", "0.001");
config->set_property("Acquisition.doppler_max", "10000");
config->set_property("Acquisition.doppler_step", "250");
config->set_property("Acquisition.bit_transition_flag", "false");
@ -343,7 +344,7 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_2()
std::to_string(integration_time_ms));
config->set_property("Acquisition.max_dwells", "1");
config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition");
// config->set_property("Acquisition.pfa", "0.1");
config->set_property("Acquisition.pfa", "0.001");
config->set_property("Acquisition.doppler_max", "10000");
config->set_property("Acquisition.doppler_step", "250");
config->set_property("Acquisition.bit_transition_flag", "false");
@ -497,9 +498,9 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults)
acquisition->set_doppler_step(500);
}) << "Failure setting doppler_step.";
ASSERT_NO_THROW({
acquisition->set_threshold(0.05);
}) << "Failure setting threshold.";
//ASSERT_NO_THROW({
//acquisition->set_threshold(0.05);
//}) << "Failure setting threshold.";
ASSERT_NO_THROW({
acquisition->connect(top_block);
@ -585,9 +586,9 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResultsProbabilities)
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500));
}) << "Failure setting doppler_step.";
ASSERT_NO_THROW({
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
}) << "Failure setting threshold.";
//ASSERT_NO_THROW({
//acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
//}) << "Failure setting threshold.";
ASSERT_NO_THROW({
acquisition->connect(top_block);

View File

@ -252,7 +252,8 @@ void GpsL1CaPcpsAcquisitionGSoC2013Test::config_1()
config->set_property("Acquisition_1C.coherent_integration_time_ms",
std::to_string(integration_time_ms));
config->set_property("Acquisition_1C.max_dwells", "1");
config->set_property("Acquisition_1C.threshold", "0.8");
//config->set_property("Acquisition_1C.threshold", "0.8");
config->set_property("Acquisition_1C.pfa", "0.001");
config->set_property("Acquisition_1C.doppler_max", "10000");
config->set_property("Acquisition_1C.doppler_step", "250");
config->set_property("Acquisition_1C.bit_transition_flag", "false");
@ -339,7 +340,7 @@ void GpsL1CaPcpsAcquisitionGSoC2013Test::config_2()
config->set_property("Acquisition_1C.coherent_integration_time_ms",
std::to_string(integration_time_ms));
config->set_property("Acquisition_1C.max_dwells", "1");
config->set_property("Acquisition_1C.pfa", "0.1");
config->set_property("Acquisition_1C.pfa", "0.001");
config->set_property("Acquisition_1C.doppler_max", "10000");
config->set_property("Acquisition_1C.doppler_step", "250");
config->set_property("Acquisition_1C.bit_transition_flag", "false");
@ -490,9 +491,9 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResults)
acquisition->set_doppler_step(500);
}) << "Failure setting doppler_step.";
ASSERT_NO_THROW({
acquisition->set_threshold(0.5);
}) << "Failure setting threshold.";
//ASSERT_NO_THROW({
//acquisition->set_threshold(0.5);
//}) << "Failure setting threshold.";
ASSERT_NO_THROW({
acquisition->connect(top_block);
@ -579,9 +580,9 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResultsProbabilities)
acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500));
}) << "Failure setting doppler_step.";
ASSERT_NO_THROW({
acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0));
}) << "Failure setting threshold.";
//ASSERT_NO_THROW({
//acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0));
//}) << "Failure setting threshold.";
ASSERT_NO_THROW({
acquisition->connect(top_block);

View File

@ -0,0 +1,259 @@
/*!
* \file item_type_helpers_test.cc
* \brief This file implements unit tests for the item_type_helpers
* custom block
* \author Cillian O'Driscoll, 2019. cillian.odriscoll (at) gmail.com
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "item_type_helpers.h"
#include <gtest/gtest.h>
#include <random>
class ItemTypeHelpersTest : public ::testing::Test
{
protected:
static constexpr size_t N = 1000;
public:
ItemTypeHelpersTest()
{
std::random_device r;
std::default_random_engine e(r());
std::uniform_int_distribution<int8_t> udist_int8(-100, 100);
std::uniform_int_distribution<int16_t> udist_int16(-100, 100);
std::uniform_real_distribution<float> udist_float(-100, 100);
std::generate(byte_array_in.begin(), byte_array_in.end(), [&udist_int8, &e]() { return udist_int8(e); });
std::generate(short_array_in.begin(), short_array_in.end(), [&udist_int16, &e]() { return udist_int16(e); });
std::generate(float_array_in.begin(), float_array_in.end(), [&udist_float, &e]() { return udist_float(e); });
}
std::vector<std::string> valid_item_types = {"byte", "ibyte", "cbyte",
"short", "ishort", "cshort", "float", "gr_complex"};
std::vector<std::string> invalid_item_types = {"i8", "tfgs", "cbite",
"shirt", "qshort", "csort", "flat", "igr_complex"};
std::array<int8_t, 2 * N> byte_array_in;
std::array<int8_t, 2 * N> byte_array_out;
std::array<int16_t, 2 * N> short_array_in;
std::array<int16_t, 2 * N> short_array_out;
std::array<float, 2 * N> float_array_in;
std::array<float, 2 * N> float_array_out;
};
TEST_F(ItemTypeHelpersTest, CheckValidTypes)
{
for (auto &valid_type : valid_item_types)
{
EXPECT_TRUE(item_type_valid(valid_type));
}
for (auto &invalid_type : invalid_item_types)
{
EXPECT_FALSE(item_type_valid(invalid_type));
}
}
TEST_F(ItemTypeHelpersTest, CheckSizes)
{
EXPECT_EQ(item_type_size("byte"), 1);
EXPECT_EQ(item_type_size("ibyte"), 1);
EXPECT_EQ(item_type_size("cbyte"), 2);
EXPECT_EQ(item_type_size("short"), 2);
EXPECT_EQ(item_type_size("ishort"), 2);
EXPECT_EQ(item_type_size("cshort"), 4);
EXPECT_EQ(item_type_size("float"), 4);
EXPECT_EQ(item_type_size("gr_complex"), 8);
for (auto &invalid_type : invalid_item_types)
{
EXPECT_EQ(item_type_size(invalid_type), 0);
}
}
TEST_F(ItemTypeHelpersTest, CheckMakeConverters)
{
for (auto &input_type : valid_item_types)
{
for (auto &output_type : valid_item_types)
{
item_type_converter_t converter = nullptr;
if (item_type_is_complex(input_type) == item_type_is_complex(output_type))
{
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
}
else
{
EXPECT_THROW(converter = make_vector_converter(input_type, output_type), std::runtime_error);
}
}
}
}
TEST_F(ItemTypeHelpersTest, CheckConversionsReal)
{
std::string input_type = "byte";
std::string output_type = "byte";
item_type_converter_t converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), byte_array_in.data(), N);
EXPECT_TRUE(std::equal(byte_array_in.begin(), byte_array_in.begin() + N, byte_array_out.begin()));
input_type = "byte";
output_type = "short";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), byte_array_in.data(), N);
converter = make_vector_converter(output_type, input_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), short_array_out.data(), N);
EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin()));
input_type = "byte";
output_type = "float";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(float_array_out.data(), byte_array_in.data(), N);
converter = make_vector_converter(output_type, input_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), float_array_out.data(), N);
EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin()));
input_type = "short";
output_type = "short";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), short_array_in.data(), N);
EXPECT_TRUE(std::equal(short_array_in.begin(), short_array_in.begin() + N, short_array_out.begin()));
input_type = "short";
output_type = "float";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(float_array_out.data(), short_array_in.data(), N);
converter = make_vector_converter(output_type, input_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), float_array_out.data(), N);
EXPECT_TRUE(std::equal(short_array_out.begin(), short_array_out.begin() + N, short_array_in.begin()));
input_type = "float";
output_type = "float";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(float_array_out.data(), float_array_in.data(), N);
EXPECT_TRUE(std::equal(float_array_in.begin(), float_array_in.begin() + N, float_array_out.begin()));
}
TEST_F(ItemTypeHelpersTest, CheckConversionsComplex)
{
std::string input_type = "cbyte";
std::string output_type = "cbyte";
item_type_converter_t converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), byte_array_in.data(), N);
EXPECT_TRUE(std::equal(byte_array_in.begin(), byte_array_in.begin() + N, byte_array_out.begin()));
input_type = "cbyte";
output_type = "ibyte";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), byte_array_in.data(), N);
EXPECT_TRUE(std::equal(byte_array_in.begin(), byte_array_in.begin() + N, byte_array_out.begin()));
input_type = "cbyte";
output_type = "cshort";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), byte_array_in.data(), N);
converter = make_vector_converter(output_type, input_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), short_array_out.data(), N);
EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin()));
input_type = "cbyte";
output_type = "ishort";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), byte_array_in.data(), N);
converter = make_vector_converter(output_type, input_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), short_array_out.data(), N);
EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin()));
input_type = "cbyte";
output_type = "gr_complex";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(float_array_out.data(), byte_array_in.data(), N);
converter = make_vector_converter(output_type, input_type);
EXPECT_NE(converter, nullptr);
converter(byte_array_out.data(), float_array_out.data(), N);
EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin()));
input_type = "cshort";
output_type = "cshort";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), short_array_in.data(), N);
EXPECT_TRUE(std::equal(short_array_in.begin(), short_array_in.begin() + N, short_array_out.begin()));
input_type = "cshort";
output_type = "ishort";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), short_array_in.data(), N);
EXPECT_TRUE(std::equal(short_array_in.begin(), short_array_in.begin() + N, short_array_out.begin()));
input_type = "cshort";
output_type = "gr_complex";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(float_array_out.data(), short_array_in.data(), N);
converter = make_vector_converter(output_type, input_type);
EXPECT_NE(converter, nullptr);
converter(short_array_out.data(), float_array_out.data(), N);
EXPECT_TRUE(std::equal(short_array_out.begin(), short_array_out.begin() + N, short_array_in.begin()));
input_type = "gr_complex";
output_type = "gr_complex";
converter = make_vector_converter(input_type, output_type);
EXPECT_NE(converter, nullptr);
converter(float_array_out.data(), float_array_in.data(), N);
EXPECT_TRUE(std::equal(float_array_in.begin(), float_array_in.begin() + N, float_array_out.begin()));
}