1
0
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:
Carles Fernandez 2019-03-26 22:34:08 +01:00
parent 1a2d90a8f1
commit 77851e5589
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
11 changed files with 482 additions and 79 deletions

View File

@ -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_

View File

@ -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,11 +907,12 @@ 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) {
i[0] = SPEED_OF_LIGHT / FREQ1_BDS; // B1I
i[1] = SPEED_OF_LIGHT / FREQ3_BDS; // B3I
i[2] = SPEED_OF_LIGHT / FREQ5; // L5/E5
}
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
}
}
result = rtkpos(&rtk_, obs_data, valid_obs + glo_valid_obs, &nav_data);

View File

@ -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_;

View File

@ -47,8 +47,8 @@
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;
// Get signal type info to adjust code type based on constellation
std::string sig_ = gnss_synchro.Signal;
rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz;
rtklib_obs.P[band] = gnss_synchro.Pseudorange_m;
@ -92,12 +92,14 @@ 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"){
rtklib_obs.code[band] = static_cast<unsigned char>(CODE_L2I);
}
else if (sig_ == "B3"){
rtklib_obs.code[band] = static_cast<unsigned char>(CODE_L6I);
}
if (sig_ == "B1")
{
rtklib_obs.code[band] = static_cast<unsigned char>(CODE_L2I);
}
else if (sig_ == "B3")
{
rtklib_obs.code[band] = static_cast<unsigned char>(CODE_L6I);
}
break;

View File

@ -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; }

View File

@ -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;

View File

@ -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
*/

View File

@ -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)";

View File

@ -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();
}
}

View File

@ -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

View File

@ -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'])