mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2026-08-17 15:48:58 +00:00
Implement tracking_Gaussian_filter for use in mixed_veml_tracking. Add mixed tracking block for galileo e1, along with test block
This commit is contained in:
@@ -49,6 +49,7 @@ endif()
|
||||
|
||||
set(TRACKING_ADAPTER_SOURCES
|
||||
galileo_e1_dll_pll_veml_tracking.cc
|
||||
galileo_e1_mixed_veml_tracking.cc
|
||||
galileo_e1_tcp_connector_tracking.cc
|
||||
gps_l1_ca_dll_pll_tracking.cc
|
||||
gps_l1_ca_tcp_connector_tracking.cc
|
||||
@@ -67,6 +68,7 @@ set(TRACKING_ADAPTER_SOURCES
|
||||
|
||||
set(TRACKING_ADAPTER_HEADERS
|
||||
galileo_e1_dll_pll_veml_tracking.h
|
||||
galileo_e1_mixed_veml_tracking.h
|
||||
galileo_e1_tcp_connector_tracking.h
|
||||
gps_l1_ca_dll_pll_tracking.h
|
||||
gps_l1_ca_tcp_connector_tracking.h
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
/*!
|
||||
* \file galileo_e1_mixed_veml_tracking.cc
|
||||
* \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block
|
||||
* to a TrackingInterface for Galileo E1 signals
|
||||
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
*
|
||||
* Code DLL + carrier PLL according to the algorithms described in:
|
||||
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
|
||||
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
|
||||
* Approach, Birkhauser, 2007
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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 "galileo_e1_mixed_veml_tracking.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "display.h"
|
||||
#include "dll_pll_conf.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
|
||||
GalileoE1MixedVemlTracking::GalileoE1MixedVemlTracking(
|
||||
ConfigurationInterface* configuration, const std::string& role,
|
||||
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||
{
|
||||
Dll_Pll_Conf trk_param = Dll_Pll_Conf();
|
||||
DLOG(INFO) << "role " << role;
|
||||
//################# CONFIGURATION PARAMETERS ########################
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string item_type = configuration->property(role + ".item_type", default_item_type);
|
||||
int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||
int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||
trk_param.fs_in = fs_in;
|
||||
bool dump = configuration->property(role + ".dump", false);
|
||||
trk_param.dump = dump;
|
||||
std::string default_dump_filename = "./track_ch";
|
||||
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
trk_param.dump_filename = dump_filename;
|
||||
bool dump_mat = configuration->property(role + ".dump_mat", true);
|
||||
trk_param.dump_mat = dump_mat;
|
||||
trk_param.high_dyn = configuration->property(role + ".high_dyn", false);
|
||||
if (configuration->property(role + ".smoother_length", 10) < 1)
|
||||
{
|
||||
trk_param.smoother_length = 1;
|
||||
std::cout << TEXT_RED << "WARNING: Gal. E1. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
trk_param.smoother_length = configuration->property(role + ".smoother_length", 10);
|
||||
}
|
||||
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0);
|
||||
if (FLAGS_pll_bw_hz != 0.0)
|
||||
{
|
||||
pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
|
||||
}
|
||||
trk_param.pll_bw_hz = pll_bw_hz;
|
||||
float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 0.5);
|
||||
if (FLAGS_dll_bw_hz != 0.0)
|
||||
{
|
||||
dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz);
|
||||
}
|
||||
trk_param.dll_bw_hz = dll_bw_hz;
|
||||
float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0);
|
||||
trk_param.pll_bw_narrow_hz = pll_bw_narrow_hz;
|
||||
float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25);
|
||||
trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz;
|
||||
|
||||
int dll_filter_order = configuration->property(role + ".dll_filter_order", 2);
|
||||
if (dll_filter_order < 1)
|
||||
{
|
||||
LOG(WARNING) << "dll_filter_order parameter must be 1, 2 or 3. Set to 1.";
|
||||
dll_filter_order = 1;
|
||||
}
|
||||
if (dll_filter_order > 3)
|
||||
{
|
||||
LOG(WARNING) << "dll_filter_order parameter must be 1, 2 or 3. Set to 3.";
|
||||
dll_filter_order = 3;
|
||||
}
|
||||
trk_param.dll_filter_order = dll_filter_order;
|
||||
|
||||
int pll_filter_order = configuration->property(role + ".pll_filter_order", 3);
|
||||
if (pll_filter_order < 2)
|
||||
{
|
||||
LOG(WARNING) << "pll_filter_order parameter must be 2 or 3. Set to 2.";
|
||||
pll_filter_order = 2;
|
||||
}
|
||||
if (pll_filter_order > 3)
|
||||
{
|
||||
LOG(WARNING) << "pll_filter_order parameter must be 2 or 3. Set to 3.";
|
||||
pll_filter_order = 3;
|
||||
}
|
||||
trk_param.pll_filter_order = pll_filter_order;
|
||||
|
||||
if (pll_filter_order == 2)
|
||||
{
|
||||
trk_param.fll_filter_order = 1;
|
||||
}
|
||||
if (pll_filter_order == 3)
|
||||
{
|
||||
trk_param.fll_filter_order = 2;
|
||||
}
|
||||
|
||||
bool enable_fll_pull_in = configuration->property(role + ".enable_fll_pull_in", false);
|
||||
trk_param.enable_fll_pull_in = enable_fll_pull_in;
|
||||
float fll_bw_hz = configuration->property(role + ".fll_bw_hz", 35.0);
|
||||
trk_param.fll_bw_hz = fll_bw_hz;
|
||||
trk_param.pull_in_time_s = configuration->property(role + ".pull_in_time_s", trk_param.pull_in_time_s);
|
||||
|
||||
int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1);
|
||||
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.15);
|
||||
trk_param.early_late_space_chips = early_late_space_chips;
|
||||
float very_early_late_space_chips = configuration->property(role + ".very_early_late_space_chips", 0.5);
|
||||
trk_param.very_early_late_space_chips = very_early_late_space_chips;
|
||||
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15);
|
||||
trk_param.early_late_space_narrow_chips = early_late_space_narrow_chips;
|
||||
float very_early_late_space_narrow_chips = configuration->property(role + ".very_early_late_space_narrow_chips", 0.5);
|
||||
trk_param.very_early_late_space_narrow_chips = very_early_late_space_narrow_chips;
|
||||
bool track_pilot = configuration->property(role + ".track_pilot", false);
|
||||
if (extend_correlation_symbols < 1)
|
||||
{
|
||||
extend_correlation_symbols = 1;
|
||||
std::cout << TEXT_RED << "WARNING: Galileo E1. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (4 ms)" << TEXT_RESET << std::endl;
|
||||
}
|
||||
else if (!track_pilot and extend_correlation_symbols > 1)
|
||||
{
|
||||
extend_correlation_symbols = 1;
|
||||
std::cout << TEXT_RED << "WARNING: Galileo E1. Extended coherent integration is not allowed when tracking the data component. Coherent integration has been set to 4 ms (1 symbol)" << TEXT_RESET << std::endl;
|
||||
}
|
||||
if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz))
|
||||
{
|
||||
std::cout << TEXT_RED << "WARNING: Galileo E1. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl;
|
||||
}
|
||||
trk_param.track_pilot = track_pilot;
|
||||
trk_param.extend_correlation_symbols = extend_correlation_symbols;
|
||||
int vector_length = std::round(fs_in / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS));
|
||||
trk_param.vector_length = vector_length;
|
||||
trk_param.system = 'E';
|
||||
char sig_[3] = "1B";
|
||||
std::memcpy(trk_param.signal, sig_, 3);
|
||||
trk_param.cn0_samples = configuration->property(role + ".cn0_samples", trk_param.cn0_samples);
|
||||
trk_param.cn0_min = configuration->property(role + ".cn0_min", trk_param.cn0_min);
|
||||
trk_param.max_code_lock_fail = configuration->property(role + ".max_lock_fail", trk_param.max_code_lock_fail);
|
||||
trk_param.max_carrier_lock_fail = configuration->property(role + ".max_carrier_lock_fail", trk_param.max_carrier_lock_fail);
|
||||
trk_param.carrier_lock_th = configuration->property(role + ".carrier_lock_th", trk_param.carrier_lock_th);
|
||||
|
||||
//################# MAKE TRACKING GNURadio object ###################
|
||||
if (item_type == "gr_complex")
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
tracking_ = mixed_veml_make_tracking(trk_param);
|
||||
}
|
||||
else
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
LOG(WARNING) << item_type << " unknown tracking item type.";
|
||||
}
|
||||
|
||||
channel_ = 0;
|
||||
DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")";
|
||||
if (in_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GalileoE1MixedVemlTracking::~GalileoE1MixedVemlTracking() = default;
|
||||
|
||||
|
||||
void GalileoE1MixedVemlTracking::stop_tracking()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GalileoE1MixedVemlTracking::start_tracking()
|
||||
{
|
||||
tracking_->start_tracking();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set tracking channel unique ID
|
||||
*/
|
||||
void GalileoE1MixedVemlTracking::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
tracking_->set_channel(channel);
|
||||
}
|
||||
|
||||
|
||||
void GalileoE1MixedVemlTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
|
||||
{
|
||||
tracking_->set_gnss_synchro(p_gnss_synchro);
|
||||
}
|
||||
|
||||
|
||||
void GalileoE1MixedVemlTracking::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (top_block)
|
||||
{ /* top_block is not null */
|
||||
};
|
||||
//nothing to connect, now the tracking uses gr_sync_decimator
|
||||
}
|
||||
|
||||
|
||||
void GalileoE1MixedVemlTracking::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (top_block)
|
||||
{ /* top_block is not null */
|
||||
};
|
||||
//nothing to disconnect, now the tracking uses gr_sync_decimator
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE1MixedVemlTracking::get_left_block()
|
||||
{
|
||||
return tracking_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE1MixedVemlTracking::get_right_block()
|
||||
{
|
||||
return tracking_;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*!
|
||||
* \file galileo_e1_mixed_veml_tracking.h
|
||||
* \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block
|
||||
* to a TrackingInterface for Galileo E1 signals
|
||||
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
*
|
||||
* Code DLL + carrier PLL according to the algorithms described in:
|
||||
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
|
||||
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
|
||||
* Approach, Birkhauser, 2007
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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_GALILEO_E1_MIXED_VEML_TRACKING_H_
|
||||
#define GNSS_SDR_GALILEO_E1_MIXED_VEML_TRACKING_H_
|
||||
|
||||
#include "mixed_veml_tracking.h"
|
||||
#include "tracking_interface.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class Adapts a DLL+PLL VEML (Very Early Minus Late) tracking
|
||||
* loop block to a TrackingInterface for Galileo E1 signals
|
||||
*/
|
||||
class GalileoE1MixedVemlTracking : public TrackingInterface
|
||||
{
|
||||
public:
|
||||
GalileoE1MixedVemlTracking(ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams);
|
||||
|
||||
virtual ~GalileoE1MixedVemlTracking();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
//! Returns "Galileo_E1_MIXED_VEML_Tracking"
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Galileo_E1_Mixed_VEML_Tracking";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block) override;
|
||||
void disconnect(gr::top_block_sptr top_block) override;
|
||||
gr::basic_block_sptr get_left_block() override;
|
||||
gr::basic_block_sptr get_right_block() override;
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel unique ID
|
||||
*/
|
||||
void set_channel(unsigned int channel) override;
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
|
||||
* to efficiently exchange synchronization data between acquisition and
|
||||
* tracking blocks
|
||||
*/
|
||||
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
|
||||
|
||||
void start_tracking() override;
|
||||
/*!
|
||||
* \brief Stop running tracking
|
||||
*/
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
mixed_veml_tracking_sptr tracking_;
|
||||
size_t item_size_;
|
||||
unsigned int channel_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
};
|
||||
|
||||
#endif // GNSS_SDR_GALILEO_E1_MIXED_VEML_TRACKING_H_
|
||||
@@ -49,6 +49,7 @@ set(TRACKING_GR_BLOCKS_SOURCES
|
||||
glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc
|
||||
glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc
|
||||
dll_pll_veml_tracking.cc
|
||||
mixed_veml_tracking.cc
|
||||
${OPT_TRACKING_BLOCKS_SOURCES}
|
||||
)
|
||||
|
||||
@@ -62,6 +63,7 @@ set(TRACKING_GR_BLOCKS_HEADERS
|
||||
glonass_l2_ca_dll_pll_tracking_cc.h
|
||||
glonass_l2_ca_dll_pll_c_aid_tracking_cc.h
|
||||
glonass_l2_ca_dll_pll_c_aid_tracking_sc.h
|
||||
mixed_veml_tracking.h
|
||||
dll_pll_veml_tracking.h
|
||||
${OPT_TRACKING_BLOCKS_HEADERS}
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,266 @@
|
||||
/*!
|
||||
* \file mixed_veml_tracking.h
|
||||
* \brief Implementation of a code DLL + carrier PLL tracking block.
|
||||
* \author Javier Arribas, 2018. jarribas(at)cttc.es
|
||||
* \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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_MIXED_VEML_TRACKING_H
|
||||
#define GNSS_SDR_MIXED_VEML_TRACKING_H
|
||||
|
||||
//#include "tracking_models.h"
|
||||
#include "tracking_Gaussian_filter.h"
|
||||
|
||||
#include "cpu_multicorrelator_real_codes.h"
|
||||
#include "dll_pll_conf.h"
|
||||
#include "exponential_smoother.h"
|
||||
#include "tracking_FLL_PLL_filter.h" // for PLL/FLL filter
|
||||
#include "tracking_loop_filter.h" // for DLL filter
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/shared_ptr.hpp> // for boost::shared_ptr
|
||||
#include <gnuradio/block.h> // for block
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
#include <gnuradio/types.h> // for gr_vector_int, gr_vector...
|
||||
#include <pmt/pmt.h> // for pmt_t
|
||||
#include <cstdint> // for int32_t
|
||||
#include <fstream> // for string, ofstream
|
||||
#include <utility> // for pair
|
||||
#include <vector>
|
||||
|
||||
class CarrierTransitionModel : public ModelFunction
|
||||
{
|
||||
public:
|
||||
// explicit CarrierTransitionModel(const float carrier_pdi) { pdi = carrier_pdi; };
|
||||
arma::vec operator()(const arma::vec& input) override {
|
||||
arma::vec output = arma::zeros(3,1);
|
||||
output(0, 0) = input(0) + PI_2*pdi*input(1) + 0.5*PI_2*std::pow(pdi, 2)*input(2);
|
||||
output(0, 0) = input(1) + pdi*input(2);
|
||||
output(0, 0) = input(2);
|
||||
|
||||
return output;
|
||||
};
|
||||
void set_code_period(const float carrier_pdi) { pdi = carrier_pdi; };
|
||||
|
||||
private:
|
||||
arma::mat t_mat;
|
||||
float pdi;
|
||||
};
|
||||
|
||||
class CarrierMeasurementModel : public ModelFunction
|
||||
{
|
||||
public:
|
||||
// explicit CarrierMeasurementModel(const float carrier_pow) { alpha = carrier_pow; };
|
||||
arma::vec operator()(const arma::vec& input) override {
|
||||
using namespace std::complex_literals;
|
||||
std::complex<double> output_iq = static_cast<double>(alpha) * std::exp( 1i * static_cast<double>(input(0)) );
|
||||
|
||||
arma::vec output = arma::zeros(2,1);
|
||||
output(0, 0) = static_cast<float>( std::real( output_iq ) );
|
||||
output(1, 0) = static_cast<float>( std::imag( output_iq ) );
|
||||
|
||||
return output;
|
||||
};
|
||||
void set_signal_power(const float carrier_pow) { alpha = carrier_pow; };
|
||||
|
||||
private:
|
||||
float alpha;
|
||||
};
|
||||
|
||||
|
||||
class Gnss_Synchro;
|
||||
class mixed_veml_tracking;
|
||||
|
||||
using mixed_veml_tracking_sptr = boost::shared_ptr<mixed_veml_tracking>;
|
||||
|
||||
mixed_veml_tracking_sptr mixed_veml_make_tracking(const Dll_Pll_Conf &conf_);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a code DLL + carrier PLL tracking block.
|
||||
*/
|
||||
class mixed_veml_tracking : public gr::block
|
||||
{
|
||||
public:
|
||||
~mixed_veml_tracking();
|
||||
|
||||
void set_channel(uint32_t channel);
|
||||
void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro);
|
||||
void start_tracking();
|
||||
void stop_tracking();
|
||||
|
||||
int general_work(int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||
|
||||
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
|
||||
|
||||
CarrierTransitionModel d_carrier_evolution_model;
|
||||
CarrierMeasurementModel d_correllator_output_model;
|
||||
|
||||
private:
|
||||
friend mixed_veml_tracking_sptr mixed_veml_make_tracking(const Dll_Pll_Conf &conf_);
|
||||
void msg_handler_telemetry_to_trk(const pmt::pmt_t &msg);
|
||||
mixed_veml_tracking(const Dll_Pll_Conf &conf_);
|
||||
|
||||
bool cn0_and_tracking_lock_status(double coh_integration_time_s);
|
||||
bool acquire_secondary();
|
||||
void do_correlation_step(const gr_complex *input_samples);
|
||||
void run_dll_pll();
|
||||
void update_tracking_vars();
|
||||
void clear_tracking_vars();
|
||||
void save_correlation_results();
|
||||
void log_data();
|
||||
int32_t save_matfile();
|
||||
|
||||
// tracking configuration vars
|
||||
Dll_Pll_Conf trk_parameters;
|
||||
bool d_veml;
|
||||
bool d_cloop;
|
||||
uint32_t d_channel;
|
||||
Gnss_Synchro *d_acquisition_gnss_synchro;
|
||||
|
||||
// Signal parameters
|
||||
bool d_secondary;
|
||||
double d_signal_carrier_freq;
|
||||
double d_code_period;
|
||||
double d_code_chip_rate;
|
||||
uint32_t d_secondary_code_length;
|
||||
uint32_t d_data_secondary_code_length;
|
||||
uint32_t d_code_length_chips;
|
||||
uint32_t d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled)
|
||||
int32_t d_symbols_per_bit;
|
||||
std::string systemName;
|
||||
std::string signal_type;
|
||||
std::string *d_secondary_code_string;
|
||||
std::string *d_data_secondary_code_string;
|
||||
std::string signal_pretty_name;
|
||||
|
||||
int32_t *d_preambles_symbols;
|
||||
int32_t d_preamble_length_symbols;
|
||||
|
||||
// dll filter buffer
|
||||
boost::circular_buffer<float> d_dll_filt_history;
|
||||
// tracking state machine
|
||||
int32_t d_state;
|
||||
|
||||
// Integration period in samples
|
||||
int32_t d_correlation_length_ms;
|
||||
int32_t d_n_correlator_taps;
|
||||
|
||||
float *d_tracking_code;
|
||||
float *d_data_code;
|
||||
float *d_local_code_shift_chips;
|
||||
float *d_prompt_data_shift;
|
||||
Cpu_Multicorrelator_Real_Codes multicorrelator_cpu;
|
||||
Cpu_Multicorrelator_Real_Codes correlator_data_cpu; //for data channel
|
||||
|
||||
/* TODO: currently the multicorrelator does not support adding extra correlator
|
||||
with different local code, thus we need extra multicorrelator instance.
|
||||
Implement this functionality inside multicorrelator class
|
||||
as an enhancement to increase the performance
|
||||
*/
|
||||
gr_complex *d_correlator_outs;
|
||||
gr_complex *d_Very_Early;
|
||||
gr_complex *d_Early;
|
||||
gr_complex *d_Prompt;
|
||||
gr_complex *d_Late;
|
||||
gr_complex *d_Very_Late;
|
||||
|
||||
bool d_enable_extended_integration;
|
||||
int32_t d_extend_correlation_symbols_count;
|
||||
int32_t d_current_symbol;
|
||||
int32_t d_current_data_symbol;
|
||||
|
||||
gr_complex d_VE_accu;
|
||||
gr_complex d_E_accu;
|
||||
gr_complex d_P_accu;
|
||||
gr_complex d_P_accu_old;
|
||||
gr_complex d_L_accu;
|
||||
gr_complex d_VL_accu;
|
||||
|
||||
gr_complex d_P_data_accu;
|
||||
gr_complex *d_Prompt_Data;
|
||||
|
||||
double d_code_phase_step_chips;
|
||||
double d_code_phase_rate_step_chips;
|
||||
boost::circular_buffer<std::pair<double, double>> d_code_ph_history;
|
||||
double d_carrier_phase_step_rad;
|
||||
double d_carrier_phase_rate_step_rad;
|
||||
boost::circular_buffer<std::pair<double, double>> d_carr_ph_history;
|
||||
|
||||
// remaining code phase and carrier phase between tracking loops
|
||||
double d_rem_code_phase_samples;
|
||||
float d_rem_carr_phase_rad;
|
||||
|
||||
TrackingNonlinearFilter<CubatureFilter> d_carrier_loop_ckf;
|
||||
Tracking_loop_filter d_code_loop_filter;
|
||||
Tracking_FLL_PLL_filter d_carrier_loop_filter;
|
||||
|
||||
// acquisition
|
||||
double d_acq_code_phase_samples;
|
||||
double d_acq_carrier_doppler_hz;
|
||||
|
||||
// tracking vars
|
||||
bool d_pull_in_transitory;
|
||||
bool d_corrected_doppler;
|
||||
double d_current_correlation_time_s;
|
||||
double d_carr_phase_error_hz;
|
||||
double d_carr_freq_error_hz;
|
||||
double d_carr_error_filt_hz;
|
||||
double d_code_error_chips;
|
||||
double d_code_error_filt_chips;
|
||||
double d_code_freq_chips;
|
||||
double d_carrier_doppler_hz;
|
||||
double d_acc_carrier_phase_rad;
|
||||
double d_rem_code_phase_chips;
|
||||
double T_chip_seconds;
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
// PRN period in samples
|
||||
int32_t d_current_prn_length_samples;
|
||||
// processing samples counters
|
||||
uint64_t d_sample_counter;
|
||||
uint64_t d_acq_sample_stamp;
|
||||
|
||||
// CN0 estimation and lock detector
|
||||
int32_t d_cn0_estimation_counter;
|
||||
int32_t d_carrier_lock_fail_counter;
|
||||
int32_t d_code_lock_fail_counter;
|
||||
double d_carrier_lock_test;
|
||||
double d_CN0_SNV_dB_Hz;
|
||||
double d_carrier_lock_threshold;
|
||||
boost::circular_buffer<gr_complex> d_Prompt_circular_buffer;
|
||||
std::vector<gr_complex> d_Prompt_buffer;
|
||||
Exponential_Smoother d_cn0_smoother;
|
||||
Exponential_Smoother d_carrier_lock_test_smoother;
|
||||
// file dump
|
||||
std::ofstream d_dump_file;
|
||||
std::string d_dump_filename;
|
||||
bool d_dump;
|
||||
bool d_dump_mat;
|
||||
};
|
||||
|
||||
#endif // GNSS_SDR_MIXED_VEML_TRACKING_H
|
||||
@@ -29,6 +29,7 @@ set(TRACKING_LIB_SOURCES
|
||||
tracking_discriminators.cc
|
||||
tracking_FLL_PLL_filter.cc
|
||||
tracking_loop_filter.cc
|
||||
tracking_Gaussian_filter.cc
|
||||
dll_pll_conf.cc
|
||||
bayesian_estimation.cc
|
||||
exponential_smoother.cc
|
||||
@@ -46,9 +47,11 @@ set(TRACKING_LIB_HEADERS
|
||||
tracking_discriminators.h
|
||||
tracking_FLL_PLL_filter.h
|
||||
tracking_loop_filter.h
|
||||
tracking_Gaussian_filter.h
|
||||
dll_pll_conf.h
|
||||
bayesian_estimation.h
|
||||
exponential_smoother.h
|
||||
tracking_models.h
|
||||
)
|
||||
|
||||
|
||||
@@ -67,7 +70,7 @@ if(ENABLE_CUDA)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ARMADILLO_VERSION_STRING VERSION_GREATER 7.400)
|
||||
if(ARMADILLO_VERSION_STRING VERSION_GREATER_EQUAL 7.400)
|
||||
# sqrtmat_sympd() requires 7.400
|
||||
set(TRACKING_LIB_SOURCES ${TRACKING_LIB_SOURCES} nonlinear_tracking.cc)
|
||||
set(TRACKING_LIB_HEADERS ${TRACKING_LIB_HEADERS} nonlinear_tracking.h)
|
||||
|
||||
@@ -132,7 +132,6 @@ void CubatureFilter::predict_sequential(const arma::vec& x_post, const arma::mat
|
||||
// Propagate and evaluate cubature points
|
||||
arma::vec Xi_post;
|
||||
arma::vec Xi_pred;
|
||||
|
||||
for (uint8_t i = 0; i < np; i++)
|
||||
{
|
||||
Xi_post = Sm_post * (std::sqrt(static_cast<float>(np) / 2.0) * gen_one.col(i)) + x_post;
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
#include <armadillo>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
//#include "tracking_models.h"
|
||||
|
||||
// Abstract model function
|
||||
class ModelFunction
|
||||
@@ -55,6 +56,7 @@ public:
|
||||
virtual ~ModelFunction() = default;
|
||||
};
|
||||
|
||||
|
||||
class GaussianFilter
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*!
|
||||
* \file tracking_Gaussian_filter.cc
|
||||
* \brief Implementation of a nonlinear Gaussian filter for tracking carrier loop.
|
||||
*
|
||||
* Class that implements a nonlinear Gaussian for tracking carrier loop using
|
||||
* CKF or UKF implementations.
|
||||
*
|
||||
* [1] I Arasaratnam and S Haykin. Cubature kalman filters. IEEE
|
||||
* Transactions on Automatic Control, 54(6):1254–1269,2009.
|
||||
*
|
||||
* \authors <ul>
|
||||
* <li> Gerald LaMountain, 2018. gerald(at)ece.neu.edu
|
||||
* <li> Jordi Vila-Valls 2019. 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 "tracking_Gaussian_filter.h"
|
||||
|
||||
void TrackingGaussianFilter::set_ncov_measurement(float ev_1, float ev_2)
|
||||
{
|
||||
ncov_measurement = arma::zeros(2, 2);
|
||||
ncov_measurement(0, 0) = ev_1;
|
||||
ncov_measurement(1, 1) = ev_2;
|
||||
}
|
||||
|
||||
void TrackingGaussianFilter::set_ncov_process(float ev_1, float ev_2, float ev_3)
|
||||
{
|
||||
ncov_process = arma::zeros(3, 3);
|
||||
ncov_process(0, 0) = ev_1;
|
||||
ncov_process(1, 1) = ev_2;
|
||||
ncov_process(2, 2) = ev_3;
|
||||
}
|
||||
|
||||
void TrackingGaussianFilter::set_params(float ev_1, float ev_2, float pdi_carr)
|
||||
{
|
||||
set_ncov_measurement(ev_1, ev_2);
|
||||
set_ncov_process(std::pow(pdi_carr, 6), std::pow(pdi_carr, 4), std::pow(pdi_carr, 2));
|
||||
}
|
||||
|
||||
void TrackingGaussianFilter::set_state(float x_1, float x_2, float x_3)
|
||||
{
|
||||
state = arma::zeros(3,1);
|
||||
state(0) = x_1;
|
||||
state(1) = x_2;
|
||||
state(2) = x_3;
|
||||
}
|
||||
|
||||
void TrackingGaussianFilter::set_state_cov(float P_x_1, float P_x_2, float P_x_3)
|
||||
{
|
||||
state_cov = arma::zeros(3,3);
|
||||
state_cov(0, 0) = P_x_1;
|
||||
state_cov(1, 1) = P_x_2;
|
||||
state_cov(2, 2) = P_x_3;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*!
|
||||
* \file tracking_Gaussian_filter.h
|
||||
* \brief Implementation of a Gaussian filter for tracking carrier loop.
|
||||
*
|
||||
* Class that implements a Gaussian for tracking carrier loop using
|
||||
* CKF or UKF implementations.
|
||||
*
|
||||
* [1] I Arasaratnam and S Haykin. Cubature kalman filters. IEEE
|
||||
* Transactions on Automatic Control, 54(6):1254–1269,2009.
|
||||
*
|
||||
* \authors <ul>
|
||||
* <li> Gerald LaMountain, 2018. gerald(at)ece.neu.edu
|
||||
* <li> Jordi Vila-Valls 2019. 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_TRACKING_GAUSSIAN_FILTER_H_
|
||||
#define GNSS_SDR_TRACKING_GAUSSIAN_FILTER_H_
|
||||
|
||||
#include <armadillo>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
// #include "tracking_models.h"
|
||||
#include "nonlinear_tracking.h"
|
||||
#include "MATH_CONSTANTS.h"
|
||||
|
||||
/*!
|
||||
* \brief This class implements a standard Gaussian filter for carrier tracking.
|
||||
*
|
||||
* The algorithm is described in:
|
||||
* [1] I Arasaratnam and S Haykin. Cubature kalman filters. IEEE
|
||||
* Transactions on Automatic Control, 54(6):1254–1269,2009.
|
||||
*/
|
||||
class TrackingGaussianFilter
|
||||
{
|
||||
public:
|
||||
// TrackingGaussianFilter();
|
||||
// TrackingGaussianFilter(float pdi_carr, uint32_t kf_order, bool kf_extended);
|
||||
// ~TrackingGaussianFilter();
|
||||
|
||||
// void initialize();
|
||||
//void initialize(float pdi_carar, arma::colvec x_ini, arma::mat P_x_ini, arma::mat Q_ini, arma::mat R_ini, ModelFunction* f_t, ModelFunction* f_m);
|
||||
|
||||
//void set_ncov_process(float err_variance);
|
||||
void set_ncov_process(float ev_1, float ev_2, float ev_3);
|
||||
|
||||
// void set_ncov_measurement(float err_variance);
|
||||
void set_ncov_measurement(float ev_1, float ev_2);
|
||||
|
||||
void set_params(float ev_1, float ev_2, float pdi_carr);
|
||||
|
||||
// void set_KF_x(float x_1, float x_2);
|
||||
void set_state(float x_1, float x_2, float x_3);
|
||||
|
||||
//void set_KF_P_x(float P_x_1, float P_x_2);
|
||||
void set_state_cov(float P_x_1, float P_x_2, float P_x_3);
|
||||
|
||||
// void setup_filter(float pdi_carr, uint32_t kf_order, bool kf_extended);
|
||||
|
||||
protected:
|
||||
|
||||
//float d_pdi_carr = 0.0;
|
||||
// uint32_t d_kf_order = 2U;
|
||||
// bool d_kf_extended = false;
|
||||
|
||||
// Kalman filter parameters
|
||||
// arma::colvec kf_x_ini; /* initial state vector */
|
||||
// arma::mat kf_P_x_ini; /* initial state error covariance matrix */
|
||||
|
||||
arma::colvec state; /* state vector */
|
||||
arma::mat state_cov; /* state error covariance matrix */
|
||||
|
||||
// arma::colvec kf_x_pre; /* predicted state vector */
|
||||
// arma::mat kf_P_x_pre; /* Predicted state error covariance matrix */
|
||||
|
||||
// arma::mat kf_P_y; /* innovation covariance matrix */
|
||||
|
||||
// arma::mat kf_F; /* state transition matrix */
|
||||
// arma::mat kf_H; /* system matrix */
|
||||
|
||||
arma::mat ncov_process; /* model error covariance matrix */
|
||||
arma::mat ncov_measurement; /* measurement error covariance matrix */
|
||||
|
||||
// arma::colvec kf_z; /* measurement vector */
|
||||
// arma::colvec kf_y; /* innovation vector */
|
||||
// arma::mat kf_K; /* Kalman gain matrix */
|
||||
|
||||
};
|
||||
|
||||
template <class NonlinearFilter>
|
||||
class TrackingNonlinearFilter : public TrackingGaussianFilter
|
||||
{
|
||||
public:
|
||||
//carr_nco get_carrier_nco(float PLL_discriminator, float pll_bw_hz);
|
||||
std::pair<float, float> get_carrier_nco(const gr_complex Prompt);
|
||||
|
||||
void set_transition_model(ModelFunction* ft) { func_transition = ft; };
|
||||
void set_measurement_model(ModelFunction* fm) { func_measurement = fm; };
|
||||
void set_model(ModelFunction* ft, ModelFunction* fm) {
|
||||
set_transition_model(ft);
|
||||
set_measurement_model(fm);
|
||||
};
|
||||
|
||||
private:
|
||||
ModelFunction* func_transition;
|
||||
ModelFunction* func_measurement;
|
||||
|
||||
NonlinearFilter GaussFilt;
|
||||
// CubatureFilter GaussFilt;
|
||||
|
||||
};
|
||||
#include "tracking_Gaussian_filter.tcc"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
#ifndef GNSS_SDR_TRACKING_GAUSSIAN_FILTER_TCC_
|
||||
#define GNSS_SDR_TRACKING_GAUSSIAN_FILTER_TCC_
|
||||
|
||||
#include <armadillo>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include "MATH_CONSTANTS.h"
|
||||
|
||||
/*
|
||||
* Gaussian filter operating on correlator outputs
|
||||
* Req Input in [Hz/Ti]
|
||||
* The output is in [Hz/s].
|
||||
*/
|
||||
template <class NonlinearFilter>
|
||||
// carr_nco TrackingNonlinearFilter<NonlinearFilter>::get_carrier_nco(gr_complex Prompt)
|
||||
std::pair<float, float> TrackingNonlinearFilter<NonlinearFilter>::get_carrier_nco(const gr_complex Prompt)
|
||||
{
|
||||
arma::colvec state_pred;
|
||||
arma::mat state_cov_pred;
|
||||
|
||||
// State Update
|
||||
# if 0
|
||||
std::cout << "state:";
|
||||
state.print();
|
||||
std::cout << std::endl;
|
||||
std::cout << "state_cov:";
|
||||
state_cov.print();
|
||||
std::cout << std::endl;
|
||||
std::cout << "ncov_process:";
|
||||
ncov_process.print();
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "BEGIN PREDICT" << std::endl;
|
||||
#endif
|
||||
GaussFilt.predict_sequential(state, state_cov, func_transition, ncov_process);
|
||||
state_pred = GaussFilt.get_x_pred();
|
||||
state_cov_pred = GaussFilt.get_P_x_pred();
|
||||
|
||||
// Measurement Update
|
||||
arma::colvec measurement = arma::zeros(2, 1);
|
||||
measurement(0) = Prompt.real();
|
||||
measurement(1) = Prompt.imag();
|
||||
|
||||
/*
|
||||
arma::colvec innovation = arma::zeros(2, 1);
|
||||
innovation(0) = measurement(0) - std::sqrt(d_carrier_power_snv) * cos(state_pred(0));
|
||||
innovation(1) = measurement(1) - std::sqrt(d_carrier_power_snv) * sin(state_pred(0));
|
||||
*/
|
||||
|
||||
GaussFilt.update_sequential(measurement, state_pred, state_cov_pred, func_measurement, ncov_measurement);
|
||||
state = GaussFilt.get_x_pred();
|
||||
state_cov = GaussFilt.get_P_x_pred();
|
||||
|
||||
// Set a new carrier estimation to the NCO
|
||||
return std::make_pair(static_cast<float>(state(0)), static_cast<float>(state(1)));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
/*!
|
||||
* \file tracking_models.h
|
||||
* \brief Implementation of linear and nonlinear tracking models.
|
||||
* \author Gerald LaMountain, 2019. gerald(at)ece.neu.edu
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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_TRACKING_MODELS_H_
|
||||
#define GNSS_SDR_TRACKING_MODELS_H_
|
||||
|
||||
#include "cpu_multicorrelator_real_codes.h"
|
||||
#include "dll_pll_conf.h"
|
||||
#include "exponential_smoother.h"
|
||||
#include "tracking_FLL_PLL_filter.h" // for PLL/FLL filter
|
||||
#include "tracking_loop_filter.h" // for DLL filter
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/shared_ptr.hpp> // for boost::shared_ptr
|
||||
#include <gnuradio/block.h> // for block
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
#include <gnuradio/types.h> // for gr_vector_int, gr_vector...
|
||||
#include <pmt/pmt.h>
|
||||
#include <cstdint> // for int32_t
|
||||
#include <fstream> // for string, ofstream
|
||||
#include <utility> // for pair
|
||||
#include <vector>
|
||||
|
||||
// Abstract model function
|
||||
class ModelFunction
|
||||
{
|
||||
public:
|
||||
ModelFunction(){};
|
||||
virtual arma::vec operator()(const arma::vec& input) = 0;
|
||||
virtual ~ModelFunction() = default;
|
||||
};
|
||||
|
||||
class CarrierTransitionModel : public ModelFunction
|
||||
{
|
||||
public:
|
||||
explicit CarrierTransitionModel(const float carrier_pdi) { pdi = carrier_pdi; };
|
||||
arma::vec operator()(const arma::vec& input) override {
|
||||
arma::vec output = arma::zeros(3,1);
|
||||
output(0, 0) = input(0) + PI_2*pdi*input(1) + 0.5*PI_2*std::pow(pdi, 2)*input(2);
|
||||
output(0, 0) = input(1) + pdi*input(2);
|
||||
output(0, 0) = input(2);
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
private:
|
||||
arma::mat t_mat;
|
||||
float pdi;
|
||||
};
|
||||
|
||||
class CarrierMeasurementModel : public ModelFunction
|
||||
{
|
||||
public:
|
||||
explicit CarrierMeasurementModel(const float carrier_pow) { alpha = carrier_pow; };
|
||||
arma::vec operator()(const arma::vec& input) override {
|
||||
using namespace std::complex_literals;
|
||||
std::complex<double> output_iq = static_cast<double>(alpha) * std::exp( 1i * static_cast<double>(input(0)) );
|
||||
|
||||
arma::vec output = arma::zeros(2,1);
|
||||
output(0, 0) = static_cast<float>( std::real( output_iq ) );
|
||||
output(1, 0) = static_cast<float>( std::imag( output_iq ) );
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
private:
|
||||
float alpha;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "fir_filter.h"
|
||||
#include "freq_xlating_fir_filter.h"
|
||||
#include "galileo_e1_dll_pll_veml_tracking.h"
|
||||
#include "galileo_e1_mixed_veml_tracking.h"
|
||||
#include "galileo_e1_pcps_8ms_ambiguous_acquisition.h"
|
||||
#include "galileo_e1_pcps_ambiguous_acquisition.h"
|
||||
#include "galileo_e1_pcps_cccwsr_ambiguous_acquisition.h"
|
||||
@@ -1791,6 +1792,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "Galileo_E1_Mixed_VEML_Tracking")
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1MixedVemlTracking(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
#if ENABLE_FPGA
|
||||
else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")
|
||||
{
|
||||
@@ -2167,6 +2174,12 @@ std::unique_ptr<TrackingInterface> GNSSBlockFactory::GetTrkBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "Galileo_E1_Mixed_VEML_Tracking")
|
||||
{
|
||||
std::unique_ptr<TrackingInterface> block_(new GalileoE1MixedVemlTracking(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
#if ENABLE_FPGA
|
||||
else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")
|
||||
{
|
||||
|
||||
@@ -812,6 +812,7 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
|
||||
endif()
|
||||
add_executable(trk_test
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/galileo_e1_mixed_veml_tracking_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc
|
||||
|
||||
@@ -103,6 +103,7 @@ DECLARE_string(log_dir);
|
||||
#include "unit-tests/signal-processing-blocks/tracking/cubature_filter_test.cc"
|
||||
#include "unit-tests/signal-processing-blocks/tracking/unscented_filter_test.cc"
|
||||
#endif
|
||||
#include "unit-tests/signal-processing-blocks/tracking/galileo_e1_mixed_veml_tracking_test.cc"
|
||||
#include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc"
|
||||
#include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc"
|
||||
#include "unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc"
|
||||
@@ -138,7 +139,7 @@ DECLARE_string(log_dir);
|
||||
#include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc"
|
||||
#include "unit-tests/signal-processing-blocks/pvt/rtklib_solver_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_mixed_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/tracking_pull-in_test.cc"
|
||||
#if FPGA_BLOCKS_TEST
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// #include "tracking_models.h"
|
||||
#include "nonlinear_tracking.h"
|
||||
#include <armadillo>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
/*!
|
||||
* \file galileo_e1_mixed_veml_tracking_test.cc
|
||||
* \brief This class implements a tracking test for GalileoE1MixedVemlTracking
|
||||
* class based on some input parameters.
|
||||
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
* \author Gerald LaMountain, 2019. gerald(at)ece.neu.edu
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2012-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 "galileo_e1_mixed_veml_tracking.h"
|
||||
#include "gnss_block_factory.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "in_memory_configuration.h"
|
||||
#include <gnuradio/analog/sig_source_waveform.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
#include <gnuradio/blocks/skiphead.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#ifdef GR_GREATER_38
|
||||
#include <gnuradio/analog/sig_source.h>
|
||||
#else
|
||||
#include <gnuradio/analog/sig_source_c.h>
|
||||
#endif
|
||||
|
||||
class GalileoE1MixedVemlTrackingInternalTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
GalileoE1MixedVemlTrackingInternalTest()
|
||||
{
|
||||
factory = std::make_shared<GNSSBlockFactory>();
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
item_size = sizeof(gr_complex);
|
||||
stop = false;
|
||||
message = 0;
|
||||
gnss_synchro = Gnss_Synchro();
|
||||
}
|
||||
|
||||
~GalileoE1MixedVemlTrackingInternalTest() override = default;
|
||||
|
||||
void init();
|
||||
|
||||
gr::msg_queue::sptr queue;
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<GNSSBlockFactory> factory;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
Gnss_Synchro gnss_synchro{};
|
||||
size_t item_size;
|
||||
bool stop;
|
||||
int message;
|
||||
};
|
||||
|
||||
|
||||
void GalileoE1MixedVemlTrackingInternalTest::init()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'E';
|
||||
std::string signal = "1B";
|
||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||
gnss_synchro.PRN = 11;
|
||||
|
||||
config->set_property("GNSS-SDR.internal_fs_sps", "8000000");
|
||||
config->set_property("Tracking_1B.implementation", "Galileo_E1_Mixed_VEML_Tracking");
|
||||
config->set_property("Tracking_1B.item_type", "gr_complex");
|
||||
config->set_property("Tracking_1B.dump", "false");
|
||||
config->set_property("Tracking_1B.dump_filename", "../data/veml_tracking_ch_");
|
||||
config->set_property("Tracking_1B.early_late_space_chips", "0.15");
|
||||
config->set_property("Tracking_1B.very_early_late_space_chips", "0.6");
|
||||
config->set_property("Tracking_1B.pll_bw_hz", "30.0");
|
||||
config->set_property("Tracking_1B.dll_bw_hz", "2.0");
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GalileoE1MixedVemlTrackingInternalTest, Instantiate)
|
||||
{
|
||||
init();
|
||||
auto tracking = factory->GetBlock(config, "Tracking_1B", "Galileo_E1_Mixed_VEML_Tracking", 1, 1);
|
||||
EXPECT_STREQ("Galileo_E1_Mixed_VEML_Tracking", tracking->implementation().c_str());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GalileoE1MixedVemlTrackingInternalTest, ConnectAndRun)
|
||||
{
|
||||
int fs_in = 8000000;
|
||||
int nsamples = 40000000;
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> elapsed_seconds(0);
|
||||
init();
|
||||
queue = gr::msg_queue::make(0);
|
||||
top_block = gr::make_top_block("Tracking test");
|
||||
|
||||
// Example using smart pointers and the block factory
|
||||
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking_1B", "Galileo_E1_Mixed_VEML_Tracking", 1, 1);
|
||||
std::shared_ptr<GalileoE1MixedVemlTracking> tracking = std::dynamic_pointer_cast<GalileoE1MixedVemlTracking>(trk_);
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
tracking->set_channel(gnss_synchro.Channel_ID);
|
||||
}) << "Failure setting channel.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
tracking->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
tracking->connect(top_block);
|
||||
gr::analog::sig_source_c::sptr source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0));
|
||||
boost::shared_ptr<gr::block> valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue);
|
||||
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
||||
top_block->connect(source, 0, valve, 0);
|
||||
top_block->connect(valve, 0, tracking->get_left_block(), 0);
|
||||
top_block->connect(tracking->get_right_block(), 0, sink, 0);
|
||||
}) << "Failure connecting the blocks of tracking test.";
|
||||
|
||||
tracking->start_tracking();
|
||||
|
||||
EXPECT_NO_THROW({
|
||||
start = std::chrono::system_clock::now();
|
||||
top_block->run(); //Start threads and wait
|
||||
end = std::chrono::system_clock::now();
|
||||
elapsed_seconds = end - start;
|
||||
}) << "Failure running the top_block.";
|
||||
|
||||
std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GalileoE1MixedVemlTrackingInternalTest, ValidationOfResults)
|
||||
{
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> elapsed_seconds(0);
|
||||
// int num_samples = 40000000; // 4 Msps
|
||||
// unsigned int skiphead_sps = 24000000; // 4 Msps
|
||||
int num_samples = 80000000; // 8 Msps
|
||||
unsigned int skiphead_sps = 8000000; // 8 Msps
|
||||
init();
|
||||
queue = gr::msg_queue::make(0);
|
||||
top_block = gr::make_top_block("Tracking test");
|
||||
|
||||
// Example using smart pointers and the block factory
|
||||
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking_1B", "Galileo_E1_Mixed_VEML_Tracking", 1, 1);
|
||||
std::shared_ptr<TrackingInterface> tracking = std::dynamic_pointer_cast<TrackingInterface>(trk_);
|
||||
|
||||
// gnss_synchro.Acq_delay_samples = 1753; // 4 Msps
|
||||
// gnss_synchro.Acq_doppler_hz = -9500; // 4 Msps
|
||||
gnss_synchro.Acq_delay_samples = 17256; // 8 Msps
|
||||
gnss_synchro.Acq_doppler_hz = -8750; // 8 Msps
|
||||
gnss_synchro.Acq_samplestamp_samples = 0;
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
tracking->set_channel(gnss_synchro.Channel_ID);
|
||||
}) << "Failure setting channel.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
tracking->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
tracking->connect(top_block);
|
||||
}) << "Failure connecting tracking to the top_block.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
std::string path = std::string(TEST_PATH);
|
||||
std::string file = path + "signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat";
|
||||
const char* file_name = file.c_str();
|
||||
gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false);
|
||||
gr::blocks::skiphead::sptr skip_head = gr::blocks::skiphead::make(sizeof(gr_complex), skiphead_sps);
|
||||
boost::shared_ptr<gr::block> valve = gnss_sdr_make_valve(sizeof(gr_complex), num_samples, queue);
|
||||
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
||||
top_block->connect(file_source, 0, skip_head, 0);
|
||||
top_block->connect(skip_head, 0, valve, 0);
|
||||
top_block->connect(valve, 0, tracking->get_left_block(), 0);
|
||||
top_block->connect(tracking->get_right_block(), 0, sink, 0);
|
||||
}) << "Failure connecting the blocks of tracking test.";
|
||||
|
||||
tracking->start_tracking();
|
||||
|
||||
EXPECT_NO_THROW({
|
||||
start = std::chrono::system_clock::now();
|
||||
top_block->run(); // Start threads and wait
|
||||
end = std::chrono::system_clock::now();
|
||||
elapsed_seconds = end - start;
|
||||
}) << "Failure running the top_block.";
|
||||
|
||||
std::cout << "Tracked " << num_samples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
||||
}
|
||||
@@ -28,6 +28,7 @@
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// #include "tracking_models.h"
|
||||
#include "nonlinear_tracking.h"
|
||||
#include <armadillo>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
Reference in New Issue
Block a user