1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2026-05-02 19:51:25 +00:00

Merge branch 'MathieuFavreau-bug/fix-acquisition-blocking-param' into next

This commit is contained in:
Carles Fernandez
2025-11-27 08:21:02 +01:00
3 changed files with 176 additions and 139 deletions

View File

@@ -33,7 +33,7 @@ All notable changes to GNSS-SDR will be documented in this file.
implementations, greatly improving maintainability, simplifying the addition
of new signals, and eliminating a lot of duplicated code. Awesome contribution
by @MathieuFavreau.
- Added a base class for the main acquisition adapters, improving
- Major refactoring of the acquisition adapters and GNU Radio blocks, improving
maintainability and extensibility. Another excellent contribution by
@MathieuFavreau.
- Refactored the internal handling of multi-signal configurations in the PVT
@@ -67,6 +67,8 @@ All notable changes to GNSS-SDR will be documented in this file.
`true`, Telemetry blocks send asynchronous messages back to the Tracking
blocks containing the information required to compute the TOW and week number
at the tracking stage. The default value is `false`.
- Fixed a long-standing issue in which acquisition blocks still blocked
execution even when `blocking=false` was specified in the configuration.
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/

View File

@@ -118,29 +118,29 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_)
d_cshort(conf_.it_size != sizeof(gr_complex)),
d_use_CFAR_algorithm_flag(conf_.use_CFAR_algorithm_flag),
d_dump(!d_dump_filename.empty()),
d_worker(nullptr),
d_gnss_synchro(nullptr),
d_input_power(0.0),
d_doppler_center_step_two(0.0),
d_state(0),
d_doppler_center(0U),
d_doppler_center(0),
d_doppler_bias(0),
d_dump_number(0LL),
d_channel(0U),
d_num_noncoherent_integrations_counter(0U),
d_buffer_count(0U),
d_buffer_count(0),
d_channel(0),
d_resampler_latency_samples(conf_.resampler_latency_samples),
d_sample_counter(0ULL),
d_sample_count(0),
d_step_two(false),
d_active(false),
d_worker_active(false),
d_step_two(false),
d_num_noncoherent_integrations_counter(0),
d_dump_number(0),
d_doppler_center_step_two(0),
d_magnitude_grid(d_num_doppler_bins, volk_gnsssdr::vector<float>(d_fft_size)),
d_tmp_buffer(d_fft_size),
d_input_signal(d_fft_size),
d_ifft(gnss_fft_rev_make_unique(d_fft_size)),
d_grid_doppler_wipeoffs(d_num_doppler_bins, volk_gnsssdr::vector<std::complex<float>>(d_fft_size)),
d_fft_codes(d_fft_size),
d_data_buffer(d_consumed_samples),
d_fft_if(gnss_fft_fwd_make_unique(d_fft_size)),
d_ifft(gnss_fft_rev_make_unique(d_fft_size))
d_fft_if(gnss_fft_fwd_make_unique(d_fft_size))
{
this->message_port_register_out(pmt::mp("events"));
@@ -187,6 +187,26 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_)
}
pcps_acquisition::~pcps_acquisition()
{
wait_if_active();
}
void pcps_acquisition::set_active(bool active)
{
{
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
d_active = active;
}
if (!active)
{
wait_if_active();
}
}
void pcps_acquisition::set_resampler_latency(uint32_t latency_samples)
{
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
@@ -280,23 +300,23 @@ void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
}
void pcps_acquisition::log_acquisition(bool positive, float test_statistics) const
void pcps_acquisition::log_acquisition(const AcquisitionResult& result) const
{
DLOG(INFO) << (positive ? "positive" : "negative") << " acquisition"
DLOG(INFO) << (result.positive_acq ? "positive" : "negative") << " acquisition"
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< ", sample_stamp " << d_sample_counter
<< ", test statistics value " << test_statistics
<< ", sample_stamp " << result.sample_count
<< ", test statistics value " << result.test_statistics
<< ", test statistics threshold " << get_threshold()
<< ", code phase " << d_gnss_synchro->Acq_delay_samples
<< ", doppler " << d_gnss_synchro->Acq_doppler_hz
<< ", input signal power " << d_input_power
<< ", doppler " << static_cast<double>(result.doppler)
<< ", input signal power " << result.input_power
<< ", Assist doppler_center " << d_doppler_center;
}
void pcps_acquisition::send_positive_acquisition(float test_statistics)
void pcps_acquisition::send_positive_acquisition(const AcquisitionResult& result)
{
log_acquisition(true, test_statistics);
log_acquisition(result);
if (!d_channel_fsm.expired())
{
@@ -318,9 +338,9 @@ void pcps_acquisition::send_positive_acquisition(float test_statistics)
}
void pcps_acquisition::send_negative_acquisition(float test_statistics)
void pcps_acquisition::send_negative_acquisition(const AcquisitionResult& result)
{
log_acquisition(false, test_statistics);
log_acquisition(result);
// Declare negative acquisition using a message port
// 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
@@ -328,7 +348,7 @@ void pcps_acquisition::send_negative_acquisition(float test_statistics)
}
void pcps_acquisition::dump_results(float test_statistics, bool positive_acq)
void pcps_acquisition::dump_results(const AcquisitionResult& result)
{
d_dump_number++;
std::string filename = d_dump_filename;
@@ -358,13 +378,13 @@ void pcps_acquisition::dump_results(float test_statistics, bool positive_acq)
write_matlab_var<2>("acq_grid", d_grid.memptr(), matfp, dims_2d);
write_matlab_var<1>("doppler_max", static_cast<int32_t>(d_doppler_max), matfp, dims_1d);
write_matlab_var<1>("doppler_step", static_cast<int32_t>(d_doppler_step), matfp, dims_1d);
write_matlab_var<1>("positive_acq", static_cast<int32_t>(positive_acq ? 1 : 0), matfp, dims_1d);
write_matlab_var<1>("positive_acq", static_cast<int32_t>(result.positive_acq ? 1 : 0), matfp, dims_1d);
write_matlab_var<1>("acq_doppler_hz", static_cast<float>(d_gnss_synchro->Acq_doppler_hz), matfp, dims_1d);
write_matlab_var<1>("acq_delay_samples", static_cast<float>(d_gnss_synchro->Acq_delay_samples), matfp, dims_1d);
write_matlab_var<1>("test_statistic", test_statistics, matfp, dims_1d);
write_matlab_var<1>("test_statistic", result.test_statistics, matfp, dims_1d);
write_matlab_var<1>("threshold", get_threshold(), matfp, dims_1d);
write_matlab_var<1>("input_power", d_input_power, matfp, dims_1d);
write_matlab_var<1>("sample_counter", d_sample_counter, matfp, dims_1d);
write_matlab_var<1>("input_power", result.input_power, matfp, dims_1d);
write_matlab_var<1>("sample_counter", result.sample_count, matfp, dims_1d);
write_matlab_var<1>("PRN", d_gnss_synchro->PRN, matfp, dims_1d);
write_matlab_var<1>("num_dwells", static_cast<int32_t>(d_num_noncoherent_integrations_counter), matfp, dims_1d);
@@ -383,12 +403,12 @@ void pcps_acquisition::dump_results(float test_statistics, bool positive_acq)
}
float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step)
pcps_acquisition::AcquisitionResult pcps_acquisition::max_to_input_power_statistic(uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step)
{
AcquisitionResult result;
float grid_maximum = 0.0;
uint32_t index_doppler = 0U;
uint32_t tmp_intex_t = 0U;
uint32_t index_time = 0U;
// Find the correlation peak and the carrier frequency
for (uint32_t i = 0; i < num_doppler_bins; i++)
@@ -398,38 +418,44 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t&
{
grid_maximum = d_magnitude_grid[i][tmp_intex_t];
index_doppler = i;
index_time = tmp_intex_t;
result.index_time = tmp_intex_t;
}
}
indext = index_time;
if (!d_step_two)
{
const auto index_opp = (index_doppler + d_num_doppler_bins / 2) % d_num_doppler_bins;
d_input_power = static_cast<float>(std::accumulate(d_magnitude_grid[index_opp].data(), d_magnitude_grid[index_opp].data() + d_effective_fft_size, static_cast<float>(0.0)) / d_effective_fft_size / 2.0 / d_num_noncoherent_integrations_counter);
doppler = -static_cast<int32_t>(doppler_max) + d_doppler_center + doppler_step * static_cast<int32_t>(index_doppler);
result.input_power = static_cast<float>(std::accumulate(d_magnitude_grid[index_opp].data(), d_magnitude_grid[index_opp].data() + d_effective_fft_size, static_cast<float>(0.0)) / d_effective_fft_size / 2.0 / d_num_noncoherent_integrations_counter);
result.doppler = -static_cast<int32_t>(doppler_max) + d_doppler_center + doppler_step * static_cast<int32_t>(index_doppler);
}
else
{
doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * d_acq_parameters.doppler_step2);
result.doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * d_acq_parameters.doppler_step2);
}
if (d_input_power < std::numeric_limits<float>::epsilon())
if (result.input_power < std::numeric_limits<float>::epsilon())
{
return 0.0;
result.test_statistics = 0;
}
return grid_maximum / d_input_power;
else
{
result.test_statistics = grid_maximum / result.input_power;
}
return result;
}
float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step)
pcps_acquisition::AcquisitionResult pcps_acquisition::first_vs_second_peak_statistic(uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step)
{
// Look for correlation peaks in the results
// Find the highest peak and compare it to the second highest peak
// The second peak is chosen not closer than 1 chip to the highest peak
AcquisitionResult result;
float firstPeak = 0.0;
uint32_t index_doppler = 0U;
uint32_t tmp_intex_t = 0U;
uint32_t index_time = 0U;
// Find the correlation peak and the carrier frequency
for (uint32_t i = 0; i < num_doppler_bins; i++)
@@ -439,23 +465,22 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t
{
firstPeak = d_magnitude_grid[i][tmp_intex_t];
index_doppler = i;
index_time = tmp_intex_t;
result.index_time = tmp_intex_t;
}
}
indext = index_time;
if (!d_step_two)
{
doppler = -static_cast<int32_t>(doppler_max) + d_doppler_center + doppler_step * static_cast<int32_t>(index_doppler);
result.doppler = -static_cast<int32_t>(doppler_max) + d_doppler_center + doppler_step * static_cast<int32_t>(index_doppler);
}
else
{
doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * d_acq_parameters.doppler_step2);
result.doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * d_acq_parameters.doppler_step2);
}
// Find 1 chip wide code phase exclude range around the peak
int32_t excludeRangeIndex1 = index_time - d_samplesPerChip;
int32_t excludeRangeIndex2 = index_time + d_samplesPerChip;
int32_t excludeRangeIndex1 = result.index_time - d_samplesPerChip;
int32_t excludeRangeIndex2 = result.index_time + d_samplesPerChip;
// Correct code phase exclude range if the range includes array boundaries
if (excludeRangeIndex1 < 0)
@@ -485,7 +510,9 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t
const float secondPeak = d_tmp_buffer[tmp_intex_t];
// Compute the test statistics and compare to the threshold
return firstPeak / secondPeak;
result.test_statistics = firstPeak / secondPeak;
return result;
}
@@ -530,7 +557,7 @@ void pcps_acquisition::doppler_grid(const gr_complex* in)
}
float pcps_acquisition::get_test_statistics(uint32_t& indext, int32_t& doppler)
pcps_acquisition::AcquisitionResult pcps_acquisition::compute_statistics()
{
const auto bin_count = d_step_two ? d_num_doppler_bins_step2 : d_num_doppler_bins;
const auto doppler_step = d_step_two ? d_acq_parameters.doppler_step2 : d_doppler_step;
@@ -538,31 +565,30 @@ float pcps_acquisition::get_test_statistics(uint32_t& indext, int32_t& doppler)
if (d_use_CFAR_algorithm_flag)
{
return max_to_input_power_statistic(indext, doppler, bin_count, doppler_max, doppler_step);
return max_to_input_power_statistic(bin_count, doppler_max, doppler_step);
}
else
{
return first_vs_second_peak_statistic(indext, doppler, bin_count, doppler_max, doppler_step);
return first_vs_second_peak_statistic(bin_count, doppler_max, doppler_step);
}
}
void pcps_acquisition::update_synchro(uint32_t indext, int32_t doppler, uint64_t samp_count)
void pcps_acquisition::update_synchro(const AcquisitionResult& result)
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(result.index_time), d_acq_parameters.samples_per_code));
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(result.doppler);
if (d_acq_parameters.use_automatic_resampler)
{
// take into account the acquisition resampler ratio
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), d_acq_parameters.samples_per_code)) * d_acq_parameters.resampler_ratio;
d_gnss_synchro->Acq_delay_samples -= static_cast<double>(d_resampler_latency_samples); // account the resampler filter latency
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(samp_count) * d_acq_parameters.resampler_ratio);
d_gnss_synchro->Acq_delay_samples = (d_gnss_synchro->Acq_delay_samples * d_acq_parameters.resampler_ratio) - static_cast<double>(d_resampler_latency_samples);
d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(result.sample_count) * d_acq_parameters.resampler_ratio);
d_gnss_synchro->fs = d_acq_parameters.resampled_fs;
}
else
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), d_acq_parameters.samples_per_code));
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
d_gnss_synchro->Acq_samplestamp_samples = result.sample_count;
d_gnss_synchro->fs = d_acq_parameters.fs_in;
}
@@ -573,23 +599,21 @@ void pcps_acquisition::update_synchro(uint32_t indext, int32_t doppler, uint64_t
}
bool pcps_acquisition::handle_threshold_reached(float test_statistics)
void pcps_acquisition::handle_threshold_reached(AcquisitionResult& result)
{
d_active = false;
d_state = 0;
bool positive_acq = false;
if (d_acq_parameters.make_2_steps)
{
if (d_step_two)
{
send_positive_acquisition(test_statistics);
positive_acq = true;
send_positive_acquisition(result);
result.positive_acq = true;
}
else
{
d_doppler_center_step_two = static_cast<float>(d_gnss_synchro->Acq_doppler_hz);
d_doppler_center_step_two = static_cast<float>(result.doppler);
update_grid_doppler_wipeoffs_step2();
d_num_noncoherent_integrations_counter = 0;
}
@@ -598,19 +622,17 @@ bool pcps_acquisition::handle_threshold_reached(float test_statistics)
}
else
{
send_positive_acquisition(test_statistics);
positive_acq = true;
send_positive_acquisition(result);
result.positive_acq = true;
}
return positive_acq;
}
void pcps_acquisition::handle_integration_done(float test_statistics)
void pcps_acquisition::handle_integration_done(const AcquisitionResult& result)
{
if (d_state != 0)
{
send_negative_acquisition(test_statistics);
send_negative_acquisition(result);
}
d_active = false;
@@ -619,7 +641,7 @@ void pcps_acquisition::handle_integration_done(float test_statistics)
}
void pcps_acquisition::acquisition_core(uint64_t samp_count)
void pcps_acquisition::acquisition_core(uint64_t sample_count)
{
gr::thread::scoped_lock lk(d_setlock);
@@ -642,36 +664,28 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
DLOG(INFO) << "Channel: " << d_channel
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< " , sample stamp: " << samp_count
<< " , sample stamp: " << sample_count
<< ", threshold: " << get_threshold()
<< ", doppler_max: " << d_doppler_max
<< ", doppler_step: " << d_doppler_step
<< ", use_CFAR_algorithm_flag: " << (d_use_CFAR_algorithm_flag ? "true" : "false");
if (d_acq_parameters.blocking)
{
lk.unlock();
}
lk.unlock();
// Doppler frequency grid loop
int32_t doppler = 0;
uint32_t indext = 0U;
// Doppler frequency grid loop, only access variables that doesn't need a lock
doppler_grid(in);
const auto test_statistics = get_test_statistics(indext, doppler);
update_synchro(indext, doppler, samp_count);
auto result = compute_statistics();
result.sample_count = sample_count;
if (d_acq_parameters.blocking)
{
lk.lock();
}
lk.lock();
bool positive_acq = false;
update_synchro(result);
if (!d_acq_parameters.bit_transition_flag)
{
if (test_statistics > get_threshold())
if (result.test_statistics > get_threshold())
{
positive_acq = handle_threshold_reached(test_statistics);
handle_threshold_reached(result);
}
else
{
@@ -681,41 +695,32 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
if (d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells)
{
handle_integration_done(test_statistics);
handle_integration_done(result);
}
}
else
{
if (test_statistics > d_threshold)
if (result.test_statistics > d_threshold)
{
positive_acq = handle_threshold_reached(test_statistics);
handle_threshold_reached(result);
}
else
{
handle_integration_done(test_statistics);
handle_integration_done(result);
}
}
d_worker_active = false;
if ((d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) or (positive_acq) or (d_acq_parameters.bit_transition_flag))
if ((d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) or (result.positive_acq) or (d_acq_parameters.bit_transition_flag))
{
// Record results to file if required
if (d_dump and d_channel == d_dump_channel)
{
pcps_acquisition::dump_results(test_statistics, positive_acq);
pcps_acquisition::dump_results(result);
}
d_num_noncoherent_integrations_counter = 0U;
}
}
// Called by gnuradio to enable drivers, etc for i/o devices.
bool pcps_acquisition::start()
{
gr::thread::scoped_lock lk(d_setlock);
d_sample_counter = 0ULL;
return true;
d_worker_active = false;
}
@@ -759,7 +764,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
bool consume_samples = ((!d_active) || (d_worker_active && (d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells)));
if ((!d_acq_parameters.blocking_on_standby) && consume_samples)
{
d_sample_counter += static_cast<uint64_t>(ninput_items[0]);
d_sample_count += static_cast<uint64_t>(ninput_items[0]);
consume_each(ninput_items[0]);
}
if (d_step_two)
@@ -805,7 +810,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
d_state = 2;
}
d_buffer_count += buff_increment;
d_sample_counter += static_cast<uint64_t>(buff_increment);
d_sample_count += static_cast<uint64_t>(buff_increment);
consume_each(buff_increment);
break;
}
@@ -815,11 +820,14 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
if (d_acq_parameters.blocking)
{
lk.unlock();
acquisition_core(d_sample_counter);
acquisition_core(d_sample_count);
}
else
{
gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter);
lk.unlock();
wait_if_active();
lk.lock();
d_worker = std::make_unique<gr::thread::thread>(&pcps_acquisition::acquisition_core, this, d_sample_count);
d_worker_active = true;
}
consume_each(0);
@@ -844,3 +852,22 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
return 0;
}
void pcps_acquisition::wait_if_active()
{
std::unique_ptr<gr::thread::thread> worker;
{
gr::thread::scoped_lock lk(d_setlock);
worker = std::move(d_worker);
d_worker = nullptr;
}
if (worker != nullptr)
{
if (worker->joinable())
{
worker->join();
}
}
}

