Merge branch 'MathieuFavreau-refactor/last-acquisition-classes-cleanup' into next

This commit is contained in:
Carles Fernandez
2025-11-13 17:53:30 +01:00
17 changed files with 251 additions and 1416 deletions
@@ -32,7 +32,13 @@ namespace
{
const std::string default_dump_filename("./acquisition.dat");
Acq_Conf get_acq_conf(const ConfigurationInterface* configuration, const std::string& role, double chip_rate, double opt_freq, uint32_t ms_per_code)
Acq_Conf get_acq_conf(
const ConfigurationInterface* configuration,
const std::string& role,
double chip_rate,
double opt_freq,
uint32_t ms_per_code,
uint32_t max_sampled_ms)
{
Acq_Conf acq_parameters;
acq_parameters.ms_per_code = ms_per_code;
@@ -60,6 +66,13 @@ Acq_Conf get_acq_conf(const ConfigurationInterface* configuration, const std::st
}
#endif
if (acq_parameters.sampled_ms > max_sampled_ms)
{
acq_parameters.sampled_ms = max_sampled_ms;
DLOG(INFO) << "Coherent integration time should be " << max_sampled_ms << " ms or less. Changing to " << max_sampled_ms << "ms ";
std::cout << "Too high coherent integration time. Changing to " << max_sampled_ms << "ms\n";
}
return acq_parameters;
}
} // namespace
@@ -74,8 +87,9 @@ BasePcpsAcquisitionCustom::BasePcpsAcquisitionCustom(
double code_length_chips,
unsigned int ms_per_code,
bool use_stream_to_vector,
bool compute_threshold_from_pfa)
: acq_parameters_(get_acq_conf(configuration, role, chip_rate, 0, ms_per_code)),
bool compute_threshold_from_pfa,
uint32_t max_sampled_ms)
: acq_parameters_(get_acq_conf(configuration, role, chip_rate, 0, ms_per_code, max_sampled_ms)),
num_codes_(acq_parameters_.sampled_ms / ms_per_code),
code_length_(static_cast<unsigned int>(round(acq_parameters_.fs_in / (chip_rate / code_length_chips)))),
vector_length_(code_length_ * num_codes_),
@@ -25,6 +25,7 @@
#include "pcps_acquisition.h"
#include <gnuradio/blocks/stream_to_vector.h>
#include <volk_gnsssdr/volk_gnsssdr_alloc.h>
#include <limits>
/** \addtogroup Acquisition
* Classes for GNSS signal acquisition
@@ -50,7 +51,8 @@ public:
double code_length_chips,
unsigned int ms_per_code,
bool use_stream_to_vector,
bool compute_threshold_from_pfa);
bool compute_threshold_from_pfa,
uint32_t max_sampled_ms = std::numeric_limits<uint32_t>::max());
~BasePcpsAcquisitionCustom() = default;
@@ -128,16 +130,16 @@ protected:
acquisition_impl_interface_sptr acquisition_cc_;
Gnss_Synchro* gnss_synchro_;
unsigned int channel_;
volk_gnsssdr::vector<std::complex<float>> code_;
private:
float calculate_threshold(float pfa) const;
virtual float calculate_threshold(float pfa) const;
/*!
* \brief Generate code
*/
virtual void code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq) = 0;
volk_gnsssdr::vector<std::complex<float>> code_;
gr::blocks::stream_to_vector::sptr stream_to_vector_;
const std::string role_;
const bool is_type_gr_complex_;
@@ -19,7 +19,7 @@
#include "Galileo_E1.h"
#include "configuration_interface.h"
#include "galileo_e1_signal_replica.h"
#include "gnss_sdr_flags.h"
#include "pcps_cccwsr_acquisition_cc.h"
#include <boost/math/distributions/exponential.hpp>
#if USE_GLOG_AND_GFLAGS
@@ -33,208 +33,44 @@ GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition
const std::string& role,
unsigned int in_streams,
unsigned int out_streams)
: configuration_(configuration),
role_(role),
gnss_synchro_(nullptr),
item_size_(sizeof(gr_complex)),
threshold_(0.0),
channel_(0),
doppler_max_(configuration_->property(role + ".doppler_max", 5000)),
doppler_step_(configuration_->property(role + ".doppler_step", 500)),
sampled_ms_(configuration_->property(role + ".coherent_integration_time_ms", 4)),
dump_(configuration_->property(role + ".dump", false)),
cboc_(configuration_->property(role + ".cboc", false))
: BasePcpsAcquisitionCustom(
configuration,
role,
in_streams,
out_streams,
GALILEO_E1_CODE_CHIP_RATE_CPS,
GALILEO_E1_B_CODE_LENGTH_CHIPS,
GALILEO_E1_CODE_PERIOD_MS,
true,
false),
code_pilot_(vector_length_),
cboc_(configuration->property(role + ".cboc", false))
{
const std::string default_item_type("gr_complex");
const std::string default_dump_filename("./acquisition.dat");
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);
dump_filename_ = configuration_->property(role_ + ".dump_filename", default_dump_filename);
#if USE_GLOG_AND_GFLAGS
if (FLAGS_doppler_max != 0)
if (is_type_gr_complex())
{
doppler_max_ = FLAGS_doppler_max;
const auto samples_per_ms = static_cast<int>(code_length_) / 4;
acquisition_cc_ = pcps_cccwsr_make_acquisition_cc(acq_parameters_.sampled_ms, acq_parameters_.max_dwells,
acq_parameters_.doppler_max, acq_parameters_.doppler_step, acq_parameters_.fs_in, samples_per_ms, code_length_,
acq_parameters_.dump, acq_parameters_.dump_filename, acq_parameters_.enable_monitor_output);
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")";
}
if (FLAGS_doppler_step != 0)
{
doppler_step_ = static_cast<uint32_t>(FLAGS_doppler_step);
}
#else
if (absl::GetFlag(FLAGS_doppler_max) != 0)
{
doppler_max_ = absl::GetFlag(FLAGS_doppler_max);
}
if (absl::GetFlag(FLAGS_doppler_step) != 0)
{
doppler_step_ = static_cast<uint32_t>(absl::GetFlag(FLAGS_doppler_step));
}
#endif
if (sampled_ms_ % 4 != 0)
{
sampled_ms_ = static_cast<int>(sampled_ms_ / 4) * 4;
LOG(WARNING) << "coherent_integration_time should be multiple of "
<< "Galileo code length (4 ms). coherent_integration_time = "
<< sampled_ms_ << " ms will be used.";
}
// -- Find number of samples per spreading code (4 ms) -----------------
code_length_ = static_cast<unsigned int>(round(
fs_in_ / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * static_cast<int>(sampled_ms_ / 4);
auto samples_per_ms = static_cast<int>(code_length_) / 4;
code_data_ = std::vector<std::complex<float>>(vector_length_);
code_pilot_ = std::vector<std::complex<float>>(vector_length_);
bool enable_monitor_output = configuration_->property("AcquisitionMonitor.enable_monitor", false);
DLOG(INFO) << "role " << role_;
if (item_type_ == "gr_complex")
{
unsigned int max_dwells = configuration_->property(role + ".max_dwells", 1);
acquisition_cc_ = pcps_cccwsr_make_acquisition_cc(sampled_ms_, max_dwells,
doppler_max_, doppler_step_, fs_in_, samples_per_ms, code_length_,
dump_, dump_filename_, enable_monitor_output);
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
DLOG(INFO) << "stream_to_vector("
<< stream_to_vector_->unique_id() << ")";
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id()
<< ")";
}
else
{
item_size_ = 0;
acquisition_cc_ = nullptr;
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
if (in_streams > 1)
{
LOG(ERROR) << "This implementation only supports one input stream";
}
if (out_streams > 0)
{
LOG(ERROR) << "This implementation does not provide an output stream";
}
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_threshold(float threshold)
{
threshold_ = threshold;
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_threshold(threshold_);
}
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_gnss_synchro(
Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
}
}
signed int GalileoE1PcpsCccwsrAmbiguousAcquisition::mag()
{
if (item_type_ == "gr_complex")
{
return acquisition_cc_->mag();
}
return 0;
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::init()
{
acquisition_cc_->init();
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_local_code()
{
if (item_type_ == "gr_complex")
if (is_type_gr_complex())
{
auto& code_data_ = code_;
std::array<char, 3> signal = {{'1', 'B', '\0'}};
galileo_e1_code_gen_complex_sampled(code_data_, signal, cboc_, gnss_synchro_->PRN, fs_in_, 0, false);
galileo_e1_code_gen_complex_sampled(code_data_, signal, cboc_, gnss_synchro_->PRN, acq_parameters_.fs_in, 0, false);
std::array<char, 3> signal_C = {{'1', 'C', '\0'}};
galileo_e1_code_gen_complex_sampled(code_pilot_, signal_C, cboc_, gnss_synchro_->PRN, fs_in_, 0, false);
galileo_e1_code_gen_complex_sampled(code_pilot_, signal_C, cboc_, gnss_synchro_->PRN, acq_parameters_.fs_in, 0, false);
acquisition_cc_->set_local_code(code_data_.data(), code_pilot_.data());
}
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::reset()
{
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_active(true);
}
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_state(int state)
{
acquisition_cc_->set_state(state);
}
float GalileoE1PcpsCccwsrAmbiguousAcquisition::calculate_threshold(float pfa)
{
if (pfa > 0.0)
{ /* Not implemented*/
};
return 0.0;
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
{
top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
}
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::disconnect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
{
top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
}
}
gr::basic_block_sptr GalileoE1PcpsCccwsrAmbiguousAcquisition::get_left_block()
{
return stream_to_vector_;
}
gr::basic_block_sptr GalileoE1PcpsCccwsrAmbiguousAcquisition::get_right_block()
{
return acquisition_cc_;
}
@@ -18,28 +18,18 @@
#ifndef GNSS_SDR_GALILEO_E1_PCPS_CCCWSR_AMBIGUOUS_ACQUISITION_H
#define GNSS_SDR_GALILEO_E1_PCPS_CCCWSR_AMBIGUOUS_ACQUISITION_H
#include "channel_fsm.h"
#include "gnss_synchro.h"
#include "pcps_cccwsr_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base_pcps_acquisition_custom.h"
/** \addtogroup Acquisition
* \{ */
/** \addtogroup Acq_adapters
* \{ */
class ConfigurationInterface;
/*!
* \brief Adapts a PCPS CCCWSR acquisition block to an AcquisitionInterface
* for Galileo E1 Signals
*/
class GalileoE1PcpsCccwsrAmbiguousAcquisition : public AcquisitionInterface
class GalileoE1PcpsCccwsrAmbiguousAcquisition : public BasePcpsAcquisitionCustom
{
public:
GalileoE1PcpsCccwsrAmbiguousAcquisition(
@@ -50,11 +40,6 @@ public:
~GalileoE1PcpsCccwsrAmbiguousAcquisition() = default;
inline std::string role() override
{
return role_;
}
/*!
* \brief Returns "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition"
*/
@@ -63,98 +48,13 @@ public:
return "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition";
}
inline size_t item_size() override
{
return item_size_;
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Set acquisition channel unique ID
*/
inline void set_channel(unsigned int channel) override
{
channel_ = channel;
acquisition_cc_->set_channel(channel_);
}
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{
channel_fsm_ = std::move(channel_fsm);
acquisition_cc_->set_channel_fsm(channel_fsm_);
}
/*!
* \brief Set statistics threshold of CCCWSR algorithm
*/
void set_threshold(float threshold) override;
/*!
* \brief Initializes acquisition algorithm.
*/
void init() override;
void set_local_code() override;
/*!
* \brief Returns the maximum peak of grid search
*/
signed int mag() override;
/*!
* \brief Restart acquisition algorithm
*/
void reset() override;
/*!
* \brief If state = 1, it forces the block to start acquiring from the first sample
*/
void set_state(int state) override;
/*!
* \brief Stop running acquisition
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {};
private:
float calculate_threshold(float pfa);
// We don't implement this function since we override set_local_code
void code_gen_complex_sampled(own::span<std::complex<float>> /*dest*/, uint32_t /*prn*/, int32_t /*sampling_freq*/) override {}
const ConfigurationInterface* configuration_;
pcps_cccwsr_acquisition_cc_sptr acquisition_cc_;
gr::blocks::stream_to_vector::sptr stream_to_vector_;
std::weak_ptr<ChannelFsm> channel_fsm_;
std::vector<std::complex<float>> code_data_;
std::vector<std::complex<float>> code_pilot_;
std::string item_type_;
std::string dump_filename_;
std::string role_;
Gnss_Synchro* gnss_synchro_;
int64_t fs_in_;
size_t item_size_;
float threshold_;
unsigned int vector_length_;
unsigned int code_length_;
unsigned int channel_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
bool dump_;
const bool cboc_;
};
@@ -19,9 +19,8 @@
#include "Galileo_E1.h"
#include "configuration_interface.h"
#include "galileo_e1_signal_replica.h"
#include "gnss_sdr_flags.h"
#include "pcps_quicksync_acquisition_cc.h"
#include <boost/math/distributions/exponential.hpp>
#include <algorithm>
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
@@ -29,252 +28,69 @@
#include <absl/log/log.h>
#endif
#if HAS_STD_SPAN
#include <span>
namespace own = std;
#else
#include <gsl-lite/gsl-lite.hpp>
namespace own = gsl_lite;
#endif
namespace
{
uint32_t get_folding_factor(const ConfigurationInterface* configuration, const std::string& role)
{
/* Calculate the folding factor value based on the formula described in the paper.
This may be a bug, but acquisition also work by variying the folding factor at va-
lues different that the expressed in the paper. In addition, it is important to point
out that by making the folding factor smaller we were able to get QuickSync work with
Galileo. Future work should be directed to test this assumption statistically. */
// return static_cast<unsigned int>(ceil(sqrt(log2(code_length_))));
return configuration->property(role + ".folding_factor", 2);
}
} // namespace
GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcquisition(
const ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams)
: configuration_(configuration),
role_(role),
gnss_synchro_(nullptr),
item_size_(sizeof(gr_complex)),
threshold_(0.0),
channel_(0),
doppler_max_(configuration_->property(role + ".doppler_max", 5000)),
doppler_step_(configuration_->property(role + ".doppler_step", 500)),
sampled_ms_(configuration_->property(role + ".coherent_integration_time_ms", 8)),
bit_transition_flag_(configuration_->property(role + ".bit_transition_flag", false)),
dump_(configuration_->property(role + ".dump", false)),
cboc_(configuration_->property(role + ".cboc", false))
: BasePcpsAcquisitionCustom(
configuration,
role,
in_streams,
out_streams,
GALILEO_E1_CODE_CHIP_RATE_CPS,
GALILEO_E1_B_CODE_LENGTH_CHIPS,
GALILEO_E1_CODE_PERIOD_MS * get_folding_factor(configuration, role),
true,
true),
folding_factor_(get_folding_factor(configuration, role)),
cboc_(configuration->property(role + ".cboc", false))
{
const std::string default_item_type("gr_complex");
const std::string default_dump_filename("./acquisition.dat");
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);
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
#if USE_GLOG_AND_GFLAGS
if (FLAGS_doppler_max != 0)
if (is_type_gr_complex())
{
doppler_max_ = FLAGS_doppler_max;
}
if (FLAGS_doppler_step != 0)
{
doppler_step_ = static_cast<uint32_t>(FLAGS_doppler_step);
}
#else
if (absl::GetFlag(FLAGS_doppler_max) != 0)
{
doppler_max_ = absl::GetFlag(FLAGS_doppler_max);
}
if (absl::GetFlag(FLAGS_doppler_step) != 0)
{
doppler_step_ = static_cast<uint32_t>(absl::GetFlag(FLAGS_doppler_step));
}
#endif
// const auto samples_per_ms = static_cast<int>(round(code_length_ / acq_parameters_.sampled_ms));
const unsigned int max_dwells = acq_parameters_.bit_transition_flag ? 2 : acq_parameters_.max_dwells;
/* --- Find number of samples per spreading code (4 ms) -----------------*/
code_length_ = static_cast<unsigned int>(round(
fs_in_ / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS)));
auto samples_per_ms = static_cast<int>(round(code_length_ / 4.0));
DLOG(INFO) << "role " << role;
/*Calculate the folding factor value based on the formula described in the paper.
This may be a bug, but acquisition also work by variying the folding factor at va-
lues different that the expressed in the paper. In addition, it is important to point
out that by making the folding factor smaller we were able to get QuickSync work with
Galileo. Future work should be directed to test this assumption statistically.*/
// folding_factor_ = static_cast<unsigned int>(ceil(sqrt(log2(code_length_))));
folding_factor_ = configuration_->property(role + ".folding_factor", 2);
if (sampled_ms_ % (folding_factor_ * 4) != 0)
{
LOG(WARNING) << "QuickSync Algorithm requires a coherent_integration_time"
<< " multiple of " << (folding_factor_ * 4) << "ms, Value entered "
<< sampled_ms_ << " ms";
if (sampled_ms_ < (folding_factor_ * 4))
{
sampled_ms_ = static_cast<int>(folding_factor_ * 4);
}
else
{
sampled_ms_ = static_cast<int>(sampled_ms_ / (folding_factor_ * 4)) * (folding_factor_ * 4);
}
LOG(WARNING) << "coherent_integration_time should be multiple of "
<< "Galileo code length (4 ms). coherent_integration_time = "
<< sampled_ms_ << " ms will be used.";
}
// vector_length_ = (sampled_ms_/folding_factor_) * code_length_;
vector_length_ = sampled_ms_ * samples_per_ms;
// 8/2 * code_length_
// 8 * code_length_ / 4
unsigned int max_dwells = 2;
if (!bit_transition_flag_)
{
max_dwells = configuration_->property(role + ".max_dwells", 1);
}
bool enable_monitor_output = configuration_->property("AcquisitionMonitor.enable_monitor", false);
code_ = std::vector<std::complex<float>>(code_length_);
LOG(INFO) << "Vector Length: " << vector_length_
<< ", Samples per ms: " << samples_per_ms
<< ", Folding factor: " << folding_factor_
<< ", Sampled ms: " << sampled_ms_
<< ", Code Length: " << code_length_;
if (item_type_ == "gr_complex")
{
acquisition_cc_ = pcps_quicksync_make_acquisition_cc(folding_factor_,
sampled_ms_, max_dwells, doppler_max_, doppler_step_, fs_in_,
samples_per_ms, code_length_, bit_transition_flag_,
dump_, dump_filename_, enable_monitor_output);
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_,
vector_length_);
DLOG(INFO) << "stream_to_vector_quicksync("
<< stream_to_vector_->unique_id() << ")";
DLOG(INFO) << "acquisition_quicksync(" << acquisition_cc_->unique_id()
<< ")";
}
else
{
acquisition_cc_ = nullptr;
item_size_ = 0;
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
vector_length_, max_dwells, acq_parameters_.doppler_max, acq_parameters_.doppler_step,
acq_parameters_.fs_in, code_length_, acq_parameters_.bit_transition_flag,
acq_parameters_.dump, acq_parameters_.dump_filename, acq_parameters_.enable_monitor_output);
if (in_streams > 1)
{
LOG(ERROR) << "This implementation only supports one input stream";
}
if (out_streams > 0)
{
LOG(ERROR) << "This implementation does not provide an output stream";
DLOG(INFO) << "acquisition_quicksync(" << acquisition_cc_->unique_id() << ")";
}
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition()
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq)
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}
std::array<char, 3> Signal_{};
Signal_[0] = gnss_synchro_->Signal[0];
Signal_[1] = gnss_synchro_->Signal[1];
Signal_[2] = '\0';
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", static_cast<float>(0.0));
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", static_cast<float>(0.0));
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_threshold(threshold_);
}
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_gnss_synchro(
Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
}
}
signed int
GalileoE1PcpsQuickSyncAmbiguousAcquisition::mag()
{
if (item_type_ == "gr_complex")
{
return acquisition_cc_->mag();
}
return 0;
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::init()
{
acquisition_cc_->init();
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_local_code()
{
if (item_type_ == "gr_complex")
{
std::vector<std::complex<float>> code(code_length_);
std::array<char, 3> Signal_{};
Signal_[0] = gnss_synchro_->Signal[0];
Signal_[1] = gnss_synchro_->Signal[1];
Signal_[2] = '\0';
galileo_e1_code_gen_complex_sampled(code, Signal_, cboc_, gnss_synchro_->PRN, fs_in_, 0, false);
own::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < (sampled_ms_ / (folding_factor_ * 4)); i++)
{
std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
}
acquisition_cc_->set_local_code(code_.data());
}
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::reset()
{
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_active(true);
}
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_state(int state)
{
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_state(state);
}
galileo_e1_code_gen_complex_sampled(dest, Signal_, cboc_, prn, sampling_freq, 0, false);
}
float GalileoE1PcpsQuickSyncAmbiguousAcquisition::calculate_threshold(float pfa) const
{
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += static_cast<int>(doppler_step_))
for (int doppler = -acq_parameters_.doppler_max; doppler <= acq_parameters_.doppler_max; doppler += static_cast<int>(acq_parameters_.doppler_step))
{
frequency_bins++;
}
@@ -290,33 +106,3 @@ float GalileoE1PcpsQuickSyncAmbiguousAcquisition::calculate_threshold(float pfa)
return threshold;
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
{
top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
}
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::disconnect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
{
top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
}
}
gr::basic_block_sptr GalileoE1PcpsQuickSyncAmbiguousAcquisition::get_left_block()
{
return stream_to_vector_;
}
gr::basic_block_sptr GalileoE1PcpsQuickSyncAmbiguousAcquisition::get_right_block()
{
return acquisition_cc_;
}
@@ -18,28 +18,18 @@
#ifndef GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H
#define GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H
#include "channel_fsm.h"
#include "gnss_synchro.h"
#include "pcps_quicksync_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base_pcps_acquisition_custom.h"
/** \addtogroup Acquisition
* \{ */
/** \addtogroup Acq_adapters
* \{ */
class ConfigurationInterface;
/*!
* \brief This class adapts a PCPS acquisition block to an
* AcquisitionInterface for Galileo E1 Signals
*/
class GalileoE1PcpsQuickSyncAmbiguousAcquisition : public AcquisitionInterface
class GalileoE1PcpsQuickSyncAmbiguousAcquisition : public BasePcpsAcquisitionCustom
{
public:
GalileoE1PcpsQuickSyncAmbiguousAcquisition(
@@ -50,11 +40,6 @@ public:
~GalileoE1PcpsQuickSyncAmbiguousAcquisition() = default;
inline std::string role() override
{
return role_;
}
/*!
* \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition"
*/
@@ -63,102 +48,11 @@ public:
return "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition";
}
inline size_t item_size() override
{
return item_size_;
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Set acquisition channel unique ID
*/
inline void set_channel(unsigned int channel) override
{
channel_ = channel;
acquisition_cc_->set_channel(channel_);
}
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{
channel_fsm_ = std::move(channel_fsm);
acquisition_cc_->set_channel_fsm(channel_fsm_);
}
/*!
* \brief Set statistics threshold of PCPS algorithm
*/
void set_threshold(float threshold) override;
/*!
* \brief Initializes acquisition algorithm.
*/
void init() override;
/*!
* \brief Sets local code for Galileo E1 PCPS acquisition algorithm.
*/
void set_local_code() override;
/*!
* \brief Returns the maximum peak of grid search
*/
signed int mag() override;
/*!
* \brief Restart acquisition algorithm
*/
void reset() override;
/*!
* \brief If state = 1, it forces the block to start acquiring from the first sample
*/
void set_state(int state) override;
/*!
* \brief Stop running acquisition
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {};
private:
float calculate_threshold(float pfa) const;
float calculate_threshold(float pfa) const override;
void code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq) override;
const ConfigurationInterface* configuration_;
pcps_quicksync_acquisition_cc_sptr acquisition_cc_;
gr::blocks::stream_to_vector::sptr stream_to_vector_;
std::weak_ptr<ChannelFsm> channel_fsm_;
std::vector<std::complex<float>> code_;
std::string item_type_;
std::string role_;
std::string dump_filename_;
Gnss_Synchro* gnss_synchro_;
int64_t fs_in_;
size_t item_size_;
float threshold_;
unsigned int vector_length_;
unsigned int code_length_;
unsigned int channel_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int folding_factor_;
bool bit_transition_flag_;
bool dump_;
const unsigned int folding_factor_;
const bool cboc_;
};
@@ -25,7 +25,7 @@
#include "Galileo_E5a.h"
#include "configuration_interface.h"
#include "galileo_e5_signal_replica.h"
#include "gnss_sdr_flags.h"
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
#include <boost/math/distributions/exponential.hpp>
#include <algorithm>
@@ -43,198 +43,88 @@ namespace own = std;
namespace own = gsl_lite;
#endif
namespace
{
int get_zero_padding(const ConfigurationInterface* configuration, const std::string& role)
{
return configuration->property(role + ".Zero_padding", 0);
}
uint32_t get_max_sampled_ms(const ConfigurationInterface* configuration, const std::string& role)
{
const auto zero_padding = get_zero_padding(configuration, role);
if (zero_padding > 0)
{
DLOG(INFO) << "Zero padding activated. Changing to 1ms code + 1ms zero padding ";
std::cout << "Zero padding activated. Changing to 1ms code + 1ms zero padding\n";
return 2;
}
return 3;
}
} // namespace
GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
const ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams)
: configuration_(configuration),
role_(role),
gnss_synchro_(nullptr),
item_size_(sizeof(gr_complex)),
threshold_(0.0),
Zero_padding(configuration_->property(role + ".Zero_padding", 0)),
CAF_window_hz_(configuration_->property(role + ".CAF_window_hz", 0)),
channel_(0),
doppler_max_(configuration_->property(role + ".doppler_max", 5000)),
doppler_step_(configuration_->property(role + ".doppler_step", 500)),
sampled_ms_(configuration_->property(role + ".coherent_integration_time_ms", 1)),
bit_transition_flag_(configuration_->property(role + ".bit_transition_flag", false)),
dump_(configuration_->property(role + ".dump", false))
: BasePcpsAcquisitionCustom(
configuration,
role,
in_streams,
out_streams,
GALILEO_E5A_CODE_CHIP_RATE_CPS,
GALILEO_E5A_CODE_LENGTH_CHIPS,
GALILEO_E5A_CODE_PERIOD_MS,
false,
true,
get_max_sampled_ms(configuration, role)),
zero_padding_(get_zero_padding(configuration, role)),
caf_window_hz_(configuration->property(role + ".CAF_window_hz", 0)),
codeQ_(vector_length_)
{
const std::string default_item_type("gr_complex");
const std::string default_dump_filename("./acquisition.dat");
item_type_ = configuration_->property(role_ + ".item_type", default_item_type);
dump_filename_ = configuration_->property(role_ + ".dump_filename", default_dump_filename);
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);
#if USE_GLOG_AND_GFLAGS
if (FLAGS_doppler_max != 0)
if (is_type_gr_complex())
{
doppler_max_ = FLAGS_doppler_max;
const auto sig = configuration->property("Channel.signal", std::string("5X"));
const auto both_signal_components = (sig.at(0) == '5' && sig.at(1) == 'X');
acquisition_cc_ = galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(acq_parameters_.sampled_ms, acq_parameters_.max_dwells,
acq_parameters_.doppler_max, acq_parameters_.doppler_step, acq_parameters_.fs_in, code_length_, code_length_, acq_parameters_.bit_transition_flag,
acq_parameters_.dump, acq_parameters_.dump_filename, both_signal_components, caf_window_hz_, zero_padding_, acq_parameters_.enable_monitor_output);
}
if (FLAGS_doppler_step != 0)
{
doppler_step_ = static_cast<uint32_t>(FLAGS_doppler_step);
}
#else
if (absl::GetFlag(FLAGS_doppler_max) != 0)
{
doppler_max_ = absl::GetFlag(FLAGS_doppler_max);
}
if (absl::GetFlag(FLAGS_doppler_step) != 0)
{
doppler_step_ = static_cast<uint32_t>(absl::GetFlag(FLAGS_doppler_step));
}
#endif
DLOG(INFO) << "role " << role_;
if (sampled_ms_ > 3)
{
sampled_ms_ = 3;
DLOG(INFO) << "Coherent integration time should be 3 ms or less. Changing to 3ms ";
std::cout << "Too high coherent integration time. Changing to 3ms\n";
}
if (Zero_padding > 0)
{
sampled_ms_ = 2;
DLOG(INFO) << "Zero padding activated. Changing to 1ms code + 1ms zero padding ";
std::cout << "Zero padding activated. Changing to 1ms code + 1ms zero padding\n";
}
// -- Find number of samples per spreading code (1ms)-------------------------
code_length_ = static_cast<int>(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_;
codeI_ = std::vector<std::complex<float>>(vector_length_);
codeQ_ = std::vector<std::complex<float>>(vector_length_);
both_signal_components = false;
bool enable_monitor_output = configuration->property("AcquisitionMonitor.enable_monitor", false);
std::string sig_ = configuration_->property("Channel.signal", std::string("5X"));
if (sig_.at(0) == '5' && sig_.at(1) == 'X')
{
both_signal_components = true;
}
if (item_type_ == "gr_complex")
{
unsigned int max_dwells = configuration_->property(role + ".max_dwells", 1);
acquisition_cc_ = galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(sampled_ms_, max_dwells,
doppler_max_, doppler_step_, fs_in_, code_length_, code_length_, bit_transition_flag_,
dump_, dump_filename_, both_signal_components, CAF_window_hz_, Zero_padding, enable_monitor_output);
}
else
{
item_size_ = 0;
acquisition_cc_ = nullptr;
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
if (in_streams > 1)
{
LOG(ERROR) << "This implementation only supports one input stream";
}
if (out_streams > 0)
{
LOG(ERROR) << "This implementation does not provide an output stream";
}
}
void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition()
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}
void GalileoE5aNoncoherentIQAcquisitionCaf::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", static_cast<float>(0.0));
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", static_cast<float>(0.0));
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_threshold(threshold_);
}
}
void GalileoE5aNoncoherentIQAcquisitionCaf::set_gnss_synchro(
Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
}
}
signed int GalileoE5aNoncoherentIQAcquisitionCaf::mag()
{
if (item_type_ == "gr_complex")
{
return static_cast<signed int>(acquisition_cc_->mag());
}
return 0;
}
void GalileoE5aNoncoherentIQAcquisitionCaf::init()
{
acquisition_cc_->init();
}
void GalileoE5aNoncoherentIQAcquisitionCaf::set_local_code()
{
if (item_type_ == "gr_complex")
if (is_type_gr_complex())
{
auto& codeI_ = code_;
std::vector<std::complex<float>> codeI(code_length_);
std::vector<std::complex<float>> codeQ(code_length_);
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
{
std::array<char, 3> a = {{'5', 'I', '\0'}};
galileo_e5_a_code_gen_complex_sampled(codeI,
gnss_synchro_->PRN, a, fs_in_, 0);
galileo_e5_a_code_gen_complex_sampled(codeI, gnss_synchro_->PRN, a, acq_parameters_.fs_in, 0);
std::array<char, 3> b = {{'5', 'Q', '\0'}};
galileo_e5_a_code_gen_complex_sampled(codeQ,
gnss_synchro_->PRN, b, fs_in_, 0);
galileo_e5_a_code_gen_complex_sampled(codeQ, gnss_synchro_->PRN, b, acq_parameters_.fs_in, 0);
}
else
{
std::array<char, 3> signal_type_ = {{'5', 'X', '\0'}};
galileo_e5_a_code_gen_complex_sampled(codeI,
gnss_synchro_->PRN, signal_type_, fs_in_, 0);
galileo_e5_a_code_gen_complex_sampled(codeI, gnss_synchro_->PRN, signal_type_, acq_parameters_.fs_in, 0);
}
// WARNING: 3ms are coherently integrated. Secondary sequence (1,1,1)
// is generated, and modulated in the 'block'.
own::span<gr_complex> codeQ_span(codeQ_.data(), vector_length_);
own::span<gr_complex> codeI_span(codeI_.data(), vector_length_);
if (Zero_padding == 0) // if no zero_padding
own::span<gr_complex> codeQ_span(codeQ_.data(), vector_length_);
if (zero_padding_ == 0) // if no zero_padding
{
for (unsigned int i = 0; i < sampled_ms_; i++)
for (unsigned int i = 0; i < acq_parameters_.sampled_ms; i++)
{
std::copy_n(codeI.data(), code_length_, codeI_span.subspan(i * code_length_, code_length_).data());
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
@@ -256,68 +146,3 @@ void GalileoE5aNoncoherentIQAcquisitionCaf::set_local_code()
acquisition_cc_->set_local_code(codeI_.data(), codeQ_.data());
}
}
void GalileoE5aNoncoherentIQAcquisitionCaf::reset()
{
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_active(true);
}
}
float GalileoE5aNoncoherentIQAcquisitionCaf::calculate_threshold(float pfa) const
{
// Calculate the threshold
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += static_cast<int>(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 GalileoE5aNoncoherentIQAcquisitionCaf::set_state(int state)
{
acquisition_cc_->set_state(state);
}
void GalileoE5aNoncoherentIQAcquisitionCaf::connect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
// Nothing to connect internally
}
void GalileoE5aNoncoherentIQAcquisitionCaf::disconnect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
// Nothing to disconnect internally
}
gr::basic_block_sptr GalileoE5aNoncoherentIQAcquisitionCaf::get_left_block()
{
return acquisition_cc_;
}
gr::basic_block_sptr GalileoE5aNoncoherentIQAcquisitionCaf::get_right_block()
{
return acquisition_cc_;
}
@@ -24,23 +24,14 @@
#ifndef GNSS_SDR_GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H
#define GNSS_SDR_GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H
#include "channel_fsm.h"
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
#include "gnss_synchro.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base_pcps_acquisition_custom.h"
/** \addtogroup Acquisition
* \{ */
/** \addtogroup Acq_adapters
* \{ */
class ConfigurationInterface;
class GalileoE5aNoncoherentIQAcquisitionCaf : public AcquisitionInterface
class GalileoE5aNoncoherentIQAcquisitionCaf : public BasePcpsAcquisitionCustom
{
public:
GalileoE5aNoncoherentIQAcquisitionCaf(const ConfigurationInterface* configuration,
@@ -50,11 +41,6 @@ public:
~GalileoE5aNoncoherentIQAcquisitionCaf() = default;
inline std::string role() override
{
return role_;
}
/*!
* \brief Returns "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF"
*/
@@ -63,106 +49,19 @@ public:
return "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF";
}
inline size_t item_size() override
{
return item_size_;
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Set acquisition channel unique ID
*/
inline void set_channel(unsigned int channel) override
{
channel_ = channel;
acquisition_cc_->set_channel(channel_);
}
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{
channel_fsm_ = std::move(channel_fsm);
acquisition_cc_->set_channel_fsm(channel_fsm_);
}
/*!
* \brief Set statistics threshold of PCPS algorithm
*/
void set_threshold(float threshold) override;
/*!
* \brief Initializes acquisition algorithm.
*/
void init() override;
/*!
* \brief Sets local Galileo E5a code for PCPS acquisition algorithm.
*/
void set_local_code() override;
/*!
* \brief Returns the maximum peak of grid search
*/
signed int mag() override;
/*!
* \brief Restart acquisition algorithm
*/
void reset() override;
/*!
* \brief If set to 1, ensures that acquisition starts at the
* first available sample.
* \param state - int=1 forces start of acquisition
*/
void set_state(int state) override;
/*!
* \brief Stop running acquisition
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {};
private:
float calculate_threshold(float pfa) const;
// We don't implement this function since we override set_local_code
void code_gen_complex_sampled(own::span<std::complex<float>> /*dest*/, uint32_t /*prn*/, int32_t /*sampling_freq*/) override {}
const int zero_padding_;
const int caf_window_hz_;
const ConfigurationInterface* configuration_;
galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr acquisition_cc_;
std::weak_ptr<ChannelFsm> channel_fsm_;
std::vector<std::complex<float>> codeI_;
std::vector<std::complex<float>> codeQ_;
std::string item_type_;
std::string role_;
std::string dump_filename_;
Gnss_Synchro* gnss_synchro_;
int64_t fs_in_;
size_t item_size_;
float threshold_;
int Zero_padding;
int CAF_window_hz_;
int code_length_;
unsigned int vector_length_;
unsigned int channel_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
bool bit_transition_flag_;
bool both_signal_components;
bool dump_;
};
@@ -19,10 +19,9 @@
#include "gps_l1_ca_pcps_quicksync_acquisition.h"
#include "GPS_L1_CA.h"
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include "gps_sdr_signal_replica.h"
#include "pcps_quicksync_acquisition_cc.h"
#include <boost/math/distributions/exponential.hpp>
#include <algorithm>
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
@@ -30,231 +29,52 @@
#include <absl/log/log.h>
#endif
#if HAS_STD_SPAN
#include <span>
namespace own = std;
#else
#include <gsl-lite/gsl-lite.hpp>
namespace own = gsl_lite;
#endif
namespace
{
uint32_t get_folding_factor(const ConfigurationInterface* configuration, const std::string& role)
{
const int64_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", static_cast<int64_t>(4000000));
const auto fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
const auto code_length = static_cast<unsigned int>(round(fs_in / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS)));
const auto folding_factor = static_cast<unsigned int>(ceil(sqrt(log2(code_length))));
return configuration->property(role + ".folding_factor", folding_factor);
}
} // namespace
GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
const ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams)
: configuration_(configuration),
role_(role),
gnss_synchro_(nullptr),
item_size_(sizeof(gr_complex)),
threshold_(0.0),
channel_(0),
doppler_max_(configuration->property(role + ".doppler_max", 5000)),
doppler_step_(configuration_->property(role + ".doppler_step", 500)),
sampled_ms_(configuration_->property(role + ".coherent_integration_time_ms", 4)),
bit_transition_flag_(configuration_->property(role + ".bit_transition_flag", false)),
dump_(configuration_->property(role + ".dump", false))
: BasePcpsAcquisitionCustom(
configuration,
role,
in_streams,
out_streams,
GPS_L1_CA_CODE_RATE_CPS,
GPS_L1_CA_CODE_LENGTH_CHIPS,
GPS_L1_CA_CODE_PERIOD_MS * get_folding_factor(configuration, role),
true,
true),
folding_factor_(get_folding_factor(configuration, role))
{
const std::string default_item_type("gr_complex");
std::string default_dump_filename = "./data/acquisition.dat";
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);
#if USE_GLOG_AND_GFLAGS
if (FLAGS_doppler_max != 0)
if (is_type_gr_complex())
{
doppler_max_ = FLAGS_doppler_max;
}
if (FLAGS_doppler_step != 0)
{
doppler_step_ = static_cast<uint32_t>(FLAGS_doppler_step);
}
#else
if (absl::GetFlag(FLAGS_doppler_max) != 0)
{
doppler_max_ = absl::GetFlag(FLAGS_doppler_max);
}
if (absl::GetFlag(FLAGS_doppler_step) != 0)
{
doppler_step_ = static_cast<uint32_t>(absl::GetFlag(FLAGS_doppler_step));
}
#endif
// const int samples_per_ms = round(code_length_ / acq_parameters_.sampled_ms);
const unsigned int max_dwells = acq_parameters_.bit_transition_flag ? 2 : acq_parameters_.max_dwells;
// -- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(round(fs_in_ / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS)));
/* Calculate the folding factor value */
auto temp = static_cast<unsigned int>(ceil(sqrt(log2(code_length_))));
folding_factor_ = configuration_->property(role_ + ".folding_factor", temp);
if (sampled_ms_ % folding_factor_ != 0)
{
LOG(WARNING) << "QuickSync Algorithm requires a coherent_integration_time"
<< " multiple of " << folding_factor_ << "ms, Value entered "
<< sampled_ms_ << " ms";
if (sampled_ms_ < folding_factor_)
{
sampled_ms_ = static_cast<int>(folding_factor_);
}
else
{
sampled_ms_ = static_cast<int>(sampled_ms_ / folding_factor_) * folding_factor_;
}
LOG(WARNING) << " Coherent_integration_time of "
<< sampled_ms_ << " ms will be used instead.";
}
vector_length_ = code_length_ * sampled_ms_;
unsigned int max_dwells = 2;
if (!bit_transition_flag_)
{
max_dwells = configuration->property(role + ".max_dwells", 1);
}
dump_filename_ = configuration_->property(role_ + ".dump_filename", std::move(default_dump_filename));
bool enable_monitor_output = configuration_->property("AcquisitionMonitor.enable_monitor", false);
int samples_per_ms = round(code_length_);
code_ = std::vector<std::complex<float>>(code_length_);
DLOG(INFO) << "role " << role_;
/* Object relevant information for debugging */
LOG(INFO) << "Implementation: " << this->implementation()
<< ", Vector Length: " << vector_length_
<< ", Samples per ms: " << samples_per_ms
<< ", Folding factor: " << folding_factor_
<< ", Sampled ms: " << sampled_ms_
<< ", Code Length: " << code_length_;
if (item_type_ == "gr_complex")
{
acquisition_cc_ = pcps_quicksync_make_acquisition_cc(folding_factor_,
sampled_ms_, max_dwells, doppler_max_, doppler_step_, fs_in_,
samples_per_ms, code_length_, bit_transition_flag_,
dump_, dump_filename_, enable_monitor_output);
vector_length_, max_dwells, acq_parameters_.doppler_max, acq_parameters_.doppler_step, acq_parameters_.fs_in, code_length_, acq_parameters_.bit_transition_flag,
acq_parameters_.dump, acq_parameters_.dump_filename, acq_parameters_.enable_monitor_output);
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_,
code_length_ * folding_factor_);
DLOG(INFO) << "stream_to_vector_quicksync(" << stream_to_vector_->unique_id() << ")";
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")";
}
else
{
item_size_ = 0;
acquisition_cc_ = nullptr;
LOG(WARNING) << item_type_ << " unknown acquisition item type";
}
if (in_streams > 1)
{
LOG(ERROR) << "This implementation only supports one input stream";
}
if (out_streams > 0)
{
LOG(ERROR) << "This implementation does not provide an output stream";
}
}
void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition()
void GpsL1CaPcpsQuickSyncAcquisition::code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq)
{
acquisition_cc_->set_state(0);
acquisition_cc_->set_active(false);
}
void GpsL1CaPcpsQuickSyncAcquisition::set_threshold(float threshold)
{
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", static_cast<float>(0.0));
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", static_cast<float>(0.0));
}
if (pfa == 0.0)
{
threshold_ = threshold;
}
else
{
threshold_ = calculate_threshold(pfa);
}
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_threshold(threshold_);
}
}
void GpsL1CaPcpsQuickSyncAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
}
}
signed int GpsL1CaPcpsQuickSyncAcquisition::mag()
{
if (item_type_ == "gr_complex")
{
return acquisition_cc_->mag();
}
return 0;
}
void GpsL1CaPcpsQuickSyncAcquisition::init()
{
acquisition_cc_->init();
}
void GpsL1CaPcpsQuickSyncAcquisition::set_local_code()
{
if (item_type_ == "gr_complex")
{
std::vector<std::complex<float>> code(code_length_);
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0);
own::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < (sampled_ms_ / folding_factor_); i++)
{
std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
}
acquisition_cc_->set_local_code(code_.data());
}
}
void GpsL1CaPcpsQuickSyncAcquisition::reset()
{
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_active(true);
}
}
void GpsL1CaPcpsQuickSyncAcquisition::set_state(int state)
{
if (item_type_ == "gr_complex")
{
acquisition_cc_->set_state(state);
}
gps_l1_ca_code_gen_complex_sampled(dest, prn, sampling_freq, 0);
}
@@ -262,7 +82,7 @@ float GpsL1CaPcpsQuickSyncAcquisition::calculate_threshold(float pfa) const
{
// Calculate the threshold
unsigned int frequency_bins = 0;
for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += static_cast<int>(doppler_step_))
for (int doppler = -acq_parameters_.doppler_max; doppler <= acq_parameters_.doppler_max; doppler += acq_parameters_.doppler_step)
{
frequency_bins++;
}
@@ -276,33 +96,3 @@ float GpsL1CaPcpsQuickSyncAcquisition::calculate_threshold(float pfa) const
return threshold;
}
void GpsL1CaPcpsQuickSyncAcquisition::connect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
{
top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
}
}
void GpsL1CaPcpsQuickSyncAcquisition::disconnect(gr::top_block_sptr top_block)
{
if (item_type_ == "gr_complex")
{
top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
}
}
gr::basic_block_sptr GpsL1CaPcpsQuickSyncAcquisition::get_left_block()
{
return stream_to_vector_;
}
gr::basic_block_sptr GpsL1CaPcpsQuickSyncAcquisition::get_right_block()
{
return acquisition_cc_;
}
@@ -19,29 +19,18 @@
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H
#define GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H
#include "channel_fsm.h"
#include "configuration_interface.h"
#include "gnss_synchro.h"
#include "pcps_quicksync_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base_pcps_acquisition_custom.h"
/** \addtogroup Acquisition
* \{ */
/** \addtogroup Acq_adapters
* \{ */
class ConfigurationInterface;
/*!
* \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
* for GPS L1 C/A signals
*/
class GpsL1CaPcpsQuickSyncAcquisition : public AcquisitionInterface
class GpsL1CaPcpsQuickSyncAcquisition : public BasePcpsAcquisitionCustom
{
public:
GpsL1CaPcpsQuickSyncAcquisition(
@@ -52,11 +41,6 @@ public:
~GpsL1CaPcpsQuickSyncAcquisition() = default;
inline std::string role() override
{
return role_;
}
/*!
* \brief Returns "GPS_L1_CA_PCPS_QuickSync_Acquisition"
*/
@@ -65,105 +49,11 @@ public:
return "GPS_L1_CA_PCPS_QuickSync_Acquisition";
}
inline size_t item_size() override
{
return item_size_;
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Set acquisition channel unique ID
*/
inline void set_channel(unsigned int channel) override
{
channel_ = channel;
acquisition_cc_->set_channel(channel_);
}
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{
channel_fsm_ = std::move(channel_fsm);
acquisition_cc_->set_channel_fsm(channel_fsm_);
}
/*!
* \brief Set statistics threshold of PCPS algorithm
*/
void set_threshold(float threshold) override;
/*!
* \brief Initializes acquisition algorithm.
*/
void init() override;
/*!
* \brief Sets local code for GPS L1/CA PCPS acquisition algorithm.
*/
void set_local_code() override;
/*!
* \brief Returns the maximum peak of grid search
*/
signed int mag() override;
/*!
* \brief Restart acquisition algorithm
*/
void reset() override;
/*!
* \brief If state = 1, it forces the block to start acquiring from the first sample
*/
void set_state(int state) override;
/*!
* \brief Stop running acquisition
*/
void stop_acquisition() override;
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {};
private:
float calculate_threshold(float pfa) const;
float calculate_threshold(float pfa) const override;
void code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq) override;
const ConfigurationInterface* configuration_;
pcps_quicksync_acquisition_cc_sptr acquisition_cc_;
std::weak_ptr<ChannelFsm> channel_fsm_;
gr::blocks::stream_to_vector::sptr stream_to_vector_;
std::vector<std::complex<float>> code_;
std::string item_type_;
std::string dump_filename_;
std::string role_;
Gnss_Synchro* gnss_synchro_;
int64_t fs_in_;
size_t item_size_;
float threshold_;
unsigned int vector_length_;
unsigned int code_length_;
unsigned int channel_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int folding_factor_;
bool bit_transition_flag_;
bool dump_;
const unsigned int folding_factor_;
};
@@ -59,7 +59,8 @@ public:
virtual void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) = 0;
virtual void set_threshold(float threshold) = 0;
virtual void init() = 0;
virtual void set_local_code(std::complex<float>* code) = 0;
virtual void set_local_code(std::complex<float>* /*code*/) {};
virtual void set_local_code(std::complex<float>* /*code_data*/, std::complex<float>* /*code_pilot*/) {};
virtual void set_state(int32_t state) = 0;
virtual uint32_t mag() const = 0;
virtual void set_active(bool active) = 0;
@@ -74,7 +74,7 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisit
int CAF_window_hz_,
int Zero_padding_,
bool enable_monitor_output)
: gr::block("galileo_e5a_noncoherentIQ_acquisition_caf_cc",
: acquisition_impl_interface("galileo_e5a_noncoherentIQ_acquisition_caf_cc",
gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(0, 1, sizeof(Gnss_Synchro))),
d_dump_filename(dump_filename),
@@ -24,6 +24,7 @@
#ifndef GNSS_SDR_GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H
#define GNSS_SDR_GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H
#include "acquisition_impl_interface.h"
#include "channel_fsm.h"
#include "gnss_sdr_fft.h"
#include "gnss_synchro.h"
@@ -66,7 +67,7 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make
* Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
* Algorithm 1, for a pseudocode description of this implementation.
*/
class galileo_e5a_noncoherentIQ_acquisition_caf_cc : public gr::block
class galileo_e5a_noncoherentIQ_acquisition_caf_cc : public acquisition_impl_interface
{
public:
/*!
@@ -79,7 +80,7 @@ public:
* to exchange synchronization data between acquisition and tracking blocks.
* \param p_gnss_synchro Satellite information shared by the processing blocks.
*/
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override
{
d_gnss_synchro = p_gnss_synchro;
}
@@ -87,7 +88,7 @@ public:
/*!
* \brief Returns the maximum peak of grid search.
*/
inline unsigned int mag() const
inline unsigned int mag() const override
{
return d_mag;
}
@@ -95,20 +96,20 @@ public:
/*!
* \brief Initializes acquisition algorithm.
*/
void init();
void init() override;
/*!
* \brief Sets local code for PCPS acquisition algorithm.
* \param code - Pointer to the PRN code.
*/
void set_local_code(std::complex<float>* code, std::complex<float>* codeQ);
void set_local_code(std::complex<float>* code, std::complex<float>* codeQ) override;
/*!
* \brief Starts acquisition algorithm, turning from standby mode to
* active mode
* \param active - bool that activates/deactivates the block.
*/
inline void set_active(bool active)
inline void set_active(bool active) override
{
d_active = active;
}
@@ -118,13 +119,13 @@ public:
* first available sample.
* \param state - int=1 forces start of acquisition
*/
void set_state(int state);
void set_state(int state) override;
/*!
* \brief Set acquisition channel unique ID
* \param channel - receiver channel.
*/
inline void set_channel(unsigned int channel)
inline void set_channel(unsigned int channel) override
{
d_channel = channel;
}
@@ -132,7 +133,7 @@ public:
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm)
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{
d_channel_fsm = std::move(channel_fsm);
}
@@ -142,7 +143,7 @@ public:
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
* Algorithm 1, for a definition of this threshold).
*/
inline void set_threshold(float threshold)
inline void set_threshold(float threshold) override
{
d_threshold = threshold;
}
@@ -152,7 +153,7 @@ public:
*/
int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
gr_vector_void_star& output_items) override;
private:
friend galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr
@@ -67,7 +67,7 @@ pcps_cccwsr_acquisition_cc::pcps_cccwsr_acquisition_cc(
bool dump,
const std::string &dump_filename,
bool enable_monitor_output)
: gr::block("pcps_cccwsr_acquisition_cc",
: acquisition_impl_interface("pcps_cccwsr_acquisition_cc",
gr::io_signature::make(1, 1, static_cast<int>(sizeof(gr_complex) * sampled_ms * samples_per_ms)),
gr::io_signature::make(0, 1, sizeof(Gnss_Synchro))),
d_dump_filename(dump_filename),
@@ -23,6 +23,7 @@
#ifndef GNSS_SDR_PCPS_CCCWSR_ACQUISITION_CC_H
#define GNSS_SDR_PCPS_CCCWSR_ACQUISITION_CC_H
#include "acquisition_impl_interface.h"
#include "channel_fsm.h"
#include "gnss_sdr_fft.h"
#include "gnss_synchro.h"
@@ -60,7 +61,7 @@ pcps_cccwsr_acquisition_cc_sptr pcps_cccwsr_make_acquisition_cc(
* \brief This class implements a Parallel Code Phase Search Acquisition with
* Coherent Channel Combining With Sign Recovery scheme.
*/
class pcps_cccwsr_acquisition_cc : public gr::block
class pcps_cccwsr_acquisition_cc : public acquisition_impl_interface
{
public:
/*!
@@ -73,7 +74,7 @@ public:
* to exchange synchronization data between acquisition and tracking blocks.
* \param p_gnss_synchro Satellite information shared by the processing blocks.
*/
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override
{
d_gnss_synchro = p_gnss_synchro;
}
@@ -81,7 +82,7 @@ public:
/*!
* \brief Returns the maximum peak of grid search.
*/
inline uint32_t mag() const
inline uint32_t mag() const override
{
return d_mag;
}
@@ -89,21 +90,21 @@ public:
/*!
* \brief Initializes acquisition algorithm.
*/
void init();
void init() override;
/*!
* \brief Sets local code for CCCWSR acquisition algorithm.
* \param data_code - Pointer to the data PRN code.
* \param pilot_code - Pointer to the pilot PRN code.
*/
void set_local_code(std::complex<float>* code_data, std::complex<float>* code_pilot);
void set_local_code(std::complex<float>* code_data, std::complex<float>* code_pilot) override;
/*!
* \brief Starts acquisition algorithm, turning from standby mode to
* active mode
* \param active - bool that activates/deactivates the block.
*/
inline void set_active(bool active)
inline void set_active(bool active) override
{
d_active = active;
}
@@ -113,13 +114,13 @@ public:
* first available sample.
* \param state - int=1 forces start of acquisition
*/
void set_state(int32_t state);
void set_state(int32_t state) override;
/*!
* \brief Set acquisition channel unique ID
* \param channel - receiver channel.
*/
inline void set_channel(uint32_t channel)
inline void set_channel(uint32_t channel) override
{
d_channel = channel;
}
@@ -127,7 +128,7 @@ public:
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm)
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{
d_channel_fsm = std::move(channel_fsm);
}
@@ -137,7 +138,7 @@ public:
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
* Algorithm 1, for a definition of this threshold).
*/
inline void set_threshold(float threshold)
inline void set_threshold(float threshold) override
{
d_threshold = threshold;
}
@@ -147,7 +148,7 @@ public:
*/
int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
gr_vector_void_star& output_items) override;
private:
friend pcps_cccwsr_acquisition_cc_sptr
@@ -33,12 +33,11 @@
pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
uint32_t folding_factor,
uint32_t sampled_ms,
uint32_t vector_length,
uint32_t max_dwells,
uint32_t doppler_max,
uint32_t doppler_step,
int64_t fs_in,
int32_t samples_per_ms,
int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
@@ -48,8 +47,8 @@ pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
return pcps_quicksync_acquisition_cc_sptr(
new pcps_quicksync_acquisition_cc(
folding_factor,
sampled_ms, max_dwells, doppler_max,
doppler_step, fs_in, samples_per_ms,
vector_length, max_dwells, doppler_max,
doppler_step, fs_in,
samples_per_code,
bit_transition_flag,
dump, dump_filename,
@@ -58,16 +57,15 @@ pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
uint32_t folding_factor,
uint32_t sampled_ms, uint32_t max_dwells,
uint32_t folding_factor, uint32_t vector_length, uint32_t max_dwells,
uint32_t doppler_max, uint32_t doppler_step, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
const std::string& dump_filename,
bool enable_monitor_output)
: gr::block("pcps_quicksync_acquisition_cc",
gr::io_signature::make(1, 1, static_cast<int>(sizeof(gr_complex) * sampled_ms * samples_per_ms)),
: acquisition_impl_interface("pcps_quicksync_acquisition_cc",
gr::io_signature::make(1, 1, static_cast<int>(sizeof(gr_complex) * vector_length)),
gr::io_signature::make(0, 1, sizeof(Gnss_Synchro))),
d_dump_filename(dump_filename),
d_gnss_synchro(nullptr),
@@ -79,7 +77,7 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
d_mag(0),
d_input_power(0.0),
d_test_statistics(0),
d_samples_per_ms(samples_per_ms),
d_vector_length(vector_length),
d_samples_per_code(samples_per_code),
d_state(0),
d_channel(0),
@@ -87,7 +85,6 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
d_doppler_resolution(0),
d_doppler_max(doppler_max),
d_doppler_step(doppler_step),
d_sampled_ms(sampled_ms),
d_max_dwells(max_dwells),
d_well_count(0),
d_fft_size((d_samples_per_code) / d_folding_factor),
@@ -257,7 +254,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_state = 1;
}
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter
d_sample_counter += static_cast<uint64_t>(d_vector_length) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
// DLOG(INFO) << "END CASE 0";
break;
@@ -291,7 +288,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_test_statistics = 0.0;
d_noise_floor_power = 0.0;
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms; // sample counter
d_sample_counter += static_cast<uint64_t>(d_vector_length); // sample counter
d_well_count++;
@@ -495,7 +492,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter
d_sample_counter += static_cast<uint64_t>(d_vector_length) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 1;
@@ -538,7 +535,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter
d_sample_counter += static_cast<uint64_t>(d_vector_length) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 2;
@@ -37,6 +37,7 @@
#ifndef GNSS_SDR_PCPS_QUICKSYNC_ACQUISITION_CC_H
#define GNSS_SDR_PCPS_QUICKSYNC_ACQUISITION_CC_H
#include "acquisition_impl_interface.h"
#include "channel_fsm.h"
#include "gnss_sdr_fft.h"
#include "gnss_synchro.h"
@@ -63,12 +64,11 @@ using pcps_quicksync_acquisition_cc_sptr = gnss_shared_ptr<pcps_quicksync_acquis
pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
uint32_t folding_factor,
uint32_t sampled_ms,
uint32_t vector_length,
uint32_t max_dwells,
uint32_t doppler_max,
uint32_t doppler_step,
int64_t fs_in,
int32_t samples_per_ms,
int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
@@ -82,7 +82,7 @@ pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
* Check \ref Navitec2012 "Faster GPS via the Sparse Fourier Transform",
* for details of its implementation and functionality.
*/
class pcps_quicksync_acquisition_cc : public gr::block
class pcps_quicksync_acquisition_cc : public acquisition_impl_interface
{
public:
/*!
@@ -95,7 +95,7 @@ public:
* to exchange synchronization data between acquisition and tracking blocks.
* \param p_gnss_synchro Satellite information shared by the processing blocks.
*/
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override
{
d_gnss_synchro = p_gnss_synchro;
}
@@ -103,7 +103,7 @@ public:
/*!
* \brief Returns the maximum peak of grid search.
*/
inline uint32_t mag() const
inline uint32_t mag() const override
{
return d_mag;
}
@@ -111,20 +111,20 @@ public:
/*!
* \brief Initializes acquisition algorithm.
*/
void init();
void init() override;
/*!
* \brief Sets local code for PCPS acquisition algorithm.
* \param code - Pointer to the PRN code.
*/
void set_local_code(std::complex<float>* code);
void set_local_code(std::complex<float>* code) override;
/*!
* \brief Starts acquisition algorithm, turning from standby mode to
* active mode
* \param active - bool that activates/deactivates the block.
*/
inline void set_active(bool active)
inline void set_active(bool active) override
{
d_active = active;
}
@@ -134,13 +134,13 @@ public:
* first available sample.
* \param state - int=1 forces start of acquisition
*/
void set_state(int32_t state);
void set_state(int32_t state) override;
/*!
* \brief Set acquisition channel unique ID
* \param channel - receiver channel.
*/
inline void set_channel(uint32_t channel)
inline void set_channel(uint32_t channel) override
{
d_channel = channel;
}
@@ -148,7 +148,7 @@ public:
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm)
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{
d_channel_fsm = std::move(channel_fsm);
}
@@ -158,7 +158,7 @@ public:
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
* Algorithm 1, for a definition of this threshold).
*/
inline void set_threshold(float threshold)
inline void set_threshold(float threshold) override
{
d_threshold = threshold;
}
@@ -168,23 +168,23 @@ public:
*/
int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
gr_vector_void_star& output_items) override;
private:
friend pcps_quicksync_acquisition_cc_sptr
pcps_quicksync_make_acquisition_cc(uint32_t folding_factor,
uint32_t sampled_ms, uint32_t max_dwells,
uint32_t vector_length, uint32_t max_dwells,
uint32_t doppler_max, uint32_t doppler_step, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
const std::string& dump_filename,
bool enable_monitor_output);
pcps_quicksync_acquisition_cc(uint32_t folding_factor,
uint32_t sampled_ms, uint32_t max_dwells,
uint32_t vector_length, uint32_t max_dwells,
uint32_t doppler_max, uint32_t doppler_step, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
const std::string& dump_filename,
@@ -224,7 +224,7 @@ private:
float d_mag;
float d_input_power;
float d_test_statistics;
int32_t d_samples_per_ms;
const int32_t d_vector_length;
int32_t d_samples_per_code;
int32_t d_state;
uint32_t d_channel;
@@ -232,7 +232,6 @@ private:
uint32_t d_doppler_resolution;
const uint32_t d_doppler_max;
const uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_max_dwells;
uint32_t d_well_count;
uint32_t d_fft_size;