mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-13 11:40:33 +00:00
BeiDou B3I bug fixes (credits to dmiralles2019)
This commit is contained in:
parent
1a2d90a8f1
commit
77851e5589
@ -47,6 +47,8 @@ InputFilter.filter_type=bandpass
|
||||
InputFilter.grid_density=16
|
||||
InputFilter.sampling_frequency=25000000
|
||||
InputFilter.IF=6250000
|
||||
InputFilter.dump = false
|
||||
InputFilter.dump_filename=/home/dmiralles/Documents/gnss-sdr/src/tests/signal_samples/BdsB1IStr01_fs25e6_if0_4ms.dat
|
||||
Resampler.implementation=Pass_Through
|
||||
Resampler.sample_freq_in=25000000
|
||||
Resampler.sample_freq_out=25000000
|
||||
@ -77,7 +79,7 @@ Acquisition_B1.threshold=0.0038
|
||||
;Acquisition_B1.pfa=0.0000001;
|
||||
Acquisition_B1.doppler_max=10000
|
||||
Acquisition_B1.doppler_step=100
|
||||
Acquisition_B1.dump=false
|
||||
Acquisition_B1.dump=true
|
||||
Acquisition_B1.dump_filename=./bds_acq
|
||||
Acquisition_B1.blocking=false;
|
||||
Acquisition_B1.use_CFAR_algorithm=true;
|
||||
@ -89,7 +91,7 @@ Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
|
||||
Tracking_B1.item_type=gr_complex
|
||||
Tracking_B1.pll_bw_hz=25.0;
|
||||
Tracking_B1.dll_bw_hz=2.50;
|
||||
Tracking_B1.dump=false;
|
||||
Tracking_B1.dump=true;
|
||||
Tracking_B1.dump_filename=./epl_tracking_ch_
|
||||
|
||||
|
||||
|
@ -66,7 +66,6 @@
|
||||
#include <utility>
|
||||
|
||||
|
||||
|
||||
Rtklib_Solver::Rtklib_Solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, const rtk_t &rtk)
|
||||
{
|
||||
// init empty ephemeris for all the available GNSS channels
|
||||
@ -908,7 +907,8 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
|
||||
// Keep update on sat number
|
||||
sat++;
|
||||
if(sat > NSYSGPS + NSYSGLO + NSYSGAL + NSYSQZS and sat < NSYSGPS + NSYSGLO + NSYSGAL + NSYSQZS + NSYSBDS) {
|
||||
if (sat > NSYSGPS + NSYSGLO + NSYSGAL + NSYSQZS and sat < NSYSGPS + NSYSGLO + NSYSGAL + NSYSQZS + NSYSBDS)
|
||||
{
|
||||
i[0] = SPEED_OF_LIGHT / FREQ1_BDS; // B1I
|
||||
i[1] = SPEED_OF_LIGHT / FREQ3_BDS; // B3I
|
||||
i[2] = SPEED_OF_LIGHT / FREQ5; // L5/E5
|
||||
|
@ -26,7 +26,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
@ -57,7 +57,6 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
|
||||
DLOG(INFO) << "role " << role;
|
||||
|
||||
item_type_ = configuration_->property(role + ".item_type", default_item_type);
|
||||
|
||||
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||
acq_parameters.fs_in = fs_in_;
|
||||
|
@ -48,7 +48,7 @@
|
||||
obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro, int week, int band)
|
||||
{
|
||||
// Get signal type info to adjust code type based on constellation
|
||||
std::string sig_= gnss_synchro.Signal;
|
||||
std::string sig_ = gnss_synchro.Signal;
|
||||
|
||||
rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz;
|
||||
rtklib_obs.P[band] = gnss_synchro.Pseudorange_m;
|
||||
@ -92,10 +92,12 @@ obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro
|
||||
case 'C':
|
||||
rtklib_obs.sat = gnss_synchro.PRN + NSATGPS + NSATGLO + NSATGAL + NSATQZS;
|
||||
// Update signal code
|
||||
if (sig_ == "B1"){
|
||||
if (sig_ == "B1")
|
||||
{
|
||||
rtklib_obs.code[band] = static_cast<unsigned char>(CODE_L2I);
|
||||
}
|
||||
else if (sig_ == "B3"){
|
||||
else if (sig_ == "B3")
|
||||
{
|
||||
rtklib_obs.code[band] = static_cast<unsigned char>(CODE_L6I);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class BeidouB3iTelemetryDecoder : public TelemetryDecoderInterface
|
||||
{
|
||||
public:
|
||||
BeidouB3iTelemetryDecoder(ConfigurationInterface *configuration,
|
||||
const std::string& role, unsigned int in_streams,
|
||||
const std::string &role, unsigned int in_streams,
|
||||
unsigned int out_streams);
|
||||
|
||||
virtual ~BeidouB3iTelemetryDecoder();
|
||||
@ -72,7 +72,11 @@ public:
|
||||
telemetry_decoder_->set_channel(channel);
|
||||
}
|
||||
|
||||
inline void reset() override { return; }
|
||||
inline void reset() override
|
||||
{
|
||||
telemetry_decoder_->reset();
|
||||
return;
|
||||
}
|
||||
|
||||
inline size_t item_size() override { return 0; }
|
||||
|
||||
|
@ -56,6 +56,7 @@ beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite,
|
||||
new beidou_b3i_telemetry_decoder_gs(satellite, dump));
|
||||
}
|
||||
|
||||
|
||||
beidou_b3i_telemetry_decoder_gs::beidou_b3i_telemetry_decoder_gs(
|
||||
const Gnss_Satellite &satellite, bool dump)
|
||||
: gr::block("beidou_b3i_telemetry_decoder_gs",
|
||||
@ -64,6 +65,9 @@ beidou_b3i_telemetry_decoder_gs::beidou_b3i_telemetry_decoder_gs(
|
||||
{
|
||||
// Ephemeris data port out
|
||||
this->message_port_register_out(pmt::mp("telemetry"));
|
||||
// Control messages to tracking block
|
||||
this->message_port_register_out(pmt::mp("telemetry_to_trk"));
|
||||
|
||||
// initialize internal vars
|
||||
d_dump = dump;
|
||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
@ -396,6 +400,7 @@ void beidou_b3i_telemetry_decoder_gs::set_satellite(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void beidou_b3i_telemetry_decoder_gs::set_channel(int32_t channel)
|
||||
{
|
||||
d_channel = channel;
|
||||
|
@ -60,7 +60,10 @@ public:
|
||||
~beidou_b3i_telemetry_decoder_gs(); //!< Class destructor
|
||||
void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN
|
||||
void set_channel(int channel); //!< Set receiver's channel
|
||||
|
||||
inline void reset()
|
||||
{
|
||||
return;
|
||||
}
|
||||
/*!
|
||||
* \brief This is where all signal processing takes place
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@
|
||||
* \brief This class implements an acquisition test for
|
||||
* BeidouB1iPcpsAcquisition class based on some input parameters.
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* \author Damian Miralles, 2019. dmiralles2009(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
@ -44,7 +44,6 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/analog/sig_source_c.h>
|
||||
#include <gnuradio/analog/sig_source_waveform.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
@ -52,12 +51,18 @@
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#include <utility>
|
||||
#ifdef GR_GREATER_38
|
||||
#include <gnuradio/analog/sig_source.h>
|
||||
#else
|
||||
#include <gnuradio/analog/sig_source_c.h>
|
||||
#endif
|
||||
|
||||
|
||||
// ######## GNURADIO BLOCK MESSAGE RECEVER #########
|
||||
class BeidouB1iPcpsAcquisitionTest_msg_rx;
|
||||
|
||||
typedef boost::shared_ptr<BeidouB1iPcpsAcquisitionTest_msg_rx> BeidouB1iPcpsAcquisitionTest_msg_rx_sptr;
|
||||
using BeidouB1iPcpsAcquisitionTest_msg_rx_sptr = boost::shared_ptr<BeidouB1iPcpsAcquisitionTest_msg_rx>;
|
||||
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx_sptr BeidouB1iPcpsAcquisitionTest_msg_rx_make();
|
||||
|
||||
@ -84,7 +89,7 @@ void BeidouB1iPcpsAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
long int message = pmt::to_long(msg);
|
||||
int64_t message = pmt::to_long(std::move(msg));
|
||||
rx_message = message;
|
||||
}
|
||||
catch (boost::bad_any_cast &e)
|
||||
@ -103,9 +108,7 @@ BeidouB1iPcpsAcquisitionTest_msg_rx::BeidouB1iPcpsAcquisitionTest_msg_rx() : gr:
|
||||
}
|
||||
|
||||
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx::~BeidouB1iPcpsAcquisitionTest_msg_rx()
|
||||
{
|
||||
}
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx::~BeidouB1iPcpsAcquisitionTest_msg_rx() = default;
|
||||
|
||||
|
||||
// ###########################################################
|
||||
@ -123,9 +126,7 @@ protected:
|
||||
doppler_step = 100;
|
||||
}
|
||||
|
||||
~BeidouB1iPcpsAcquisitionTest()
|
||||
{
|
||||
}
|
||||
~BeidouB1iPcpsAcquisitionTest() = default;
|
||||
|
||||
void init();
|
||||
void plot_grid();
|
||||
@ -133,7 +134,7 @@ protected:
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<GNSSBlockFactory> factory;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
Gnss_Synchro gnss_synchro;
|
||||
Gnss_Synchro gnss_synchro{};
|
||||
size_t item_size;
|
||||
unsigned int doppler_max;
|
||||
unsigned int doppler_step;
|
||||
@ -159,8 +160,9 @@ void BeidouB1iPcpsAcquisitionTest::init()
|
||||
{
|
||||
config->set_property("Acquisition_B1.dump", "false");
|
||||
}
|
||||
config->set_property("Acquisition_B1.dump_filename", "./tmp-acq-beidou1/acquisition");
|
||||
config->set_property("Acquisition_B1.threshold", "0.00001");
|
||||
config->set_property("Acquisition_B1.dump_filename", "./tmp-acq-bds-b1i/acquisition");
|
||||
config->set_property("Acquisition_B1.dump_channel", "1");
|
||||
config->set_property("Acquisition_B1.threshold", "0.0038");
|
||||
config->set_property("Acquisition_B1.doppler_max", std::to_string(doppler_max));
|
||||
config->set_property("Acquisition_B1.doppler_step", std::to_string(doppler_step));
|
||||
config->set_property("Acquisition_B1.repeat_satellite", "false");
|
||||
@ -171,13 +173,16 @@ void BeidouB1iPcpsAcquisitionTest::init()
|
||||
void BeidouB1iPcpsAcquisitionTest::plot_grid()
|
||||
{
|
||||
//load the measured values
|
||||
std::string basename = "./tmp-acq-beidou1/acquisition_C_B1";
|
||||
unsigned int sat = static_cast<unsigned int>(gnss_synchro.PRN);
|
||||
std::string basename = "./tmp-acq-bds-b1i/acquisition_C_B1";
|
||||
auto sat = static_cast<unsigned int>(gnss_synchro.PRN);
|
||||
|
||||
unsigned int samples_per_code = static_cast<unsigned int>(round(4000000 / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS))); // !!
|
||||
acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code);
|
||||
auto samples_per_code = static_cast<unsigned int>(round(25000000 / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS))); // !!
|
||||
Acquisition_Dump_Reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code, 1);
|
||||
|
||||
if (!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl;
|
||||
if (!acq_dump.read_binary_acq())
|
||||
{
|
||||
std::cout << "Error reading files" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<int> *doppler = &acq_dump.doppler;
|
||||
std::vector<unsigned int> *samples = &acq_dump.samples;
|
||||
@ -197,26 +202,33 @@ void BeidouB1iPcpsAcquisitionTest::plot_grid()
|
||||
{
|
||||
boost::filesystem::path p(gnuplot_executable);
|
||||
boost::filesystem::path dir = p.parent_path();
|
||||
std::string gnuplot_path = dir.native();
|
||||
const std::string &gnuplot_path = dir.native();
|
||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||
|
||||
Gnuplot g1("lines");
|
||||
g1.set_title("BeiDou signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
||||
if (FLAGS_show_plots)
|
||||
{
|
||||
g1.showonscreen(); // window output
|
||||
}
|
||||
else
|
||||
{
|
||||
g1.disablescreen();
|
||||
}
|
||||
g1.set_title("BeiDou B1I signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
||||
g1.set_xlabel("Doppler [Hz]");
|
||||
g1.set_ylabel("Sample");
|
||||
//g1.cmd("set view 60, 105, 1, 1");
|
||||
g1.plot_grid3d(*doppler, *samples, *mag);
|
||||
|
||||
g1.savetops("BEIDOU_B1I_acq_grid");
|
||||
g1.savetopdf("BEIDOU_BI1_acq_grid");
|
||||
g1.showonscreen();
|
||||
g1.savetops("BeiDou_B1I_acq_grid");
|
||||
g1.savetopdf("BeiDou_B1I_acq_grid");
|
||||
}
|
||||
catch (const GnuplotException &ge)
|
||||
{
|
||||
std::cout << ge.what() << std::endl;
|
||||
}
|
||||
}
|
||||
std::string data_str = "./tmp-acq-beidou1";
|
||||
std::string data_str = "./tmp-acq-bds-b1i";
|
||||
if (boost::filesystem::exists(data_str))
|
||||
{
|
||||
boost::filesystem::remove_all(data_str);
|
||||
@ -234,7 +246,7 @@ TEST_F(BeidouB1iPcpsAcquisitionTest, Instantiate)
|
||||
TEST_F(BeidouB1iPcpsAcquisitionTest, ConnectAndRun)
|
||||
{
|
||||
int fs_in = 25000000;
|
||||
int nsamples = 4000;
|
||||
int nsamples = 25000;
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> elapsed_seconds(0);
|
||||
gr::msg_queue::sptr queue = gr::msg_queue::make(0);
|
||||
@ -270,14 +282,14 @@ TEST_F(BeidouB1iPcpsAcquisitionTest, ValidationOfResults)
|
||||
std::chrono::duration<double> elapsed_seconds(0.0);
|
||||
top_block = gr::make_top_block("Acquisition test");
|
||||
|
||||
double expected_delay_samples = 524;
|
||||
double expected_doppler_hz = 1680;
|
||||
double expected_delay_samples = 22216;
|
||||
double expected_doppler_hz = 125;
|
||||
|
||||
init();
|
||||
|
||||
if (FLAGS_plot_acq_grid == true)
|
||||
{
|
||||
std::string data_str = "./tmp-acq-beidou1";
|
||||
std::string data_str = "./tmp-acq-bds-b1i";
|
||||
if (boost::filesystem::exists(data_str))
|
||||
{
|
||||
boost::filesystem::remove_all(data_str);
|
||||
@ -297,7 +309,7 @@ TEST_F(BeidouB1iPcpsAcquisitionTest, ValidationOfResults)
|
||||
}) << "Failure setting gnss_synchro.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_threshold(0.001);
|
||||
acquisition->set_threshold(0.0038);
|
||||
}) << "Failure setting threshold.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
@ -314,7 +326,7 @@ TEST_F(BeidouB1iPcpsAcquisitionTest, ValidationOfResults)
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
std::string path = std::string(TEST_PATH);
|
||||
std::string file = path + "signal_samples/BEIDOU_B1I_ID_1_Fs_4Msps_2ms.dat";
|
||||
std::string file = path + "signal_samples/BdsB1IStr01_fs25e6_if0_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);
|
||||
top_block->connect(file_source, 0, acquisition->get_left_block(), 0);
|
||||
@ -332,12 +344,12 @@ TEST_F(BeidouB1iPcpsAcquisitionTest, ValidationOfResults)
|
||||
elapsed_seconds = end - start;
|
||||
}) << "Failure running the top_block.";
|
||||
|
||||
unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples;
|
||||
uint64_t nsamples = gnss_synchro.Acq_samplestamp_samples;
|
||||
std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
||||
ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS.";
|
||||
|
||||
double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro.Acq_delay_samples);
|
||||
float delay_error_chips = static_cast<float>(delay_error_samples * 1023 / 4000);
|
||||
auto delay_error_chips = static_cast<float>(delay_error_samples * BEIDOU_B1I_CODE_LENGTH_CHIPS / 25000);
|
||||
double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz);
|
||||
|
||||
EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)";
|
||||
|
@ -0,0 +1,361 @@
|
||||
/*!
|
||||
* \file beidou_b3i_pcps_acquisition_test.cc
|
||||
* \brief This class implements an acquisition test for
|
||||
* BeidouB3iPcpsAcquisition class based on some input parameters.
|
||||
* \author Damian Miralles, 2019. dmiralles2009(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/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "Beidou_B3I.h"
|
||||
#include "acquisition_dump_reader.h"
|
||||
#include "gnss_block_factory.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "gnuplot_i.h"
|
||||
#include "beidou_b3i_pcps_acquisition.h"
|
||||
#include "in_memory_configuration.h"
|
||||
#include "test_flags.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/analog/sig_source_waveform.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#include <utility>
|
||||
#ifdef GR_GREATER_38
|
||||
#include <gnuradio/analog/sig_source.h>
|
||||
#else
|
||||
#include <gnuradio/analog/sig_source_c.h>
|
||||
#endif
|
||||
|
||||
|
||||
// ######## GNURADIO BLOCK MESSAGE RECEVER #########
|
||||
class BeidouB3iPcpsAcquisitionTest_msg_rx;
|
||||
|
||||
using BeidouB3iPcpsAcquisitionTest_msg_rx_sptr = boost::shared_ptr<BeidouB3iPcpsAcquisitionTest_msg_rx>;
|
||||
|
||||
BeidouB3iPcpsAcquisitionTest_msg_rx_sptr BeidouB3iPcpsAcquisitionTest_msg_rx_make();
|
||||
|
||||
class BeidouB3iPcpsAcquisitionTest_msg_rx : public gr::block
|
||||
{
|
||||
private:
|
||||
friend BeidouB3iPcpsAcquisitionTest_msg_rx_sptr BeidouB3iPcpsAcquisitionTest_msg_rx_make();
|
||||
void msg_handler_events(pmt::pmt_t msg);
|
||||
BeidouB3iPcpsAcquisitionTest_msg_rx();
|
||||
|
||||
public:
|
||||
int rx_message;
|
||||
~BeidouB3iPcpsAcquisitionTest_msg_rx(); //!< Default destructor
|
||||
};
|
||||
|
||||
|
||||
BeidouB3iPcpsAcquisitionTest_msg_rx_sptr BeidouB3iPcpsAcquisitionTest_msg_rx_make()
|
||||
{
|
||||
return BeidouB3iPcpsAcquisitionTest_msg_rx_sptr(new BeidouB3iPcpsAcquisitionTest_msg_rx());
|
||||
}
|
||||
|
||||
|
||||
void BeidouB3iPcpsAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
int64_t message = pmt::to_long(std::move(msg));
|
||||
rx_message = message;
|
||||
}
|
||||
catch (boost::bad_any_cast &e)
|
||||
{
|
||||
LOG(WARNING) << "msg_handler_telemetry Bad any cast!";
|
||||
rx_message = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BeidouB3iPcpsAcquisitionTest_msg_rx::BeidouB3iPcpsAcquisitionTest_msg_rx() : gr::block("BeidouB3iPcpsAcquisitionTest_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->set_msg_handler(pmt::mp("events"), boost::bind(&BeidouB3iPcpsAcquisitionTest_msg_rx::msg_handler_events, this, _1));
|
||||
rx_message = 0;
|
||||
}
|
||||
|
||||
|
||||
BeidouB3iPcpsAcquisitionTest_msg_rx::~BeidouB3iPcpsAcquisitionTest_msg_rx() = default;
|
||||
|
||||
|
||||
// ###########################################################
|
||||
|
||||
class BeidouB3iPcpsAcquisitionTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
BeidouB3iPcpsAcquisitionTest()
|
||||
{
|
||||
factory = std::make_shared<GNSSBlockFactory>();
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
item_size = sizeof(gr_complex);
|
||||
gnss_synchro = Gnss_Synchro();
|
||||
doppler_max = 5000;
|
||||
doppler_step = 100;
|
||||
}
|
||||
|
||||
~BeidouB3iPcpsAcquisitionTest() = default;
|
||||
|
||||
void init();
|
||||
void plot_grid();
|
||||
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<GNSSBlockFactory> factory;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
Gnss_Synchro gnss_synchro{};
|
||||
size_t item_size;
|
||||
unsigned int doppler_max;
|
||||
unsigned int doppler_step;
|
||||
};
|
||||
|
||||
|
||||
void BeidouB3iPcpsAcquisitionTest::init()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'C';
|
||||
std::string signal = "B3";
|
||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||
gnss_synchro.PRN = 1;
|
||||
config->set_property("GNSS-SDR.internal_fs_sps", "50000000");
|
||||
config->set_property("Acquisition_B3.implementation", "BEIDOU_B3I_PCPS_Acquisition");
|
||||
config->set_property("Acquisition_B3.item_type", "gr_complex");
|
||||
config->set_property("Acquisition_B3.coherent_integration_time_ms", "1");
|
||||
if (FLAGS_plot_acq_grid == true)
|
||||
{
|
||||
config->set_property("Acquisition_B3.dump", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
config->set_property("Acquisition_B3.dump", "false");
|
||||
}
|
||||
config->set_property("Acquisition_B3.dump_filename", "./tmp-acq-bds-b3i/acquisition");
|
||||
config->set_property("Acquisition_B3.dump_channel", "1");
|
||||
config->set_property("Acquisition_B3.threshold", "0.00001");
|
||||
config->set_property("Acquisition_B3.doppler_max", std::to_string(doppler_max));
|
||||
config->set_property("Acquisition_B3.doppler_step", std::to_string(doppler_step));
|
||||
config->set_property("Acquisition_B3.repeat_satellite", "false");
|
||||
}
|
||||
|
||||
|
||||
void BeidouB3iPcpsAcquisitionTest::plot_grid()
|
||||
{
|
||||
//load the measured values
|
||||
std::string basename = "./tmp-acq-bds-b3i/acquisition_C_B3";
|
||||
auto sat = static_cast<unsigned int>(gnss_synchro.PRN);
|
||||
|
||||
auto samples_per_code = static_cast<unsigned int>(round(50000000 / (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS))); // !!
|
||||
Acquisition_Dump_Reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code, 1);
|
||||
|
||||
if (!acq_dump.read_binary_acq())
|
||||
{
|
||||
std::cout << "Error reading files" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<int> *doppler = &acq_dump.doppler;
|
||||
std::vector<unsigned int> *samples = &acq_dump.samples;
|
||||
std::vector<std::vector<float> > *mag = &acq_dump.mag;
|
||||
|
||||
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
|
||||
if (gnuplot_executable.empty())
|
||||
{
|
||||
std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE," << std::endl;
|
||||
std::cout << "gnuplot has not been found in your system." << std::endl;
|
||||
std::cout << "Test results will not be plotted." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Plotting the acquisition grid. This can take a while..." << std::endl;
|
||||
try
|
||||
{
|
||||
boost::filesystem::path p(gnuplot_executable);
|
||||
boost::filesystem::path dir = p.parent_path();
|
||||
const std::string &gnuplot_path = dir.native();
|
||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||
|
||||
Gnuplot g1("lines");
|
||||
if (FLAGS_show_plots)
|
||||
{
|
||||
g1.showonscreen(); // window output
|
||||
}
|
||||
else
|
||||
{
|
||||
g1.disablescreen();
|
||||
}
|
||||
g1.set_title("BeiDou B3I signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
||||
g1.set_xlabel("Doppler [Hz]");
|
||||
g1.set_ylabel("Sample");
|
||||
//g1.cmd("set view 60, 105, 1, 1");
|
||||
g1.plot_grid3d(*doppler, *samples, *mag);
|
||||
|
||||
g1.savetops("BDS_B3I_acq_grid");
|
||||
g1.savetopdf("BDS_B3I_acq_grid");
|
||||
}
|
||||
catch (const GnuplotException &ge)
|
||||
{
|
||||
std::cout << ge.what() << std::endl;
|
||||
}
|
||||
}
|
||||
std::string data_str = "./tmp-acq-bds-b3i";
|
||||
if (boost::filesystem::exists(data_str))
|
||||
{
|
||||
boost::filesystem::remove_all(data_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_F(BeidouB3iPcpsAcquisitionTest, Instantiate)
|
||||
{
|
||||
init();
|
||||
boost::shared_ptr<BeidouB3iPcpsAcquisition> acquisition = boost::make_shared<BeidouB3iPcpsAcquisition>(config.get(), "Acquisition_B3", 1, 0);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(BeidouB3iPcpsAcquisitionTest, ConnectAndRun)
|
||||
{
|
||||
int fs_in = 50000000;
|
||||
int nsamples = 50000;
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> elapsed_seconds(0);
|
||||
gr::msg_queue::sptr queue = gr::msg_queue::make(0);
|
||||
|
||||
top_block = gr::make_top_block("Acquisition test");
|
||||
init();
|
||||
boost::shared_ptr<BeidouB3iPcpsAcquisition> acquisition = boost::make_shared<BeidouB3iPcpsAcquisition>(config.get(), "Acquisition_B3", 1, 0);
|
||||
boost::shared_ptr<BeidouB3iPcpsAcquisitionTest_msg_rx> msg_rx = BeidouB3iPcpsAcquisitionTest_msg_rx_make();
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->connect(top_block);
|
||||
boost::shared_ptr<gr::analog::sig_source_c> 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);
|
||||
top_block->connect(source, 0, valve, 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"));
|
||||
}) << "Failure connecting the blocks of acquisition test.";
|
||||
|
||||
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(BeidouB3iPcpsAcquisitionTest, ValidationOfResults)
|
||||
{
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> elapsed_seconds(0.0);
|
||||
top_block = gr::make_top_block("Acquisition test");
|
||||
|
||||
double expected_delay_samples = 3380;
|
||||
double expected_doppler_hz = 700;
|
||||
|
||||
init();
|
||||
|
||||
if (FLAGS_plot_acq_grid == true)
|
||||
{
|
||||
std::string data_str = "./tmp-acq-bds-b3i";
|
||||
if (boost::filesystem::exists(data_str))
|
||||
{
|
||||
boost::filesystem::remove_all(data_str);
|
||||
}
|
||||
boost::filesystem::create_directory(data_str);
|
||||
}
|
||||
|
||||
std::shared_ptr<BeidouB3iPcpsAcquisition> acquisition = std::make_shared<BeidouB3iPcpsAcquisition>(config.get(), "Acquisition_B3", 1, 0);
|
||||
boost::shared_ptr<BeidouB3iPcpsAcquisitionTest_msg_rx> msg_rx = BeidouB3iPcpsAcquisitionTest_msg_rx_make();
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_channel(1);
|
||||
}) << "Failure setting channel.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_threshold(0.0002);
|
||||
}) << "Failure setting threshold.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_doppler_max(doppler_max);
|
||||
}) << "Failure setting doppler_max.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_doppler_step(doppler_step);
|
||||
}) << "Failure setting doppler_step.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
std::string path = std::string(TEST_PATH);
|
||||
std::string file = path + "signal_samples/BdsB3IStr01_fs50e6_if0_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);
|
||||
top_block->connect(file_source, 0, acquisition->get_left_block(), 0);
|
||||
top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
||||
}) << "Failure connecting the blocks of acquisition test.";
|
||||
|
||||
acquisition->set_local_code();
|
||||
acquisition->set_state(1); // Ensure that acquisition starts at the first sample
|
||||
acquisition->init();
|
||||
|
||||
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.";
|
||||
|
||||
uint64_t nsamples = gnss_synchro.Acq_samplestamp_samples;
|
||||
std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
||||
ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS.";
|
||||
|
||||
double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro.Acq_delay_samples);
|
||||
auto delay_error_chips = static_cast<float>(delay_error_samples * BEIDOU_B3I_CODE_LENGTH_CHIPS / 50000);
|
||||
double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz);
|
||||
|
||||
EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)";
|
||||
EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips";
|
||||
|
||||
if (FLAGS_plot_acq_grid == true)
|
||||
{
|
||||
plot_grid();
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ end
|
||||
|
||||
samplingFreq = 25000000; %[Hz]
|
||||
coherent_integration_time_ms = 1; %[ms]
|
||||
channels = 10; % Number of channels
|
||||
channels = 1; % Number of channels
|
||||
first_channel = 0; % Number of the first channel
|
||||
|
||||
path = '/home/dmiralles/Documents/gnss-sdr/'; %% CHANGE THIS PATH
|
||||
|
@ -26,15 +26,12 @@
|
||||
% -------------------------------------------------------------------------
|
||||
%
|
||||
|
||||
%%%%%%%%% ?????? CONFIGURE !!! %%%%%%%%%%%%%
|
||||
|
||||
path = '/home/dmiralles/Documents/Research/Publications/INSIDE_GNSS/bds_leg_pvt/Data/'; %% CHANGE THIS PATH
|
||||
file = 'bds_b3i_acq';
|
||||
|
||||
sat = 27;
|
||||
|
||||
%% Configuration
|
||||
path = '/home/dmiralles/Documents/gnss-sdr/';
|
||||
file = 'bds_acq';
|
||||
sat = 6;
|
||||
channel = 0;
|
||||
execution = 6;
|
||||
execution = 4;
|
||||
% Signal:
|
||||
% 1 GPS L1
|
||||
% 2 GPS L2M
|
||||
@ -42,17 +39,21 @@ execution = 6;
|
||||
% 4 Gal. E1B
|
||||
% 5 Gal. E5
|
||||
% 6 Glo. 1G
|
||||
% 7 BDS B1
|
||||
% 7 Glo. 2G
|
||||
% 8 BDS. B1
|
||||
% 9 BDS. B3
|
||||
% 10 BDS. B2a
|
||||
|
||||
signal_type = 8;
|
||||
|
||||
%%% True for light acq_grid representation
|
||||
%%% True for light grid representation
|
||||
lite_view = true;
|
||||
|
||||
%%% If lite_view, it sets the number of samples per chip in the graphical representation
|
||||
n_samples_per_chip = 3;
|
||||
d_samples_per_code = 25000;
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% Load data
|
||||
|
||||
switch(signal_type)
|
||||
case 1
|
||||
@ -80,45 +81,59 @@ switch(signal_type)
|
||||
system = 'R';
|
||||
signal = '1G';
|
||||
case 7
|
||||
n_chips = 2046;
|
||||
n_chips = 511;
|
||||
system = 'R';
|
||||
signal = '2G';
|
||||
case 8
|
||||
n_chips = 2048;
|
||||
system = 'C';
|
||||
signal = 'B1';
|
||||
case 8
|
||||
case 9
|
||||
n_chips = 10230;
|
||||
system = 'C';
|
||||
signal = 'B3';
|
||||
case 10
|
||||
n_chips = 10230;
|
||||
system = 'C';
|
||||
signal = '5C';
|
||||
end
|
||||
filename = [path file '_' system '_' signal '_ch_' num2str(channel) '_' num2str(execution) '_sat_' num2str(sat) '.mat'];
|
||||
load(filename);
|
||||
[n_fft n_dop_bins] = size(acq_grid);
|
||||
[d_max f_max] = find(acq_grid == max(max(acq_grid)));
|
||||
freq = (0 : n_dop_bins - 1) * doppler_step - doppler_max;
|
||||
[n_fft, n_dop_bins] = size(acq_grid);
|
||||
[d_max, f_max] = find(acq_grid == max(max(acq_grid)));
|
||||
freq = (0 : n_dop_bins - 1) * double(doppler_step) - double(doppler_max);
|
||||
delay = (0 : n_fft - 1) / n_fft * n_chips;
|
||||
|
||||
|
||||
%% Plot data
|
||||
%--- Acquisition grid (3D)
|
||||
figure(1)
|
||||
if(lite_view == false)
|
||||
surf(freq, delay, acq_grid, 'FaceColor', 'interp', 'LineStyle', 'none')
|
||||
ylim([min(delay) max(delay)])
|
||||
else
|
||||
delay_interp = (0 : n_samples_per_chip * n_chips - 1) / n_samples_per_chip;
|
||||
acq_grid_interp = spline(delay, acq_grid', delay_interp)';
|
||||
surf(freq, delay_interp, acq_grid_interp, 'FaceColor', 'interp', 'LineStyle', 'none')
|
||||
grid_interp = spline(delay, acq_grid', delay_interp)';
|
||||
surf(freq, delay_interp, grid_interp, 'FaceColor', 'interp', 'LineStyle', 'none')
|
||||
ylim([min(delay_interp) max(delay_interp)])
|
||||
end
|
||||
xlabel('Doppler shift / Hz')
|
||||
xlabel('Doppler shift (Hz)')
|
||||
xlim([min(freq) max(freq)])
|
||||
ylabel('Code delay / chips')
|
||||
zlabel('Test statistics')
|
||||
ylabel('Code delay (chips)')
|
||||
zlabel('Test Statistics')
|
||||
|
||||
%--- Acquisition grid (2D)
|
||||
figure(2)
|
||||
subplot(2,1,1)
|
||||
plot(freq, acq_grid(d_max, :))
|
||||
xlim([min(freq) max(freq)])
|
||||
xlabel('Doppler shift / Hz')
|
||||
xlabel('Doppler shift (Hz)')
|
||||
ylabel('Test statistics')
|
||||
title(['Fixed code delay to ' num2str((d_max - 1) / n_fft * n_chips) ' chips'])
|
||||
subplot(2,1,2)
|
||||
normalization = (d_samples_per_code^4) * input_power;
|
||||
plot(delay, acq_acq_grid(:, f_max)./normalization)
|
||||
plot(delay, acq_grid(:, f_max)./normalization)
|
||||
xlim([min(delay) max(delay)])
|
||||
xlabel('Code delay / chips')
|
||||
xlabel('Code delay (chips)')
|
||||
ylabel('Test statistics')
|
||||
title(['Doppler wipe-off = ' num2str((f_max - 1) * doppler_step - doppler_max) ' Hz'])
|
||||
|
Loading…
Reference in New Issue
Block a user