mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-06-25 22:52:52 +00:00
used clang-format
This commit is contained in:
parent
9bfe37877e
commit
1d5ff14619
@ -44,12 +44,12 @@
|
|||||||
#include "in_memory_configuration.h"
|
#include "in_memory_configuration.h"
|
||||||
#include "test_flags.h"
|
#include "test_flags.h"
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <cmath> // for abs, pow, floor
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <pmt/pmt.h>
|
#include <pmt/pmt.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cmath> // for abs, pow, floor
|
||||||
|
#include <pthread.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifdef GR_GREATER_38
|
#ifdef GR_GREATER_38
|
||||||
@ -81,24 +81,23 @@ struct DMA_handler_args_galileo_e1_pcps_ambiguous_acq_test
|
|||||||
|
|
||||||
struct acquisition_handler_args_galileo_e1_pcps_ambiguous_acq_test
|
struct acquisition_handler_args_galileo_e1_pcps_ambiguous_acq_test
|
||||||
{
|
{
|
||||||
std::shared_ptr<AcquisitionInterface> acquisition;
|
std::shared_ptr<AcquisitionInterface> acquisition;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GalileoE1PcpsAmbiguousAcquisitionTestFpga : public ::testing::Test
|
class GalileoE1PcpsAmbiguousAcquisitionTestFpga : public ::testing::Test
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool acquire_signal();
|
bool acquire_signal();
|
||||||
std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga";
|
std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga";
|
||||||
std::vector<Gnss_Synchro> gnss_synchro_vec;
|
std::vector<Gnss_Synchro> gnss_synchro_vec;
|
||||||
|
|
||||||
static const int32_t TEST_ACQ_SKIP_SAMPLES = 1024;
|
static const int32_t TEST_ACQ_SKIP_SAMPLES = 1024;
|
||||||
static const int BASEBAND_SAMPLING_FREQ = 4000000;
|
static const int BASEBAND_SAMPLING_FREQ = 4000000;
|
||||||
static constexpr float MAX_SAMPLE_VALUE = 0.096257761120796;
|
static constexpr float MAX_SAMPLE_VALUE = 0.096257761120796;
|
||||||
static const int DMA_BITS_PER_SAMPLE = 8;
|
static const int DMA_BITS_PER_SAMPLE = 8;
|
||||||
static constexpr float DMA_SIGNAL_SCALING_FACTOR = (pow(2, DMA_BITS_PER_SAMPLE - 1) - 1) / MAX_SAMPLE_VALUE;
|
static constexpr float DMA_SIGNAL_SCALING_FACTOR = (pow(2, DMA_BITS_PER_SAMPLE - 1) - 1) / MAX_SAMPLE_VALUE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
GalileoE1PcpsAmbiguousAcquisitionTestFpga();
|
GalileoE1PcpsAmbiguousAcquisitionTestFpga();
|
||||||
~GalileoE1PcpsAmbiguousAcquisitionTestFpga() = default;
|
~GalileoE1PcpsAmbiguousAcquisitionTestFpga() = default;
|
||||||
|
|
||||||
@ -109,14 +108,11 @@ protected:
|
|||||||
unsigned int doppler_max;
|
unsigned int doppler_max;
|
||||||
unsigned int doppler_step;
|
unsigned int doppler_step;
|
||||||
unsigned int nsamples_to_transfer;
|
unsigned int nsamples_to_transfer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GalileoE1PcpsAmbiguousAcquisitionTestFpga::GalileoE1PcpsAmbiguousAcquisitionTestFpga()
|
GalileoE1PcpsAmbiguousAcquisitionTestFpga::GalileoE1PcpsAmbiguousAcquisitionTestFpga()
|
||||||
{
|
{
|
||||||
|
|
||||||
config = std::make_shared<InMemoryConfiguration>();
|
config = std::make_shared<InMemoryConfiguration>();
|
||||||
|
|
||||||
doppler_max = 5000;
|
doppler_max = 5000;
|
||||||
@ -125,13 +121,13 @@ GalileoE1PcpsAmbiguousAcquisitionTestFpga::GalileoE1PcpsAmbiguousAcquisitionTest
|
|||||||
|
|
||||||
void* handler_DMA_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
void* handler_DMA_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
||||||
{
|
{
|
||||||
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
||||||
|
|
||||||
auto* args = (struct DMA_handler_args_galileo_e1_pcps_ambiguous_acq_test*)arguments;
|
auto* args = (struct DMA_handler_args_galileo_e1_pcps_ambiguous_acq_test*)arguments;
|
||||||
|
|
||||||
std::string Filename = args->file; // input filename
|
std::string Filename = args->file; // input filename
|
||||||
int32_t skip_used_samples = args->skip_used_samples;
|
int32_t skip_used_samples = args->skip_used_samples;
|
||||||
int32_t nsamples_tx = args->nsamples_tx;
|
int32_t nsamples_tx = args->nsamples_tx;
|
||||||
|
|
||||||
std::vector<float> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
std::vector<float> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
||||||
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
||||||
@ -149,7 +145,7 @@ void* handler_DMA_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
|||||||
{
|
{
|
||||||
infile.open(Filename, std::ios::binary);
|
infile.open(Filename, std::ios::binary);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception opening file " << Filename << std::endl;
|
std::cerr << "Exception opening file " << Filename << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -169,67 +165,65 @@ void* handler_DMA_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
|||||||
// Open input file
|
// Open input file
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
uint32_t skip_samples = 0; //static_cast<uint32_t>(FLAGS_skip_samples);
|
uint32_t skip_samples = 0; //static_cast<uint32_t>(FLAGS_skip_samples);
|
||||||
|
|
||||||
if (skip_samples + skip_used_samples > 0)
|
if (skip_samples + skip_used_samples > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.ignore((skip_samples + skip_used_samples) * 2);
|
infile.ignore((skip_samples + skip_used_samples) * 2);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsamples_remaining = nsamples_tx;
|
nsamples_remaining = nsamples_tx;
|
||||||
nsamples_block_size = 0;
|
nsamples_block_size = 0;
|
||||||
|
|
||||||
while (file_completed == false)
|
while (file_completed == false)
|
||||||
{
|
{
|
||||||
dma_index = 0;
|
dma_index = 0;
|
||||||
|
|
||||||
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
||||||
{
|
{
|
||||||
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nsamples_block_size = nsamples_remaining;
|
nsamples_block_size = nsamples_remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 2 bytes per complex sample
|
// 2 bytes per complex sample
|
||||||
infile.read(reinterpret_cast<char *>(input_samples.data()), nsamples_block_size * 2 * sizeof(float));
|
infile.read(reinterpret_cast<char*>(input_samples.data()), nsamples_block_size * 2 * sizeof(float));
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
||||||
{
|
{
|
||||||
|
// channel 1 (queue 1) -> E5/L5
|
||||||
|
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0] * args->scaling_factor);
|
||||||
|
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1] * args->scaling_factor);
|
||||||
|
// channel 0 (queue 0) -> E1/L1
|
||||||
|
input_samples_dma[dma_index + 2] = 0;
|
||||||
|
input_samples_dma[dma_index + 3] = 0;
|
||||||
|
|
||||||
// channel 1 (queue 1) -> E5/L5
|
dma_index += 4;
|
||||||
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0]*args->scaling_factor);
|
}
|
||||||
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1]*args->scaling_factor);
|
|
||||||
// channel 0 (queue 0) -> E1/L1
|
|
||||||
input_samples_dma[dma_index + 2] = 0;
|
|
||||||
input_samples_dma[dma_index + 3] = 0;
|
|
||||||
|
|
||||||
dma_index += 4;
|
if (write(tx_fd, input_samples_dma.data(), nsamples_block_size * 2 * 2) != nsamples_block_size * 2 * 2)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// Throttle the DMA
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
if (write(tx_fd, input_samples_dma.data(), nsamples_block_size * 2 * 2) != nsamples_block_size * 2 * 2)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throttle the DMA
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
|
|
||||||
|
|
||||||
nsamples_remaining -= nsamples_block_size;
|
nsamples_remaining -= nsamples_block_size;
|
||||||
@ -238,39 +232,37 @@ void* handler_DMA_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
|||||||
{
|
{
|
||||||
file_completed = true;
|
file_completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.close();
|
infile.close();
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing files " << Filename << std::endl;
|
std::cerr << "Exception closing files " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
close(tx_fd);
|
close(tx_fd);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing loop device " << std::endl;
|
std::cerr << "Exception closing loop device " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void* handler_acquisition_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
void* handler_acquisition_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
||||||
{
|
{
|
||||||
// the acquisition is a blocking function so we have to
|
// the acquisition is a blocking function so we have to
|
||||||
// create a thread
|
// create a thread
|
||||||
auto* args = (struct acquisition_handler_args_galileo_e1_pcps_ambiguous_acq_test*)arguments;
|
auto* args = (struct acquisition_handler_args_galileo_e1_pcps_ambiguous_acq_test*)arguments;
|
||||||
args->acquisition->reset();
|
args->acquisition->reset();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,51 +275,46 @@ void* handler_acquisition_galileo_e1_pcps_ambiguous_acq_test(void* arguments)
|
|||||||
// of the channel state machine are modified here, in order to
|
// of the channel state machine are modified here, in order to
|
||||||
// simplify the instantiation of the acquisition class in the
|
// simplify the instantiation of the acquisition class in the
|
||||||
// unit test.
|
// unit test.
|
||||||
class ChannelFsm_galileo_e1_pcps_ambiguous_acq_test: public ChannelFsm
|
class ChannelFsm_galileo_e1_pcps_ambiguous_acq_test : public ChannelFsm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool Event_valid_acquisition() override
|
||||||
bool Event_valid_acquisition() override
|
{
|
||||||
{
|
acquisition_successful = true;
|
||||||
acquisition_successful = true;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_repeat() override
|
bool Event_failed_acquisition_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_no_repeat() override
|
bool Event_failed_acquisition_no_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Event_check_test_result()
|
bool Event_check_test_result()
|
||||||
{
|
{
|
||||||
return acquisition_successful;
|
return acquisition_successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event_clear_test_result()
|
void Event_clear_test_result()
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool acquisition_successful;
|
||||||
bool acquisition_successful;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal()
|
bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal()
|
||||||
{
|
{
|
||||||
|
|
||||||
pthread_t thread_DMA, thread_acquisition;
|
pthread_t thread_DMA, thread_acquisition;
|
||||||
|
|
||||||
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
||||||
@ -352,22 +339,22 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal()
|
|||||||
args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR;
|
args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR;
|
||||||
|
|
||||||
std::string file = "data/Galileo_E1_ID_1_Fs_4Msps_8ms.dat";
|
std::string file = "data/Galileo_E1_ID_1_Fs_4Msps_8ms.dat";
|
||||||
args.file = file; // DMA file configuration
|
args.file = file; // DMA file configuration
|
||||||
|
|
||||||
// instantiate the FPGA switch and set the
|
// instantiate the FPGA switch and set the
|
||||||
// switch position to DMA.
|
// switch position to DMA.
|
||||||
std::shared_ptr<Fpga_Switch> switch_fpga;
|
std::shared_ptr<Fpga_Switch> switch_fpga;
|
||||||
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
||||||
switch_fpga->set_switch_position(0); // set switch position to DMA
|
switch_fpga->set_switch_position(0); // set switch position to DMA
|
||||||
|
|
||||||
// create the correspondign acquisition block according to the desired tracking signal
|
// create the correspondign acquisition block according to the desired tracking signal
|
||||||
tmp_gnss_synchro.System = 'E';
|
tmp_gnss_synchro.System = 'E';
|
||||||
signal = "1B";
|
signal = "1B";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 2); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 2); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
const std::string& role = "Acquisition";
|
const std::string& role = "Acquisition";
|
||||||
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
||||||
acquisition->set_channel_fsm(channel_fsm_);
|
acquisition->set_channel_fsm(channel_fsm_);
|
||||||
@ -379,46 +366,46 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal()
|
|||||||
|
|
||||||
nsamples_to_transfer = static_cast<unsigned int>(std::round(static_cast<double>(BASEBAND_SAMPLING_FREQ) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS)));
|
nsamples_to_transfer = static_cast<unsigned int>(std::round(static_cast<double>(BASEBAND_SAMPLING_FREQ) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS)));
|
||||||
|
|
||||||
channel_fsm_->Event_clear_test_result();
|
channel_fsm_->Event_clear_test_result();
|
||||||
|
|
||||||
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
||||||
acquisition->init();
|
acquisition->init();
|
||||||
acquisition->set_local_code();
|
acquisition->set_local_code();
|
||||||
|
|
||||||
args.skip_used_samples = 0;
|
args.skip_used_samples = 0;
|
||||||
|
|
||||||
// Configure the DMA to send the required samples to perform an acquisition
|
// Configure the DMA to send the required samples to perform an acquisition
|
||||||
args.nsamples_tx = nsamples_to_transfer;
|
args.nsamples_tx = nsamples_to_transfer;
|
||||||
|
|
||||||
// run the acquisition. The acquisition must run in a separate thread because it is a blocking function
|
// run the acquisition. The acquisition must run in a separate thread because it is a blocking function
|
||||||
args_acq.acquisition = acquisition;
|
args_acq.acquisition = acquisition;
|
||||||
|
|
||||||
if (pthread_create(&thread_acquisition, nullptr, handler_acquisition_galileo_e1_pcps_ambiguous_acq_test, reinterpret_cast<void*>(&args_acq)) < 0)
|
if (pthread_create(&thread_acquisition, nullptr, handler_acquisition_galileo_e1_pcps_ambiguous_acq_test, reinterpret_cast<void*>(&args_acq)) < 0)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR cannot create acquisition Process" << std::endl;
|
std::cout << "ERROR cannot create acquisition Process" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait to give time for the acquisition thread to set up the acquisition HW accelerator in the FPGA
|
// wait to give time for the acquisition thread to set up the acquisition HW accelerator in the FPGA
|
||||||
usleep(1000000);
|
usleep(1000000);
|
||||||
|
|
||||||
// create DMA child process
|
// create DMA child process
|
||||||
if (pthread_create(&thread_DMA, nullptr, handler_DMA_galileo_e1_pcps_ambiguous_acq_test, reinterpret_cast<void*>(&args)) < 0)
|
if (pthread_create(&thread_DMA, nullptr, handler_DMA_galileo_e1_pcps_ambiguous_acq_test, reinterpret_cast<void*>(&args)) < 0)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR cannot create DMA Process" << std::endl;
|
std::cout << "ERROR cannot create DMA Process" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait until the acquisition is finished
|
// wait until the acquisition is finished
|
||||||
pthread_join(thread_acquisition, nullptr);
|
pthread_join(thread_acquisition, nullptr);
|
||||||
|
|
||||||
// wait for the child DMA process to finish
|
// wait for the child DMA process to finish
|
||||||
pthread_join(thread_DMA, nullptr);
|
pthread_join(thread_DMA, nullptr);
|
||||||
|
|
||||||
acquisition_successful = channel_fsm_->Event_check_test_result();
|
acquisition_successful = channel_fsm_->Event_check_test_result();
|
||||||
|
|
||||||
if (acquisition_successful)
|
if (acquisition_successful)
|
||||||
{
|
{
|
||||||
gnss_synchro_vec.push_back(tmp_gnss_synchro);
|
gnss_synchro_vec.push_back(tmp_gnss_synchro);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gnss_synchro_vec.empty())
|
if (!gnss_synchro_vec.empty())
|
||||||
{
|
{
|
||||||
@ -466,10 +453,10 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTestFpga, ValidationOfResults)
|
|||||||
end = std::chrono::system_clock::now();
|
end = std::chrono::system_clock::now();
|
||||||
elapsed_seconds = end - start;
|
elapsed_seconds = end - start;
|
||||||
|
|
||||||
uint32_t n = 0; // there is only one channel
|
uint32_t n = 0; // there is only one channel
|
||||||
std::cout << "Acquired " << nsamples_to_transfer << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
std::cout << "Acquired " << nsamples_to_transfer << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
||||||
|
|
||||||
double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro_vec.at(n).Acq_delay_samples);
|
double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro_vec.at(n).Acq_delay_samples);
|
||||||
auto delay_error_chips = static_cast<float>(delay_error_samples * 1023 / 4000);
|
auto delay_error_chips = static_cast<float>(delay_error_samples * 1023 / 4000);
|
||||||
double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro_vec.at(n).Acq_doppler_hz);
|
double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro_vec.at(n).Acq_doppler_hz);
|
||||||
|
|
||||||
@ -477,6 +464,4 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTestFpga, ValidationOfResults)
|
|||||||
|
|
||||||
EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)";
|
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";
|
EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,10 +43,10 @@
|
|||||||
#include "in_memory_configuration.h"
|
#include "in_memory_configuration.h"
|
||||||
#include "test_flags.h"
|
#include "test_flags.h"
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <cmath> // for abs, pow, floor
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cmath> // for abs, pow, floor
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -79,24 +79,23 @@ struct DMA_handler_args_gps_l1_acq_test
|
|||||||
|
|
||||||
struct acquisition_handler_args_gps_l1_acq_test
|
struct acquisition_handler_args_gps_l1_acq_test
|
||||||
{
|
{
|
||||||
std::shared_ptr<AcquisitionInterface> acquisition;
|
std::shared_ptr<AcquisitionInterface> acquisition;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GpsL1CaPcpsAcquisitionTestFpga : public ::testing::Test
|
class GpsL1CaPcpsAcquisitionTestFpga : public ::testing::Test
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool acquire_signal();
|
bool acquire_signal();
|
||||||
std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga";
|
std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga";
|
||||||
std::vector<Gnss_Synchro> gnss_synchro_vec;
|
std::vector<Gnss_Synchro> gnss_synchro_vec;
|
||||||
|
|
||||||
static const int32_t TEST_ACQ_SKIP_SAMPLES = 1024;
|
static const int32_t TEST_ACQ_SKIP_SAMPLES = 1024;
|
||||||
static const int BASEBAND_SAMPLING_FREQ = 4000000;
|
static const int BASEBAND_SAMPLING_FREQ = 4000000;
|
||||||
static constexpr float MAX_SAMPLE_VALUE = 0.096257761120796;
|
static constexpr float MAX_SAMPLE_VALUE = 0.096257761120796;
|
||||||
static const int DMA_BITS_PER_SAMPLE = 8;
|
static const int DMA_BITS_PER_SAMPLE = 8;
|
||||||
static constexpr float DMA_SIGNAL_SCALING_FACTOR = (pow(2, DMA_BITS_PER_SAMPLE - 1) - 1) / MAX_SAMPLE_VALUE;
|
static constexpr float DMA_SIGNAL_SCALING_FACTOR = (pow(2, DMA_BITS_PER_SAMPLE - 1) - 1) / MAX_SAMPLE_VALUE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
GpsL1CaPcpsAcquisitionTestFpga();
|
GpsL1CaPcpsAcquisitionTestFpga();
|
||||||
~GpsL1CaPcpsAcquisitionTestFpga() = default;
|
~GpsL1CaPcpsAcquisitionTestFpga() = default;
|
||||||
|
|
||||||
@ -107,14 +106,11 @@ protected:
|
|||||||
unsigned int doppler_max;
|
unsigned int doppler_max;
|
||||||
unsigned int doppler_step;
|
unsigned int doppler_step;
|
||||||
unsigned int nsamples_to_transfer;
|
unsigned int nsamples_to_transfer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GpsL1CaPcpsAcquisitionTestFpga::GpsL1CaPcpsAcquisitionTestFpga()
|
GpsL1CaPcpsAcquisitionTestFpga::GpsL1CaPcpsAcquisitionTestFpga()
|
||||||
{
|
{
|
||||||
|
|
||||||
config = std::make_shared<InMemoryConfiguration>();
|
config = std::make_shared<InMemoryConfiguration>();
|
||||||
|
|
||||||
doppler_max = 5000;
|
doppler_max = 5000;
|
||||||
@ -123,13 +119,13 @@ GpsL1CaPcpsAcquisitionTestFpga::GpsL1CaPcpsAcquisitionTestFpga()
|
|||||||
|
|
||||||
void* handler_DMA_gps_l1_acq_test(void* arguments)
|
void* handler_DMA_gps_l1_acq_test(void* arguments)
|
||||||
{
|
{
|
||||||
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
||||||
|
|
||||||
auto* args = (struct DMA_handler_args_gps_l1_acq_test*)arguments;
|
auto* args = (struct DMA_handler_args_gps_l1_acq_test*)arguments;
|
||||||
|
|
||||||
std::string Filename = args->file; // input filename
|
std::string Filename = args->file; // input filename
|
||||||
int32_t skip_used_samples = args->skip_used_samples;
|
int32_t skip_used_samples = args->skip_used_samples;
|
||||||
int32_t nsamples_tx = args->nsamples_tx;
|
int32_t nsamples_tx = args->nsamples_tx;
|
||||||
|
|
||||||
std::vector<float> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
std::vector<float> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
||||||
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
||||||
@ -147,7 +143,7 @@ void* handler_DMA_gps_l1_acq_test(void* arguments)
|
|||||||
{
|
{
|
||||||
infile.open(Filename, std::ios::binary);
|
infile.open(Filename, std::ios::binary);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception opening file " << Filename << std::endl;
|
std::cerr << "Exception opening file " << Filename << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -167,67 +163,65 @@ void* handler_DMA_gps_l1_acq_test(void* arguments)
|
|||||||
// Open input file
|
// Open input file
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
uint32_t skip_samples = 0; //static_cast<uint32_t>(FLAGS_skip_samples);
|
uint32_t skip_samples = 0; //static_cast<uint32_t>(FLAGS_skip_samples);
|
||||||
|
|
||||||
if (skip_samples + skip_used_samples > 0)
|
if (skip_samples + skip_used_samples > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.ignore((skip_samples + skip_used_samples) * 2);
|
infile.ignore((skip_samples + skip_used_samples) * 2);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsamples_remaining = nsamples_tx;
|
nsamples_remaining = nsamples_tx;
|
||||||
nsamples_block_size = 0;
|
nsamples_block_size = 0;
|
||||||
|
|
||||||
while (file_completed == false)
|
while (file_completed == false)
|
||||||
{
|
{
|
||||||
dma_index = 0;
|
dma_index = 0;
|
||||||
|
|
||||||
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
||||||
{
|
{
|
||||||
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nsamples_block_size = nsamples_remaining;
|
nsamples_block_size = nsamples_remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 2 bytes per complex sample
|
// 2 bytes per complex sample
|
||||||
infile.read(reinterpret_cast<char *>(input_samples.data()), nsamples_block_size * 2 * sizeof(float));
|
infile.read(reinterpret_cast<char*>(input_samples.data()), nsamples_block_size * 2 * sizeof(float));
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
||||||
{
|
{
|
||||||
|
// channel 1 (queue 1) -> E5/L5
|
||||||
|
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0] * args->scaling_factor);
|
||||||
|
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1] * args->scaling_factor);
|
||||||
|
// channel 0 (queue 0) -> E1/L1
|
||||||
|
input_samples_dma[dma_index + 2] = 0;
|
||||||
|
input_samples_dma[dma_index + 3] = 0;
|
||||||
|
|
||||||
// channel 1 (queue 1) -> E5/L5
|
dma_index += 4;
|
||||||
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0]*args->scaling_factor);
|
}
|
||||||
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1]*args->scaling_factor);
|
|
||||||
// channel 0 (queue 0) -> E1/L1
|
|
||||||
input_samples_dma[dma_index + 2] = 0;
|
|
||||||
input_samples_dma[dma_index + 3] = 0;
|
|
||||||
|
|
||||||
dma_index += 4;
|
if (write(tx_fd, input_samples_dma.data(), nsamples_block_size * 2 * 2) != nsamples_block_size * 2 * 2)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// Throttle the DMA
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
if (write(tx_fd, input_samples_dma.data(), nsamples_block_size * 2 * 2) != nsamples_block_size * 2 * 2)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throttle the DMA
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
|
|
||||||
|
|
||||||
nsamples_remaining -= nsamples_block_size;
|
nsamples_remaining -= nsamples_block_size;
|
||||||
@ -236,39 +230,37 @@ void* handler_DMA_gps_l1_acq_test(void* arguments)
|
|||||||
{
|
{
|
||||||
file_completed = true;
|
file_completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.close();
|
infile.close();
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing files " << Filename << std::endl;
|
std::cerr << "Exception closing files " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
close(tx_fd);
|
close(tx_fd);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing loop device " << std::endl;
|
std::cerr << "Exception closing loop device " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void* handler_acquisition_gps_l1_acq_test(void* arguments)
|
void* handler_acquisition_gps_l1_acq_test(void* arguments)
|
||||||
{
|
{
|
||||||
// the acquisition is a blocking function so we have to
|
// the acquisition is a blocking function so we have to
|
||||||
// create a thread
|
// create a thread
|
||||||
auto* args = (struct acquisition_handler_args_gps_l1_acq_test*)arguments;
|
auto* args = (struct acquisition_handler_args_gps_l1_acq_test*)arguments;
|
||||||
args->acquisition->reset();
|
args->acquisition->reset();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -281,51 +273,46 @@ void* handler_acquisition_gps_l1_acq_test(void* arguments)
|
|||||||
// of the channel state machine are modified here, in order to
|
// of the channel state machine are modified here, in order to
|
||||||
// simplify the instantiation of the acquisition class in the
|
// simplify the instantiation of the acquisition class in the
|
||||||
// unit test.
|
// unit test.
|
||||||
class ChannelFsm_gps_l1_acq_test: public ChannelFsm
|
class ChannelFsm_gps_l1_acq_test : public ChannelFsm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool Event_valid_acquisition() override
|
||||||
bool Event_valid_acquisition() override
|
{
|
||||||
{
|
acquisition_successful = true;
|
||||||
acquisition_successful = true;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_repeat() override
|
bool Event_failed_acquisition_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_no_repeat() override
|
bool Event_failed_acquisition_no_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Event_check_test_result()
|
bool Event_check_test_result()
|
||||||
{
|
{
|
||||||
return acquisition_successful;
|
return acquisition_successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event_clear_test_result()
|
void Event_clear_test_result()
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool acquisition_successful;
|
||||||
bool acquisition_successful;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal()
|
bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal()
|
||||||
{
|
{
|
||||||
|
|
||||||
pthread_t thread_DMA, thread_acquisition;
|
pthread_t thread_DMA, thread_acquisition;
|
||||||
|
|
||||||
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
||||||
@ -350,22 +337,22 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal()
|
|||||||
args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR;
|
args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR;
|
||||||
|
|
||||||
std::string file = "data/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat";
|
std::string file = "data/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat";
|
||||||
args.file = file; // DMA file configuration
|
args.file = file; // DMA file configuration
|
||||||
|
|
||||||
// instantiate the FPGA switch and set the
|
// instantiate the FPGA switch and set the
|
||||||
// switch position to DMA.
|
// switch position to DMA.
|
||||||
std::shared_ptr<Fpga_Switch> switch_fpga;
|
std::shared_ptr<Fpga_Switch> switch_fpga;
|
||||||
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
||||||
switch_fpga->set_switch_position(0); // set switch position to DMA
|
switch_fpga->set_switch_position(0); // set switch position to DMA
|
||||||
|
|
||||||
// create the correspondign acquisition block according to the desired tracking signal
|
// create the correspondign acquisition block according to the desired tracking signal
|
||||||
tmp_gnss_synchro.System = 'G';
|
tmp_gnss_synchro.System = 'G';
|
||||||
signal = "1C";
|
signal = "1C";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
const std::string& role = "Acquisition";
|
const std::string& role = "Acquisition";
|
||||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
||||||
acquisition->set_channel_fsm(channel_fsm_);
|
acquisition->set_channel_fsm(channel_fsm_);
|
||||||
@ -377,46 +364,46 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal()
|
|||||||
|
|
||||||
nsamples_to_transfer = static_cast<unsigned int>(std::round(static_cast<double>(BASEBAND_SAMPLING_FREQ) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
nsamples_to_transfer = static_cast<unsigned int>(std::round(static_cast<double>(BASEBAND_SAMPLING_FREQ) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
||||||
|
|
||||||
channel_fsm_->Event_clear_test_result();
|
channel_fsm_->Event_clear_test_result();
|
||||||
|
|
||||||
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
||||||
acquisition->init();
|
acquisition->init();
|
||||||
acquisition->set_local_code();
|
acquisition->set_local_code();
|
||||||
|
|
||||||
args.skip_used_samples = 0;
|
args.skip_used_samples = 0;
|
||||||
|
|
||||||
// Configure the DMA to send the required samples to perform an acquisition
|
// Configure the DMA to send the required samples to perform an acquisition
|
||||||
args.nsamples_tx = nsamples_to_transfer;
|
args.nsamples_tx = nsamples_to_transfer;
|
||||||
|
|
||||||
// run the acquisition. The acquisition must run in a separate thread because it is a blocking function
|
// run the acquisition. The acquisition must run in a separate thread because it is a blocking function
|
||||||
args_acq.acquisition = acquisition;
|
args_acq.acquisition = acquisition;
|
||||||
|
|
||||||
if (pthread_create(&thread_acquisition, nullptr, handler_acquisition_gps_l1_acq_test, reinterpret_cast<void*>(&args_acq)) < 0)
|
if (pthread_create(&thread_acquisition, nullptr, handler_acquisition_gps_l1_acq_test, reinterpret_cast<void*>(&args_acq)) < 0)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR cannot create acquisition Process" << std::endl;
|
std::cout << "ERROR cannot create acquisition Process" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait to give time for the acquisition thread to set up the acquisition HW accelerator in the FPGA
|
// wait to give time for the acquisition thread to set up the acquisition HW accelerator in the FPGA
|
||||||
usleep(1000000);
|
usleep(1000000);
|
||||||
|
|
||||||
// create DMA child process
|
// create DMA child process
|
||||||
if (pthread_create(&thread_DMA, nullptr, handler_DMA_gps_l1_acq_test, reinterpret_cast<void*>(&args)) < 0)
|
if (pthread_create(&thread_DMA, nullptr, handler_DMA_gps_l1_acq_test, reinterpret_cast<void*>(&args)) < 0)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR cannot create DMA Process" << std::endl;
|
std::cout << "ERROR cannot create DMA Process" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait until the acquisition is finished
|
// wait until the acquisition is finished
|
||||||
pthread_join(thread_acquisition, nullptr);
|
pthread_join(thread_acquisition, nullptr);
|
||||||
|
|
||||||
// wait for the child DMA process to finish
|
// wait for the child DMA process to finish
|
||||||
pthread_join(thread_DMA, nullptr);
|
pthread_join(thread_DMA, nullptr);
|
||||||
|
|
||||||
acquisition_successful = channel_fsm_->Event_check_test_result();
|
acquisition_successful = channel_fsm_->Event_check_test_result();
|
||||||
|
|
||||||
if (acquisition_successful)
|
if (acquisition_successful)
|
||||||
{
|
{
|
||||||
gnss_synchro_vec.push_back(tmp_gnss_synchro);
|
gnss_synchro_vec.push_back(tmp_gnss_synchro);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gnss_synchro_vec.empty())
|
if (!gnss_synchro_vec.empty())
|
||||||
{
|
{
|
||||||
@ -464,10 +451,10 @@ TEST_F(GpsL1CaPcpsAcquisitionTestFpga, ValidationOfResults)
|
|||||||
end = std::chrono::system_clock::now();
|
end = std::chrono::system_clock::now();
|
||||||
elapsed_seconds = end - start;
|
elapsed_seconds = end - start;
|
||||||
|
|
||||||
uint32_t n = 0; // there is only one channel
|
uint32_t n = 0; // there is only one channel
|
||||||
std::cout << "Acquired " << nsamples_to_transfer << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
std::cout << "Acquired " << nsamples_to_transfer << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
||||||
|
|
||||||
double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro_vec.at(n).Acq_delay_samples);
|
double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro_vec.at(n).Acq_delay_samples);
|
||||||
auto delay_error_chips = static_cast<float>(delay_error_samples * 1023 / 4000);
|
auto delay_error_chips = static_cast<float>(delay_error_samples * 1023 / 4000);
|
||||||
double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro_vec.at(n).Acq_doppler_hz);
|
double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro_vec.at(n).Acq_doppler_hz);
|
||||||
|
|
||||||
@ -475,6 +462,4 @@ TEST_F(GpsL1CaPcpsAcquisitionTestFpga, ValidationOfResults)
|
|||||||
|
|
||||||
EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)";
|
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";
|
EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +272,6 @@ public:
|
|||||||
|
|
||||||
static const int32_t TEST_OBS_SKIP_SAMPLES = 1024;
|
static const int32_t TEST_OBS_SKIP_SAMPLES = 1024;
|
||||||
static constexpr float DMA_SIGNAL_SCALING_FACTOR = 8.0;
|
static constexpr float DMA_SIGNAL_SCALING_FACTOR = 8.0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int HybridObservablesTestFpga::configure_generator()
|
int HybridObservablesTestFpga::configure_generator()
|
||||||
@ -304,9 +303,9 @@ int HybridObservablesTestFpga::generate_signal()
|
|||||||
|
|
||||||
int pid;
|
int pid;
|
||||||
if ((pid = fork()) == -1)
|
if ((pid = fork()) == -1)
|
||||||
{
|
{
|
||||||
perror("fork err");
|
perror("fork err");
|
||||||
}
|
}
|
||||||
else if (pid == 0)
|
else if (pid == 0)
|
||||||
{
|
{
|
||||||
execv(&generator_binary[0], parmList);
|
execv(&generator_binary[0], parmList);
|
||||||
@ -331,27 +330,27 @@ struct DMA_handler_args_obs_test
|
|||||||
|
|
||||||
struct acquisition_handler_args_obs_test
|
struct acquisition_handler_args_obs_test
|
||||||
{
|
{
|
||||||
std::shared_ptr<AcquisitionInterface> acquisition;
|
std::shared_ptr<AcquisitionInterface> acquisition;
|
||||||
};
|
};
|
||||||
|
|
||||||
void* handler_acquisition_obs_test(void* arguments)
|
void* handler_acquisition_obs_test(void* arguments)
|
||||||
{
|
{
|
||||||
// the acquisition is a blocking function so we have to
|
// the acquisition is a blocking function so we have to
|
||||||
// create a thread
|
// create a thread
|
||||||
auto* args = (struct acquisition_handler_args_obs_test*)arguments;
|
auto* args = (struct acquisition_handler_args_obs_test*)arguments;
|
||||||
args->acquisition->reset();
|
args->acquisition->reset();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* handler_DMA_obs_test(void* arguments)
|
void* handler_DMA_obs_test(void* arguments)
|
||||||
{
|
{
|
||||||
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
||||||
|
|
||||||
auto* args = (struct DMA_handler_args_obs_test*)arguments;
|
auto* args = (struct DMA_handler_args_obs_test*)arguments;
|
||||||
|
|
||||||
std::string Filename = args->file; // input filename
|
std::string Filename = args->file; // input filename
|
||||||
int32_t skip_used_samples = args->skip_used_samples;
|
int32_t skip_used_samples = args->skip_used_samples;
|
||||||
int32_t nsamples_tx = args->nsamples_tx;
|
int32_t nsamples_tx = args->nsamples_tx;
|
||||||
|
|
||||||
std::vector<int8_t> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
std::vector<int8_t> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
||||||
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
||||||
@ -369,7 +368,7 @@ void* handler_DMA_obs_test(void* arguments)
|
|||||||
{
|
{
|
||||||
infile.open(Filename, std::ios::binary);
|
infile.open(Filename, std::ios::binary);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception opening file " << Filename << std::endl;
|
std::cerr << "Exception opening file " << Filename << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -391,79 +390,76 @@ void* handler_DMA_obs_test(void* arguments)
|
|||||||
|
|
||||||
uint32_t skip_samples = static_cast<uint32_t>(FLAGS_skip_samples);
|
uint32_t skip_samples = static_cast<uint32_t>(FLAGS_skip_samples);
|
||||||
|
|
||||||
if (skip_samples + skip_used_samples > 0)
|
if (skip_samples + skip_used_samples > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.ignore((skip_samples + skip_used_samples) * 2);
|
infile.ignore((skip_samples + skip_used_samples) * 2);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsamples_remaining = nsamples_tx;
|
nsamples_remaining = nsamples_tx;
|
||||||
nsamples_block_size = 0;
|
nsamples_block_size = 0;
|
||||||
|
|
||||||
while (file_completed == false)
|
while (file_completed == false)
|
||||||
{
|
{
|
||||||
dma_index = 0;
|
dma_index = 0;
|
||||||
|
|
||||||
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
||||||
{
|
{
|
||||||
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nsamples_block_size = nsamples_remaining;
|
nsamples_block_size = nsamples_remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
// 2 bytes per complex sample
|
||||||
|
infile.read(reinterpret_cast<char*>(input_samples.data()), nsamples_block_size * 2);
|
||||||
|
}
|
||||||
|
catch (const std::ifstream::failure& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
||||||
|
{
|
||||||
|
if (args->freq_band == 0)
|
||||||
{
|
{
|
||||||
// 2 bytes per complex sample
|
// channel 1 (queue 1) -> E5/L5
|
||||||
infile.read(reinterpret_cast<char *>(input_samples.data()), nsamples_block_size * 2);
|
input_samples_dma[dma_index] = 0;
|
||||||
|
input_samples_dma[dma_index + 1] = 0;
|
||||||
|
// channel 0 (queue 0) -> E1/L1
|
||||||
|
input_samples_dma[dma_index + 2] = static_cast<int8_t>(input_samples[index0] * args->scaling_factor);
|
||||||
|
input_samples_dma[dma_index + 3] = static_cast<int8_t>(input_samples[index0 + 1] * args->scaling_factor);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
// channel 1 (queue 1) -> E5/L5
|
||||||
|
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0] * args->scaling_factor);
|
||||||
|
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1] * args->scaling_factor);
|
||||||
|
// channel 0 (queue 0) -> E1/L1
|
||||||
|
input_samples_dma[dma_index + 2] = 0;
|
||||||
|
input_samples_dma[dma_index + 3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
dma_index += 4;
|
||||||
{
|
}
|
||||||
|
|
||||||
if (args->freq_band == 0)
|
|
||||||
{
|
|
||||||
// channel 1 (queue 1) -> E5/L5
|
|
||||||
input_samples_dma[dma_index] = 0;
|
|
||||||
input_samples_dma[dma_index + 1] = 0;
|
|
||||||
// channel 0 (queue 0) -> E1/L1
|
|
||||||
input_samples_dma[dma_index + 2] = static_cast<int8_t>(input_samples[index0]*args->scaling_factor);
|
|
||||||
input_samples_dma[dma_index + 3] = static_cast<int8_t>(input_samples[index0 + 1]*args->scaling_factor);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// channel 1 (queue 1) -> E5/L5
|
|
||||||
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0]*args->scaling_factor);
|
|
||||||
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1]*args->scaling_factor);
|
|
||||||
// channel 0 (queue 0) -> E1/L1
|
|
||||||
input_samples_dma[dma_index + 2] = 0;
|
|
||||||
input_samples_dma[dma_index + 3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dma_index += 4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//std::cout << "DMA: sending nsamples_block_size = " << nsamples_block_size << " samples" << std::endl;
|
//std::cout << "DMA: sending nsamples_block_size = " << nsamples_block_size << " samples" << std::endl;
|
||||||
if (write(tx_fd, input_samples_dma.data(), (int) (nsamples_block_size * 4)) != (int) (nsamples_block_size * 4))
|
if (write(tx_fd, input_samples_dma.data(), (int)(nsamples_block_size * 4)) != (int)(nsamples_block_size * 4))
|
||||||
{
|
{
|
||||||
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Throttle the DMA
|
// Throttle the DMA
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
|
||||||
|
|
||||||
nsamples_remaining -= nsamples_block_size;
|
nsamples_remaining -= nsamples_block_size;
|
||||||
@ -472,35 +468,30 @@ void* handler_DMA_obs_test(void* arguments)
|
|||||||
{
|
{
|
||||||
file_completed = true;
|
file_completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.close();
|
infile.close();
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing files " << Filename << std::endl;
|
std::cerr << "Exception closing files " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
close(tx_fd);
|
close(tx_fd);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing loop device " << std::endl;
|
std::cerr << "Exception closing loop device " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// When using the FPGA the acquisition class calls the states
|
// When using the FPGA the acquisition class calls the states
|
||||||
// of the channel finite state machine directly. This is done
|
// of the channel finite state machine directly. This is done
|
||||||
// in order to reduce the latency of the receiver when going
|
// in order to reduce the latency of the receiver when going
|
||||||
@ -510,49 +501,45 @@ void* handler_DMA_obs_test(void* arguments)
|
|||||||
// of the channel state machine are modified here, in order to
|
// of the channel state machine are modified here, in order to
|
||||||
// simplify the instantiation of the acquisition class in the
|
// simplify the instantiation of the acquisition class in the
|
||||||
// unit test.
|
// unit test.
|
||||||
class ChannelFsm_obs_test: public ChannelFsm
|
class ChannelFsm_obs_test : public ChannelFsm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool Event_valid_acquisition() override
|
||||||
bool Event_valid_acquisition() override
|
{
|
||||||
{
|
acquisition_successful = true;
|
||||||
acquisition_successful = true;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_repeat() override
|
bool Event_failed_acquisition_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_no_repeat() override
|
bool Event_failed_acquisition_no_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Event_check_test_result()
|
bool Event_check_test_result()
|
||||||
{
|
{
|
||||||
return acquisition_successful;
|
return acquisition_successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event_clear_test_result()
|
void Event_clear_test_result()
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool acquisition_successful;
|
||||||
bool acquisition_successful;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool HybridObservablesTestFpga::acquire_signal()
|
bool HybridObservablesTestFpga::acquire_signal()
|
||||||
{
|
{
|
||||||
|
|
||||||
pthread_t thread_DMA, thread_acquisition;
|
pthread_t thread_DMA, thread_acquisition;
|
||||||
|
|
||||||
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
||||||
@ -577,66 +564,62 @@ bool HybridObservablesTestFpga::acquire_signal()
|
|||||||
struct acquisition_handler_args_obs_test args_acq;
|
struct acquisition_handler_args_obs_test args_acq;
|
||||||
|
|
||||||
std::string file = FLAGS_signal_file;
|
std::string file = FLAGS_signal_file;
|
||||||
args.file = file; // DMA file configuration
|
args.file = file; // DMA file configuration
|
||||||
|
|
||||||
// instantiate the FPGA switch and set the
|
// instantiate the FPGA switch and set the
|
||||||
// switch position to DMA.
|
// switch position to DMA.
|
||||||
std::shared_ptr<Fpga_Switch> switch_fpga;
|
std::shared_ptr<Fpga_Switch> switch_fpga;
|
||||||
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
||||||
switch_fpga->set_switch_position(0); // set switch position to DMA
|
switch_fpga->set_switch_position(0); // set switch position to DMA
|
||||||
|
|
||||||
// create the correspondign acquisition block according to the desired tracking signal
|
// create the correspondign acquisition block according to the desired tracking signal
|
||||||
if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga")
|
if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'G';
|
tmp_gnss_synchro.System = 'G';
|
||||||
signal = "1C";
|
signal = "1C";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "GPS L1 CA";
|
System_and_Signal = "GPS L1 CA";
|
||||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")
|
else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'E';
|
tmp_gnss_synchro.System = 'E';
|
||||||
signal = "1B";
|
signal = "1B";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "Galileo E1B";
|
System_and_Signal = "Galileo E1B";
|
||||||
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga")
|
else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'E';
|
tmp_gnss_synchro.System = 'E';
|
||||||
signal = "5X";
|
signal = "5X";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "Galileo E5a";
|
System_and_Signal = "Galileo E5a";
|
||||||
acquisition = std::make_shared<GalileoE5aPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GalileoE5aPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")
|
else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'G';
|
tmp_gnss_synchro.System = 'G';
|
||||||
signal = "L5";
|
signal = "L5";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "GPS L5I";
|
System_and_Signal = "GPS L5I";
|
||||||
acquisition = std::make_shared<GpsL5iPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GpsL5iPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -696,10 +679,9 @@ bool HybridObservablesTestFpga::acquire_signal()
|
|||||||
|
|
||||||
for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++)
|
for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++)
|
||||||
{
|
{
|
||||||
|
|
||||||
tmp_gnss_synchro.PRN = PRN;
|
tmp_gnss_synchro.PRN = PRN;
|
||||||
|
|
||||||
channel_fsm_->Event_clear_test_result();
|
channel_fsm_->Event_clear_test_result();
|
||||||
|
|
||||||
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
||||||
acquisition->init();
|
acquisition->init();
|
||||||
@ -707,9 +689,9 @@ bool HybridObservablesTestFpga::acquire_signal()
|
|||||||
|
|
||||||
if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"))
|
if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"))
|
||||||
{
|
{
|
||||||
// Skip the first TEST_OBS_SKIP_SAMPLES samples
|
// Skip the first TEST_OBS_SKIP_SAMPLES samples
|
||||||
args.skip_used_samples = 0;
|
args.skip_used_samples = 0;
|
||||||
args.nsamples_tx = TEST_OBS_SKIP_SAMPLES; // limit is between 645 and 650 samples
|
args.nsamples_tx = TEST_OBS_SKIP_SAMPLES; // limit is between 645 and 650 samples
|
||||||
|
|
||||||
// create DMA child process
|
// create DMA child process
|
||||||
if (pthread_create(&thread_DMA, nullptr, handler_DMA_obs_test, reinterpret_cast<void*>(&args)) < 0)
|
if (pthread_create(&thread_DMA, nullptr, handler_DMA_obs_test, reinterpret_cast<void*>(&args)) < 0)
|
||||||
@ -774,7 +756,6 @@ bool HybridObservablesTestFpga::acquire_signal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "]" << std::endl;
|
std::cout << "]" << std::endl;
|
||||||
@ -1752,7 +1733,7 @@ bool HybridObservablesTestFpga::ReadRinexObs(std::vector<arma::mat>* obs_vec, Gn
|
|||||||
}
|
}
|
||||||
} // end while
|
} // end while
|
||||||
|
|
||||||
} // End of 'try' block
|
} // End of 'try' block
|
||||||
|
|
||||||
|
|
||||||
catch (const gpstk::FFStreamError& e)
|
catch (const gpstk::FFStreamError& e)
|
||||||
@ -1976,7 +1957,6 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults)
|
|||||||
std::string file;
|
std::string file;
|
||||||
|
|
||||||
ASSERT_NO_THROW({
|
ASSERT_NO_THROW({
|
||||||
|
|
||||||
if (!FLAGS_enable_external_signal_file)
|
if (!FLAGS_enable_external_signal_file)
|
||||||
{
|
{
|
||||||
file = "./" + filename_raw_data;
|
file = "./" + filename_raw_data;
|
||||||
@ -2007,7 +1987,7 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults)
|
|||||||
|
|
||||||
top_block->start();
|
top_block->start();
|
||||||
|
|
||||||
usleep(1000000); // give time for the system to start before receiving the start tracking command.
|
usleep(1000000); // give time for the system to start before receiving the start tracking command.
|
||||||
|
|
||||||
for (auto& n : tracking_ch_vec)
|
for (auto& n : tracking_ch_vec)
|
||||||
{
|
{
|
||||||
@ -2100,16 +2080,14 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!FLAGS_duplicated_satellites_test)
|
||||||
if (!FLAGS_duplicated_satellites_test)
|
{
|
||||||
{
|
ASSERT_EQ(ReadRinexObs(&true_obs_vec, gnss_synchro_master), true)
|
||||||
ASSERT_EQ(ReadRinexObs(&true_obs_vec, gnss_synchro_master), true)
|
<< "Failure reading RINEX file";
|
||||||
<< "Failure reading RINEX file";
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// read measured values
|
// read measured values
|
||||||
Observables_Dump_Reader estimated_observables(tracking_ch_vec.size());
|
Observables_Dump_Reader estimated_observables(tracking_ch_vec.size());
|
||||||
ASSERT_NO_THROW({
|
ASSERT_NO_THROW({
|
||||||
@ -2377,6 +2355,5 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::cout << "Test completed in " << elapsed_seconds.count() << " [s]" << std::endl;
|
std::cout << "Test completed in " << elapsed_seconds.count() << " [s]" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
* Copyright (C) 2012-2019 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2012-2019 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
@ -61,9 +62,9 @@
|
|||||||
#include <gnuradio/top_block.h>
|
#include <gnuradio/top_block.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <pmt/pmt.h>
|
#include <pmt/pmt.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <pthread.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -149,27 +150,27 @@ struct DMA_handler_args_trk_pull_in_test
|
|||||||
|
|
||||||
struct acquisition_handler_args_trk_pull_in_test
|
struct acquisition_handler_args_trk_pull_in_test
|
||||||
{
|
{
|
||||||
std::shared_ptr<AcquisitionInterface> acquisition;
|
std::shared_ptr<AcquisitionInterface> acquisition;
|
||||||
};
|
};
|
||||||
|
|
||||||
void* handler_acquisition_trk_pull_in_test(void* arguments)
|
void* handler_acquisition_trk_pull_in_test(void* arguments)
|
||||||
{
|
{
|
||||||
// the acquisition is a blocking function so we have to
|
// the acquisition is a blocking function so we have to
|
||||||
// create a thread
|
// create a thread
|
||||||
auto* args = (struct acquisition_handler_args_trk_pull_in_test*)arguments;
|
auto* args = (struct acquisition_handler_args_trk_pull_in_test*)arguments;
|
||||||
args->acquisition->reset();
|
args->acquisition->reset();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* handler_DMA_trk_pull_in_test(void* arguments)
|
void* handler_DMA_trk_pull_in_test(void* arguments)
|
||||||
{
|
{
|
||||||
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
|
||||||
|
|
||||||
auto* args = (struct DMA_handler_args_trk_pull_in_test*)arguments;
|
auto* args = (struct DMA_handler_args_trk_pull_in_test*)arguments;
|
||||||
|
|
||||||
std::string Filename = args->file; // input filename
|
std::string Filename = args->file; // input filename
|
||||||
int32_t skip_used_samples = args->skip_used_samples;
|
int32_t skip_used_samples = args->skip_used_samples;
|
||||||
int32_t nsamples_tx = args->nsamples_tx;
|
int32_t nsamples_tx = args->nsamples_tx;
|
||||||
|
|
||||||
std::vector<int8_t> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
std::vector<int8_t> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
|
||||||
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
|
||||||
@ -187,7 +188,7 @@ void* handler_DMA_trk_pull_in_test(void* arguments)
|
|||||||
{
|
{
|
||||||
infile.open(Filename, std::ios::binary);
|
infile.open(Filename, std::ios::binary);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception opening file " << Filename << std::endl;
|
std::cerr << "Exception opening file " << Filename << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -209,81 +210,75 @@ void* handler_DMA_trk_pull_in_test(void* arguments)
|
|||||||
|
|
||||||
uint32_t skip_samples = static_cast<uint32_t>(FLAGS_skip_samples);
|
uint32_t skip_samples = static_cast<uint32_t>(FLAGS_skip_samples);
|
||||||
|
|
||||||
if (skip_samples + skip_used_samples > 0)
|
if (skip_samples + skip_used_samples > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.ignore((skip_samples + skip_used_samples) * 2);
|
infile.ignore((skip_samples + skip_used_samples) * 2);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsamples_remaining = nsamples_tx;
|
nsamples_remaining = nsamples_tx;
|
||||||
nsamples_block_size = 0;
|
nsamples_block_size = 0;
|
||||||
|
|
||||||
while (file_completed == false)
|
while (file_completed == false)
|
||||||
{
|
{
|
||||||
dma_index = 0;
|
dma_index = 0;
|
||||||
|
|
||||||
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
if (nsamples_remaining > MAX_INPUT_SAMPLES_TOTAL)
|
||||||
{
|
{
|
||||||
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
nsamples_block_size = MAX_INPUT_SAMPLES_TOTAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nsamples_block_size = nsamples_remaining;
|
nsamples_block_size = nsamples_remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
// 2 bytes per complex sample
|
||||||
|
infile.read(reinterpret_cast<char*>(input_samples.data()), nsamples_block_size * 2);
|
||||||
|
}
|
||||||
|
catch (const std::ifstream::failure& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Exception reading file " << Filename << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
||||||
|
{
|
||||||
|
if (args->freq_band == 0)
|
||||||
{
|
{
|
||||||
// 2 bytes per complex sample
|
// channel 1 (queue 1) -> E5/L5
|
||||||
infile.read(reinterpret_cast<char *>(input_samples.data()), nsamples_block_size * 2);
|
input_samples_dma[dma_index] = 0;
|
||||||
|
input_samples_dma[dma_index + 1] = 0;
|
||||||
|
// channel 0 (queue 0) -> E1/L1
|
||||||
|
input_samples_dma[dma_index + 2] = static_cast<int8_t>(input_samples[index0] * args->scaling_factor);
|
||||||
|
input_samples_dma[dma_index + 3] = static_cast<int8_t>(input_samples[index0 + 1] * args->scaling_factor);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Exception reading file " << Filename << std::endl;
|
// channel 1 (queue 1) -> E5/L5
|
||||||
|
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0] * args->scaling_factor);
|
||||||
|
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1] * args->scaling_factor);
|
||||||
|
// channel 0 (queue 0) -> E1/L1
|
||||||
|
input_samples_dma[dma_index + 2] = 0;
|
||||||
|
input_samples_dma[dma_index + 3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index0 = 0; index0 < (nsamples_block_size * 2); index0 += 2)
|
dma_index += 4;
|
||||||
{
|
}
|
||||||
|
|
||||||
if (args->freq_band == 0)
|
if (write(tx_fd, input_samples_dma.data(), nsamples_block_size * 2 * 2) != nsamples_block_size * 2 * 2)
|
||||||
{
|
{
|
||||||
// channel 1 (queue 1) -> E5/L5
|
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
||||||
input_samples_dma[dma_index] = 0;
|
}
|
||||||
input_samples_dma[dma_index + 1] = 0;
|
|
||||||
// channel 0 (queue 0) -> E1/L1
|
|
||||||
// input_samples_dma[dma_index + 2] = input_samples[index0];
|
|
||||||
// input_samples_dma[dma_index + 3] = input_samples[index0 + 1];
|
|
||||||
input_samples_dma[dma_index + 2] = static_cast<int8_t>(input_samples[index0]*args->scaling_factor);
|
|
||||||
input_samples_dma[dma_index + 3] = static_cast<int8_t>(input_samples[index0 + 1]*args->scaling_factor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// channel 1 (queue 1) -> E5/L5
|
|
||||||
// input_samples_dma[dma_index] = input_samples[index0];
|
|
||||||
// input_samples_dma[dma_index + 1] = input_samples[index0 + 1];
|
|
||||||
input_samples_dma[dma_index] = static_cast<int8_t>(input_samples[index0]*args->scaling_factor);
|
|
||||||
input_samples_dma[dma_index + 1] = static_cast<int8_t>(input_samples[index0 + 1]*args->scaling_factor);
|
|
||||||
// channel 0 (queue 0) -> E1/L1
|
|
||||||
input_samples_dma[dma_index + 2] = 0;
|
|
||||||
input_samples_dma[dma_index + 3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dma_index += 4;
|
// Throttle the DMA
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
}
|
|
||||||
|
|
||||||
if (write(tx_fd, input_samples_dma.data(), nsamples_block_size * 2 * 2) != nsamples_block_size * 2 * 2)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: DMA could not send all the required samples " << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throttle the DMA
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
|
|
||||||
|
|
||||||
nsamples_remaining -= nsamples_block_size;
|
nsamples_remaining -= nsamples_block_size;
|
||||||
@ -292,28 +287,27 @@ void* handler_DMA_trk_pull_in_test(void* arguments)
|
|||||||
{
|
{
|
||||||
file_completed = true;
|
file_completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infile.close();
|
infile.close();
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing files " << Filename << std::endl;
|
std::cerr << "Exception closing files " << Filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
close(tx_fd);
|
close(tx_fd);
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure &e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Exception closing loop device " << std::endl;
|
std::cerr << "Exception closing loop device " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrackingPullInTestFpga : public ::testing::Test
|
class TrackingPullInTestFpga : public ::testing::Test
|
||||||
@ -394,9 +388,8 @@ public:
|
|||||||
|
|
||||||
std::shared_ptr<Concurrent_Queue<pmt::pmt_t>> queue;
|
std::shared_ptr<Concurrent_Queue<pmt::pmt_t>> queue;
|
||||||
|
|
||||||
static const int32_t TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES = 1024; //48
|
static const int32_t TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES = 1024; //48
|
||||||
static constexpr float DMA_SIGNAL_SCALING_FACTOR = 8.0;
|
static constexpr float DMA_SIGNAL_SCALING_FACTOR = 8.0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int TrackingPullInTestFpga::configure_generator(double CN0_dBHz, int file_idx)
|
int TrackingPullInTestFpga::configure_generator(double CN0_dBHz, int file_idx)
|
||||||
@ -454,44 +447,41 @@ int TrackingPullInTestFpga::generate_signal()
|
|||||||
// of the channel state machine are modified here, in order to
|
// of the channel state machine are modified here, in order to
|
||||||
// simplify the instantiation of the acquisition class in the
|
// simplify the instantiation of the acquisition class in the
|
||||||
// unit test.
|
// unit test.
|
||||||
class ChannelFsm_trk_pull_in_test: public ChannelFsm
|
class ChannelFsm_trk_pull_in_test : public ChannelFsm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool Event_valid_acquisition() override
|
||||||
bool Event_valid_acquisition() override
|
{
|
||||||
{
|
acquisition_successful = true;
|
||||||
acquisition_successful = true;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_repeat() override
|
bool Event_failed_acquisition_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Event_failed_acquisition_no_repeat() override
|
bool Event_failed_acquisition_no_repeat() override
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Event_check_test_result()
|
bool Event_check_test_result()
|
||||||
{
|
{
|
||||||
return acquisition_successful;
|
return acquisition_successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event_clear_test_result()
|
void Event_clear_test_result()
|
||||||
{
|
{
|
||||||
acquisition_successful = false;
|
acquisition_successful = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool acquisition_successful;
|
||||||
bool acquisition_successful;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TrackingPullInTestFpga::configure_receiver(
|
void TrackingPullInTestFpga::configure_receiver(
|
||||||
@ -583,7 +573,6 @@ void TrackingPullInTestFpga::configure_receiver(
|
|||||||
|
|
||||||
bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
||||||
{
|
{
|
||||||
|
|
||||||
pthread_t thread_DMA, thread_acquisition;
|
pthread_t thread_DMA, thread_acquisition;
|
||||||
|
|
||||||
// fsm
|
// fsm
|
||||||
@ -605,66 +594,62 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
|||||||
struct acquisition_handler_args_trk_pull_in_test args_acq;
|
struct acquisition_handler_args_trk_pull_in_test args_acq;
|
||||||
|
|
||||||
std::string file = FLAGS_signal_file;
|
std::string file = FLAGS_signal_file;
|
||||||
args.file = file; // DMA file configuration
|
args.file = file; // DMA file configuration
|
||||||
|
|
||||||
// instantiate the FPGA switch and set the
|
// instantiate the FPGA switch and set the
|
||||||
// switch position to DMA.
|
// switch position to DMA.
|
||||||
std::shared_ptr<Fpga_Switch> switch_fpga;
|
std::shared_ptr<Fpga_Switch> switch_fpga;
|
||||||
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
|
||||||
switch_fpga->set_switch_position(0); // set switch position to DMA
|
switch_fpga->set_switch_position(0); // set switch position to DMA
|
||||||
|
|
||||||
// create the correspondign acquisition block according to the desired tracking signal
|
// create the correspondign acquisition block according to the desired tracking signal
|
||||||
if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga")
|
if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'G';
|
tmp_gnss_synchro.System = 'G';
|
||||||
signal = "1C";
|
signal = "1C";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "GPS L1 CA";
|
System_and_Signal = "GPS L1 CA";
|
||||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")
|
else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'E';
|
tmp_gnss_synchro.System = 'E';
|
||||||
signal = "1B";
|
signal = "1B";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "Galileo E1B";
|
System_and_Signal = "Galileo E1B";
|
||||||
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 0; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga")
|
else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'E';
|
tmp_gnss_synchro.System = 'E';
|
||||||
signal = "5X";
|
signal = "5X";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "Galileo E5a";
|
System_and_Signal = "Galileo E5a";
|
||||||
acquisition = std::make_shared<GalileoE5aPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GalileoE5aPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")
|
else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")
|
||||||
{
|
{
|
||||||
tmp_gnss_synchro.System = 'G';
|
tmp_gnss_synchro.System = 'G';
|
||||||
signal = "L5";
|
signal = "L5";
|
||||||
const char* str = signal.c_str(); // get a C style null terminated string
|
const char* str = signal.c_str(); // get a C style null terminated string
|
||||||
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null
|
||||||
tmp_gnss_synchro.PRN = SV_ID;
|
tmp_gnss_synchro.PRN = SV_ID;
|
||||||
System_and_Signal = "GPS L5I";
|
System_and_Signal = "GPS L5I";
|
||||||
acquisition = std::make_shared<GpsL5iPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
acquisition = std::make_shared<GpsL5iPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
|
||||||
|
|
||||||
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
args.freq_band = 1; // frequency band on which the DMA has to transfer the samples
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -728,10 +713,9 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
|||||||
|
|
||||||
for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++)
|
for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++)
|
||||||
{
|
{
|
||||||
|
|
||||||
tmp_gnss_synchro.PRN = PRN;
|
tmp_gnss_synchro.PRN = PRN;
|
||||||
|
|
||||||
channel_fsm_->Event_clear_test_result();
|
channel_fsm_->Event_clear_test_result();
|
||||||
|
|
||||||
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
||||||
acquisition->init();
|
acquisition->init();
|
||||||
@ -739,8 +723,8 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
|||||||
|
|
||||||
if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"))
|
if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"))
|
||||||
{
|
{
|
||||||
// Configure the DMA to send TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES in order to initialize the internal
|
// Configure the DMA to send TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES in order to initialize the internal
|
||||||
// states of the downsampling filter in the FPGA
|
// states of the downsampling filter in the FPGA
|
||||||
args.skip_used_samples = 0;
|
args.skip_used_samples = 0;
|
||||||
args.nsamples_tx = TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES;
|
args.nsamples_tx = TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES;
|
||||||
|
|
||||||
@ -799,10 +783,10 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
|||||||
|
|
||||||
if (acquisition_successful)
|
if (acquisition_successful)
|
||||||
{
|
{
|
||||||
std::cout << " " << PRN << " ";
|
std::cout << " " << PRN << " ";
|
||||||
doppler_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_doppler_hz));
|
doppler_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_doppler_hz));
|
||||||
code_delay_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_delay_samples));
|
code_delay_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_delay_samples));
|
||||||
acq_samplestamp_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_samplestamp_samples));
|
acq_samplestamp_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_samplestamp_samples));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -810,7 +794,6 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "]" << std::endl;
|
std::cout << "]" << std::endl;
|
||||||
@ -827,7 +810,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID)
|
|||||||
std::cout << "Total signal acquisition run time "
|
std::cout << "Total signal acquisition run time "
|
||||||
<< elapsed_seconds.count()
|
<< elapsed_seconds.count()
|
||||||
<< " [seconds]" << std::endl;
|
<< " [seconds]" << std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -836,7 +819,7 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults)
|
|||||||
// pointer to the DMA thread that sends the samples to the acquisition engine
|
// pointer to the DMA thread that sends the samples to the acquisition engine
|
||||||
pthread_t thread_DMA;
|
pthread_t thread_DMA;
|
||||||
|
|
||||||
struct DMA_handler_args_trk_pull_in_test args;
|
struct DMA_handler_args_trk_pull_in_test args;
|
||||||
|
|
||||||
// *************************************************
|
// *************************************************
|
||||||
// ***** STEP 1: Prepare the parameters sweep ******
|
// ***** STEP 1: Prepare the parameters sweep ******
|
||||||
@ -1010,7 +993,6 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults)
|
|||||||
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
acquisition->stop_acquisition(); // reset the whole system including the sample counters
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// create flowgraph
|
// create flowgraph
|
||||||
top_block = gr::make_top_block("Tracking test");
|
top_block = gr::make_top_block("Tracking test");
|
||||||
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking", config->property("Tracking.implementation", std::string("undefined")), 1, 1);
|
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking", config->property("Tracking.implementation", std::string("undefined")), 1, 1);
|
||||||
@ -1043,8 +1025,6 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults)
|
|||||||
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
||||||
top_block->connect(tracking->get_right_block(), 0, sink, 0);
|
top_block->connect(tracking->get_right_block(), 0, sink, 0);
|
||||||
top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
||||||
|
|
||||||
|
|
||||||
}) << "Failure connecting the blocks of tracking test.";
|
}) << "Failure connecting the blocks of tracking test.";
|
||||||
|
|
||||||
|
|
||||||
@ -1057,26 +1037,25 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults)
|
|||||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||||
|
|
||||||
|
|
||||||
|
top_block->start();
|
||||||
top_block->start();
|
|
||||||
|
|
||||||
|
|
||||||
usleep(1000000); // give time for the system to start before receiving the start tracking command.
|
usleep(1000000); // give time for the system to start before receiving the start tracking command.
|
||||||
|
|
||||||
if (acq_to_trk_delay_samples > 0)
|
if (acq_to_trk_delay_samples > 0)
|
||||||
{
|
{
|
||||||
std::cout << "--- SIMULATING A PULL-IN DELAY OF " << FLAGS_acq_to_trk_delay_s << " SECONDS ---\n";
|
std::cout << "--- SIMULATING A PULL-IN DELAY OF " << FLAGS_acq_to_trk_delay_s << " SECONDS ---\n";
|
||||||
|
|
||||||
args.file = file;
|
args.file = file;
|
||||||
args.nsamples_tx = acq_to_trk_delay_samples; // 150 s for now but will be all file
|
args.nsamples_tx = acq_to_trk_delay_samples; // 150 s for now but will be all file
|
||||||
|
|
||||||
args.skip_used_samples = 0;
|
args.skip_used_samples = 0;
|
||||||
|
|
||||||
if (pthread_create(&thread_DMA, nullptr, handler_DMA_trk_pull_in_test, reinterpret_cast<void*>(&args)) < 0)
|
if (pthread_create(&thread_DMA, nullptr, handler_DMA_trk_pull_in_test, reinterpret_cast<void*>(&args)) < 0)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR cannot create DMA Process" << std::endl;
|
std::cout << "ERROR cannot create DMA Process" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::cout << " Starting tracking...\n";
|
std::cout << " Starting tracking...\n";
|
||||||
@ -1275,8 +1254,8 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults)
|
|||||||
}
|
}
|
||||||
} // end plot
|
} // end plot
|
||||||
|
|
||||||
} // end acquisition Delay errors loop
|
} // end acquisition Delay errors loop
|
||||||
} // end acquisition Doppler errors loop
|
} // end acquisition Doppler errors loop
|
||||||
pull_in_results_v_v.push_back(pull_in_results_v);
|
pull_in_results_v_v.push_back(pull_in_results_v);
|
||||||
} // end CN0 LOOP
|
} // end CN0 LOOP
|
||||||
|
|
||||||
@ -1338,8 +1317,5 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults)
|
|||||||
g4.savetops("trk_pull_in_grid_external_file");
|
g4.savetops("trk_pull_in_grid_external_file");
|
||||||
g4.savetopdf("trk_pull_in_grid_external_file", 12);
|
g4.savetopdf("trk_pull_in_grid_external_file", 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user