Cleanup last acquisition classes

This commit is contained in:
Mathieu Favreau
2025-11-10 21:47:12 +00:00
parent c78848e973
commit a160f112a6
11 changed files with 129 additions and 655 deletions
@@ -32,7 +32,7 @@ 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 +60,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 +81,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 <climits>
/** \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 = INT_MAX);
~BasePcpsAcquisitionCustom() = default;
@@ -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,43 @@ 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_data_(vector_length_),
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())
{
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,14 @@ 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_;
};
@@ -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,171 +43,64 @@ 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)),
codeI_(vector_length_),
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())
{
std::vector<std::complex<float>> codeI(code_length_);
std::vector<std::complex<float>> codeQ(code_length_);
@@ -215,26 +108,23 @@ void GalileoE5aNoncoherentIQAcquisitionCaf::set_local_code()
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
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,20 @@ 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_;
};
@@ -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