mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-17 04:33:03 +00:00
Added 'blocking' option to pcps_acquisition_cc
Using C++ 11 threading routines to create a worker thread that can perform the FFT for acquisition in a non-blocking manner. By default 'blocking' is set to true, which is identical to the previous behaviour (with the added overhead of an extra thread). When 'blocking' is set to false, then the main thread does not wait for the worker, thereby letting the receiver continue even when the FFT thread is working. This is very useful for using FFT acquisition at higher sampling rates, where the FFT cannot be performed in real-time. The aim is to replace the separate pcps_multithread_acquisition_cc. TODO: implement the same thing for the pcps_acquisition_sc
This commit is contained in:
parent
3f557eeb41
commit
ba3d7bfcd8
@ -56,6 +56,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||
if_ = configuration_->property(role + ".if", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
blocking_ = configuration_->property(role + ".blocking", true);
|
||||
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4);
|
||||
|
||||
@ -91,7 +92,8 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
||||
item_size_ = sizeof(lv_16sc_t);
|
||||
acquisition_sc_ = pcps_make_acquisition_sc(sampled_ms_, max_dwells_,
|
||||
doppler_max_, if_, fs_in_, samples_per_ms, code_length_,
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, dump_filename_);
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_,
|
||||
dump_filename_);
|
||||
DLOG(INFO) << "acquisition(" << acquisition_sc_->unique_id() << ")";
|
||||
|
||||
}
|
||||
@ -100,7 +102,8 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, max_dwells_,
|
||||
doppler_max_, if_, fs_in_, samples_per_ms, code_length_,
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, dump_filename_);
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_,
|
||||
dump_filename_);
|
||||
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
@ -155,6 +155,7 @@ private:
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
bool blocking_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float> * code_;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
|
@ -59,6 +59,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||
if_ = configuration_->property(role + ".if", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
blocking_ = configuration_->property(role + ".blocking", true);
|
||||
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||
|
||||
@ -94,7 +95,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, max_dwells_,
|
||||
doppler_max_, if_, fs_in_, code_length_, code_length_,
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, dump_filename_);
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_);
|
||||
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,7 @@ private:
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
bool blocking_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float> * code_;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
|
@ -59,6 +59,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||
if_ = configuration_->property(role + ".if", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
blocking_ = configuration_->property(role + ".blocking", true);
|
||||
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
|
||||
|
||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||
@ -95,7 +96,8 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_make_acquisition_cc(1, max_dwells_,
|
||||
doppler_max_, if_, fs_in_, code_length_, code_length_,
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, dump_filename_);
|
||||
bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_,
|
||||
dump_filename_);
|
||||
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,7 @@ private:
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
bool blocking_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float> * code_;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
|
@ -50,12 +50,12 @@ pcps_acquisition_cc_sptr pcps_make_acquisition_cc(
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
|
||||
bool dump,
|
||||
bool dump, bool blocking,
|
||||
std::string dump_filename)
|
||||
{
|
||||
return pcps_acquisition_cc_sptr(
|
||||
new pcps_acquisition_cc(sampled_ms, max_dwells, doppler_max, freq, fs_in, samples_per_ms,
|
||||
samples_per_code, bit_transition_flag, use_CFAR_algorithm_flag, dump, dump_filename));
|
||||
samples_per_code, bit_transition_flag, use_CFAR_algorithm_flag, dump, blocking, dump_filename));
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ pcps_acquisition_cc::pcps_acquisition_cc(
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
|
||||
bool dump,
|
||||
bool dump, bool blocking,
|
||||
std::string dump_filename) :
|
||||
gr::block("pcps_acquisition_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex) * sampled_ms * samples_per_ms * ( bit_transition_flag ? 2 : 1 )),
|
||||
@ -129,6 +129,16 @@ pcps_acquisition_cc::pcps_acquisition_cc(
|
||||
|
||||
d_gnss_synchro = 0;
|
||||
d_grid_doppler_wipeoffs = 0;
|
||||
|
||||
d_done = false;
|
||||
d_blocking = blocking;
|
||||
d_new_data_available = false;
|
||||
d_worker_active = false;
|
||||
d_data_buffer = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
|
||||
// Start the worker thread and wait for it to acknowledge:
|
||||
std::thread t1( &pcps_acquisition_cc::acquisition_core, this );
|
||||
std::swap( d_worker_thread, t1 );
|
||||
}
|
||||
|
||||
|
||||
@ -153,6 +163,16 @@ pcps_acquisition_cc::~pcps_acquisition_cc()
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
// Let the worker thread know that we are done and then wait to join
|
||||
{
|
||||
std::lock_guard<std::mutex> lk( d_mutex );
|
||||
d_done = true;
|
||||
d_cond.notify_one();
|
||||
}
|
||||
|
||||
d_worker_thread.join();
|
||||
volk_gnsssdr_free( d_data_buffer );
|
||||
}
|
||||
|
||||
|
||||
@ -212,6 +232,10 @@ void pcps_acquisition_cc::init()
|
||||
int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index;
|
||||
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_freq + doppler);
|
||||
}
|
||||
|
||||
d_new_data_available = false;
|
||||
d_done = false;
|
||||
d_worker_active = false;
|
||||
}
|
||||
|
||||
|
||||
@ -316,176 +340,217 @@ int pcps_acquisition_cc::general_work(int noutput_items,
|
||||
|
||||
case 1:
|
||||
{
|
||||
// initialize acquisition algorithm
|
||||
int doppler;
|
||||
uint32_t indext = 0;
|
||||
float magt = 0.0;
|
||||
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]);
|
||||
std::unique_lock<std::mutex> lk( d_mutex );
|
||||
|
||||
int effective_fft_size = ( d_bit_transition_flag ? d_fft_size/2 : d_fft_size );
|
||||
|
||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||
|
||||
d_input_power = 0.0;
|
||||
d_mag = 0.0;
|
||||
d_sample_counter += d_fft_size; // sample counter
|
||||
d_well_count++;
|
||||
|
||||
DLOG(INFO)<< "Channel: " << d_channel
|
||||
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
||||
<< " ,sample stamp: " << d_sample_counter << ", threshold: "
|
||||
<< d_threshold << ", doppler_max: " << d_doppler_max
|
||||
<< ", doppler_step: " << d_doppler_step<<std::endl;
|
||||
|
||||
if (d_use_CFAR_algorithm_flag == true)
|
||||
if( d_worker_active && !d_blocking )
|
||||
{
|
||||
d_sample_counter += d_fft_size * ninput_items[0];
|
||||
consume_each( ninput_items[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( d_worker_active && d_blocking )
|
||||
{
|
||||
// 1- (optional) Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size);
|
||||
d_input_power /= static_cast<float>(d_fft_size);
|
||||
}
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in,
|
||||
d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
||||
|
||||
// 3- Perform the FFT-based convolution (parallel time search)
|
||||
// Compute the FFT of the carrier wiped--off incoming signal
|
||||
d_fft_if->execute();
|
||||
|
||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
||||
// with the local FFT'd code reference using SIMD operations with VOLK library
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||
|
||||
// compute the inverse FFT
|
||||
d_ifft->execute();
|
||||
|
||||
// Search maximum
|
||||
size_t offset = ( d_bit_transition_flag ? effective_fft_size : 0 );
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
|
||||
magt = d_magnitude[indext];
|
||||
|
||||
if (d_use_CFAR_algorithm_flag == true)
|
||||
{
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
if (d_mag < magt)
|
||||
{
|
||||
d_mag = magt;
|
||||
|
||||
if (d_use_CFAR_algorithm_flag == false)
|
||||
{
|
||||
// Search grid noise floor approximation for this doppler line
|
||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
|
||||
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
|
||||
}
|
||||
|
||||
// In case that d_bit_transition_flag = true, we compare the potentially
|
||||
// new maximum test statistics (d_mag/d_input_power) with the value in
|
||||
// d_test_statistics. When the second dwell is being processed, the value
|
||||
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
|
||||
// the maximum test statistics in the previous dwell is greater than
|
||||
// current d_mag/d_input_power). Note that d_test_statistics is not
|
||||
// restarted between consecutive dwells in multidwell operation.
|
||||
|
||||
if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag)
|
||||
{
|
||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||
|
||||
// 5- Compute the test statistics and compare to the threshold
|
||||
//d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
|
||||
d_test_statistics = d_mag / d_input_power;
|
||||
}
|
||||
}
|
||||
|
||||
// Record results to file if required
|
||||
if (d_dump)
|
||||
{
|
||||
std::stringstream filename;
|
||||
std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
|
||||
boost::filesystem::path p = d_dump_filename;
|
||||
filename << p.parent_path().string()
|
||||
<< boost::filesystem::path::preferred_separator
|
||||
<< p.stem().string()
|
||||
<< "_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_"
|
||||
<< doppler
|
||||
<< p.extension().string();
|
||||
|
||||
DLOG(INFO) << "Writing ACQ out to " << filename.str();
|
||||
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write(reinterpret_cast<char*>(d_ifft->get_outbuf()), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
}
|
||||
d_cond.wait( lk, [&]{ return !this->d_worker_active; } );
|
||||
}
|
||||
|
||||
if (!d_bit_transition_flag)
|
||||
d_sample_counter += d_fft_size;
|
||||
|
||||
|
||||
if( d_well_count > 0 )
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
|
||||
if (!d_bit_transition_flag)
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 0; // Positive acquisition
|
||||
d_active = false;
|
||||
send_positive_acquisition();
|
||||
}
|
||||
else if (d_well_count == d_max_dwells)
|
||||
else if (d_well_count == d_max_dwells)
|
||||
{
|
||||
d_state = 0;
|
||||
d_active = false;
|
||||
send_negative_acquisition();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_well_count == d_max_dwells) // d_max_dwells = 2
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_well_count == d_max_dwells) // d_max_dwells = 2
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 0; // Positive acquisition
|
||||
d_active = false;
|
||||
send_positive_acquisition();
|
||||
}
|
||||
{
|
||||
d_state = 0; // Positive acquisition
|
||||
d_active = false;
|
||||
send_positive_acquisition();
|
||||
}
|
||||
else
|
||||
{
|
||||
d_state = 0; // Negative acquisition
|
||||
d_active = false;
|
||||
send_negative_acquisition();
|
||||
}
|
||||
{
|
||||
d_state = 0; // Negative acquisition
|
||||
d_active = false;
|
||||
send_negative_acquisition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( d_active )
|
||||
{
|
||||
memcpy( d_data_buffer, input_items[0], d_fft_size * sizeof( gr_complex ) );
|
||||
d_new_data_available = true;
|
||||
d_cond.notify_one();
|
||||
}
|
||||
|
||||
consume_each(1);
|
||||
} // if worker_active (else)
|
||||
|
||||
} // case 1, switch d_state
|
||||
|
||||
} // switch d_state
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
void pcps_acquisition_cc::acquisition_core( void )
|
||||
{
|
||||
d_worker_active = false;
|
||||
while( 1 )
|
||||
{
|
||||
std::unique_lock<std::mutex> lk( d_mutex );
|
||||
d_cond.wait( lk, [&]{ return this->d_new_data_available or this->d_done; } );
|
||||
d_worker_active = !d_done;
|
||||
lk.unlock();
|
||||
|
||||
//void pcps_acquisition_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||
//{
|
||||
//// COD:
|
||||
//// For zero-padded case we need one extra code period
|
||||
//if( d_bit_transition_flag )
|
||||
//{
|
||||
//ninput_items_required[0] = noutput_items*(d_samples_per_code * d_max_dwells + d_samples_per_code);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
//ninput_items_required[0] = noutput_items*d_fft_size*d_max_dwells;
|
||||
//}
|
||||
//}
|
||||
if( d_done )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// initialize acquisition algorithm
|
||||
int doppler;
|
||||
uint32_t indext = 0;
|
||||
float magt = 0.0;
|
||||
const gr_complex *in = d_data_buffer; //Get the input samples pointer
|
||||
|
||||
int effective_fft_size = ( d_bit_transition_flag ? d_fft_size/2 : d_fft_size );
|
||||
|
||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||
|
||||
d_input_power = 0.0;
|
||||
d_mag = 0.0;
|
||||
unsigned long int sample_counter = d_sample_counter; // sample counter
|
||||
d_well_count++;
|
||||
|
||||
DLOG(INFO)<< "Channel: " << d_channel
|
||||
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
||||
<< " ,sample stamp: " << sample_counter << ", threshold: "
|
||||
<< d_threshold << ", doppler_max: " << d_doppler_max
|
||||
<< ", doppler_step: " << d_doppler_step
|
||||
<< ", use_CFAR_algorithm_flag: " << ( d_use_CFAR_algorithm_flag ? "true" : "false" )
|
||||
<<std::endl;
|
||||
|
||||
if (d_use_CFAR_algorithm_flag == true)
|
||||
{
|
||||
// 1- (optional) Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size);
|
||||
d_input_power /= static_cast<float>(d_fft_size);
|
||||
}
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in,
|
||||
d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
||||
|
||||
// 3- Perform the FFT-based convolution (parallel time search)
|
||||
// Compute the FFT of the carrier wiped--off incoming signal
|
||||
d_fft_if->execute();
|
||||
|
||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
||||
// with the local FFT'd code reference using SIMD operations with VOLK library
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||
|
||||
// compute the inverse FFT
|
||||
d_ifft->execute();
|
||||
|
||||
// Search maximum
|
||||
size_t offset = ( d_bit_transition_flag ? effective_fft_size : 0 );
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
|
||||
magt = d_magnitude[indext];
|
||||
|
||||
if (d_use_CFAR_algorithm_flag == true)
|
||||
{
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
if (d_mag < magt)
|
||||
{
|
||||
d_mag = magt;
|
||||
|
||||
if (d_use_CFAR_algorithm_flag == false)
|
||||
{
|
||||
// Search grid noise floor approximation for this doppler line
|
||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
|
||||
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
|
||||
}
|
||||
|
||||
// In case that d_bit_transition_flag = true, we compare the potentially
|
||||
// new maximum test statistics (d_mag/d_input_power) with the value in
|
||||
// d_test_statistics. When the second dwell is being processed, the value
|
||||
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
|
||||
// the maximum test statistics in the previous dwell is greater than
|
||||
// current d_mag/d_input_power). Note that d_test_statistics is not
|
||||
// restarted between consecutive dwells in multidwell operation.
|
||||
|
||||
if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag)
|
||||
{
|
||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||
d_gnss_synchro->Acq_samplestamp_samples = sample_counter;
|
||||
|
||||
// 5- Compute the test statistics and compare to the threshold
|
||||
//d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
|
||||
d_test_statistics = d_mag / d_input_power;
|
||||
}
|
||||
}
|
||||
|
||||
// Record results to file if required
|
||||
if (d_dump)
|
||||
{
|
||||
std::stringstream filename;
|
||||
std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
|
||||
boost::filesystem::path p = d_dump_filename;
|
||||
filename << p.parent_path().string()
|
||||
<< boost::filesystem::path::preferred_separator
|
||||
<< p.stem().string()
|
||||
<< "_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_"
|
||||
<< doppler
|
||||
<< p.extension().string();
|
||||
|
||||
DLOG(INFO) << "Writing ACQ out to " << filename.str();
|
||||
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_ifft->get_outbuf(), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
lk.lock();
|
||||
d_worker_active = false;
|
||||
d_new_data_available = false;
|
||||
lk.unlock();
|
||||
d_cond.notify_one();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,9 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <gnuradio/fft/fft.h>
|
||||
@ -66,7 +69,7 @@ pcps_make_acquisition_cc(unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
|
||||
bool dump,
|
||||
bool dump, bool blocking,
|
||||
std::string dump_filename);
|
||||
|
||||
/*!
|
||||
@ -83,18 +86,20 @@ private:
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
|
||||
bool dump,
|
||||
bool dump, bool blocking,
|
||||
std::string dump_filename);
|
||||
|
||||
pcps_acquisition_cc(unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag, bool use_CFAR_algorithm_flag,
|
||||
bool dump,
|
||||
bool dump, bool blocking,
|
||||
std::string dump_filename);
|
||||
|
||||
void update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq);
|
||||
|
||||
void acquisition_core( void );
|
||||
|
||||
void send_negative_acquisition();
|
||||
void send_positive_acquisition();
|
||||
long d_fs_in;
|
||||
@ -132,6 +137,17 @@ private:
|
||||
unsigned int d_channel;
|
||||
std::string d_dump_filename;
|
||||
|
||||
std::thread d_worker_thread;
|
||||
std::mutex d_mutex;
|
||||
|
||||
std::condition_variable d_cond;
|
||||
bool d_done;
|
||||
bool d_new_data_available;
|
||||
bool d_worker_active;
|
||||
bool d_blocking;
|
||||
|
||||
gr_complex *d_data_buffer;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Default destructor.
|
||||
|
Loading…
Reference in New Issue
Block a user