View File

@@ -93,7 +93,7 @@ pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
class pcps_acquisition : public acquisition_impl_interface
{
public:
~pcps_acquisition() override = default;
~pcps_acquisition() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
@@ -127,11 +127,7 @@ public:
* active mode
* \param active - bool that activates/deactivates the block.
*/
inline void set_active(bool active) override
{
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
d_active = active;
}
void set_active(bool active) override;
/*!
* \brief Set acquisition channel unique ID
@@ -167,24 +163,34 @@ private:
friend pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
explicit pcps_acquisition(const Acq_Conf& conf_);
struct AcquisitionResult
{
int32_t doppler{0};
uint32_t index_time{0};
uint64_t sample_count{0};
float input_power{0};
float test_statistics{0};
bool positive_acq{false};
};
void update_local_carrier(own::span<gr_complex> carrier_vector, float freq) const;
void update_grid_doppler_wipeoffs();
void update_grid_doppler_wipeoffs_step2();
void doppler_grid(const gr_complex* in);
float get_test_statistics(uint32_t& indext, int32_t& doppler);
void update_synchro(uint32_t indext, int32_t doppler, uint64_t samp_count);
bool handle_threshold_reached(float test_statistics);
void handle_integration_done(float test_statistics);
void acquisition_core(uint64_t samp_count);
void log_acquisition(bool positive, float test_statistics) const;
void send_negative_acquisition(float test_statistics);
void send_positive_acquisition(float test_statistics);
void dump_results(float test_statistics, bool positive_acq);
AcquisitionResult compute_statistics();
void update_synchro(const AcquisitionResult& result);
void handle_threshold_reached(AcquisitionResult& result);
void handle_integration_done(const AcquisitionResult& result);
void acquisition_core(uint64_t sample_count);
void log_acquisition(const AcquisitionResult& result) const;
void send_negative_acquisition(const AcquisitionResult& result);
void send_positive_acquisition(const AcquisitionResult& result);
void dump_results(const AcquisitionResult& result);
bool is_fdma();
bool start() override;
float get_threshold() const;
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
AcquisitionResult first_vs_second_peak_statistic(uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
AcquisitionResult max_to_input_power_statistic(uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
void wait_if_active();
const Acq_Conf d_acq_parameters;
const std::string d_dump_filename;
@@ -203,38 +209,40 @@ private:
const bool d_use_CFAR_algorithm_flag;
const bool d_dump;
// Need lock to access these
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::unique_ptr<gr::thread::thread> d_worker;
Gnss_Synchro* d_gnss_synchro;
arma::fmat d_grid;
arma::fmat d_narrow_grid;
std::queue<Gnss_Synchro> d_monitor_queue;
float d_input_power;
float d_doppler_center_step_two;
int32_t d_state;
int32_t d_doppler_center;
int32_t d_doppler_bias;
int64_t d_dump_number;
uint32_t d_channel;
uint32_t d_num_noncoherent_integrations_counter;
uint32_t d_buffer_count;
uint32_t d_channel;
uint32_t d_resampler_latency_samples;
uint64_t d_sample_counter;
uint64_t d_sample_count;
bool d_step_two;
bool d_active;
bool d_worker_active;
bool d_step_two;
// Only access these in acquisition_core and functions strictly called from acquisition_core
uint32_t d_num_noncoherent_integrations_counter;
int64_t d_dump_number;
float d_doppler_center_step_two;
volk_gnsssdr::vector<volk_gnsssdr::vector<float>> d_magnitude_grid;
volk_gnsssdr::vector<float> d_tmp_buffer;
volk_gnsssdr::vector<std::complex<float>> d_input_signal;
volk_gnsssdr::vector<volk_gnsssdr::vector<std::complex<float>>> d_grid_doppler_wipeoffs;
volk_gnsssdr::vector<volk_gnsssdr::vector<std::complex<float>>> d_grid_doppler_wipeoffs_step_two;
std::unique_ptr<gnss_fft_complex_rev> d_ifft;
arma::fmat d_grid;
arma::fmat d_narrow_grid;
// These are never accessed outside acquisition_core while acquisition is active
volk_gnsssdr::vector<volk_gnsssdr::vector<std::complex<float>>> d_grid_doppler_wipeoffs;
volk_gnsssdr::vector<std::complex<float>> d_fft_codes;
volk_gnsssdr::vector<std::complex<float>> d_data_buffer;
volk_gnsssdr::vector<lv_16sc_t> d_data_buffer_sc;
std::unique_ptr<gnss_fft_complex_fwd> d_fft_if;
std::unique_ptr<gnss_fft_complex_rev> d_ifft;
std::weak_ptr<ChannelFsm> d_channel_fsm;
};