mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-13 19:50:34 +00:00
Better VOLK usage. Memory alignment, using dispatcher instead of
aligned/unaligned versions. Code cleaning.
This commit is contained in:
parent
fd6a8e3cff
commit
9106f147ef
@ -107,35 +107,27 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisit
|
||||
d_both_signal_components = both_signal_components_;
|
||||
d_CAF_window_hz = CAF_window_hz_;
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_inbuffer, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_fft_code_I_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeIA, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_inbuffer = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_fft_code_I_A = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitudeIA = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
if (posix_memalign((void**)&d_fft_code_Q_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeQA, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_code_Q_A = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitudeQA = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
}
|
||||
// IF COHERENT INTEGRATION TIME > 1
|
||||
if (d_sampled_ms > 1)
|
||||
{
|
||||
if (posix_memalign((void**)&d_fft_code_I_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeIB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_code_I_B = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitudeIB = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
if (posix_memalign((void**)&d_fft_code_Q_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeQB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_code_Q_B = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitudeQB = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
}
|
||||
}
|
||||
|
||||
// if (posix_memalign((void**)&d_fft_code_Q_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
// if (posix_memalign((void**)&d_magnitudeQA, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
// if (posix_memalign((void**)&d_fft_code_I_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
// if (posix_memalign((void**)&d_magnitudeIB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
// if (posix_memalign((void**)&d_fft_code_Q_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
// if (posix_memalign((void**)&d_magnitudeQB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
|
||||
@ -153,34 +145,43 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::~galileo_e5a_noncoherentIQ_acquisi
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_code_I_A);
|
||||
free(d_magnitudeIA);
|
||||
volk_free(d_inbuffer);
|
||||
volk_free(d_fft_code_I_A);
|
||||
volk_free(d_magnitudeIA);
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
free(d_fft_code_Q_A);
|
||||
free(d_magnitudeQA);
|
||||
volk_free(d_fft_code_Q_A);
|
||||
volk_free(d_magnitudeQA);
|
||||
}
|
||||
// IF INTEGRATION TIME > 1
|
||||
if (d_sampled_ms > 1)
|
||||
{
|
||||
free(d_fft_code_I_B);
|
||||
free(d_magnitudeIB);
|
||||
volk_free(d_fft_code_I_B);
|
||||
volk_free(d_magnitudeIB);
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
free(d_fft_code_Q_B);
|
||||
free(d_magnitudeQB);
|
||||
volk_free(d_fft_code_Q_B);
|
||||
volk_free(d_magnitudeQB);
|
||||
}
|
||||
}
|
||||
if (d_CAF_window_hz > 0)
|
||||
{
|
||||
volk_free(d_CAF_vector);
|
||||
volk_free(d_CAF_vector_I);
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
volk_free(d_CAF_vector_Q);
|
||||
}
|
||||
}
|
||||
|
||||
delete d_fft_if;
|
||||
delete d_ifft;
|
||||
|
||||
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
@ -197,70 +198,45 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::set_local_code(std::complex<f
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
|
||||
// SAME FOR PILOT SIGNAL
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// Three replicas of pilot primary code. CODE A: (1,1,1)
|
||||
memcpy(d_fft_if->get_inbuf(), codeQ, sizeof(gr_complex)*d_fft_size);
|
||||
{
|
||||
// Three replicas of pilot primary code. CODE A: (1,1,1)
|
||||
memcpy(d_fft_if->get_inbuf(), codeQ, sizeof(gr_complex)*d_fft_size);
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
}
|
||||
//Conjugate the local code
|
||||
volk_32fc_conjugate_32fc(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
// IF INTEGRATION TIME > 1 code, we need to evaluate the other possible combination
|
||||
// Note: max integration time allowed = 3ms (dealt in adapter)
|
||||
if (d_sampled_ms > 1)
|
||||
{
|
||||
// DATA CODE B: First replica is inverted (0,1,1)
|
||||
volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
|
||||
&codeI[0], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
{
|
||||
// DATA CODE B: First replica is inverted (0,1,1)
|
||||
volk_32fc_s32fc_multiply_32fc(&(d_fft_if->get_inbuf())[0],
|
||||
&codeI[0], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// PILOT CODE B: First replica is inverted (0,1,1)
|
||||
volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
|
||||
&codeQ[0], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Conjugate the local code
|
||||
volk_32fc_conjugate_32fc(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// PILOT CODE B: First replica is inverted (0,1,1)
|
||||
volk_32fc_s32fc_multiply_32fc(&(d_fft_if->get_inbuf())[0],
|
||||
&codeQ[0], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
volk_32fc_conjugate_32fc(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init()
|
||||
@ -284,9 +260,7 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init()
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in, d_fft_size);
|
||||
@ -297,11 +271,11 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init()
|
||||
// if (d_CAF_filter)
|
||||
if (d_CAF_window_hz > 0)
|
||||
{
|
||||
if (posix_memalign((void**)&d_CAF_vector, 16, d_num_doppler_bins * sizeof(float)) == 0){};
|
||||
if (posix_memalign((void**)&d_CAF_vector_I, 16, d_num_doppler_bins * sizeof(float)) == 0){};
|
||||
d_CAF_vector = (float*)volk_malloc(d_num_doppler_bins * sizeof(float), volk_get_alignment());
|
||||
d_CAF_vector_I = (float*)volk_malloc(d_num_doppler_bins * sizeof(float), volk_get_alignment());
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
if (posix_memalign((void**)&d_CAF_vector_Q, 16, d_num_doppler_bins * sizeof(float)) == 0){};
|
||||
d_CAF_vector_Q = (float*)volk_malloc(d_num_doppler_bins * sizeof(float), volk_get_alignment());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -408,18 +382,18 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_inbuffer, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitudeIA, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitudeIA, d_inbuffer, d_fft_size);
|
||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitudeIA, d_fft_size);
|
||||
d_input_power /= (float)d_fft_size;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
doppler = -(int)d_doppler_max + d_doppler_step * doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), d_inbuffer,
|
||||
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), d_inbuffer,
|
||||
d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
||||
|
||||
// 3- Perform the FFT-based convolution (parallel time search)
|
||||
@ -429,46 +403,46 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
// CODE IA
|
||||
// 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_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_I_A, d_fft_size);
|
||||
|
||||
// compute the inverse FFT
|
||||
d_ifft->execute();
|
||||
|
||||
// Search maximum
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_IA, d_magnitudeIA, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitudeIA, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_IA, d_magnitudeIA, d_fft_size);
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt_IA = d_magnitudeIA[indext_IA] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// REPEAT FOR ALL CODES. CODE_QA
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_Q_A, d_fft_size);
|
||||
d_ifft->execute();
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeQA, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_QA, d_magnitudeQA, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitudeQA, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_QA, d_magnitudeQA, d_fft_size);
|
||||
magt_QA = d_magnitudeQA[indext_QA] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
if (d_sampled_ms > 1) // If Integration time > 1 code
|
||||
{
|
||||
// REPEAT FOR ALL CODES. CODE_IB
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_I_B, d_fft_size);
|
||||
d_ifft->execute();
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeIB, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_IB, d_magnitudeIB, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitudeIB, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_IB, d_magnitudeIB, d_fft_size);
|
||||
magt_IB = d_magnitudeIB[indext_IB] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// REPEAT FOR ALL CODES. CODE_QB
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_Q_B, d_fft_size);
|
||||
d_ifft->execute();
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeQB, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_QB, d_magnitudeQB, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitudeQB, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_QB, d_magnitudeQB, d_fft_size);
|
||||
magt_QB = d_magnitudeIB[indext_QB] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
}
|
||||
@ -505,7 +479,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
}
|
||||
}
|
||||
}
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitudeIA, d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitudeIA, d_fft_size);
|
||||
magt = d_magnitudeIA[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
else
|
||||
@ -534,7 +508,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
}
|
||||
}
|
||||
}
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitudeIB, d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitudeIB, d_fft_size);
|
||||
magt = d_magnitudeIB[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
}
|
||||
@ -552,7 +526,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
d_magnitudeIA[i] += d_magnitudeQA[i];
|
||||
}
|
||||
}
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitudeIA, d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitudeIA, d_fft_size);
|
||||
magt = d_magnitudeIA[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
|
||||
@ -609,104 +583,103 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
// 6 OPTIONAL: CAF filter to avoid Doppler ambiguity in bit transition.
|
||||
if (d_CAF_window_hz > 0)
|
||||
{
|
||||
int CAF_bins_half;
|
||||
float* accum;
|
||||
// double* accum;
|
||||
if (posix_memalign((void**)&accum, 16, sizeof(float)) == 0){};
|
||||
CAF_bins_half = d_CAF_window_hz/(2*d_doppler_step);
|
||||
float weighting_factor;
|
||||
weighting_factor = 0.5/(float)CAF_bins_half;
|
||||
// weighting_factor = 0;
|
||||
// std::cout << "weighting_factor " << weighting_factor << std::endl;
|
||||
// Initialize first iterations
|
||||
for (int doppler_index=0;doppler_index<CAF_bins_half;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], d_CAF_vector_I, CAF_bins_half+doppler_index+1);
|
||||
for (int i = 0; i < CAF_bins_half+doppler_index+1; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= CAF_bins_half+doppler_index+1;
|
||||
d_CAF_vector[doppler_index] /= 1+CAF_bins_half+doppler_index - weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 - weighting_factor*doppler_index*(doppler_index+1)/2; // triangles = [n*(n+1)/2]
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], d_CAF_vector_Q, CAF_bins_half+doppler_index+1);
|
||||
for (int i = 0; i < CAF_bins_half+doppler_index+1; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= CAF_bins_half+doppler_index+1;
|
||||
accum[0] /= 1+CAF_bins_half+doppler_index - weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 - weighting_factor*doppler_index*(doppler_index+1)/2; // triangles = [n*(n+1)/2]
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
// Body loop
|
||||
for (unsigned int doppler_index=CAF_bins_half;doppler_index<d_num_doppler_bins-CAF_bins_half;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], &d_CAF_vector_I[doppler_index-CAF_bins_half], 2*CAF_bins_half+1);
|
||||
for (int i = doppler_index-CAF_bins_half; i < doppler_index+CAF_bins_half+1; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= 2*CAF_bins_half+1;
|
||||
d_CAF_vector[doppler_index] /= 1+2*CAF_bins_half - 2*weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2;
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], &d_CAF_vector_Q[doppler_index-CAF_bins_half], 2*CAF_bins_half);
|
||||
for (int i = doppler_index-CAF_bins_half; i < doppler_index+CAF_bins_half+1; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= 2*CAF_bins_half+1;
|
||||
accum[0] /= 1+2*CAF_bins_half - 2*weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2;
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
// Final iterations
|
||||
for (unsigned int doppler_index=d_num_doppler_bins-CAF_bins_half;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], &d_CAF_vector_I[doppler_index-CAF_bins_half], CAF_bins_half + (d_num_doppler_bins-doppler_index));
|
||||
for (int i = doppler_index-CAF_bins_half; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= CAF_bins_half+(d_num_doppler_bins-doppler_index);
|
||||
d_CAF_vector[doppler_index] /= 1+CAF_bins_half+(d_num_doppler_bins-doppler_index-1) -weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 -weighting_factor*(d_num_doppler_bins-doppler_index-1)*(d_num_doppler_bins-doppler_index)/2;
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], &d_CAF_vector_Q[doppler_index-CAF_bins_half], CAF_bins_half + (d_num_doppler_bins-doppler_index));
|
||||
for (int i = doppler_index-CAF_bins_half; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= CAF_bins_half+(d_num_doppler_bins-doppler_index);
|
||||
accum[0] /= 1+CAF_bins_half+(d_num_doppler_bins-doppler_index-1) -weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 -weighting_factor*(d_num_doppler_bins-doppler_index-1)*(d_num_doppler_bins-doppler_index)/2;
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
int CAF_bins_half;
|
||||
float* accum = (float*)volk_malloc(sizeof(float), volk_get_alignment());
|
||||
CAF_bins_half = d_CAF_window_hz/(2*d_doppler_step);
|
||||
float weighting_factor;
|
||||
weighting_factor = 0.5/(float)CAF_bins_half;
|
||||
// weighting_factor = 0;
|
||||
// std::cout << "weighting_factor " << weighting_factor << std::endl;
|
||||
// Initialize first iterations
|
||||
for (int doppler_index=0;doppler_index<CAF_bins_half;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], d_CAF_vector_I, CAF_bins_half+doppler_index+1);
|
||||
for (int i = 0; i < CAF_bins_half+doppler_index+1; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= CAF_bins_half+doppler_index+1;
|
||||
d_CAF_vector[doppler_index] /= 1+CAF_bins_half+doppler_index - weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 - weighting_factor*doppler_index*(doppler_index+1)/2; // triangles = [n*(n+1)/2]
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], d_CAF_vector_Q, CAF_bins_half+doppler_index+1);
|
||||
for (int i = 0; i < CAF_bins_half+doppler_index+1; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= CAF_bins_half+doppler_index+1;
|
||||
accum[0] /= 1+CAF_bins_half+doppler_index - weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 - weighting_factor*doppler_index*(doppler_index+1)/2; // triangles = [n*(n+1)/2]
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
// Body loop
|
||||
for (unsigned int doppler_index=CAF_bins_half;doppler_index<d_num_doppler_bins-CAF_bins_half;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], &d_CAF_vector_I[doppler_index-CAF_bins_half], 2*CAF_bins_half+1);
|
||||
for (int i = doppler_index-CAF_bins_half; i < doppler_index+CAF_bins_half+1; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= 2*CAF_bins_half+1;
|
||||
d_CAF_vector[doppler_index] /= 1+2*CAF_bins_half - 2*weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2;
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], &d_CAF_vector_Q[doppler_index-CAF_bins_half], 2*CAF_bins_half);
|
||||
for (int i = doppler_index-CAF_bins_half; i < doppler_index+CAF_bins_half+1; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= 2*CAF_bins_half+1;
|
||||
accum[0] /= 1+2*CAF_bins_half - 2*weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2;
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
// Final iterations
|
||||
for (unsigned int doppler_index=d_num_doppler_bins-CAF_bins_half;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], &d_CAF_vector_I[doppler_index-CAF_bins_half], CAF_bins_half + (d_num_doppler_bins-doppler_index));
|
||||
for (int i = doppler_index-CAF_bins_half; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= CAF_bins_half+(d_num_doppler_bins-doppler_index);
|
||||
d_CAF_vector[doppler_index] /= 1+CAF_bins_half+(d_num_doppler_bins-doppler_index-1) -weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 -weighting_factor*(d_num_doppler_bins-doppler_index-1)*(d_num_doppler_bins-doppler_index)/2;
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], &d_CAF_vector_Q[doppler_index-CAF_bins_half], CAF_bins_half + (d_num_doppler_bins-doppler_index));
|
||||
for (int i = doppler_index-CAF_bins_half; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= CAF_bins_half+(d_num_doppler_bins-doppler_index);
|
||||
accum[0] /= 1+CAF_bins_half+(d_num_doppler_bins-doppler_index-1) -weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 -weighting_factor*(d_num_doppler_bins-doppler_index-1)*(d_num_doppler_bins-doppler_index)/2;
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Recompute the maximum doppler peak
|
||||
volk_32f_index_max_16u_a(&indext, d_CAF_vector, d_num_doppler_bins);
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*indext;
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)doppler;
|
||||
// Dump if required, appended at the end of the file
|
||||
if (d_dump)
|
||||
{
|
||||
std::stringstream filename;
|
||||
std::streamsize n = sizeof(float) * (d_num_doppler_bins); // noncomplex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_E5a_sat_"
|
||||
<< d_gnss_synchro->PRN << "_CAF.dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_CAF_vector, n);
|
||||
d_dump_file.close();
|
||||
}
|
||||
// Recompute the maximum doppler peak
|
||||
volk_32f_index_max_16u(&indext, d_CAF_vector, d_num_doppler_bins);
|
||||
doppler = -(int)d_doppler_max + d_doppler_step*indext;
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)doppler;
|
||||
// Dump if required, appended at the end of the file
|
||||
if (d_dump)
|
||||
{
|
||||
std::stringstream filename;
|
||||
std::streamsize n = sizeof(float) * (d_num_doppler_bins); // noncomplex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_E5a_sat_"
|
||||
<< d_gnss_synchro->PRN << "_CAF.dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_CAF_vector, n);
|
||||
d_dump_file.close();
|
||||
}
|
||||
volk_free(accum);
|
||||
}
|
||||
|
||||
if (d_well_count == d_max_dwells)
|
||||
@ -725,7 +698,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
d_state = 1;
|
||||
}
|
||||
|
||||
consume_each(d_fft_size-d_buffer_count);
|
||||
consume_each(d_fft_size - d_buffer_count);
|
||||
d_buffer_count = 0;
|
||||
break;
|
||||
}
|
||||
@ -745,7 +718,6 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
|
||||
|
||||
acquisition_message = 1;
|
||||
d_channel_internal_queue->push(acquisition_message);
|
||||
d_sample_counter += ninput_items[0]; // sample counter
|
||||
|
@ -79,10 +79,9 @@ galileo_pcps_8ms_acquisition_cc::galileo_pcps_8ms_acquisition_cc(
|
||||
d_input_power = 0.0;
|
||||
d_num_doppler_bins = 0;
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_fft_code_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_fft_code_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_code_A = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_fft_code_B = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitude = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
@ -101,14 +100,14 @@ galileo_pcps_8ms_acquisition_cc::~galileo_pcps_8ms_acquisition_cc()
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_code_A);
|
||||
free(d_fft_code_B);
|
||||
free(d_magnitude);
|
||||
volk_free(d_fft_code_A);
|
||||
volk_free(d_fft_code_B);
|
||||
volk_free(d_magnitude);
|
||||
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
@ -121,37 +120,23 @@ galileo_pcps_8ms_acquisition_cc::~galileo_pcps_8ms_acquisition_cc()
|
||||
|
||||
void galileo_pcps_8ms_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
{
|
||||
// code A: two replicas of a primary code
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size);
|
||||
// code A: two replicas of a primary code
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size);
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_code_A, d_fft_if->get_outbuf(), d_fft_size);
|
||||
|
||||
// code B: two replicas of a primary code; the second replica is inverted.
|
||||
volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[d_samples_per_code],
|
||||
&code[d_samples_per_code], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
volk_32fc_s32fc_multiply_32fc(&(d_fft_if->get_inbuf())[d_samples_per_code],
|
||||
&code[d_samples_per_code], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_code_B, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
|
||||
void galileo_pcps_8ms_acquisition_cc::init()
|
||||
@ -173,12 +158,10 @@ void galileo_pcps_8ms_acquisition_cc::init()
|
||||
|
||||
// Create the carrier Doppler wipeoff signals
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index=0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
int doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in, d_fft_size);
|
||||
}
|
||||
@ -241,18 +224,18 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
|
||||
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 /= (float)d_fft_size;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in,
|
||||
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)
|
||||
@ -262,15 +245,15 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
||||
// with the local FFT'd code A reference using SIMD operations with
|
||||
// VOLK library
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_A, d_fft_size);
|
||||
|
||||
// compute the inverse FFT
|
||||
d_ifft->execute();
|
||||
|
||||
// Search maximum
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_A, d_magnitude, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_A, d_magnitude, d_fft_size);
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt_A = d_magnitude[indext_A] / (fft_normalization_factor * fft_normalization_factor);
|
||||
@ -278,15 +261,15 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
||||
// with the local FFT'd code B reference using SIMD operations with
|
||||
// VOLK library
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_B, d_fft_size);
|
||||
|
||||
// compute the inverse FFT
|
||||
d_ifft->execute();
|
||||
|
||||
// Search maximum
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_B, d_magnitude, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_B, d_magnitude, d_fft_size);
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt_B = d_magnitude[indext_B] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
@ -86,9 +86,8 @@ pcps_acquisition_cc::pcps_acquisition_cc(
|
||||
d_num_doppler_bins = 0;
|
||||
d_bit_transition_flag = bit_transition_flag;
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_codes = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitude = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
@ -107,13 +106,13 @@ pcps_acquisition_cc::~pcps_acquisition_cc()
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_codes);
|
||||
free(d_magnitude);
|
||||
volk_free(d_fft_codes);
|
||||
volk_free(d_magnitude);
|
||||
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
@ -126,19 +125,9 @@ pcps_acquisition_cc::~pcps_acquisition_cc()
|
||||
|
||||
void pcps_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
{
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size);
|
||||
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_fft_size);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_codes,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
|
||||
void pcps_acquisition_cc::init()
|
||||
@ -160,14 +149,12 @@ void pcps_acquisition_cc::init()
|
||||
|
||||
// Create the carrier Doppler wipeoff signals
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in, d_fft_size);
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step * doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], d_freq + doppler, d_fs_in, d_fft_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,18 +221,18 @@ int pcps_acquisition_cc::general_work(int noutput_items,
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
|
||||
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 /= (float)d_fft_size;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index=0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
doppler = -(int)d_doppler_max + d_doppler_step * doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in,
|
||||
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)
|
||||
@ -254,15 +241,15 @@ int pcps_acquisition_cc::general_work(int noutput_items,
|
||||
|
||||
// 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_a(d_ifft->get_inbuf(),
|
||||
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
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitude, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitude, d_fft_size);
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
@ -46,96 +46,94 @@
|
||||
using google::LogMessage;
|
||||
|
||||
pcps_acquisition_fine_doppler_cc_sptr pcps_make_acquisition_fine_doppler_cc(
|
||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min, long freq,
|
||||
long fs_in, int samples_per_ms, boost::shared_ptr<gr::msg_queue> queue, bool dump,
|
||||
std::string dump_filename)
|
||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min, long freq,
|
||||
long fs_in, int samples_per_ms, boost::shared_ptr<gr::msg_queue> queue, bool dump,
|
||||
std::string dump_filename)
|
||||
{
|
||||
|
||||
return pcps_acquisition_fine_doppler_cc_sptr(
|
||||
new pcps_acquisition_fine_doppler_cc(max_dwells, sampled_ms, doppler_max, doppler_min, freq,
|
||||
fs_in, samples_per_ms, queue, dump, dump_filename));
|
||||
return pcps_acquisition_fine_doppler_cc_sptr(
|
||||
new pcps_acquisition_fine_doppler_cc(max_dwells, sampled_ms, doppler_max, doppler_min, freq,
|
||||
fs_in, samples_per_ms, queue, dump, dump_filename));
|
||||
}
|
||||
|
||||
|
||||
|
||||
pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(
|
||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min, long freq,
|
||||
long fs_in, int samples_per_ms, boost::shared_ptr<gr::msg_queue> queue, bool dump,
|
||||
std::string dump_filename) :
|
||||
gr::block("pcps_acquisition_fine_doppler_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min, long freq,
|
||||
long fs_in, int samples_per_ms, boost::shared_ptr<gr::msg_queue> queue, bool dump,
|
||||
std::string dump_filename) :
|
||||
gr::block("pcps_acquisition_fine_doppler_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
||||
{
|
||||
d_sample_counter = 0; // SAMPLE COUNTER
|
||||
d_active = false;
|
||||
d_queue = queue;
|
||||
d_freq = freq;
|
||||
d_fs_in = fs_in;
|
||||
d_samples_per_ms = samples_per_ms;
|
||||
d_sampled_ms = sampled_ms;
|
||||
d_config_doppler_max = doppler_max;
|
||||
d_config_doppler_min=doppler_min;
|
||||
d_fft_size = d_sampled_ms * d_samples_per_ms;
|
||||
// HS Acquisition
|
||||
d_max_dwells= max_dwells;
|
||||
d_gnuradio_forecast_samples=d_fft_size;
|
||||
d_input_power = 0.0;
|
||||
d_state=0;
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_carrier, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_sample_counter = 0; // SAMPLE COUNTER
|
||||
d_active = false;
|
||||
d_queue = queue;
|
||||
d_freq = freq;
|
||||
d_fs_in = fs_in;
|
||||
d_samples_per_ms = samples_per_ms;
|
||||
d_sampled_ms = sampled_ms;
|
||||
d_config_doppler_max = doppler_max;
|
||||
d_config_doppler_min = doppler_min;
|
||||
d_fft_size = d_sampled_ms * d_samples_per_ms;
|
||||
// HS Acquisition
|
||||
d_max_dwells = max_dwells;
|
||||
d_gnuradio_forecast_samples = d_fft_size;
|
||||
d_input_power = 0.0;
|
||||
d_state = 0;
|
||||
d_carrier = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_fft_codes = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitude = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
|
||||
// Inverse FFT
|
||||
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
||||
// Inverse FFT
|
||||
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
||||
|
||||
// For dumping samples into a file
|
||||
d_dump = dump;
|
||||
d_dump_filename = dump_filename;
|
||||
// For dumping samples into a file
|
||||
d_dump = dump;
|
||||
d_dump_filename = dump_filename;
|
||||
}
|
||||
|
||||
void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
d_doppler_step = doppler_step;
|
||||
// Create the search grid array
|
||||
d_doppler_step = doppler_step;
|
||||
// Create the search grid array
|
||||
|
||||
d_num_doppler_points=floor(std::abs(d_config_doppler_max-d_config_doppler_min)/d_doppler_step);
|
||||
|
||||
d_grid_data=new float*[d_num_doppler_points];
|
||||
for (int i=0;i<d_num_doppler_points;i++)
|
||||
{
|
||||
if (posix_memalign((void**)&d_grid_data[i], 16, d_fft_size * sizeof(float)) == 0){};
|
||||
|
||||
}
|
||||
|
||||
update_carrier_wipeoff();
|
||||
d_num_doppler_points = floor(std::abs(d_config_doppler_max - d_config_doppler_min) / d_doppler_step);
|
||||
|
||||
d_grid_data = new float*[d_num_doppler_points];
|
||||
for (int i = 0; i < d_num_doppler_points; i++)
|
||||
{
|
||||
d_grid_data[i] = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
}
|
||||
update_carrier_wipeoff();
|
||||
}
|
||||
|
||||
void pcps_acquisition_fine_doppler_cc::free_grid_memory()
|
||||
{
|
||||
for (int i=0;i<d_num_doppler_points;i++)
|
||||
{
|
||||
delete[] d_grid_data[i];
|
||||
delete[] d_grid_doppler_wipeoffs[i];
|
||||
}
|
||||
delete d_grid_data;
|
||||
delete d_grid_doppler_wipeoffs;
|
||||
for (int i = 0; i < d_num_doppler_points; i++)
|
||||
{
|
||||
volk_free(d_grid_data[i]);
|
||||
delete[] d_grid_doppler_wipeoffs[i];
|
||||
}
|
||||
delete d_grid_data;
|
||||
delete d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
pcps_acquisition_fine_doppler_cc::~pcps_acquisition_fine_doppler_cc()
|
||||
{
|
||||
free(d_carrier);
|
||||
free(d_fft_codes);
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
free_grid_memory();
|
||||
volk_free(d_carrier);
|
||||
volk_free(d_fft_codes);
|
||||
volk_free(d_magnitude);
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
free_grid_memory();
|
||||
}
|
||||
|
||||
|
||||
@ -143,378 +141,370 @@ pcps_acquisition_fine_doppler_cc::~pcps_acquisition_fine_doppler_cc()
|
||||
void pcps_acquisition_fine_doppler_cc::set_local_code(std::complex<float> * code)
|
||||
{
|
||||
|
||||
memcpy(d_fft_if->get_inbuf(),code,sizeof(gr_complex)*d_fft_size);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
//Conjugate the local code
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes,d_fft_if->get_outbuf(),d_fft_size);
|
||||
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_fft_size);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
//Conjugate the local code
|
||||
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
|
||||
void pcps_acquisition_fine_doppler_cc::init()
|
||||
{
|
||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||
d_input_power = 0.0;
|
||||
d_state=0;
|
||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||
d_input_power = 0.0;
|
||||
d_state = 0;
|
||||
|
||||
}
|
||||
|
||||
void pcps_acquisition_fine_doppler_cc::forecast (int noutput_items,
|
||||
gr_vector_int &ninput_items_required)
|
||||
gr_vector_int &ninput_items_required)
|
||||
{
|
||||
ninput_items_required[0] = d_gnuradio_forecast_samples ; //set the required available samples in each call
|
||||
ninput_items_required[0] = d_gnuradio_forecast_samples ; //set the required available samples in each call
|
||||
}
|
||||
|
||||
|
||||
void pcps_acquisition_fine_doppler_cc::reset_grid()
|
||||
{
|
||||
d_well_count=0;
|
||||
for (int i=0;i<d_num_doppler_points;i++)
|
||||
{
|
||||
for (unsigned int j=0;j<d_fft_size;j++)
|
||||
{
|
||||
d_grid_data[i][j]=0.0;
|
||||
}
|
||||
}
|
||||
d_well_count = 0;
|
||||
for (int i=0; i<d_num_doppler_points; i++)
|
||||
{
|
||||
for (unsigned int j=0; j < d_fft_size; j++)
|
||||
{
|
||||
d_grid_data[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff()
|
||||
{
|
||||
// create the carrier Doppler wipeoff signals
|
||||
int doppler_hz;
|
||||
// create the carrier Doppler wipeoff signals
|
||||
int doppler_hz;
|
||||
float phase_step_rad;
|
||||
d_grid_doppler_wipeoffs=new gr_complex*[d_num_doppler_points];
|
||||
for (int doppler_index=0;doppler_index<d_num_doppler_points;doppler_index++)
|
||||
{
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_points];
|
||||
for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++)
|
||||
{
|
||||
|
||||
doppler_hz=d_config_doppler_min+d_doppler_step*doppler_index;
|
||||
// doppler search steps
|
||||
// compute the carrier doppler wipe-off signal and store it
|
||||
phase_step_rad = (float)GPS_TWO_PI*doppler_hz / (float)d_fs_in;
|
||||
|
||||
d_grid_doppler_wipeoffs[doppler_index]=new gr_complex[d_fft_size];
|
||||
fxp_nco(d_grid_doppler_wipeoffs[doppler_index], d_fft_size,0, phase_step_rad);
|
||||
}
|
||||
doppler_hz = d_config_doppler_min + d_doppler_step*doppler_index;
|
||||
// doppler search steps
|
||||
// compute the carrier doppler wipe-off signal and store it
|
||||
phase_step_rad = (float)GPS_TWO_PI*doppler_hz / (float)d_fs_in;
|
||||
d_grid_doppler_wipeoffs[doppler_index] = new gr_complex[d_fft_size];
|
||||
fxp_nco(d_grid_doppler_wipeoffs[doppler_index], d_fft_size,0, phase_step_rad);
|
||||
}
|
||||
}
|
||||
|
||||
double pcps_acquisition_fine_doppler_cc::search_maximum()
|
||||
{
|
||||
float magt = 0.0;
|
||||
float fft_normalization_factor;
|
||||
int index_doppler = 0;
|
||||
unsigned int tmp_intex_t;
|
||||
unsigned int index_time = 0;
|
||||
float magt = 0.0;
|
||||
float fft_normalization_factor;
|
||||
int index_doppler = 0;
|
||||
unsigned int tmp_intex_t;
|
||||
unsigned int index_time = 0;
|
||||
|
||||
for (int i=0;i<d_num_doppler_points;i++)
|
||||
{
|
||||
volk_32f_index_max_16u_a(&tmp_intex_t,d_grid_data[i],d_fft_size);
|
||||
if (d_grid_data[i][tmp_intex_t] > magt)
|
||||
{
|
||||
magt = d_grid_data[i][tmp_intex_t];
|
||||
//std::cout<<magt<<std::endl;
|
||||
index_doppler = i;
|
||||
index_time = tmp_intex_t;
|
||||
}
|
||||
}
|
||||
for (int i=0;i<d_num_doppler_points;i++)
|
||||
{
|
||||
volk_32f_index_max_16u(&tmp_intex_t, d_grid_data[i], d_fft_size);
|
||||
if (d_grid_data[i][tmp_intex_t] > magt)
|
||||
{
|
||||
magt = d_grid_data[i][tmp_intex_t];
|
||||
//std::cout<<magt<<std::endl;
|
||||
index_doppler = i;
|
||||
index_time = tmp_intex_t;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;;
|
||||
magt = magt / (fft_normalization_factor * fft_normalization_factor);
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;;
|
||||
magt = magt / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
// 5- Compute the test statistics and compare to the threshold
|
||||
d_test_statistics = magt/(d_input_power*std::sqrt(d_well_count));
|
||||
// 5- Compute the test statistics and compare to the threshold
|
||||
d_test_statistics = magt/(d_input_power*std::sqrt(d_well_count));
|
||||
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
d_gnss_synchro->Acq_delay_samples = (double)index_time;
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)(index_doppler*d_doppler_step+d_config_doppler_min);
|
||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
d_gnss_synchro->Acq_delay_samples = (double)index_time;
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)(index_doppler * d_doppler_step + d_config_doppler_min);
|
||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||
|
||||
// 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("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << d_gnss_synchro->Acq_doppler_hz << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
| std::ios::binary);
|
||||
d_dump_file.write((char*)d_grid_data[index_doppler], n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
}
|
||||
// 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("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << d_gnss_synchro->Acq_doppler_hz << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
| std::ios::binary);
|
||||
d_dump_file.write((char*)d_grid_data[index_doppler], n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
return d_test_statistics;
|
||||
return d_test_statistics;
|
||||
}
|
||||
|
||||
float pcps_acquisition_fine_doppler_cc::estimate_input_power(gr_vector_const_void_star &input_items)
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
// 1- Compute the input signal power estimation
|
||||
float power;
|
||||
power=0;
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_magnitude_squared_32f_u(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&power, d_magnitude, d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&power, d_magnitude, d_fft_size);
|
||||
}
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
// Compute the input signal power estimation
|
||||
float power = 0;
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f(&power, d_magnitude, d_fft_size);
|
||||
power /= (float)d_fft_size;
|
||||
return power;
|
||||
|
||||
}
|
||||
|
||||
int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_const_void_star &input_items)
|
||||
{
|
||||
// initialize acquisition algorithm
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
// initialize acquisition algorithm
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
|
||||
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_config_doppler_max
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
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_config_doppler_max
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
float* p_tmp_vector;
|
||||
if (posix_memalign((void**)&p_tmp_vector, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
// 2- Doppler frequency search loop
|
||||
float* p_tmp_vector = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
for (int doppler_index=0;doppler_index<d_num_doppler_points;doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
// Perform the carrier wipe-off
|
||||
volk_32fc_x2_multiply_32fc_u(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();
|
||||
for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
// Perform the carrier wipe-off
|
||||
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_a(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||
// 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();
|
||||
// compute the inverse FFT
|
||||
d_ifft->execute();
|
||||
|
||||
// save the grid matrix delay file
|
||||
// save the grid matrix delay file
|
||||
|
||||
volk_32fc_magnitude_squared_32f_a(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size);
|
||||
const float* old_vector=d_grid_data[doppler_index];
|
||||
volk_32f_x2_add_32f_u(d_grid_data[doppler_index],old_vector,p_tmp_vector,d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size);
|
||||
const float* old_vector = d_grid_data[doppler_index];
|
||||
volk_32f_x2_add_32f(d_grid_data[doppler_index], old_vector, p_tmp_vector, d_fft_size);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
free(p_tmp_vector);
|
||||
return d_fft_size;
|
||||
volk_free(p_tmp_vector);
|
||||
return d_fft_size;
|
||||
}
|
||||
|
||||
int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star &input_items, int available_samples)
|
||||
{
|
||||
|
||||
// Direct FFT
|
||||
int zero_padding_factor=16;
|
||||
int fft_size_extended=d_fft_size*zero_padding_factor;
|
||||
gr::fft::fft_complex *fft_operator=new gr::fft::fft_complex(fft_size_extended,true);
|
||||
//zero padding the entire vector
|
||||
memset(fft_operator->get_inbuf(),0,fft_size_extended*sizeof(gr_complex));
|
||||
// Direct FFT
|
||||
int zero_padding_factor = 16;
|
||||
int fft_size_extended = d_fft_size * zero_padding_factor;
|
||||
gr::fft::fft_complex *fft_operator = new gr::fft::fft_complex(fft_size_extended, true);
|
||||
//zero padding the entire vector
|
||||
memset(fft_operator->get_inbuf(), 0, fft_size_extended * sizeof(gr_complex));
|
||||
|
||||
//1. generate local code aligned with the acquisition code phase estimation
|
||||
gr_complex *code_replica;
|
||||
if (posix_memalign((void**)&code_replica, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
gps_l1_ca_code_gen_complex_sampled(code_replica, d_gnss_synchro->PRN, d_fs_in, 0);
|
||||
//1. generate local code aligned with the acquisition code phase estimation
|
||||
gr_complex *code_replica = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
int shift_index=(int)d_gnss_synchro->Acq_delay_samples;
|
||||
gps_l1_ca_code_gen_complex_sampled(code_replica, d_gnss_synchro->PRN, d_fs_in, 0);
|
||||
|
||||
//std::cout<<"shift_index="<<shift_index<<std::endl;
|
||||
// Rotate to align the local code replica using acquisition time delay estimation
|
||||
if (shift_index!=0)
|
||||
{
|
||||
std::rotate(code_replica,code_replica+(d_fft_size-shift_index),code_replica+d_fft_size-1);
|
||||
}
|
||||
int shift_index = (int)d_gnss_synchro->Acq_delay_samples;
|
||||
|
||||
//2. Perform code wipe-off
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
//std::cout<<"shift_index="<<shift_index<<std::endl;
|
||||
// Rotate to align the local code replica using acquisition time delay estimation
|
||||
if (shift_index != 0)
|
||||
{
|
||||
std::rotate(code_replica, code_replica + (d_fft_size - shift_index), code_replica + d_fft_size - 1);
|
||||
}
|
||||
|
||||
volk_32fc_x2_multiply_32fc_u(fft_operator->get_inbuf(), in, code_replica, d_fft_size);
|
||||
//2. Perform code wipe-off
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
|
||||
// 3. Perform the FFT (zero padded!)
|
||||
fft_operator->execute();
|
||||
volk_32fc_x2_multiply_32fc(fft_operator->get_inbuf(), in, code_replica, d_fft_size);
|
||||
|
||||
// 4. Compute the magnitude and find the maximum
|
||||
float* p_tmp_vector;
|
||||
if (posix_memalign((void**)&p_tmp_vector, 16, fft_size_extended * sizeof(float)) == 0){};
|
||||
// 3. Perform the FFT (zero padded!)
|
||||
fft_operator->execute();
|
||||
|
||||
volk_32fc_magnitude_squared_32f_a(p_tmp_vector, fft_operator->get_outbuf(), fft_size_extended);
|
||||
// 4. Compute the magnitude and find the maximum
|
||||
float* p_tmp_vector = (float*)volk_malloc(fft_size_extended * sizeof(float), volk_get_alignment());
|
||||
|
||||
unsigned int tmp_index_freq=0;
|
||||
volk_32f_index_max_16u_a(&tmp_index_freq,p_tmp_vector,fft_size_extended);
|
||||
volk_32fc_magnitude_squared_32f(p_tmp_vector, fft_operator->get_outbuf(), fft_size_extended);
|
||||
|
||||
//std::cout<<"FFT maximum index present at "<<tmp_index_freq<<std::endl;
|
||||
unsigned int tmp_index_freq = 0;
|
||||
volk_32f_index_max_16u(&tmp_index_freq,p_tmp_vector,fft_size_extended);
|
||||
|
||||
//case even
|
||||
int counter=0;
|
||||
//std::cout<<"FFT maximum index present at "<<tmp_index_freq<<std::endl;
|
||||
|
||||
float fftFreqBins[fft_size_extended];
|
||||
//case even
|
||||
int counter = 0;
|
||||
|
||||
for (int k=0;k<(fft_size_extended/2);k++)
|
||||
{
|
||||
fftFreqBins[counter]=(((float)d_fs_in/2.0)*(float)k)/((float)fft_size_extended/2.0);
|
||||
counter++;
|
||||
}
|
||||
float fftFreqBins[fft_size_extended];
|
||||
|
||||
for (int k=fft_size_extended/2;k>0;k--)
|
||||
{
|
||||
fftFreqBins[counter]=((-(float)d_fs_in/2)*(float)k)/((float)fft_size_extended/2.0);
|
||||
counter++;
|
||||
}
|
||||
for (int k=0; k < (fft_size_extended / 2); k++)
|
||||
{
|
||||
fftFreqBins[counter] = (((float)d_fs_in / 2.0) * (float)k) / ((float)fft_size_extended / 2.0);
|
||||
counter++;
|
||||
}
|
||||
|
||||
// 5. Update the Doppler estimation in Hz
|
||||
if (abs(fftFreqBins[tmp_index_freq]-d_gnss_synchro->Acq_doppler_hz)<1000)
|
||||
{
|
||||
d_gnss_synchro->Acq_doppler_hz=(double)fftFreqBins[tmp_index_freq];
|
||||
//std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl;
|
||||
}else{
|
||||
DLOG(INFO)<<"Abs(Grid Doppler - FFT Doppler)="<<abs(fftFreqBins[tmp_index_freq]-d_gnss_synchro->Acq_doppler_hz)<<std::endl;
|
||||
DLOG(INFO)<<std::endl<<"Error estimating fine frequency Doppler"<<std::endl;
|
||||
//debug log
|
||||
//
|
||||
// std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl;
|
||||
// std::stringstream filename;
|
||||
// std::streamsize n = sizeof(gr_complex) * (d_fft_size);
|
||||
//
|
||||
// filename.str("");
|
||||
// filename << "../data/code_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write((char*)code_replica, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
//
|
||||
// filename.str("");
|
||||
// filename << "../data/signal_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write((char*)in, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
//
|
||||
//
|
||||
// n = sizeof(float) * (fft_size_extended);
|
||||
// filename.str("");
|
||||
// filename << "../data/fft_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write((char*)p_tmp_vector, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
}
|
||||
for (int k = fft_size_extended / 2; k > 0; k--)
|
||||
{
|
||||
fftFreqBins[counter] = ((-(float)d_fs_in / 2) * (float)k) / ((float)fft_size_extended / 2.0);
|
||||
counter++;
|
||||
}
|
||||
|
||||
// 5. Update the Doppler estimation in Hz
|
||||
if (abs(fftFreqBins[tmp_index_freq] - d_gnss_synchro->Acq_doppler_hz) < 1000)
|
||||
{
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)fftFreqBins[tmp_index_freq];
|
||||
//std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
DLOG(INFO) << "Abs(Grid Doppler - FFT Doppler)=" << abs(fftFreqBins[tmp_index_freq] - d_gnss_synchro->Acq_doppler_hz);
|
||||
DLOG(INFO) << "Error estimating fine frequency Doppler";
|
||||
//debug log
|
||||
//
|
||||
// std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl;
|
||||
// std::stringstream filename;
|
||||
// std::streamsize n = sizeof(gr_complex) * (d_fft_size);
|
||||
//
|
||||
// filename.str("");
|
||||
// filename << "../data/code_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write((char*)code_replica, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
//
|
||||
// filename.str("");
|
||||
// filename << "../data/signal_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write((char*)in, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
//
|
||||
//
|
||||
// n = sizeof(float) * (fft_size_extended);
|
||||
// filename.str("");
|
||||
// filename << "../data/fft_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write((char*)p_tmp_vector, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
}
|
||||
|
||||
|
||||
// free memory!!
|
||||
delete fft_operator;
|
||||
free(code_replica);
|
||||
free(p_tmp_vector);
|
||||
return d_fft_size;
|
||||
// free memory!!
|
||||
delete fft_operator;
|
||||
volk_free(code_replica);
|
||||
volk_free(p_tmp_vector);
|
||||
return d_fft_size;
|
||||
}
|
||||
|
||||
|
||||
int pcps_acquisition_fine_doppler_cc::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_int &ninput_items, gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
|
||||
/*!
|
||||
* TODO: High sensitivity acquisition algorithm:
|
||||
* State Mechine:
|
||||
* S0. StandBy. If d_active==1 -> S1
|
||||
* S1. ComputeGrid. Perform the FFT acqusition doppler and delay grid.
|
||||
* Accumulate the search grid matrix (#doppler_bins x #fft_size)
|
||||
* Compare maximum to threshold and decide positive or negative
|
||||
* If T>=gamma -> S4 else
|
||||
* If d_well_count<max_dwells -> S2
|
||||
* else -> S5.
|
||||
* S4. Positive_Acq: Send message and stop acq -> S0
|
||||
* S5. Negative_Acq: Send message and stop acq -> S0
|
||||
*/
|
||||
/*!
|
||||
* TODO: High sensitivity acquisition algorithm:
|
||||
* State Mechine:
|
||||
* S0. StandBy. If d_active==1 -> S1
|
||||
* S1. ComputeGrid. Perform the FFT acqusition doppler and delay grid.
|
||||
* Accumulate the search grid matrix (#doppler_bins x #fft_size)
|
||||
* Compare maximum to threshold and decide positive or negative
|
||||
* If T>=gamma -> S4 else
|
||||
* If d_well_count<max_dwells -> S2
|
||||
* else -> S5.
|
||||
* S4. Positive_Acq: Send message and stop acq -> S0
|
||||
* S5. Negative_Acq: Send message and stop acq -> S0
|
||||
*/
|
||||
|
||||
switch (d_state)
|
||||
{
|
||||
case 0: // S0. StandBy
|
||||
//DLOG(INFO) <<"S0"<<std::endl;
|
||||
if (d_active==true)
|
||||
{
|
||||
reset_grid();
|
||||
d_state=1;
|
||||
}
|
||||
break;
|
||||
case 1: // S1. ComputeGrid
|
||||
//DLOG(INFO) <<"S1"<<std::endl;
|
||||
compute_and_accumulate_grid(input_items);
|
||||
d_well_count++;
|
||||
if (d_well_count>=d_max_dwells)
|
||||
{
|
||||
d_state=2;
|
||||
}
|
||||
break;
|
||||
case 2: // Compute test statistics and decide
|
||||
//DLOG(INFO) <<"S2"<<std::endl;
|
||||
d_input_power=estimate_input_power(input_items);
|
||||
d_test_statistics=search_maximum();
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state=3; //perform fine doppler estimation
|
||||
}else{
|
||||
d_state=5; //negative acquisition
|
||||
}
|
||||
break;
|
||||
switch (d_state)
|
||||
{
|
||||
case 0: // S0. StandBy
|
||||
//DLOG(INFO) <<"S0"<<std::endl;
|
||||
if (d_active == true)
|
||||
{
|
||||
reset_grid();
|
||||
d_state = 1;
|
||||
}
|
||||
break;
|
||||
case 1: // S1. ComputeGrid
|
||||
//DLOG(INFO) <<"S1"<<std::endl;
|
||||
compute_and_accumulate_grid(input_items);
|
||||
d_well_count++;
|
||||
if (d_well_count >= d_max_dwells)
|
||||
{
|
||||
d_state = 2;
|
||||
}
|
||||
break;
|
||||
case 2: // Compute test statistics and decide
|
||||
//DLOG(INFO) <<"S2"<<std::endl;
|
||||
d_input_power = estimate_input_power(input_items);
|
||||
d_test_statistics = search_maximum();
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 3; //perform fine doppler estimation
|
||||
}
|
||||
else
|
||||
{
|
||||
d_state = 5; //negative acquisition
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case 3: // Fine doppler estimation
|
||||
//DLOG(INFO) <<"S3"<<std::endl;
|
||||
DLOG(INFO) << "Performing fine Doppler estimation";
|
||||
estimate_Doppler(input_items, ninput_items[0]); //disabled in repo
|
||||
d_state=4;
|
||||
break;
|
||||
case 4: // Positive_Acq
|
||||
//DLOG(INFO) <<"S4"<<std::endl;
|
||||
DLOG(INFO) << "positive acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
case 3: // Fine doppler estimation
|
||||
//DLOG(INFO) <<"S3"<<std::endl;
|
||||
DLOG(INFO) << "Performing fine Doppler estimation";
|
||||
estimate_Doppler(input_items, ninput_items[0]); //disabled in repo
|
||||
d_state = 4;
|
||||
break;
|
||||
case 4: // Positive_Acq
|
||||
//DLOG(INFO) <<"S4"<<std::endl;
|
||||
DLOG(INFO) << "positive acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
// Send message to channel queue //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
d_channel_internal_queue->push(1); // 1-> positive acquisition
|
||||
d_state=0;
|
||||
break;
|
||||
case 5: // Negative_Acq
|
||||
//DLOG(INFO) <<"S5"<<std::endl;
|
||||
DLOG(INFO) << "negative acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
d_active = false;
|
||||
// Send message to channel queue //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
d_channel_internal_queue->push(1); // 1-> positive acquisition
|
||||
d_state = 0;
|
||||
break;
|
||||
case 5: // Negative_Acq
|
||||
//DLOG(INFO) <<"S5"<<std::endl;
|
||||
DLOG(INFO) << "negative acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
// Send message to channel queue //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
d_channel_internal_queue->push(2); // 2-> negative acquisition
|
||||
d_state=0;
|
||||
break;
|
||||
default:
|
||||
d_state=0;
|
||||
break;
|
||||
}
|
||||
d_active = false;
|
||||
// Send message to channel queue //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
d_channel_internal_queue->push(2); // 2-> negative acquisition
|
||||
d_state = 0;
|
||||
break;
|
||||
default:
|
||||
d_state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//DLOG(INFO)<<"d_sample_counter="<<d_sample_counter<<std::endl;
|
||||
d_sample_counter += d_fft_size; // sample counter
|
||||
consume_each(d_fft_size);
|
||||
return 0;
|
||||
//DLOG(INFO)<<"d_sample_counter="<<d_sample_counter<<std::endl;
|
||||
d_sample_counter += d_fft_size; // sample counter
|
||||
consume_each(d_fft_size);
|
||||
return 0;
|
||||
}
|
||||
|
@ -82,9 +82,8 @@ pcps_assisted_acquisition_cc::pcps_assisted_acquisition_cc(
|
||||
d_input_power = 0.0;
|
||||
d_state = 0;
|
||||
d_disable_assist = false;
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_carrier, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
d_fft_codes = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_carrier = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
@ -120,8 +119,8 @@ void pcps_assisted_acquisition_cc::free_grid_memory()
|
||||
|
||||
pcps_assisted_acquisition_cc::~pcps_assisted_acquisition_cc()
|
||||
{
|
||||
free(d_carrier);
|
||||
free(d_fft_codes);
|
||||
volk_free(d_carrier);
|
||||
volk_free(d_fft_codes);
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
if (d_dump)
|
||||
@ -150,7 +149,7 @@ void pcps_assisted_acquisition_cc::init()
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
|
||||
|
||||
@ -214,7 +213,7 @@ void pcps_assisted_acquisition_cc::redefine_grid()
|
||||
d_doppler_min = d_config_doppler_min;
|
||||
}
|
||||
// Create the search grid array
|
||||
d_num_doppler_points = floor(std::abs(d_doppler_max-d_doppler_min)/d_doppler_step);
|
||||
d_num_doppler_points = floor(std::abs(d_doppler_max - d_doppler_min) / d_doppler_step);
|
||||
|
||||
d_grid_data = new float*[d_num_doppler_points];
|
||||
for (int i = 0; i < d_num_doppler_points; i++)
|
||||
@ -293,14 +292,14 @@ float pcps_assisted_acquisition_cc::estimate_input_power(gr_vector_const_void_st
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
// 1- Compute the input signal power estimation
|
||||
float* p_tmp_vector;
|
||||
if (posix_memalign((void**)&p_tmp_vector, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
volk_32fc_magnitude_squared_32f_u(p_tmp_vector, in, d_fft_size);
|
||||
float* p_tmp_vector = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
volk_32fc_magnitude_squared_32f(p_tmp_vector, in, d_fft_size);
|
||||
|
||||
const float* p_const_tmp_vector = p_tmp_vector;
|
||||
float power;
|
||||
volk_32f_accumulator_s32f_a(&power, p_const_tmp_vector, d_fft_size);
|
||||
free(p_tmp_vector);
|
||||
volk_32f_accumulator_s32f(&power, p_const_tmp_vector, d_fft_size);
|
||||
volk_free(p_tmp_vector);
|
||||
return ( power / (float)d_fft_size);
|
||||
}
|
||||
|
||||
@ -319,33 +318,35 @@ int pcps_assisted_acquisition_cc::compute_and_accumulate_grid(gr_vector_const_vo
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
float* p_tmp_vector;
|
||||
if (posix_memalign((void**)&p_tmp_vector, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
float* p_tmp_vector = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
// Perform the carrier wipe-off
|
||||
volk_32fc_x2_multiply_32fc_u(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
||||
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_a(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||
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();
|
||||
|
||||
// save the grid matrix delay file
|
||||
volk_32fc_magnitude_squared_32f_a(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size);
|
||||
const float* old_vector = d_grid_data[doppler_index];
|
||||
volk_32f_x2_add_32f_a(d_grid_data[doppler_index], old_vector, p_tmp_vector, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size);
|
||||
const float* old_vector = d_grid_data[doppler_index];
|
||||
volk_32f_x2_add_32f(d_grid_data[doppler_index], old_vector, p_tmp_vector, d_fft_size);
|
||||
}
|
||||
free(p_tmp_vector);
|
||||
volk_free(p_tmp_vector);
|
||||
return d_fft_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pcps_assisted_acquisition_cc::general_work(int noutput_items,
|
||||
gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
|
@ -86,14 +86,13 @@ pcps_cccwsr_acquisition_cc::pcps_cccwsr_acquisition_cc(
|
||||
d_input_power = 0.0;
|
||||
d_num_doppler_bins = 0;
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_fft_code_data, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_fft_code_pilot, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_data_correlation, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_pilot_correlation, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_correlation_plus, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_correlation_minus, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_code_data = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_fft_code_pilot = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_data_correlation = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_pilot_correlation = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_correlation_plus = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_correlation_minus = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitude = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
@ -112,18 +111,18 @@ pcps_cccwsr_acquisition_cc::~pcps_cccwsr_acquisition_cc()
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_code_data);
|
||||
free(d_fft_code_pilot);
|
||||
free(d_data_correlation);
|
||||
free(d_pilot_correlation);
|
||||
free(d_correlation_plus);
|
||||
free(d_correlation_minus);
|
||||
free(d_magnitude);
|
||||
volk_free(d_fft_code_data);
|
||||
volk_free(d_fft_code_pilot);
|
||||
volk_free(d_data_correlation);
|
||||
volk_free(d_pilot_correlation);
|
||||
volk_free(d_correlation_plus);
|
||||
volk_free(d_correlation_minus);
|
||||
volk_free(d_magnitude);
|
||||
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
@ -134,8 +133,8 @@ pcps_cccwsr_acquisition_cc::~pcps_cccwsr_acquisition_cc()
|
||||
}
|
||||
}
|
||||
|
||||
void pcps_cccwsr_acquisition_cc::set_local_code(std::complex<float> * code_data,
|
||||
std::complex<float> * code_pilot)
|
||||
void pcps_cccwsr_acquisition_cc::set_local_code(std::complex<float>* code_data,
|
||||
std::complex<float>* code_pilot)
|
||||
{
|
||||
// Data code (E1B)
|
||||
memcpy(d_fft_if->get_inbuf(), code_data, sizeof(gr_complex)*d_fft_size);
|
||||
@ -143,14 +142,7 @@ void pcps_cccwsr_acquisition_cc::set_local_code(std::complex<float> * code_data,
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_data,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_data,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_code_data,d_fft_if->get_outbuf(),d_fft_size);
|
||||
|
||||
// Pilot code (E1C)
|
||||
memcpy(d_fft_if->get_inbuf(), code_pilot, sizeof(gr_complex)*d_fft_size);
|
||||
@ -158,14 +150,7 @@ void pcps_cccwsr_acquisition_cc::set_local_code(std::complex<float> * code_data,
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code,
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_pilot,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_pilot,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_code_pilot,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
|
||||
void pcps_cccwsr_acquisition_cc::init()
|
||||
@ -187,12 +172,11 @@ void pcps_cccwsr_acquisition_cc::init()
|
||||
|
||||
// Create the carrier Doppler wipeoff signals
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
int doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in, d_fft_size);
|
||||
}
|
||||
@ -252,18 +236,18 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
|
||||
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 /= (float)d_fft_size;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
doppler = -(int)d_doppler_max + d_doppler_step * doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in,
|
||||
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)
|
||||
@ -273,7 +257,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
||||
// with the local FFT'd data code reference (E1B) using SIMD operations
|
||||
// with VOLK library
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_data, d_fft_size);
|
||||
|
||||
// compute the inverse FFT
|
||||
@ -286,7 +270,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
||||
// with the local FFT'd pilot code reference (E1C) using SIMD operations
|
||||
// with VOLK library
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_pilot, d_fft_size);
|
||||
|
||||
// Compute the inverse FFT
|
||||
@ -307,12 +291,12 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
||||
d_data_correlation[i].imag() - d_pilot_correlation[i].real());
|
||||
}
|
||||
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_correlation_plus, d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_plus, d_magnitude, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_correlation_plus, d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_plus, d_magnitude, d_fft_size);
|
||||
magt_plus = d_magnitude[indext_plus] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_correlation_minus, d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_minus, d_magnitude, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_correlation_minus, d_fft_size);
|
||||
volk_32f_index_max_16u(&indext_minus, d_magnitude, d_fft_size);
|
||||
magt_minus = d_magnitude[indext_minus] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
if (magt_plus >= magt_minus)
|
||||
|
@ -92,12 +92,10 @@ pcps_multithread_acquisition_cc::pcps_multithread_acquisition_cc(
|
||||
//todo: do something if posix_memalign fails
|
||||
for (unsigned int i = 0; i < d_max_dwells; i++)
|
||||
{
|
||||
if (posix_memalign((void**)&d_in_buffer[i], 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
d_in_buffer[i] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
}
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_codes = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitude = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
@ -116,19 +114,19 @@ pcps_multithread_acquisition_cc::~pcps_multithread_acquisition_cc()
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < d_max_dwells; i++)
|
||||
{
|
||||
free(d_in_buffer[i]);
|
||||
volk_free(d_in_buffer[i]);
|
||||
}
|
||||
delete[] d_in_buffer;
|
||||
|
||||
free(d_fft_codes);
|
||||
free(d_magnitude);
|
||||
volk_free(d_fft_codes);
|
||||
volk_free(d_magnitude);
|
||||
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
@ -160,10 +158,9 @@ void pcps_multithread_acquisition_cc::init()
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
int doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in, d_fft_size);
|
||||
}
|
||||
@ -176,14 +173,7 @@ void pcps_multithread_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_codes,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
|
||||
void pcps_multithread_acquisition_cc::acquisition_core()
|
||||
@ -208,18 +198,18 @@ void pcps_multithread_acquisition_cc::acquisition_core()
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
|
||||
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 /= (float)d_fft_size;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in,
|
||||
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)
|
||||
@ -228,15 +218,15 @@ void pcps_multithread_acquisition_cc::acquisition_core()
|
||||
|
||||
// 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_a(d_ifft->get_inbuf(),
|
||||
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
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitude, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitude, d_fft_size);
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
@ -114,17 +114,13 @@ pcps_opencl_acquisition_cc::pcps_opencl_acquisition_cc(
|
||||
d_cl_fft_batch_size = 1;
|
||||
|
||||
d_in_buffer = new gr_complex*[d_max_dwells];
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
for (unsigned int i = 0; i < d_max_dwells; i++)
|
||||
{
|
||||
if (posix_memalign((void**)&d_in_buffer[i], 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
d_in_buffer[i] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
}
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size_pow2 * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_zero_vector, 16, (d_fft_size_pow2-d_fft_size) * sizeof(gr_complex)) == 0){};
|
||||
d_magnitude = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
d_fft_codes = (gr_complex*)volk_malloc(d_fft_size_pow2 * sizeof(gr_complex), volk_get_alignment());
|
||||
d_zero_vector = (gr_complex*)volk_malloc((d_fft_size_pow2 - d_fft_size) * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
for (unsigned int i = 0; i < (d_fft_size_pow2-d_fft_size); i++)
|
||||
{
|
||||
@ -156,20 +152,20 @@ pcps_opencl_acquisition_cc::~pcps_opencl_acquisition_cc()
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < d_max_dwells; i++)
|
||||
{
|
||||
free(d_in_buffer[i]);
|
||||
volk_free(d_in_buffer[i]);
|
||||
}
|
||||
delete[] d_in_buffer;
|
||||
|
||||
free(d_fft_codes);
|
||||
free(d_magnitude);
|
||||
free(d_zero_vector);
|
||||
volk_free(d_fft_codes);
|
||||
volk_free(d_magnitude);
|
||||
volk_free(d_zero_vector);
|
||||
|
||||
if (d_opencl == 0)
|
||||
{
|
||||
@ -318,8 +314,7 @@ void pcps_opencl_acquisition_cc::init()
|
||||
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
int doppler= -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
@ -347,44 +342,37 @@ void pcps_opencl_acquisition_cc::init()
|
||||
void pcps_opencl_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
{
|
||||
if(d_opencl == 0)
|
||||
{
|
||||
d_cl_queue->enqueueWriteBuffer(*d_cl_buffer_2, CL_TRUE, 0,
|
||||
sizeof(gr_complex)*d_fft_size, code);
|
||||
{
|
||||
d_cl_queue->enqueueWriteBuffer(*d_cl_buffer_2, CL_TRUE, 0,
|
||||
sizeof(gr_complex)*d_fft_size, code);
|
||||
|
||||
d_cl_queue->enqueueWriteBuffer(*d_cl_buffer_2, CL_TRUE, sizeof(gr_complex)*d_fft_size,
|
||||
sizeof(gr_complex)*(d_fft_size_pow2 - 2*d_fft_size),
|
||||
d_zero_vector);
|
||||
d_cl_queue->enqueueWriteBuffer(*d_cl_buffer_2, CL_TRUE, sizeof(gr_complex)*d_fft_size,
|
||||
sizeof(gr_complex)*(d_fft_size_pow2 - 2*d_fft_size),
|
||||
d_zero_vector);
|
||||
|
||||
d_cl_queue->enqueueWriteBuffer(*d_cl_buffer_2, CL_TRUE, sizeof(gr_complex)
|
||||
*(d_fft_size_pow2 - d_fft_size),
|
||||
sizeof(gr_complex)*d_fft_size, code);
|
||||
d_cl_queue->enqueueWriteBuffer(*d_cl_buffer_2, CL_TRUE, sizeof(gr_complex)
|
||||
*(d_fft_size_pow2 - d_fft_size),
|
||||
sizeof(gr_complex)*d_fft_size, code);
|
||||
|
||||
clFFT_ExecuteInterleaved((*d_cl_queue)(), d_cl_fft_plan, d_cl_fft_batch_size,
|
||||
clFFT_Forward, (*d_cl_buffer_2)(), (*d_cl_buffer_2)(),
|
||||
0, NULL, NULL);
|
||||
clFFT_ExecuteInterleaved((*d_cl_queue)(), d_cl_fft_plan, d_cl_fft_batch_size,
|
||||
clFFT_Forward, (*d_cl_buffer_2)(), (*d_cl_buffer_2)(),
|
||||
0, NULL, NULL);
|
||||
|
||||
//Conjucate the local code
|
||||
cl::Kernel kernel = cl::Kernel(d_cl_program, "conj_vector");
|
||||
kernel.setArg(0, *d_cl_buffer_2); //input
|
||||
kernel.setArg(1, *d_cl_buffer_fft_codes); //output
|
||||
d_cl_queue->enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(d_fft_size_pow2), cl::NullRange);
|
||||
}
|
||||
//Conjucate the local code
|
||||
cl::Kernel kernel = cl::Kernel(d_cl_program, "conj_vector");
|
||||
kernel.setArg(0, *d_cl_buffer_2); //input
|
||||
kernel.setArg(1, *d_cl_buffer_fft_codes); //output
|
||||
d_cl_queue->enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(d_fft_size_pow2), cl::NullRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size);
|
||||
{
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size);
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
}
|
||||
//Conjugate the local code
|
||||
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
}
|
||||
|
||||
void pcps_opencl_acquisition_cc::acquisition_core_volk()
|
||||
@ -409,19 +397,17 @@ void pcps_opencl_acquisition_cc::acquisition_core_volk()
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
|
||||
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 /= (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 = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in,
|
||||
|
||||
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)
|
||||
@ -430,15 +416,15 @@ void pcps_opencl_acquisition_cc::acquisition_core_volk()
|
||||
|
||||
// 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_a(d_ifft->get_inbuf(),
|
||||
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
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitude, d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitude, d_fft_size);
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
@ -543,8 +529,8 @@ void pcps_opencl_acquisition_cc::acquisition_core_opencl()
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
|
||||
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 /= (float)d_fft_size;
|
||||
|
||||
cl::Kernel kernel;
|
||||
@ -600,7 +586,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_opencl()
|
||||
|
||||
// Search maximum
|
||||
// @TODO: find an efficient way to search the maximum with OpenCL in the GPU.
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitude, d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitude, d_fft_size);
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
@ -70,9 +70,9 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename):
|
||||
gr::block("pcps_quicksync_acquisition_cc",
|
||||
gr::io_signature::make(1, 1, (sizeof(gr_complex)*sampled_ms * samples_per_ms )),
|
||||
gr::io_signature::make(0, 0, (sizeof(gr_complex)*sampled_ms * samples_per_ms )))
|
||||
gr::block("pcps_quicksync_acquisition_cc",
|
||||
gr::io_signature::make(1, 1, (sizeof(gr_complex)*sampled_ms * samples_per_ms )),
|
||||
gr::io_signature::make(0, 0, (sizeof(gr_complex)*sampled_ms * samples_per_ms )))
|
||||
{
|
||||
//DLOG(INFO) << "START CONSTRUCTOR";
|
||||
|
||||
@ -97,20 +97,17 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
|
||||
//fft size is reduced.
|
||||
d_fft_size = (d_samples_per_code) / d_folding_factor;
|
||||
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_samples_per_code * d_folding_factor * sizeof(float)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude_folded, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_codes = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitude = (float*)volk_malloc(d_samples_per_code * d_folding_factor * sizeof(float), volk_get_alignment());
|
||||
d_magnitude_folded = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
d_possible_delay = new unsigned int[d_folding_factor];
|
||||
d_corr_output_f = new float[d_folding_factor];
|
||||
d_corr_output_f = new float[d_folding_factor];
|
||||
|
||||
/*Create the d_code signal , which would store the values of the code in its
|
||||
original form to perform later correlation in time domain*/
|
||||
d_code = new gr_complex[d_samples_per_code]();
|
||||
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
// Inverse FFT
|
||||
@ -130,25 +127,20 @@ pcps_quicksync_acquisition_cc::~pcps_quicksync_acquisition_cc()
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_codes);
|
||||
free(d_magnitude);
|
||||
free(d_magnitude_folded);
|
||||
volk_free(d_fft_codes);
|
||||
volk_free(d_magnitude);
|
||||
volk_free(d_magnitude_folded);
|
||||
|
||||
delete d_ifft;
|
||||
d_ifft = NULL;
|
||||
delete d_fft_if;
|
||||
d_fft_if = NULL;
|
||||
delete d_code;
|
||||
d_code = NULL;
|
||||
delete d_possible_delay;
|
||||
d_possible_delay = NULL;
|
||||
delete d_corr_output_f;
|
||||
d_corr_output_f = NULL;
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
@ -156,11 +148,9 @@ pcps_quicksync_acquisition_cc::~pcps_quicksync_acquisition_cc()
|
||||
// DLOG(INFO) << "END DESTROYER";
|
||||
}
|
||||
|
||||
|
||||
void pcps_quicksync_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
{
|
||||
// DLOG(INFO) << "START LOCAL CODE";
|
||||
|
||||
|
||||
/*save a local copy of the code without the folding process to perform corre-
|
||||
lation in time in the final steps of the acquisition stage*/
|
||||
memcpy(d_code, code, sizeof(gr_complex)*d_samples_per_code);
|
||||
@ -182,16 +172,7 @@ void pcps_quicksync_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_codes,d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes,d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
// DLOG(INFO) << "END LOCAL CODE";
|
||||
|
||||
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
|
||||
void pcps_quicksync_acquisition_cc::init()
|
||||
@ -216,10 +197,8 @@ void pcps_quicksync_acquisition_cc::init()
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_samples_per_code * d_folding_factor * sizeof(gr_complex)) == 0){};
|
||||
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_samples_per_code * d_folding_factor * sizeof(gr_complex), volk_get_alignment());
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step * doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in,
|
||||
d_samples_per_code * d_folding_factor);
|
||||
@ -278,22 +257,16 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
float magt = 0.0;
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
|
||||
gr_complex *in_temp;
|
||||
if (posix_memalign((void**)&(in_temp), 16,d_samples_per_code * d_folding_factor * sizeof(gr_complex)) == 0){};
|
||||
|
||||
|
||||
gr_complex *in_temp_folded;
|
||||
if (posix_memalign((void**)&(in_temp_folded), 16,d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
gr_complex *in_temp = (gr_complex*)volk_malloc(d_samples_per_code * d_folding_factor * sizeof(gr_complex), volk_get_alignment());
|
||||
gr_complex *in_temp_folded = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
/*Create a signal to store a signal of size 1ms, to perform correlation
|
||||
in time. No folding on this data is required*/
|
||||
gr_complex *in_1code;
|
||||
if (posix_memalign((void**)&(in_1code), 16,d_samples_per_code * sizeof(gr_complex)) == 0){};
|
||||
gr_complex *in_1code = (gr_complex*)volk_malloc(d_samples_per_code * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
/*Stores the values of the correlation output between the local code
|
||||
and the signal with doppler shift corrected */
|
||||
gr_complex *corr_output;
|
||||
if (posix_memalign((void**)&(corr_output), 16,d_samples_per_code * sizeof(gr_complex)) == 0){};
|
||||
gr_complex *corr_output = (gr_complex*)volk_malloc(d_samples_per_code * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
/*Stores a copy of the folded version of the signal.This is used for
|
||||
the FFT operations in future steps of excecution*/
|
||||
@ -322,30 +295,27 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
|
||||
/* 1- Compute the input signal power estimation. This operation is
|
||||
being performed in a signal of size nxp */
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_samples_per_code * d_folding_factor);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_samples_per_code * d_folding_factor);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, in, d_samples_per_code * d_folding_factor);
|
||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_samples_per_code * d_folding_factor);
|
||||
d_input_power /= (float)(d_samples_per_code * d_folding_factor);
|
||||
|
||||
|
||||
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
/*Ensure that the signal is going to start with all samples
|
||||
at zero. This is done to avoid over acumulation when performing
|
||||
the folding process to be stored in d_fft_if->get_inbuf()*/
|
||||
d_signal_folded = new gr_complex[d_fft_size]();
|
||||
memcpy( d_fft_if->get_inbuf(),d_signal_folded,
|
||||
sizeof(gr_complex)*(d_fft_size));
|
||||
memcpy( d_fft_if->get_inbuf(), d_signal_folded, sizeof(gr_complex) * (d_fft_size));
|
||||
|
||||
/*Doppler search steps and then multiplication of the incoming
|
||||
signal with the doppler wipeoffs to eliminate frequency offset
|
||||
*/
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
|
||||
/*Perform multiplication of the incoming signal with the
|
||||
complex exponential vector. This removes the frequency doppler
|
||||
shift offset*/
|
||||
volk_32fc_x2_multiply_32fc_a(in_temp, in,
|
||||
volk_32fc_x2_multiply_32fc(in_temp, in,
|
||||
d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_samples_per_code * d_folding_factor);
|
||||
|
||||
@ -354,8 +324,8 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
incoming raw data signal is of d_folding_factor^2*/
|
||||
for ( int i = 0; i < (int)(d_folding_factor*d_folding_factor); i++)
|
||||
{
|
||||
std::transform ((in_temp+i*d_fft_size),
|
||||
(in_temp+((i+1)*d_fft_size)) ,
|
||||
std::transform ((in_temp + i * d_fft_size),
|
||||
(in_temp + ((i + 1) * d_fft_size)) ,
|
||||
d_fft_if->get_inbuf(),
|
||||
d_fft_if->get_inbuf(),
|
||||
std::plus<gr_complex>());
|
||||
@ -368,7 +338,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
/*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_a(d_ifft->get_inbuf(),
|
||||
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||
|
||||
/* compute the inverse FFT of the aliased signal*/
|
||||
@ -376,14 +346,14 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
|
||||
/* Compute the magnitude and get the maximum value with its
|
||||
index position*/
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude_folded,
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude_folded,
|
||||
d_ifft->get_outbuf(), d_fft_size);
|
||||
|
||||
/* Normalize the maximum value to correct the scale factor
|
||||
introduced by FFTW*/
|
||||
//volk_32f_s32f_multiply_32f_a(d_magnitude_folded,d_magnitude_folded,
|
||||
// (1 / (fft_normalization_factor * fft_normalization_factor)), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitude_folded, d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_magnitude_folded, d_fft_size);
|
||||
|
||||
magt = d_magnitude_folded[indext]/ (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
@ -415,7 +385,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
|
||||
for (int i = 0; i < (int)d_folding_factor; i++)
|
||||
{
|
||||
d_possible_delay[i]= detected_delay_samples_folded+
|
||||
d_possible_delay[i] = detected_delay_samples_folded +
|
||||
(i)*d_fft_size;
|
||||
}
|
||||
|
||||
@ -432,61 +402,42 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
effect corrected and accumulates its value. This
|
||||
is indeed correlation in time for an specific value
|
||||
of a shift*/
|
||||
volk_32fc_x2_multiply_32fc_a(corr_output, in_1code,
|
||||
volk_32fc_x2_multiply_32fc(corr_output, in_1code,
|
||||
d_code, d_samples_per_code);
|
||||
|
||||
for(int j=0; j < (d_samples_per_code); j++)
|
||||
for(int j = 0; j < d_samples_per_code; j++)
|
||||
{
|
||||
complex_acumulator[i] += (corr_output[j]);
|
||||
}
|
||||
|
||||
}
|
||||
/*Obtain maximun value of correlation given the
|
||||
possible delay selected */
|
||||
volk_32fc_magnitude_squared_32f_a(d_corr_output_f,
|
||||
complex_acumulator, d_folding_factor);
|
||||
volk_32f_index_max_16u_a(&indext, d_corr_output_f,
|
||||
d_folding_factor);
|
||||
/*Obtain maximun value of correlation given the possible delay selected */
|
||||
volk_32fc_magnitude_squared_32f(d_corr_output_f, complex_acumulator, d_folding_factor);
|
||||
volk_32f_index_max_16u(&indext, d_corr_output_f, d_folding_factor);
|
||||
|
||||
/*Now save the real code phase in the gnss_syncro
|
||||
block for use in other stages*/
|
||||
d_gnss_synchro->Acq_delay_samples = (double)
|
||||
(d_possible_delay[indext]);
|
||||
/*Now save the real code phase in the gnss_syncro block for use in other stages*/
|
||||
d_gnss_synchro->Acq_delay_samples = (double)(d_possible_delay[indext]);
|
||||
d_gnss_synchro->Acq_doppler_hz = (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;*/
|
||||
/* 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;
|
||||
//delete complex_acumulator;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 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("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
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();
|
||||
*/
|
||||
/*Since QuickSYnc performs a folded correlation in frequency by means
|
||||
of the FFT, it is esential to also keep the values obtained from the
|
||||
possible delay to show how it is maximize*/
|
||||
of the FFT, it is esential to also keep the values obtained from the
|
||||
possible delay to show how it is maximize*/
|
||||
std::stringstream filename;
|
||||
std::streamsize n = sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_magnitude_folded, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
@ -524,11 +475,9 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
consume_each(1);
|
||||
|
||||
delete d_code_folded;
|
||||
d_code_folded = NULL;
|
||||
|
||||
free(in_temp);
|
||||
free(in_1code);
|
||||
free(corr_output);
|
||||
volk_free(in_temp);
|
||||
volk_free(in_1code);
|
||||
volk_free(corr_output);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -99,9 +99,8 @@ pcps_tong_acquisition_cc::pcps_tong_acquisition_cc(
|
||||
d_input_power = 0.0;
|
||||
d_num_doppler_bins = 0;
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
d_fft_codes = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
d_magnitude = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
@ -120,15 +119,15 @@ pcps_tong_acquisition_cc::~pcps_tong_acquisition_cc()
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
free(d_grid_data[i]);
|
||||
volk_free(d_grid_doppler_wipeoffs[i]);
|
||||
volk_free(d_grid_data[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
delete[] d_grid_data;
|
||||
}
|
||||
|
||||
free(d_fft_codes);
|
||||
free(d_magnitude);
|
||||
volk_free(d_fft_codes);
|
||||
volk_free(d_magnitude);
|
||||
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
@ -146,14 +145,7 @@ void pcps_tong_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
|
||||
void pcps_tong_acquisition_cc::init()
|
||||
@ -178,16 +170,14 @@ void pcps_tong_acquisition_cc::init()
|
||||
d_grid_data = new float*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
d_grid_doppler_wipeoffs[doppler_index] = (gr_complex*)volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment());
|
||||
|
||||
int doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in, d_fft_size);
|
||||
|
||||
if (posix_memalign((void**)&(d_grid_data[doppler_index]), 16,
|
||||
d_fft_size * sizeof(float)) == 0){};
|
||||
d_grid_data[doppler_index] = (float*)volk_malloc(d_fft_size * sizeof(float), volk_get_alignment());
|
||||
|
||||
for (unsigned int i = 0; i < d_fft_size; i++)
|
||||
{
|
||||
@ -257,8 +247,8 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size);
|
||||
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 /= (float)d_fft_size;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
@ -268,7 +258,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
||||
|
||||
doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in,
|
||||
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)
|
||||
@ -277,25 +267,25 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
||||
|
||||
// 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_a(d_ifft->get_inbuf(),
|
||||
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();
|
||||
|
||||
// Compute magnitude
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf(), d_fft_size);
|
||||
|
||||
// Compute vector of test statistics corresponding to current doppler index.
|
||||
volk_32f_s32f_multiply_32f_a(d_magnitude, d_magnitude,
|
||||
volk_32f_s32f_multiply_32f(d_magnitude, d_magnitude,
|
||||
1/(fft_normalization_factor*fft_normalization_factor*d_input_power),
|
||||
d_fft_size);
|
||||
|
||||
// Accumulate test statistics in d_grid_data.
|
||||
volk_32f_x2_add_32f_a(d_grid_data[doppler_index], d_magnitude, d_grid_data[doppler_index], d_fft_size);
|
||||
volk_32f_x2_add_32f(d_grid_data[doppler_index], d_magnitude, d_grid_data[doppler_index], d_fft_size);
|
||||
|
||||
// Search maximum
|
||||
volk_32f_index_max_16u_a(&indext, d_grid_data[doppler_index], d_fft_size);
|
||||
volk_32f_index_max_16u(&indext, d_grid_data[doppler_index], d_fft_size);
|
||||
|
||||
magt = d_grid_data[doppler_index][indext];
|
||||
|
||||
|
@ -191,7 +191,6 @@ Galileo_E5a_Dll_Pll_Tracking_cc::~Galileo_E5a_Dll_Pll_Tracking_cc ()
|
||||
volk_free(d_Early);
|
||||
volk_free(d_Prompt);
|
||||
volk_free(d_Late);
|
||||
volk_free(d_Prompt_data);
|
||||
volk_free(d_codeQ);
|
||||
volk_free(d_codeI);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user