mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-15 04:30:33 +00:00
Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next
This commit is contained in:
commit
cb8221ff63
@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* \file gpx_printer.cc
|
||||
* \brief Interface of a class that prints PVT information to a gpx file
|
||||
* \brief Implementation of a class that prints PVT information to a gpx file
|
||||
* \author Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com
|
||||
*
|
||||
*
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "acq_conf.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
@ -49,29 +50,35 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler(
|
||||
std::string default_dump_filename = "./data/acquisition.dat";
|
||||
|
||||
DLOG(INFO) << "role " << role;
|
||||
Acq_Conf acq_parameters = Acq_Conf();
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
long 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_;
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
acq_parameters.dump_filename = dump_filename_;
|
||||
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
|
||||
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||
doppler_min_ = configuration->property(role + ".doppler_min", -doppler_max_);
|
||||
acq_parameters.doppler_max = doppler_max_;
|
||||
sampled_ms_ = configuration->property(role + ".coherent_integration_time_ms", 1);
|
||||
acq_parameters.sampled_ms = sampled_ms_;
|
||||
max_dwells_ = configuration->property(role + ".max_dwells", 1);
|
||||
acq_parameters.max_dwells = max_dwells_;
|
||||
|
||||
acq_parameters.blocking_on_standby = configuration->property(role + ".blocking_on_standby", false);
|
||||
|
||||
//--- Find number of samples per spreading code -------------------------
|
||||
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
|
||||
|
||||
acq_parameters.samples_per_ms = vector_length_;
|
||||
code_ = new gr_complex[vector_length_];
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_make_acquisition_fine_doppler_cc(max_dwells_, sampled_ms_,
|
||||
doppler_max_, doppler_min_, fs_in_, vector_length_,
|
||||
dump_, dump_filename_);
|
||||
acquisition_cc_ = pcps_make_acquisition_fine_doppler_cc(acq_parameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -131,7 +131,6 @@ private:
|
||||
float threshold_;
|
||||
int doppler_max_;
|
||||
unsigned int doppler_step_;
|
||||
int doppler_min_;
|
||||
unsigned int sampled_ms_;
|
||||
int max_dwells_;
|
||||
long fs_in_;
|
||||
|
@ -40,46 +40,43 @@
|
||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||
#include <algorithm> // std::rotate, std::fill_n
|
||||
#include <sstream>
|
||||
#include <matio.h>
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
pcps_acquisition_fine_doppler_cc_sptr pcps_make_acquisition_fine_doppler_cc(
|
||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min,
|
||||
long fs_in, int samples_per_ms, bool dump,
|
||||
std::string dump_filename)
|
||||
pcps_acquisition_fine_doppler_cc_sptr pcps_make_acquisition_fine_doppler_cc(const Acq_Conf &conf_)
|
||||
{
|
||||
return pcps_acquisition_fine_doppler_cc_sptr(
|
||||
new pcps_acquisition_fine_doppler_cc(max_dwells, sampled_ms, doppler_max, doppler_min,
|
||||
fs_in, samples_per_ms, dump, dump_filename));
|
||||
new pcps_acquisition_fine_doppler_cc(conf_));
|
||||
}
|
||||
|
||||
|
||||
pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(
|
||||
int max_dwells, unsigned int sampled_ms, int doppler_max, int doppler_min,
|
||||
long fs_in, int samples_per_ms, bool dump,
|
||||
std::string dump_filename) : gr::block("pcps_acquisition_fine_doppler_cc",
|
||||
pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Conf &conf_)
|
||||
: gr::block("pcps_acquisition_fine_doppler_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
||||
{
|
||||
this->message_port_register_out(pmt::mp("events"));
|
||||
acq_parameters = conf_;
|
||||
d_sample_counter = 0; // SAMPLE COUNTER
|
||||
d_active = false;
|
||||
d_fs_in = fs_in;
|
||||
d_samples_per_ms = samples_per_ms;
|
||||
d_sampled_ms = sampled_ms;
|
||||
d_config_doppler_max = doppler_max;
|
||||
d_config_doppler_min = doppler_min;
|
||||
d_fs_in = conf_.fs_in;
|
||||
d_samples_per_ms = conf_.samples_per_ms;
|
||||
d_sampled_ms = conf_.sampled_ms;
|
||||
d_config_doppler_max = conf_.doppler_max;
|
||||
d_config_doppler_min = -conf_.doppler_max;
|
||||
d_fft_size = d_sampled_ms * d_samples_per_ms;
|
||||
// HS Acquisition
|
||||
d_max_dwells = max_dwells;
|
||||
d_max_dwells = conf_.max_dwells;
|
||||
d_gnuradio_forecast_samples = d_fft_size;
|
||||
d_input_power = 0.0;
|
||||
d_state = 0;
|
||||
d_carrier = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
d_fft_codes = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||
|
||||
d_10_ms_buffer = static_cast<gr_complex *>(volk_gnsssdr_malloc(10 * d_samples_per_ms * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
|
||||
@ -87,10 +84,10 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(
|
||||
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
||||
|
||||
// For dumping samples into a file
|
||||
d_dump = dump;
|
||||
d_dump_filename = dump_filename;
|
||||
d_dump = conf_.dump;
|
||||
d_dump_filename = conf_.dump_filename;
|
||||
|
||||
d_doppler_resolution = 0;
|
||||
d_n_samples_in_buffer = 0;
|
||||
d_threshold = 0;
|
||||
d_num_doppler_points = 0;
|
||||
d_doppler_step = 0;
|
||||
@ -102,9 +99,28 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(
|
||||
d_test_statistics = 0;
|
||||
d_well_count = 0;
|
||||
d_channel = 0;
|
||||
d_positive_acq = 0;
|
||||
d_dump_number = 0;
|
||||
d_dump_channel = 0; // this implementation can only produce dumps in channel 0
|
||||
//todo: migrate config parameters to the unified acquisition config class
|
||||
}
|
||||
|
||||
|
||||
// Finds next power of two
|
||||
// for n. If n itself is a
|
||||
// power of two then returns n
|
||||
unsigned int pcps_acquisition_fine_doppler_cc::nextPowerOf2(unsigned int n)
|
||||
{
|
||||
n--;
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
d_doppler_step = doppler_step;
|
||||
@ -138,12 +154,9 @@ pcps_acquisition_fine_doppler_cc::~pcps_acquisition_fine_doppler_cc()
|
||||
volk_gnsssdr_free(d_carrier);
|
||||
volk_gnsssdr_free(d_fft_codes);
|
||||
volk_gnsssdr_free(d_magnitude);
|
||||
volk_gnsssdr_free(d_10_ms_buffer);
|
||||
delete d_ifft;
|
||||
delete d_fft_if;
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
free_grid_memory();
|
||||
}
|
||||
|
||||
@ -167,8 +180,12 @@ void pcps_acquisition_fine_doppler_cc::init()
|
||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||
d_input_power = 0.0;
|
||||
d_state = 0;
|
||||
|
||||
if (d_dump)
|
||||
{
|
||||
grid_ = arma::fmat(d_fft_size, d_num_doppler_points, arma::fill::zeros);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +204,7 @@ void pcps_acquisition_fine_doppler_cc::reset_grid()
|
||||
d_well_count = 0;
|
||||
for (int i = 0; i < d_num_doppler_points; i++)
|
||||
{
|
||||
//todo: use memset here
|
||||
for (unsigned int j = 0; j < d_fft_size; j++)
|
||||
{
|
||||
d_grid_data[i][j] = 0.0;
|
||||
@ -215,52 +233,71 @@ void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff()
|
||||
}
|
||||
|
||||
|
||||
double pcps_acquisition_fine_doppler_cc::search_maximum()
|
||||
double pcps_acquisition_fine_doppler_cc::compute_CAF()
|
||||
{
|
||||
float magt = 0.0;
|
||||
float fft_normalization_factor;
|
||||
float firstPeak = 0.0;
|
||||
int index_doppler = 0;
|
||||
uint32_t tmp_intex_t = 0;
|
||||
uint32_t index_time = 0;
|
||||
|
||||
// Look for correlation peaks in the results ==============================
|
||||
// Find the highest peak and compare it to the second highest peak
|
||||
// The second peak is chosen not closer than 1 chip to the highest peak
|
||||
//--- Find the correlation peak and the carrier frequency --------------
|
||||
for (int i = 0; i < d_num_doppler_points; i++)
|
||||
{
|
||||
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[i], d_fft_size);
|
||||
if (d_grid_data[i][tmp_intex_t] > magt)
|
||||
if (d_grid_data[i][tmp_intex_t] > firstPeak)
|
||||
{
|
||||
magt = d_grid_data[i][tmp_intex_t];
|
||||
//std::cout<<magt<<std::endl;
|
||||
firstPeak = d_grid_data[i][tmp_intex_t];
|
||||
index_doppler = i;
|
||||
index_time = tmp_intex_t;
|
||||
}
|
||||
|
||||
// Record results to file if required
|
||||
if (d_dump and d_channel == d_dump_channel)
|
||||
{
|
||||
memcpy(grid_.colptr(i), d_grid_data[i], sizeof(float) * d_fft_size);
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||
magt = magt / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
// -- - Find 1 chip wide code phase exclude range around the peak
|
||||
uint32_t samplesPerChip = ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(this->d_fs_in));
|
||||
int32_t excludeRangeIndex1 = index_time - samplesPerChip;
|
||||
int32_t excludeRangeIndex2 = index_time + samplesPerChip;
|
||||
|
||||
// -- - Correct code phase exclude range if the range includes array boundaries
|
||||
if (excludeRangeIndex1 < 0)
|
||||
{
|
||||
excludeRangeIndex1 = d_fft_size + excludeRangeIndex1;
|
||||
}
|
||||
else if (excludeRangeIndex2 >= static_cast<int>(d_fft_size))
|
||||
{
|
||||
excludeRangeIndex2 = excludeRangeIndex2 - d_fft_size;
|
||||
}
|
||||
|
||||
int32_t idx = excludeRangeIndex1;
|
||||
do
|
||||
{
|
||||
d_grid_data[index_doppler][idx] = 0.0;
|
||||
idx++;
|
||||
if (idx == static_cast<int>(d_fft_size)) idx = 0;
|
||||
}
|
||||
while (idx != excludeRangeIndex2);
|
||||
|
||||
//--- Find the second highest correlation peak in the same freq. bin ---
|
||||
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[index_doppler], d_fft_size);
|
||||
float secondPeak = d_grid_data[index_doppler][tmp_intex_t];
|
||||
|
||||
// 5- Compute the test statistics and compare to the threshold
|
||||
d_test_statistics = magt / (d_input_power * std::sqrt(d_well_count));
|
||||
d_test_statistics = firstPeak / secondPeak;
|
||||
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(index_time);
|
||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(index_doppler * d_doppler_step + d_config_doppler_min);
|
||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||
|
||||
// Record results to file if required
|
||||
if (d_dump)
|
||||
{
|
||||
std::stringstream filename;
|
||||
std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<< "_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << d_gnss_synchro->Acq_doppler_hz << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write(reinterpret_cast<char *>(d_grid_data[index_doppler]), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
return d_test_statistics;
|
||||
}
|
||||
|
||||
@ -308,10 +345,9 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons
|
||||
d_ifft->execute();
|
||||
|
||||
// save the grid matrix delay file
|
||||
|
||||
volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size);
|
||||
const float *old_vector = d_grid_data[doppler_index];
|
||||
volk_32f_x2_add_32f(d_grid_data[doppler_index], old_vector, p_tmp_vector, d_fft_size);
|
||||
//accumulate grid values
|
||||
volk_32f_x2_add_32f(d_grid_data[doppler_index], d_grid_data[doppler_index], p_tmp_vector, d_fft_size);
|
||||
}
|
||||
|
||||
volk_gnsssdr_free(p_tmp_vector);
|
||||
@ -319,18 +355,21 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons
|
||||
}
|
||||
|
||||
|
||||
int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star &input_items)
|
||||
int pcps_acquisition_fine_doppler_cc::estimate_Doppler()
|
||||
{
|
||||
// Direct FFT
|
||||
int zero_padding_factor = 2;
|
||||
int fft_size_extended = d_fft_size * zero_padding_factor;
|
||||
int zero_padding_factor = 8;
|
||||
int prn_replicas = 10;
|
||||
int signal_samples = prn_replicas * d_fft_size;
|
||||
//int fft_size_extended = nextPowerOf2(signal_samples * zero_padding_factor);
|
||||
int fft_size_extended = signal_samples * zero_padding_factor;
|
||||
gr::fft::fft_complex *fft_operator = new gr::fft::fft_complex(fft_size_extended, true);
|
||||
|
||||
//zero padding the entire vector
|
||||
std::fill_n(fft_operator->get_inbuf(), fft_size_extended, gr_complex(0.0, 0.0));
|
||||
|
||||
//1. generate local code aligned with the acquisition code phase estimation
|
||||
gr_complex *code_replica = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
gr_complex *code_replica = static_cast<gr_complex *>(volk_gnsssdr_malloc(signal_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
|
||||
gps_l1_ca_code_gen_complex_sampled(code_replica, d_gnss_synchro->PRN, d_fs_in, 0);
|
||||
|
||||
@ -342,10 +381,13 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star
|
||||
std::rotate(code_replica, code_replica + (d_fft_size - shift_index), code_replica + d_fft_size - 1);
|
||||
}
|
||||
|
||||
for (int n = 0; n < prn_replicas - 1; n++)
|
||||
{
|
||||
memcpy(&code_replica[(n + 1) * d_fft_size], code_replica, d_fft_size * sizeof(gr_complex));
|
||||
}
|
||||
//2. Perform code wipe-off
|
||||
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]); //Get the input samples pointer
|
||||
|
||||
volk_32fc_x2_multiply_32fc(fft_operator->get_inbuf(), in, code_replica, d_fft_size);
|
||||
volk_32fc_x2_multiply_32fc(fft_operator->get_inbuf(), d_10_ms_buffer, code_replica, signal_samples);
|
||||
|
||||
// 3. Perform the FFT (zero padded!)
|
||||
fft_operator->execute();
|
||||
@ -380,40 +422,12 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star
|
||||
if (std::abs(fftFreqBins[tmp_index_freq] - d_gnss_synchro->Acq_doppler_hz) < 1000)
|
||||
{
|
||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(fftFreqBins[tmp_index_freq]);
|
||||
//std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl;
|
||||
//std::cout << "FFT maximum present at " << fftFreqBins[tmp_index_freq] << " [Hz]" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
DLOG(INFO) << "Abs(Grid Doppler - FFT Doppler)=" << std::abs(fftFreqBins[tmp_index_freq] - d_gnss_synchro->Acq_doppler_hz);
|
||||
DLOG(INFO) << "Error estimating fine frequency Doppler";
|
||||
//debug log
|
||||
//
|
||||
// std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl;
|
||||
// std::stringstream filename;
|
||||
// std::streamsize n = sizeof(gr_complex) * (d_fft_size);
|
||||
//
|
||||
// filename.str("");
|
||||
// filename << "../data/code_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write(reinterpret_cast<char*>(code_replica), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
//
|
||||
// filename.str("");
|
||||
// filename << "../data/signal_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write(reinterpret_cast<char*>(in), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
//
|
||||
//
|
||||
// n = sizeof(float) * (fft_size_extended);
|
||||
// filename.str("");
|
||||
// filename << "../data/fft_prn_" << d_gnss_synchro->PRN << ".dat";
|
||||
// d_dump_file.open(filename.str().c_str(), std::ios::out
|
||||
// | std::ios::binary);
|
||||
// d_dump_file.write(reinterpret_cast<char*>(p_tmp_vector), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
// d_dump_file.close();
|
||||
}
|
||||
|
||||
// free memory!!
|
||||
@ -423,6 +437,12 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star
|
||||
return d_fft_size;
|
||||
}
|
||||
|
||||
// Called by gnuradio to enable drivers, etc for i/o devices.
|
||||
bool pcps_acquisition_fine_doppler_cc::start()
|
||||
{
|
||||
d_sample_counter = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
||||
gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items,
|
||||
@ -442,29 +462,33 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
||||
* S5. Negative_Acq: Send message and stop acq -> S0
|
||||
*/
|
||||
|
||||
int samples_remaining;
|
||||
switch (d_state)
|
||||
{
|
||||
case 0: // S0. StandBy
|
||||
//DLOG(INFO) <<"S0"<<std::endl;
|
||||
if (d_active == true)
|
||||
{
|
||||
reset_grid();
|
||||
d_state = 1;
|
||||
}
|
||||
if (!acq_parameters.blocking_on_standby)
|
||||
{
|
||||
d_sample_counter += d_fft_size; // sample counter
|
||||
consume_each(d_fft_size);
|
||||
}
|
||||
break;
|
||||
case 1: // S1. ComputeGrid
|
||||
//DLOG(INFO) <<"S1"<<std::endl;
|
||||
compute_and_accumulate_grid(input_items);
|
||||
d_well_count++;
|
||||
if (d_well_count >= d_max_dwells)
|
||||
{
|
||||
d_state = 2;
|
||||
}
|
||||
d_sample_counter += d_fft_size; // sample counter
|
||||
consume_each(d_fft_size);
|
||||
break;
|
||||
case 2: // Compute test statistics and decide
|
||||
//DLOG(INFO) <<"S2"<<std::endl;
|
||||
d_input_power = estimate_input_power(input_items);
|
||||
d_test_statistics = search_maximum();
|
||||
d_test_statistics = compute_CAF();
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 3; //perform fine doppler estimation
|
||||
@ -473,15 +497,35 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
||||
{
|
||||
d_state = 5; //negative acquisition
|
||||
}
|
||||
d_n_samples_in_buffer = 0;
|
||||
// Record results to file if required
|
||||
if (d_dump and d_channel == d_dump_channel)
|
||||
{
|
||||
dump_results(d_fft_size);
|
||||
}
|
||||
d_sample_counter += d_fft_size; // sample counter
|
||||
consume_each(d_fft_size);
|
||||
break;
|
||||
case 3: // Fine doppler estimation
|
||||
//DLOG(INFO) <<"S3"<<std::endl;
|
||||
DLOG(INFO) << "Performing fine Doppler estimation";
|
||||
estimate_Doppler(input_items); //disabled in repo
|
||||
samples_remaining = 10 * d_samples_per_ms - d_n_samples_in_buffer;
|
||||
|
||||
if (samples_remaining > noutput_items)
|
||||
{
|
||||
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), noutput_items * sizeof(gr_complex));
|
||||
d_n_samples_in_buffer += noutput_items;
|
||||
d_sample_counter += noutput_items; // sample counter
|
||||
consume_each(noutput_items);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), samples_remaining * sizeof(gr_complex));
|
||||
estimate_Doppler(); //disabled in repo
|
||||
d_sample_counter += samples_remaining; // sample counter
|
||||
consume_each(samples_remaining);
|
||||
d_state = 4;
|
||||
}
|
||||
break;
|
||||
case 4: // Positive_Acq
|
||||
//DLOG(INFO) <<"S4"<<std::endl;
|
||||
DLOG(INFO) << "positive acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
@ -489,15 +533,18 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_positive_acq = 1;
|
||||
d_active = false;
|
||||
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
|
||||
d_state = 0;
|
||||
if (!acq_parameters.blocking_on_standby)
|
||||
{
|
||||
d_sample_counter += noutput_items; // sample counter
|
||||
consume_each(noutput_items);
|
||||
}
|
||||
break;
|
||||
case 5: // Negative_Acq
|
||||
//DLOG(INFO) <<"S5"<<std::endl;
|
||||
DLOG(INFO) << "negative acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
@ -505,20 +552,103 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_positive_acq = 0;
|
||||
d_active = false;
|
||||
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
|
||||
d_state = 0;
|
||||
if (!acq_parameters.blocking_on_standby)
|
||||
{
|
||||
d_sample_counter += noutput_items; // sample counter
|
||||
consume_each(noutput_items);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
d_state = 0;
|
||||
if (!acq_parameters.blocking_on_standby)
|
||||
{
|
||||
d_sample_counter += noutput_items; // sample counter
|
||||
consume_each(noutput_items);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//DLOG(INFO)<<"d_sample_counter="<<d_sample_counter<<std::endl;
|
||||
d_sample_counter += d_fft_size; // sample counter
|
||||
consume_each(d_fft_size);
|
||||
return noutput_items;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pcps_acquisition_fine_doppler_cc::dump_results(int effective_fft_size)
|
||||
{
|
||||
d_dump_number++;
|
||||
std::string filename = d_dump_filename;
|
||||
filename.append("_");
|
||||
filename.append(1, d_gnss_synchro->System);
|
||||
filename.append("_");
|
||||
filename.append(1, d_gnss_synchro->Signal[0]);
|
||||
filename.append(1, d_gnss_synchro->Signal[1]);
|
||||
filename.append("_ch_");
|
||||
filename.append(std::to_string(d_channel));
|
||||
filename.append("_");
|
||||
filename.append(std::to_string(d_dump_number));
|
||||
filename.append("_sat_");
|
||||
filename.append(std::to_string(d_gnss_synchro->PRN));
|
||||
filename.append(".mat");
|
||||
|
||||
mat_t *matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
|
||||
if (matfp == NULL)
|
||||
{
|
||||
std::cout << "Unable to create or open Acquisition dump file" << std::endl;
|
||||
d_dump = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t dims[2] = {static_cast<size_t>(effective_fft_size), static_cast<size_t>(d_num_doppler_points)};
|
||||
matvar_t *matvar = Mat_VarCreate("acq_grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
dims[0] = static_cast<size_t>(1);
|
||||
dims[1] = static_cast<size_t>(1);
|
||||
matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_config_doppler_max, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
matvar = Mat_VarCreate("d_positive_acq", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_positive_acq, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
float aux = static_cast<float>(d_gnss_synchro->Acq_doppler_hz);
|
||||
matvar = Mat_VarCreate("acq_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
aux = static_cast<float>(d_gnss_synchro->Acq_delay_samples);
|
||||
matvar = Mat_VarCreate("acq_delay_samples", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
matvar = Mat_VarCreate("test_statistic", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_test_statistics, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
matvar = Mat_VarCreate("threshold", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_threshold, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
aux = 0.0;
|
||||
matvar = Mat_VarCreate("input_power", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
matvar = Mat_VarCreate("sample_counter", MAT_C_UINT64, MAT_T_UINT64, 1, dims, &d_sample_counter, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_gnss_synchro->PRN, 0);
|
||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||
Mat_VarFree(matvar);
|
||||
|
||||
Mat_Close(matfp);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
/*!
|
||||
* \file pcps_acquisition_fine_doppler_acquisition_cc.h
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition with multi-dwells and fine Doppler estimation
|
||||
* for GPS L1 C/A signal
|
||||
*
|
||||
* Acquisition strategy (Kay Borre book + CFAR threshold).
|
||||
* Acquisition strategy (Kay Borre book).
|
||||
* <ol>
|
||||
* <li> Compute the input signal power estimation
|
||||
* <li> Doppler serial search loop
|
||||
@ -49,11 +50,13 @@
|
||||
#define GNSS_SDR_PCPS_ACQUISITION_FINE_DOPPLER_CC_H_
|
||||
|
||||
#include "gnss_synchro.h"
|
||||
#include "acq_conf.h"
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <gnuradio/fft/fft.h>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <armadillo>
|
||||
|
||||
class pcps_acquisition_fine_doppler_cc;
|
||||
|
||||
@ -61,46 +64,33 @@ typedef boost::shared_ptr<pcps_acquisition_fine_doppler_cc>
|
||||
pcps_acquisition_fine_doppler_cc_sptr;
|
||||
|
||||
pcps_acquisition_fine_doppler_cc_sptr
|
||||
pcps_make_acquisition_fine_doppler_cc(int max_dwells, unsigned int sampled_ms,
|
||||
int doppler_max, int doppler_min, long fs_in, int samples_per_ms,
|
||||
bool dump, std::string dump_filename);
|
||||
pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition.
|
||||
*
|
||||
* Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
|
||||
* Algorithm 1, for a pseudocode description of this implementation.
|
||||
*/
|
||||
|
||||
class pcps_acquisition_fine_doppler_cc : public gr::block
|
||||
{
|
||||
private:
|
||||
friend pcps_acquisition_fine_doppler_cc_sptr
|
||||
pcps_make_acquisition_fine_doppler_cc(int max_dwells, unsigned int sampled_ms,
|
||||
int doppler_max, int doppler_min, long fs_in,
|
||||
int samples_per_ms, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
pcps_acquisition_fine_doppler_cc(int max_dwells, unsigned int sampled_ms,
|
||||
int doppler_max, int doppler_min, long fs_in,
|
||||
int samples_per_ms, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
|
||||
int doppler_offset);
|
||||
pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
|
||||
pcps_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
|
||||
|
||||
int compute_and_accumulate_grid(gr_vector_const_void_star& input_items);
|
||||
int estimate_Doppler(gr_vector_const_void_star& input_items);
|
||||
int estimate_Doppler();
|
||||
float estimate_input_power(gr_vector_const_void_star& input_items);
|
||||
double search_maximum();
|
||||
double compute_CAF();
|
||||
void reset_grid();
|
||||
void update_carrier_wipeoff();
|
||||
void free_grid_memory();
|
||||
bool start();
|
||||
|
||||
Acq_Conf acq_parameters;
|
||||
long d_fs_in;
|
||||
int d_samples_per_ms;
|
||||
int d_max_dwells;
|
||||
unsigned int d_doppler_resolution;
|
||||
int d_gnuradio_forecast_samples;
|
||||
float d_threshold;
|
||||
std::string d_satellite_str;
|
||||
@ -114,6 +104,7 @@ private:
|
||||
unsigned long int d_sample_counter;
|
||||
gr_complex* d_carrier;
|
||||
gr_complex* d_fft_codes;
|
||||
gr_complex* d_10_ms_buffer;
|
||||
float* d_magnitude;
|
||||
|
||||
float** d_grid_data;
|
||||
@ -124,17 +115,23 @@ private:
|
||||
Gnss_Synchro* d_gnss_synchro;
|
||||
unsigned int d_code_phase;
|
||||
float d_doppler_freq;
|
||||
float d_input_power;
|
||||
float d_test_statistics;
|
||||
std::ofstream d_dump_file;
|
||||
int d_positive_acq;
|
||||
|
||||
int d_state;
|
||||
bool d_active;
|
||||
int d_well_count;
|
||||
int d_n_samples_in_buffer;
|
||||
bool d_dump;
|
||||
unsigned int d_channel;
|
||||
|
||||
std::string d_dump_filename;
|
||||
|
||||
arma::fmat grid_;
|
||||
long int d_dump_number;
|
||||
unsigned int d_dump_channel;
|
||||
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Default destructor.
|
||||
@ -187,6 +184,7 @@ public:
|
||||
inline void set_channel(unsigned int channel)
|
||||
{
|
||||
d_channel = channel;
|
||||
d_dump_channel = d_channel;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -222,6 +220,14 @@ public:
|
||||
gr_vector_void_star& output_items);
|
||||
|
||||
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
|
||||
|
||||
/*!
|
||||
* \brief Obtains the next power of 2 greater or equal to the input parameter
|
||||
* \param n - Integer value to obtain the next power of 2.
|
||||
*/
|
||||
unsigned int nextPowerOf2(unsigned int n);
|
||||
|
||||
void dump_results(int effective_fft_size);
|
||||
};
|
||||
|
||||
#endif /* pcps_acquisition_fine_doppler_cc*/
|
||||
|
@ -19,4 +19,4 @@
|
||||
add_subdirectory(system_parameters)
|
||||
add_subdirectory(libs)
|
||||
add_subdirectory(receiver)
|
||||
|
||||
add_subdirectory(monitor)
|
||||
|
37
src/core/monitor/CMakeLists.txt
Normal file
37
src/core/monitor/CMakeLists.txt
Normal file
@ -0,0 +1,37 @@
|
||||
# Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors)
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
|
||||
set(CORE_MONITOR_LIBS_SOURCES
|
||||
gnss_synchro_monitor.cc
|
||||
gnss_synchro_udp_sink.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/core/system_parameters
|
||||
${GLOG_INCLUDE_DIRS}
|
||||
${GFlags_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
file(GLOB CORE_MONITOR_LIBS_HEADERS "*.h")
|
||||
list(SORT CORE_MONITOR_LIBS_HEADERS)
|
||||
add_library(core_monitor_lib ${CORE_MONITOR_LIBS_SOURCES} ${CORE_MONITOR_LIBS_HEADERS})
|
||||
source_group(Headers FILES ${CORE_MONITOR_LIBS_HEADERS})
|
||||
target_link_libraries(core_monitor_lib ${Boost_LIBRARIES})
|
92
src/core/monitor/gnss_synchro_monitor.cc
Normal file
92
src/core/monitor/gnss_synchro_monitor.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/*!
|
||||
* \file gnss_synchro_monitor.cc
|
||||
* \brief Interface of a Position Velocity and Time computation block
|
||||
* \author Álvaro Cebrián Juan, 2018. acebrianjuan(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 "gnss_synchro_monitor.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include <glog/logging.h>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
|
||||
gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels,
|
||||
int output_rate_ms,
|
||||
int udp_port,
|
||||
std::vector<std::string> udp_addresses)
|
||||
{
|
||||
return gnss_synchro_monitor_sptr(new gnss_synchro_monitor(n_channels,
|
||||
output_rate_ms,
|
||||
udp_port,
|
||||
udp_addresses));
|
||||
}
|
||||
|
||||
|
||||
gnss_synchro_monitor::gnss_synchro_monitor(unsigned int n_channels,
|
||||
int output_rate_ms,
|
||||
int udp_port,
|
||||
std::vector<std::string> udp_addresses) : gr::sync_block("gnss_synchro_monitor",
|
||||
gr::io_signature::make(n_channels, n_channels, sizeof(Gnss_Synchro)),
|
||||
gr::io_signature::make(0, 0, 0))
|
||||
{
|
||||
d_output_rate_ms = output_rate_ms;
|
||||
d_nchannels = n_channels;
|
||||
|
||||
udp_sink_ptr = std::unique_ptr<Gnss_Synchro_Udp_Sink>(new Gnss_Synchro_Udp_Sink(udp_addresses, udp_port));
|
||||
}
|
||||
|
||||
|
||||
gnss_synchro_monitor::~gnss_synchro_monitor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int gnss_synchro_monitor::work(int noutput_items, gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items __attribute__((unused)))
|
||||
{
|
||||
const Gnss_Synchro** in = reinterpret_cast<const Gnss_Synchro**>(&input_items[0]); // Get the input buffer pointer
|
||||
for (int epoch = 0; epoch < noutput_items; epoch++)
|
||||
{
|
||||
// ############ 1. READ PSEUDORANGES ####
|
||||
for (unsigned int i = 0; i < d_nchannels; i++)
|
||||
{
|
||||
//if (in[i][epoch].Flag_valid_pseudorange)
|
||||
// {
|
||||
// }
|
||||
//todo: send the gnss_synchro objects
|
||||
|
||||
std::vector<Gnss_Synchro> stocks;
|
||||
stocks.push_back(in[i][epoch]);
|
||||
udp_sink_ptr->write_gnss_synchro(stocks);
|
||||
}
|
||||
}
|
||||
return noutput_items;
|
||||
}
|
81
src/core/monitor/gnss_synchro_monitor.h
Normal file
81
src/core/monitor/gnss_synchro_monitor.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*!
|
||||
* \file gnss_synchro_monitor.h
|
||||
* \brief Interface of a Position Velocity and Time computation block
|
||||
* \author Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GNSS_SYNCHRO_MONITOR_H
|
||||
#define GNSS_SDR_GNSS_SYNCHRO_MONITOR_H
|
||||
|
||||
|
||||
#include "gnss_synchro_udp_sink.h"
|
||||
#include <gnuradio/sync_block.h>
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
|
||||
class gnss_synchro_monitor;
|
||||
|
||||
typedef boost::shared_ptr<gnss_synchro_monitor> gnss_synchro_monitor_sptr;
|
||||
|
||||
gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int n_channels,
|
||||
int output_rate_ms,
|
||||
int udp_port,
|
||||
std::vector<std::string> udp_addresses);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a block that computes the PVT solution with Galileo E1 signals
|
||||
*/
|
||||
class gnss_synchro_monitor : public gr::sync_block
|
||||
{
|
||||
private:
|
||||
friend gnss_synchro_monitor_sptr gnss_synchro_make_monitor(unsigned int nchannels,
|
||||
int output_rate_ms,
|
||||
int udp_port,
|
||||
std::vector<std::string> udp_addresses);
|
||||
|
||||
unsigned int d_nchannels;
|
||||
|
||||
int d_output_rate_ms;
|
||||
|
||||
std::unique_ptr<Gnss_Synchro_Udp_Sink> udp_sink_ptr;
|
||||
|
||||
|
||||
public:
|
||||
gnss_synchro_monitor(unsigned int nchannels,
|
||||
int output_rate_ms,
|
||||
int udp_port,
|
||||
std::vector<std::string> udp_addresses);
|
||||
|
||||
~gnss_synchro_monitor(); //!< Default destructor
|
||||
|
||||
int work(int noutput_items, gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items);
|
||||
};
|
||||
|
||||
#endif
|
69
src/core/monitor/gnss_synchro_udp_sink.cc
Normal file
69
src/core/monitor/gnss_synchro_udp_sink.cc
Normal file
@ -0,0 +1,69 @@
|
||||
/*!
|
||||
* \file gnss_synchro_udp_sink.cc
|
||||
* \brief Implementation of a class that sends serialized Gnss_Synchro
|
||||
* objects over udp to one or multiple endponits
|
||||
* \author Álvaro Cebrián Juan, 2018. acebrianjuan(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 "gnss_synchro_udp_sink.h"
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
Gnss_Synchro_Udp_Sink::Gnss_Synchro_Udp_Sink(std::vector<std::string> addresses, const unsigned short& port) : socket{io_service}
|
||||
{
|
||||
for (auto address : addresses)
|
||||
{
|
||||
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port);
|
||||
endpoints.push_back(endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
bool Gnss_Synchro_Udp_Sink::write_gnss_synchro(std::vector<Gnss_Synchro> stocks)
|
||||
{
|
||||
std::ostringstream archive_stream;
|
||||
boost::archive::binary_oarchive oa{archive_stream};
|
||||
oa << stocks;
|
||||
std::string outbound_data = archive_stream.str();
|
||||
|
||||
for (auto endpoint : endpoints)
|
||||
{
|
||||
socket.open(endpoint.protocol(), error);
|
||||
socket.connect(endpoint, error);
|
||||
|
||||
try
|
||||
{
|
||||
socket.send(boost::asio::buffer(outbound_data));
|
||||
}
|
||||
catch (boost::system::system_error const& e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
53
src/core/monitor/gnss_synchro_udp_sink.h
Normal file
53
src/core/monitor/gnss_synchro_udp_sink.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*!
|
||||
* \file gnss_synchro_udp_sink.h
|
||||
* \brief Interface of a class that sends serialized Gnss_Synchro objects
|
||||
* over udp to one or multiple endponits
|
||||
* \author Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SYNCHRO_UDP_SINK_H_
|
||||
#define GNSS_SYNCHRO_UDP_SINK_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
class Gnss_Synchro_Udp_Sink
|
||||
{
|
||||
public:
|
||||
Gnss_Synchro_Udp_Sink(std::vector<std::string> addresses, const unsigned short &port);
|
||||
bool write_gnss_synchro(std::vector<Gnss_Synchro> stocks);
|
||||
|
||||
private:
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::ip::udp::socket socket;
|
||||
boost::system::error_code error;
|
||||
std::vector<boost::asio::ip::udp::endpoint> endpoints;
|
||||
std::vector<Gnss_Synchro> stocks;
|
||||
};
|
||||
|
||||
|
||||
#endif /* GNSS_SYNCHRO_UDP_SINK_H_ */
|
@ -111,6 +111,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl
|
||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp
|
||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl
|
||||
${CMAKE_SOURCE_DIR}/src/core/monitor
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters
|
||||
@ -178,4 +179,5 @@ target_link_libraries(gnss_rx ${Boost_LIBRARIES}
|
||||
pvt_adapters
|
||||
pvt_lib
|
||||
rx_core_lib
|
||||
core_monitor_lib
|
||||
)
|
||||
|
@ -4,6 +4,7 @@
|
||||
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
|
||||
* Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
* Carles Fernandez-Prades, 2014. cfernandez(at)cttc.es
|
||||
* Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
@ -496,6 +497,25 @@ void GNSSFlowgraph::connect()
|
||||
return;
|
||||
}
|
||||
|
||||
// GNSS SYNCHRO MONITOR
|
||||
if (enable_monitor_)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (unsigned int i = 0; i < channels_count_; i++)
|
||||
{
|
||||
top_block_->connect(observables_->get_right_block(), i, GnssSynchroMonitor_, i);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG(WARNING) << "Can't connect observables to Monitor block";
|
||||
LOG(ERROR) << e.what();
|
||||
top_block_->disconnect_all();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Activate acquisition in enabled channels
|
||||
for (unsigned int i = 0; i < channels_count_; i++)
|
||||
{
|
||||
@ -1091,6 +1111,25 @@ void GNSSFlowgraph::init()
|
||||
set_channels_state();
|
||||
applied_actions_ = 0;
|
||||
DLOG(INFO) << "Blocks instantiated. " << channels_count_ << " channels.";
|
||||
|
||||
/*
|
||||
* Instantiate the receiver monitor block, if required
|
||||
*/
|
||||
enable_monitor_ = configuration_->property("Monitor.enable_monitor", false);
|
||||
|
||||
std::vector<std::string> udp_addr_vec;
|
||||
|
||||
std::string address_string = configuration_->property("Monitor.client_addresses", std::string("127.0.0.1"));
|
||||
//todo: split the string in substrings using the separator and fill the address vector.
|
||||
udp_addr_vec.push_back(address_string);
|
||||
|
||||
if (enable_monitor_)
|
||||
{
|
||||
GnssSynchroMonitor_ = gr::basic_block_sptr(new gnss_synchro_monitor(channels_count_,
|
||||
configuration_->property("Monitor.output_rate_ms", 1),
|
||||
configuration_->property("Monitor.udp_port", 1234),
|
||||
udp_addr_vec));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
|
||||
* Luis Esteve, 2011. luis(at)epsilon-formacion.com
|
||||
* Carles Fernandez-Prades, 2014. cfernandez(at)cttc.es
|
||||
* Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com
|
||||
*
|
||||
* It contains a signal source,
|
||||
* a signal conditioner, a set of channels, an observables block and a pvt.
|
||||
@ -39,6 +40,7 @@
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "gnss_signal.h"
|
||||
#include "gnss_sdr_sample_counter.h"
|
||||
#include "gnss_synchro_monitor.h"
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/null_source.h>
|
||||
@ -185,6 +187,9 @@ private:
|
||||
|
||||
std::vector<unsigned int> channels_state_;
|
||||
std::mutex signal_list_mutex;
|
||||
|
||||
bool enable_monitor_;
|
||||
gr::basic_block_sptr GnssSynchroMonitor_;
|
||||
};
|
||||
|
||||
#endif /*GNSS_SDR_GNSS_FLOWGRAPH_H_*/
|
||||
|
@ -4,6 +4,7 @@
|
||||
* \author
|
||||
* Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
* Javier Arribas, 2012. jarribas(at)cttc.es
|
||||
* Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||
@ -73,6 +74,44 @@ public:
|
||||
double RX_time; //!< Set by Observables processing block
|
||||
bool Flag_valid_pseudorange; //!< Set by Observables processing block
|
||||
double interp_TOW_ms; //!< Set by Observables processing block
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This member function is necessary to serialize and restore
|
||||
* Gnss_Synchro objects from a byte stream.
|
||||
*/
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int version)
|
||||
{
|
||||
// Satellite and signal info
|
||||
ar& System;
|
||||
ar& Signal;
|
||||
ar& PRN;
|
||||
ar& Channel_ID;
|
||||
ar& Acq_delay_samples;
|
||||
ar& Acq_doppler_hz;
|
||||
ar& Acq_samplestamp_samples;
|
||||
ar& Flag_valid_acquisition;
|
||||
//Tracking
|
||||
ar& fs;
|
||||
ar& Prompt_I;
|
||||
ar& Prompt_Q;
|
||||
ar& CN0_dB_hz;
|
||||
ar& Carrier_Doppler_hz;
|
||||
ar& Carrier_phase_rads;
|
||||
ar& Code_phase_samples;
|
||||
ar& Tracking_sample_counter;
|
||||
ar& Flag_valid_symbol_output;
|
||||
ar& correlation_length_ms;
|
||||
//Telemetry Decoder
|
||||
ar& Flag_valid_word;
|
||||
ar& TOW_at_current_symbol_ms;
|
||||
// Observables
|
||||
ar& Pseudorange_m;
|
||||
ar& RX_time;
|
||||
ar& Flag_valid_pseudorange;
|
||||
ar& interp_TOW_ms;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -307,6 +307,7 @@ set(LIST_INCLUDE_DIRS
|
||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl
|
||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp
|
||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl
|
||||
${CMAKE_SOURCE_DIR}/src/core/monitor
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/adapters
|
||||
|
@ -218,6 +218,7 @@ public:
|
||||
const std::string &labely = "y",
|
||||
const std::string &labelz = "z");
|
||||
|
||||
|
||||
/// destructor: needed to delete temporary files
|
||||
~Gnuplot();
|
||||
|
||||
@ -246,6 +247,9 @@ public:
|
||||
/// sets terminal type to terminal_std
|
||||
Gnuplot &showonscreen(); // window output is set by default (win/x11/aqua)
|
||||
|
||||
/// sets terminal type to unknown (disable the screen output)
|
||||
Gnuplot &disablescreen();
|
||||
|
||||
/// saves a gnuplot session to a postscript file, filename without extension
|
||||
Gnuplot &savetops(const std::string &filename = "gnuplot_output");
|
||||
|
||||
@ -1195,6 +1199,17 @@ Gnuplot &Gnuplot::set_smooth(const std::string &stylestr)
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Disable screen output
|
||||
//
|
||||
Gnuplot &Gnuplot::disablescreen()
|
||||
{
|
||||
cmd("set output");
|
||||
cmd("set terminal unknown");
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// sets terminal type to windows / x11
|
||||
@ -2090,19 +2105,19 @@ std::string Gnuplot::create_tmpfile(std::ofstream &tmp)
|
||||
throw GnuplotException(except.str());
|
||||
}
|
||||
|
||||
// int mkstemp(char *name);
|
||||
// shall replace the contents of the string pointed to by "name" by a unique
|
||||
// filename, and return a file descriptor for the file open for reading and
|
||||
// writing. Otherwise, -1 shall be returned if no suitable file could be
|
||||
// created. The string in template should look like a filename with six
|
||||
// trailing 'X' s; mkstemp() replaces each 'X' with a character from the
|
||||
// portable filename character set. The characters are chosen such that the
|
||||
// resulting name does not duplicate the name of an existing file at the
|
||||
// time of a call to mkstemp()
|
||||
// int mkstemp(char *name);
|
||||
// shall replace the contents of the string pointed to by "name" by a unique
|
||||
// filename, and return a file descriptor for the file open for reading and
|
||||
// writing. Otherwise, -1 shall be returned if no suitable file could be
|
||||
// created. The string in template should look like a filename with six
|
||||
// trailing 'X' s; mkstemp() replaces each 'X' with a character from the
|
||||
// portable filename character set. The characters are chosen such that the
|
||||
// resulting name does not duplicate the name of an existing file at the
|
||||
// time of a call to mkstemp()
|
||||
|
||||
//
|
||||
// open temporary files for output
|
||||
//
|
||||
//
|
||||
// open temporary files for output
|
||||
//
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
||||
if (_mktemp(name) == NULL)
|
||||
|
@ -36,7 +36,8 @@
|
||||
|
||||
// Input signal configuration
|
||||
DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator");
|
||||
DEFINE_string(signal_file, std::string("gps_l1_capture.dat"), "Path of the external signal capture file");
|
||||
DEFINE_int32(external_signal_acquisition_threshold, 2.0, "Threshold for satellite acquisition when external file is used");
|
||||
DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file");
|
||||
DEFINE_double(CN0_dBHz_start, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]");
|
||||
DEFINE_double(CN0_dBHz_stop, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]");
|
||||
DEFINE_double(CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]");
|
||||
@ -52,13 +53,13 @@ DEFINE_double(DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz
|
||||
DEFINE_double(PLL_narrow_bw_hz, 5.0, "PLL Narrow configuration value [Hz]");
|
||||
DEFINE_double(DLL_narrow_bw_hz, 0.75, "DLL Narrow configuration value [Hz]");
|
||||
|
||||
DEFINE_double(Acq_Doppler_error_hz_start, 500.0, "Acquisition Doppler error start sweep value [Hz]");
|
||||
DEFINE_double(Acq_Doppler_error_hz_stop, -500.0, "Acquisition Doppler error stop sweep value [Hz]");
|
||||
DEFINE_double(Acq_Doppler_error_hz_step, -50.0, "Acquisition Doppler error sweep step value [Hz]");
|
||||
DEFINE_double(acq_Doppler_error_hz_start, 1000.0, "Acquisition Doppler error start sweep value [Hz]");
|
||||
DEFINE_double(acq_Doppler_error_hz_stop, -1000.0, "Acquisition Doppler error stop sweep value [Hz]");
|
||||
DEFINE_double(acq_Doppler_error_hz_step, -50.0, "Acquisition Doppler error sweep step value [Hz]");
|
||||
|
||||
DEFINE_double(Acq_Delay_error_chips_start, 2.0, "Acquisition Code Delay error start sweep value [Hz]");
|
||||
DEFINE_double(Acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Hz]");
|
||||
DEFINE_double(Acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Hz]");
|
||||
DEFINE_double(acq_Delay_error_chips_start, 2.0, "Acquisition Code Delay error start sweep value [Chips]");
|
||||
DEFINE_double(acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Chips]");
|
||||
DEFINE_double(acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Chips]");
|
||||
|
||||
|
||||
DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters");
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "gnss_block_factory.h"
|
||||
#include "tracking_interface.h"
|
||||
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
|
||||
#include "in_memory_configuration.h"
|
||||
#include "tracking_true_obs_reader.h"
|
||||
#include "tracking_dump_reader.h"
|
||||
@ -52,7 +53,59 @@
|
||||
#include "test_flags.h"
|
||||
#include "tracking_tests_flags.h"
|
||||
|
||||
// ######## GNURADIO BLOCK MESSAGE RECEVER #########
|
||||
|
||||
// ######## GNURADIO ACQUISITION BLOCK MESSAGE RECEVER #########
|
||||
class Acquisition_msg_rx;
|
||||
|
||||
typedef boost::shared_ptr<Acquisition_msg_rx> Acquisition_msg_rx_sptr;
|
||||
|
||||
Acquisition_msg_rx_sptr Acquisition_msg_rx_make();
|
||||
|
||||
|
||||
class Acquisition_msg_rx : public gr::block
|
||||
{
|
||||
private:
|
||||
friend Acquisition_msg_rx_sptr Acquisition_msg_rx_make();
|
||||
void msg_handler_events(pmt::pmt_t msg);
|
||||
Acquisition_msg_rx();
|
||||
|
||||
public:
|
||||
int rx_message;
|
||||
~Acquisition_msg_rx(); //!< Default destructor
|
||||
};
|
||||
|
||||
|
||||
Acquisition_msg_rx_sptr Acquisition_msg_rx_make()
|
||||
{
|
||||
return Acquisition_msg_rx_sptr(new Acquisition_msg_rx());
|
||||
}
|
||||
|
||||
|
||||
void Acquisition_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
long int message = pmt::to_long(msg);
|
||||
rx_message = message;
|
||||
}
|
||||
catch (boost::bad_any_cast& e)
|
||||
{
|
||||
LOG(WARNING) << "msg_handler_acquisition Bad cast!\n";
|
||||
rx_message = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Acquisition_msg_rx::Acquisition_msg_rx() : gr::block("Acquisition_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(&Acquisition_msg_rx::msg_handler_events, this, _1));
|
||||
rx_message = 0;
|
||||
}
|
||||
|
||||
|
||||
Acquisition_msg_rx::~Acquisition_msg_rx() {}
|
||||
// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER #########
|
||||
class GpsL1CADllPllTrackingPullInTest_msg_rx;
|
||||
|
||||
typedef boost::shared_ptr<GpsL1CADllPllTrackingPullInTest_msg_rx> GpsL1CADllPllTrackingPullInTest_msg_rx_sptr;
|
||||
@ -88,7 +141,7 @@ void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg)
|
||||
}
|
||||
catch (boost::bad_any_cast& e)
|
||||
{
|
||||
LOG(WARNING) << "msg_handler_telemetry Bad any cast!";
|
||||
LOG(WARNING) << "msg_handler_tracking Bad cast!";
|
||||
rx_message = 0;
|
||||
}
|
||||
}
|
||||
@ -124,7 +177,11 @@ public:
|
||||
const int baseband_sampling_freq = FLAGS_fs_gen_sps;
|
||||
|
||||
std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
|
||||
std::string filename_raw_data = FLAGS_filename_raw_data;
|
||||
std::string filename_raw_data = FLAGS_signal_file;
|
||||
|
||||
std::map<int, double> doppler_measurements_map;
|
||||
std::map<int, double> code_delay_measurements_map;
|
||||
std::map<int, unsigned long int> acq_samplestamp_map;
|
||||
|
||||
int configure_generator(double CN0_dBHz, int file_idx);
|
||||
int generate_signal();
|
||||
@ -165,6 +222,7 @@ public:
|
||||
double DLL_narrow_bw_hz,
|
||||
int extend_correlation_symbols);
|
||||
|
||||
bool acquire_GPS_L1CA_signal(int SV_ID);
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<GNSSBlockFactory> factory;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
@ -188,7 +246,7 @@ int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int fi
|
||||
p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position);
|
||||
}
|
||||
p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output
|
||||
p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples
|
||||
p4 = std::string("-sig_out_file=") + FLAGS_signal_file + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples
|
||||
p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); //Baseband sampling frequency [MSps]
|
||||
p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0
|
||||
return 0;
|
||||
@ -259,20 +317,130 @@ void GpsL1CADllPllTrackingPullInTest::configure_receiver(
|
||||
}
|
||||
|
||||
|
||||
bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID)
|
||||
{
|
||||
// 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m)
|
||||
gr::top_block_sptr top_block;
|
||||
top_block = gr::make_top_block("Acquisition test");
|
||||
|
||||
// Satellite signal definition
|
||||
Gnss_Synchro tmp_gnss_synchro;
|
||||
tmp_gnss_synchro.Channel_ID = 0;
|
||||
tmp_gnss_synchro.System = 'G';
|
||||
std::string signal = "1C";
|
||||
signal.copy(tmp_gnss_synchro.Signal, 2, 0);
|
||||
tmp_gnss_synchro.PRN = SV_ID;
|
||||
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq));
|
||||
|
||||
config->set_property("Acquisition.max_dwells", "10");
|
||||
config->set_property("Acquisition.dump", "true");
|
||||
GNSSBlockFactory block_factory;
|
||||
GpsL1CaPcpsAcquisitionFineDoppler* acquisition;
|
||||
acquisition = new GpsL1CaPcpsAcquisitionFineDoppler(config.get(), "Acquisition", 1, 1);
|
||||
|
||||
acquisition->set_channel(1);
|
||||
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
||||
acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold));
|
||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500));
|
||||
|
||||
boost::shared_ptr<Acquisition_msg_rx> msg_rx;
|
||||
try
|
||||
{
|
||||
msg_rx = Acquisition_msg_rx_make();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Failure connecting the message port system: " << e.what() << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
gr::blocks::file_source::sptr file_source;
|
||||
std::string file = FLAGS_signal_file;
|
||||
const char* file_name = file.c_str();
|
||||
file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false);
|
||||
gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make();
|
||||
gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro));
|
||||
top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0);
|
||||
top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0);
|
||||
top_block->msg_connect(acquisition->get_left_block(), pmt::mp("events"), msg_rx, pmt::mp("events"));
|
||||
|
||||
// 5. Run the flowgraph
|
||||
// Get visible GPS satellites (positive acquisitions with Doppler measurements)
|
||||
// record startup time
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> elapsed_seconds;
|
||||
start = std::chrono::system_clock::now();
|
||||
|
||||
bool start_msg = true;
|
||||
|
||||
doppler_measurements_map.clear();
|
||||
code_delay_measurements_map.clear();
|
||||
acq_samplestamp_map.clear();
|
||||
|
||||
for (unsigned int PRN = 1; PRN < 33; PRN++)
|
||||
{
|
||||
tmp_gnss_synchro.PRN = PRN;
|
||||
acquisition->set_gnss_synchro(&tmp_gnss_synchro);
|
||||
acquisition->init();
|
||||
acquisition->set_local_code();
|
||||
acquisition->reset();
|
||||
msg_rx->rx_message = 0;
|
||||
top_block->run();
|
||||
if (start_msg == true)
|
||||
{
|
||||
std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl;
|
||||
std::cout << "Searching for GPS Satellites in L1 band..." << std::endl;
|
||||
std::cout << "[";
|
||||
start_msg = false;
|
||||
}
|
||||
while (msg_rx->rx_message == 0)
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
if (msg_rx->rx_message == 1)
|
||||
{
|
||||
std::cout << " " << PRN << " ";
|
||||
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));
|
||||
acq_samplestamp_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_samplestamp_samples));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " . ";
|
||||
}
|
||||
top_block->stop();
|
||||
file_source->seek(0, 0);
|
||||
std::cout.flush();
|
||||
}
|
||||
std::cout << "]" << std::endl;
|
||||
|
||||
// report the elapsed time
|
||||
end = std::chrono::system_clock::now();
|
||||
elapsed_seconds = end - start;
|
||||
std::cout << "Total signal acquisition run time "
|
||||
<< elapsed_seconds.count()
|
||||
<< " [seconds]" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
{
|
||||
//*************************************************
|
||||
//***** STEP 2: Prepare the parameters sweep ******
|
||||
//***** STEP 1: Prepare the parameters sweep ******
|
||||
//*************************************************
|
||||
std::vector<double> acq_doppler_error_hz_values;
|
||||
std::vector<double>
|
||||
acq_doppler_error_hz_values;
|
||||
std::vector<std::vector<double>> acq_delay_error_chips_values; //vector of vector
|
||||
|
||||
for (double doppler_hz = FLAGS_Acq_Doppler_error_hz_start; doppler_hz >= FLAGS_Acq_Doppler_error_hz_stop; doppler_hz = doppler_hz + FLAGS_Acq_Doppler_error_hz_step)
|
||||
for (double doppler_hz = FLAGS_acq_Doppler_error_hz_start; doppler_hz >= FLAGS_acq_Doppler_error_hz_stop; doppler_hz = doppler_hz + FLAGS_acq_Doppler_error_hz_step)
|
||||
{
|
||||
acq_doppler_error_hz_values.push_back(doppler_hz);
|
||||
std::vector<double> tmp_vector;
|
||||
//Code Delay Sweep
|
||||
for (double code_delay_chips = FLAGS_Acq_Delay_error_chips_start; code_delay_chips >= FLAGS_Acq_Delay_error_chips_stop; code_delay_chips = code_delay_chips + FLAGS_Acq_Delay_error_chips_step)
|
||||
for (double code_delay_chips = FLAGS_acq_Delay_error_chips_start; code_delay_chips >= FLAGS_acq_Delay_error_chips_stop; code_delay_chips = code_delay_chips + FLAGS_acq_Delay_error_chips_step)
|
||||
{
|
||||
tmp_vector.push_back(code_delay_chips);
|
||||
}
|
||||
@ -280,10 +448,16 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
}
|
||||
|
||||
|
||||
//*********************************************
|
||||
//***** STEP 3: Generate the input signal *****
|
||||
//*********************************************
|
||||
//***********************************************************
|
||||
//***** STEP 2: Generate the input signal (if required) *****
|
||||
//***********************************************************
|
||||
std::vector<double> generator_CN0_values;
|
||||
if (FLAGS_enable_external_signal_file)
|
||||
{
|
||||
generator_CN0_values.push_back(999); // an external input signal capture is selected, no CN0 information available
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop)
|
||||
{
|
||||
generator_CN0_values.push_back(FLAGS_CN0_dBHz_start);
|
||||
@ -295,11 +469,16 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
generator_CN0_values.push_back(cn0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use generator or use an external capture file
|
||||
if (FLAGS_enable_external_signal_file)
|
||||
{
|
||||
//todo: create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters
|
||||
//create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters
|
||||
ASSERT_EQ(acquire_GPS_L1CA_signal(FLAGS_test_satellite_PRN), true);
|
||||
bool found_satellite = doppler_measurements_map.find(FLAGS_test_satellite_PRN) != doppler_measurements_map.end();
|
||||
EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << FLAGS_test_satellite_PRN << " is not acquired";
|
||||
if (!found_satellite) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -326,6 +505,10 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
//***** Obtain the initial signal sinchronization parameters (emulating an acquisition) ****
|
||||
//******************************************************************************************
|
||||
int test_satellite_PRN = 0;
|
||||
double true_acq_doppler_hz = 0.0;
|
||||
double true_acq_delay_samples = 0.0;
|
||||
unsigned long int acq_samplestamp_samples = 0;
|
||||
|
||||
tracking_true_obs_reader true_obs_data;
|
||||
if (!FLAGS_enable_external_signal_file)
|
||||
{
|
||||
@ -341,14 +524,23 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
<< "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) +
|
||||
" is not available?";
|
||||
std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl;
|
||||
std::cout << "True Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " rue Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl;
|
||||
std::cout << "True Initial Doppler " << true_obs_data.doppler_l1_hz << " [Hz], true Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << "[Chips]" << std::endl;
|
||||
true_acq_doppler_hz = true_obs_data.doppler_l1_hz;
|
||||
true_acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast<double>(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD;
|
||||
acq_samplestamp_samples = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//todo: Simulate a perfect acquisition for the external capture file
|
||||
true_acq_doppler_hz = doppler_measurements_map.find(FLAGS_test_satellite_PRN)->second;
|
||||
true_acq_delay_samples = code_delay_measurements_map.find(FLAGS_test_satellite_PRN)->second;
|
||||
acq_samplestamp_samples = 0;
|
||||
std::cout << "Estimated Initial Doppler " << true_acq_doppler_hz
|
||||
<< " [Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]"
|
||||
<< " Acquisition SampleStamp is " << acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second << std::endl;
|
||||
}
|
||||
//CN0 LOOP
|
||||
std::vector<std::vector<double>> pull_in_results_v_v;
|
||||
|
||||
for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++)
|
||||
{
|
||||
std::vector<double> pull_in_results_v;
|
||||
@ -356,23 +548,18 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
{
|
||||
for (unsigned int current_acq_code_error_idx = 0; current_acq_code_error_idx < acq_delay_error_chips_values.at(current_acq_doppler_error_idx).size(); current_acq_code_error_idx++)
|
||||
{
|
||||
gnss_synchro.Acq_samplestamp_samples = acq_samplestamp_samples;
|
||||
//simulate a Doppler error in acquisition
|
||||
double acq_doppler_hz = true_obs_data.doppler_l1_hz + acq_doppler_error_hz_values.at(current_acq_doppler_error_idx);
|
||||
gnss_synchro.Acq_doppler_hz = true_acq_doppler_hz + acq_doppler_error_hz_values.at(current_acq_doppler_error_idx);
|
||||
//simulate Code Delay error in acquisition
|
||||
double acq_delay_samples;
|
||||
acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast<double>(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD;
|
||||
acq_delay_samples += (acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) / GPS_L1_CA_CODE_RATE_HZ) * static_cast<double>(baseband_sampling_freq);
|
||||
gnss_synchro.Acq_delay_samples = true_acq_delay_samples + (acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) / GPS_L1_CA_CODE_RATE_HZ) * static_cast<double>(baseband_sampling_freq);
|
||||
|
||||
//create flowgraph
|
||||
top_block = gr::make_top_block("Tracking test");
|
||||
std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1);
|
||||
std::shared_ptr<TrackingInterface> tracking = std::dynamic_pointer_cast<TrackingInterface>(trk_);
|
||||
|
||||
boost::shared_ptr<GpsL1CADllPllTrackingPullInTest_msg_rx> msg_rx = GpsL1CADllPllTrackingPullInTest_msg_rx_make();
|
||||
|
||||
gnss_synchro.Acq_delay_samples = acq_delay_samples;
|
||||
gnss_synchro.Acq_doppler_hz = acq_doppler_hz;
|
||||
gnss_synchro.Acq_samplestamp_samples = 0;
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
tracking->set_channel(gnss_synchro.Channel_ID);
|
||||
@ -386,8 +573,16 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
tracking->connect(top_block);
|
||||
}) << "Failure connecting tracking to the top_block.";
|
||||
|
||||
std::string file;
|
||||
ASSERT_NO_THROW({
|
||||
std::string file = "./" + filename_raw_data + std::to_string(current_cn0_idx);
|
||||
if (!FLAGS_enable_external_signal_file)
|
||||
{
|
||||
file = "./" + filename_raw_data + std::to_string(current_cn0_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
file = FLAGS_signal_file;
|
||||
}
|
||||
const char* file_name = file.c_str();
|
||||
gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false);
|
||||
gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make();
|
||||
@ -396,6 +591,8 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
top_block->connect(gr_interleaved_char_to_complex, 0, tracking->get_left_block(), 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"));
|
||||
|
||||
file_source->seek(acq_samplestamp_samples, 0);
|
||||
}) << "Failure connecting the blocks of tracking test.";
|
||||
|
||||
|
||||
@ -420,7 +617,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
//********************************
|
||||
//***** STEP 7: Plot results *****
|
||||
//********************************
|
||||
if (FLAGS_plot_gps_l1_tracking_test == true)
|
||||
if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots)
|
||||
{
|
||||
//load the measured values
|
||||
tracking_dump_reader trk_dump;
|
||||
@ -465,7 +662,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
|
||||
if (gnuplot_executable.empty())
|
||||
{
|
||||
std::cout << "WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE," << std::endl;
|
||||
std::cout << "WARNING: Although the flag show_plots 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;
|
||||
}
|
||||
@ -479,11 +676,19 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||
unsigned int decimate = static_cast<unsigned int>(FLAGS_plot_decimate);
|
||||
|
||||
if (FLAGS_plot_detail_level >= 2)
|
||||
if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots)
|
||||
{
|
||||
Gnuplot g1("linespoints");
|
||||
if (FLAGS_show_plots) g1.showonscreen(); // window output
|
||||
g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
g1.showonscreen(); // window output
|
||||
if (!FLAGS_enable_external_signal_file)
|
||||
{
|
||||
g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
}
|
||||
|
||||
g1.set_grid();
|
||||
g1.set_xlabel("Time [s]");
|
||||
g1.set_ylabel("Correlators' output");
|
||||
@ -496,8 +701,16 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
//g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18);
|
||||
|
||||
Gnuplot g2("points");
|
||||
if (FLAGS_show_plots) g2.showonscreen(); // window output
|
||||
g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
g2.showonscreen(); // window output
|
||||
if (!FLAGS_enable_external_signal_file)
|
||||
{
|
||||
g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
}
|
||||
|
||||
g2.set_grid();
|
||||
g2.set_xlabel("Inphase");
|
||||
g2.set_ylabel("Quadrature");
|
||||
@ -507,7 +720,14 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
//g2.savetopdf("Constellation", 18);
|
||||
|
||||
Gnuplot g3("linespoints");
|
||||
if (!FLAGS_enable_external_signal_file)
|
||||
{
|
||||
g3.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
}
|
||||
g3.set_grid();
|
||||
g3.set_xlabel("Time [s]");
|
||||
g3.set_ylabel("Reported CN0 [dB-Hz]");
|
||||
@ -519,7 +739,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
g3.set_legend();
|
||||
//g3.savetops("CN0_output");
|
||||
//g3.savetopdf("CN0_output", 18);
|
||||
if (FLAGS_show_plots) g3.showonscreen(); // window output
|
||||
g3.showonscreen(); // window output
|
||||
}
|
||||
}
|
||||
catch (const GnuplotException& ge)
|
||||
@ -553,21 +773,45 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults)
|
||||
pull_in_result_mesh = pull_in_results_v_v.at(current_cn0_idx);
|
||||
//plot grid
|
||||
Gnuplot g4("points palette pointsize 2 pointtype 7");
|
||||
if (FLAGS_show_plots)
|
||||
{
|
||||
g4.showonscreen(); // window output
|
||||
}
|
||||
else
|
||||
{
|
||||
g4.disablescreen();
|
||||
}
|
||||
g4.cmd("set palette defined ( 0 \"black\", 1 \"green\" )");
|
||||
g4.cmd("set key off");
|
||||
g4.cmd("set view map");
|
||||
std::string title("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast<int>(round(generator_CN0_values.at(current_cn0_idx)))) + " dB-Hz, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz.");
|
||||
std::string title;
|
||||
if (!FLAGS_enable_external_signal_file)
|
||||
{
|
||||
title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast<int>(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz].");
|
||||
}
|
||||
else
|
||||
{
|
||||
title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")");
|
||||
}
|
||||
|
||||
g4.set_title(title);
|
||||
g4.set_grid();
|
||||
g4.set_xlabel("Acquisition Doppler error [Hz]");
|
||||
g4.set_ylabel("Acquisition Code Delay error [Chips]");
|
||||
|
||||
g4.cmd("set cbrange[0:1]");
|
||||
g4.plot_xyz(doppler_error_mesh,
|
||||
code_delay_error_mesh,
|
||||
pull_in_result_mesh);
|
||||
g4.set_legend();
|
||||
if (!FLAGS_enable_external_signal_file)
|
||||
{
|
||||
g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast<int>(round(generator_CN0_values.at(current_cn0_idx)))));
|
||||
g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast<int>(round(generator_CN0_values.at(current_cn0_idx)))), 12);
|
||||
if (FLAGS_show_plots) g4.showonscreen(); // window output
|
||||
}
|
||||
else
|
||||
{
|
||||
g4.savetops("trk_pull_in_grid_external_file");
|
||||
g4.savetopdf("trk_pull_in_grid_external_file", 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||
${GLOG_INCLUDE_DIRS}
|
||||
${GFlags_INCLUDE_DIRS}
|
||||
|
@ -144,8 +144,6 @@ FrontEndCal_msg_rx::FrontEndCal_msg_rx() : gr::block("FrontEndCal_msg_rx", gr::i
|
||||
|
||||
|
||||
FrontEndCal_msg_rx::~FrontEndCal_msg_rx() {}
|
||||
|
||||
|
||||
void wait_message()
|
||||
{
|
||||
while (!stop)
|
||||
@ -353,13 +351,14 @@ int main(int argc, char** argv)
|
||||
gnss_synchro->PRN = 1;
|
||||
|
||||
long fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000);
|
||||
configuration->set_property("Acquisition.max_dwells", "10");
|
||||
|
||||
GNSSBlockFactory block_factory;
|
||||
acquisition = new GpsL1CaPcpsAcquisitionFineDoppler(configuration.get(), "Acquisition", 1, 1);
|
||||
|
||||
acquisition->set_channel(1);
|
||||
acquisition->set_gnss_synchro(gnss_synchro);
|
||||
acquisition->set_threshold(configuration->property("Acquisition.threshold", 0.0));
|
||||
acquisition->set_threshold(configuration->property("Acquisition.threshold", 2.0));
|
||||
acquisition->set_doppler_max(configuration->property("Acquisition.doppler_max", 10000));
|
||||
acquisition->set_doppler_step(configuration->property("Acquisition.doppler_step", 250));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user