mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-15 20:50:33 +00:00
Merge branch 'glamountain-kf' into kf
This commit is contained in:
commit
ca4614811c
1
AUTHORS
1
AUTHORS
@ -40,6 +40,7 @@ Antonio Ramos antonio.ramosdet@gmail.com Developer
|
|||||||
Marc Majoral marc.majoral@cttc.cat Developer
|
Marc Majoral marc.majoral@cttc.cat Developer
|
||||||
Jordi Vilà-Valls jordi.vila@cttc.cat Consultant
|
Jordi Vilà-Valls jordi.vila@cttc.cat Consultant
|
||||||
Pau Closas pau.closas@northeastern.edu Consultant
|
Pau Closas pau.closas@northeastern.edu Consultant
|
||||||
|
Álvaro Cebrián Juan acebrianjuan@gmail.com Contributor
|
||||||
Andres Cecilia Luque a.cecilia.luque@gmail.com Contributor
|
Andres Cecilia Luque a.cecilia.luque@gmail.com Contributor
|
||||||
Anthony Arnold anthony.arnold@uqconnect.edu.au Contributor
|
Anthony Arnold anthony.arnold@uqconnect.edu.au Contributor
|
||||||
Carlos Avilés carlos.avilesr@googlemail.com Contributor
|
Carlos Avilés carlos.avilesr@googlemail.com Contributor
|
||||||
|
@ -32,12 +32,11 @@
|
|||||||
#ifndef GNSS_SDR_GALILEO_E1_PCPS_8MS_AMBIGUOUS_ACQUISITION_H_
|
#ifndef GNSS_SDR_GALILEO_E1_PCPS_8MS_AMBIGUOUS_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GALILEO_E1_PCPS_8MS_AMBIGUOUS_ACQUISITION_H_
|
#define GNSS_SDR_GALILEO_E1_PCPS_8MS_AMBIGUOUS_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "galileo_pcps_8ms_acquisition_cc.h"
|
#include "galileo_pcps_8ms_acquisition_cc.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -123,6 +122,7 @@ public:
|
|||||||
* \brief Restart acquisition algorithm
|
* \brief Restart acquisition algorithm
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
void set_state(int state __attribute__((unused))) override{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -58,31 +58,38 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
|
||||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in_;
|
acq_parameters.fs_in = fs_in_;
|
||||||
dump_ = configuration_->property(role + ".dump", false);
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
|
||||||
acq_parameters.dump = dump_;
|
|
||||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
|
||||||
blocking_ = configuration_->property(role + ".blocking", true);
|
|
||||||
acq_parameters.blocking = blocking_;
|
|
||||||
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||||
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
acq_parameters.doppler_max = doppler_max_;
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
sampled_ms_ = 4;
|
acq_parameters.ms_per_code = 4;
|
||||||
|
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
|
if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4";
|
||||||
|
acq_parameters.sampled_ms = acq_parameters.ms_per_code;
|
||||||
|
}
|
||||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||||
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
|
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
|
||||||
acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions
|
acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions
|
||||||
|
|
||||||
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||||
acq_parameters.max_dwells = max_dwells_;
|
acq_parameters.max_dwells = max_dwells_;
|
||||||
|
dump_ = configuration_->property(role + ".dump", false);
|
||||||
|
acq_parameters.dump = dump_;
|
||||||
|
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||||
|
blocking_ = configuration_->property(role + ".blocking", true);
|
||||||
|
acq_parameters.blocking = blocking_;
|
||||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
acq_parameters.dump_filename = dump_filename_;
|
acq_parameters.dump_filename = dump_filename_;
|
||||||
//--- Find number of samples per spreading code (4 ms) -----------------
|
//--- Find number of samples per spreading code (4 ms) -----------------
|
||||||
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||||
acq_parameters.samples_per_code = code_length_;
|
|
||||||
int samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
|
float samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_ms = samples_per_ms;
|
acq_parameters.samples_per_ms = samples_per_ms;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS);
|
||||||
vector_length_ = sampled_ms_ * samples_per_ms;
|
vector_length_ = sampled_ms_ * samples_per_ms;
|
||||||
|
|
||||||
if (bit_transition_flag_)
|
if (bit_transition_flag_)
|
||||||
|
@ -130,7 +130,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -32,12 +32,11 @@
|
|||||||
#ifndef GNSS_SDR_GALILEO_E1_PCPS_CCCWSR_AMBIGUOUS_ACQUISITION_H_
|
#ifndef GNSS_SDR_GALILEO_E1_PCPS_CCCWSR_AMBIGUOUS_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GALILEO_E1_PCPS_CCCWSR_AMBIGUOUS_ACQUISITION_H_
|
#define GNSS_SDR_GALILEO_E1_PCPS_CCCWSR_AMBIGUOUS_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_cccwsr_acquisition_cc.h"
|
#include "pcps_cccwsr_acquisition_cc.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -32,11 +32,11 @@
|
|||||||
#ifndef GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
#ifndef GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
#define GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_quicksync_acquisition_cc.h"
|
#include "pcps_quicksync_acquisition_cc.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
@ -127,7 +127,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -32,12 +32,11 @@
|
|||||||
#ifndef GNSS_SDR_GALILEO_E1_PCPS_TONG_AMBIGUOUS_ACQUISITION_H_
|
#ifndef GNSS_SDR_GALILEO_E1_PCPS_TONG_AMBIGUOUS_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GALILEO_E1_PCPS_TONG_AMBIGUOUS_ACQUISITION_H_
|
#define GNSS_SDR_GALILEO_E1_PCPS_TONG_AMBIGUOUS_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_tong_acquisition_cc.h"
|
#include "pcps_tong_acquisition_cc.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -127,7 +126,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -38,10 +38,10 @@
|
|||||||
#ifndef GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
|
#ifndef GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
|
||||||
#define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
|
#define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
|
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ public:
|
|||||||
* first available sample.
|
* first available sample.
|
||||||
* \param state - int=1 forces start of acquisition
|
* \param state - int=1 forces start of acquisition
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -57,6 +57,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
|
||||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in_;
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E5a_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
|
||||||
acq_pilot_ = configuration_->property(role + ".acquire_pilot", false);
|
acq_pilot_ = configuration_->property(role + ".acquire_pilot", false);
|
||||||
acq_iq_ = configuration_->property(role + ".acquire_iq", false);
|
acq_iq_ = configuration_->property(role + ".acquire_iq", false);
|
||||||
if (acq_iq_)
|
if (acq_iq_)
|
||||||
@ -100,9 +101,10 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
|
|||||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
}
|
}
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
|
acq_parameters.ms_per_code = 1;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GALILEO_E5a_CODE_PERIOD_MS);
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
|
@ -121,7 +121,7 @@ public:
|
|||||||
* first available sample.
|
* first available sample.
|
||||||
* \param state - int=1 forces start of acquisition
|
* \param state - int=1 forces start of acquisition
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float calculate_threshold(float pfa);
|
float calculate_threshold(float pfa);
|
||||||
|
@ -59,6 +59,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in_;
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GLONASS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||||
dump_ = configuration_->property(role + ".dump", false);
|
dump_ = configuration_->property(role + ".dump", false);
|
||||||
acq_parameters.dump = dump_;
|
acq_parameters.dump = dump_;
|
||||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||||
@ -99,8 +100,9 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
|
|||||||
}
|
}
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.ms_per_code = 1;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD * 1000.0);
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
|
@ -130,7 +130,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -58,6 +58,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in_;
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GLONASS_L2_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||||
dump_ = configuration_->property(role + ".dump", false);
|
dump_ = configuration_->property(role + ".dump", false);
|
||||||
acq_parameters.dump = dump_;
|
acq_parameters.dump = dump_;
|
||||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||||
@ -98,8 +99,9 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
|
|||||||
}
|
}
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.ms_per_code = 1;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD * 1000.0);
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
|
@ -129,7 +129,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -60,6 +60,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in_;
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||||
dump_ = configuration_->property(role + ".dump", false);
|
dump_ = configuration_->property(role + ".dump", false);
|
||||||
acq_parameters.dump = dump_;
|
acq_parameters.dump = dump_;
|
||||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||||
@ -70,6 +71,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
|||||||
acq_parameters.doppler_max = doppler_max_;
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
|
acq_parameters.ms_per_code = 1;
|
||||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||||
@ -82,15 +84,11 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
|||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
//--- Find number of samples per spreading code -------------------------
|
//--- Find number of samples per spreading code -------------------------
|
||||||
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
||||||
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
vector_length_ = code_length_ * sampled_ms_;
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
|
||||||
|
|
||||||
if (bit_transition_flag_)
|
|
||||||
{
|
|
||||||
vector_length_ *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1);
|
||||||
code_ = new gr_complex[vector_length_];
|
code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
if (item_type_.compare("cshort") == 0)
|
if (item_type_.compare("cshort") == 0)
|
||||||
@ -101,8 +99,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
|||||||
{
|
{
|
||||||
item_size_ = sizeof(gr_complex);
|
item_size_ = sizeof(gr_complex);
|
||||||
}
|
}
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
|
||||||
acq_parameters.samples_per_code = code_length_;
|
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
|
@ -134,7 +134,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -33,11 +33,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
|
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
|
||||||
#include <glog/logging.h>
|
|
||||||
#include "gps_sdr_signal_processing.h"
|
#include "gps_sdr_signal_processing.h"
|
||||||
#include "GPS_L1_CA.h"
|
#include "GPS_L1_CA.h"
|
||||||
#include "configuration_interface.h"
|
#include "configuration_interface.h"
|
||||||
#include "gnss_sdr_flags.h"
|
#include "gnss_sdr_flags.h"
|
||||||
|
#include "acq_conf.h"
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
@ -49,29 +50,36 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler(
|
|||||||
std::string default_dump_filename = "./data/acquisition.dat";
|
std::string default_dump_filename = "./data/acquisition.dat";
|
||||||
|
|
||||||
DLOG(INFO) << "role " << role;
|
DLOG(INFO) << "role " << role;
|
||||||
|
Acq_Conf acq_parameters = Acq_Conf();
|
||||||
|
|
||||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||||
long fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||||
dump_ = configuration->property(role + ".dump", false);
|
dump_ = configuration->property(role + ".dump", false);
|
||||||
|
acq_parameters.dump = dump_;
|
||||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||||
|
acq_parameters.dump_filename = dump_filename_;
|
||||||
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
|
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
|
||||||
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
doppler_min_ = configuration->property(role + ".doppler_min", -doppler_max_);
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
sampled_ms_ = configuration->property(role + ".coherent_integration_time_ms", 1);
|
sampled_ms_ = configuration->property(role + ".coherent_integration_time_ms", 1);
|
||||||
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
max_dwells_ = configuration->property(role + ".max_dwells", 1);
|
max_dwells_ = configuration->property(role + ".max_dwells", 1);
|
||||||
|
acq_parameters.max_dwells = max_dwells_;
|
||||||
|
|
||||||
|
acq_parameters.blocking_on_standby = configuration->property(role + ".blocking_on_standby", false);
|
||||||
|
|
||||||
//--- Find number of samples per spreading code -------------------------
|
//--- Find number of samples per spreading code -------------------------
|
||||||
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
|
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
|
||||||
|
acq_parameters.samples_per_ms = vector_length_;
|
||||||
code_ = new gr_complex[vector_length_];
|
code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
item_size_ = sizeof(gr_complex);
|
item_size_ = sizeof(gr_complex);
|
||||||
acquisition_cc_ = pcps_make_acquisition_fine_doppler_cc(max_dwells_, sampled_ms_,
|
acquisition_cc_ = pcps_make_acquisition_fine_doppler_cc(acq_parameters);
|
||||||
doppler_max_, doppler_min_, fs_in_, vector_length_,
|
|
||||||
dump_, dump_filename_);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -161,6 +169,12 @@ void GpsL1CaPcpsAcquisitionFineDoppler::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL1CaPcpsAcquisitionFineDoppler::set_state(int state)
|
||||||
|
{
|
||||||
|
acquisition_cc_->set_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaPcpsAcquisitionFineDoppler::connect(boost::shared_ptr<gr::top_block> top_block)
|
void GpsL1CaPcpsAcquisitionFineDoppler::connect(boost::shared_ptr<gr::top_block> top_block)
|
||||||
{
|
{
|
||||||
if (top_block)
|
if (top_block)
|
||||||
|
@ -34,11 +34,10 @@
|
|||||||
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FINE_DOPPLER_H_
|
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FINE_DOPPLER_H_
|
||||||
#define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FINE_DOPPLER_H_
|
#define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FINE_DOPPLER_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_acquisition_fine_doppler_cc.h"
|
#include "pcps_acquisition_fine_doppler_cc.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -122,6 +121,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
|
*/
|
||||||
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pcps_acquisition_fine_doppler_cc_sptr acquisition_cc_;
|
pcps_acquisition_fine_doppler_cc_sptr acquisition_cc_;
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
@ -131,7 +135,6 @@ private:
|
|||||||
float threshold_;
|
float threshold_;
|
||||||
int doppler_max_;
|
int doppler_max_;
|
||||||
unsigned int doppler_step_;
|
unsigned int doppler_step_;
|
||||||
int doppler_min_;
|
|
||||||
unsigned int sampled_ms_;
|
unsigned int sampled_ms_;
|
||||||
int max_dwells_;
|
int max_dwells_;
|
||||||
long fs_in_;
|
long fs_in_;
|
||||||
|
@ -60,6 +60,7 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in;
|
acq_parameters.fs_in = fs_in;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||||
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||||
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
acq_parameters.doppler_max = doppler_max_;
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
|
@ -132,7 +132,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -34,11 +34,10 @@
|
|||||||
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_ASSISTED_ACQUISITION_H_
|
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_ASSISTED_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GPS_L1_CA_PCPS_ASSISTED_ACQUISITION_H_
|
#define GNSS_SDR_GPS_L1_CA_PCPS_ASSISTED_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_assisted_acquisition_cc.h"
|
#include "pcps_assisted_acquisition_cc.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -121,6 +120,7 @@ public:
|
|||||||
* \brief Restart acquisition algorithm
|
* \brief Restart acquisition algorithm
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
void set_state(int state __attribute__((unused))) override{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pcps_assisted_acquisition_cc_sptr acquisition_cc_;
|
pcps_assisted_acquisition_cc_sptr acquisition_cc_;
|
||||||
|
@ -32,12 +32,11 @@
|
|||||||
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_OPENCL_ACQUISITION_H_
|
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_OPENCL_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GPS_L1_CA_PCPS_OPENCL_ACQUISITION_H_
|
#define GNSS_SDR_GPS_L1_CA_PCPS_OPENCL_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_opencl_acquisition_cc.h"
|
#include "pcps_opencl_acquisition_cc.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -123,6 +122,7 @@ public:
|
|||||||
* \brief Restart acquisition algorithm
|
* \brief Restart acquisition algorithm
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
void set_state(int state __attribute__((unused))) override{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -33,13 +33,12 @@
|
|||||||
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
#define GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_quicksync_acquisition_cc.h"
|
#include "pcps_quicksync_acquisition_cc.h"
|
||||||
#include "configuration_interface.h"
|
#include "configuration_interface.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -129,7 +128,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -32,12 +32,12 @@
|
|||||||
#ifndef GNSS_SDR_GPS_L1_CA_TONG_ACQUISITION_H_
|
#ifndef GNSS_SDR_GPS_L1_CA_TONG_ACQUISITION_H_
|
||||||
#define GNSS_SDR_GPS_L1_CA_TONG_ACQUISITION_H_
|
#define GNSS_SDR_GPS_L1_CA_TONG_ACQUISITION_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "pcps_tong_acquisition_cc.h"
|
#include "pcps_tong_acquisition_cc.h"
|
||||||
#include "configuration_interface.h"
|
#include "configuration_interface.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
@ -60,6 +60,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in_;
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L2_M_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
|
||||||
dump_ = configuration_->property(role + ".dump", false);
|
dump_ = configuration_->property(role + ".dump", false);
|
||||||
acq_parameters.dump = dump_;
|
acq_parameters.dump = dump_;
|
||||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||||
@ -77,15 +78,19 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
acq_parameters.dump_filename = dump_filename_;
|
acq_parameters.dump_filename = dump_filename_;
|
||||||
//--- Find number of samples per spreading code -------------------------
|
//--- Find number of samples per spreading code -------------------------
|
||||||
code_length_ = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS)));
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
|
acq_parameters.ms_per_code = 20;
|
||||||
vector_length_ = code_length_;
|
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
|
||||||
|
if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
|
||||||
if (bit_transition_flag_)
|
|
||||||
{
|
{
|
||||||
vector_length_ *= 2;
|
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20";
|
||||||
|
acq_parameters.sampled_ms = acq_parameters.ms_per_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code_length_ = acq_parameters.ms_per_code * acq_parameters.samples_per_ms;
|
||||||
|
|
||||||
|
vector_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
|
||||||
|
|
||||||
code_ = new gr_complex[vector_length_];
|
code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
if (item_type_.compare("cshort") == 0)
|
if (item_type_.compare("cshort") == 0)
|
||||||
@ -96,13 +101,13 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
{
|
{
|
||||||
item_size_ = sizeof(gr_complex);
|
item_size_ = sizeof(gr_complex);
|
||||||
}
|
}
|
||||||
acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
|
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD * 1000.0);
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = 20;
|
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
||||||
@ -120,6 +125,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
threshold_ = 0.0;
|
threshold_ = 0.0;
|
||||||
doppler_step_ = 0;
|
doppler_step_ = 0;
|
||||||
gnss_synchro_ = 0;
|
gnss_synchro_ = 0;
|
||||||
|
num_codes_ = acq_parameters.sampled_ms / acq_parameters.ms_per_code;
|
||||||
if (in_streams_ > 1)
|
if (in_streams_ > 1)
|
||||||
{
|
{
|
||||||
LOG(ERROR) << "This implementation only supports one input stream";
|
LOG(ERROR) << "This implementation only supports one input stream";
|
||||||
@ -208,9 +214,18 @@ void GpsL2MPcpsAcquisition::init()
|
|||||||
|
|
||||||
void GpsL2MPcpsAcquisition::set_local_code()
|
void GpsL2MPcpsAcquisition::set_local_code()
|
||||||
{
|
{
|
||||||
gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_);
|
std::complex<float>* code = new std::complex<float>[code_length_];
|
||||||
|
|
||||||
|
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < num_codes_; i++)
|
||||||
|
{
|
||||||
|
memcpy(&(code_[i * code_length_]), code,
|
||||||
|
sizeof(gr_complex) * code_length_);
|
||||||
|
}
|
||||||
|
|
||||||
acquisition_->set_local_code(code_);
|
acquisition_->set_local_code(code_);
|
||||||
|
delete[] code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
@ -160,6 +160,7 @@ private:
|
|||||||
std::string role_;
|
std::string role_;
|
||||||
unsigned int in_streams_;
|
unsigned int in_streams_;
|
||||||
unsigned int out_streams_;
|
unsigned int out_streams_;
|
||||||
|
unsigned int num_codes_;
|
||||||
|
|
||||||
float calculate_threshold(float pfa);
|
float calculate_threshold(float pfa);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file gps_l5i pcps_acquisition.cc
|
* \file gps_l5i_pcps_acquisition.cc
|
||||||
* \brief Adapts a PCPS acquisition block to an Acquisition Interface for
|
* \brief Adapts a PCPS acquisition block to an Acquisition Interface for
|
||||||
* GPS L5i signals
|
* GPS L5i signals
|
||||||
* \authors <ul>
|
* \authors <ul>
|
||||||
@ -59,6 +59,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
|
|||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
acq_parameters.fs_in = fs_in_;
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L5i_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
|
||||||
dump_ = configuration_->property(role + ".dump", false);
|
dump_ = configuration_->property(role + ".dump", false);
|
||||||
acq_parameters.dump = dump_;
|
acq_parameters.dump = dump_;
|
||||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||||
@ -95,10 +96,12 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
|
|||||||
{
|
{
|
||||||
item_size_ = sizeof(gr_complex);
|
item_size_ = sizeof(gr_complex);
|
||||||
}
|
}
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L5i_PERIOD * 1000.0);
|
||||||
|
acq_parameters.ms_per_code = 1;
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = 1;
|
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||||
|
num_codes_ = acq_parameters.sampled_ms;
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
@ -205,9 +208,18 @@ void GpsL5iPcpsAcquisition::init()
|
|||||||
|
|
||||||
void GpsL5iPcpsAcquisition::set_local_code()
|
void GpsL5iPcpsAcquisition::set_local_code()
|
||||||
{
|
{
|
||||||
gps_l5i_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_);
|
std::complex<float>* code = new std::complex<float>[code_length_];
|
||||||
|
|
||||||
|
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < num_codes_; i++)
|
||||||
|
{
|
||||||
|
memcpy(&(code_[i * code_length_]), code,
|
||||||
|
sizeof(gr_complex) * code_length_);
|
||||||
|
}
|
||||||
|
|
||||||
acquisition_->set_local_code(code_);
|
acquisition_->set_local_code(code_);
|
||||||
|
delete[] code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file GPS_L5i_PCPS_Acquisition.h
|
* \file gps_l5i_pcps_acquisition.h
|
||||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
* GPS L5i signals
|
* GPS L5i signals
|
||||||
* \authors <ul>
|
* \authors <ul>
|
||||||
@ -132,7 +132,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
@ -158,6 +158,7 @@ private:
|
|||||||
std::complex<float>* code_;
|
std::complex<float>* code_;
|
||||||
Gnss_Synchro* gnss_synchro_;
|
Gnss_Synchro* gnss_synchro_;
|
||||||
std::string role_;
|
std::string role_;
|
||||||
|
unsigned int num_codes_;
|
||||||
unsigned int in_streams_;
|
unsigned int in_streams_;
|
||||||
unsigned int out_streams_;
|
unsigned int out_streams_;
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_)
|
|||||||
|
|
||||||
|
|
||||||
pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition",
|
pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition",
|
||||||
gr::io_signature::make(1, 1, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)),
|
gr::io_signature::make(1, 1, conf_.it_size * std::floor(conf_.sampled_ms * conf_.samples_per_ms) * (conf_.bit_transition_flag ? 2 : 1)),
|
||||||
gr::io_signature::make(0, 0, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)))
|
gr::io_signature::make(0, 0, conf_.it_size))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
|
|
||||||
@ -63,8 +63,17 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
|
|||||||
d_positive_acq = 0;
|
d_positive_acq = 0;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_old_freq = 0;
|
d_old_freq = 0;
|
||||||
d_well_count = 0;
|
d_num_noncoherent_integrations_counter = 0;
|
||||||
d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
|
d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
|
||||||
|
if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
|
||||||
|
{
|
||||||
|
d_fft_size = d_consumed_samples;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_fft_size = d_consumed_samples * 2;
|
||||||
|
}
|
||||||
|
//d_fft_size = next power of two? ////
|
||||||
d_mag = 0;
|
d_mag = 0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_num_doppler_bins = 0;
|
d_num_doppler_bins = 0;
|
||||||
@ -94,12 +103,14 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
|
|||||||
// size of the input buffer and padding the code with zeros.
|
// size of the input buffer and padding the code with zeros.
|
||||||
if (acq_parameters.bit_transition_flag)
|
if (acq_parameters.bit_transition_flag)
|
||||||
{
|
{
|
||||||
d_fft_size *= 2;
|
d_fft_size = d_consumed_samples * 2;
|
||||||
acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells
|
acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d_tmp_buffer = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||||
d_fft_codes = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_fft_codes = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
d_magnitude = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
d_magnitude = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||||
|
d_input_signal = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
|
||||||
// Direct FFT
|
// Direct FFT
|
||||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||||
@ -110,11 +121,12 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
|
|||||||
d_gnss_synchro = 0;
|
d_gnss_synchro = 0;
|
||||||
d_grid_doppler_wipeoffs = nullptr;
|
d_grid_doppler_wipeoffs = nullptr;
|
||||||
d_grid_doppler_wipeoffs_step_two = nullptr;
|
d_grid_doppler_wipeoffs_step_two = nullptr;
|
||||||
|
d_magnitude_grid = nullptr;
|
||||||
d_worker_active = false;
|
d_worker_active = false;
|
||||||
d_data_buffer = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_data_buffer = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_consumed_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
if (d_cshort)
|
if (d_cshort)
|
||||||
{
|
{
|
||||||
d_data_buffer_sc = static_cast<lv_16sc_t*>(volk_gnsssdr_malloc(d_fft_size * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment()));
|
d_data_buffer_sc = static_cast<lv_16sc_t*>(volk_gnsssdr_malloc(d_consumed_samples * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -124,6 +136,16 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
|
|||||||
d_step_two = false;
|
d_step_two = false;
|
||||||
d_dump_number = 0;
|
d_dump_number = 0;
|
||||||
d_dump_channel = acq_parameters.dump_channel;
|
d_dump_channel = acq_parameters.dump_channel;
|
||||||
|
d_samplesPerChip = acq_parameters.samples_per_chip;
|
||||||
|
// todo: CFAR statistic not available for non-coherent integration
|
||||||
|
if (acq_parameters.max_dwells == 1)
|
||||||
|
{
|
||||||
|
d_use_CFAR_algorithm_flag = acq_parameters.use_CFAR_algorithm_flag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_use_CFAR_algorithm_flag = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -134,8 +156,10 @@ pcps_acquisition::~pcps_acquisition()
|
|||||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]);
|
volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]);
|
||||||
|
volk_gnsssdr_free(d_magnitude_grid[i]);
|
||||||
}
|
}
|
||||||
delete[] d_grid_doppler_wipeoffs;
|
delete[] d_grid_doppler_wipeoffs;
|
||||||
|
delete[] d_magnitude_grid;
|
||||||
}
|
}
|
||||||
if (acq_parameters.make_2_steps)
|
if (acq_parameters.make_2_steps)
|
||||||
{
|
{
|
||||||
@ -147,6 +171,8 @@ pcps_acquisition::~pcps_acquisition()
|
|||||||
}
|
}
|
||||||
volk_gnsssdr_free(d_fft_codes);
|
volk_gnsssdr_free(d_fft_codes);
|
||||||
volk_gnsssdr_free(d_magnitude);
|
volk_gnsssdr_free(d_magnitude);
|
||||||
|
volk_gnsssdr_free(d_tmp_buffer);
|
||||||
|
volk_gnsssdr_free(d_input_signal);
|
||||||
delete d_ifft;
|
delete d_ifft;
|
||||||
delete d_fft_if;
|
delete d_fft_if;
|
||||||
volk_gnsssdr_free(d_data_buffer);
|
volk_gnsssdr_free(d_data_buffer);
|
||||||
@ -179,7 +205,15 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_fft_size);
|
if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
|
||||||
|
{
|
||||||
|
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::fill_n(d_fft_if->get_inbuf(), d_fft_size - d_consumed_samples, gr_complex(0.0, 0.0));
|
||||||
|
memcpy(d_fft_if->get_inbuf() + d_consumed_samples, code, sizeof(gr_complex) * d_consumed_samples);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d_fft_if->execute(); // We need the FFT of local code
|
d_fft_if->execute(); // We need the FFT of local code
|
||||||
@ -244,12 +278,20 @@ void pcps_acquisition::init()
|
|||||||
d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d_magnitude_grid = new float*[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++)
|
||||||
{
|
{
|
||||||
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
d_magnitude_grid[doppler_index] = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||||
|
for (unsigned k = 0; k < d_fft_size; k++)
|
||||||
|
{
|
||||||
|
d_magnitude_grid[doppler_index][k] = 0.0;
|
||||||
|
}
|
||||||
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
||||||
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler);
|
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler);
|
||||||
}
|
}
|
||||||
|
|
||||||
d_worker_active = false;
|
d_worker_active = false;
|
||||||
|
|
||||||
if (acq_parameters.dump)
|
if (acq_parameters.dump)
|
||||||
@ -269,6 +311,7 @@ void pcps_acquisition::update_grid_doppler_wipeoffs()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
|
void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
|
||||||
{
|
{
|
||||||
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
|
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
|
||||||
@ -278,6 +321,7 @@ void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::set_state(int state)
|
void pcps_acquisition::set_state(int state)
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||||
@ -288,7 +332,6 @@ void pcps_acquisition::set_state(int state)
|
|||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_step = 0;
|
d_gnss_synchro->Acq_doppler_step = 0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||||
d_well_count = 0;
|
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
@ -419,117 +462,202 @@ void pcps_acquisition::dump_results(int effective_fft_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power, unsigned int num_doppler_bins, int doppler_max, int doppler_step)
|
||||||
|
{
|
||||||
|
float grid_maximum = 0.0;
|
||||||
|
unsigned int index_doppler = 0;
|
||||||
|
uint32_t tmp_intex_t = 0;
|
||||||
|
uint32_t index_time = 0;
|
||||||
|
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||||
|
|
||||||
|
// Find the correlation peak and the carrier frequency
|
||||||
|
for (unsigned int i = 0; i < num_doppler_bins; i++)
|
||||||
|
{
|
||||||
|
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size);
|
||||||
|
if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum)
|
||||||
|
{
|
||||||
|
grid_maximum = d_magnitude_grid[i][tmp_intex_t];
|
||||||
|
index_doppler = i;
|
||||||
|
index_time = tmp_intex_t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indext = index_time;
|
||||||
|
if (!d_step_two)
|
||||||
|
{
|
||||||
|
doppler = -static_cast<int>(doppler_max) + doppler_step * static_cast<int>(index_doppler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doppler = static_cast<int>(d_doppler_center_step_two + (index_doppler - (acq_parameters.num_doppler_bins_step2 / 2.0) * acq_parameters.doppler_step2));
|
||||||
|
}
|
||||||
|
|
||||||
|
float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor);
|
||||||
|
return magt / input_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& doppler, unsigned int num_doppler_bins, int doppler_max, int doppler_step)
|
||||||
|
{
|
||||||
|
// Look for correlation peaks in the results
|
||||||
|
// Find the highest peak and compare it to the second highest peak
|
||||||
|
// The second peak is chosen not closer than 1 chip to the highest peak
|
||||||
|
|
||||||
|
float firstPeak = 0.0;
|
||||||
|
unsigned int index_doppler = 0;
|
||||||
|
uint32_t tmp_intex_t = 0;
|
||||||
|
uint32_t index_time = 0;
|
||||||
|
|
||||||
|
// Find the correlation peak and the carrier frequency
|
||||||
|
for (unsigned int i = 0; i < num_doppler_bins; i++)
|
||||||
|
{
|
||||||
|
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size);
|
||||||
|
if (d_magnitude_grid[i][tmp_intex_t] > firstPeak)
|
||||||
|
{
|
||||||
|
firstPeak = d_magnitude_grid[i][tmp_intex_t];
|
||||||
|
index_doppler = i;
|
||||||
|
index_time = tmp_intex_t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indext = index_time;
|
||||||
|
|
||||||
|
if (!d_step_two)
|
||||||
|
{
|
||||||
|
doppler = -static_cast<int>(doppler_max) + doppler_step * static_cast<int>(index_doppler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doppler = static_cast<int>(d_doppler_center_step_two + (index_doppler - (acq_parameters.num_doppler_bins_step2 / 2.0) * acq_parameters.doppler_step2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find 1 chip wide code phase exclude range around the peak
|
||||||
|
int32_t excludeRangeIndex1 = index_time - d_samplesPerChip;
|
||||||
|
int32_t excludeRangeIndex2 = index_time + d_samplesPerChip;
|
||||||
|
|
||||||
|
// Correct code phase exclude range if the range includes array boundaries
|
||||||
|
if (excludeRangeIndex1 < 0)
|
||||||
|
{
|
||||||
|
excludeRangeIndex1 = d_fft_size + excludeRangeIndex1;
|
||||||
|
}
|
||||||
|
else if (excludeRangeIndex2 >= static_cast<int>(d_fft_size))
|
||||||
|
{
|
||||||
|
excludeRangeIndex2 = excludeRangeIndex2 - d_fft_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t idx = excludeRangeIndex1;
|
||||||
|
memcpy(d_tmp_buffer, d_magnitude_grid[index_doppler], d_fft_size);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
d_tmp_buffer[idx] = 0.0;
|
||||||
|
idx++;
|
||||||
|
if (idx == static_cast<int>(d_fft_size)) idx = 0;
|
||||||
|
}
|
||||||
|
while (idx != excludeRangeIndex2);
|
||||||
|
|
||||||
|
// Find the second highest correlation peak in the same freq. bin ---
|
||||||
|
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_tmp_buffer, d_fft_size);
|
||||||
|
float secondPeak = d_tmp_buffer[tmp_intex_t];
|
||||||
|
|
||||||
|
// Compute the test statistics and compare to the threshold
|
||||||
|
return firstPeak / secondPeak;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lk(d_setlock);
|
gr::thread::scoped_lock lk(d_setlock);
|
||||||
|
|
||||||
// initialize acquisition algorithm
|
// initialize acquisition algorithm
|
||||||
|
int doppler = 0;
|
||||||
uint32_t indext = 0;
|
uint32_t indext = 0;
|
||||||
float magt = 0.0;
|
|
||||||
const gr_complex* in = d_data_buffer; // Get the input samples pointer
|
|
||||||
int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
|
int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
|
||||||
if (d_cshort)
|
if (d_cshort)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_fft_size);
|
volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_consumed_samples);
|
||||||
}
|
}
|
||||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
memcpy(d_input_signal, d_data_buffer, d_consumed_samples * sizeof(gr_complex));
|
||||||
|
if (d_fft_size > d_consumed_samples)
|
||||||
|
{
|
||||||
|
for (unsigned int i = d_consumed_samples; i < d_fft_size; i++)
|
||||||
|
{
|
||||||
|
d_input_signal[i] = gr_complex(0.0, 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const gr_complex* in = d_input_signal; // Get the input samples pointer
|
||||||
|
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_well_count++;
|
d_num_noncoherent_integrations_counter++;
|
||||||
|
|
||||||
DLOG(INFO) << "Channel: " << d_channel
|
DLOG(INFO) << "Channel: " << d_channel
|
||||||
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
||||||
<< " ,sample stamp: " << samp_count << ", threshold: "
|
<< " ,sample stamp: " << samp_count << ", threshold: "
|
||||||
<< d_threshold << ", doppler_max: " << acq_parameters.doppler_max
|
<< d_threshold << ", doppler_max: " << acq_parameters.doppler_max
|
||||||
<< ", doppler_step: " << d_doppler_step
|
<< ", doppler_step: " << d_doppler_step
|
||||||
<< ", use_CFAR_algorithm_flag: " << (acq_parameters.use_CFAR_algorithm_flag ? "true" : "false");
|
<< ", use_CFAR_algorithm_flag: " << (d_use_CFAR_algorithm_flag ? "true" : "false");
|
||||||
|
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
if (acq_parameters.use_CFAR_algorithm_flag)
|
|
||||||
|
if (d_use_CFAR_algorithm_flag or acq_parameters.bit_transition_flag)
|
||||||
{
|
{
|
||||||
// 1- (optional) Compute the input signal power estimation
|
// Compute the input signal power estimation
|
||||||
volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size);
|
volk_32fc_magnitude_squared_32f(d_tmp_buffer, in, d_fft_size);
|
||||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size);
|
volk_32f_accumulator_s32f(&d_input_power, d_tmp_buffer, d_fft_size);
|
||||||
d_input_power /= static_cast<float>(d_fft_size);
|
d_input_power /= static_cast<float>(d_fft_size);
|
||||||
}
|
}
|
||||||
// 2- Doppler frequency search loop
|
|
||||||
|
// Doppler frequency grid loop
|
||||||
if (!d_step_two)
|
if (!d_step_two)
|
||||||
{
|
{
|
||||||
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
|
// Remove Doppler
|
||||||
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
|
||||||
|
|
||||||
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
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)
|
// Perform the FFT-based convolution (parallel time search)
|
||||||
// Compute the FFT of the carrier wiped--off incoming signal
|
// Compute the FFT of the carrier wiped--off incoming signal
|
||||||
d_fft_if->execute();
|
d_fft_if->execute();
|
||||||
|
|
||||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
// Multiply carrier wiped--off, Fourier transformed incoming signal with the local FFT'd code reference
|
||||||
// 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);
|
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||||
|
|
||||||
// compute the inverse FFT
|
// Compute the inverse FFT
|
||||||
d_ifft->execute();
|
d_ifft->execute();
|
||||||
|
|
||||||
// Search maximum
|
// Compute squared magnitude (and accumulate in case of non-coherent integration)
|
||||||
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
|
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
|
||||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
|
if (d_num_noncoherent_integrations_counter == 1)
|
||||||
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
|
|
||||||
magt = d_magnitude[indext];
|
|
||||||
|
|
||||||
if (acq_parameters.use_CFAR_algorithm_flag)
|
|
||||||
{
|
{
|
||||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
|
||||||
}
|
}
|
||||||
// 4- record the maximum peak and the associated synchronization parameters
|
else
|
||||||
if (d_mag < magt)
|
|
||||||
{
|
{
|
||||||
d_mag = magt;
|
volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||||
|
volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size);
|
||||||
if (!acq_parameters.use_CFAR_algorithm_flag)
|
|
||||||
{
|
|
||||||
// Search grid noise floor approximation for this doppler line
|
|
||||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
|
|
||||||
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// In case that acq_parameters.bit_transition_flag = true, we compare the potentially
|
|
||||||
// new maximum test statistics (d_mag/d_input_power) with the value in
|
|
||||||
// d_test_statistics. When the second dwell is being processed, the value
|
|
||||||
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
|
|
||||||
// the maximum test statistics in the previous dwell is greater than
|
|
||||||
// current d_mag/d_input_power). Note that d_test_statistics is not
|
|
||||||
// restarted between consecutive dwells in multidwell operation.
|
|
||||||
|
|
||||||
if (d_test_statistics < (d_mag / d_input_power) or !acq_parameters.bit_transition_flag)
|
|
||||||
{
|
|
||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
|
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
|
||||||
|
|
||||||
// 5- Compute the test statistics and compare to the threshold
|
|
||||||
//d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
|
|
||||||
d_test_statistics = d_mag / d_input_power;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Record results to file if required
|
// Record results to file if required
|
||||||
if (acq_parameters.dump and d_channel == d_dump_channel)
|
if (acq_parameters.dump and d_channel == d_dump_channel)
|
||||||
{
|
{
|
||||||
memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size);
|
memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the test statistic
|
||||||
|
if (d_use_CFAR_algorithm_flag)
|
||||||
|
{
|
||||||
|
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
|
||||||
|
}
|
||||||
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
|
||||||
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
|
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
|
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
|
||||||
{
|
{
|
||||||
// doppler search steps
|
|
||||||
float doppler = d_doppler_center_step_two + (static_cast<float>(doppler_index) - static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2;
|
|
||||||
|
|
||||||
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size);
|
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size);
|
||||||
|
|
||||||
// 3- Perform the FFT-based convolution (parallel time search)
|
// 3- Perform the FFT-based convolution (parallel time search)
|
||||||
@ -543,55 +671,31 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
// compute the inverse FFT
|
// compute the inverse FFT
|
||||||
d_ifft->execute();
|
d_ifft->execute();
|
||||||
|
|
||||||
// Search maximum
|
|
||||||
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
|
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
|
||||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
|
if (d_num_noncoherent_integrations_counter == 1)
|
||||||
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
|
|
||||||
magt = d_magnitude[indext];
|
|
||||||
|
|
||||||
if (acq_parameters.use_CFAR_algorithm_flag)
|
|
||||||
{
|
{
|
||||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
|
||||||
}
|
}
|
||||||
// 4- record the maximum peak and the associated synchronization parameters
|
else
|
||||||
if (d_mag < magt)
|
|
||||||
{
|
{
|
||||||
d_mag = magt;
|
volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||||
|
volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size);
|
||||||
if (!acq_parameters.use_CFAR_algorithm_flag)
|
|
||||||
{
|
|
||||||
// Search grid noise floor approximation for this doppler line
|
|
||||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
|
|
||||||
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// In case that acq_parameters.bit_transition_flag = true, we compare the potentially
|
// Compute the test statistic
|
||||||
// new maximum test statistics (d_mag/d_input_power) with the value in
|
if (d_use_CFAR_algorithm_flag)
|
||||||
// d_test_statistics. When the second dwell is being processed, the value
|
|
||||||
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
|
|
||||||
// the maximum test statistics in the previous dwell is greater than
|
|
||||||
// current d_mag/d_input_power). Note that d_test_statistics is not
|
|
||||||
// restarted between consecutive dwells in multidwell operation.
|
|
||||||
|
|
||||||
if (d_test_statistics < (d_mag / d_input_power) or !acq_parameters.bit_transition_flag)
|
|
||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
|
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, acq_parameters.num_doppler_bins_step2, static_cast<int>(d_doppler_center_step_two - (static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_test_statistics = first_vs_second_peak_statistic(indext, doppler, acq_parameters.num_doppler_bins_step2, static_cast<int>(d_doppler_center_step_two - (static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2);
|
||||||
|
}
|
||||||
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
||||||
|
}
|
||||||
|
|
||||||
// 5- Compute the test statistics and compare to the threshold
|
|
||||||
//d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;
|
|
||||||
d_test_statistics = d_mag / d_input_power;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Record results to file if required
|
|
||||||
if (acq_parameters.dump and d_channel == d_dump_channel)
|
|
||||||
{
|
|
||||||
memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lk.lock();
|
lk.lock();
|
||||||
if (!acq_parameters.bit_transition_flag)
|
if (!acq_parameters.bit_transition_flag)
|
||||||
{
|
{
|
||||||
@ -618,12 +722,13 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
d_state = 0; // Positive acquisition
|
d_state = 0; // Positive acquisition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (d_well_count == acq_parameters.max_dwells)
|
|
||||||
|
if (d_num_noncoherent_integrations_counter == acq_parameters.max_dwells)
|
||||||
{
|
{
|
||||||
|
if (d_state != 0) send_negative_acquisition();
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_step_two = false;
|
d_step_two = false;
|
||||||
send_negative_acquisition();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -659,11 +764,25 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_worker_active = false;
|
d_worker_active = false;
|
||||||
|
|
||||||
|
if ((d_num_noncoherent_integrations_counter == acq_parameters.max_dwells) or (d_positive_acq == 1))
|
||||||
|
{
|
||||||
// Record results to file if required
|
// Record results to file if required
|
||||||
if (acq_parameters.dump and d_channel == d_dump_channel)
|
if (acq_parameters.dump and d_channel == d_dump_channel)
|
||||||
{
|
{
|
||||||
pcps_acquisition::dump_results(effective_fft_size);
|
pcps_acquisition::dump_results(effective_fft_size);
|
||||||
}
|
}
|
||||||
|
d_num_noncoherent_integrations_counter = 0;
|
||||||
|
d_positive_acq = 0;
|
||||||
|
// Reset grid
|
||||||
|
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||||
|
{
|
||||||
|
for (unsigned k = 0; k < d_fft_size; k++)
|
||||||
|
{
|
||||||
|
d_magnitude_grid[i][k] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -681,13 +800,12 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
|
|||||||
* 5. Compute the test statistics and compare to the threshold
|
* 5. Compute the test statistics and compare to the threshold
|
||||||
* 6. Declare positive or negative acquisition using a message port
|
* 6. Declare positive or negative acquisition using a message port
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gr::thread::scoped_lock lk(d_setlock);
|
gr::thread::scoped_lock lk(d_setlock);
|
||||||
if (!d_active or d_worker_active)
|
if (!d_active or d_worker_active)
|
||||||
{
|
{
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += d_fft_size * ninput_items[0];
|
d_sample_counter += d_consumed_samples * ninput_items[0];
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
}
|
}
|
||||||
if (d_step_two)
|
if (d_step_two)
|
||||||
@ -708,14 +826,13 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
|
|||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||||
d_well_count = 0;
|
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
d_state = 1;
|
d_state = 1;
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += d_consumed_samples * ninput_items[0]; // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -726,11 +843,11 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
|
|||||||
// Copy the data to the core and let it know that new data is available
|
// Copy the data to the core and let it know that new data is available
|
||||||
if (d_cshort)
|
if (d_cshort)
|
||||||
{
|
{
|
||||||
memcpy(d_data_buffer_sc, input_items[0], d_fft_size * sizeof(lv_16sc_t));
|
memcpy(d_data_buffer_sc, input_items[0], d_consumed_samples * sizeof(lv_16sc_t));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(d_data_buffer, input_items[0], d_fft_size * sizeof(gr_complex));
|
memcpy(d_data_buffer, input_items[0], d_consumed_samples * sizeof(gr_complex));
|
||||||
}
|
}
|
||||||
if (acq_parameters.blocking)
|
if (acq_parameters.blocking)
|
||||||
{
|
{
|
||||||
@ -742,7 +859,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
|
|||||||
gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter);
|
gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter);
|
||||||
d_worker_active = true;
|
d_worker_active = true;
|
||||||
}
|
}
|
||||||
d_sample_counter += d_fft_size;
|
d_sample_counter += d_consumed_samples;
|
||||||
consume_each(1);
|
consume_each(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -95,24 +95,33 @@ private:
|
|||||||
|
|
||||||
void dump_results(int effective_fft_size);
|
void dump_results(int effective_fft_size);
|
||||||
|
|
||||||
|
float first_vs_second_peak_statistic(uint32_t& indext, int& doppler, unsigned int num_doppler_bins, int doppler_max, int doppler_step);
|
||||||
|
float max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power, unsigned int num_doppler_bins, int doppler_max, int doppler_step);
|
||||||
|
|
||||||
Acq_Conf acq_parameters;
|
Acq_Conf acq_parameters;
|
||||||
bool d_active;
|
bool d_active;
|
||||||
bool d_worker_active;
|
bool d_worker_active;
|
||||||
bool d_cshort;
|
bool d_cshort;
|
||||||
bool d_step_two;
|
bool d_step_two;
|
||||||
|
bool d_use_CFAR_algorithm_flag;
|
||||||
int d_positive_acq;
|
int d_positive_acq;
|
||||||
float d_threshold;
|
float d_threshold;
|
||||||
float d_mag;
|
float d_mag;
|
||||||
float d_input_power;
|
float d_input_power;
|
||||||
float d_test_statistics;
|
float d_test_statistics;
|
||||||
float* d_magnitude;
|
float* d_magnitude;
|
||||||
|
float** d_magnitude_grid;
|
||||||
|
float* d_tmp_buffer;
|
||||||
|
gr_complex* d_input_signal;
|
||||||
|
uint32_t d_samplesPerChip;
|
||||||
long d_old_freq;
|
long d_old_freq;
|
||||||
int d_state;
|
int d_state;
|
||||||
unsigned int d_channel;
|
unsigned int d_channel;
|
||||||
unsigned int d_doppler_step;
|
unsigned int d_doppler_step;
|
||||||
float d_doppler_center_step_two;
|
float d_doppler_center_step_two;
|
||||||
unsigned int d_well_count;
|
unsigned int d_num_noncoherent_integrations_counter;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
|
unsigned int d_consumed_samples;
|
||||||
unsigned int d_num_doppler_bins;
|
unsigned int d_num_doppler_bins;
|
||||||
unsigned long int d_sample_counter;
|
unsigned long int d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
@ -150,7 +159,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Initializes acquisition algorithm.
|
* \brief Initializes acquisition algorithm and reserves memory.
|
||||||
*/
|
*/
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
@ -40,46 +40,41 @@
|
|||||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
#include <algorithm> // std::rotate, std::fill_n
|
#include <algorithm> // std::rotate, std::fill_n
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <matio.h>
|
||||||
|
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
pcps_acquisition_fine_doppler_cc_sptr pcps_make_acquisition_fine_doppler_cc(
|
pcps_acquisition_fine_doppler_cc_sptr pcps_make_acquisition_fine_doppler_cc(const Acq_Conf &conf_)
|
||||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min,
|
|
||||||
long fs_in, int samples_per_ms, bool dump,
|
|
||||||
std::string dump_filename)
|
|
||||||
{
|
{
|
||||||
return pcps_acquisition_fine_doppler_cc_sptr(
|
return pcps_acquisition_fine_doppler_cc_sptr(
|
||||||
new pcps_acquisition_fine_doppler_cc(max_dwells, sampled_ms, doppler_max, doppler_min,
|
new pcps_acquisition_fine_doppler_cc(conf_));
|
||||||
fs_in, samples_per_ms, dump, dump_filename));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(
|
pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Conf &conf_)
|
||||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min,
|
: gr::block("pcps_acquisition_fine_doppler_cc",
|
||||||
long fs_in, int samples_per_ms, 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(1, 1, sizeof(gr_complex)),
|
||||||
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
|
acq_parameters = conf_;
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = conf_.fs_in;
|
||||||
d_samples_per_ms = samples_per_ms;
|
d_samples_per_ms = conf_.samples_per_ms;
|
||||||
d_sampled_ms = sampled_ms;
|
d_config_doppler_max = conf_.doppler_max;
|
||||||
d_config_doppler_max = doppler_max;
|
d_fft_size = d_samples_per_ms;
|
||||||
d_config_doppler_min = doppler_min;
|
|
||||||
d_fft_size = d_sampled_ms * d_samples_per_ms;
|
|
||||||
// HS Acquisition
|
// HS Acquisition
|
||||||
d_max_dwells = max_dwells;
|
d_max_dwells = conf_.max_dwells;
|
||||||
d_gnuradio_forecast_samples = d_fft_size;
|
d_gnuradio_forecast_samples = d_fft_size;
|
||||||
d_input_power = 0.0;
|
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_carrier = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_carrier = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
d_fft_codes = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_fft_codes = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||||
|
|
||||||
|
d_10_ms_buffer = static_cast<gr_complex *>(volk_gnsssdr_malloc(50 * d_samples_per_ms * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
|
||||||
// Direct FFT
|
// Direct FFT
|
||||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||||
|
|
||||||
@ -87,10 +82,10 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(
|
|||||||
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
||||||
|
|
||||||
// For dumping samples into a file
|
// For dumping samples into a file
|
||||||
d_dump = dump;
|
d_dump = conf_.dump;
|
||||||
d_dump_filename = dump_filename;
|
d_dump_filename = conf_.dump_filename;
|
||||||
|
|
||||||
d_doppler_resolution = 0;
|
d_n_samples_in_buffer = 0;
|
||||||
d_threshold = 0;
|
d_threshold = 0;
|
||||||
d_num_doppler_points = 0;
|
d_num_doppler_points = 0;
|
||||||
d_doppler_step = 0;
|
d_doppler_step = 0;
|
||||||
@ -102,21 +97,46 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(
|
|||||||
d_test_statistics = 0;
|
d_test_statistics = 0;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_channel = 0;
|
d_channel = 0;
|
||||||
|
d_positive_acq = 0;
|
||||||
|
d_dump_number = 0;
|
||||||
|
d_dump_channel = 0; // this implementation can only produce dumps in channel 0
|
||||||
|
//todo: migrate config parameters to the unified acquisition config class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Finds next power of two
|
||||||
|
// for n. If n itself is a
|
||||||
|
// power of two then returns n
|
||||||
|
unsigned int pcps_acquisition_fine_doppler_cc::nextPowerOf2(unsigned int n)
|
||||||
|
{
|
||||||
|
n--;
|
||||||
|
n |= n >> 1;
|
||||||
|
n |= n >> 2;
|
||||||
|
n |= n >> 4;
|
||||||
|
n |= n >> 8;
|
||||||
|
n |= n >> 16;
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_step)
|
void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_step)
|
||||||
{
|
{
|
||||||
d_doppler_step = doppler_step;
|
d_doppler_step = doppler_step;
|
||||||
// Create the search grid array
|
// Create the search grid array
|
||||||
|
|
||||||
d_num_doppler_points = floor(std::abs(d_config_doppler_max - d_config_doppler_min) / d_doppler_step);
|
d_num_doppler_points = floor(std::abs(2 * d_config_doppler_max) / d_doppler_step);
|
||||||
|
|
||||||
d_grid_data = new float *[d_num_doppler_points];
|
d_grid_data = new float *[d_num_doppler_points];
|
||||||
for (int i = 0; i < d_num_doppler_points; i++)
|
for (int i = 0; i < d_num_doppler_points; i++)
|
||||||
{
|
{
|
||||||
d_grid_data[i] = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
d_grid_data[i] = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d_dump)
|
||||||
|
{
|
||||||
|
grid_ = arma::fmat(d_fft_size, d_num_doppler_points, arma::fill::zeros);
|
||||||
|
}
|
||||||
|
|
||||||
update_carrier_wipeoff();
|
update_carrier_wipeoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,12 +158,9 @@ pcps_acquisition_fine_doppler_cc::~pcps_acquisition_fine_doppler_cc()
|
|||||||
volk_gnsssdr_free(d_carrier);
|
volk_gnsssdr_free(d_carrier);
|
||||||
volk_gnsssdr_free(d_fft_codes);
|
volk_gnsssdr_free(d_fft_codes);
|
||||||
volk_gnsssdr_free(d_magnitude);
|
volk_gnsssdr_free(d_magnitude);
|
||||||
|
volk_gnsssdr_free(d_10_ms_buffer);
|
||||||
delete d_ifft;
|
delete d_ifft;
|
||||||
delete d_fft_if;
|
delete d_fft_if;
|
||||||
if (d_dump)
|
|
||||||
{
|
|
||||||
d_dump_file.close();
|
|
||||||
}
|
|
||||||
free_grid_memory();
|
free_grid_memory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +184,6 @@ void pcps_acquisition_fine_doppler_cc::init()
|
|||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||||
d_input_power = 0.0;
|
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +203,7 @@ void pcps_acquisition_fine_doppler_cc::reset_grid()
|
|||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
for (int i = 0; i < d_num_doppler_points; i++)
|
for (int i = 0; i < d_num_doppler_points; i++)
|
||||||
{
|
{
|
||||||
|
//todo: use memset here
|
||||||
for (unsigned int j = 0; j < d_fft_size; j++)
|
for (unsigned int j = 0; j < d_fft_size; j++)
|
||||||
{
|
{
|
||||||
d_grid_data[i][j] = 0.0;
|
d_grid_data[i][j] = 0.0;
|
||||||
@ -203,7 +220,7 @@ void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff()
|
|||||||
d_grid_doppler_wipeoffs = new gr_complex *[d_num_doppler_points];
|
d_grid_doppler_wipeoffs = new gr_complex *[d_num_doppler_points];
|
||||||
for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++)
|
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_hz = d_doppler_step * doppler_index - d_config_doppler_max;
|
||||||
// doppler search steps
|
// doppler search steps
|
||||||
// compute the carrier doppler wipe-off signal and store it
|
// compute the carrier doppler wipe-off signal and store it
|
||||||
phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in);
|
phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in);
|
||||||
@ -215,52 +232,70 @@ void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double pcps_acquisition_fine_doppler_cc::search_maximum()
|
double pcps_acquisition_fine_doppler_cc::compute_CAF()
|
||||||
{
|
{
|
||||||
float magt = 0.0;
|
float firstPeak = 0.0;
|
||||||
float fft_normalization_factor;
|
|
||||||
int index_doppler = 0;
|
int index_doppler = 0;
|
||||||
uint32_t tmp_intex_t = 0;
|
uint32_t tmp_intex_t = 0;
|
||||||
uint32_t index_time = 0;
|
uint32_t index_time = 0;
|
||||||
|
|
||||||
|
// Look for correlation peaks in the results ==============================
|
||||||
|
// Find the highest peak and compare it to the second highest peak
|
||||||
|
// The second peak is chosen not closer than 1 chip to the highest peak
|
||||||
|
//--- Find the correlation peak and the carrier frequency --------------
|
||||||
for (int i = 0; i < d_num_doppler_points; i++)
|
for (int i = 0; i < d_num_doppler_points; i++)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[i], d_fft_size);
|
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[i], d_fft_size);
|
||||||
if (d_grid_data[i][tmp_intex_t] > magt)
|
if (d_grid_data[i][tmp_intex_t] > firstPeak)
|
||||||
{
|
{
|
||||||
magt = d_grid_data[i][tmp_intex_t];
|
firstPeak = d_grid_data[i][tmp_intex_t];
|
||||||
//std::cout<<magt<<std::endl;
|
|
||||||
index_doppler = i;
|
index_doppler = i;
|
||||||
index_time = tmp_intex_t;
|
index_time = tmp_intex_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Record results to file if required
|
||||||
|
if (d_dump and d_channel == d_dump_channel)
|
||||||
|
{
|
||||||
|
memcpy(grid_.colptr(i), d_grid_data[i], sizeof(float) * d_fft_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
// -- - Find 1 chip wide code phase exclude range around the peak
|
||||||
fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
uint32_t samplesPerChip = ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(this->d_fs_in));
|
||||||
magt = magt / (fft_normalization_factor * fft_normalization_factor);
|
int32_t excludeRangeIndex1 = index_time - samplesPerChip;
|
||||||
|
int32_t excludeRangeIndex2 = index_time + samplesPerChip;
|
||||||
|
|
||||||
|
// -- - Correct code phase exclude range if the range includes array boundaries
|
||||||
|
if (excludeRangeIndex1 < 0)
|
||||||
|
{
|
||||||
|
excludeRangeIndex1 = d_fft_size + excludeRangeIndex1;
|
||||||
|
}
|
||||||
|
else if (excludeRangeIndex2 >= static_cast<int>(d_fft_size))
|
||||||
|
{
|
||||||
|
excludeRangeIndex2 = excludeRangeIndex2 - d_fft_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t idx = excludeRangeIndex1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
d_grid_data[index_doppler][idx] = 0.0;
|
||||||
|
idx++;
|
||||||
|
if (idx == static_cast<int>(d_fft_size)) idx = 0;
|
||||||
|
}
|
||||||
|
while (idx != excludeRangeIndex2);
|
||||||
|
|
||||||
|
//--- Find the second highest correlation peak in the same freq. bin ---
|
||||||
|
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[index_doppler], d_fft_size);
|
||||||
|
float secondPeak = d_grid_data[index_doppler][tmp_intex_t];
|
||||||
|
|
||||||
// 5- Compute the test statistics and compare to the threshold
|
// 5- Compute the test statistics and compare to the threshold
|
||||||
d_test_statistics = magt / (d_input_power * std::sqrt(d_well_count));
|
d_test_statistics = firstPeak / secondPeak;
|
||||||
|
|
||||||
// 4- record the maximum peak and the associated synchronization parameters
|
// 4- record the maximum peak and the associated synchronization parameters
|
||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(index_time);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(index_time);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(index_doppler * d_doppler_step + d_config_doppler_min);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(index_doppler * d_doppler_step - d_config_doppler_max);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
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(reinterpret_cast<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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +331,7 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons
|
|||||||
// doppler search steps
|
// doppler search steps
|
||||||
// Perform the carrier wipe-off
|
// 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);
|
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)
|
// 3- Perform the FFT-based convolution (parallel time search)
|
||||||
// Compute the FFT of the carrier wiped--off incoming signal
|
// Compute the FFT of the carrier wiped--off incoming signal
|
||||||
d_fft_if->execute();
|
d_fft_if->execute();
|
||||||
@ -308,29 +344,38 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons
|
|||||||
d_ifft->execute();
|
d_ifft->execute();
|
||||||
|
|
||||||
// save the grid matrix delay file
|
// save the grid matrix delay file
|
||||||
|
|
||||||
volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), 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];
|
//accumulate grid values
|
||||||
volk_32f_x2_add_32f(d_grid_data[doppler_index], old_vector, p_tmp_vector, d_fft_size);
|
volk_32f_x2_add_32f(d_grid_data[doppler_index], d_grid_data[doppler_index], p_tmp_vector, d_fft_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
volk_gnsssdr_free(p_tmp_vector);
|
volk_gnsssdr_free(p_tmp_vector);
|
||||||
return d_fft_size;
|
return d_fft_size;
|
||||||
|
//debug
|
||||||
|
// std::cout << "iff=[";
|
||||||
|
// for (int n = 0; n < d_fft_size; n++)
|
||||||
|
// {
|
||||||
|
// std::cout << std::real(d_ifft->get_outbuf()[n]) << "+" << std::imag(d_ifft->get_outbuf()[n]) << "i,";
|
||||||
|
// }
|
||||||
|
// std::cout << "]\n";
|
||||||
|
// getchar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star &input_items)
|
int pcps_acquisition_fine_doppler_cc::estimate_Doppler()
|
||||||
{
|
{
|
||||||
// Direct FFT
|
// Direct FFT
|
||||||
int zero_padding_factor = 2;
|
int zero_padding_factor = 8;
|
||||||
int fft_size_extended = d_fft_size * zero_padding_factor;
|
int prn_replicas = 10;
|
||||||
|
int signal_samples = prn_replicas * d_fft_size;
|
||||||
|
//int fft_size_extended = nextPowerOf2(signal_samples * zero_padding_factor);
|
||||||
|
int fft_size_extended = signal_samples * zero_padding_factor;
|
||||||
gr::fft::fft_complex *fft_operator = new gr::fft::fft_complex(fft_size_extended, true);
|
gr::fft::fft_complex *fft_operator = new gr::fft::fft_complex(fft_size_extended, true);
|
||||||
|
|
||||||
//zero padding the entire vector
|
//zero padding the entire vector
|
||||||
std::fill_n(fft_operator->get_inbuf(), fft_size_extended, gr_complex(0.0, 0.0));
|
std::fill_n(fft_operator->get_inbuf(), fft_size_extended, gr_complex(0.0, 0.0));
|
||||||
|
|
||||||
//1. generate local code aligned with the acquisition code phase estimation
|
//1. generate local code aligned with the acquisition code phase estimation
|
||||||
gr_complex *code_replica = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
gr_complex *code_replica = static_cast<gr_complex *>(volk_gnsssdr_malloc(signal_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
|
||||||
gps_l1_ca_code_gen_complex_sampled(code_replica, d_gnss_synchro->PRN, d_fs_in, 0);
|
gps_l1_ca_code_gen_complex_sampled(code_replica, d_gnss_synchro->PRN, d_fs_in, 0);
|
||||||
|
|
||||||
@ -342,10 +387,12 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star
|
|||||||
std::rotate(code_replica, code_replica + (d_fft_size - shift_index), code_replica + d_fft_size - 1);
|
std::rotate(code_replica, code_replica + (d_fft_size - shift_index), code_replica + d_fft_size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n < prn_replicas - 1; n++)
|
||||||
|
{
|
||||||
|
memcpy(&code_replica[(n + 1) * d_fft_size], code_replica, d_fft_size * sizeof(gr_complex));
|
||||||
|
}
|
||||||
//2. Perform code wipe-off
|
//2. Perform code wipe-off
|
||||||
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]); //Get the input samples pointer
|
volk_32fc_x2_multiply_32fc(fft_operator->get_inbuf(), d_10_ms_buffer, code_replica, signal_samples);
|
||||||
|
|
||||||
volk_32fc_x2_multiply_32fc(fft_operator->get_inbuf(), in, code_replica, d_fft_size);
|
|
||||||
|
|
||||||
// 3. Perform the FFT (zero padded!)
|
// 3. Perform the FFT (zero padded!)
|
||||||
fft_operator->execute();
|
fft_operator->execute();
|
||||||
@ -360,8 +407,8 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star
|
|||||||
|
|
||||||
//case even
|
//case even
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
float *fftFreqBins = new float[fft_size_extended];
|
||||||
|
|
||||||
float fftFreqBins[fft_size_extended];
|
|
||||||
std::fill_n(fftFreqBins, fft_size_extended, 0.0);
|
std::fill_n(fftFreqBins, fft_size_extended, 0.0);
|
||||||
|
|
||||||
for (int k = 0; k < (fft_size_extended / 2); k++)
|
for (int k = 0; k < (fft_size_extended / 2); k++)
|
||||||
@ -372,7 +419,7 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star
|
|||||||
|
|
||||||
for (int k = fft_size_extended / 2; k > 0; k--)
|
for (int k = fft_size_extended / 2; k > 0; k--)
|
||||||
{
|
{
|
||||||
fftFreqBins[counter] = ((-static_cast<float>(d_fs_in) / 2) * static_cast<float>(k)) / (static_cast<float>(fft_size_extended) / 2.0);
|
fftFreqBins[counter] = ((-static_cast<float>(d_fs_in) / 2.0) * static_cast<float>(k)) / (static_cast<float>(fft_size_extended) / 2.0);
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,44 +433,50 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star
|
|||||||
{
|
{
|
||||||
DLOG(INFO) << "Abs(Grid Doppler - FFT Doppler)=" << std::abs(fftFreqBins[tmp_index_freq] - d_gnss_synchro->Acq_doppler_hz);
|
DLOG(INFO) << "Abs(Grid Doppler - FFT Doppler)=" << std::abs(fftFreqBins[tmp_index_freq] - d_gnss_synchro->Acq_doppler_hz);
|
||||||
DLOG(INFO) << "Error estimating fine frequency Doppler";
|
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(reinterpret_cast<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(reinterpret_cast<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(reinterpret_cast<char*>(p_tmp_vector), n); //write directly |abs(x)|^2 in this Doppler bin?
|
|
||||||
// d_dump_file.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// free memory!!
|
// free memory!!
|
||||||
delete fft_operator;
|
delete fft_operator;
|
||||||
volk_gnsssdr_free(code_replica);
|
volk_gnsssdr_free(code_replica);
|
||||||
volk_gnsssdr_free(p_tmp_vector);
|
volk_gnsssdr_free(p_tmp_vector);
|
||||||
|
delete[] fftFreqBins;
|
||||||
return d_fft_size;
|
return d_fft_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Called by gnuradio to enable drivers, etc for i/o devices.
|
||||||
|
bool pcps_acquisition_fine_doppler_cc::start()
|
||||||
|
{
|
||||||
|
d_sample_counter = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pcps_acquisition_fine_doppler_cc::set_state(int state)
|
||||||
|
{
|
||||||
|
//gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||||
|
d_state = state;
|
||||||
|
|
||||||
|
if (d_state == 1)
|
||||||
|
{
|
||||||
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
|
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||||
|
d_well_count = 0;
|
||||||
|
d_test_statistics = 0.0;
|
||||||
|
d_active = true;
|
||||||
|
reset_grid();
|
||||||
|
}
|
||||||
|
else if (d_state == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(ERROR) << "State can only be set to 0 or 1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
||||||
gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items,
|
gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items,
|
||||||
gr_vector_void_star &output_items __attribute__((unused)))
|
gr_vector_void_star &output_items __attribute__((unused)))
|
||||||
@ -442,29 +495,36 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
* S5. Negative_Acq: Send message and stop acq -> S0
|
* S5. Negative_Acq: Send message and stop acq -> S0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int samples_remaining;
|
||||||
switch (d_state)
|
switch (d_state)
|
||||||
{
|
{
|
||||||
case 0: // S0. StandBy
|
case 0: // S0. StandBy
|
||||||
//DLOG(INFO) <<"S0"<<std::endl;
|
|
||||||
if (d_active == true)
|
if (d_active == true)
|
||||||
{
|
{
|
||||||
reset_grid();
|
reset_grid();
|
||||||
|
d_n_samples_in_buffer = 0;
|
||||||
d_state = 1;
|
d_state = 1;
|
||||||
}
|
}
|
||||||
|
if (!acq_parameters.blocking_on_standby)
|
||||||
|
{
|
||||||
|
d_sample_counter += d_fft_size; // sample counter
|
||||||
|
consume_each(d_fft_size);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // S1. ComputeGrid
|
case 1: // S1. ComputeGrid
|
||||||
//DLOG(INFO) <<"S1"<<std::endl;
|
|
||||||
compute_and_accumulate_grid(input_items);
|
compute_and_accumulate_grid(input_items);
|
||||||
|
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), d_fft_size * sizeof(gr_complex));
|
||||||
|
d_n_samples_in_buffer += d_fft_size;
|
||||||
d_well_count++;
|
d_well_count++;
|
||||||
if (d_well_count >= d_max_dwells)
|
if (d_well_count >= d_max_dwells)
|
||||||
{
|
{
|
||||||
d_state = 2;
|
d_state = 2;
|
||||||
}
|
}
|
||||||
|
d_sample_counter += d_fft_size; // sample counter
|
||||||
|
consume_each(d_fft_size);
|
||||||
break;
|
break;
|
||||||
case 2: // Compute test statistics and decide
|
case 2: // Compute test statistics and decide
|
||||||
//DLOG(INFO) <<"S2"<<std::endl;
|
d_test_statistics = compute_CAF();
|
||||||
d_input_power = estimate_input_power(input_items);
|
|
||||||
d_test_statistics = search_maximum();
|
|
||||||
if (d_test_statistics > d_threshold)
|
if (d_test_statistics > d_threshold)
|
||||||
{
|
{
|
||||||
d_state = 3; //perform fine doppler estimation
|
d_state = 3; //perform fine doppler estimation
|
||||||
@ -472,16 +532,34 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_state = 5; //negative acquisition
|
d_state = 5; //negative acquisition
|
||||||
|
d_n_samples_in_buffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 3: // Fine doppler estimation
|
case 3: // Fine doppler estimation
|
||||||
//DLOG(INFO) <<"S3"<<std::endl;
|
samples_remaining = 10 * d_samples_per_ms - d_n_samples_in_buffer;
|
||||||
DLOG(INFO) << "Performing fine Doppler estimation";
|
|
||||||
estimate_Doppler(input_items); //disabled in repo
|
if (samples_remaining > noutput_items)
|
||||||
|
{
|
||||||
|
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), noutput_items * sizeof(gr_complex));
|
||||||
|
d_n_samples_in_buffer += noutput_items;
|
||||||
|
d_sample_counter += noutput_items; // sample counter
|
||||||
|
consume_each(noutput_items);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (samples_remaining > 0)
|
||||||
|
{
|
||||||
|
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), samples_remaining * sizeof(gr_complex));
|
||||||
|
d_sample_counter += samples_remaining; // sample counter
|
||||||
|
consume_each(samples_remaining);
|
||||||
|
}
|
||||||
|
estimate_Doppler(); //disabled in repo
|
||||||
|
d_n_samples_in_buffer = 0;
|
||||||
d_state = 4;
|
d_state = 4;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // Positive_Acq
|
case 4: // Positive_Acq
|
||||||
//DLOG(INFO) <<"S4"<<std::endl;
|
|
||||||
DLOG(INFO) << "positive acquisition";
|
DLOG(INFO) << "positive acquisition";
|
||||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||||
@ -489,15 +567,23 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||||
DLOG(INFO) << "input signal power " << d_input_power;
|
d_positive_acq = 1;
|
||||||
|
|
||||||
d_active = false;
|
d_active = false;
|
||||||
|
// Record results to file if required
|
||||||
|
if (d_dump and d_channel == d_dump_channel)
|
||||||
|
{
|
||||||
|
dump_results(d_fft_size);
|
||||||
|
}
|
||||||
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
if (!acq_parameters.blocking_on_standby)
|
||||||
|
{
|
||||||
|
d_sample_counter += noutput_items; // sample counter
|
||||||
|
consume_each(noutput_items);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // Negative_Acq
|
case 5: // Negative_Acq
|
||||||
//DLOG(INFO) <<"S5"<<std::endl;
|
|
||||||
DLOG(INFO) << "negative acquisition";
|
DLOG(INFO) << "negative acquisition";
|
||||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||||
@ -505,20 +591,108 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||||
DLOG(INFO) << "input signal power " << d_input_power;
|
d_positive_acq = 0;
|
||||||
|
|
||||||
d_active = false;
|
d_active = false;
|
||||||
|
// Record results to file if required
|
||||||
|
if (d_dump and d_channel == d_dump_channel)
|
||||||
|
{
|
||||||
|
dump_results(d_fft_size);
|
||||||
|
}
|
||||||
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
if (!acq_parameters.blocking_on_standby)
|
||||||
|
{
|
||||||
|
d_sample_counter += noutput_items; // sample counter
|
||||||
|
consume_each(noutput_items);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
if (!acq_parameters.blocking_on_standby)
|
||||||
|
{
|
||||||
|
d_sample_counter += noutput_items; // sample counter
|
||||||
|
consume_each(noutput_items);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
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);
|
void pcps_acquisition_fine_doppler_cc::dump_results(int effective_fft_size)
|
||||||
return noutput_items;
|
{
|
||||||
|
d_dump_number++;
|
||||||
|
std::string filename = d_dump_filename;
|
||||||
|
filename.append("_");
|
||||||
|
filename.append(1, d_gnss_synchro->System);
|
||||||
|
filename.append("_");
|
||||||
|
filename.append(1, d_gnss_synchro->Signal[0]);
|
||||||
|
filename.append(1, d_gnss_synchro->Signal[1]);
|
||||||
|
filename.append("_ch_");
|
||||||
|
filename.append(std::to_string(d_channel));
|
||||||
|
filename.append("_");
|
||||||
|
filename.append(std::to_string(d_dump_number));
|
||||||
|
filename.append("_sat_");
|
||||||
|
filename.append(std::to_string(d_gnss_synchro->PRN));
|
||||||
|
filename.append(".mat");
|
||||||
|
|
||||||
|
mat_t *matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
|
||||||
|
if (matfp == NULL)
|
||||||
|
{
|
||||||
|
std::cout << "Unable to create or open Acquisition dump file" << std::endl;
|
||||||
|
d_dump = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t dims[2] = {static_cast<size_t>(effective_fft_size), static_cast<size_t>(d_num_doppler_points)};
|
||||||
|
matvar_t *matvar = Mat_VarCreate("acq_grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
dims[0] = static_cast<size_t>(1);
|
||||||
|
dims[1] = static_cast<size_t>(1);
|
||||||
|
matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_config_doppler_max, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("d_positive_acq", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_positive_acq, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
float aux = static_cast<float>(d_gnss_synchro->Acq_doppler_hz);
|
||||||
|
matvar = Mat_VarCreate("acq_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
aux = static_cast<float>(d_gnss_synchro->Acq_delay_samples);
|
||||||
|
matvar = Mat_VarCreate("acq_delay_samples", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("test_statistic", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_test_statistics, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("threshold", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_threshold, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
aux = 0.0;
|
||||||
|
matvar = Mat_VarCreate("input_power", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("sample_counter", MAT_C_UINT64, MAT_T_UINT64, 1, dims, &d_sample_counter, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_gnss_synchro->PRN, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
Mat_Close(matfp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file pcps_acquisition_fine_doppler_acquisition_cc.h
|
* \file pcps_acquisition_fine_doppler_acquisition_cc.h
|
||||||
* \brief This class implements a Parallel Code Phase Search Acquisition with multi-dwells and fine Doppler estimation
|
* \brief This class implements a Parallel Code Phase Search Acquisition with multi-dwells and fine Doppler estimation
|
||||||
|
* for GPS L1 C/A signal
|
||||||
*
|
*
|
||||||
* Acquisition strategy (Kay Borre book + CFAR threshold).
|
* Acquisition strategy (Kay Borre book).
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li> Compute the input signal power estimation
|
* <li> Compute the input signal power estimation
|
||||||
* <li> Doppler serial search loop
|
* <li> Doppler serial search loop
|
||||||
@ -49,6 +50,8 @@
|
|||||||
#define GNSS_SDR_PCPS_ACQUISITION_FINE_DOPPLER_CC_H_
|
#define GNSS_SDR_PCPS_ACQUISITION_FINE_DOPPLER_CC_H_
|
||||||
|
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
|
#include "acq_conf.h"
|
||||||
|
#include <armadillo>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include <gnuradio/gr_complex.h>
|
#include <gnuradio/gr_complex.h>
|
||||||
#include <gnuradio/fft/fft.h>
|
#include <gnuradio/fft/fft.h>
|
||||||
@ -61,59 +64,44 @@ typedef boost::shared_ptr<pcps_acquisition_fine_doppler_cc>
|
|||||||
pcps_acquisition_fine_doppler_cc_sptr;
|
pcps_acquisition_fine_doppler_cc_sptr;
|
||||||
|
|
||||||
pcps_acquisition_fine_doppler_cc_sptr
|
pcps_acquisition_fine_doppler_cc_sptr
|
||||||
pcps_make_acquisition_fine_doppler_cc(int max_dwells, unsigned int sampled_ms,
|
pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
|
||||||
int doppler_max, int doppler_min, long fs_in, int samples_per_ms,
|
|
||||||
bool dump, std::string dump_filename);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This class implements a Parallel Code Phase Search Acquisition.
|
* \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_acquisition_fine_doppler_cc : public gr::block
|
class pcps_acquisition_fine_doppler_cc : public gr::block
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend pcps_acquisition_fine_doppler_cc_sptr
|
friend pcps_acquisition_fine_doppler_cc_sptr
|
||||||
pcps_make_acquisition_fine_doppler_cc(int max_dwells, unsigned int sampled_ms,
|
pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
|
||||||
int doppler_max, int doppler_min, long fs_in,
|
pcps_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
|
||||||
int samples_per_ms, bool dump,
|
|
||||||
std::string dump_filename);
|
|
||||||
|
|
||||||
pcps_acquisition_fine_doppler_cc(int max_dwells, unsigned int sampled_ms,
|
|
||||||
int doppler_max, int doppler_min, long fs_in,
|
|
||||||
int samples_per_ms, bool dump,
|
|
||||||
std::string dump_filename);
|
|
||||||
|
|
||||||
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
|
|
||||||
int doppler_offset);
|
|
||||||
|
|
||||||
int compute_and_accumulate_grid(gr_vector_const_void_star& input_items);
|
int compute_and_accumulate_grid(gr_vector_const_void_star& input_items);
|
||||||
int estimate_Doppler(gr_vector_const_void_star& input_items);
|
int estimate_Doppler();
|
||||||
float estimate_input_power(gr_vector_const_void_star& input_items);
|
float estimate_input_power(gr_vector_const_void_star& input_items);
|
||||||
double search_maximum();
|
double compute_CAF();
|
||||||
void reset_grid();
|
void reset_grid();
|
||||||
void update_carrier_wipeoff();
|
void update_carrier_wipeoff();
|
||||||
void free_grid_memory();
|
void free_grid_memory();
|
||||||
|
bool start();
|
||||||
|
|
||||||
|
Acq_Conf acq_parameters;
|
||||||
long d_fs_in;
|
long d_fs_in;
|
||||||
int d_samples_per_ms;
|
int d_samples_per_ms;
|
||||||
int d_max_dwells;
|
int d_max_dwells;
|
||||||
unsigned int d_doppler_resolution;
|
|
||||||
int d_gnuradio_forecast_samples;
|
int d_gnuradio_forecast_samples;
|
||||||
float d_threshold;
|
float d_threshold;
|
||||||
std::string d_satellite_str;
|
std::string d_satellite_str;
|
||||||
int d_config_doppler_max;
|
int d_config_doppler_max;
|
||||||
int d_config_doppler_min;
|
|
||||||
|
|
||||||
int d_num_doppler_points;
|
int d_num_doppler_points;
|
||||||
int d_doppler_step;
|
int d_doppler_step;
|
||||||
unsigned int d_sampled_ms;
|
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
unsigned long int d_sample_counter;
|
||||||
gr_complex* d_carrier;
|
gr_complex* d_carrier;
|
||||||
gr_complex* d_fft_codes;
|
gr_complex* d_fft_codes;
|
||||||
|
gr_complex* d_10_ms_buffer;
|
||||||
float* d_magnitude;
|
float* d_magnitude;
|
||||||
|
|
||||||
float** d_grid_data;
|
float** d_grid_data;
|
||||||
@ -124,17 +112,22 @@ private:
|
|||||||
Gnss_Synchro* d_gnss_synchro;
|
Gnss_Synchro* d_gnss_synchro;
|
||||||
unsigned int d_code_phase;
|
unsigned int d_code_phase;
|
||||||
float d_doppler_freq;
|
float d_doppler_freq;
|
||||||
float d_input_power;
|
|
||||||
float d_test_statistics;
|
float d_test_statistics;
|
||||||
std::ofstream d_dump_file;
|
int d_positive_acq;
|
||||||
|
|
||||||
int d_state;
|
int d_state;
|
||||||
bool d_active;
|
bool d_active;
|
||||||
int d_well_count;
|
int d_well_count;
|
||||||
|
int d_n_samples_in_buffer;
|
||||||
bool d_dump;
|
bool d_dump;
|
||||||
unsigned int d_channel;
|
unsigned int d_channel;
|
||||||
|
|
||||||
std::string d_dump_filename;
|
std::string d_dump_filename;
|
||||||
|
|
||||||
|
arma::fmat grid_;
|
||||||
|
long int d_dump_number;
|
||||||
|
unsigned int d_dump_channel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief Default destructor.
|
* \brief Default destructor.
|
||||||
@ -187,6 +180,7 @@ public:
|
|||||||
inline void set_channel(unsigned int channel)
|
inline void set_channel(unsigned int channel)
|
||||||
{
|
{
|
||||||
d_channel = channel;
|
d_channel = channel;
|
||||||
|
d_dump_channel = d_channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -214,6 +208,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
void set_doppler_step(unsigned int doppler_step);
|
void set_doppler_step(unsigned int doppler_step);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief If set to 1, ensures that acquisition starts at the
|
||||||
|
* first available sample.
|
||||||
|
* \param state - int=1 forces start of acquisition
|
||||||
|
*/
|
||||||
|
void set_state(int state);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Parallel Code Phase Search Acquisition signal processing.
|
* \brief Parallel Code Phase Search Acquisition signal processing.
|
||||||
*/
|
*/
|
||||||
@ -222,6 +223,14 @@ public:
|
|||||||
gr_vector_void_star& output_items);
|
gr_vector_void_star& output_items);
|
||||||
|
|
||||||
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
|
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Obtains the next power of 2 greater or equal to the input parameter
|
||||||
|
* \param n - Integer value to obtain the next power of 2.
|
||||||
|
*/
|
||||||
|
unsigned int nextPowerOf2(unsigned int n);
|
||||||
|
|
||||||
|
void dump_results(int effective_fft_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* pcps_acquisition_fine_doppler_cc*/
|
#endif /* pcps_acquisition_fine_doppler_cc*/
|
||||||
|
@ -35,13 +35,15 @@ Acq_Conf::Acq_Conf()
|
|||||||
{
|
{
|
||||||
/* PCPS acquisition configuration */
|
/* PCPS acquisition configuration */
|
||||||
sampled_ms = 0;
|
sampled_ms = 0;
|
||||||
|
ms_per_code = 0;
|
||||||
max_dwells = 0;
|
max_dwells = 0;
|
||||||
|
samples_per_chip = 0;
|
||||||
doppler_max = 0;
|
doppler_max = 0;
|
||||||
num_doppler_bins_step2 = 0;
|
num_doppler_bins_step2 = 0;
|
||||||
doppler_step2 = 0.0;
|
doppler_step2 = 0.0;
|
||||||
fs_in = 0;
|
fs_in = 0;
|
||||||
samples_per_ms = 0;
|
samples_per_ms = 0.0;
|
||||||
samples_per_code = 0;
|
samples_per_code = 0.0;
|
||||||
bit_transition_flag = false;
|
bit_transition_flag = false;
|
||||||
use_CFAR_algorithm_flag = false;
|
use_CFAR_algorithm_flag = false;
|
||||||
dump = false;
|
dump = false;
|
||||||
|
@ -40,13 +40,15 @@ class Acq_Conf
|
|||||||
public:
|
public:
|
||||||
/* PCPS Acquisition configuration */
|
/* PCPS Acquisition configuration */
|
||||||
unsigned int sampled_ms;
|
unsigned int sampled_ms;
|
||||||
|
unsigned int ms_per_code;
|
||||||
|
unsigned int samples_per_chip;
|
||||||
unsigned int max_dwells;
|
unsigned int max_dwells;
|
||||||
unsigned int doppler_max;
|
unsigned int doppler_max;
|
||||||
unsigned int num_doppler_bins_step2;
|
unsigned int num_doppler_bins_step2;
|
||||||
float doppler_step2;
|
float doppler_step2;
|
||||||
long fs_in;
|
long fs_in;
|
||||||
int samples_per_ms;
|
float samples_per_ms;
|
||||||
int samples_per_code;
|
float samples_per_code;
|
||||||
bool bit_transition_flag;
|
bool bit_transition_flag;
|
||||||
bool use_CFAR_algorithm_flag;
|
bool use_CFAR_algorithm_flag;
|
||||||
bool dump;
|
bool dump;
|
||||||
|
@ -144,6 +144,7 @@ void gps_l1_ca_code_gen_complex(std::complex<float>* _dest, signed int _prn, uns
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
|
* Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
|
||||||
|
* NOTICE: the number of samples is rounded towards zero (integer truncation)
|
||||||
*/
|
*/
|
||||||
void gps_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs, unsigned int _chip_shift)
|
void gps_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs, unsigned int _chip_shift)
|
||||||
{
|
{
|
||||||
|
@ -83,26 +83,20 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_stat = 0;
|
d_stat = 0;
|
||||||
d_symbol_accumulator = 0;
|
|
||||||
d_symbol_accumulator_counter = 0;
|
|
||||||
d_frame_bit_index = 0;
|
|
||||||
d_flag_frame_sync = false;
|
d_flag_frame_sync = false;
|
||||||
d_GPS_frame_4bytes = 0;
|
|
||||||
d_prev_GPS_frame_4bytes = 0;
|
d_prev_GPS_frame_4bytes = 0;
|
||||||
d_flag_parity = false;
|
|
||||||
d_TOW_at_Preamble_ms = 0;
|
d_TOW_at_Preamble_ms = 0;
|
||||||
flag_TOW_set = false;
|
flag_TOW_set = false;
|
||||||
d_flag_preamble = false;
|
d_flag_preamble = false;
|
||||||
d_flag_new_tow_available = false;
|
d_flag_new_tow_available = false;
|
||||||
d_word_number = 0;
|
|
||||||
d_channel = 0;
|
d_channel = 0;
|
||||||
flag_PLL_180_deg_phase_locked = false;
|
flag_PLL_180_deg_phase_locked = false;
|
||||||
d_preamble_time_samples = 0;
|
d_preamble_time_samples = 0;
|
||||||
d_TOW_at_current_symbol_ms = 0;
|
d_TOW_at_current_symbol_ms = 0;
|
||||||
d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS + 1); // Change fixed buffer size
|
d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size
|
||||||
d_symbol_history.clear(); // Clear all the elements in the buffer
|
d_symbol_history.clear(); // Clear all the elements in the buffer
|
||||||
d_make_correlation = true;
|
d_crc_error_synchronization_counter = 0;
|
||||||
d_symbol_counter_corr = 0;
|
d_current_subframe_symbol = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -150,9 +144,10 @@ bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(unsigned int gpsword)
|
|||||||
|
|
||||||
void gps_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite)
|
void gps_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite)
|
||||||
{
|
{
|
||||||
|
d_nav.reset();
|
||||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||||
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
|
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
|
||||||
d_GPS_FSM.i_satellite_PRN = d_satellite.get_PRN();
|
d_nav.i_satellite_PRN = d_satellite.get_PRN();
|
||||||
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
|
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +155,7 @@ void gps_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satelli
|
|||||||
void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel)
|
void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel)
|
||||||
{
|
{
|
||||||
d_channel = channel;
|
d_channel = channel;
|
||||||
d_GPS_FSM.i_channel_ID = channel;
|
d_nav.i_channel_ID = channel;
|
||||||
DLOG(INFO) << "Navigation channel set to " << channel;
|
DLOG(INFO) << "Navigation channel set to " << channel;
|
||||||
// ############# ENABLE DATA FILE LOG #################
|
// ############# ENABLE DATA FILE LOG #################
|
||||||
if (d_dump == true)
|
if (d_dump == true)
|
||||||
@ -186,10 +181,127 @@ void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool gps_l1_ca_telemetry_decoder_cc::decode_subframe()
|
||||||
|
{
|
||||||
|
char subframe[GPS_SUBFRAME_LENGTH];
|
||||||
|
|
||||||
|
int symbol_accumulator_counter = 0;
|
||||||
|
int frame_bit_index = 0;
|
||||||
|
int word_index = 0;
|
||||||
|
uint32_t GPS_frame_4bytes = 0;
|
||||||
|
float symbol_accumulator = 0;
|
||||||
|
bool subframe_synchro_confirmation = false;
|
||||||
|
bool CRC_ok = true;
|
||||||
|
|
||||||
|
for (int n = 0; n < GPS_SUBFRAME_MS; n++)
|
||||||
|
{
|
||||||
|
//******* SYMBOL TO BIT *******
|
||||||
|
// extended correlation to bit period is enabled in tracking!
|
||||||
|
symbol_accumulator += d_subframe_symbols[n]; // accumulate the input value in d_symbol_accumulator
|
||||||
|
symbol_accumulator_counter++;
|
||||||
|
if (symbol_accumulator_counter == 20)
|
||||||
|
{
|
||||||
|
//symbol to bit
|
||||||
|
if (symbol_accumulator > 0) GPS_frame_4bytes += 1; //insert the telemetry bit in LSB
|
||||||
|
symbol_accumulator = 0;
|
||||||
|
symbol_accumulator_counter = 0;
|
||||||
|
|
||||||
|
//******* bits to words ******
|
||||||
|
frame_bit_index++;
|
||||||
|
if (frame_bit_index == 30)
|
||||||
|
{
|
||||||
|
frame_bit_index = 0;
|
||||||
|
// parity check
|
||||||
|
// Each word in wordbuff is composed of:
|
||||||
|
// Bits 0 to 29 = the GPS data word
|
||||||
|
// Bits 30 to 31 = 2 LSBs of the GPS word ahead.
|
||||||
|
// prepare the extended frame [-2 -1 0 ... 30]
|
||||||
|
if (d_prev_GPS_frame_4bytes & 0x00000001)
|
||||||
|
{
|
||||||
|
GPS_frame_4bytes = GPS_frame_4bytes | 0x40000000;
|
||||||
|
}
|
||||||
|
if (d_prev_GPS_frame_4bytes & 0x00000002)
|
||||||
|
{
|
||||||
|
GPS_frame_4bytes = GPS_frame_4bytes | 0x80000000;
|
||||||
|
}
|
||||||
|
/* Check that the 2 most recently logged words pass parity. Have to first
|
||||||
|
invert the data bits according to bit 30 of the previous word. */
|
||||||
|
if (GPS_frame_4bytes & 0x40000000)
|
||||||
|
{
|
||||||
|
GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR)
|
||||||
|
}
|
||||||
|
if (gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(GPS_frame_4bytes))
|
||||||
|
{
|
||||||
|
subframe_synchro_confirmation = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//std::cout << "word invalid sat " << this->d_satellite << std::endl;
|
||||||
|
CRC_ok = false;
|
||||||
|
}
|
||||||
|
//add word to subframe
|
||||||
|
// insert the word in the correct position of the subframe
|
||||||
|
std::memcpy(&subframe[word_index * GPS_WORD_LENGTH], &GPS_frame_4bytes, sizeof(uint32_t));
|
||||||
|
word_index++;
|
||||||
|
d_prev_GPS_frame_4bytes = GPS_frame_4bytes; // save the actual frame
|
||||||
|
GPS_frame_4bytes = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GPS_frame_4bytes <<= 1; //shift 1 bit left the telemetry word
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//decode subframe
|
||||||
|
// NEW GPS SUBFRAME HAS ARRIVED!
|
||||||
|
if (CRC_ok)
|
||||||
|
{
|
||||||
|
int subframe_ID = d_nav.subframe_decoder(subframe); //decode the subframe
|
||||||
|
std::cout << "New GPS NAV message received in channel " << this->d_channel << ": "
|
||||||
|
<< "subframe "
|
||||||
|
<< subframe_ID << " from satellite "
|
||||||
|
<< Gnss_Satellite(std::string("GPS"), d_nav.i_satellite_PRN) << std::endl;
|
||||||
|
|
||||||
|
switch (subframe_ID)
|
||||||
|
{
|
||||||
|
case 3: //we have a new set of ephemeris data for the current SV
|
||||||
|
if (d_nav.satellite_validation() == true)
|
||||||
|
{
|
||||||
|
// get ephemeris object for this SV (mandatory)
|
||||||
|
std::shared_ptr<Gps_Ephemeris> tmp_obj = std::make_shared<Gps_Ephemeris>(d_nav.get_ephemeris());
|
||||||
|
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: // Possible IONOSPHERE and UTC model update (page 18)
|
||||||
|
if (d_nav.flag_iono_valid == true)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Gps_Iono> tmp_obj = std::make_shared<Gps_Iono>(d_nav.get_iono());
|
||||||
|
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||||
|
}
|
||||||
|
if (d_nav.flag_utc_model_valid == true)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Gps_Utc_Model> tmp_obj = std::make_shared<Gps_Utc_Model>(d_nav.get_utc_model());
|
||||||
|
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
// get almanac (if available)
|
||||||
|
//TODO: implement almanac reader in navigation_message
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d_flag_new_tow_available = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return subframe_synchro_confirmation;
|
||||||
|
}
|
||||||
|
|
||||||
int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
|
int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||||
{
|
{
|
||||||
int corr_value = 0;
|
|
||||||
int preamble_diff_ms = 0;
|
int preamble_diff_ms = 0;
|
||||||
|
|
||||||
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
|
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
|
||||||
@ -198,15 +310,25 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
|
|||||||
Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block
|
Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block
|
||||||
//1. Copy the current tracking output
|
//1. Copy the current tracking output
|
||||||
current_symbol = in[0][0];
|
current_symbol = in[0][0];
|
||||||
|
|
||||||
|
//record the oldest subframe symbol before inserting a new symbol into the circular buffer
|
||||||
|
if (d_current_subframe_symbol < GPS_SUBFRAME_MS and d_symbol_history.size() > 0)
|
||||||
|
{
|
||||||
|
d_subframe_symbols[d_current_subframe_symbol] = d_symbol_history.at(0).Prompt_I;
|
||||||
|
d_current_subframe_symbol++;
|
||||||
|
}
|
||||||
|
|
||||||
d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue
|
d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue
|
||||||
consume_each(1);
|
consume_each(1);
|
||||||
|
|
||||||
unsigned int required_symbols = GPS_CA_PREAMBLE_LENGTH_SYMBOLS;
|
|
||||||
d_flag_preamble = false;
|
d_flag_preamble = false;
|
||||||
|
|
||||||
if ((d_symbol_history.size() > required_symbols) and (d_make_correlation or !d_flag_frame_sync))
|
|
||||||
{
|
|
||||||
//******* preamble correlation ********
|
//******* preamble correlation ********
|
||||||
|
int corr_value = 0;
|
||||||
|
if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)) // and (d_make_correlation or !d_flag_frame_sync))
|
||||||
|
{
|
||||||
|
// std::cout << "-------\n";
|
||||||
for (unsigned int i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++)
|
for (unsigned int i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++)
|
||||||
{
|
{
|
||||||
if (d_symbol_history.at(i).Flag_valid_symbol_output == true)
|
if (d_symbol_history.at(i).Flag_valid_symbol_output == true)
|
||||||
@ -221,38 +343,27 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (std::abs(corr_value) >= GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
|
|
||||||
{
|
|
||||||
d_symbol_counter_corr++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//******* frame sync ******************
|
//******* frame sync ******************
|
||||||
if (std::abs(corr_value) == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
|
if (std::abs(corr_value) == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
|
||||||
{
|
{
|
||||||
//TODO: Rewrite with state machine
|
//TODO: Rewrite with state machine
|
||||||
if (d_stat == 0)
|
if (d_stat == 0)
|
||||||
{
|
{
|
||||||
d_GPS_FSM.Event_gps_word_preamble();
|
|
||||||
//record the preamble sample stamp
|
//record the preamble sample stamp
|
||||||
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp
|
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp
|
||||||
DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "d_symbol_history.at(0).Tracking_sample_counter=" << d_symbol_history.at(0).Tracking_sample_counter;
|
DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "d_symbol_history.at(0).Tracking_sample_counter=" << d_symbol_history.at(0).Tracking_sample_counter;
|
||||||
//sync the symbol to bits integrator
|
|
||||||
d_symbol_accumulator = 0;
|
|
||||||
d_symbol_accumulator_counter = 0;
|
|
||||||
d_frame_bit_index = 0;
|
|
||||||
d_stat = 1; // enter into frame pre-detection status
|
d_stat = 1; // enter into frame pre-detection status
|
||||||
}
|
}
|
||||||
else if (d_stat == 1) //check 6 seconds of preamble separation
|
else if (d_stat == 1) //check 6 seconds of preamble separation
|
||||||
{
|
{
|
||||||
preamble_diff_ms = std::round(((static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter) - d_preamble_time_samples) / static_cast<double>(d_symbol_history.at(0).fs)) * 1000.0);
|
preamble_diff_ms = std::round(((static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter) - d_preamble_time_samples) / static_cast<double>(d_symbol_history.at(0).fs)) * 1000.0);
|
||||||
if (std::abs(preamble_diff_ms - GPS_SUBFRAME_MS) < 1)
|
if (std::abs(preamble_diff_ms - GPS_SUBFRAME_MS) % GPS_SUBFRAME_MS == 0)
|
||||||
{
|
{
|
||||||
DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite;
|
DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite;
|
||||||
d_GPS_FSM.Event_gps_word_preamble();
|
|
||||||
d_flag_preamble = true;
|
d_flag_preamble = true;
|
||||||
d_make_correlation = false;
|
|
||||||
d_symbol_counter_corr = 0;
|
|
||||||
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the PRN start sample index associated to the preamble
|
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the PRN start sample index associated to the preamble
|
||||||
if (!d_flag_frame_sync)
|
if (!d_flag_frame_sync)
|
||||||
{
|
{
|
||||||
@ -269,131 +380,46 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
|
|||||||
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
|
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
|
||||||
<< static_cast<double>(d_preamble_time_samples) / static_cast<double>(d_symbol_history.at(0).fs) << " [s]";
|
<< static_cast<double>(d_preamble_time_samples) / static_cast<double>(d_symbol_history.at(0).fs) << " [s]";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
//try to decode the subframe:
|
||||||
}
|
if (decode_subframe() == false)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
d_symbol_counter_corr++;
|
d_crc_error_synchronization_counter++;
|
||||||
if (d_symbol_counter_corr > (GPS_SUBFRAME_MS - GPS_CA_TELEMETRY_SYMBOLS_PER_BIT))
|
if (d_crc_error_synchronization_counter > 3)
|
||||||
{
|
{
|
||||||
d_make_correlation = true;
|
DLOG(INFO) << "TOO MANY CRC ERRORS: Lost of frame sync SAT " << this->d_satellite << std::endl;
|
||||||
}
|
|
||||||
if (d_stat == 1)
|
|
||||||
{
|
|
||||||
preamble_diff_ms = round(((static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter) - static_cast<double>(d_preamble_time_samples)) / static_cast<double>(d_symbol_history.at(0).fs)) * 1000.0);
|
|
||||||
if (preamble_diff_ms > GPS_SUBFRAME_MS + 1)
|
|
||||||
{
|
|
||||||
DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms;
|
|
||||||
d_stat = 0; //lost of frame sync
|
d_stat = 0; //lost of frame sync
|
||||||
d_flag_frame_sync = false;
|
d_flag_frame_sync = false;
|
||||||
flag_TOW_set = false;
|
flag_TOW_set = false;
|
||||||
d_make_correlation = true;
|
d_crc_error_synchronization_counter = 0;
|
||||||
d_symbol_counter_corr = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
d_current_subframe_symbol = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//******* SYMBOL TO BIT *******
|
|
||||||
if (d_symbol_history.at(0).Flag_valid_symbol_output == true)
|
|
||||||
{
|
|
||||||
// extended correlation to bit period is enabled in tracking!
|
|
||||||
d_symbol_accumulator += d_symbol_history.at(0).Prompt_I; // accumulate the input value in d_symbol_accumulator
|
|
||||||
d_symbol_accumulator_counter += d_symbol_history.at(0).correlation_length_ms;
|
|
||||||
}
|
}
|
||||||
if (d_symbol_accumulator_counter >= 20)
|
|
||||||
{
|
|
||||||
if (d_symbol_accumulator > 0)
|
|
||||||
{ //symbol to bit
|
|
||||||
d_GPS_frame_4bytes += 1; //insert the telemetry bit in LSB
|
|
||||||
}
|
|
||||||
d_symbol_accumulator = 0;
|
|
||||||
d_symbol_accumulator_counter = 0;
|
|
||||||
//******* bits to words ******
|
|
||||||
d_frame_bit_index++;
|
|
||||||
if (d_frame_bit_index == 30)
|
|
||||||
{
|
|
||||||
d_frame_bit_index = 0;
|
|
||||||
// parity check
|
|
||||||
// Each word in wordbuff is composed of:
|
|
||||||
// Bits 0 to 29 = the GPS data word
|
|
||||||
// Bits 30 to 31 = 2 LSBs of the GPS word ahead.
|
|
||||||
// prepare the extended frame [-2 -1 0 ... 30]
|
|
||||||
if (d_prev_GPS_frame_4bytes & 0x00000001)
|
|
||||||
{
|
|
||||||
d_GPS_frame_4bytes = d_GPS_frame_4bytes | 0x40000000;
|
|
||||||
}
|
|
||||||
if (d_prev_GPS_frame_4bytes & 0x00000002)
|
|
||||||
{
|
|
||||||
d_GPS_frame_4bytes = d_GPS_frame_4bytes | 0x80000000;
|
|
||||||
}
|
|
||||||
/* Check that the 2 most recently logged words pass parity. Have to first
|
|
||||||
invert the data bits according to bit 30 of the previous word. */
|
|
||||||
if (d_GPS_frame_4bytes & 0x40000000)
|
|
||||||
{
|
|
||||||
d_GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR)
|
|
||||||
}
|
|
||||||
if (gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(d_GPS_frame_4bytes))
|
|
||||||
{
|
|
||||||
memcpy(&d_GPS_FSM.d_GPS_frame_4bytes, &d_GPS_frame_4bytes, sizeof(char) * 4);
|
|
||||||
//d_GPS_FSM.d_preamble_time_ms = d_preamble_time_seconds * 1000.0;
|
|
||||||
d_GPS_FSM.Event_gps_word_valid();
|
|
||||||
// send TLM data to PVT using asynchronous message queues
|
|
||||||
if (d_GPS_FSM.d_flag_new_subframe == true)
|
|
||||||
{
|
|
||||||
switch (d_GPS_FSM.d_subframe_ID)
|
|
||||||
{
|
|
||||||
case 3: //we have a new set of ephemeris data for the current SV
|
|
||||||
if (d_GPS_FSM.d_nav.satellite_validation() == true)
|
|
||||||
{
|
|
||||||
// get ephemeris object for this SV (mandatory)
|
|
||||||
std::shared_ptr<Gps_Ephemeris> tmp_obj = std::make_shared<Gps_Ephemeris>(d_GPS_FSM.d_nav.get_ephemeris());
|
|
||||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4: // Possible IONOSPHERE and UTC model update (page 18)
|
|
||||||
if (d_GPS_FSM.d_nav.flag_iono_valid == true)
|
|
||||||
{
|
|
||||||
std::shared_ptr<Gps_Iono> tmp_obj = std::make_shared<Gps_Iono>(d_GPS_FSM.d_nav.get_iono());
|
|
||||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
|
||||||
}
|
|
||||||
if (d_GPS_FSM.d_nav.flag_utc_model_valid == true)
|
|
||||||
{
|
|
||||||
std::shared_ptr<Gps_Utc_Model> tmp_obj = std::make_shared<Gps_Utc_Model>(d_GPS_FSM.d_nav.get_utc_model());
|
|
||||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// get almanac (if available)
|
|
||||||
//TODO: implement almanac reader in navigation_message
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
d_GPS_FSM.clear_flag_new_subframe();
|
|
||||||
d_flag_new_tow_available = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_flag_parity = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_GPS_FSM.Event_gps_word_invalid();
|
if (d_stat == 1)
|
||||||
d_flag_parity = false;
|
|
||||||
}
|
|
||||||
d_prev_GPS_frame_4bytes = d_GPS_frame_4bytes; // save the actual frame
|
|
||||||
d_GPS_frame_4bytes = d_GPS_frame_4bytes & 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
d_GPS_frame_4bytes <<= 1; //shift 1 bit left the telemetry word
|
preamble_diff_ms = round(((static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter) - static_cast<double>(d_preamble_time_samples)) / static_cast<double>(d_symbol_history.at(0).fs)) * 1000.0);
|
||||||
|
if (preamble_diff_ms > GPS_SUBFRAME_MS)
|
||||||
|
{
|
||||||
|
DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms;
|
||||||
|
// std::cout << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms << std::endl;
|
||||||
|
d_stat = 0; //lost of frame sync
|
||||||
|
d_flag_frame_sync = false;
|
||||||
|
flag_TOW_set = false;
|
||||||
|
d_current_subframe_symbol = 0;
|
||||||
|
d_crc_error_synchronization_counter = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//2. Add the telemetry decoder information
|
//2. Add the telemetry decoder information
|
||||||
if (this->d_flag_preamble == true and d_flag_new_tow_available == true)
|
if (this->d_flag_preamble == true and d_flag_new_tow_available == true)
|
||||||
{
|
{
|
||||||
d_TOW_at_current_symbol_ms = static_cast<unsigned int>(d_GPS_FSM.d_nav.d_TOW) * 1000 + GPS_L1_CA_CODE_PERIOD_MS + GPS_CA_PREAMBLE_DURATION_MS;
|
d_TOW_at_current_symbol_ms = static_cast<unsigned int>(d_nav.d_TOW) * 1000 + GPS_L1_CA_CODE_PERIOD_MS + GPS_CA_PREAMBLE_DURATION_MS;
|
||||||
d_TOW_at_Preamble_ms = d_TOW_at_current_symbol_ms;
|
d_TOW_at_Preamble_ms = d_TOW_at_current_symbol_ms;
|
||||||
flag_TOW_set = true;
|
flag_TOW_set = true;
|
||||||
d_flag_new_tow_available = false;
|
d_flag_new_tow_available = false;
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#define GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_CC_H
|
#define GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_CC_H
|
||||||
|
|
||||||
#include "GPS_L1_CA.h"
|
#include "GPS_L1_CA.h"
|
||||||
#include "gps_l1_ca_subframe_fsm.h"
|
#include "gps_navigation_message.h"
|
||||||
#include "gnss_satellite.h"
|
#include "gnss_satellite.h"
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
@ -72,7 +72,9 @@ private:
|
|||||||
|
|
||||||
bool gps_word_parityCheck(unsigned int gpsword);
|
bool gps_word_parityCheck(unsigned int gpsword);
|
||||||
|
|
||||||
// class private vars
|
bool decode_subframe();
|
||||||
|
bool new_decoder();
|
||||||
|
int d_crc_error_synchronization_counter;
|
||||||
|
|
||||||
int *d_preambles_symbols;
|
int *d_preambles_symbols;
|
||||||
unsigned int d_stat;
|
unsigned int d_stat;
|
||||||
@ -80,26 +82,16 @@ private:
|
|||||||
|
|
||||||
// symbols
|
// symbols
|
||||||
boost::circular_buffer<Gnss_Synchro> d_symbol_history;
|
boost::circular_buffer<Gnss_Synchro> d_symbol_history;
|
||||||
|
float d_subframe_symbols[GPS_SUBFRAME_MS]; //symbols per subframe
|
||||||
double d_symbol_accumulator;
|
int d_current_subframe_symbol;
|
||||||
short int d_symbol_accumulator_counter;
|
|
||||||
|
|
||||||
// symbol counting
|
|
||||||
bool d_make_correlation;
|
|
||||||
unsigned int d_symbol_counter_corr;
|
|
||||||
|
|
||||||
//bits and frame
|
//bits and frame
|
||||||
unsigned short int d_frame_bit_index;
|
|
||||||
unsigned int d_GPS_frame_4bytes;
|
|
||||||
unsigned int d_prev_GPS_frame_4bytes;
|
unsigned int d_prev_GPS_frame_4bytes;
|
||||||
bool d_flag_parity;
|
|
||||||
bool d_flag_preamble;
|
bool d_flag_preamble;
|
||||||
bool d_flag_new_tow_available;
|
bool d_flag_new_tow_available;
|
||||||
int d_word_number;
|
|
||||||
|
|
||||||
// navigation message vars
|
// navigation message vars
|
||||||
Gps_Navigation_Message d_nav;
|
Gps_Navigation_Message d_nav;
|
||||||
GpsL1CaSubframeFsm d_GPS_FSM;
|
|
||||||
|
|
||||||
bool d_dump;
|
bool d_dump;
|
||||||
Gnss_Satellite d_satellite;
|
Gnss_Satellite d_satellite;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
add_subdirectory(libswiftcnav)
|
add_subdirectory(libswiftcnav)
|
||||||
|
|
||||||
set(TELEMETRY_DECODER_LIB_SOURCES
|
set(TELEMETRY_DECODER_LIB_SOURCES
|
||||||
gps_l1_ca_subframe_fsm.cc
|
|
||||||
viterbi_decoder.cc
|
viterbi_decoder.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,289 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file gps_l1_ca_subframe_fsm.cc
|
|
||||||
* \brief Implementation of a GPS NAV message word-to-subframe decoder state machine
|
|
||||||
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
|
||||||
*
|
|
||||||
* -------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* -------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gps_l1_ca_subframe_fsm.h"
|
|
||||||
#include "gnss_satellite.h"
|
|
||||||
#include <boost/statechart/simple_state.hpp>
|
|
||||||
#include <boost/statechart/state.hpp>
|
|
||||||
#include <boost/statechart/transition.hpp>
|
|
||||||
#include <boost/statechart/custom_reaction.hpp>
|
|
||||||
#include <boost/mpl/list.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
//************ GPS WORD TO SUBFRAME DECODER STATE MACHINE **********
|
|
||||||
struct Ev_gps_word_valid : sc::event<Ev_gps_word_valid>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Ev_gps_word_invalid : sc::event<Ev_gps_word_invalid>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Ev_gps_word_preamble : sc::event<Ev_gps_word_preamble>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S0 : public sc::state<gps_subframe_fsm_S0, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// sc::transition(event,next_status)
|
|
||||||
typedef sc::transition<Ev_gps_word_preamble, gps_subframe_fsm_S1> reactions;
|
|
||||||
gps_subframe_fsm_S0(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S0 "<<std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S1 : public sc::state<gps_subframe_fsm_S1, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S2> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S1(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S1 "<<std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S2 : public sc::state<gps_subframe_fsm_S2, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S3> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S2(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S2 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S3 : public sc::state<gps_subframe_fsm_S3, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S4> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S3(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S3 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S4 : public sc::state<gps_subframe_fsm_S4, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S5> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S4(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S4 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S5 : public sc::state<gps_subframe_fsm_S5, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S6> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S5(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S5 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(3);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S6 : public sc::state<gps_subframe_fsm_S6, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S7> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S6(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S6 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(4);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S7 : public sc::state<gps_subframe_fsm_S7, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S8> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S7(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S7 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(5);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S8 : public sc::state<gps_subframe_fsm_S8, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S9> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S8(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S8 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(6);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S9 : public sc::state<gps_subframe_fsm_S9, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S10> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S9(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S9 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(7);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S10 : public sc::state<gps_subframe_fsm_S10, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef mpl::list<sc::transition<Ev_gps_word_invalid, gps_subframe_fsm_S0>,
|
|
||||||
sc::transition<Ev_gps_word_valid, gps_subframe_fsm_S11> >
|
|
||||||
reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S10(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Enter S10 "<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(8);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S11 : public sc::state<gps_subframe_fsm_S11, GpsL1CaSubframeFsm>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef sc::transition<Ev_gps_word_preamble, gps_subframe_fsm_S1> reactions;
|
|
||||||
|
|
||||||
gps_subframe_fsm_S11(my_context ctx) : my_base(ctx)
|
|
||||||
{
|
|
||||||
//std::cout<<"Completed GPS Subframe!"<<std::endl;
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_word_to_subframe(9);
|
|
||||||
context<GpsL1CaSubframeFsm>().gps_subframe_to_nav_msg(); //decode the subframe
|
|
||||||
// DECODE SUBFRAME
|
|
||||||
//std::cout<<"Enter S11"<<std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
GpsL1CaSubframeFsm::GpsL1CaSubframeFsm()
|
|
||||||
{
|
|
||||||
d_nav.reset();
|
|
||||||
i_channel_ID = 0;
|
|
||||||
i_satellite_PRN = 0;
|
|
||||||
d_subframe_ID = 0;
|
|
||||||
d_flag_new_subframe = false;
|
|
||||||
initiate(); //start the FSM
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::gps_word_to_subframe(int position)
|
|
||||||
{
|
|
||||||
// insert the word in the correct position of the subframe
|
|
||||||
std::memcpy(&d_subframe[position * GPS_WORD_LENGTH], &d_GPS_frame_4bytes, sizeof(char) * GPS_WORD_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::clear_flag_new_subframe()
|
|
||||||
{
|
|
||||||
d_flag_new_subframe = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
|
|
||||||
{
|
|
||||||
//int subframe_ID;
|
|
||||||
// NEW GPS SUBFRAME HAS ARRIVED!
|
|
||||||
d_subframe_ID = d_nav.subframe_decoder(this->d_subframe); //decode the subframe
|
|
||||||
std::cout << "New GPS NAV message received in channel " << i_channel_ID << ": "
|
|
||||||
<< "subframe "
|
|
||||||
<< d_subframe_ID << " from satellite "
|
|
||||||
<< Gnss_Satellite(std::string("GPS"), i_satellite_PRN) << std::endl;
|
|
||||||
d_nav.i_satellite_PRN = i_satellite_PRN;
|
|
||||||
d_nav.i_channel_ID = i_channel_ID;
|
|
||||||
|
|
||||||
d_flag_new_subframe = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::Event_gps_word_valid()
|
|
||||||
{
|
|
||||||
this->process_event(Ev_gps_word_valid());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::Event_gps_word_invalid()
|
|
||||||
{
|
|
||||||
this->process_event(Ev_gps_word_invalid());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::Event_gps_word_preamble()
|
|
||||||
{
|
|
||||||
this->process_event(Ev_gps_word_preamble());
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file gps_l1_ca_subframe_fsm.h
|
|
||||||
* \brief Interface of a GPS NAV message word-to-subframe decoder state machine
|
|
||||||
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
|
||||||
*
|
|
||||||
* -------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* -------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef GNSS_SDR_GPS_L1_CA_SUBFRAME_FSM_H_
|
|
||||||
#define GNSS_SDR_GPS_L1_CA_SUBFRAME_FSM_H_
|
|
||||||
|
|
||||||
#include "GPS_L1_CA.h"
|
|
||||||
#include "gps_navigation_message.h"
|
|
||||||
#include "gps_ephemeris.h"
|
|
||||||
#include "gps_iono.h"
|
|
||||||
#include "gps_almanac.h"
|
|
||||||
#include "gps_utc_model.h"
|
|
||||||
#include <boost/statechart/state_machine.hpp>
|
|
||||||
|
|
||||||
namespace sc = boost::statechart;
|
|
||||||
namespace mpl = boost::mpl;
|
|
||||||
|
|
||||||
struct gps_subframe_fsm_S0;
|
|
||||||
struct gps_subframe_fsm_S1;
|
|
||||||
struct gps_subframe_fsm_S2;
|
|
||||||
struct gps_subframe_fsm_S3;
|
|
||||||
struct gps_subframe_fsm_S4;
|
|
||||||
struct gps_subframe_fsm_S5;
|
|
||||||
struct gps_subframe_fsm_S6;
|
|
||||||
struct gps_subframe_fsm_S7;
|
|
||||||
struct gps_subframe_fsm_S8;
|
|
||||||
struct gps_subframe_fsm_S9;
|
|
||||||
struct gps_subframe_fsm_S10;
|
|
||||||
struct gps_subframe_fsm_S11;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief This class implements a Finite State Machine that handles the decoding
|
|
||||||
* of the GPS L1 C/A NAV message
|
|
||||||
*/
|
|
||||||
class GpsL1CaSubframeFsm : public sc::state_machine<GpsL1CaSubframeFsm, gps_subframe_fsm_S0>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GpsL1CaSubframeFsm(); //!< The constructor starts the Finite State Machine
|
|
||||||
void clear_flag_new_subframe();
|
|
||||||
// channel and satellite info
|
|
||||||
int i_channel_ID; //!< Channel id
|
|
||||||
unsigned int i_satellite_PRN; //!< Satellite PRN number
|
|
||||||
|
|
||||||
Gps_Navigation_Message d_nav; //!< GPS L1 C/A navigation message object
|
|
||||||
|
|
||||||
// GPS SV and System parameters
|
|
||||||
Gps_Ephemeris ephemeris; //!< Object that handles GPS ephemeris parameters
|
|
||||||
Gps_Almanac almanac; //!< Object that handles GPS almanac data
|
|
||||||
Gps_Utc_Model utc_model; //!< Object that handles UTM model parameters
|
|
||||||
Gps_Iono iono; //!< Object that handles ionospheric parameters
|
|
||||||
|
|
||||||
char d_subframe[GPS_SUBFRAME_LENGTH];
|
|
||||||
int d_subframe_ID;
|
|
||||||
bool d_flag_new_subframe;
|
|
||||||
char d_GPS_frame_4bytes[GPS_WORD_LENGTH];
|
|
||||||
//double d_preamble_time_ms;
|
|
||||||
|
|
||||||
void gps_word_to_subframe(int position); //!< inserts the word in the correct position of the subframe
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief This function decodes a NAv message subframe and pushes the information to the right queues
|
|
||||||
*/
|
|
||||||
void gps_subframe_to_nav_msg();
|
|
||||||
|
|
||||||
//FSM EVENTS
|
|
||||||
void Event_gps_word_valid(); //!< FSM event: the received word is valid
|
|
||||||
void Event_gps_word_invalid(); //!< FSM event: the received word is not valid
|
|
||||||
void Event_gps_word_preamble(); //!< FSM event: word preamble detected
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -50,6 +50,7 @@ include_directories(
|
|||||||
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks
|
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs
|
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||||
|
${ARMADILLO_INCLUDE_DIRS}
|
||||||
${GLOG_INCLUDE_DIRS}
|
${GLOG_INCLUDE_DIRS}
|
||||||
${GFlags_INCLUDE_DIRS}
|
${GFlags_INCLUDE_DIRS}
|
||||||
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||||
|
@ -49,6 +49,7 @@ include_directories(
|
|||||||
${CMAKE_SOURCE_DIR}/src/core/receiver
|
${CMAKE_SOURCE_DIR}/src/core/receiver
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs
|
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||||
|
${ARMADILLO_INCLUDE_DIRS}
|
||||||
${GLOG_INCLUDE_DIRS}
|
${GLOG_INCLUDE_DIRS}
|
||||||
${GFlags_INCLUDE_DIRS}
|
${GFlags_INCLUDE_DIRS}
|
||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* \file dll_pll_veml_tracking.cc
|
* \file dll_pll_veml_tracking.cc
|
||||||
* \brief Implementation of a code DLL + carrier PLL tracking block.
|
* \brief Implementation of a code DLL + carrier PLL tracking block.
|
||||||
* \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com
|
* \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com
|
||||||
|
* Javier Arribas, 2018. jarribas(at)cttc.es
|
||||||
*
|
*
|
||||||
* Code DLL + carrier PLL according to the algorithms described in:
|
* Code DLL + carrier PLL according to the algorithms described in:
|
||||||
* [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
|
* [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
|
||||||
@ -84,10 +85,12 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
|
|||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
this->set_relative_rate(1.0 / static_cast<double>(trk_parameters.vector_length));
|
this->set_relative_rate(1.0 / static_cast<double>(trk_parameters.vector_length));
|
||||||
|
|
||||||
|
// Telemetry bit synchronization message port input (mainly for GPS L1 CA)
|
||||||
|
this->message_port_register_in(pmt::mp("preamble_samplestamp"));
|
||||||
|
|
||||||
// initialize internal vars
|
// initialize internal vars
|
||||||
d_veml = false;
|
d_veml = false;
|
||||||
d_cloop = true;
|
d_cloop = true;
|
||||||
d_synchonizing = false;
|
|
||||||
d_code_chip_rate = 0.0;
|
d_code_chip_rate = 0.0;
|
||||||
d_secondary_code_length = 0;
|
d_secondary_code_length = 0;
|
||||||
d_secondary_code_string = nullptr;
|
d_secondary_code_string = nullptr;
|
||||||
@ -120,6 +123,30 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
|
|||||||
d_secondary = false;
|
d_secondary = false;
|
||||||
trk_parameters.track_pilot = false;
|
trk_parameters.track_pilot = false;
|
||||||
interchange_iq = false;
|
interchange_iq = false;
|
||||||
|
|
||||||
|
// set the preamble
|
||||||
|
unsigned short int preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE;
|
||||||
|
|
||||||
|
// preamble bits to sampled symbols
|
||||||
|
d_gps_l1ca_preambles_symbols = static_cast<int *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment()));
|
||||||
|
int n = 0;
|
||||||
|
for (int i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++)
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
|
||||||
|
{
|
||||||
|
if (preambles_bits[i] == 1)
|
||||||
|
{
|
||||||
|
d_gps_l1ca_preambles_symbols[n] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_gps_l1ca_preambles_symbols[n] = -1;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size
|
||||||
|
d_symbol_history.clear(); // Clear all the elements in the buffer
|
||||||
}
|
}
|
||||||
else if (signal_type.compare("2S") == 0)
|
else if (signal_type.compare("2S") == 0)
|
||||||
{
|
{
|
||||||
@ -399,7 +426,8 @@ void dll_pll_veml_tracking::start_tracking()
|
|||||||
double T_prn_mod_seconds = T_chip_mod_seconds * static_cast<double>(d_code_length_chips);
|
double T_prn_mod_seconds = T_chip_mod_seconds * static_cast<double>(d_code_length_chips);
|
||||||
double T_prn_mod_samples = T_prn_mod_seconds * trk_parameters.fs_in;
|
double T_prn_mod_samples = T_prn_mod_seconds * trk_parameters.fs_in;
|
||||||
|
|
||||||
d_current_prn_length_samples = std::round(T_prn_mod_samples);
|
//d_current_prn_length_samples = std::round(T_prn_mod_samples);
|
||||||
|
d_current_prn_length_samples = std::floor(T_prn_mod_samples);
|
||||||
|
|
||||||
double T_prn_true_seconds = static_cast<double>(d_code_length_chips) / d_code_chip_rate;
|
double T_prn_true_seconds = static_cast<double>(d_code_length_chips) / d_code_chip_rate;
|
||||||
double T_prn_true_samples = T_prn_true_seconds * trk_parameters.fs_in;
|
double T_prn_true_samples = T_prn_true_seconds * trk_parameters.fs_in;
|
||||||
@ -520,7 +548,6 @@ void dll_pll_veml_tracking::start_tracking()
|
|||||||
|
|
||||||
// enable tracking pull-in
|
// enable tracking pull-in
|
||||||
d_state = 1;
|
d_state = 1;
|
||||||
d_synchonizing = false;
|
|
||||||
d_cloop = true;
|
d_cloop = true;
|
||||||
d_Prompt_buffer_deque.clear();
|
d_Prompt_buffer_deque.clear();
|
||||||
d_last_prompt = gr_complex(0.0, 0.0);
|
d_last_prompt = gr_complex(0.0, 0.0);
|
||||||
@ -532,6 +559,11 @@ void dll_pll_veml_tracking::start_tracking()
|
|||||||
|
|
||||||
dll_pll_veml_tracking::~dll_pll_veml_tracking()
|
dll_pll_veml_tracking::~dll_pll_veml_tracking()
|
||||||
{
|
{
|
||||||
|
if (signal_type.compare("1C") == 0)
|
||||||
|
{
|
||||||
|
volk_gnsssdr_free(d_gps_l1ca_preambles_symbols);
|
||||||
|
}
|
||||||
|
|
||||||
if (d_dump_file.is_open())
|
if (d_dump_file.is_open())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -753,7 +785,8 @@ void dll_pll_veml_tracking::update_tracking_vars()
|
|||||||
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
|
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
|
||||||
T_prn_samples = T_prn_seconds * trk_parameters.fs_in;
|
T_prn_samples = T_prn_seconds * trk_parameters.fs_in;
|
||||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * trk_parameters.fs_in;
|
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * trk_parameters.fs_in;
|
||||||
d_current_prn_length_samples = static_cast<int>(round(K_blk_samples)); // round to a discrete number of samples
|
//d_current_prn_length_samples = static_cast<int>(round(K_blk_samples)); // round to a discrete number of samples
|
||||||
|
d_current_prn_length_samples = static_cast<int>(std::floor(K_blk_samples)); // round to a discrete number of samples
|
||||||
|
|
||||||
//################### PLL COMMANDS #################################################
|
//################### PLL COMMANDS #################################################
|
||||||
// carrier phase step (NCO phase increment per sample) [rads/sample]
|
// carrier phase step (NCO phase increment per sample) [rads/sample]
|
||||||
@ -834,6 +867,7 @@ void dll_pll_veml_tracking::log_data(bool integrating)
|
|||||||
float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL;
|
float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL;
|
||||||
float tmp_float;
|
float tmp_float;
|
||||||
double tmp_double;
|
double tmp_double;
|
||||||
|
unsigned long int tmp_long_int;
|
||||||
if (trk_parameters.track_pilot)
|
if (trk_parameters.track_pilot)
|
||||||
{
|
{
|
||||||
if (interchange_iq)
|
if (interchange_iq)
|
||||||
@ -900,7 +934,8 @@ void dll_pll_veml_tracking::log_data(bool integrating)
|
|||||||
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
|
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
|
||||||
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
|
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
|
||||||
// PRN start sample stamp
|
// PRN start sample stamp
|
||||||
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
|
tmp_long_int = d_sample_counter + d_current_prn_length_samples;
|
||||||
|
d_dump_file.write(reinterpret_cast<char *>(&tmp_long_int), sizeof(unsigned long int));
|
||||||
// accumulated carrier phase
|
// accumulated carrier phase
|
||||||
tmp_float = d_acc_carrier_phase_rad;
|
tmp_float = d_acc_carrier_phase_rad;
|
||||||
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
|
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
|
||||||
@ -1277,39 +1312,82 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
|||||||
}
|
}
|
||||||
else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change
|
else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change
|
||||||
{
|
{
|
||||||
if (d_synchonizing)
|
float current_tracking_time_s = static_cast<float>(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in;
|
||||||
|
if (current_tracking_time_s > 10)
|
||||||
{
|
{
|
||||||
if (d_Prompt->real() * d_last_prompt.real() > 0.0)
|
d_symbol_history.push_back(d_Prompt->real());
|
||||||
|
//******* preamble correlation ********
|
||||||
|
int corr_value = 0;
|
||||||
|
if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)) // and (d_make_correlation or !d_flag_frame_sync))
|
||||||
{
|
{
|
||||||
d_current_symbol++;
|
for (unsigned int i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++)
|
||||||
}
|
|
||||||
else if (d_current_symbol > d_symbols_per_bit)
|
|
||||||
{
|
{
|
||||||
d_synchonizing = false;
|
if (d_symbol_history.at(i) < 0) // symbols clipping
|
||||||
d_current_symbol = 1;
|
{
|
||||||
|
corr_value -= d_gps_l1ca_preambles_symbols[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_current_symbol = 1;
|
corr_value += d_gps_l1ca_preambles_symbols[i];
|
||||||
d_last_prompt = *d_Prompt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (d_last_prompt.real() != 0.0)
|
}
|
||||||
|
if (corr_value == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
|
||||||
{
|
{
|
||||||
d_current_symbol++;
|
//std::cout << "Preamble detected at tracking!" << std::endl;
|
||||||
if (d_current_symbol == d_symbols_per_bit) next_state = true;
|
next_state = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_last_prompt = *d_Prompt;
|
next_state = false;
|
||||||
d_synchonizing = true;
|
}
|
||||||
d_current_symbol = 1;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next_state = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
next_state = true;
|
next_state = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ########### Output the tracking results to Telemetry block ##########
|
||||||
|
if (interchange_iq)
|
||||||
|
{
|
||||||
|
if (trk_parameters.track_pilot)
|
||||||
|
{
|
||||||
|
// Note that data and pilot components are in quadrature. I and Q are interchanged
|
||||||
|
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).imag());
|
||||||
|
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).real());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).imag());
|
||||||
|
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).real());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (trk_parameters.track_pilot)
|
||||||
|
{
|
||||||
|
// Note that data and pilot components are in quadrature. I and Q are interchanged
|
||||||
|
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).real());
|
||||||
|
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).imag());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real());
|
||||||
|
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
|
||||||
|
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
|
||||||
|
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
|
||||||
|
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
|
||||||
|
current_synchro_data.Flag_valid_symbol_output = true;
|
||||||
|
current_synchro_data.correlation_length_ms = d_correlation_length_ms;
|
||||||
|
|
||||||
if (next_state)
|
if (next_state)
|
||||||
{ // reset extended correlator
|
{ // reset extended correlator
|
||||||
d_VE_accu = gr_complex(0.0, 0.0);
|
d_VE_accu = gr_complex(0.0, 0.0);
|
||||||
@ -1320,7 +1398,6 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
|||||||
d_last_prompt = gr_complex(0.0, 0.0);
|
d_last_prompt = gr_complex(0.0, 0.0);
|
||||||
d_Prompt_buffer_deque.clear();
|
d_Prompt_buffer_deque.clear();
|
||||||
d_current_symbol = 0;
|
d_current_symbol = 0;
|
||||||
d_synchonizing = false;
|
|
||||||
|
|
||||||
if (d_enable_extended_integration)
|
if (d_enable_extended_integration)
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <boost/circular_buffer.hpp>
|
||||||
|
|
||||||
class dll_pll_veml_tracking;
|
class dll_pll_veml_tracking;
|
||||||
|
|
||||||
@ -69,6 +70,7 @@ private:
|
|||||||
friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_);
|
friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_);
|
||||||
|
|
||||||
dll_pll_veml_tracking(const Dll_Pll_Conf &conf_);
|
dll_pll_veml_tracking(const Dll_Pll_Conf &conf_);
|
||||||
|
void msg_handler_preamble_index(pmt::pmt_t msg);
|
||||||
|
|
||||||
bool cn0_and_tracking_lock_status(double coh_integration_time_s);
|
bool cn0_and_tracking_lock_status(double coh_integration_time_s);
|
||||||
bool acquire_secondary();
|
bool acquire_secondary();
|
||||||
@ -102,9 +104,12 @@ private:
|
|||||||
std::string *d_secondary_code_string;
|
std::string *d_secondary_code_string;
|
||||||
std::string signal_pretty_name;
|
std::string signal_pretty_name;
|
||||||
|
|
||||||
|
uint64_t d_preamble_sample_counter;
|
||||||
|
int *d_gps_l1ca_preambles_symbols;
|
||||||
|
boost::circular_buffer<float> d_symbol_history;
|
||||||
|
|
||||||
//tracking state machine
|
//tracking state machine
|
||||||
int d_state;
|
int d_state;
|
||||||
bool d_synchonizing;
|
|
||||||
//Integration period in samples
|
//Integration period in samples
|
||||||
int d_correlation_length_ms;
|
int d_correlation_length_ms;
|
||||||
int d_n_correlator_taps;
|
int d_n_correlator_taps;
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "tracking_2nd_PLL_filter.h"
|
#include "tracking_2nd_PLL_filter.h"
|
||||||
#include <armadillo>
|
#include <armadillo>
|
||||||
#include "cpu_multicorrelator_real_codes.h"
|
#include "cpu_multicorrelator_real_codes.h"
|
||||||
|
#include "bayesian_estimation.h"
|
||||||
|
|
||||||
class Gps_L1_Ca_Kf_Tracking_cc;
|
class Gps_L1_Ca_Kf_Tracking_cc;
|
||||||
|
|
||||||
@ -133,6 +134,9 @@ private:
|
|||||||
arma::colvec kf_y_pre; //measurement vector
|
arma::colvec kf_y_pre; //measurement vector
|
||||||
arma::mat kf_K; //Kalman gain matrix
|
arma::mat kf_K; //Kalman gain matrix
|
||||||
|
|
||||||
|
// Bayesian estimator
|
||||||
|
Bayesian_estimator cov_est;
|
||||||
|
|
||||||
|
|
||||||
// PLL and DLL filter library
|
// PLL and DLL filter library
|
||||||
Tracking_2nd_DLL_filter d_code_loop_filter;
|
Tracking_2nd_DLL_filter d_code_loop_filter;
|
||||||
|
@ -44,6 +44,7 @@ set(TRACKING_LIB_SOURCES
|
|||||||
tracking_FLL_PLL_filter.cc
|
tracking_FLL_PLL_filter.cc
|
||||||
tracking_loop_filter.cc
|
tracking_loop_filter.cc
|
||||||
dll_pll_conf.cc
|
dll_pll_conf.cc
|
||||||
|
bayesian_estimation.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_FPGA)
|
if(ENABLE_FPGA)
|
||||||
@ -56,6 +57,7 @@ include_directories(
|
|||||||
${CMAKE_SOURCE_DIR}/src/core/interfaces
|
${CMAKE_SOURCE_DIR}/src/core/interfaces
|
||||||
${CMAKE_SOURCE_DIR}/src/core/receiver
|
${CMAKE_SOURCE_DIR}/src/core/receiver
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||||
|
${ARMADILLO_INCLUDE_DIRS}
|
||||||
${VOLK_INCLUDE_DIRS}
|
${VOLK_INCLUDE_DIRS}
|
||||||
${GLOG_INCLUDE_DIRS}
|
${GLOG_INCLUDE_DIRS}
|
||||||
${GFlags_INCLUDE_DIRS}
|
${GFlags_INCLUDE_DIRS}
|
||||||
|
167
src/algorithms/tracking/libs/bayesian_estimation.cc
Normal file
167
src/algorithms/tracking/libs/bayesian_estimation.cc
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*!
|
||||||
|
* \file bayesian_estimation.cc
|
||||||
|
* \brief Interface of a library with Bayesian noise statistic estimation
|
||||||
|
*
|
||||||
|
* Bayesian_estimator is a Bayesian estimator which attempts to estimate
|
||||||
|
* the properties of a stochastic process based on a sequence of
|
||||||
|
* discrete samples of the sequence.
|
||||||
|
*
|
||||||
|
* [1] TODO: Refs
|
||||||
|
*
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> Gerald LaMountain, 2018. gerald(at)ece.neu.edu
|
||||||
|
* <li> Jordi Vila-Valls 2018. jvila(at)cttc.es
|
||||||
|
* </ul>
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bayesian_estimation.h"
|
||||||
|
#include <armadillo>
|
||||||
|
|
||||||
|
Bayesian_estimator::Bayesian_estimator()
|
||||||
|
{
|
||||||
|
kappa_prior = 0;
|
||||||
|
nu_prior = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bayesian_estimator::Bayesian_estimator(int ny)
|
||||||
|
{
|
||||||
|
mu_prior = arma::zeros(ny,1);
|
||||||
|
kappa_prior = 0;
|
||||||
|
nu_prior = 0;
|
||||||
|
Psi_prior = arma::eye(ny,ny) * (nu_prior + ny + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bayesian_estimator::Bayesian_estimator(arma::vec mu_prior_0, int kappa_prior_0, int nu_prior_0, arma::mat Psi_prior_0)
|
||||||
|
{
|
||||||
|
mu_prior = mu_prior_0;
|
||||||
|
kappa_prior = kappa_prior_0;
|
||||||
|
nu_prior = nu_prior_0;
|
||||||
|
Psi_prior = Psi_prior_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bayesian_estimator::~Bayesian_estimator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform Bayesian noise estimation using the normal-inverse-Wishart priors stored in
|
||||||
|
* the class structure, and update the priors according to the computed posteriors
|
||||||
|
*/
|
||||||
|
void Bayesian_estimator::update_sequential(arma::vec data)
|
||||||
|
{
|
||||||
|
int K = data.n_cols;
|
||||||
|
int ny = data.n_rows;
|
||||||
|
|
||||||
|
if (mu_prior.is_empty())
|
||||||
|
{
|
||||||
|
mu_prior = arma::zeros(ny,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Psi_prior.is_empty())
|
||||||
|
{
|
||||||
|
Psi_prior = arma::zeros(ny,ny);
|
||||||
|
}
|
||||||
|
|
||||||
|
arma::vec y_mean = arma::mean(data, 1);
|
||||||
|
arma::mat Psi_N = arma::zeros(ny, ny);
|
||||||
|
|
||||||
|
for (int kk = 0; kk < K; kk++)
|
||||||
|
{
|
||||||
|
Psi_N = Psi_N + (data.col(kk)-y_mean)*((data.col(kk)-y_mean).t());
|
||||||
|
}
|
||||||
|
|
||||||
|
arma::vec mu_posterior = (kappa_prior*mu_prior + K*y_mean) / (kappa_prior + K);
|
||||||
|
int kappa_posterior = kappa_prior + K;
|
||||||
|
int nu_posterior = nu_prior + K;
|
||||||
|
arma::mat Psi_posterior = Psi_prior + Psi_N + (kappa_prior*K)/(kappa_prior + K)*(y_mean - mu_prior)*((y_mean - mu_prior).t());
|
||||||
|
|
||||||
|
mu_est = mu_posterior;
|
||||||
|
if ((nu_posterior - ny - 1) > 0)
|
||||||
|
{
|
||||||
|
Psi_est = Psi_posterior / (nu_posterior - ny - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Psi_est = Psi_posterior / (nu_posterior + ny + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mu_prior = mu_posterior;
|
||||||
|
kappa_prior = kappa_posterior;
|
||||||
|
nu_prior = nu_posterior;
|
||||||
|
Psi_prior = Psi_posterior;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform Bayesian noise estimation using a new set of normal-inverse-Wishart priors
|
||||||
|
* and update the priors according to the computed posteriors
|
||||||
|
*/
|
||||||
|
void Bayesian_estimator::update_sequential(arma::vec data, arma::vec mu_prior_0, int kappa_prior_0, int nu_prior_0, arma::mat Psi_prior_0)
|
||||||
|
{
|
||||||
|
|
||||||
|
int K = data.n_cols;
|
||||||
|
int ny = data.n_rows;
|
||||||
|
|
||||||
|
arma::vec y_mean = arma::mean(data, 1);
|
||||||
|
arma::mat Psi_N = arma::zeros(ny, ny);
|
||||||
|
|
||||||
|
for (int kk = 0; kk < K; kk++)
|
||||||
|
{
|
||||||
|
Psi_N = Psi_N + (data.col(kk)-y_mean)*((data.col(kk)-y_mean).t());
|
||||||
|
}
|
||||||
|
|
||||||
|
arma::vec mu_posterior = (kappa_prior_0*mu_prior_0 + K*y_mean) / (kappa_prior_0 + K);
|
||||||
|
int kappa_posterior = kappa_prior_0 + K;
|
||||||
|
int nu_posterior = nu_prior_0 + K;
|
||||||
|
arma::mat Psi_posterior = Psi_prior_0 + Psi_N + (kappa_prior_0*K)/(kappa_prior_0 + K)*(y_mean - mu_prior_0)*((y_mean - mu_prior_0).t());
|
||||||
|
|
||||||
|
mu_est = mu_posterior;
|
||||||
|
if ((nu_posterior - ny - 1) > 0)
|
||||||
|
{
|
||||||
|
Psi_est = Psi_posterior / (nu_posterior - ny - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Psi_est = Psi_posterior / (nu_posterior + ny + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mu_prior = mu_posterior;
|
||||||
|
kappa_prior = kappa_posterior;
|
||||||
|
nu_prior = nu_posterior;
|
||||||
|
Psi_prior = Psi_posterior;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
arma::vec Bayesian_estimator::get_mu_est()
|
||||||
|
{
|
||||||
|
return mu_est;
|
||||||
|
}
|
||||||
|
|
||||||
|
arma::mat Bayesian_estimator::get_Psi_est()
|
||||||
|
{
|
||||||
|
return Psi_est;
|
||||||
|
}
|
||||||
|
|
86
src/algorithms/tracking/libs/bayesian_estimation.h
Normal file
86
src/algorithms/tracking/libs/bayesian_estimation.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*!
|
||||||
|
* \file bayesian_estimation.h
|
||||||
|
* \brief Interface of a library with Bayesian noise statistic estimation
|
||||||
|
*
|
||||||
|
* Bayesian_estimator is a Bayesian estimator which attempts to estimate
|
||||||
|
* the properties of a stochastic process based on a sequence of
|
||||||
|
* discrete samples of the sequence.
|
||||||
|
*
|
||||||
|
* [1] TODO: Refs
|
||||||
|
*
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> Gerald LaMountain, 2018. gerald(at)ece.neu.edu
|
||||||
|
* <li> Jordi Vila-Valls 2018. jvila(at)cttc.es
|
||||||
|
* </ul>
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNSS_SDR_BAYESIAN_ESTIMATION_H_
|
||||||
|
#define GNSS_SDR_BAYESIAN_ESTIMATION_H_
|
||||||
|
|
||||||
|
#include <gnuradio/gr_complex.h>
|
||||||
|
#include <armadillo>
|
||||||
|
|
||||||
|
/*! \brief Bayesian_estimator is an estimator of noise characteristics (i.e. mean, covariance)
|
||||||
|
*
|
||||||
|
* Bayesian_estimator is an estimator which performs estimation of noise characteristics from
|
||||||
|
* a sequence of identically and independently distributed (IID) samples of a stationary
|
||||||
|
* stochastic process by way of Bayesian inference using conjugate priors. The posterior
|
||||||
|
* distribution is assumed to be Gaussian with mean \mathbf{\mu} and covariance \hat{\mathbf{C}},
|
||||||
|
* which has a conjugate prior given by a normal-inverse-Wishart distribution with paramemters
|
||||||
|
* \mathbf{\mu}_{0}, \kappa_{0}, \nu_{0}, and \mathbf{\Psi}.
|
||||||
|
*
|
||||||
|
* [1] TODO: Ref1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Bayesian_estimator
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Bayesian_estimator();
|
||||||
|
Bayesian_estimator(int ny);
|
||||||
|
Bayesian_estimator(arma::vec mu_prior_0, int kappa_prior_0, int nu_prior_0, arma::mat Psi_prior_0);
|
||||||
|
~Bayesian_estimator();
|
||||||
|
|
||||||
|
void update_sequential(arma::vec data);
|
||||||
|
void update_sequential(arma::vec data, arma::vec mu_prior_0, int kappa_prior_0, int nu_prior_0, arma::mat Psi_prior_0);
|
||||||
|
|
||||||
|
arma::vec get_mu_est();
|
||||||
|
arma::mat get_Psi_est();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
arma::vec mu_est;
|
||||||
|
arma::mat Psi_est;
|
||||||
|
|
||||||
|
arma::vec mu_prior;
|
||||||
|
int kappa_prior;
|
||||||
|
int nu_prior;
|
||||||
|
arma::mat Psi_prior;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -61,6 +61,7 @@ public:
|
|||||||
virtual void set_doppler_step(unsigned int doppler_step) = 0;
|
virtual void set_doppler_step(unsigned int doppler_step) = 0;
|
||||||
virtual void init() = 0;
|
virtual void init() = 0;
|
||||||
virtual void set_local_code() = 0;
|
virtual void set_local_code() = 0;
|
||||||
|
virtual void set_state(int state) = 0;
|
||||||
virtual signed int mag() = 0;
|
virtual signed int mag() = 0;
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,7 @@ include_directories(
|
|||||||
${CMAKE_SOURCE_DIR}/src/core/system_parameters
|
${CMAKE_SOURCE_DIR}/src/core/system_parameters
|
||||||
${GLOG_INCLUDE_DIRS}
|
${GLOG_INCLUDE_DIRS}
|
||||||
${GFlags_INCLUDE_DIRS}
|
${GFlags_INCLUDE_DIRS}
|
||||||
|
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,3 +36,4 @@ list(SORT CORE_MONITOR_LIBS_HEADERS)
|
|||||||
add_library(core_monitor_lib ${CORE_MONITOR_LIBS_SOURCES} ${CORE_MONITOR_LIBS_HEADERS})
|
add_library(core_monitor_lib ${CORE_MONITOR_LIBS_SOURCES} ${CORE_MONITOR_LIBS_HEADERS})
|
||||||
source_group(Headers FILES ${CORE_MONITOR_LIBS_HEADERS})
|
source_group(Headers FILES ${CORE_MONITOR_LIBS_HEADERS})
|
||||||
target_link_libraries(core_monitor_lib ${Boost_LIBRARIES})
|
target_link_libraries(core_monitor_lib ${Boost_LIBRARIES})
|
||||||
|
add_dependencies(core_monitor_lib glog-${glog_RELEASE})
|
||||||
|
@ -418,7 +418,7 @@ void GNSSFlowgraph::connect()
|
|||||||
}
|
}
|
||||||
if (sat == 0)
|
if (sat == 0)
|
||||||
{
|
{
|
||||||
channels_.at(i)->set_signal(search_next_signal(gnss_signal, true));
|
channels_.at(i)->set_signal(search_next_signal(gnss_signal, false));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -896,6 +896,43 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
LOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_[who]->get_signal().get_satellite();
|
LOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_[who]->get_signal().get_satellite();
|
||||||
|
|
||||||
|
// If the satellite is in the list of available ones, remove it.
|
||||||
|
switch (mapStringValues_[channels_[who]->get_signal().get_signal_str()])
|
||||||
|
{
|
||||||
|
case evGPS_1C:
|
||||||
|
available_GPS_1C_signals_.remove(channels_[who]->get_signal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case evGPS_2S:
|
||||||
|
available_GPS_2S_signals_.remove(channels_[who]->get_signal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case evGPS_L5:
|
||||||
|
available_GPS_L5_signals_.remove(channels_[who]->get_signal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case evGAL_1B:
|
||||||
|
available_GAL_1B_signals_.remove(channels_[who]->get_signal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case evGAL_5X:
|
||||||
|
available_GAL_5X_signals_.remove(channels_[who]->get_signal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case evGLO_1G:
|
||||||
|
available_GLO_1G_signals_.remove(channels_[who]->get_signal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case evGLO_2G:
|
||||||
|
available_GLO_2G_signals_.remove(channels_[who]->get_signal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG(ERROR) << "This should not happen :-(";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
channels_state_[who] = 2;
|
channels_state_[who] = 2;
|
||||||
acq_channels_count_--;
|
acq_channels_count_--;
|
||||||
for (unsigned int i = 0; i < channels_count_; i++)
|
for (unsigned int i = 0; i < channels_count_; i++)
|
||||||
@ -1357,9 +1394,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
|
|||||||
{
|
{
|
||||||
case evGPS_1C:
|
case evGPS_1C:
|
||||||
result = available_GPS_1C_signals_.front();
|
result = available_GPS_1C_signals_.front();
|
||||||
if (pop)
|
|
||||||
{
|
|
||||||
available_GPS_1C_signals_.pop_front();
|
available_GPS_1C_signals_.pop_front();
|
||||||
|
if (!pop)
|
||||||
|
{
|
||||||
|
available_GPS_1C_signals_.push_back(result);
|
||||||
}
|
}
|
||||||
if (tracked)
|
if (tracked)
|
||||||
{
|
{
|
||||||
@ -1387,9 +1425,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
|
|||||||
|
|
||||||
case evGPS_2S:
|
case evGPS_2S:
|
||||||
result = available_GPS_2S_signals_.front();
|
result = available_GPS_2S_signals_.front();
|
||||||
if (pop)
|
|
||||||
{
|
|
||||||
available_GPS_2S_signals_.pop_front();
|
available_GPS_2S_signals_.pop_front();
|
||||||
|
if (!pop)
|
||||||
|
{
|
||||||
|
available_GPS_2S_signals_.push_back(result);
|
||||||
}
|
}
|
||||||
if (tracked)
|
if (tracked)
|
||||||
{
|
{
|
||||||
@ -1417,9 +1456,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
|
|||||||
|
|
||||||
case evGPS_L5:
|
case evGPS_L5:
|
||||||
result = available_GPS_L5_signals_.front();
|
result = available_GPS_L5_signals_.front();
|
||||||
if (pop)
|
|
||||||
{
|
|
||||||
available_GPS_L5_signals_.pop_front();
|
available_GPS_L5_signals_.pop_front();
|
||||||
|
if (!pop)
|
||||||
|
{
|
||||||
|
available_GPS_L5_signals_.push_back(result);
|
||||||
}
|
}
|
||||||
if (tracked)
|
if (tracked)
|
||||||
{
|
{
|
||||||
@ -1447,9 +1487,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
|
|||||||
|
|
||||||
case evGAL_1B:
|
case evGAL_1B:
|
||||||
result = available_GAL_1B_signals_.front();
|
result = available_GAL_1B_signals_.front();
|
||||||
if (pop)
|
|
||||||
{
|
|
||||||
available_GAL_1B_signals_.pop_front();
|
available_GAL_1B_signals_.pop_front();
|
||||||
|
if (!pop)
|
||||||
|
{
|
||||||
|
available_GAL_1B_signals_.push_back(result);
|
||||||
}
|
}
|
||||||
if (tracked)
|
if (tracked)
|
||||||
{
|
{
|
||||||
@ -1471,9 +1512,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
|
|||||||
|
|
||||||
case evGAL_5X:
|
case evGAL_5X:
|
||||||
result = available_GAL_5X_signals_.front();
|
result = available_GAL_5X_signals_.front();
|
||||||
if (pop)
|
|
||||||
{
|
|
||||||
available_GAL_5X_signals_.pop_front();
|
available_GAL_5X_signals_.pop_front();
|
||||||
|
if (!pop)
|
||||||
|
{
|
||||||
|
available_GAL_5X_signals_.push_back(result);
|
||||||
}
|
}
|
||||||
if (tracked)
|
if (tracked)
|
||||||
{
|
{
|
||||||
@ -1495,9 +1537,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
|
|||||||
|
|
||||||
case evGLO_1G:
|
case evGLO_1G:
|
||||||
result = available_GLO_1G_signals_.front();
|
result = available_GLO_1G_signals_.front();
|
||||||
if (pop)
|
|
||||||
{
|
|
||||||
available_GLO_1G_signals_.pop_front();
|
available_GLO_1G_signals_.pop_front();
|
||||||
|
if (!pop)
|
||||||
|
{
|
||||||
|
available_GLO_1G_signals_.push_back(result);
|
||||||
}
|
}
|
||||||
if (tracked)
|
if (tracked)
|
||||||
{
|
{
|
||||||
@ -1519,9 +1562,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
|
|||||||
|
|
||||||
case evGLO_2G:
|
case evGLO_2G:
|
||||||
result = available_GLO_2G_signals_.front();
|
result = available_GLO_2G_signals_.front();
|
||||||
if (pop)
|
|
||||||
{
|
|
||||||
available_GLO_2G_signals_.pop_front();
|
available_GLO_2G_signals_.pop_front();
|
||||||
|
if (!pop)
|
||||||
|
{
|
||||||
|
available_GLO_2G_signals_.push_back(result);
|
||||||
}
|
}
|
||||||
if (tracked)
|
if (tracked)
|
||||||
{
|
{
|
||||||
|
@ -84,6 +84,9 @@ public:
|
|||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
void serialize(Archive& ar, const unsigned int version)
|
||||||
{
|
{
|
||||||
|
if (version)
|
||||||
|
{
|
||||||
|
};
|
||||||
// Satellite and signal info
|
// Satellite and signal info
|
||||||
ar& System;
|
ar& System;
|
||||||
ar& Signal;
|
ar& Signal;
|
||||||
|
@ -34,8 +34,15 @@
|
|||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
|
DEFINE_string(trk_test_implementation, std::string("GPS_L1_CA_DLL_PLL_Tracking"), "Tracking block implementation under test, defaults to GPS_L1_CA_DLL_PLL_Tracking");
|
||||||
// Input signal configuration
|
// Input signal configuration
|
||||||
DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator");
|
DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator");
|
||||||
|
DEFINE_double(external_signal_acquisition_threshold, 2.5, "Threshold for satellite acquisition when external file is used");
|
||||||
|
DEFINE_int32(external_signal_acquisition_dwells, 5, "Maximum dwells count for satellite acquisition when external file is used");
|
||||||
|
DEFINE_double(external_signal_acquisition_doppler_max_hz, 5000.0, "Doppler max for satellite acquisition when external file is used");
|
||||||
|
DEFINE_double(external_signal_acquisition_doppler_step_hz, 125, "Doppler step for satellite acquisition when external file is used");
|
||||||
|
|
||||||
DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file");
|
DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file");
|
||||||
DEFINE_double(CN0_dBHz_start, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]");
|
DEFINE_double(CN0_dBHz_start, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]");
|
||||||
DEFINE_double(CN0_dBHz_stop, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]");
|
DEFINE_double(CN0_dBHz_stop, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]");
|
||||||
@ -60,9 +67,12 @@ DEFINE_double(acq_Delay_error_chips_start, 2.0, "Acquisition Code Delay error st
|
|||||||
DEFINE_double(acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Chips]");
|
DEFINE_double(acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Chips]");
|
||||||
DEFINE_double(acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Chips]");
|
DEFINE_double(acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Chips]");
|
||||||
|
|
||||||
|
DEFINE_int64(skip_samples, 0, "Skip an initial transitory in the processed signal file capture [samples]");
|
||||||
|
|
||||||
DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters");
|
DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters");
|
||||||
|
|
||||||
|
DEFINE_double(skip_trk_transitory_s, 1.0, "Skip the initial tracking output signal to avoid transitory results [s]");
|
||||||
|
|
||||||
//Emulated acquisition configuration
|
//Emulated acquisition configuration
|
||||||
|
|
||||||
//Tracking configuration
|
//Tracking configuration
|
||||||
|
@ -600,6 +600,14 @@ void ObsSystemTest::compute_pseudorange_error(
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("linespoints");
|
Gnuplot g1("linespoints");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title(signal_name + " Pseudorange error");
|
g1.set_title(signal_name + " Pseudorange error");
|
||||||
g1.set_grid();
|
g1.set_grid();
|
||||||
g1.set_xlabel("PRN");
|
g1.set_xlabel("PRN");
|
||||||
@ -620,7 +628,6 @@ void ObsSystemTest::compute_pseudorange_error(
|
|||||||
}
|
}
|
||||||
g1.savetops("Pseudorange_error_" + signal_name);
|
g1.savetops("Pseudorange_error_" + signal_name);
|
||||||
g1.savetopdf("Pseudorange_error_" + signal_name, 18);
|
g1.savetopdf("Pseudorange_error_" + signal_name, 18);
|
||||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
@ -691,6 +698,14 @@ void ObsSystemTest::compute_carrierphase_error(
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("linespoints");
|
Gnuplot g1("linespoints");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title(signal_name + " Carrier phase error");
|
g1.set_title(signal_name + " Carrier phase error");
|
||||||
g1.set_grid();
|
g1.set_grid();
|
||||||
g1.set_xlabel("PRN");
|
g1.set_xlabel("PRN");
|
||||||
@ -711,7 +726,6 @@ void ObsSystemTest::compute_carrierphase_error(
|
|||||||
}
|
}
|
||||||
g1.savetops("Carrier_phase_error_" + signal_name);
|
g1.savetops("Carrier_phase_error_" + signal_name);
|
||||||
g1.savetopdf("Carrier_phase_error_" + signal_name, 18);
|
g1.savetopdf("Carrier_phase_error_" + signal_name, 18);
|
||||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
@ -782,6 +796,14 @@ void ObsSystemTest::compute_doppler_error(
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("linespoints");
|
Gnuplot g1("linespoints");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title(signal_name + " Doppler error");
|
g1.set_title(signal_name + " Doppler error");
|
||||||
g1.set_grid();
|
g1.set_grid();
|
||||||
g1.set_xlabel("PRN");
|
g1.set_xlabel("PRN");
|
||||||
@ -802,7 +824,6 @@ void ObsSystemTest::compute_doppler_error(
|
|||||||
}
|
}
|
||||||
g1.savetops("Doppler_error_" + signal_name);
|
g1.savetops("Doppler_error_" + signal_name);
|
||||||
g1.savetopdf("Doppler_error_" + signal_name, 18);
|
g1.savetopdf("Doppler_error_" + signal_name, 18);
|
||||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
|
@ -619,6 +619,14 @@ void StaticPositionSystemTest::print_results(const std::vector<double>& east,
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("points");
|
Gnuplot g1("points");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title("2D precision");
|
g1.set_title("2D precision");
|
||||||
g1.set_xlabel("East [m]");
|
g1.set_xlabel("East [m]");
|
||||||
g1.set_ylabel("North [m]");
|
g1.set_ylabel("North [m]");
|
||||||
@ -635,9 +643,16 @@ void StaticPositionSystemTest::print_results(const std::vector<double>& east,
|
|||||||
|
|
||||||
g1.savetops("Position_test_2D");
|
g1.savetops("Position_test_2D");
|
||||||
g1.savetopdf("Position_test_2D", 18);
|
g1.savetopdf("Position_test_2D", 18);
|
||||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
|
||||||
|
|
||||||
Gnuplot g2("points");
|
Gnuplot g2("points");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g2.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g2.disablescreen();
|
||||||
|
}
|
||||||
g2.set_title("3D precision");
|
g2.set_title("3D precision");
|
||||||
g2.set_xlabel("East [m]");
|
g2.set_xlabel("East [m]");
|
||||||
g2.set_ylabel("North [m]");
|
g2.set_ylabel("North [m]");
|
||||||
@ -656,7 +671,6 @@ void StaticPositionSystemTest::print_results(const std::vector<double>& east,
|
|||||||
|
|
||||||
g2.savetops("Position_test_3D");
|
g2.savetops("Position_test_3D");
|
||||||
g2.savetopdf("Position_test_3D");
|
g2.savetopdf("Position_test_3D");
|
||||||
if (FLAGS_show_plots) g2.showonscreen(); // window output
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
|
@ -145,10 +145,11 @@ DECLARE_string(log_dir);
|
|||||||
#if EXTRA_TESTS
|
#if EXTRA_TESTS
|
||||||
#include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc"
|
#include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc"
|
||||||
#include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc"
|
#include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc"
|
||||||
#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc"
|
#include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc"
|
||||||
#include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc"
|
#include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc"
|
||||||
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc"
|
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc"
|
||||||
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc"
|
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc"
|
||||||
|
#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc"
|
||||||
#include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc"
|
#include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc"
|
||||||
#include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc"
|
#include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc"
|
||||||
#endif
|
#endif
|
||||||
|
@ -116,6 +116,14 @@ TEST(FFTLengthTest, MeasureExecutionTime)
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("linespoints");
|
Gnuplot g1("linespoints");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title("FFT execution times for different lengths");
|
g1.set_title("FFT execution times for different lengths");
|
||||||
g1.set_grid();
|
g1.set_grid();
|
||||||
g1.set_xlabel("FFT length");
|
g1.set_xlabel("FFT length");
|
||||||
@ -124,9 +132,16 @@ TEST(FFTLengthTest, MeasureExecutionTime)
|
|||||||
g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2");
|
g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2");
|
||||||
g1.savetops("FFT_execution_times_extended");
|
g1.savetops("FFT_execution_times_extended");
|
||||||
g1.savetopdf("FFT_execution_times_extended", 18);
|
g1.savetopdf("FFT_execution_times_extended", 18);
|
||||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
|
||||||
|
|
||||||
Gnuplot g2("linespoints");
|
Gnuplot g2("linespoints");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g2.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g2.disablescreen();
|
||||||
|
}
|
||||||
g2.set_title("FFT execution times for different lengths (up to 2^{14}=16384)");
|
g2.set_title("FFT execution times for different lengths (up to 2^{14}=16384)");
|
||||||
g2.set_grid();
|
g2.set_grid();
|
||||||
g2.set_xlabel("FFT length");
|
g2.set_xlabel("FFT length");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file gps_l1_acq_performance_test.cc
|
* \file acq_performance_test.cc
|
||||||
* \brief This class implements an acquisition performance test
|
* \brief This class implements an acquisition performance test
|
||||||
* \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat
|
* \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat
|
||||||
*
|
*
|
||||||
@ -29,26 +29,38 @@
|
|||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "test_flags.h"
|
#include "gps_l1_ca_pcps_acquisition.h"
|
||||||
#include "signal_generator_flags.h"
|
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
|
||||||
#include "tracking_true_obs_reader.h"
|
#include "galileo_e1_pcps_ambiguous_acquisition.h"
|
||||||
#include "true_observables_reader.h"
|
#include "galileo_e5a_pcps_acquisition.h"
|
||||||
|
#include "glonass_l1_ca_pcps_acquisition.h"
|
||||||
|
#include "glonass_l2_ca_pcps_acquisition.h"
|
||||||
|
#include "gps_l2_m_pcps_acquisition.h"
|
||||||
|
#include "gps_l5i_pcps_acquisition.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "gnuplot_i.h"
|
#include "gnuplot_i.h"
|
||||||
|
#include "signal_generator_flags.h"
|
||||||
|
#include "test_flags.h"
|
||||||
|
#include "tracking_true_obs_reader.h"
|
||||||
|
#include "true_observables_reader.h"
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <gnuradio/top_block.h>
|
#include <gnuradio/top_block.h>
|
||||||
#include <glog/logging.h>
|
#include <gnuradio/blocks/skiphead.h>
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test.");
|
DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test.");
|
||||||
DEFINE_string(acq_test_input_file, std::string(""), "File containing raw signal data, must be in int8_t format. The signal generator will not be used.");
|
DEFINE_string(acq_test_input_file, std::string(""), "File containing raw signal data, must be in int8_t format. The signal generator will not be used.");
|
||||||
|
DEFINE_string(acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition"), "Acquisition block implementation under test. Alternatives: GPS_L1_CA_PCPS_Acquisition, GPS_L1_CA_PCPS_Acquisition_Fine_Doppler, Galileo_E1_PCPS_Ambiguous_Acquisition, GLONASS_L1_CA_PCPS_Acquisition, GLONASS_L2_CA_PCPS_Acquisition, GPS_L2_M_PCPS_Acquisition, Galileo_E5a_Pcps_Acquisition, GPS_L5i_PCPS_Acquisition");
|
||||||
|
|
||||||
DEFINE_int32(acq_test_doppler_max, 5000, "Maximum Doppler, in Hz");
|
DEFINE_int32(acq_test_doppler_max, 5000, "Maximum Doppler, in Hz");
|
||||||
DEFINE_int32(acq_test_doppler_step, 125, "Doppler step, in Hz.");
|
DEFINE_int32(acq_test_doppler_step, 125, "Doppler step, in Hz.");
|
||||||
DEFINE_int32(acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms");
|
DEFINE_int32(acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms");
|
||||||
DEFINE_int32(acq_test_max_dwells, 1, "Number of non-coherent integrations");
|
DEFINE_int32(acq_test_max_dwells, 1, "Number of non-coherent integrations.");
|
||||||
DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm");
|
DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm.");
|
||||||
DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag");
|
DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag.");
|
||||||
|
DEFINE_bool(acq_test_make_two_steps, false, "Perform second step in a thinner grid.");
|
||||||
|
DEFINE_int32(acq_test_second_nbins, 4, "If --acq_test_make_two_steps is set to true, this parameter sets the number of bins done in the acquisition refinement stage.");
|
||||||
|
DEFINE_int32(acq_test_second_doppler_step, 10, "If --acq_test_make_two_steps is set to true, this parameter sets the Doppler step applied in the acquisition refinement stage, in Hz.");
|
||||||
|
|
||||||
DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration, in s");
|
DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration, in s");
|
||||||
DEFINE_int32(acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file.");
|
DEFINE_int32(acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file.");
|
||||||
@ -56,9 +68,9 @@ DEFINE_double(acq_test_cn0_init, 33.0, "Initial CN0, in dBHz.");
|
|||||||
DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz.");
|
DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz.");
|
||||||
DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB.");
|
DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB.");
|
||||||
|
|
||||||
DEFINE_double(acq_test_threshold_init, 11.0, "Initial acquisition threshold");
|
DEFINE_double(acq_test_threshold_init, 3.0, "Initial acquisition threshold");
|
||||||
DEFINE_double(acq_test_threshold_final, 16.0, "Final acquisition threshold");
|
DEFINE_double(acq_test_threshold_final, 4.0, "Final acquisition threshold");
|
||||||
DEFINE_double(acq_test_threshold_step, 1.0, "Acquisition threshold step");
|
DEFINE_double(acq_test_threshold_step, 0.5, "Acquisition threshold step");
|
||||||
|
|
||||||
DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0");
|
DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0");
|
||||||
|
|
||||||
@ -67,6 +79,7 @@ DEFINE_int32(acq_test_fake_PRN, 33, "PRN number of a non-present satellite");
|
|||||||
|
|
||||||
DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)");
|
DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)");
|
||||||
DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available");
|
DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available");
|
||||||
|
DEFINE_int32(acq_test_skiphead, 0, "Number of samples to skip in the input file");
|
||||||
|
|
||||||
// ######## GNURADIO BLOCK MESSAGE RECEVER #########
|
// ######## GNURADIO BLOCK MESSAGE RECEVER #########
|
||||||
class AcqPerfTest_msg_rx;
|
class AcqPerfTest_msg_rx;
|
||||||
@ -151,6 +164,84 @@ protected:
|
|||||||
{
|
{
|
||||||
cn0_vector = {0.0};
|
cn0_vector = {0.0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "1C";
|
||||||
|
system_id = 'G';
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
min_integration_ms = 1;
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "1C";
|
||||||
|
system_id = 'G';
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
min_integration_ms = 1;
|
||||||
|
}
|
||||||
|
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "1B";
|
||||||
|
system_id = 'E';
|
||||||
|
min_integration_ms = 4;
|
||||||
|
if (FLAGS_acq_test_coherent_time_ms == 1)
|
||||||
|
{
|
||||||
|
coherent_integration_time_ms = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "1G";
|
||||||
|
system_id = 'R';
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
min_integration_ms = 1;
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "2G";
|
||||||
|
system_id = 'R';
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
min_integration_ms = 1;
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "2S";
|
||||||
|
system_id = 'G';
|
||||||
|
if (FLAGS_acq_test_coherent_time_ms == 1)
|
||||||
|
{
|
||||||
|
coherent_integration_time_ms = 20;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
}
|
||||||
|
min_integration_ms = 20;
|
||||||
|
}
|
||||||
|
else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "5X";
|
||||||
|
system_id = 'E';
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
min_integration_ms = 1;
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
signal_id = "L5";
|
||||||
|
system_id = 'G';
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
signal_id = "1C";
|
||||||
|
system_id = 'G';
|
||||||
|
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||||
|
min_integration_ms = 1;
|
||||||
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
if (FLAGS_acq_test_pfa_init > 0.0)
|
if (FLAGS_acq_test_pfa_init > 0.0)
|
||||||
@ -178,7 +269,7 @@ protected:
|
|||||||
|
|
||||||
num_thresholds = pfa_vector.size();
|
num_thresholds = pfa_vector.size();
|
||||||
|
|
||||||
int aux2 = ((generated_signal_duration_s * 1000 - FLAGS_acq_test_coherent_time_ms) / FLAGS_acq_test_coherent_time_ms);
|
int aux2 = ((generated_signal_duration_s * 1000 - (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells)) / (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells));
|
||||||
if ((FLAGS_acq_test_num_meas > 0) and (FLAGS_acq_test_num_meas < aux2))
|
if ((FLAGS_acq_test_num_meas > 0) and (FLAGS_acq_test_num_meas < aux2))
|
||||||
{
|
{
|
||||||
num_of_measurements = static_cast<unsigned int>(FLAGS_acq_test_num_meas);
|
num_of_measurements = static_cast<unsigned int>(FLAGS_acq_test_num_meas);
|
||||||
@ -200,7 +291,6 @@ protected:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<double> cn0_vector;
|
std::vector<double> cn0_vector;
|
||||||
std::vector<float> pfa_vector;
|
std::vector<float> pfa_vector;
|
||||||
|
|
||||||
@ -223,7 +313,7 @@ protected:
|
|||||||
|
|
||||||
gr::msg_queue::sptr queue;
|
gr::msg_queue::sptr queue;
|
||||||
gr::top_block_sptr top_block;
|
gr::top_block_sptr top_block;
|
||||||
std::shared_ptr<GpsL1CaPcpsAcquisition> acquisition;
|
std::shared_ptr<AcquisitionInterface> acquisition;
|
||||||
std::shared_ptr<InMemoryConfiguration> config;
|
std::shared_ptr<InMemoryConfiguration> config;
|
||||||
std::shared_ptr<FileConfiguration> config_f;
|
std::shared_ptr<FileConfiguration> config_f;
|
||||||
Gnss_Synchro gnss_synchro;
|
Gnss_Synchro gnss_synchro;
|
||||||
@ -235,10 +325,10 @@ protected:
|
|||||||
int message;
|
int message;
|
||||||
boost::thread ch_thread;
|
boost::thread ch_thread;
|
||||||
|
|
||||||
std::string implementation = "GPS_L1_CA_PCPS_Acquisition";
|
std::string implementation = FLAGS_acq_test_implementation;
|
||||||
|
|
||||||
const double baseband_sampling_freq = static_cast<double>(FLAGS_fs_gen_sps);
|
const double baseband_sampling_freq = static_cast<double>(FLAGS_fs_gen_sps);
|
||||||
const int coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
int coherent_integration_time_ms;
|
||||||
const int in_acquisition = 1;
|
const int in_acquisition = 1;
|
||||||
const int dump_channel = 0;
|
const int dump_channel = 0;
|
||||||
|
|
||||||
@ -250,11 +340,14 @@ protected:
|
|||||||
std::string path_str = "./acq-perf-test";
|
std::string path_str = "./acq-perf-test";
|
||||||
|
|
||||||
int num_thresholds;
|
int num_thresholds;
|
||||||
|
unsigned int min_integration_ms;
|
||||||
|
|
||||||
std::vector<std::vector<float>> Pd;
|
std::vector<std::vector<float>> Pd;
|
||||||
std::vector<std::vector<float>> Pfa;
|
std::vector<std::vector<float>> Pfa;
|
||||||
std::vector<std::vector<float>> Pd_correct;
|
std::vector<std::vector<float>> Pd_correct;
|
||||||
|
|
||||||
|
std::string signal_id;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string generator_binary;
|
std::string generator_binary;
|
||||||
std::string p1;
|
std::string p1;
|
||||||
@ -266,6 +359,7 @@ private:
|
|||||||
|
|
||||||
std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
|
std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
|
||||||
std::string filename_raw_data = FLAGS_filename_raw_data;
|
std::string filename_raw_data = FLAGS_filename_raw_data;
|
||||||
|
char system_id;
|
||||||
|
|
||||||
double compute_stdev_precision(const std::vector<double>& vec);
|
double compute_stdev_precision(const std::vector<double>& vec);
|
||||||
double compute_stdev_accuracy(const std::vector<double>& vec, double ref);
|
double compute_stdev_accuracy(const std::vector<double>& vec, double ref);
|
||||||
@ -275,8 +369,8 @@ private:
|
|||||||
void AcquisitionPerformanceTest::init()
|
void AcquisitionPerformanceTest::init()
|
||||||
{
|
{
|
||||||
gnss_synchro.Channel_ID = 0;
|
gnss_synchro.Channel_ID = 0;
|
||||||
gnss_synchro.System = 'G';
|
gnss_synchro.System = system_id;
|
||||||
std::string signal = "1C";
|
std::string signal = signal_id;
|
||||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||||
gnss_synchro.PRN = observed_satellite;
|
gnss_synchro.PRN = observed_satellite;
|
||||||
message = 0;
|
message = 0;
|
||||||
@ -376,50 +470,59 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign
|
|||||||
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal));
|
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal));
|
||||||
|
|
||||||
// Set Acquisition
|
// Set Acquisition
|
||||||
config->set_property("Acquisition_1C.implementation", implementation);
|
config->set_property("Acquisition.implementation", implementation);
|
||||||
config->set_property("Acquisition_1C.item_type", "gr_complex");
|
config->set_property("Acquisition.item_type", "gr_complex");
|
||||||
config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max));
|
config->set_property("Acquisition.doppler_max", std::to_string(doppler_max));
|
||||||
config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step));
|
config->set_property("Acquisition.doppler_min", std::to_string(-doppler_max));
|
||||||
|
config->set_property("Acquisition.doppler_step", std::to_string(doppler_step));
|
||||||
|
|
||||||
config->set_property("Acquisition_1C.threshold", std::to_string(pfa));
|
config->set_property("Acquisition.threshold", std::to_string(pfa));
|
||||||
//if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa));
|
//if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition.pfa", std::to_string(pfa));
|
||||||
if (FLAGS_acq_test_pfa_init > 0.0)
|
if (FLAGS_acq_test_pfa_init > 0.0)
|
||||||
{
|
{
|
||||||
config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa));
|
config->supersede_property("Acquisition.pfa", std::to_string(pfa));
|
||||||
}
|
}
|
||||||
if (FLAGS_acq_test_use_CFAR_algorithm)
|
if (FLAGS_acq_test_use_CFAR_algorithm)
|
||||||
{
|
{
|
||||||
config->set_property("Acquisition_1C.use_CFAR_algorithm", "true");
|
config->set_property("Acquisition.use_CFAR_algorithm", "true");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
config->set_property("Acquisition_1C.use_CFAR_algorithm", "false");
|
config->set_property("Acquisition.use_CFAR_algorithm", "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms));
|
config->set_property("Acquisition.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms));
|
||||||
if (FLAGS_acq_test_bit_transition_flag)
|
if (FLAGS_acq_test_bit_transition_flag)
|
||||||
{
|
{
|
||||||
config->set_property("Acquisition_1C.bit_transition_flag", "true");
|
config->set_property("Acquisition.bit_transition_flag", "true");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
config->set_property("Acquisition_1C.bit_transition_flag", "false");
|
config->set_property("Acquisition.bit_transition_flag", "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
config->set_property("Acquisition_1C.max_dwells", std::to_string(FLAGS_acq_test_max_dwells));
|
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_acq_test_max_dwells));
|
||||||
|
|
||||||
config->set_property("Acquisition_1C.repeat_satellite", "true");
|
config->set_property("Acquisition.repeat_satellite", "true");
|
||||||
|
|
||||||
config->set_property("Acquisition_1C.blocking", "true");
|
config->set_property("Acquisition.blocking", "true");
|
||||||
config->set_property("Acquisition_1C.make_two_steps", "false");
|
if (FLAGS_acq_test_make_two_steps)
|
||||||
config->set_property("Acquisition_1C.second_nbins", std::to_string(4));
|
{
|
||||||
config->set_property("Acquisition_1C.second_doppler_step", std::to_string(125));
|
config->set_property("Acquisition.make_two_steps", "true");
|
||||||
|
config->set_property("Acquisition.second_nbins", std::to_string(FLAGS_acq_test_second_nbins));
|
||||||
|
config->set_property("Acquisition.second_doppler_step", std::to_string(FLAGS_acq_test_second_doppler_step));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config->set_property("Acquisition.make_two_steps", "false");
|
||||||
|
}
|
||||||
|
|
||||||
config->set_property("Acquisition_1C.dump", "true");
|
|
||||||
|
config->set_property("Acquisition.dump", "true");
|
||||||
std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa);
|
std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa);
|
||||||
config->set_property("Acquisition_1C.dump_filename", dump_file);
|
config->set_property("Acquisition.dump_filename", dump_file);
|
||||||
config->set_property("Acquisition_1C.dump_channel", std::to_string(dump_channel));
|
config->set_property("Acquisition.dump_channel", std::to_string(dump_channel));
|
||||||
config->set_property("Acquisition_1C.blocking_on_standby", "true");
|
config->set_property("Acquisition.blocking_on_standby", "true");
|
||||||
|
|
||||||
config_f = 0;
|
config_f = 0;
|
||||||
}
|
}
|
||||||
@ -450,6 +553,7 @@ int AcquisitionPerformanceTest::run_receiver()
|
|||||||
|
|
||||||
top_block = gr::make_top_block("Acquisition test");
|
top_block = gr::make_top_block("Acquisition test");
|
||||||
boost::shared_ptr<AcqPerfTest_msg_rx> msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue);
|
boost::shared_ptr<AcqPerfTest_msg_rx> msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue);
|
||||||
|
gr::blocks::skiphead::sptr skiphead = gr::blocks::skiphead::make(sizeof(gr_complex), FLAGS_acq_test_skiphead);
|
||||||
|
|
||||||
queue = gr::msg_queue::make(0);
|
queue = gr::msg_queue::make(0);
|
||||||
gnss_synchro = Gnss_Synchro();
|
gnss_synchro = Gnss_Synchro();
|
||||||
@ -457,23 +561,61 @@ int AcquisitionPerformanceTest::run_receiver()
|
|||||||
|
|
||||||
int nsamples = floor(config->property("GNSS-SDR.internal_fs_sps", 2000000) * generated_signal_duration_s);
|
int nsamples = floor(config->property("GNSS-SDR.internal_fs_sps", 2000000) * generated_signal_duration_s);
|
||||||
boost::shared_ptr<gr::block> valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue);
|
boost::shared_ptr<gr::block> valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue);
|
||||||
|
if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GpsL1CaPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFineDoppler>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GlonassL1CaPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GlonassL2CaPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GpsL2MPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GalileoE5aPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0)
|
||||||
|
{
|
||||||
|
acquisition = std::make_shared<GpsL5iPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool aux = false;
|
||||||
|
EXPECT_EQ(true, aux);
|
||||||
|
}
|
||||||
|
|
||||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisition>(config.get(), "Acquisition_1C", 1, 0);
|
|
||||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||||
acquisition->set_channel(0);
|
acquisition->set_channel(0);
|
||||||
|
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||||
|
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500));
|
||||||
|
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
|
||||||
|
acquisition->init();
|
||||||
acquisition->set_local_code();
|
acquisition->set_local_code();
|
||||||
acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000));
|
|
||||||
acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500));
|
|
||||||
acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0));
|
|
||||||
acquisition->set_state(1); // Ensure that acquisition starts at the first sample
|
acquisition->set_state(1); // Ensure that acquisition starts at the first sample
|
||||||
acquisition->connect(top_block);
|
acquisition->connect(top_block);
|
||||||
top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
|
||||||
|
|
||||||
acquisition->init();
|
|
||||||
|
|
||||||
|
acquisition->reset();
|
||||||
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
|
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
|
||||||
top_block->connect(gr_interleaved_char_to_complex, 0, valve, 0);
|
top_block->connect(gr_interleaved_char_to_complex, 0, skiphead, 0);
|
||||||
|
top_block->connect(skiphead, 0, valve, 0);
|
||||||
top_block->connect(valve, 0, acquisition->get_left_block(), 0);
|
top_block->connect(valve, 0, acquisition->get_left_block(), 0);
|
||||||
|
top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
||||||
|
|
||||||
start_queue();
|
start_queue();
|
||||||
|
|
||||||
@ -534,9 +676,17 @@ void AcquisitionPerformanceTest::plot_results()
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("linespoints");
|
Gnuplot g1("linespoints");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.cmd("set font \"Times,18\"");
|
g1.cmd("set font \"Times,18\"");
|
||||||
g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition");
|
g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition");
|
||||||
g1.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\"");
|
g1.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\"");
|
||||||
g1.cmd("set logscale x");
|
g1.cmd("set logscale x");
|
||||||
g1.cmd("set yrange [0:1]");
|
g1.cmd("set yrange [0:1]");
|
||||||
g1.cmd("set xrange[0.0001:1]");
|
g1.cmd("set xrange[0.0001:1]");
|
||||||
@ -560,12 +710,19 @@ void AcquisitionPerformanceTest::plot_results()
|
|||||||
g1.set_legend();
|
g1.set_legend();
|
||||||
g1.savetops("ROC");
|
g1.savetops("ROC");
|
||||||
g1.savetopdf("ROC", 18);
|
g1.savetopdf("ROC", 18);
|
||||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
|
||||||
|
|
||||||
Gnuplot g2("linespoints");
|
Gnuplot g2("linespoints");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g2.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g2.disablescreen();
|
||||||
|
}
|
||||||
g2.cmd("set font \"Times,18\"");
|
g2.cmd("set font \"Times,18\"");
|
||||||
g2.set_title("Receiver Operating Characteristic for GPS L1 C/A valid acquisition");
|
g2.set_title("Receiver Operating Characteristic for GPS L1 C/A valid acquisition");
|
||||||
g2.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\"");
|
g2.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\"");
|
||||||
g2.cmd("set logscale x");
|
g2.cmd("set logscale x");
|
||||||
g2.cmd("set yrange [0:1]");
|
g2.cmd("set yrange [0:1]");
|
||||||
g2.cmd("set xrange[0.0001:1]");
|
g2.cmd("set xrange[0.0001:1]");
|
||||||
@ -589,7 +746,6 @@ void AcquisitionPerformanceTest::plot_results()
|
|||||||
g2.set_legend();
|
g2.set_legend();
|
||||||
g2.savetops("ROC-valid-detection");
|
g2.savetops("ROC-valid-detection");
|
||||||
g2.savetopdf("ROC-valid-detection", 18);
|
g2.savetopdf("ROC-valid-detection", 18);
|
||||||
if (FLAGS_show_plots) g2.showonscreen(); // window output
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
@ -659,22 +815,40 @@ TEST_F(AcquisitionPerformanceTest, ROC)
|
|||||||
run_receiver();
|
run_receiver();
|
||||||
|
|
||||||
// count executions
|
// count executions
|
||||||
std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_vector[pfa_iter]) + "_" + gnss_synchro.System + "_1C";
|
std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_vector[pfa_iter]) + "_" + gnss_synchro.System + "_" + signal_id;
|
||||||
int num_executions = count_executions(basename, observed_satellite);
|
int num_executions = count_executions(basename, observed_satellite);
|
||||||
|
|
||||||
// Read measured data
|
// Read measured data
|
||||||
int ch = config->property("Acquisition_1C.dump_channel", 0);
|
int ch = config->property("Acquisition.dump_channel", 0);
|
||||||
arma::vec meas_timestamp_s = arma::zeros(num_executions, 1);
|
arma::vec meas_timestamp_s = arma::zeros(num_executions, 1);
|
||||||
arma::vec meas_doppler = arma::zeros(num_executions, 1);
|
arma::vec meas_doppler = arma::zeros(num_executions, 1);
|
||||||
arma::vec positive_acq = arma::zeros(num_executions, 1);
|
arma::vec positive_acq = arma::zeros(num_executions, 1);
|
||||||
arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1);
|
arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1);
|
||||||
|
|
||||||
double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1);
|
double coh_time_ms = config->property("Acquisition.coherent_integration_time_ms", 1);
|
||||||
|
|
||||||
std::cout << "Num executions: " << num_executions << std::endl;
|
std::cout << "Num executions: " << num_executions << std::endl;
|
||||||
|
|
||||||
|
unsigned int fft_size = 0;
|
||||||
|
unsigned int d_consumed_samples = coh_time_ms * config->property("GNSS-SDR.internal_fs_sps", 0) * 0.001; // * (config->property("Acquisition.bit_transition_flag", false) ? 2 : 1);
|
||||||
|
if (coh_time_ms == min_integration_ms)
|
||||||
|
{
|
||||||
|
fft_size = d_consumed_samples;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fft_size = d_consumed_samples * 2;
|
||||||
|
}
|
||||||
|
|
||||||
for (int execution = 1; execution <= num_executions; execution++)
|
for (int execution = 1; execution <= num_executions; execution++)
|
||||||
{
|
{
|
||||||
acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast<double>(coh_time_ms), ch, execution);
|
acquisition_dump_reader acq_dump(basename,
|
||||||
|
observed_satellite,
|
||||||
|
config->property("Acquisition.doppler_max", 0),
|
||||||
|
config->property("Acquisition.doppler_step", 0),
|
||||||
|
fft_size,
|
||||||
|
ch,
|
||||||
|
execution);
|
||||||
acq_dump.read_binary_acq();
|
acq_dump.read_binary_acq();
|
||||||
if (acq_dump.positive_acq)
|
if (acq_dump.positive_acq)
|
||||||
{
|
{
|
||||||
@ -794,7 +968,7 @@ TEST_F(AcquisitionPerformanceTest, ROC)
|
|||||||
for (int i = 0; i < num_clean_executions - 1; i++)
|
for (int i = 0; i < num_clean_executions - 1; i++)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast<float>(config->property("Acquisition_1C.doppler_step", 1)) / 2.0)
|
if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast<float>(config->property("Acquisition.doppler_step", 1)) / 2.0)
|
||||||
{
|
{
|
||||||
correctly_detected = correctly_detected + 1.0;
|
correctly_detected = correctly_detected + 1.0;
|
||||||
}
|
}
|
@ -201,6 +201,14 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid()
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("lines");
|
Gnuplot g1("lines");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title("Galileo E1b/c signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
g1.set_title("Galileo E1b/c signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
||||||
g1.set_xlabel("Doppler [Hz]");
|
g1.set_xlabel("Doppler [Hz]");
|
||||||
g1.set_ylabel("Sample");
|
g1.set_ylabel("Sample");
|
||||||
@ -209,7 +217,6 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid()
|
|||||||
|
|
||||||
g1.savetops("Galileo_E1_acq_grid");
|
g1.savetops("Galileo_E1_acq_grid");
|
||||||
g1.savetopdf("Galileo_E1_acq_grid");
|
g1.savetopdf("Galileo_E1_acq_grid");
|
||||||
if (FLAGS_show_plots) g1.showonscreen();
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
|
@ -341,7 +341,7 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_2()
|
|||||||
std::to_string(integration_time_ms));
|
std::to_string(integration_time_ms));
|
||||||
config->set_property("Acquisition.max_dwells", "1");
|
config->set_property("Acquisition.max_dwells", "1");
|
||||||
config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition");
|
config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition");
|
||||||
config->set_property("Acquisition.pfa", "0.1");
|
//config->set_property("Acquisition.pfa", "0.1");
|
||||||
config->set_property("Acquisition.doppler_max", "10000");
|
config->set_property("Acquisition.doppler_max", "10000");
|
||||||
config->set_property("Acquisition.doppler_step", "250");
|
config->set_property("Acquisition.doppler_step", "250");
|
||||||
config->set_property("Acquisition.bit_transition_flag", "false");
|
config->set_property("Acquisition.bit_transition_flag", "false");
|
||||||
@ -496,7 +496,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults)
|
|||||||
}) << "Failure setting doppler_step.";
|
}) << "Failure setting doppler_step.";
|
||||||
|
|
||||||
ASSERT_NO_THROW({
|
ASSERT_NO_THROW({
|
||||||
acquisition->set_threshold(0.5);
|
acquisition->set_threshold(0.05);
|
||||||
}) << "Failure setting threshold.";
|
}) << "Failure setting threshold.";
|
||||||
|
|
||||||
ASSERT_NO_THROW({
|
ASSERT_NO_THROW({
|
||||||
|
@ -202,6 +202,14 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid()
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("lines");
|
Gnuplot g1("lines");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title("GPS L1 C/A signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
g1.set_title("GPS L1 C/A signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
||||||
g1.set_xlabel("Doppler [Hz]");
|
g1.set_xlabel("Doppler [Hz]");
|
||||||
g1.set_ylabel("Sample");
|
g1.set_ylabel("Sample");
|
||||||
@ -210,7 +218,6 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid()
|
|||||||
|
|
||||||
g1.savetops("GPS_L1_acq_grid");
|
g1.savetops("GPS_L1_acq_grid");
|
||||||
g1.savetopdf("GPS_L1_acq_grid");
|
g1.savetopdf("GPS_L1_acq_grid");
|
||||||
if (FLAGS_show_plots) g1.showonscreen();
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException &ge)
|
catch (const GnuplotException &ge)
|
||||||
{
|
{
|
||||||
|
@ -205,6 +205,14 @@ void GpsL2MPcpsAcquisitionTest::plot_grid()
|
|||||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
Gnuplot g1("impulses");
|
Gnuplot g1("impulses");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title("GPS L2CM signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
g1.set_title("GPS L2CM signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
||||||
g1.set_xlabel("Doppler [Hz]");
|
g1.set_xlabel("Doppler [Hz]");
|
||||||
g1.set_ylabel("Sample");
|
g1.set_ylabel("Sample");
|
||||||
@ -213,7 +221,6 @@ void GpsL2MPcpsAcquisitionTest::plot_grid()
|
|||||||
|
|
||||||
g1.savetops("GPS_L2CM_acq_grid");
|
g1.savetops("GPS_L2CM_acq_grid");
|
||||||
g1.savetopdf("GPS_L2CM_acq_grid");
|
g1.savetopdf("GPS_L2CM_acq_grid");
|
||||||
if (FLAGS_show_plots) g1.showonscreen();
|
|
||||||
}
|
}
|
||||||
catch (const GnuplotException &ge)
|
catch (const GnuplotException &ge)
|
||||||
{
|
{
|
||||||
|
@ -167,6 +167,20 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename,
|
|||||||
{
|
{
|
||||||
std::cout << "¡¡¡Unreachable Acquisition dump file!!!" << std::endl;
|
std::cout << "¡¡¡Unreachable Acquisition dump file!!!" << std::endl;
|
||||||
}
|
}
|
||||||
|
acq_doppler_hz = 0.0;
|
||||||
|
acq_delay_samples = 0.0;
|
||||||
|
test_statistic = 0.0;
|
||||||
|
input_power = 0.0;
|
||||||
|
threshold = 0.0;
|
||||||
|
positive_acq = 0;
|
||||||
|
sample_counter = 0;
|
||||||
|
PRN = 0;
|
||||||
|
d_sat = 0;
|
||||||
|
d_doppler_max = doppler_max_;
|
||||||
|
d_doppler_step = doppler_step_;
|
||||||
|
d_samples_per_code = samples_per_code_;
|
||||||
|
d_num_doppler_bins = 0;
|
||||||
|
|
||||||
acquisition_dump_reader(basename,
|
acquisition_dump_reader(basename,
|
||||||
sat_,
|
sat_,
|
||||||
doppler_max_,
|
doppler_max_,
|
||||||
@ -176,6 +190,7 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename,
|
|||||||
execution);
|
execution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
acquisition_dump_reader::acquisition_dump_reader(const std::string& basename,
|
acquisition_dump_reader::acquisition_dump_reader(const std::string& basename,
|
||||||
unsigned int sat,
|
unsigned int sat,
|
||||||
unsigned int doppler_max,
|
unsigned int doppler_max,
|
||||||
@ -197,6 +212,7 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename,
|
|||||||
positive_acq = 0;
|
positive_acq = 0;
|
||||||
sample_counter = 0;
|
sample_counter = 0;
|
||||||
PRN = 0;
|
PRN = 0;
|
||||||
|
if (d_doppler_step == 0) d_doppler_step = 1;
|
||||||
d_num_doppler_bins = static_cast<unsigned int>(ceil(static_cast<double>(static_cast<int>(d_doppler_max) - static_cast<int>(-d_doppler_max)) / static_cast<double>(d_doppler_step)));
|
d_num_doppler_bins = static_cast<unsigned int>(ceil(static_cast<double>(static_cast<int>(d_doppler_max) - static_cast<int>(-d_doppler_max)) / static_cast<double>(d_doppler_step)));
|
||||||
std::vector<std::vector<float> > mag_aux(d_num_doppler_bins, std::vector<float>(d_samples_per_code));
|
std::vector<std::vector<float> > mag_aux(d_num_doppler_bins, std::vector<float>(d_samples_per_code));
|
||||||
mag = mag_aux;
|
mag = mag_aux;
|
||||||
|
@ -58,6 +58,8 @@
|
|||||||
#include "signal_generator_flags.h"
|
#include "signal_generator_flags.h"
|
||||||
#include "gnss_sdr_sample_counter.h"
|
#include "gnss_sdr_sample_counter.h"
|
||||||
#include <matio.h>
|
#include <matio.h>
|
||||||
|
#include "test_flags.h"
|
||||||
|
#include "gnuplot_i.h"
|
||||||
|
|
||||||
|
|
||||||
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES #########
|
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES #########
|
||||||
@ -183,6 +185,7 @@ public:
|
|||||||
|
|
||||||
int configure_generator();
|
int configure_generator();
|
||||||
int generate_signal();
|
int generate_signal();
|
||||||
|
bool save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename);
|
||||||
void check_results_carrier_phase(
|
void check_results_carrier_phase(
|
||||||
arma::mat& true_ch0,
|
arma::mat& true_ch0,
|
||||||
arma::mat& true_ch1,
|
arma::mat& true_ch1,
|
||||||
@ -283,10 +286,12 @@ void HybridObservablesTest::configure_receiver()
|
|||||||
config->set_property("Tracking_1C.item_type", "gr_complex");
|
config->set_property("Tracking_1C.item_type", "gr_complex");
|
||||||
config->set_property("Tracking_1C.dump", "true");
|
config->set_property("Tracking_1C.dump", "true");
|
||||||
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_");
|
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_");
|
||||||
config->set_property("Tracking_1C.pll_bw_hz", "35.0");
|
config->set_property("Tracking_1C.pll_bw_hz", "5.0");
|
||||||
config->set_property("Tracking_1C.dll_bw_hz", "0.5");
|
config->set_property("Tracking_1C.dll_bw_hz", "0.20");
|
||||||
|
config->set_property("Tracking_1C.pll_bw_narrow_hz", "1.0");
|
||||||
|
config->set_property("Tracking_1C.dll_bw_narrow_hz", "0.1");
|
||||||
|
config->set_property("Tracking_1C.extend_correlation_symbols", "20");
|
||||||
config->set_property("Tracking_1C.early_late_space_chips", "0.5");
|
config->set_property("Tracking_1C.early_late_space_chips", "0.5");
|
||||||
config->set_property("Tracking_1C.unified", "true");
|
|
||||||
|
|
||||||
config->set_property("TelemetryDecoder_1C.dump", "true");
|
config->set_property("TelemetryDecoder_1C.dump", "true");
|
||||||
config->set_property("Observables.dump", "true");
|
config->set_property("Observables.dump", "true");
|
||||||
@ -384,6 +389,41 @@ void HybridObservablesTest::check_results_carrier_phase(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool HybridObservablesTest::save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// WRITE MAT FILE
|
||||||
|
mat_t* matfp;
|
||||||
|
matvar_t* matvar;
|
||||||
|
filename.append(".mat");
|
||||||
|
std::cout << "save_mat_xy write " << filename << std::endl;
|
||||||
|
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5);
|
||||||
|
if (reinterpret_cast<long*>(matfp) != NULL)
|
||||||
|
{
|
||||||
|
size_t dims[2] = {1, x.size()};
|
||||||
|
matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "save_mat_xy: error creating file" << std::endl;
|
||||||
|
}
|
||||||
|
Mat_Close(matfp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
std::cout << "save_mat_xy: " << ex.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HybridObservablesTest::check_results_code_psudorange(
|
void HybridObservablesTest::check_results_code_psudorange(
|
||||||
arma::mat& true_ch0,
|
arma::mat& true_ch0,
|
||||||
arma::mat& true_ch1,
|
arma::mat& true_ch1,
|
||||||
@ -397,7 +437,12 @@ void HybridObservablesTest::check_results_code_psudorange(
|
|||||||
int size1 = measured_ch0.col(0).n_rows;
|
int size1 = measured_ch0.col(0).n_rows;
|
||||||
int size2 = measured_ch1.col(0).n_rows;
|
int size2 = measured_ch1.col(0).n_rows;
|
||||||
double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0));
|
double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0));
|
||||||
|
|
||||||
arma::vec t = arma::linspace<arma::vec>(t0, t1, floor((t1 - t0) * 1e3));
|
arma::vec t = arma::linspace<arma::vec>(t0, t1, floor((t1 - t0) * 1e3));
|
||||||
|
//conversion between arma::vec and std:vector
|
||||||
|
arma::vec t_from_start = arma::linspace<arma::vec>(0, t1 - t0, floor((t1 - t0) * 1e3));
|
||||||
|
std::vector<double> time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows);
|
||||||
|
|
||||||
|
|
||||||
arma::vec true_ch0_dist_interp;
|
arma::vec true_ch0_dist_interp;
|
||||||
arma::vec true_ch1_dist_interp;
|
arma::vec true_ch1_dist_interp;
|
||||||
@ -438,6 +483,31 @@ void HybridObservablesTest::check_results_code_psudorange(
|
|||||||
<< " [meters]" << std::endl;
|
<< " [meters]" << std::endl;
|
||||||
std::cout.precision(ss);
|
std::cout.precision(ss);
|
||||||
|
|
||||||
|
//plots
|
||||||
|
|
||||||
|
Gnuplot g3("linespoints");
|
||||||
|
g3.set_title("Delta Pseudorange error [m]");
|
||||||
|
g3.set_grid();
|
||||||
|
g3.set_xlabel("Time [s]");
|
||||||
|
g3.set_ylabel("Pseudorange error [m]");
|
||||||
|
//conversion between arma::vec and std:vector
|
||||||
|
std::vector<double> range_error_m(err.colptr(0), err.colptr(0) + err.n_rows);
|
||||||
|
g3.cmd("set key box opaque");
|
||||||
|
g3.plot_xy(time_vector, range_error_m,
|
||||||
|
"Delta pseudorrange error");
|
||||||
|
g3.set_legend();
|
||||||
|
g3.savetops("Delta_pseudorrange_error");
|
||||||
|
g3.savetopdf("Delta_pseudorrange_error", 18);
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g3.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g3.disablescreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
//check results against the test tolerance
|
||||||
ASSERT_LT(rmse, 0.5);
|
ASSERT_LT(rmse, 0.5);
|
||||||
ASSERT_LT(error_mean, 0.5);
|
ASSERT_LT(error_mean, 0.5);
|
||||||
ASSERT_GT(error_mean, -0.5);
|
ASSERT_GT(error_mean, -0.5);
|
||||||
@ -468,7 +538,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
|
|||||||
tracking_true_obs_reader true_obs_data_ch1;
|
tracking_true_obs_reader true_obs_data_ch1;
|
||||||
int test_satellite_PRN = FLAGS_test_satellite_PRN;
|
int test_satellite_PRN = FLAGS_test_satellite_PRN;
|
||||||
int test_satellite_PRN2 = FLAGS_test_satellite_PRN2;
|
int test_satellite_PRN2 = FLAGS_test_satellite_PRN2;
|
||||||
std::cout << "Testing satellite PRNs " << test_satellite_PRN << "," << test_satellite_PRN << std::endl;
|
std::cout << "Testing satellite PRNs " << test_satellite_PRN << "," << test_satellite_PRN2 << std::endl;
|
||||||
std::string true_obs_file = std::string("./gps_l1_ca_obs_prn");
|
std::string true_obs_file = std::string("./gps_l1_ca_obs_prn");
|
||||||
true_obs_file.append(std::to_string(test_satellite_PRN));
|
true_obs_file.append(std::to_string(test_satellite_PRN));
|
||||||
true_obs_file.append(".dat");
|
true_obs_file.append(".dat");
|
||||||
@ -700,6 +770,21 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Cut measurement initial transitory of the measurements
|
//Cut measurement initial transitory of the measurements
|
||||||
|
|
||||||
|
double initial_transitory_s = 30.0;
|
||||||
|
|
||||||
|
index = arma::find(measured_ch0.col(0) >= (measured_ch0(0, 0) + initial_transitory_s), 1, "first");
|
||||||
|
if ((index.size() > 0) and (index(0) > 0))
|
||||||
|
{
|
||||||
|
measured_ch0.shed_rows(0, index(0));
|
||||||
|
}
|
||||||
|
index = arma::find(measured_ch1.col(0) >= (measured_ch1(0, 0) + initial_transitory_s), 1, "first");
|
||||||
|
if ((index.size() > 0) and (index(0) > 0))
|
||||||
|
{
|
||||||
|
measured_ch1.shed_rows(0, index(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
index = arma::find(measured_ch0.col(0) >= true_ch0(0, 0), 1, "first");
|
index = arma::find(measured_ch0.col(0) >= true_ch0(0, 0), 1, "first");
|
||||||
if ((index.size() > 0) and (index(0) > 0))
|
if ((index.size() > 0) and (index(0) > 0))
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <armadillo>
|
#include <armadillo>
|
||||||
|
#include <matio.h>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <gnuradio/top_block.h>
|
#include <gnuradio/top_block.h>
|
||||||
#include <gnuradio/blocks/file_source.h>
|
#include <gnuradio/blocks/file_source.h>
|
||||||
@ -136,20 +137,24 @@ public:
|
|||||||
arma::vec& meas_time_s,
|
arma::vec& meas_time_s,
|
||||||
arma::vec& meas_value,
|
arma::vec& meas_value,
|
||||||
double& mean_error,
|
double& mean_error,
|
||||||
double& std_dev_error);
|
double& std_dev_error,
|
||||||
|
double& rmse);
|
||||||
std::vector<double> check_results_acc_carrier_phase(arma::vec& true_time_s,
|
std::vector<double> check_results_acc_carrier_phase(arma::vec& true_time_s,
|
||||||
arma::vec& true_value,
|
arma::vec& true_value,
|
||||||
arma::vec& meas_time_s,
|
arma::vec& meas_time_s,
|
||||||
arma::vec& meas_value,
|
arma::vec& meas_value,
|
||||||
double& mean_error,
|
double& mean_error,
|
||||||
double& std_dev_error);
|
double& std_dev_error,
|
||||||
|
double& rmse);
|
||||||
std::vector<double> check_results_codephase(arma::vec& true_time_s,
|
std::vector<double> check_results_codephase(arma::vec& true_time_s,
|
||||||
arma::vec& true_value,
|
arma::vec& true_value,
|
||||||
arma::vec& meas_time_s,
|
arma::vec& meas_time_s,
|
||||||
arma::vec& meas_value,
|
arma::vec& meas_value,
|
||||||
double& mean_error,
|
double& mean_error,
|
||||||
double& std_dev_error);
|
double& std_dev_error,
|
||||||
|
double& rmse);
|
||||||
|
|
||||||
|
bool save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename);
|
||||||
GpsL1CADllPllTrackingTest()
|
GpsL1CADllPllTrackingTest()
|
||||||
{
|
{
|
||||||
factory = std::make_shared<GNSSBlockFactory>();
|
factory = std::make_shared<GNSSBlockFactory>();
|
||||||
@ -267,7 +272,8 @@ std::vector<double> GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec&
|
|||||||
arma::vec& meas_time_s,
|
arma::vec& meas_time_s,
|
||||||
arma::vec& meas_value,
|
arma::vec& meas_value,
|
||||||
double& mean_error,
|
double& mean_error,
|
||||||
double& std_dev_error)
|
double& std_dev_error,
|
||||||
|
double& rmse)
|
||||||
{
|
{
|
||||||
// 1. True value interpolation to match the measurement times
|
// 1. True value interpolation to match the measurement times
|
||||||
arma::vec true_value_interp;
|
arma::vec true_value_interp;
|
||||||
@ -289,7 +295,7 @@ std::vector<double> GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec&
|
|||||||
std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows);
|
std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows);
|
||||||
|
|
||||||
arma::vec err2 = arma::square(err);
|
arma::vec err2 = arma::square(err);
|
||||||
double rmse = sqrt(arma::mean(err2));
|
rmse = sqrt(arma::mean(err2));
|
||||||
|
|
||||||
// 3. Mean err and variance
|
// 3. Mean err and variance
|
||||||
double error_mean = arma::mean(err);
|
double error_mean = arma::mean(err);
|
||||||
@ -317,7 +323,8 @@ std::vector<double> GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a
|
|||||||
arma::vec& meas_time_s,
|
arma::vec& meas_time_s,
|
||||||
arma::vec& meas_value,
|
arma::vec& meas_value,
|
||||||
double& mean_error,
|
double& mean_error,
|
||||||
double& std_dev_error)
|
double& std_dev_error,
|
||||||
|
double& rmse)
|
||||||
{
|
{
|
||||||
// 1. True value interpolation to match the measurement times
|
// 1. True value interpolation to match the measurement times
|
||||||
arma::vec true_value_interp;
|
arma::vec true_value_interp;
|
||||||
@ -332,12 +339,13 @@ std::vector<double> GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a
|
|||||||
|
|
||||||
// 2. RMSE
|
// 2. RMSE
|
||||||
arma::vec err;
|
arma::vec err;
|
||||||
err = meas_value - true_value_interp;
|
//it is required to remove the initial offset in the accumulated carrier phase error
|
||||||
|
err = (meas_value - meas_value(0)) - (true_value_interp - true_value_interp(0));
|
||||||
arma::vec err2 = arma::square(err);
|
arma::vec err2 = arma::square(err);
|
||||||
//conversion between arma::vec and std:vector
|
//conversion between arma::vec and std:vector
|
||||||
std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows);
|
std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows);
|
||||||
|
|
||||||
double rmse = sqrt(arma::mean(err2));
|
rmse = sqrt(arma::mean(err2));
|
||||||
|
|
||||||
// 3. Mean err and variance
|
// 3. Mean err and variance
|
||||||
double error_mean = arma::mean(err);
|
double error_mean = arma::mean(err);
|
||||||
@ -364,7 +372,8 @@ std::vector<double> GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec
|
|||||||
arma::vec& meas_time_s,
|
arma::vec& meas_time_s,
|
||||||
arma::vec& meas_value,
|
arma::vec& meas_value,
|
||||||
double& mean_error,
|
double& mean_error,
|
||||||
double& std_dev_error)
|
double& std_dev_error,
|
||||||
|
double& rmse)
|
||||||
{
|
{
|
||||||
// 1. True value interpolation to match the measurement times
|
// 1. True value interpolation to match the measurement times
|
||||||
arma::vec true_value_interp;
|
arma::vec true_value_interp;
|
||||||
@ -385,7 +394,7 @@ std::vector<double> GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec
|
|||||||
std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows);
|
std::vector<double> err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows);
|
||||||
|
|
||||||
arma::vec err2 = arma::square(err);
|
arma::vec err2 = arma::square(err);
|
||||||
double rmse = sqrt(arma::mean(err2));
|
rmse = sqrt(arma::mean(err2));
|
||||||
|
|
||||||
// 3. Mean err and variance
|
// 3. Mean err and variance
|
||||||
double error_mean = arma::mean(err);
|
double error_mean = arma::mean(err);
|
||||||
@ -420,12 +429,15 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
//data containers for config param sweep
|
//data containers for config param sweep
|
||||||
std::vector<std::vector<double>> mean_doppler_error_sweep; //swep config param and cn0 sweep
|
std::vector<std::vector<double>> mean_doppler_error_sweep; //swep config param and cn0 sweep
|
||||||
std::vector<std::vector<double>> std_dev_doppler_error_sweep; //swep config param and cn0 sweep
|
std::vector<std::vector<double>> std_dev_doppler_error_sweep; //swep config param and cn0 sweep
|
||||||
|
std::vector<std::vector<double>> rmse_doppler_sweep; //swep config param and cn0 sweep
|
||||||
|
|
||||||
std::vector<std::vector<double>> mean_code_phase_error_sweep; //swep config param and cn0 sweep
|
std::vector<std::vector<double>> mean_code_phase_error_sweep; //swep config param and cn0 sweep
|
||||||
std::vector<std::vector<double>> std_dev_code_phase_error_sweep; //swep config param and cn0 sweep
|
std::vector<std::vector<double>> std_dev_code_phase_error_sweep; //swep config param and cn0 sweep
|
||||||
|
std::vector<std::vector<double>> rmse_code_phase_sweep; //swep config param and cn0 sweep
|
||||||
|
|
||||||
std::vector<std::vector<double>> mean_carrier_phase_error_sweep; //swep config param and cn0 sweep
|
std::vector<std::vector<double>> mean_carrier_phase_error_sweep; //swep config param and cn0 sweep
|
||||||
std::vector<std::vector<double>> std_dev_carrier_phase_error_sweep; //swep config param and cn0 sweep
|
std::vector<std::vector<double>> std_dev_carrier_phase_error_sweep; //swep config param and cn0 sweep
|
||||||
|
std::vector<std::vector<double>> rmse_carrier_phase_sweep; //swep config param and cn0 sweep
|
||||||
|
|
||||||
std::vector<std::vector<double>> trk_valid_timestamp_s_sweep;
|
std::vector<std::vector<double>> trk_valid_timestamp_s_sweep;
|
||||||
std::vector<std::vector<double>> generator_CN0_values_sweep_copy;
|
std::vector<std::vector<double>> generator_CN0_values_sweep_copy;
|
||||||
@ -528,14 +540,18 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
|
|
||||||
std::vector<std::vector<double>> doppler_error_sweep;
|
std::vector<std::vector<double>> doppler_error_sweep;
|
||||||
std::vector<std::vector<double>> code_phase_error_sweep;
|
std::vector<std::vector<double>> code_phase_error_sweep;
|
||||||
|
std::vector<std::vector<double>> code_phase_error_meters_sweep;
|
||||||
std::vector<std::vector<double>> acc_carrier_phase_error_sweep;
|
std::vector<std::vector<double>> acc_carrier_phase_error_sweep;
|
||||||
|
|
||||||
std::vector<double> mean_doppler_error;
|
std::vector<double> mean_doppler_error;
|
||||||
std::vector<double> std_dev_doppler_error;
|
std::vector<double> std_dev_doppler_error;
|
||||||
|
std::vector<double> rmse_doppler;
|
||||||
std::vector<double> mean_code_phase_error;
|
std::vector<double> mean_code_phase_error;
|
||||||
std::vector<double> std_dev_code_phase_error;
|
std::vector<double> std_dev_code_phase_error;
|
||||||
|
std::vector<double> rmse_code_phase;
|
||||||
std::vector<double> mean_carrier_phase_error;
|
std::vector<double> mean_carrier_phase_error;
|
||||||
std::vector<double> std_dev_carrier_phase_error;
|
std::vector<double> std_dev_carrier_phase_error;
|
||||||
|
std::vector<double> rmse_carrier_phase;
|
||||||
std::vector<double> valid_CN0_values;
|
std::vector<double> valid_CN0_values;
|
||||||
|
|
||||||
configure_receiver(PLL_wide_bw_values.at(config_idx),
|
configure_receiver(PLL_wide_bw_values.at(config_idx),
|
||||||
@ -682,6 +698,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
{
|
{
|
||||||
std::vector<double> doppler_error_hz;
|
std::vector<double> doppler_error_hz;
|
||||||
std::vector<double> code_phase_error_chips;
|
std::vector<double> code_phase_error_chips;
|
||||||
|
std::vector<double> code_phase_error_meters;
|
||||||
std::vector<double> acc_carrier_phase_hz;
|
std::vector<double> acc_carrier_phase_hz;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -707,7 +724,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
epoch_counter++;
|
epoch_counter++;
|
||||||
}
|
}
|
||||||
// Align initial measurements and cut the tracking pull-in transitory
|
// Align initial measurements and cut the tracking pull-in transitory
|
||||||
double pull_in_offset_s = 1.0;
|
double pull_in_offset_s = FLAGS_skip_trk_transitory_s;
|
||||||
|
|
||||||
arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first");
|
arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first");
|
||||||
if (initial_meas_point.size() > 0 and tracking_last_msg != 3)
|
if (initial_meas_point.size() > 0 and tracking_last_msg != 3)
|
||||||
@ -720,20 +737,28 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
|
|
||||||
double mean_error;
|
double mean_error;
|
||||||
double std_dev_error;
|
double std_dev_error;
|
||||||
|
double rmse;
|
||||||
|
|
||||||
valid_CN0_values.push_back(generator_CN0_values.at(current_cn0_idx)); //save the current cn0 value (valid tracking)
|
valid_CN0_values.push_back(generator_CN0_values.at(current_cn0_idx)); //save the current cn0 value (valid tracking)
|
||||||
|
|
||||||
doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error);
|
doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error, rmse);
|
||||||
mean_doppler_error.push_back(mean_error);
|
mean_doppler_error.push_back(mean_error);
|
||||||
std_dev_doppler_error.push_back(std_dev_error);
|
std_dev_doppler_error.push_back(std_dev_error);
|
||||||
|
rmse_doppler.push_back(rmse);
|
||||||
|
|
||||||
code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error);
|
code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error, rmse);
|
||||||
|
for (unsigned int ii = 0; ii < code_phase_error_chips.size(); ii++)
|
||||||
|
{
|
||||||
|
code_phase_error_meters.push_back(GPS_L1_CA_CHIP_PERIOD * code_phase_error_chips.at(ii) * GPS_C_m_s);
|
||||||
|
}
|
||||||
mean_code_phase_error.push_back(mean_error);
|
mean_code_phase_error.push_back(mean_error);
|
||||||
std_dev_code_phase_error.push_back(std_dev_error);
|
std_dev_code_phase_error.push_back(std_dev_error);
|
||||||
|
rmse_code_phase.push_back(rmse);
|
||||||
|
|
||||||
acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error);
|
acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error, rmse);
|
||||||
mean_carrier_phase_error.push_back(mean_error);
|
mean_carrier_phase_error.push_back(mean_error);
|
||||||
std_dev_carrier_phase_error.push_back(std_dev_error);
|
std_dev_carrier_phase_error.push_back(std_dev_error);
|
||||||
|
rmse_carrier_phase.push_back(rmse);
|
||||||
|
|
||||||
//save tracking measurement timestamps to std::vector
|
//save tracking measurement timestamps to std::vector
|
||||||
std::vector<double> vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows);
|
std::vector<double> vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows);
|
||||||
@ -741,6 +766,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
|
|
||||||
doppler_error_sweep.push_back(doppler_error_hz);
|
doppler_error_sweep.push_back(doppler_error_hz);
|
||||||
code_phase_error_sweep.push_back(code_phase_error_chips);
|
code_phase_error_sweep.push_back(code_phase_error_chips);
|
||||||
|
code_phase_error_meters_sweep.push_back(code_phase_error_meters);
|
||||||
acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz);
|
acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -760,10 +786,16 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
{
|
{
|
||||||
mean_doppler_error_sweep.push_back(mean_doppler_error);
|
mean_doppler_error_sweep.push_back(mean_doppler_error);
|
||||||
std_dev_doppler_error_sweep.push_back(std_dev_doppler_error);
|
std_dev_doppler_error_sweep.push_back(std_dev_doppler_error);
|
||||||
|
rmse_doppler_sweep.push_back(rmse_doppler);
|
||||||
|
|
||||||
mean_code_phase_error_sweep.push_back(mean_code_phase_error);
|
mean_code_phase_error_sweep.push_back(mean_code_phase_error);
|
||||||
std_dev_code_phase_error_sweep.push_back(std_dev_code_phase_error);
|
std_dev_code_phase_error_sweep.push_back(std_dev_code_phase_error);
|
||||||
|
rmse_code_phase_sweep.push_back(rmse_code_phase);
|
||||||
|
|
||||||
mean_carrier_phase_error_sweep.push_back(mean_carrier_phase_error);
|
mean_carrier_phase_error_sweep.push_back(mean_carrier_phase_error);
|
||||||
std_dev_carrier_phase_error_sweep.push_back(std_dev_carrier_phase_error);
|
std_dev_carrier_phase_error_sweep.push_back(std_dev_carrier_phase_error);
|
||||||
|
rmse_carrier_phase_sweep.push_back(rmse_carrier_phase);
|
||||||
|
|
||||||
//make a copy of the CN0 vector for each configuration parameter in order to filter the loss of lock events
|
//make a copy of the CN0 vector for each configuration parameter in order to filter the loss of lock events
|
||||||
generator_CN0_values_sweep_copy.push_back(valid_CN0_values);
|
generator_CN0_values_sweep_copy.push_back(valid_CN0_values);
|
||||||
}
|
}
|
||||||
@ -795,7 +827,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++)
|
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++)
|
||||||
{
|
{
|
||||||
Gnuplot g1("linespoints");
|
Gnuplot g1("linespoints");
|
||||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g1.disablescreen();
|
||||||
|
}
|
||||||
g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||||
g1.set_grid();
|
g1.set_grid();
|
||||||
g1.set_xlabel("Time [s]");
|
g1.set_xlabel("Time [s]");
|
||||||
@ -809,7 +848,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18);
|
g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18);
|
||||||
}
|
}
|
||||||
Gnuplot g2("points");
|
Gnuplot g2("points");
|
||||||
if (FLAGS_show_plots) g2.showonscreen(); // window output
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g2.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g2.disablescreen();
|
||||||
|
}
|
||||||
g2.set_multiplot(ceil(static_cast<float>(generator_CN0_values.size()) / 2.0),
|
g2.set_multiplot(ceil(static_cast<float>(generator_CN0_values.size()) / 2.0),
|
||||||
ceil(static_cast<float>(generator_CN0_values.size()) / 2));
|
ceil(static_cast<float>(generator_CN0_values.size()) / 2));
|
||||||
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++)
|
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++)
|
||||||
@ -840,7 +886,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
g3.set_legend();
|
g3.set_legend();
|
||||||
g3.savetops("CN0_output");
|
g3.savetops("CN0_output");
|
||||||
g3.savetopdf("CN0_output", 18);
|
g3.savetopdf("CN0_output", 18);
|
||||||
if (FLAGS_show_plots) g3.showonscreen(); // window output
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g3.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g3.disablescreen();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//PLOT ERROR FIGURES (only if it is used the signal generator)
|
//PLOT ERROR FIGURES (only if it is used the signal generator)
|
||||||
@ -849,7 +902,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
if (FLAGS_plot_detail_level >= 1)
|
if (FLAGS_plot_detail_level >= 1)
|
||||||
{
|
{
|
||||||
Gnuplot g5("points");
|
Gnuplot g5("points");
|
||||||
if (FLAGS_show_plots) g5.showonscreen(); // window output
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g5.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g5.disablescreen();
|
||||||
|
}
|
||||||
g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||||
g5.set_grid();
|
g5.set_grid();
|
||||||
g5.set_xlabel("Time [s]");
|
g5.set_xlabel("Time [s]");
|
||||||
@ -866,15 +926,61 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
|
||||||
|
code_phase_error_sweep.at(current_cn0_idx),
|
||||||
|
"Code_error_chips" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
|
||||||
|
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
|
||||||
}
|
}
|
||||||
g5.set_legend();
|
g5.set_legend();
|
||||||
g5.set_legend();
|
g5.set_legend();
|
||||||
g5.savetops("Code_error_output");
|
g5.savetops("Code_error_chips");
|
||||||
g5.savetopdf("Code_error_output", 18);
|
g5.savetopdf("Code_error_chips", 18);
|
||||||
|
|
||||||
|
Gnuplot g5b("points");
|
||||||
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g5b.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g5b.disablescreen();
|
||||||
|
}
|
||||||
|
g5b.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||||
|
g5b.set_grid();
|
||||||
|
g5b.set_xlabel("Time [s]");
|
||||||
|
g5b.set_ylabel("Code delay error [meters]");
|
||||||
|
|
||||||
|
|
||||||
|
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
g5b.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_meters_sweep.at(current_cn0_idx),
|
||||||
|
std::to_string(static_cast<int>(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz]", decimate);
|
||||||
|
}
|
||||||
|
catch (const GnuplotException& ge)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
|
||||||
|
code_phase_error_sweep.at(current_cn0_idx),
|
||||||
|
"Code_error_meters" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
|
||||||
|
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
|
||||||
|
}
|
||||||
|
g5b.set_legend();
|
||||||
|
g5b.set_legend();
|
||||||
|
g5b.savetops("Code_error_meters");
|
||||||
|
g5b.savetopdf("Code_error_meters", 18);
|
||||||
|
|
||||||
|
|
||||||
Gnuplot g6("points");
|
Gnuplot g6("points");
|
||||||
if (FLAGS_show_plots) g6.showonscreen(); // window output
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g6.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g6.disablescreen();
|
||||||
|
}
|
||||||
g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||||
g6.set_grid();
|
g6.set_grid();
|
||||||
g6.set_xlabel("Time [s]");
|
g6.set_xlabel("Time [s]");
|
||||||
@ -891,20 +997,31 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
|
||||||
|
acc_carrier_phase_error_sweep.at(current_cn0_idx),
|
||||||
|
"Carrier_phase_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
|
||||||
|
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
|
||||||
}
|
}
|
||||||
g6.set_legend();
|
g6.set_legend();
|
||||||
g6.set_legend();
|
g6.set_legend();
|
||||||
g6.savetops("Carrier_phase_error_output");
|
g6.savetops("Acc_carrier_phase_error_cycles");
|
||||||
g6.savetopdf("Carrier_phase_error_output", 18);
|
g6.savetopdf("Acc_carrier_phase_error_cycles", 18);
|
||||||
|
|
||||||
Gnuplot g4("points");
|
Gnuplot g4("points");
|
||||||
if (FLAGS_show_plots) g4.showonscreen(); // window output
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g4.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g4.disablescreen();
|
||||||
|
}
|
||||||
g4.set_multiplot(ceil(static_cast<float>(generator_CN0_values.size()) / 2.0),
|
g4.set_multiplot(ceil(static_cast<float>(generator_CN0_values.size()) / 2.0),
|
||||||
ceil(static_cast<float>(generator_CN0_values.size()) / 2));
|
ceil(static_cast<float>(generator_CN0_values.size()) / 2));
|
||||||
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++)
|
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++)
|
||||||
{
|
{
|
||||||
g4.reset_plot();
|
g4.reset_plot();
|
||||||
g4.set_title(std::to_string(static_cast<int>(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz], PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
g4.set_title("Dopper error" + std::to_string(static_cast<int>(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz], PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||||
g4.set_grid();
|
g4.set_grid();
|
||||||
//g4.cmd("set key box opaque");
|
//g4.cmd("set key box opaque");
|
||||||
g4.set_xlabel("Time [s]");
|
g4.set_xlabel("Time [s]");
|
||||||
@ -917,10 +1034,15 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
catch (const GnuplotException& ge)
|
catch (const GnuplotException& ge)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx),
|
||||||
|
doppler_error_sweep.at(current_cn0_idx),
|
||||||
|
"Doppler_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) +
|
||||||
|
std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx)));
|
||||||
}
|
}
|
||||||
g4.unset_multiplot();
|
g4.unset_multiplot();
|
||||||
g4.savetops("Doppler_error_output");
|
g4.savetops("Doppler_error_hz");
|
||||||
g4.savetopdf("Doppler_error_output", 18);
|
g4.savetopdf("Doppler_error_hz", 18);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -942,7 +1064,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
//plot metrics
|
//plot metrics
|
||||||
|
|
||||||
Gnuplot g7("linespoints");
|
Gnuplot g7("linespoints");
|
||||||
if (FLAGS_show_plots) g7.showonscreen(); // window output
|
if (FLAGS_show_plots)
|
||||||
|
{
|
||||||
|
g7.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g7.disablescreen();
|
||||||
|
}
|
||||||
g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||||
g7.set_grid();
|
g7.set_grid();
|
||||||
g7.set_xlabel("CN0 [dB-Hz]");
|
g7.set_xlabel("CN0 [dB-Hz]");
|
||||||
@ -957,10 +1086,17 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
std_dev_doppler_error_sweep.at(config_sweep_idx),
|
std_dev_doppler_error_sweep.at(config_sweep_idx),
|
||||||
"PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
"PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
||||||
+"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz");
|
+"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz");
|
||||||
|
|
||||||
|
//matlab save
|
||||||
|
save_mat_xy(generator_CN0_values_sweep_copy.at(config_sweep_idx),
|
||||||
|
rmse_doppler_sweep.at(config_sweep_idx),
|
||||||
|
"RMSE_Doppler_CN0_Sweep_PLL_DLL" + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
||||||
|
+"_" + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)));
|
||||||
}
|
}
|
||||||
g7.savetops("Doppler_error_metrics");
|
g7.savetops("Doppler_error_metrics");
|
||||||
g7.savetopdf("Doppler_error_metrics", 18);
|
g7.savetopdf("Doppler_error_metrics", 18);
|
||||||
|
|
||||||
|
|
||||||
Gnuplot g8("linespoints");
|
Gnuplot g8("linespoints");
|
||||||
g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||||
g8.set_grid();
|
g8.set_grid();
|
||||||
@ -976,6 +1112,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
std_dev_carrier_phase_error_sweep.at(config_sweep_idx),
|
std_dev_carrier_phase_error_sweep.at(config_sweep_idx),
|
||||||
"PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
"PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
||||||
+"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz");
|
+"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz");
|
||||||
|
//matlab save
|
||||||
|
save_mat_xy(generator_CN0_values_sweep_copy.at(config_sweep_idx),
|
||||||
|
rmse_carrier_phase_sweep.at(config_sweep_idx),
|
||||||
|
"RMSE_Carrier_Phase_CN0_Sweep_PLL_DLL" + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
||||||
|
+"_" + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)));
|
||||||
}
|
}
|
||||||
g8.savetops("Carrier_error_metrics");
|
g8.savetops("Carrier_error_metrics");
|
||||||
g8.savetopdf("Carrier_error_metrics", 18);
|
g8.savetopdf("Carrier_error_metrics", 18);
|
||||||
@ -995,6 +1136,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
std_dev_code_phase_error_sweep.at(config_sweep_idx),
|
std_dev_code_phase_error_sweep.at(config_sweep_idx),
|
||||||
"PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
"PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
||||||
+"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz");
|
+"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz");
|
||||||
|
//matlab save
|
||||||
|
save_mat_xy(generator_CN0_values_sweep_copy.at(config_sweep_idx),
|
||||||
|
rmse_code_phase_sweep.at(config_sweep_idx),
|
||||||
|
"RMSE_Code_Phase_CN0_Sweep_PLL_DLL" + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) +
|
||||||
|
+"_" + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)));
|
||||||
}
|
}
|
||||||
g9.savetops("Code_error_metrics");
|
g9.savetops("Code_error_metrics");
|
||||||
g9.savetopdf("Code_error_metrics", 18);
|
g9.savetopdf("Code_error_metrics", 18);
|
||||||
@ -1006,3 +1152,33 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GpsL1CADllPllTrackingTest::save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// WRITE MAT FILE
|
||||||
|
mat_t* matfp;
|
||||||
|
matvar_t* matvar;
|
||||||
|
filename.erase(filename.length() - 4, 4);
|
||||||
|
filename.append(".mat");
|
||||||
|
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
|
||||||
|
if (reinterpret_cast<long*>(matfp) != NULL)
|
||||||
|
{
|
||||||
|
size_t dims[2] = {1, x.size()};
|
||||||
|
matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
}
|
||||||
|
Mat_Close(matfp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file gps_l1_ca_dll_pll_tracking_test.cc
|
* \file tracking_test.cc
|
||||||
* \brief This class implements a tracking Pull-In test for GPS_L1_CA_DLL_PLL_Tracking
|
* \brief This class implements a tracking Pull-In test for GPS_L1_CA_DLL_PLL_Tracking
|
||||||
* implementation based on some input parameters.
|
* implementation based on some input parameters.
|
||||||
* \author Javier Arribas, 2018. jarribas(at)cttc.es
|
* \author Javier Arribas, 2018. jarribas(at)cttc.es
|
||||||
@ -40,11 +40,17 @@
|
|||||||
#include <gnuradio/blocks/interleaved_char_to_complex.h>
|
#include <gnuradio/blocks/interleaved_char_to_complex.h>
|
||||||
#include <gnuradio/blocks/null_sink.h>
|
#include <gnuradio/blocks/null_sink.h>
|
||||||
#include <gnuradio/blocks/skiphead.h>
|
#include <gnuradio/blocks/skiphead.h>
|
||||||
|
#include <gnuradio/blocks/head.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include "GPS_L1_CA.h"
|
#include "GPS_L1_CA.h"
|
||||||
#include "gnss_block_factory.h"
|
#include "gnss_block_factory.h"
|
||||||
#include "tracking_interface.h"
|
#include "tracking_interface.h"
|
||||||
|
#include "gps_l2_m_pcps_acquisition.h"
|
||||||
|
#include "gps_l1_ca_pcps_acquisition.h"
|
||||||
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
|
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
|
||||||
|
#include "galileo_e5a_noncoherent_iq_acquisition_caf.h"
|
||||||
|
#include "galileo_e5a_pcps_acquisition.h"
|
||||||
|
#include "gps_l5i_pcps_acquisition.h"
|
||||||
#include "in_memory_configuration.h"
|
#include "in_memory_configuration.h"
|
||||||
#include "tracking_true_obs_reader.h"
|
#include "tracking_true_obs_reader.h"
|
||||||
#include "tracking_dump_reader.h"
|
#include "tracking_dump_reader.h"
|
||||||
@ -71,6 +77,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
int rx_message;
|
int rx_message;
|
||||||
|
gr::top_block_sptr top_block;
|
||||||
~Acquisition_msg_rx(); //!< Default destructor
|
~Acquisition_msg_rx(); //!< Default destructor
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,6 +94,7 @@ void Acquisition_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
|||||||
{
|
{
|
||||||
long int message = pmt::to_long(msg);
|
long int message = pmt::to_long(msg);
|
||||||
rx_message = message;
|
rx_message = message;
|
||||||
|
top_block->stop(); //stop the flowgraph
|
||||||
}
|
}
|
||||||
catch (boost::bad_any_cast& e)
|
catch (boost::bad_any_cast& e)
|
||||||
{
|
{
|
||||||
@ -106,32 +114,32 @@ Acquisition_msg_rx::Acquisition_msg_rx() : gr::block("Acquisition_msg_rx", gr::i
|
|||||||
|
|
||||||
Acquisition_msg_rx::~Acquisition_msg_rx() {}
|
Acquisition_msg_rx::~Acquisition_msg_rx() {}
|
||||||
// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER #########
|
// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER #########
|
||||||
class GpsL1CADllPllTrackingPullInTest_msg_rx;
|
class TrackingPullInTest_msg_rx;
|
||||||
|
|
||||||
typedef boost::shared_ptr<GpsL1CADllPllTrackingPullInTest_msg_rx> GpsL1CADllPllTrackingPullInTest_msg_rx_sptr;
|
typedef boost::shared_ptr<TrackingPullInTest_msg_rx> TrackingPullInTest_msg_rx_sptr;
|
||||||
|
|
||||||
GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make();
|
TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make();
|
||||||
|
|
||||||
class GpsL1CADllPllTrackingPullInTest_msg_rx : public gr::block
|
class TrackingPullInTest_msg_rx : public gr::block
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make();
|
friend TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make();
|
||||||
void msg_handler_events(pmt::pmt_t msg);
|
void msg_handler_events(pmt::pmt_t msg);
|
||||||
GpsL1CADllPllTrackingPullInTest_msg_rx();
|
TrackingPullInTest_msg_rx();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int rx_message;
|
int rx_message;
|
||||||
~GpsL1CADllPllTrackingPullInTest_msg_rx(); //!< Default destructor
|
~TrackingPullInTest_msg_rx(); //!< Default destructor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make()
|
TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make()
|
||||||
{
|
{
|
||||||
return GpsL1CADllPllTrackingPullInTest_msg_rx_sptr(new GpsL1CADllPllTrackingPullInTest_msg_rx());
|
return TrackingPullInTest_msg_rx_sptr(new TrackingPullInTest_msg_rx());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
void TrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -147,22 +155,22 @@ void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpsL1CADllPllTrackingPullInTest_msg_rx::GpsL1CADllPllTrackingPullInTest_msg_rx() : gr::block("GpsL1CADllPllTrackingPullInTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0))
|
TrackingPullInTest_msg_rx::TrackingPullInTest_msg_rx() : gr::block("TrackingPullInTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0))
|
||||||
{
|
{
|
||||||
this->message_port_register_in(pmt::mp("events"));
|
this->message_port_register_in(pmt::mp("events"));
|
||||||
this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events, this, _1));
|
this->set_msg_handler(pmt::mp("events"), boost::bind(&TrackingPullInTest_msg_rx::msg_handler_events, this, _1));
|
||||||
rx_message = 0;
|
rx_message = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpsL1CADllPllTrackingPullInTest_msg_rx::~GpsL1CADllPllTrackingPullInTest_msg_rx()
|
TrackingPullInTest_msg_rx::~TrackingPullInTest_msg_rx()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ###########################################################
|
// ###########################################################
|
||||||
|
|
||||||
class GpsL1CADllPllTrackingPullInTest : public ::testing::Test
|
class TrackingPullInTest : public ::testing::Test
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string generator_binary;
|
std::string generator_binary;
|
||||||
@ -172,7 +180,7 @@ public:
|
|||||||
std::string p4;
|
std::string p4;
|
||||||
std::string p5;
|
std::string p5;
|
||||||
std::string p6;
|
std::string p6;
|
||||||
std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking"; //"GPS_L1_CA_DLL_PLL_C_Aid_Tracking";
|
std::string implementation = FLAGS_trk_test_implementation;
|
||||||
|
|
||||||
const int baseband_sampling_freq = FLAGS_fs_gen_sps;
|
const int baseband_sampling_freq = FLAGS_fs_gen_sps;
|
||||||
|
|
||||||
@ -204,7 +212,7 @@ public:
|
|||||||
double& mean_error,
|
double& mean_error,
|
||||||
double& std_dev_error);
|
double& std_dev_error);
|
||||||
|
|
||||||
GpsL1CADllPllTrackingPullInTest()
|
TrackingPullInTest()
|
||||||
{
|
{
|
||||||
factory = std::make_shared<GNSSBlockFactory>();
|
factory = std::make_shared<GNSSBlockFactory>();
|
||||||
config = std::make_shared<InMemoryConfiguration>();
|
config = std::make_shared<InMemoryConfiguration>();
|
||||||
@ -212,7 +220,7 @@ public:
|
|||||||
gnss_synchro = Gnss_Synchro();
|
gnss_synchro = Gnss_Synchro();
|
||||||
}
|
}
|
||||||
|
|
||||||
~GpsL1CADllPllTrackingPullInTest()
|
~TrackingPullInTest()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +239,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx)
|
int TrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx)
|
||||||
{
|
{
|
||||||
// Configure signal generator
|
// Configure signal generator
|
||||||
generator_binary = FLAGS_generator_binary;
|
generator_binary = FLAGS_generator_binary;
|
||||||
@ -253,7 +261,7 @@ int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GpsL1CADllPllTrackingPullInTest::generate_signal()
|
int TrackingPullInTest::generate_signal()
|
||||||
{
|
{
|
||||||
int child_status;
|
int child_status;
|
||||||
|
|
||||||
@ -276,48 +284,104 @@ int GpsL1CADllPllTrackingPullInTest::generate_signal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CADllPllTrackingPullInTest::configure_receiver(
|
void TrackingPullInTest::configure_receiver(
|
||||||
double PLL_wide_bw_hz,
|
double PLL_wide_bw_hz,
|
||||||
double DLL_wide_bw_hz,
|
double DLL_wide_bw_hz,
|
||||||
double PLL_narrow_bw_hz,
|
double PLL_narrow_bw_hz,
|
||||||
double DLL_narrow_bw_hz,
|
double DLL_narrow_bw_hz,
|
||||||
int extend_correlation_symbols)
|
int extend_correlation_symbols)
|
||||||
{
|
{
|
||||||
|
config = std::make_shared<InMemoryConfiguration>();
|
||||||
|
config->set_property("Tracking.dump", "true");
|
||||||
|
config->set_property("Tracking.dump_filename", "./tracking_ch_");
|
||||||
|
config->set_property("Tracking.implementation", implementation);
|
||||||
|
config->set_property("Tracking.item_type", "gr_complex");
|
||||||
|
config->set_property("Tracking.pll_bw_hz", std::to_string(PLL_wide_bw_hz));
|
||||||
|
config->set_property("Tracking.dll_bw_hz", std::to_string(DLL_wide_bw_hz));
|
||||||
|
config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols));
|
||||||
|
config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz));
|
||||||
|
config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz));
|
||||||
|
gnss_synchro.PRN = FLAGS_test_satellite_PRN;
|
||||||
gnss_synchro.Channel_ID = 0;
|
gnss_synchro.Channel_ID = 0;
|
||||||
|
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
|
||||||
|
|
||||||
|
std::string System_and_Signal;
|
||||||
|
if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0)
|
||||||
|
{
|
||||||
gnss_synchro.System = 'G';
|
gnss_synchro.System = 'G';
|
||||||
std::string signal = "1C";
|
std::string signal = "1C";
|
||||||
|
System_and_Signal = "GPS L1 CA";
|
||||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||||
gnss_synchro.PRN = FLAGS_test_satellite_PRN;
|
config->set_property("Tracking.early_late_space_chips", "0.5");
|
||||||
|
config->set_property("Tracking.early_late_space_narrow_chips", "0.5");
|
||||||
config = std::make_shared<InMemoryConfiguration>();
|
}
|
||||||
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
|
else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
|
||||||
// Set Tracking
|
{
|
||||||
config->set_property("Tracking_1C.implementation", implementation);
|
gnss_synchro.System = 'E';
|
||||||
config->set_property("Tracking_1C.item_type", "gr_complex");
|
std::string signal = "1B";
|
||||||
config->set_property("Tracking_1C.pll_bw_hz", std::to_string(PLL_wide_bw_hz));
|
System_and_Signal = "Galileo E1B";
|
||||||
config->set_property("Tracking_1C.dll_bw_hz", std::to_string(DLL_wide_bw_hz));
|
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||||
config->set_property("Tracking_1C.early_late_space_chips", "0.5");
|
config->set_property("Tracking.early_late_space_chips", "0.15");
|
||||||
config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_symbols));
|
config->set_property("Tracking.very_early_late_space_chips", "0.6");
|
||||||
config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz));
|
config->set_property("Tracking.early_late_space_narrow_chips", "0.15");
|
||||||
config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz));
|
config->set_property("Tracking.very_early_late_space_narrow_chips", "0.6");
|
||||||
config->set_property("Tracking_1C.early_late_space_narrow_chips", "0.5");
|
config->set_property("Tracking.track_pilot", "true");
|
||||||
config->set_property("Tracking_1C.dump", "true");
|
}
|
||||||
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_");
|
else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0)
|
||||||
|
{
|
||||||
|
gnss_synchro.System = 'G';
|
||||||
|
std::string signal = "2S";
|
||||||
|
System_and_Signal = "GPS L2CM";
|
||||||
|
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||||
|
config->set_property("Tracking.early_late_space_chips", "0.5");
|
||||||
|
config->set_property("Tracking.track_pilot", "false");
|
||||||
|
}
|
||||||
|
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0 or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
|
||||||
|
{
|
||||||
|
gnss_synchro.System = 'E';
|
||||||
|
std::string signal = "5X";
|
||||||
|
System_and_Signal = "Galileo E5a";
|
||||||
|
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||||
|
if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
|
||||||
|
{
|
||||||
|
config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking"));
|
||||||
|
}
|
||||||
|
config->set_property("Tracking.early_late_space_chips", "0.5");
|
||||||
|
config->set_property("Tracking.track_pilot", "false");
|
||||||
|
config->set_property("Tracking.order", "2");
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)
|
||||||
|
{
|
||||||
|
gnss_synchro.System = 'G';
|
||||||
|
std::string signal = "L5";
|
||||||
|
System_and_Signal = "GPS L5I";
|
||||||
|
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||||
|
config->set_property("Tracking.early_late_space_chips", "0.5");
|
||||||
|
config->set_property("Tracking.track_pilot", "false");
|
||||||
|
config->set_property("Tracking.order", "2");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "The test can not run with the selected tracking implementation\n ";
|
||||||
|
throw(std::exception());
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "*****************************************\n";
|
std::cout << "*****************************************\n";
|
||||||
std::cout << "*** Tracking configuration parameters ***\n";
|
std::cout << "*** Tracking configuration parameters ***\n";
|
||||||
std::cout << "*****************************************\n";
|
std::cout << "*****************************************\n";
|
||||||
std::cout << "pll_bw_hz: " << config->property("Tracking_1C.pll_bw_hz", 0.0) << " Hz\n";
|
std::cout << "Signal: " << System_and_Signal << "\n";
|
||||||
std::cout << "dll_bw_hz: " << config->property("Tracking_1C.dll_bw_hz", 0.0) << " Hz\n";
|
std::cout << "implementation: " << config->property("Tracking.implementation", std::string("undefined")) << " \n";
|
||||||
std::cout << "pll_bw_narrow_hz: " << config->property("Tracking_1C.pll_bw_narrow_hz", 0.0) << " Hz\n";
|
std::cout << "pll_bw_hz: " << config->property("Tracking.pll_bw_hz", 0.0) << " Hz\n";
|
||||||
std::cout << "dll_bw_narrow_hz: " << config->property("Tracking_1C.dll_bw_narrow_hz", 0.0) << " Hz\n";
|
std::cout << "dll_bw_hz: " << config->property("Tracking.dll_bw_hz", 0.0) << " Hz\n";
|
||||||
std::cout << "extend_correlation_symbols: " << config->property("Tracking_1C.extend_correlation_symbols", 0) << " Symbols\n";
|
std::cout << "pll_bw_narrow_hz: " << config->property("Tracking.pll_bw_narrow_hz", 0.0) << " Hz\n";
|
||||||
|
std::cout << "dll_bw_narrow_hz: " << config->property("Tracking.dll_bw_narrow_hz", 0.0) << " Hz\n";
|
||||||
|
std::cout << "extend_correlation_symbols: " << config->property("Tracking.extend_correlation_symbols", 0) << " Symbols\n";
|
||||||
std::cout << "*****************************************\n";
|
std::cout << "*****************************************\n";
|
||||||
std::cout << "*****************************************\n";
|
std::cout << "*****************************************\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
||||||
{
|
{
|
||||||
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
||||||
gr::top_block_sptr top_block;
|
gr::top_block_sptr top_block;
|
||||||
@ -326,23 +390,110 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
|||||||
// Satellite signal definition
|
// Satellite signal definition
|
||||||
Gnss_Synchro tmp_gnss_synchro;
|
Gnss_Synchro tmp_gnss_synchro;
|
||||||
tmp_gnss_synchro.Channel_ID = 0;
|
tmp_gnss_synchro.Channel_ID = 0;
|
||||||
|
config = std::make_shared<InMemoryConfiguration>();
|
||||||
|
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
|
||||||
|
config->set_property("Acquisition.blocking_on_standby", "true");
|
||||||
|
config->set_property("Acquisition.blocking", "true");
|
||||||
|
config->set_property("Acquisition.dump", "false");
|
||||||
|
config->set_property("Acquisition.dump_filename", "./data/acquisition.dat");
|
||||||
|
config->set_property("Acquisition.use_CFAR_algorithm", "false");
|
||||||
|
|
||||||
|
std::shared_ptr<AcquisitionInterface> acquisition;
|
||||||
|
|
||||||
|
std::string System_and_Signal;
|
||||||
|
//create the correspondign acquisition block according to the desired tracking signal
|
||||||
|
if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0)
|
||||||
|
{
|
||||||
tmp_gnss_synchro.System = 'G';
|
tmp_gnss_synchro.System = 'G';
|
||||||
std::string signal = "1C";
|
std::string signal = "1C";
|
||||||
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
|
System_and_Signal = "GPS L1 CA";
|
||||||
|
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
|
||||||
|
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFineDoppler>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
|
||||||
|
{
|
||||||
|
tmp_gnss_synchro.System = 'E';
|
||||||
|
std::string signal = "1B";
|
||||||
|
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
||||||
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
|
System_and_Signal = "Galileo E1B";
|
||||||
|
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
|
||||||
|
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0)
|
||||||
|
{
|
||||||
|
tmp_gnss_synchro.System = 'G';
|
||||||
|
std::string signal = "2S";
|
||||||
|
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
||||||
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
|
System_and_Signal = "GPS L2CM";
|
||||||
|
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
|
||||||
|
acquisition = std::make_shared<GpsL2MPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0)
|
||||||
|
{
|
||||||
|
tmp_gnss_synchro.System = 'E';
|
||||||
|
std::string signal = "5X";
|
||||||
|
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
||||||
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
|
System_and_Signal = "Galileo E5a";
|
||||||
|
config->set_property("Acquisition_5X.coherent_integration_time_ms", "1");
|
||||||
|
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
|
||||||
|
config->set_property("Acquisition.CAF_window_hz", "0"); // **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz
|
||||||
|
config->set_property("Acquisition.Zero_padding", "0"); //**Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF.
|
||||||
|
config->set_property("Acquisition.bit_transition_flag", "false");
|
||||||
|
acquisition = std::make_shared<GalileoE5aNoncoherentIQAcquisitionCaf>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
config = std::make_shared<InMemoryConfiguration>();
|
else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0)
|
||||||
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
|
{
|
||||||
|
tmp_gnss_synchro.System = 'E';
|
||||||
|
std::string signal = "5X";
|
||||||
|
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
||||||
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
|
System_and_Signal = "Galileo E5a";
|
||||||
|
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
|
||||||
|
acquisition = std::make_shared<GalileoE5aPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)
|
||||||
|
{
|
||||||
|
tmp_gnss_synchro.System = 'G';
|
||||||
|
std::string signal = "L5";
|
||||||
|
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
||||||
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
|
System_and_Signal = "GPS L5I";
|
||||||
|
config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells));
|
||||||
|
acquisition = std::make_shared<GpsL5iPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "The test can not run with the selected tracking implementation\n ";
|
||||||
|
throw(std::exception());
|
||||||
|
}
|
||||||
|
|
||||||
GNSSBlockFactory block_factory;
|
|
||||||
GpsL1CaPcpsAcquisitionFineDoppler* acquisition;
|
|
||||||
acquisition = new GpsL1CaPcpsAcquisitionFineDoppler(config.get(), "Acquisition", 1, 1);
|
|
||||||
|
|
||||||
acquisition->set_channel(1);
|
|
||||||
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
||||||
acquisition->set_threshold(config->property("Acquisition.threshold", 0.005));
|
acquisition->set_channel(0);
|
||||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz));
|
||||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 250));
|
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz));
|
||||||
|
acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold));
|
||||||
|
acquisition->init();
|
||||||
|
acquisition->set_local_code();
|
||||||
|
acquisition->set_state(1); // Ensure that acquisition starts at the first sample
|
||||||
|
acquisition->connect(top_block);
|
||||||
|
|
||||||
|
gr::blocks::file_source::sptr file_source;
|
||||||
|
std::string file = FLAGS_signal_file;
|
||||||
|
const char* file_name = file.c_str();
|
||||||
|
file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false);
|
||||||
|
file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample
|
||||||
|
gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make();
|
||||||
|
//gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration);
|
||||||
|
|
||||||
|
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
|
||||||
|
top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
|
||||||
|
//top_block->connect(head_samples, 0, acquisition->get_left_block(), 0);
|
||||||
|
|
||||||
boost::shared_ptr<Acquisition_msg_rx> msg_rx;
|
boost::shared_ptr<Acquisition_msg_rx> msg_rx;
|
||||||
try
|
try
|
||||||
@ -355,15 +506,8 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gr::blocks::file_source::sptr file_source;
|
msg_rx->top_block = top_block;
|
||||||
std::string file = FLAGS_signal_file;
|
top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
||||||
const char* file_name = file.c_str();
|
|
||||||
file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false);
|
|
||||||
gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make();
|
|
||||||
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
|
||||||
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
|
|
||||||
top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
|
|
||||||
top_block->msg_connect(acquisition->get_left_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
|
||||||
|
|
||||||
// 5. Run the flowgraph
|
// 5. Run the flowgraph
|
||||||
// Get visible GPS satellites (positive acquisitions with Doppler measurements)
|
// Get visible GPS satellites (positive acquisitions with Doppler measurements)
|
||||||
@ -378,6 +522,7 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
|||||||
code_delay_measurements_map.clear();
|
code_delay_measurements_map.clear();
|
||||||
acq_samplestamp_map.clear();
|
acq_samplestamp_map.clear();
|
||||||
|
|
||||||
|
|
||||||
for (unsigned int PRN = 1; PRN < 33; PRN++)
|
for (unsigned int PRN = 1; PRN < 33; PRN++)
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.PRN = PRN;
|
tmp_gnss_synchro.PRN = PRN;
|
||||||
@ -385,12 +530,13 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
|||||||
acquisition->init();
|
acquisition->init();
|
||||||
acquisition->set_local_code();
|
acquisition->set_local_code();
|
||||||
acquisition->reset();
|
acquisition->reset();
|
||||||
|
acquisition->set_state(1);
|
||||||
msg_rx->rx_message = 0;
|
msg_rx->rx_message = 0;
|
||||||
top_block->run();
|
top_block->run();
|
||||||
if (start_msg == true)
|
if (start_msg == true)
|
||||||
{
|
{
|
||||||
std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl;
|
std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl;
|
||||||
std::cout << "Searching for GPS Satellites in L1 band..." << std::endl;
|
std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl;
|
||||||
std::cout << "[";
|
std::cout << "[";
|
||||||
start_msg = false;
|
start_msg = false;
|
||||||
}
|
}
|
||||||
@ -410,10 +556,16 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
|||||||
std::cout << " . ";
|
std::cout << " . ";
|
||||||
}
|
}
|
||||||
top_block->stop();
|
top_block->stop();
|
||||||
file_source->seek(0, 0);
|
file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
}
|
}
|
||||||
std::cout << "]" << std::endl;
|
std::cout << "]" << std::endl;
|
||||||
|
std::cout << "-------------------------------------------\n";
|
||||||
|
|
||||||
|
for (auto& x : doppler_measurements_map)
|
||||||
|
{
|
||||||
|
std::cout << "DETECTED SATELLITE " << System_and_Signal << " PRN: " << x.first << " with Doppler: " << x.second << " [Hz], code phase: " << code_delay_measurements_map.at(x.first) << " [samples] at signal SampleStamp " << acq_samplestamp_map.at(x.first) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// report the elapsed time
|
// report the elapsed time
|
||||||
end = std::chrono::system_clock::now();
|
end = std::chrono::system_clock::now();
|
||||||
@ -424,7 +576,7 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
TEST_F(TrackingPullInTest, ValidationOfResults)
|
||||||
{
|
{
|
||||||
//*************************************************
|
//*************************************************
|
||||||
//***** STEP 1: Prepare the parameters sweep ******
|
//***** STEP 1: Prepare the parameters sweep ******
|
||||||
@ -531,8 +683,10 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
|||||||
{
|
{
|
||||||
true_acq_doppler_hz = doppler_measurements_map.find(FLAGS_test_satellite_PRN)->second;
|
true_acq_doppler_hz = doppler_measurements_map.find(FLAGS_test_satellite_PRN)->second;
|
||||||
true_acq_delay_samples = code_delay_measurements_map.find(FLAGS_test_satellite_PRN)->second;
|
true_acq_delay_samples = code_delay_measurements_map.find(FLAGS_test_satellite_PRN)->second;
|
||||||
acq_samplestamp_samples = 0; //acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second;
|
acq_samplestamp_samples = 0;
|
||||||
std::cout << "Estimated Initial Doppler " << true_acq_doppler_hz << "[Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]" << std::endl;
|
std::cout << "Estimated Initial Doppler " << true_acq_doppler_hz
|
||||||
|
<< " [Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]"
|
||||||
|
<< " Acquisition SampleStamp is " << acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second << std::endl;
|
||||||
}
|
}
|
||||||
//CN0 LOOP
|
//CN0 LOOP
|
||||||
std::vector<std::vector<double>> pull_in_results_v_v;
|
std::vector<std::vector<double>> pull_in_results_v_v;
|
||||||
@ -552,9 +706,9 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
|||||||
|
|
||||||
//create flowgraph
|
//create flowgraph
|
||||||
top_block = gr::make_top_block("Tracking test");
|
top_block = gr::make_top_block("Tracking test");
|
||||||
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1);
|
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking", config->property("Tracking.implementation", std::string("undefined")), 1, 1);
|
||||||
std::shared_ptr<TrackingInterface> tracking = std::dynamic_pointer_cast<TrackingInterface>(trk_);
|
std::shared_ptr<TrackingInterface> tracking = std::dynamic_pointer_cast<TrackingInterface>(trk_);
|
||||||
boost::shared_ptr<GpsL1CADllPllTrackingPullInTest_msg_rx> msg_rx = GpsL1CADllPllTrackingPullInTest_msg_rx_make();
|
boost::shared_ptr<TrackingPullInTest_msg_rx> msg_rx = TrackingPullInTest_msg_rx_make();
|
||||||
|
|
||||||
|
|
||||||
ASSERT_NO_THROW({
|
ASSERT_NO_THROW({
|
||||||
@ -583,19 +737,20 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
|||||||
gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false);
|
gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false);
|
||||||
gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make();
|
gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make();
|
||||||
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
||||||
|
gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration);
|
||||||
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
|
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
|
||||||
top_block->connect(gr_interleaved_char_to_complex, 0, tracking->get_left_block(), 0);
|
top_block->connect(gr_interleaved_char_to_complex, 0, head_samples, 0);
|
||||||
|
top_block->connect(head_samples, 0, tracking->get_left_block(), 0);
|
||||||
top_block->connect(tracking->get_right_block(), 0, sink, 0);
|
top_block->connect(tracking->get_right_block(), 0, sink, 0);
|
||||||
top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
||||||
|
file_source->seek(2 * FLAGS_skip_samples + acq_samplestamp_samples, 0); //skip head. ibyte, two bytes per complex sample
|
||||||
file_source->seek(acq_samplestamp_samples, 0);
|
|
||||||
}) << "Failure connecting the blocks of tracking test.";
|
}) << "Failure connecting the blocks of tracking test.";
|
||||||
|
|
||||||
|
|
||||||
//********************************************************************
|
//********************************************************************
|
||||||
//***** STEP 5: Perform the signal tracking and read the results *****
|
//***** STEP 5: Perform the signal tracking and read the results *****
|
||||||
//********************************************************************
|
//********************************************************************
|
||||||
std::cout << "------------ START TRACKING -------------" << std::endl;
|
std::cout << "--- START TRACKING WITH PULL-IN ERROR: " << acq_doppler_error_hz_values.at(current_acq_doppler_error_idx) << " [Hz] and " << acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) << " [Chips] ---" << std::endl;
|
||||||
tracking->start_tracking();
|
tracking->start_tracking();
|
||||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||||
EXPECT_NO_THROW({
|
EXPECT_NO_THROW({
|
||||||
@ -630,6 +785,8 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
|||||||
std::vector<double> prompt;
|
std::vector<double> prompt;
|
||||||
std::vector<double> early;
|
std::vector<double> early;
|
||||||
std::vector<double> late;
|
std::vector<double> late;
|
||||||
|
std::vector<double> v_early;
|
||||||
|
std::vector<double> v_late;
|
||||||
std::vector<double> promptI;
|
std::vector<double> promptI;
|
||||||
std::vector<double> promptQ;
|
std::vector<double> promptQ;
|
||||||
std::vector<double> CN0_dBHz;
|
std::vector<double> CN0_dBHz;
|
||||||
@ -647,6 +804,8 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
|||||||
prompt.push_back(trk_dump.abs_P);
|
prompt.push_back(trk_dump.abs_P);
|
||||||
early.push_back(trk_dump.abs_E);
|
early.push_back(trk_dump.abs_E);
|
||||||
late.push_back(trk_dump.abs_L);
|
late.push_back(trk_dump.abs_L);
|
||||||
|
v_early.push_back(trk_dump.abs_VE);
|
||||||
|
v_late.push_back(trk_dump.abs_VL);
|
||||||
promptI.push_back(trk_dump.prompt_I);
|
promptI.push_back(trk_dump.prompt_I);
|
||||||
promptQ.push_back(trk_dump.prompt_Q);
|
promptQ.push_back(trk_dump.prompt_Q);
|
||||||
CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz);
|
CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz);
|
||||||
@ -692,6 +851,11 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
|||||||
g1.plot_xy(trk_timestamp_s, prompt, "Prompt", decimate);
|
g1.plot_xy(trk_timestamp_s, prompt, "Prompt", decimate);
|
||||||
g1.plot_xy(trk_timestamp_s, early, "Early", decimate);
|
g1.plot_xy(trk_timestamp_s, early, "Early", decimate);
|
||||||
g1.plot_xy(trk_timestamp_s, late, "Late", decimate);
|
g1.plot_xy(trk_timestamp_s, late, "Late", decimate);
|
||||||
|
if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0)
|
||||||
|
{
|
||||||
|
g1.plot_xy(trk_timestamp_s, v_early, "Very Early", decimate);
|
||||||
|
g1.plot_xy(trk_timestamp_s, v_late, "Very Late", decimate);
|
||||||
|
}
|
||||||
g1.set_legend();
|
g1.set_legend();
|
||||||
//g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)));
|
//g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)));
|
||||||
//g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18);
|
//g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18);
|
@ -33,6 +33,7 @@ include_directories(
|
|||||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl
|
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters
|
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks
|
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks
|
||||||
|
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs
|
||||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||||
${GLOG_INCLUDE_DIRS}
|
${GLOG_INCLUDE_DIRS}
|
||||||
${GFlags_INCLUDE_DIRS}
|
${GFlags_INCLUDE_DIRS}
|
||||||
|
@ -144,8 +144,6 @@ FrontEndCal_msg_rx::FrontEndCal_msg_rx() : gr::block("FrontEndCal_msg_rx", gr::i
|
|||||||
|
|
||||||
|
|
||||||
FrontEndCal_msg_rx::~FrontEndCal_msg_rx() {}
|
FrontEndCal_msg_rx::~FrontEndCal_msg_rx() {}
|
||||||
|
|
||||||
|
|
||||||
void wait_message()
|
void wait_message()
|
||||||
{
|
{
|
||||||
while (!stop)
|
while (!stop)
|
||||||
@ -353,13 +351,14 @@ int main(int argc, char** argv)
|
|||||||
gnss_synchro->PRN = 1;
|
gnss_synchro->PRN = 1;
|
||||||
|
|
||||||
long fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000);
|
long fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000);
|
||||||
|
configuration->set_property("Acquisition.max_dwells", "10");
|
||||||
|
|
||||||
GNSSBlockFactory block_factory;
|
GNSSBlockFactory block_factory;
|
||||||
acquisition = new GpsL1CaPcpsAcquisitionFineDoppler(configuration.get(), "Acquisition", 1, 1);
|
acquisition = new GpsL1CaPcpsAcquisitionFineDoppler(configuration.get(), "Acquisition", 1, 1);
|
||||||
|
|
||||||
acquisition->set_channel(1);
|
acquisition->set_channel(1);
|
||||||
acquisition->set_gnss_synchro(gnss_synchro);
|
acquisition->set_gnss_synchro(gnss_synchro);
|
||||||
acquisition->set_threshold(configuration->property("Acquisition.threshold", 0.0));
|
acquisition->set_threshold(configuration->property("Acquisition.threshold", 2.0));
|
||||||
acquisition->set_doppler_max(configuration->property("Acquisition.doppler_max", 10000));
|
acquisition->set_doppler_max(configuration->property("Acquisition.doppler_max", 10000));
|
||||||
acquisition->set_doppler_step(configuration->property("Acquisition.doppler_step", 250));
|
acquisition->set_doppler_step(configuration->property("Acquisition.doppler_step", 250));
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ Acquisition_2S.doppler_step=125
|
|||||||
|
|
||||||
Acquisition_2S.use_CFAR_algorithm=false
|
Acquisition_2S.use_CFAR_algorithm=false
|
||||||
|
|
||||||
Acquisition_2S.threshold=19.5
|
Acquisition_2S.threshold=10
|
||||||
|
|
||||||
Acquisition_2S.blocking=true
|
Acquisition_2S.blocking=true
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user