diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt
index 10839b0ac..4e9048b4d 100644
--- a/src/algorithms/acquisition/adapters/CMakeLists.txt
+++ b/src/algorithms/acquisition/adapters/CMakeLists.txt
@@ -19,6 +19,7 @@
set(ACQ_ADAPTER_SOURCES
galileo_e1_pcps_ambiguous_acquisition.cc
gps_l1_ca_pcps_acquisition.cc
+ gps_l1_ca_pcps_assisted_acquisition.cc
)
include_directories(
diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc
new file mode 100644
index 000000000..532001ad2
--- /dev/null
+++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc
@@ -0,0 +1,185 @@
+/*!
+ * \file gps_l1_ca_pcps_acquisition.cc
+ * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
+ * GPS L1 C/A Signals
+ * \authors
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "gps_l1_ca_pcps_assisted_acquisition.h"
+#include "gps_sdr_signal_processing.h"
+#include "GPS_L1_CA.h"
+#include "configuration_interface.h"
+#include
+#include
+#include
+#include
+
+using google::LogMessage;
+
+GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition(
+ ConfigurationInterface* configuration, std::string role,
+ unsigned int in_streams, unsigned int out_streams,
+ gr_msg_queue_sptr queue) :
+ role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(
+ queue)
+{
+
+ std::string default_item_type = "gr_complex";
+ std::string default_dump_filename = "./data/acquisition.dat";
+
+ DLOG(INFO) << "role " << role;
+
+ item_type_ = configuration->property(role + ".item_type",
+ default_item_type);
+
+ fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
+ if_ = configuration->property(role + ".ifreq", 0);
+ dump_ = configuration->property(role + ".dump", false);
+ shift_resolution_ = configuration->property(role + ".doppler_max", 15);
+ sampled_ms_ = configuration->property(role + ".sampled_ms", 1);
+ max_dwells_= configuration->property(role + ".max_dwells", 1);
+ dump_filename_ = configuration->property(role + ".dump_filename",
+ default_dump_filename);
+
+ //--- Find number of samples per spreading code -------------------------
+ vector_length_ = round(fs_in_
+ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
+
+ code_= new gr_complex[vector_length_];
+
+ if (item_type_.compare("gr_complex") == 0)
+ {
+ item_size_ = sizeof(gr_complex);
+ acquisition_cc_ = pcps_make_assisted_acquisition_cc(max_dwells_,sampled_ms_,
+ shift_resolution_, if_, fs_in_, vector_length_, queue_,
+ dump_, dump_filename_);
+
+ }
+ else
+ {
+ LOG_AT_LEVEL(WARNING) << item_type_
+ << " unknown acquisition item type";
+ }
+}
+
+
+GpsL1CaPcpsAssistedAcquisition::~GpsL1CaPcpsAssistedAcquisition()
+{
+ delete[] code_;
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::set_channel(unsigned int channel)
+{
+ channel_ = channel;
+ acquisition_cc_->set_channel(channel_);
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::set_threshold(float threshold)
+{
+ threshold_ = threshold;
+ acquisition_cc_->set_threshold(threshold_);
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::set_doppler_max(unsigned int doppler_max)
+{
+ doppler_max_ = doppler_max;
+ acquisition_cc_->set_doppler_max(doppler_max_);
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::set_doppler_step(unsigned int doppler_step)
+{
+ doppler_step_ = doppler_step;
+ acquisition_cc_->set_doppler_step(doppler_step_);
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::set_channel_queue(
+ concurrent_queue *channel_internal_queue)
+{
+ channel_internal_queue_ = channel_internal_queue;
+ acquisition_cc_->set_channel_queue(channel_internal_queue_);
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
+{
+ gnss_synchro_ = gnss_synchro;
+ acquisition_cc_->set_gnss_synchro(gnss_synchro_);
+}
+
+
+signed int GpsL1CaPcpsAssistedAcquisition::mag()
+{
+ return acquisition_cc_->mag();
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::init(){
+ gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0);
+ acquisition_cc_->set_local_code(code_);
+ acquisition_cc_->init();
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::reset()
+{
+ acquisition_cc_->set_active(true);
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::connect(gr_top_block_sptr top_block)
+{
+
+ //nothing to disconnect, now the tracking uses gr_sync_decimator
+
+}
+
+
+void GpsL1CaPcpsAssistedAcquisition::disconnect(gr_top_block_sptr top_block)
+{
+ //nothing to disconnect, now the tracking uses gr_sync_decimator
+}
+
+
+gr_basic_block_sptr GpsL1CaPcpsAssistedAcquisition::get_left_block()
+{
+ return acquisition_cc_;
+}
+
+
+gr_basic_block_sptr GpsL1CaPcpsAssistedAcquisition::get_right_block()
+{
+ return acquisition_cc_;
+}
+
diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h
new file mode 100644
index 000000000..6f13dd847
--- /dev/null
+++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h
@@ -0,0 +1,154 @@
+/*!
+ * \file gps_l1_ca_pcps_assisted_acquisition.h
+ * \brief Adapts a PCPS Assisted acquisition block to an AcquisitionInterface for
+ * GPS L1 C/A signals
+ * \authors
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
*
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef GNSS_SDR_GPS_L1_CA_PCPS_ASSISTED_ACQUISITION_H_
+#define GNSS_SDR_GPS_L1_CA_PCPS_ASSISTED_ACQUISITION_H_
+
+#include "gnss_synchro.h"
+#include "acquisition_interface.h"
+#include "pcps_assisted_acquisition_cc.h"
+#include
+#include
+
+
+class ConfigurationInterface;
+
+/*!
+ * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
+ * for GPS L1 C/A signals
+ */
+class GpsL1CaPcpsAssistedAcquisition: public AcquisitionInterface
+{
+public:
+ GpsL1CaPcpsAssistedAcquisition(ConfigurationInterface* configuration,
+ std::string role, unsigned int in_streams,
+ unsigned int out_streams, gr_msg_queue_sptr queue);
+
+ virtual ~GpsL1CaPcpsAssistedAcquisition();
+
+ std::string role()
+ {
+ return role_;
+ }
+
+ /*!
+ * \brief Returns "GPS_L1_CA_PCPS_Assisted_Acquisition"
+ */
+ std::string implementation()
+ {
+ return "GPS_L1_CA_PCPS_Assisted_Acquisition";
+ }
+ size_t item_size()
+ {
+ return item_size_;
+ }
+
+ void connect(gr_top_block_sptr top_block);
+ void disconnect(gr_top_block_sptr top_block);
+ gr_basic_block_sptr get_left_block();
+ gr_basic_block_sptr get_right_block();
+
+ /*!
+ * \brief Set acquisition/tracking common Gnss_Synchro object pointer
+ * to efficiently exchange synchronization data between acquisition and
+ * tracking blocks
+ */
+ void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
+
+ /*!
+ * \brief Set acquisition channel unique ID
+ */
+ void set_channel(unsigned int channel);
+
+ /*!
+ * \brief Set statistics threshold of PCPS algorithm
+ */
+ void set_threshold(float threshold);
+
+ /*!
+ * \brief Set maximum Doppler off grid search
+ */
+ void set_doppler_max(unsigned int doppler_max);
+
+ /*!
+ * \brief Set Doppler steps for the grid search
+ */
+ void set_doppler_step(unsigned int doppler_step);
+
+ /*!
+ * \brief Set tracking channel internal queue
+ */
+ void set_channel_queue(concurrent_queue *channel_internal_queue);
+
+ /*!
+ * \brief Initializes acquisition algorithm.
+ */
+ void init();
+
+ /*!
+ * \brief Returns the maximum peak of grid search
+ */
+ signed int mag();
+
+ /*!
+ * \brief Restart acquisition algorithm
+ */
+ void reset();
+
+private:
+ pcps_assisted_acquisition_cc_sptr acquisition_cc_;
+ size_t item_size_;
+ std::string item_type_;
+ unsigned int vector_length_;
+ //unsigned int satellite_;
+ unsigned int channel_;
+ float threshold_;
+ unsigned int doppler_max_;
+ unsigned int doppler_step_;
+ unsigned int shift_resolution_;
+ unsigned int sampled_ms_;
+ int max_dwells_;
+ long fs_in_;
+ long if_;
+ bool dump_;
+ std::string dump_filename_;
+ std::complex * code_;
+ Gnss_Synchro * gnss_synchro_;
+ std::string role_;
+ unsigned int in_streams_;
+ unsigned int out_streams_;
+ gr_msg_queue_sptr queue_;
+ concurrent_queue *channel_internal_queue_;
+};
+
+#endif /* GNSS_SDR_GPS_L1_CA_PCPS_ASSISTED_ACQUISITION_H_ */
diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
index ea056b773..e7860052e 100644
--- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
+++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
@@ -16,7 +16,10 @@
# along with GNSS-SDR. If not, see .
#
-set(ACQ_GR_BLOCKS_SOURCES pcps_acquisition_cc.cc )
+set(ACQ_GR_BLOCKS_SOURCES
+ pcps_acquisition_cc.cc
+ pcps_assisted_acquisition_cc.cc
+)
include_directories(
$(CMAKE_CURRENT_SOURCE_DIR)
diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc
new file mode 100644
index 000000000..036f3d943
--- /dev/null
+++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc
@@ -0,0 +1,311 @@
+/*!
+ * \file pcps_acquisition_cc.cc
+ * \brief This class implements a Parallel Code Phase Search Acquisition
+ * \authors
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "pcps_assisted_acquisition_cc.h"
+#include "gnss_signal_processing.h"
+#include "control_message_factory.h"
+#include
+#include
+#include
+#include
+#include
+
+using google::LogMessage;
+
+pcps_assisted_acquisition_cc_sptr pcps_make_assisted_acquisition_cc(
+ int max_dwells, unsigned int sampled_ms, unsigned int doppler_max, long freq,
+ long fs_in, int samples_per_ms, gr_msg_queue_sptr queue, bool dump,
+ std::string dump_filename)
+{
+
+ return pcps_assisted_acquisition_cc_sptr(
+ new pcps_assisted_acquisition_cc(max_dwells, sampled_ms, doppler_max, freq,
+ fs_in, samples_per_ms, queue, dump, dump_filename));
+}
+
+
+
+pcps_assisted_acquisition_cc::pcps_assisted_acquisition_cc(
+ int max_dwells, unsigned int sampled_ms, unsigned int doppler_max, long freq,
+ long fs_in, int samples_per_ms, gr_msg_queue_sptr queue, bool dump,
+ std::string dump_filename) :
+ gr_block("pcps_assisted_acquisition_cc",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(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_doppler_max = doppler_max;
+ 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_max_dwells;
+ d_mag = 0;
+ d_input_power = 0.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){};
+
+ // 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);
+
+ // For dumping samples into a file
+ d_dump = dump;
+ d_dump_filename = dump_filename;
+}
+
+
+
+pcps_assisted_acquisition_cc::~pcps_assisted_acquisition_cc()
+{
+ free(d_carrier);
+ free(d_fft_codes);
+ delete d_ifft;
+ delete d_fft_if;
+ if (d_dump)
+ {
+ d_dump_file.close();
+ }
+}
+
+
+
+void pcps_assisted_acquisition_cc::set_local_code(std::complex * code)
+{
+ memcpy(d_fft_if->get_inbuf(),code,sizeof(gr_complex)*d_fft_size);
+}
+
+
+
+void pcps_assisted_acquisition_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_mag = 0.0;
+ d_input_power = 0.0;
+
+ d_fft_if->execute(); // We need the FFT of local code
+
+ //Conjugate the local code
+ for (unsigned int i = 0; i < d_fft_size; i++)
+ {
+ d_fft_codes[i] = std::complex(conj(d_fft_if->get_outbuf()[i]));
+ }
+}
+
+
+void pcps_assisted_acquisition_cc::forecast (int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+ ninput_items_required[0] = d_gnuradio_forecast_samples ; //set the required available samples in each call
+}
+
+
+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)
+{
+ /*
+ * By J.Arribas and L.Esteve
+ * Acquisition strategy (Kay Borre book + CFAR threshold):
+ * 1. Compute the input signal power estimation
+ * 2. Doppler serial search loop
+ * 3. Perform the FFT-based circular convolution (parallel time search)
+ * 4. Record the maximum peak and the associated synchronization parameters
+ * 5. Compute the test statistics and compare to the threshold
+ * 6. Declare positive or negative acquisition using a message queue
+ */
+
+ /*!
+ * TODO: High sensitivity acquisition algorithm:
+ * 0. Define search grid with assistance information. Reset grid matrix
+ * 1. Perform the FFT acqusition doppler and delay grid
+ * 2. accumulate the search grid matrix (#doppler_bins x #fft_size)
+ * 3. compare maximum to threshold and decide positive or negative
+ * 4. positive: stop. negative: if dwell_count< max_dwells -> dwell_count++ and goto 1, else -> negative acquisition: stop.
+ */
+ if (!d_active)
+ {
+ d_sample_counter += d_fft_size * noutput_items; // sample counter
+ consume_each(noutput_items);
+ }
+ else
+ {
+ // initialize acquisition algorithm
+ int doppler;
+ unsigned int indext = 0;
+ float magt = 0.0;
+ float tmp_magt = 0.0;
+ const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
+ bool positive_acquisition = false;
+ int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
+ //aux vars
+ unsigned int i;
+ float fft_normalization_factor;
+
+ d_sample_counter += d_fft_size; // sample counter
+
+ //restart acquisition variables
+ d_gnss_synchro->Acq_delay_samples = 0.0;
+ d_gnss_synchro->Acq_doppler_hz = 0.0;
+ d_mag = 0.0;
+ d_input_power = 0.0;
+
+ DLOG(INFO) << "Channel: " << d_channel
+ << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
+ << " ,sample stamp: " << d_sample_counter << ", threshold: "
+ << d_threshold << ", doppler_max: " << d_doppler_max
+ << ", doppler_step: " << d_doppler_step;
+
+ // 1- Compute the input signal power estimation
+ for (i = 0; i < d_fft_size; i++)
+ {
+ d_input_power += std::norm(in[i]);
+ }
+ d_input_power = d_input_power / (float)d_fft_size;
+
+ // 2- Doppler frequency search loop
+ for (doppler = (int)(-d_doppler_max); doppler < (int)d_doppler_max; doppler += d_doppler_step)
+ {
+ // doppler search steps
+ // Perform the carrier wipe-off
+ complex_exp_gen_conj(d_carrier, d_freq + doppler, d_fs_in, d_fft_size);
+
+ volk_32fc_x2_multiply_32fc_u(d_fft_if->get_inbuf(), in, d_carrier, 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);
+
+ // compute the inverse FFT
+ d_ifft->execute();
+
+ // Search maximum
+ indext = 0;
+ magt = 0;
+ fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
+ for (i = 0; i < d_fft_size; i++)
+ {
+ tmp_magt = std::norm(d_ifft->get_outbuf()[i]);
+ if (tmp_magt > magt)
+ {
+ magt = tmp_magt;
+ indext = i;
+ }
+ }
+ // Normalize the maximum value to correct the scale factor introduced by FFTW
+ magt = magt / (fft_normalization_factor * fft_normalization_factor);
+
+ // 4- record the maximum peak and the associated synchronization parameters
+ if (d_mag < magt)
+ {
+ d_mag = magt;
+ d_gnss_synchro->Acq_delay_samples = (double)indext;
+ d_gnss_synchro->Acq_doppler_hz = (double)doppler;
+ }
+
+ // 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();
+ }
+ }
+
+ // 5- Compute the test statistics and compare to the threshold
+ d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
+
+ // 6- Declare positive or negative acquisition using a message queue
+ if (d_test_statistics > d_threshold)
+ {
+ positive_acquisition = true;
+ d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
+ 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) << "magnitude " << d_mag;
+ DLOG(INFO) << "input signal power " << d_input_power;
+ }
+ else
+ {
+ 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) << "magnitude " << d_mag;
+ DLOG(INFO) << "input signal power " << d_input_power;
+ }
+
+ d_active = false;
+
+ if (positive_acquisition)
+ {
+ acquisition_message = 1;
+ }
+ else
+ {
+ acquisition_message = 2;
+ }
+ d_channel_internal_queue->push(acquisition_message);
+ consume_each(1);
+ }
+ return 0;
+}
diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.h
new file mode 100644
index 000000000..fbf89b570
--- /dev/null
+++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.h
@@ -0,0 +1,229 @@
+/*!
+ * \file pcps_assisted_acquisition_cc.h
+ * \brief This class implements a Parallel Code Phase Search Acquisition
+ *
+ * Acquisition strategy (Kay Borre book + CFAR threshold).
+ *
+ * - Compute the input signal power estimation
+ *
- Doppler serial search loop
+ *
- Perform the FFT-based circular convolution (parallel time search)
+ *
- Record the maximum peak and the associated synchronization parameters
+ *
- Compute the test statistics and compare to the threshold
+ *
- Declare positive or negative acquisition using a message queue
+ *
+ *
+ * Kay Borre book: K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
+ * "A Software-Defined GPS and Galileo Receiver. A Single-Frequency
+ * Approach", Birkha user, 2007. pp 81-84
+ *
+ * \authors
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef GNSS_SDR_PCPS_assisted_acquisition_cc_H_
+#define GNSS_SDR_PCPS_assisted_acquisition_cc_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "concurrent_queue.h"
+#include "gnss_synchro.h"
+
+class pcps_assisted_acquisition_cc;
+typedef boost::shared_ptr
+pcps_assisted_acquisition_cc_sptr;
+pcps_assisted_acquisition_cc_sptr
+pcps_make_assisted_acquisition_cc(int max_dwells, unsigned int sampled_ms,
+ unsigned int doppler_max, long freq, long fs_in, int samples_per_ms,
+ gr_msg_queue_sptr queue, bool dump, std::string dump_filename);
+
+/*!
+ * \brief This class implements a Parallel Code Phase Search Acquisition.
+ *
+ * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
+ * Algorithm 1, for a pseudocode description of this implementation.
+ */
+
+class pcps_assisted_acquisition_cc: public gr_block
+{
+private:
+ friend pcps_assisted_acquisition_cc_sptr
+ pcps_make_assisted_acquisition_cc(int max_dwells, unsigned int sampled_ms,
+ unsigned int doppler_max, long freq, long fs_in,
+ int samples_per_ms, gr_msg_queue_sptr queue, bool dump,
+ std::string dump_filename);
+
+ pcps_assisted_acquisition_cc(int max_dwells, unsigned int sampled_ms,
+ unsigned int doppler_max, long freq, long fs_in,
+ int samples_per_ms, gr_msg_queue_sptr queue, bool dump,
+ std::string dump_filename);
+
+ void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
+ int doppler_offset);
+
+ long d_fs_in;
+ long d_freq;
+ int d_samples_per_ms;
+ int d_max_dwells;
+ unsigned int d_doppler_resolution;
+ int d_gnuradio_forecast_samples;
+ float d_threshold;
+ std::string d_satellite_str;
+ unsigned int d_doppler_max;
+ unsigned int d_doppler_step;
+ unsigned int d_sampled_ms;
+ unsigned int d_fft_size;
+ unsigned long int d_sample_counter;
+ gr_complex* d_carrier;
+ gr_complex* d_fft_codes;
+ gr::fft::fft_complex* d_fft_if;
+ gr::fft::fft_complex* d_ifft;
+ Gnss_Synchro *d_gnss_synchro;
+ unsigned int d_code_phase;
+ float d_doppler_freq;
+ float d_mag;
+ float d_input_power;
+ float d_test_statistics;
+ gr_msg_queue_sptr d_queue;
+ concurrent_queue *d_channel_internal_queue;
+ std::ofstream d_dump_file;
+ bool d_active;
+ bool d_dump;
+ unsigned int d_channel;
+ std::string d_dump_filename;
+
+public:
+ /*!
+ * \brief Default destructor.
+ */
+ ~pcps_assisted_acquisition_cc();
+
+ /*!
+ * \brief Set acquisition/tracking common Gnss_Synchro object pointer
+ * to exchange synchronization data between acquisition and tracking blocks.
+ * \param p_gnss_synchro Satellite information shared by the processing blocks.
+ */
+ void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
+ {
+ d_gnss_synchro = p_gnss_synchro;
+ }
+
+ /*!
+ * \brief Returns the maximum peak of grid search.
+ */
+ unsigned int mag()
+ {
+ return d_mag;
+ }
+
+ /*!
+ * \brief Initializes acquisition algorithm.
+ */
+ void init();
+
+ /*!
+ * \brief Sets local code for PCPS acquisition algorithm.
+ * \param code - Pointer to the PRN code.
+ */
+ void set_local_code(std::complex * code);
+
+ /*!
+ * \brief Starts acquisition algorithm, turning from standby mode to
+ * active mode
+ * \param active - bool that activates/deactivates the block.
+ */
+ void set_active(bool active)
+ {
+ d_active = active;
+ }
+
+ /*!
+ * \brief Set acquisition channel unique ID
+ * \param channel - receiver channel.
+ */
+ void set_channel(unsigned int channel)
+ {
+ d_channel = channel;
+ }
+
+ /*!
+ * \brief Set statistics threshold of PCPS algorithm.
+ * \param threshold - Threshold for signal detection (check \ref Navitec2012,
+ * Algorithm 1, for a definition of this threshold).
+ */
+ void set_threshold(float threshold)
+ {
+ d_threshold = threshold;
+ }
+
+ /*!
+ * \brief Set maximum Doppler grid search
+ * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
+ */
+ void set_doppler_max(unsigned int doppler_max)
+ {
+ d_doppler_max = doppler_max;
+ }
+
+ /*!
+ * \brief Set Doppler steps for the grid search
+ * \param doppler_step - Frequency bin of the search grid [Hz].
+ */
+ void set_doppler_step(unsigned int doppler_step)
+ {
+ d_doppler_step = doppler_step;
+ }
+
+
+ /*!
+ * \brief Set tracking channel internal queue.
+ * \param channel_internal_queue - Channel's internal blocks information queue.
+ */
+ void set_channel_queue(concurrent_queue *channel_internal_queue)
+ {
+ d_channel_internal_queue = channel_internal_queue;
+ }
+
+ /*!
+ * \brief Parallel Code Phase Search Acquisition signal processing.
+ */
+ int general_work(int noutput_items, gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+};
+
+#endif /* GNSS_SDR_PCPS_assisted_acquisition_cc_H_*/
diff --git a/src/core/libs/gnss_sdr_supl_client.cc b/src/core/libs/gnss_sdr_supl_client.cc
index 94316bf9e..31b076ee8 100644
--- a/src/core/libs/gnss_sdr_supl_client.cc
+++ b/src/core/libs/gnss_sdr_supl_client.cc
@@ -302,6 +302,7 @@ void gnss_sdr_supl_client::read_supl_data()
gps_acq_iterator=this->gps_acq_map.find(e->prn);
}
// fill the acquisition assistance structure
+ gps_acq_iterator->second.i_satellite_PRN=e->prn;
gps_acq_iterator->second.d_TOW=(double)assist.acq_time;
gps_acq_iterator->second.d_Doppler0=(double)e->doppler0;
gps_acq_iterator->second.d_Doppler1=(double)e->doppler1;
diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc
index da725b464..009d25534 100644
--- a/src/core/receiver/control_thread.cc
+++ b/src/core/receiver/control_thread.cc
@@ -54,12 +54,14 @@
extern concurrent_map global_gps_ephemeris_map;
extern concurrent_map global_gps_iono_map;
extern concurrent_map global_gps_utc_model_map;
+extern concurrent_map global_gps_almanac_map;
+extern concurrent_map global_gps_acq_assist_map;
extern concurrent_queue global_gps_ephemeris_queue;
extern concurrent_queue global_gps_iono_queue;
extern concurrent_queue global_gps_utc_model_queue;
extern concurrent_queue global_gps_almanac_queue;
-
+extern concurrent_queue global_gps_acq_assist_queue;
using google::LogMessage;
@@ -132,6 +134,7 @@ void ControlThread::run()
gps_ephemeris_data_collector_thread_ =boost::thread(&ControlThread::gps_ephemeris_data_collector, this);
gps_iono_data_collector_thread_ =boost::thread(&ControlThread::gps_iono_data_collector, this);
gps_utc_model_data_collector_thread_ =boost::thread(&ControlThread::gps_utc_model_data_collector, this);
+ gps_acq_assist_data_collector_thread_=boost::thread(&ControlThread::gps_acq_assist_data_collector,this);
// Main loop to read and process the control messages
while (flowgraph_->running() && !stop_)
@@ -141,11 +144,13 @@ void ControlThread::run()
if (control_messages_ != 0) process_control_messages();
}
std::cout<<"Stopping GNSS-SDR, please wait!"<stop();
gps_ephemeris_data_collector_thread_.timed_join(boost::posix_time::seconds(1));
gps_iono_data_collector_thread_.timed_join(boost::posix_time::seconds(1));
gps_utc_model_data_collector_thread_.timed_join(boost::posix_time::seconds(1));
+ gps_acq_assist_data_collector_thread_.timed_join(boost::posix_time::seconds(1));
keyboard_thread_.timed_join(boost::posix_time::seconds(1));
- flowgraph_->stop();
+
LOG_AT_LEVEL(INFO) << "Flowgraph stopped";
}
@@ -186,27 +191,27 @@ bool ControlThread::read_assistance_from_XML()
}
void ControlThread::init()
{
- // Instantiates a control queue, a GNSS flowgraph, and a control message factory
- control_queue_ = gr_make_msg_queue(0);
- flowgraph_ = new GNSSFlowgraph(configuration_, control_queue_);
- control_message_factory_ = new ControlMessageFactory();
- stop_ = false;
- processed_control_messages_ = 0;
- applied_actions_ = 0;
+ // Instantiates a control queue, a GNSS flowgraph, and a control message factory
+ control_queue_ = gr_make_msg_queue(0);
+ flowgraph_ = new GNSSFlowgraph(configuration_, control_queue_);
+ control_message_factory_ = new ControlMessageFactory();
+ stop_ = false;
+ processed_control_messages_ = 0;
+ applied_actions_ = 0;
- // GNSS Assistance configuration
- bool enable_gps_supl_assistance=configuration_->property("GNSS-SDR.SUPL_gps_enabled",false);
- if (enable_gps_supl_assistance==true)
- //SUPL SERVER TEST. Not operational yet!
- {
- std::cout<< "SUPL RRLP GPS assistance enabled!"<property("GNSS-SDR.SUPL_gps_enabled",false);
+ if (enable_gps_supl_assistance==true)
+ //SUPL SERVER TEST. Not operational yet!
+ {
+ std::cout<< "SUPL RRLP GPS assistance enabled!"<property("GNSS-SDR.SUPL_gps_ephemeris_server",default_acq_server);
supl_client_acquisition_.server_name=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server",default_eph_server);
supl_client_ephemeris_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port",7275);
supl_client_acquisition_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port",7275);
-
supl_mcc=configuration_->property("GNSS-SDR.SUPL_MCC",244);
supl_mns=configuration_->property("GNSS-SDR.SUPL_MNS",5);
@@ -218,7 +223,7 @@ void ControlThread::init()
supl_lac=0x59e2;
}
try {
- supl_ci = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_CI",default_ci));
+ supl_ci = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_CI",default_ci));
} catch(boost::bad_lexical_cast &) {
supl_ci=0x31b0;
}
@@ -230,76 +235,90 @@ void ControlThread::init()
read_assistance_from_XML();
}else{
- // Request ephemeris from SUPL server
- int error;
- supl_client_ephemeris_.request=1;
- std::cout<< "SUPL: Try read GPS ephemeris from SUPL server.."<::iterator gps_eph_iter;
- for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin();
- gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end();
- gps_eph_iter++)
+ // Request ephemeris from SUPL server
+ int error;
+ supl_client_ephemeris_.request=1;
+ std::cout<< "SUPL: Try read GPS ephemeris from SUPL server.."<first<second);
+ std::map::iterator gps_eph_iter;
+ for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin();
+ gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end();
+ gps_eph_iter++)
+ {
+ std::cout<<"SUPL: Received Ephemeris for GPS SV "<first<second);
+ }
+ //Save ephemeris to XML file
+ std::string eph_xml_filename="gps_ephemeris.xml";
+ if (supl_client_ephemeris_.save_ephemeris_xml(eph_xml_filename)==true)
+ {
+ std::cout<<"SUPL: XML Ephemeris file created"<::iterator gps_alm_iter;
- for(gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.begin();
- gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.end();
- gps_alm_iter++)
+ // Request almanac , IONO and UTC Model
+ supl_client_ephemeris_.request=0;
+ std::cout<< "SUPL: Try read Almanac, Iono, Utc Model, Ref Time and Ref Location from SUPL server.."<first<second);
+ std::map::iterator gps_alm_iter;
+ for(gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.begin();
+ gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.end();
+ gps_alm_iter++)
+ {
+ std::cout<<"SUPL: Received Almanac for GPS SV "<first<second);
+ }
+ if (supl_client_ephemeris_.gps_iono.valid==true)
+ {
+ std::cout<<"SUPL: Received GPS Iono"<::iterator gps_acq_iter;
+ for(gps_acq_iter = supl_client_acquisition_.gps_acq_map.begin();
+ gps_acq_iter != supl_client_acquisition_.gps_acq_map.end();
+ gps_acq_iter++)
+ {
+ std::cout<<"SUPL: Received Acquisition assistance for GPS SV "<first<second);
+ }
+ }else{
+ std::cout<< "ERROR: SUPL client for Acquisition assistance returned "< global_gps_ephemeris_queue;
concurrent_queue global_gps_iono_queue;
concurrent_queue global_gps_utc_model_queue;
concurrent_queue global_gps_almanac_queue;
+concurrent_queue global_gps_acq_assist_queue;
concurrent_map global_gps_ephemeris_map;
concurrent_map global_gps_iono_map;
concurrent_map global_gps_utc_model_map;
+concurrent_map global_gps_almanac_map;
+concurrent_map global_gps_acq_assist_map;
int main(int argc, char** argv)