mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-11-19 00:04:58 +00:00
Merge branch 'glonass' of https://github.com/gnss-sdr/gnss-sdr into glonass
This commit is contained in:
commit
e66457e438
@ -43,7 +43,7 @@ Acquisition_1G.pfa=0.0001
|
|||||||
Acquisition_1G.if=0
|
Acquisition_1G.if=0
|
||||||
Acquisition_1G.doppler_max=10000
|
Acquisition_1G.doppler_max=10000
|
||||||
Acquisition_1G.doppler_step=250
|
Acquisition_1G.doppler_step=250
|
||||||
Acquisition_1G.dump=false;
|
Acquisition_1G.dump=true;
|
||||||
Acquisition_1G.dump_filename=/archive/glo_acquisition.dat
|
Acquisition_1G.dump_filename=/archive/glo_acquisition.dat
|
||||||
;Acquisition_1G.coherent_integration_time_ms=10
|
;Acquisition_1G.coherent_integration_time_ms=10
|
||||||
|
|
||||||
|
126
conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf
Normal file
126
conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
[GNSS-SDR]
|
||||||
|
|
||||||
|
;######### GLOBAL OPTIONS ##################
|
||||||
|
GNSS-SDR.internal_fs_sps=6625000
|
||||||
|
Receiver.sources_count=2
|
||||||
|
SignalSource.repeat=false
|
||||||
|
|
||||||
|
;######### SIGNAL_SOURCE CONFIG ############
|
||||||
|
SignalSource0.implementation=File_Signal_Source
|
||||||
|
SignalSource0.filename=/archive/NT1065_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE
|
||||||
|
SignalSource0.item_type=ibyte
|
||||||
|
SignalSource0.sampling_frequency=6625000
|
||||||
|
SignalSource0.samples=0
|
||||||
|
SignalSource0.dump=false;
|
||||||
|
SignalSource0.dump_filename=/archive/signal_glonass.bin
|
||||||
|
|
||||||
|
SignalSource1.implementation=File_Signal_Source
|
||||||
|
SignalSource1.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE
|
||||||
|
SignalSource1.item_type=ibyte
|
||||||
|
SignalSource1.sampling_frequency=6625000
|
||||||
|
SignalSource1.samples=0
|
||||||
|
SignalSource1.dump=false;
|
||||||
|
SignalSource1.dump_filename=/archive/signal_glonass.bin
|
||||||
|
|
||||||
|
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||||
|
SignalConditioner0.implementation=Signal_Conditioner
|
||||||
|
DataTypeAdapter0.implementation=Ibyte_To_Complex
|
||||||
|
InputFilter0.implementation=Pass_Through
|
||||||
|
InputFilter0.item_type=gr_complex
|
||||||
|
Resampler0.implementation=Direct_Resampler
|
||||||
|
Resampler0.sample_freq_in=6625000
|
||||||
|
Resampler0.sample_freq_out=6625000
|
||||||
|
Resampler0.item_type=gr_complex
|
||||||
|
|
||||||
|
SignalConditioner1.implementation=Signal_Conditioner
|
||||||
|
DataTypeAdapter1.implementation=Ibyte_To_Complex
|
||||||
|
InputFilter1.implementation=Pass_Through
|
||||||
|
InputFilter1.item_type=gr_complex
|
||||||
|
Resampler1.implementation=Direct_Resampler
|
||||||
|
Resampler1.sample_freq_in=6625000
|
||||||
|
Resampler1.sample_freq_out=6625000
|
||||||
|
Resampler1.item_type=gr_complex
|
||||||
|
|
||||||
|
;######### CHANNELS GLOBAL CONFIG ############
|
||||||
|
Channels.in_acquisition=1
|
||||||
|
Channels_1G.count=5
|
||||||
|
Channels_1C.count=5
|
||||||
|
|
||||||
|
;# Defining GLONASS satellites
|
||||||
|
Channel0.RF_channel_ID=0
|
||||||
|
Channel1.RF_channel_ID=0
|
||||||
|
Channel2.RF_channel_ID=0
|
||||||
|
Channel3.RF_channel_ID=0
|
||||||
|
Channel4.RF_channel_ID=0
|
||||||
|
Channel5.RF_channel_ID=1
|
||||||
|
Channel6.RF_channel_ID=1
|
||||||
|
Channel7.RF_channel_ID=1
|
||||||
|
Channel8.RF_channel_ID=1
|
||||||
|
Channel9.RF_channel_ID=1
|
||||||
|
|
||||||
|
|
||||||
|
;######### ACQUISITION GLOBAL CONFIG ############
|
||||||
|
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||||
|
Acquisition_1C.item_type=gr_complex
|
||||||
|
Acquisition_1C.threshold=0.0
|
||||||
|
Acquisition_1C.pfa=0.00001
|
||||||
|
Acquisition_1C.if=0
|
||||||
|
Acquisition_1C.doppler_max=10000
|
||||||
|
Acquisition_1C.doppler_step=250
|
||||||
|
Acquisition_1C.dump=false;
|
||||||
|
Acquisition_1C.dump_filename=/archive/gps_acquisition.dat
|
||||||
|
;Acquisition_1C.coherent_integration_time_ms=10
|
||||||
|
|
||||||
|
Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition
|
||||||
|
Acquisition_1G.item_type=gr_complex
|
||||||
|
Acquisition_1G.threshold=0.0
|
||||||
|
Acquisition_1G.pfa=0.00001
|
||||||
|
Acquisition_1G.if=0
|
||||||
|
Acquisition_1G.doppler_max=10000
|
||||||
|
Acquisition_1G.doppler_step=250
|
||||||
|
Acquisition_1G.dump=false;
|
||||||
|
Acquisition_1G.dump_filename=/archive/glo_acquisition.dat
|
||||||
|
;Acquisition_1G.coherent_integration_time_ms=10
|
||||||
|
|
||||||
|
;######### TRACKING GLOBAL CONFIG ############
|
||||||
|
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||||
|
Tracking_1C.item_type=gr_complex
|
||||||
|
Tracking_1C.if=0
|
||||||
|
Tracking_1C.early_late_space_chips=0.5
|
||||||
|
Tracking_1C.pll_bw_hz=20.0;
|
||||||
|
Tracking_1C.dll_bw_hz=2.0;
|
||||||
|
Tracking_1C.dump=true;
|
||||||
|
Tracking_1C.dump_filename=/archive/gps_tracking_ch_
|
||||||
|
|
||||||
|
Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_Tracking
|
||||||
|
Tracking_1G.item_type=gr_complex
|
||||||
|
Tracking_1G.if=0
|
||||||
|
Tracking_1G.early_late_space_chips=0.5
|
||||||
|
Tracking_1G.pll_bw_hz=25.0;
|
||||||
|
Tracking_1G.dll_bw_hz=3.0;
|
||||||
|
Tracking_1G.dump=true;
|
||||||
|
Tracking_1G.dump_filename=/archive/glo_tracking_ch_
|
||||||
|
|
||||||
|
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||||
|
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||||
|
TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder
|
||||||
|
|
||||||
|
;######### OBSERVABLES CONFIG ############
|
||||||
|
Observables.implementation=Hybrid_Observables
|
||||||
|
Observables.dump=true;
|
||||||
|
Observables.dump_filename=/archive/gnss_observables.dat
|
||||||
|
|
||||||
|
;######### PVT CONFIG ############
|
||||||
|
PVT.implementation=RTKLIB_PVT
|
||||||
|
PVT.output_rate_ms=100
|
||||||
|
PVT.display_rate_ms=500
|
||||||
|
PVT.trop_model=Saastamoinen
|
||||||
|
PVT.flag_rtcm_server=true
|
||||||
|
PVT.flag_rtcm_tty_port=false
|
||||||
|
PVT.rtcm_dump_devname=/dev/pts/1
|
||||||
|
PVT.rtcm_tcp_port=2101
|
||||||
|
PVT.rtcm_MT1019_rate_ms=5000
|
||||||
|
PVT.rtcm_MT1045_rate_ms=5000
|
||||||
|
PVT.rtcm_MT1097_rate_ms=1000
|
||||||
|
PVT.rtcm_MT1077_rate_ms=1000
|
||||||
|
PVT.rinex_version=2
|
11
docs/PULL_REQUEST_TEMPLATE.md
Normal file
11
docs/PULL_REQUEST_TEMPLATE.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
:+1::tada: Hello, and thanks for contributing to [GNSS-SDR](http://gnss-sdr.org)! :tada::+1:
|
||||||
|
|
||||||
|
Before submitting your pull request, please make sure the following is done:
|
||||||
|
1. You undertake the [Contributor Covenant Code of Conduct](https://github.com/gnss-sdr/gnss-sdr/blob/master/CODE_OF_CONDUCT.md).
|
||||||
|
2. If you are a first-time contributor, after your pull request you will be asked to sign an Individual Contributor License Agreement ([CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement)) before your code gets accepted into `master`. This license is for your protection as a Contributor as well as for the protection of [CTTC](http://www.cttc.es/); it does not change your rights to use your own contributions for any other purpose. Except for the license granted therein to CTTC and recipients of software distributed by CTTC, you reserve all right, title, and interest in and to your contributions. The information you provide in that CLA will be maintained in accordance with [CTTC's privacy policy](http://www.cttc.es/privacy/).
|
||||||
|
3. You have read the [Contributing Guidelines](https://github.com/gnss-sdr/gnss-sdr/blob/master/CONTRIBUTING.md).
|
||||||
|
4. You have read the [coding style guide](http://gnss-sdr.org/coding-style/).
|
||||||
|
5. You have forked the [gnss-sdr upstream repository](https://github.com/gnss-sdr/gnss-sdr) and have created your branch from `next` (or any other currently living branch in the upstream repository).
|
||||||
|
6. Please include a description of your changes here.
|
||||||
|
|
||||||
|
**Please feel free to delete this line and the above text once you have read it and in case you want to go on with your pull request.**
|
@ -419,8 +419,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_M
|
|||||||
{
|
{
|
||||||
if(glonass_gnav_almanac.i_satellite_freq_channel){}
|
if(glonass_gnav_almanac.i_satellite_freq_channel){}
|
||||||
std::string line;
|
std::string line;
|
||||||
stringVersion = "3.02";
|
|
||||||
version = 3;
|
|
||||||
|
|
||||||
// -------- Line 1
|
// -------- Line 1
|
||||||
line = std::string(5, ' ');
|
line = std::string(5, ' ');
|
||||||
@ -643,8 +641,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& gali
|
|||||||
//Avoid compiler warning, there is not time system correction between Galileo and GLONASS
|
//Avoid compiler warning, there is not time system correction between Galileo and GLONASS
|
||||||
if(galileo_almanac.A_0G_10){}
|
if(galileo_almanac.A_0G_10){}
|
||||||
std::string line;
|
std::string line;
|
||||||
stringVersion = "3.02";
|
|
||||||
version = 3;
|
|
||||||
|
|
||||||
// -------- Line 1
|
// -------- Line 1
|
||||||
line = std::string(5, ' ');
|
line = std::string(5, ' ');
|
||||||
@ -753,8 +749,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& gali
|
|||||||
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac)
|
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac)
|
||||||
{
|
{
|
||||||
std::string line;
|
std::string line;
|
||||||
stringVersion = "3.02";
|
|
||||||
version = 3;
|
|
||||||
|
|
||||||
// -------- Line 1
|
// -------- Line 1
|
||||||
line = std::string(5, ' ');
|
line = std::string(5, ' ');
|
||||||
@ -1159,8 +1153,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co
|
|||||||
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac)
|
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac)
|
||||||
{
|
{
|
||||||
std::string line;
|
std::string line;
|
||||||
stringVersion = "3.02";
|
|
||||||
version = 3;
|
|
||||||
|
|
||||||
// -------- Line 1
|
// -------- Line 1
|
||||||
line = std::string(5, ' ');
|
line = std::string(5, ' ');
|
||||||
@ -2931,7 +2923,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int,Glonass_
|
|||||||
line += Rinex_Printer::doub2for(+glonass_gnav_ephemeris_iter->second.d_gamma_n, 18, 2);
|
line += Rinex_Printer::doub2for(+glonass_gnav_ephemeris_iter->second.d_gamma_n, 18, 2);
|
||||||
line += std::string(1, ' ');
|
line += std::string(1, ' ');
|
||||||
//TODO need to define this here. what is nd
|
//TODO need to define this here. what is nd
|
||||||
line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_t_k + p_utc_time.date().day()*86400, 18, 2);
|
line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_t_k + p_utc_time.date().day_of_week()*86400, 18, 2);
|
||||||
}
|
}
|
||||||
Rinex_Printer::lengthCheck(line);
|
Rinex_Printer::lengthCheck(line);
|
||||||
out << line << std::endl;
|
out << line << std::endl;
|
||||||
@ -3015,6 +3007,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int,Glonass_
|
|||||||
}
|
}
|
||||||
Rinex_Printer::lengthCheck(line);
|
Rinex_Printer::lengthCheck(line);
|
||||||
out << line << std::endl;
|
out << line << std::endl;
|
||||||
|
line.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5197,6 +5190,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
|
|||||||
out << line << std::endl;
|
out << line << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Rinex_Printer::update_obs_header(std::fstream& out, const Glonass_Gnav_Utc_Model& utc_model)
|
void Rinex_Printer::update_obs_header(std::fstream& out, const Glonass_Gnav_Utc_Model& utc_model)
|
||||||
{
|
{
|
||||||
if(utc_model.d_N_4)
|
if(utc_model.d_N_4)
|
||||||
@ -5584,7 +5578,6 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri
|
|||||||
}
|
}
|
||||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(numSatellitesObserved), 3);
|
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(numSatellitesObserved), 3);
|
||||||
|
|
||||||
|
|
||||||
// Receiver clock offset (optional)
|
// Receiver clock offset (optional)
|
||||||
//line += rightJustify(asString(clockOffset, 12), 15);
|
//line += rightJustify(asString(clockOffset, 12), 15);
|
||||||
|
|
||||||
@ -5654,6 +5647,9 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map<int,Gnss_Synchro>& observables)
|
void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map<int,Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
if(glonass_gnav_eph.d_m){} // avoid warning, not needed
|
if(glonass_gnav_eph.d_m){} // avoid warning, not needed
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file freq_xlating_fir_filter.cc
|
* \file freq_xlating_fir_filter.cc
|
||||||
* \brief Adapts a gnuradio gr_freq_xlating_fir_filter designed with gr_remez
|
* \brief Adapts a gnuradio gr_freq_xlating_fir_filter designed with gr_remez or gr_firdes
|
||||||
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||||
|
* Antonio Ramos, 2017. antonio.ramos(at)cttc.es
|
||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -32,6 +33,7 @@
|
|||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <gnuradio/blocks/file_sink.h>
|
#include <gnuradio/blocks/file_sink.h>
|
||||||
#include <gnuradio/filter/pm_remez.h>
|
#include <gnuradio/filter/pm_remez.h>
|
||||||
|
#include <gnuradio/filter/firdes.h>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <volk/volk.h>
|
#include <volk/volk.h>
|
||||||
#include "configuration_interface.h"
|
#include "configuration_interface.h"
|
||||||
@ -343,8 +345,8 @@ void FreqXlatingFirFilter::init()
|
|||||||
std::string default_output_item_type = "gr_complex";
|
std::string default_output_item_type = "gr_complex";
|
||||||
std::string default_taps_item_type = "float";
|
std::string default_taps_item_type = "float";
|
||||||
std::string default_dump_filename = "../data/input_filter.dat";
|
std::string default_dump_filename = "../data/input_filter.dat";
|
||||||
double default_intermediate_freq = 0;
|
double default_intermediate_freq = 0.0;
|
||||||
double default_sampling_freq = 4000000;
|
double default_sampling_freq = 4000000.0;
|
||||||
int default_number_of_taps = 6;
|
int default_number_of_taps = 6;
|
||||||
unsigned int default_number_of_bands = 2;
|
unsigned int default_number_of_bands = 2;
|
||||||
std::vector<double> default_bands = { 0.0, 0.4, 0.6, 1.0 };
|
std::vector<double> default_bands = { 0.0, 0.4, 0.6, 1.0 };
|
||||||
@ -364,7 +366,11 @@ void FreqXlatingFirFilter::init()
|
|||||||
sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq);
|
sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq);
|
||||||
int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps);
|
int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps);
|
||||||
unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands);
|
unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands);
|
||||||
|
std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type);
|
||||||
|
|
||||||
|
if(filter_type.compare("lowpass") != 0)
|
||||||
|
{
|
||||||
|
std::vector<double> taps_d;
|
||||||
std::vector<double> bands;
|
std::vector<double> bands;
|
||||||
std::vector<double> ampl;
|
std::vector<double> ampl;
|
||||||
std::vector<double> error_w;
|
std::vector<double> error_w;
|
||||||
@ -394,16 +400,20 @@ void FreqXlatingFirFilter::init()
|
|||||||
error_w.push_back(option_value);
|
error_w.push_back(option_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type);
|
|
||||||
int grid_density = config_->property(role_ + ".grid_density", default_grid_density);
|
int grid_density = config_->property(role_ + ".grid_density", default_grid_density);
|
||||||
|
taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density);
|
||||||
std::vector<double> taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl,
|
|
||||||
error_w, filter_type, grid_density);
|
|
||||||
|
|
||||||
taps_.reserve(taps_d.size());
|
taps_.reserve(taps_d.size());
|
||||||
for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++)
|
for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++)
|
||||||
{
|
{
|
||||||
taps_.push_back(float(*it));
|
taps_.push_back(static_cast<float>(*it));
|
||||||
//std::cout<<"TAP="<<float(*it)<<std::endl;
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double default_bw = 2000000.0;
|
||||||
|
double bw_ = config_->property(role_ + ".bw", default_bw);
|
||||||
|
double default_tw = bw_ / 10.0;
|
||||||
|
double tw_ = config_->property(role_ + ".tw", default_tw);
|
||||||
|
taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,13 @@
|
|||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pulse_blanking_filter.h"
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#include <gnuradio/filter/firdes.h>
|
||||||
#include "configuration_interface.h"
|
#include "configuration_interface.h"
|
||||||
|
#include "pulse_blanking_filter.h"
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
@ -41,6 +44,7 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration,
|
|||||||
out_streams_(out_streams)
|
out_streams_(out_streams)
|
||||||
{
|
{
|
||||||
size_t item_size;
|
size_t item_size;
|
||||||
|
xlat_ = false;
|
||||||
std::string default_input_item_type = "gr_complex";
|
std::string default_input_item_type = "gr_complex";
|
||||||
std::string default_output_item_type = "gr_complex";
|
std::string default_output_item_type = "gr_complex";
|
||||||
std::string default_dump_filename = "../data/input_filter.dat";
|
std::string default_dump_filename = "../data/input_filter.dat";
|
||||||
@ -71,7 +75,21 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration,
|
|||||||
item_size = sizeof(gr_complex); //avoids uninitialization
|
item_size = sizeof(gr_complex); //avoids uninitialization
|
||||||
input_size_ = sizeof(gr_complex); //avoids uninitialization
|
input_size_ = sizeof(gr_complex); //avoids uninitialization
|
||||||
}
|
}
|
||||||
|
double default_if = 0.0;
|
||||||
|
double if_aux = config_->property(role_ + ".if", default_if);
|
||||||
|
double if_ = config_->property(role_ + ".IF", if_aux);
|
||||||
|
if (std::abs(if_) > 1.0)
|
||||||
|
{
|
||||||
|
xlat_ = true;
|
||||||
|
double default_sampling_freq = 4000000.0;
|
||||||
|
double sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq);
|
||||||
|
double default_bw = 2000000.0;
|
||||||
|
double bw_ = config_->property(role_ + ".bw", default_bw);
|
||||||
|
double default_tw = bw_ / 10.0;
|
||||||
|
double tw_ = config_->property(role_ + ".tw", default_tw);
|
||||||
|
const std::vector<float> taps = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_ , tw_);
|
||||||
|
freq_xlating_ = gr::filter::freq_xlating_fir_filter_ccf::make(1, taps, if_, sampling_freq_);
|
||||||
|
}
|
||||||
if (dump_)
|
if (dump_)
|
||||||
{
|
{
|
||||||
DLOG(INFO) << "Dumping output into file " << dump_filename_;
|
DLOG(INFO) << "Dumping output into file " << dump_filename_;
|
||||||
@ -95,6 +113,10 @@ void PulseBlankingFilter::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
top_block->connect(pulse_blanking_cc_, 0, file_sink_, 0);
|
top_block->connect(pulse_blanking_cc_, 0, file_sink_, 0);
|
||||||
}
|
}
|
||||||
|
if (xlat_)
|
||||||
|
{
|
||||||
|
top_block->connect(freq_xlating_, 0, pulse_blanking_cc_, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -113,6 +135,10 @@ void PulseBlankingFilter::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
top_block->disconnect(pulse_blanking_cc_, 0, file_sink_, 0);
|
top_block->disconnect(pulse_blanking_cc_, 0, file_sink_, 0);
|
||||||
}
|
}
|
||||||
|
if (xlat_)
|
||||||
|
{
|
||||||
|
top_block->disconnect(freq_xlating_, 0, pulse_blanking_cc_, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -124,9 +150,16 @@ void PulseBlankingFilter::disconnect(gr::top_block_sptr top_block)
|
|||||||
gr::basic_block_sptr PulseBlankingFilter::get_left_block()
|
gr::basic_block_sptr PulseBlankingFilter::get_left_block()
|
||||||
{
|
{
|
||||||
if (input_item_type_.compare("gr_complex") == 0)
|
if (input_item_type_.compare("gr_complex") == 0)
|
||||||
|
{
|
||||||
|
if (xlat_)
|
||||||
|
{
|
||||||
|
return freq_xlating_;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return pulse_blanking_cc_;
|
return pulse_blanking_cc_;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
#define GNSS_SDR_PULSE_BLANKING_FILTER_H_
|
#define GNSS_SDR_PULSE_BLANKING_FILTER_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
#include <gnuradio/blocks/file_sink.h>
|
#include <gnuradio/blocks/file_sink.h>
|
||||||
|
#include <gnuradio/filter/freq_xlating_fir_filter_ccf.h>
|
||||||
#include "gnss_block_interface.h"
|
#include "gnss_block_interface.h"
|
||||||
#include "pulse_blanking_cc.h"
|
#include "pulse_blanking_cc.h"
|
||||||
|
|
||||||
@ -73,6 +73,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
ConfigurationInterface* config_;
|
ConfigurationInterface* config_;
|
||||||
bool dump_;
|
bool dump_;
|
||||||
|
bool xlat_;
|
||||||
std::string dump_filename_;
|
std::string dump_filename_;
|
||||||
std::string input_item_type_;
|
std::string input_item_type_;
|
||||||
size_t input_size_;
|
size_t input_size_;
|
||||||
@ -82,6 +83,7 @@ private:
|
|||||||
unsigned int out_streams_;
|
unsigned int out_streams_;
|
||||||
gr::blocks::file_sink::sptr file_sink_;
|
gr::blocks::file_sink::sptr file_sink_;
|
||||||
pulse_blanking_cc_sptr pulse_blanking_cc_;
|
pulse_blanking_cc_sptr pulse_blanking_cc_;
|
||||||
|
gr::filter::freq_xlating_fir_filter_ccf::sptr freq_xlating_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GNSS_SDR_PULSE_BLANKING_FILTER_H_
|
#endif // GNSS_SDR_PULSE_BLANKING_FILTER_H_
|
||||||
|
@ -113,8 +113,7 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor
|
|||||||
{
|
{
|
||||||
double tod = 0.0;
|
double tod = 0.0;
|
||||||
double dayofweek = 0.0;
|
double dayofweek = 0.0;
|
||||||
double utcsu2utc = 3*3600;
|
double glot2utc = 3*3600;
|
||||||
double glot2utcsu = 3*3600;
|
|
||||||
double days = 0.0;
|
double days = 0.0;
|
||||||
double total_sec = 0.0, sec_of_day = 0.0;
|
double total_sec = 0.0, sec_of_day = 0.0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -123,7 +122,7 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor
|
|||||||
|
|
||||||
// tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections
|
// tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections
|
||||||
// tk plus 10 sec is the true tod since get_TOW is called when in str5
|
// tk plus 10 sec is the true tod since get_TOW is called when in str5
|
||||||
tod = tod_offset - glot2utcsu - utcsu2utc;
|
tod = tod_offset - glot2utc ;
|
||||||
|
|
||||||
|
|
||||||
boost::posix_time::time_duration t(0, 0, tod);
|
boost::posix_time::time_duration t(0, 0, tod);
|
||||||
|
@ -1911,7 +1911,7 @@ int Rtcm::read_MT1020(const std::string & message, Glonass_Gnav_Ephemeris & glon
|
|||||||
glonass_gnav_eph.d_P_2 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 1)));
|
glonass_gnav_eph.d_P_2 = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 1)));
|
||||||
index += 1;
|
index += 1;
|
||||||
|
|
||||||
glonass_gnav_eph.d_t_b = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 7)))*glonass_gnav_eph.d_P_1*60.0;
|
glonass_gnav_eph.d_t_b = static_cast<double>(Rtcm::bin_to_uint(message_bin.substr(index, 7)))*15*60.0;
|
||||||
index += 7;
|
index += 7;
|
||||||
|
|
||||||
// TODO Check for type spec for intS24
|
// TODO Check for type spec for intS24
|
||||||
@ -4385,7 +4385,7 @@ int Rtcm::set_DF109(const Glonass_Gnav_Ephemeris & glonass_gnav_eph)
|
|||||||
|
|
||||||
int Rtcm::set_DF110(const Glonass_Gnav_Ephemeris & glonass_gnav_eph)
|
int Rtcm::set_DF110(const Glonass_Gnav_Ephemeris & glonass_gnav_eph)
|
||||||
{
|
{
|
||||||
unsigned int t_b = static_cast<unsigned int>(std::round(glonass_gnav_eph.d_t_b/(glonass_gnav_eph.d_P_1*60)));
|
unsigned int t_b = static_cast<unsigned int>(std::round(glonass_gnav_eph.d_t_b/(15*60)));
|
||||||
DF110 = std::bitset<7>(t_b);
|
DF110 = std::bitset<7>(t_b);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -414,13 +414,20 @@ if(ENABLE_SYSTEM_TESTING)
|
|||||||
set(HOST_SYSTEM "MacOS")
|
set(HOST_SYSTEM "MacOS")
|
||||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
add_definitions(-DHOST_SYSTEM="${HOST_SYSTEM}")
|
add_definitions(-DHOST_SYSTEM="${HOST_SYSTEM}")
|
||||||
add_executable(ttff
|
set(TTFF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/ttff_gps_l1.cc)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/system-tests/ttff_gps_l1.cc )
|
|
||||||
|
# Ensure that ttff is rebuilt if it was previously built and then removed
|
||||||
|
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/ttff)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${TTFF_SOURCES})
|
||||||
|
endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/ttff)
|
||||||
|
|
||||||
|
add_executable(ttff ${TTFF_SOURCES} )
|
||||||
if(NOT ${GTEST_DIR_LOCAL})
|
if(NOT ${GTEST_DIR_LOCAL})
|
||||||
add_dependencies(ttff gtest-${GNSSSDR_GTEST_LOCAL_VERSION})
|
add_dependencies(ttff gtest-${GNSSSDR_GTEST_LOCAL_VERSION})
|
||||||
else(NOT ${GTEST_DIR_LOCAL})
|
else(NOT ${GTEST_DIR_LOCAL})
|
||||||
add_dependencies(ttff gtest)
|
add_dependencies(ttff gtest)
|
||||||
endif(NOT ${GTEST_DIR_LOCAL})
|
endif(NOT ${GTEST_DIR_LOCAL})
|
||||||
|
|
||||||
target_link_libraries(ttff
|
target_link_libraries(ttff
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${GFlags_LIBS}
|
${GFlags_LIBS}
|
||||||
@ -448,8 +455,12 @@ if(ENABLE_SYSTEM_TESTING)
|
|||||||
endif(ENABLE_INSTALL_TESTS)
|
endif(ENABLE_INSTALL_TESTS)
|
||||||
|
|
||||||
if(ENABLE_SYSTEM_TESTING_EXTRA)
|
if(ENABLE_SYSTEM_TESTING_EXTRA)
|
||||||
add_executable(position_test
|
set(POSITION_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/position_test.cc)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/system-tests/position_test.cc )
|
# Ensure that position_test is rebuilt if it was previously built and then removed
|
||||||
|
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${POSITION_TEST_SOURCES})
|
||||||
|
endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
add_executable(position_test ${POSITION_TEST_SOURCES})
|
||||||
if(NOT ${GTEST_DIR_LOCAL})
|
if(NOT ${GTEST_DIR_LOCAL})
|
||||||
add_dependencies(position_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION})
|
add_dependencies(position_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION})
|
||||||
else(NOT ${GTEST_DIR_LOCAL})
|
else(NOT ${GTEST_DIR_LOCAL})
|
||||||
@ -482,11 +493,26 @@ if(ENABLE_SYSTEM_TESTING)
|
|||||||
endif(ENABLE_INSTALL_TESTS)
|
endif(ENABLE_INSTALL_TESTS)
|
||||||
|
|
||||||
if(GPSTK_FOUND OR OWN_GPSTK)
|
if(GPSTK_FOUND OR OWN_GPSTK)
|
||||||
add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc)
|
set(OBS_GPS_L1_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc)
|
||||||
|
# Ensure that obs_gps_l1_system_test is rebuilt if it was previously built and then removed
|
||||||
|
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${OBS_GPS_L1_TEST_SOURCES})
|
||||||
|
endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
add_executable(obs_gps_l1_system_test ${OBS_GPS_L1_TEST_SOURCES})
|
||||||
|
|
||||||
|
set(OBS_SYSTEM_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_system_test.cc)
|
||||||
|
# Ensure that obs_system_test is rebuilt if it was previously built and then removed
|
||||||
|
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${OBS_SYSTEM_TEST_SOURCES})
|
||||||
|
endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
add_executable(obs_system_test ${OBS_SYSTEM_TEST_SOURCES})
|
||||||
|
|
||||||
if(NOT ${GTEST_DIR_LOCAL})
|
if(NOT ${GTEST_DIR_LOCAL})
|
||||||
add_dependencies(obs_gps_l1_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} )
|
add_dependencies(obs_gps_l1_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} )
|
||||||
|
add_dependencies(obs_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} )
|
||||||
else(NOT ${GTEST_DIR_LOCAL})
|
else(NOT ${GTEST_DIR_LOCAL})
|
||||||
add_dependencies(obs_gps_l1_system_test gtest)
|
add_dependencies(obs_gps_l1_system_test gtest)
|
||||||
|
add_dependencies(obs_system_test gtest)
|
||||||
endif(NOT ${GTEST_DIR_LOCAL})
|
endif(NOT ${GTEST_DIR_LOCAL})
|
||||||
include_directories(${GPSTK_INCLUDE_DIRS} ${GPSTK_INCLUDE_DIRS}/gpstk)
|
include_directories(${GPSTK_INCLUDE_DIRS} ${GPSTK_INCLUDE_DIRS}/gpstk)
|
||||||
target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS}
|
target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS}
|
||||||
@ -496,19 +522,59 @@ if(ENABLE_SYSTEM_TESTING)
|
|||||||
gnss_rx
|
gnss_rx
|
||||||
${gpstk_libs})
|
${gpstk_libs})
|
||||||
|
|
||||||
|
target_link_libraries(obs_system_test ${GFlags_LIBS}
|
||||||
|
${GLOG_LIBRARIES}
|
||||||
|
${GTEST_LIBRARIES}
|
||||||
|
gnss_sp_libs
|
||||||
|
gnss_rx
|
||||||
|
${gpstk_libs})
|
||||||
|
|
||||||
if(ENABLE_INSTALL_TESTS)
|
if(ENABLE_INSTALL_TESTS)
|
||||||
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
install(TARGETS obs_gps_l1_system_test RUNTIME DESTINATION bin COMPONENT "obs_gps_l1_system_test")
|
install(TARGETS obs_gps_l1_system_test RUNTIME DESTINATION bin COMPONENT "obs_gps_l1_system_test")
|
||||||
|
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
install(TARGETS obs_system_test RUNTIME DESTINATION bin COMPONENT "obs_system_test")
|
||||||
else(ENABLE_INSTALL_TESTS)
|
else(ENABLE_INSTALL_TESTS)
|
||||||
add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD
|
add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:obs_gps_l1_system_test>
|
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:obs_gps_l1_system_test>
|
||||||
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:obs_gps_l1_system_test> )
|
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:obs_gps_l1_system_test> )
|
||||||
|
add_custom_command(TARGET obs_system_test POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:obs_system_test>
|
||||||
|
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:obs_system_test> )
|
||||||
|
|
||||||
endif(ENABLE_INSTALL_TESTS)
|
endif(ENABLE_INSTALL_TESTS)
|
||||||
endif(GPSTK_FOUND OR OWN_GPSTK)
|
endif(GPSTK_FOUND OR OWN_GPSTK)
|
||||||
|
else(ENABLE_SYSTEM_TESTING_EXTRA)
|
||||||
|
# Avoid working with old executables if they were switched ON and then OFF
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
endif(ENABLE_SYSTEM_TESTING_EXTRA)
|
endif(ENABLE_SYSTEM_TESTING_EXTRA)
|
||||||
|
else(ENABLE_SYSTEM_TESTING)
|
||||||
|
# Avoid working with old executables if they were switched ON and then OFF
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/ttff)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff)
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
|
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test)
|
||||||
endif(ENABLE_SYSTEM_TESTING)
|
endif(ENABLE_SYSTEM_TESTING)
|
||||||
|
|
||||||
|
|
||||||
|
939
src/tests/system-tests/obs_system_test.cc
Normal file
939
src/tests/system-tests/obs_system_test.cc
Normal file
@ -0,0 +1,939 @@
|
|||||||
|
/*!
|
||||||
|
* \file obs_system_test.cc
|
||||||
|
* \brief This class implements a test for the validation of generated observables.
|
||||||
|
* \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es
|
||||||
|
* Antonio Ramos, 2017. antonio.ramos(at)cttc.es
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2017 (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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <exception>
|
||||||
|
#include <iostream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <armadillo>
|
||||||
|
#include <gflags/gflags.h>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <gpstk/RinexUtilities.hpp>
|
||||||
|
#include <gpstk/Rinex3ObsBase.hpp>
|
||||||
|
#include <gpstk/Rinex3ObsData.hpp>
|
||||||
|
#include <gpstk/Rinex3ObsHeader.hpp>
|
||||||
|
#include <gpstk/Rinex3ObsStream.hpp>
|
||||||
|
#include "gnuplot_i.h"
|
||||||
|
#include "test_flags.h"
|
||||||
|
#include "concurrent_map.h"
|
||||||
|
#include "concurrent_queue.h"
|
||||||
|
#include "control_thread.h"
|
||||||
|
#include "file_configuration.h"
|
||||||
|
|
||||||
|
// For GPS NAVIGATION (L1)
|
||||||
|
concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue;
|
||||||
|
concurrent_map<Gps_Acq_Assist> global_gps_acq_assist_map;
|
||||||
|
|
||||||
|
DEFINE_string(configuration_file, "./default_configuration.conf", "Path of configuration file");
|
||||||
|
DEFINE_string(filename_rinex_true, "./default_rinex.txt", "Path of RINEX true observations");
|
||||||
|
DEFINE_string(filename_rinex_obs, "default_string", "Path of RINEX true observations");
|
||||||
|
DEFINE_double(pr_error_mean_max, 25.0, "Maximum mean error in pseudorange");
|
||||||
|
DEFINE_double(pr_error_std_max, 5.0, "Maximum standard deviation in pseudorange");
|
||||||
|
DEFINE_double(cp_error_mean_max, 5.0, "Maximum mean error in carrier phase");
|
||||||
|
DEFINE_double(cp_error_std_max, 2.5, "Maximum standard deviation in carrier phase");
|
||||||
|
DEFINE_double(dp_error_mean_max, 75.0, "Maximum mean error in Doppler frequency");
|
||||||
|
DEFINE_double(dp_error_std_max, 25.0, "Maximum standard deviation in Doppler frequency");
|
||||||
|
DEFINE_bool(plot_obs_sys_test, false, "Plots results of ObsSystemTest with gnuplot");
|
||||||
|
|
||||||
|
class ObsSystemTest: public ::testing::Test
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int configure_receiver();
|
||||||
|
int run_receiver();
|
||||||
|
void check_results();
|
||||||
|
bool check_valid_rinex_obs(std::string filename, int rinex_ver); // return true if the file is a valid Rinex observation file.
|
||||||
|
void read_rinex_files(
|
||||||
|
std::vector<arma::mat>& pseudorange_ref,
|
||||||
|
std::vector<arma::mat>& carrierphase_ref,
|
||||||
|
std::vector<arma::mat>& doppler_ref,
|
||||||
|
std::vector<arma::mat>& pseudorange_meas,
|
||||||
|
std::vector<arma::mat>& carrierphase_meas,
|
||||||
|
std::vector<arma::mat>& doppler_meas,
|
||||||
|
arma::mat& sow_prn_ref,
|
||||||
|
int signal_type);
|
||||||
|
void time_alignment_diff(
|
||||||
|
std::vector<arma::mat>& ref,
|
||||||
|
std::vector<arma::mat>& meas,
|
||||||
|
std::vector<arma::vec>& diff);
|
||||||
|
void time_alignment_diff_cp(
|
||||||
|
std::vector<arma::mat>& ref,
|
||||||
|
std::vector<arma::mat>& meas,
|
||||||
|
std::vector<arma::vec>& diff);
|
||||||
|
void time_alignment_diff_pr(
|
||||||
|
std::vector<arma::mat>& ref,
|
||||||
|
std::vector<arma::mat>& meas,
|
||||||
|
std::vector<arma::vec>& diff,
|
||||||
|
arma::mat& sow_prn_ref);
|
||||||
|
void compute_pseudorange_error(std::vector<arma::vec>& diff,
|
||||||
|
double error_th_mean, double error_th_std,
|
||||||
|
std::string signal_name);
|
||||||
|
void compute_carrierphase_error(
|
||||||
|
std::vector<arma::vec>& diff,
|
||||||
|
double error_th_mean, double error_th_std,
|
||||||
|
std::string signal_name);
|
||||||
|
void compute_doppler_error(
|
||||||
|
std::vector<arma::vec>& diff,
|
||||||
|
double error_th_mean, double error_th_std,
|
||||||
|
std::string signal_name);
|
||||||
|
std::string filename_rinex_obs = FLAGS_filename_rinex_true;
|
||||||
|
std::string generated_rinex_obs = FLAGS_filename_rinex_obs;
|
||||||
|
std::string configuration_file_ = FLAGS_configuration_file;
|
||||||
|
std::shared_ptr<FileConfiguration> config;
|
||||||
|
bool gps_1C = false;
|
||||||
|
bool gps_L5 = false;
|
||||||
|
bool gal_1B = false;
|
||||||
|
bool gal_E5a = false;
|
||||||
|
bool internal_rinex_generation = false;
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
const int num_prn_gps = 33;
|
||||||
|
const int num_prn_gal = 31;
|
||||||
|
|
||||||
|
double pseudorange_error_th_mean = FLAGS_pr_error_mean_max;
|
||||||
|
double pseudorange_error_th_std= FLAGS_pr_error_std_max;
|
||||||
|
double carrierphase_error_th_mean = FLAGS_cp_error_mean_max;
|
||||||
|
double carrierphase_error_th_std = FLAGS_cp_error_std_max;
|
||||||
|
double doppler_error_th_mean = FLAGS_dp_error_mean_max;
|
||||||
|
double doppler_error_th_std = FLAGS_dp_error_std_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool ObsSystemTest::check_valid_rinex_obs(std::string filename, int rinex_ver)
|
||||||
|
{
|
||||||
|
bool res = false;
|
||||||
|
if(rinex_ver == 2)
|
||||||
|
{
|
||||||
|
res = gpstk::isRinexObsFile(filename);
|
||||||
|
}
|
||||||
|
if(rinex_ver == 3)
|
||||||
|
{
|
||||||
|
res = gpstk::isRinex3ObsFile(filename);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::read_rinex_files(
|
||||||
|
std::vector<arma::mat>& pseudorange_ref,
|
||||||
|
std::vector<arma::mat>& carrierphase_ref,
|
||||||
|
std::vector<arma::mat>& doppler_ref,
|
||||||
|
std::vector<arma::mat>& pseudorange_meas,
|
||||||
|
std::vector<arma::mat>& carrierphase_meas,
|
||||||
|
std::vector<arma::mat>& doppler_meas,
|
||||||
|
arma::mat& sow_prn_ref,
|
||||||
|
int signal_type)
|
||||||
|
{
|
||||||
|
bool ref_exist = false;
|
||||||
|
bool meas_exist = false;
|
||||||
|
gpstk::SatID::SatelliteSystem sat_type = gpstk::SatID::systemUnknown;
|
||||||
|
int max_prn = 0;
|
||||||
|
std::string pr_string;
|
||||||
|
std::string cp_string;
|
||||||
|
std::string dp_string;
|
||||||
|
std::string signal_type_string;
|
||||||
|
sow_prn_ref.reset();
|
||||||
|
|
||||||
|
switch(signal_type)
|
||||||
|
{
|
||||||
|
case 0: //GPS L1
|
||||||
|
|
||||||
|
sat_type = gpstk::SatID::systemGPS;
|
||||||
|
max_prn = num_prn_gps;
|
||||||
|
pr_string = "C1C";
|
||||||
|
cp_string = "L1C";
|
||||||
|
dp_string = "D1C";
|
||||||
|
signal_type_string = "GPS L1 C/A";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: //Galileo E1B
|
||||||
|
|
||||||
|
sat_type = gpstk::SatID::systemGalileo;
|
||||||
|
max_prn = num_prn_gal;
|
||||||
|
pr_string = "C1B";
|
||||||
|
cp_string = "L1B";
|
||||||
|
dp_string = "D1B";
|
||||||
|
signal_type_string = "Galileo E1B";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: //GPS L5
|
||||||
|
|
||||||
|
sat_type = gpstk::SatID::systemGPS;
|
||||||
|
max_prn = num_prn_gps;
|
||||||
|
pr_string = "C5X";
|
||||||
|
cp_string = "L5X";
|
||||||
|
dp_string = "D5X";
|
||||||
|
signal_type_string = "GPS L5";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: //Galileo E5a
|
||||||
|
|
||||||
|
sat_type = gpstk::SatID::systemGalileo;
|
||||||
|
max_prn = num_prn_gal;
|
||||||
|
pr_string = "C5X";
|
||||||
|
cp_string = "L5X";
|
||||||
|
dp_string = "D5X";
|
||||||
|
signal_type_string = "Galileo E5a";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open and read reference RINEX observables file
|
||||||
|
std::cout << "Read: RINEX " << signal_type_string << " True" << std::endl;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
gpstk::Rinex3ObsStream r_ref(filename_rinex_obs);
|
||||||
|
r_ref.exceptions(std::ios::failbit);
|
||||||
|
gpstk::Rinex3ObsData r_ref_data;
|
||||||
|
gpstk::Rinex3ObsHeader r_ref_header;
|
||||||
|
gpstk::RinexDatum dataobj;
|
||||||
|
r_ref >> r_ref_header;
|
||||||
|
|
||||||
|
while (r_ref >> r_ref_data)
|
||||||
|
{
|
||||||
|
for (int myprn = 1; myprn < max_prn; myprn++)
|
||||||
|
{
|
||||||
|
gpstk::SatID prn( myprn, sat_type);
|
||||||
|
gpstk::CommonTime time = r_ref_data.time;
|
||||||
|
double sow(static_cast<gpstk::GPSWeekSecond>(time).sow);
|
||||||
|
gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn);
|
||||||
|
if( pointer == r_ref_data.obs.end() )
|
||||||
|
{
|
||||||
|
// PRN not present; do nothing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataobj = r_ref_data.getObs(prn, pr_string, r_ref_header);
|
||||||
|
double P1 = dataobj.data;
|
||||||
|
pseudorange_ref.at(myprn).insert_rows(pseudorange_ref.at(myprn).n_rows, arma::rowvec({sow, P1}));
|
||||||
|
|
||||||
|
dataobj = r_ref_data.getObs(prn, cp_string, r_ref_header);
|
||||||
|
double L1 = dataobj.data;
|
||||||
|
carrierphase_ref.at(myprn).insert_rows(carrierphase_ref.at(myprn).n_rows, arma::rowvec({sow, L1}));
|
||||||
|
|
||||||
|
dataobj = r_ref_data.getObs(prn, dp_string, r_ref_header);
|
||||||
|
double D1 = dataobj.data;
|
||||||
|
doppler_ref.at(myprn).insert_rows(doppler_ref.at(myprn).n_rows, arma::rowvec({sow, D1}));
|
||||||
|
|
||||||
|
ref_exist = true;
|
||||||
|
} // End of 'if( pointer == roe.obs.end() )'
|
||||||
|
} // end for
|
||||||
|
} // end while
|
||||||
|
} // End of 'try' block
|
||||||
|
catch(const gpstk::FFStreamError& e)
|
||||||
|
{
|
||||||
|
std::cout << e;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
catch(const gpstk::Exception& e)
|
||||||
|
{
|
||||||
|
std::cout << e;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "unknown error. I don't feel so well..." << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open and read measured RINEX observables file
|
||||||
|
std::cout << "Read: RINEX "<< signal_type_string << " measures" << std::endl;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::string arg2_gen;
|
||||||
|
if(internal_rinex_generation)
|
||||||
|
{
|
||||||
|
arg2_gen = std::string("./") + generated_rinex_obs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arg2_gen = generated_rinex_obs;
|
||||||
|
}
|
||||||
|
gpstk::Rinex3ObsStream r_meas(arg2_gen);
|
||||||
|
r_meas.exceptions(std::ios::failbit);
|
||||||
|
gpstk::Rinex3ObsData r_meas_data;
|
||||||
|
gpstk::Rinex3ObsHeader r_meas_header;
|
||||||
|
gpstk::RinexDatum dataobj;
|
||||||
|
r_meas >> r_meas_header;
|
||||||
|
|
||||||
|
while (r_meas >> r_meas_data)
|
||||||
|
{
|
||||||
|
double pr_min = 0.0;
|
||||||
|
double sow_insert = 0.0;
|
||||||
|
double prn_min = 0.0;
|
||||||
|
bool set_pr_min = true;
|
||||||
|
for (int myprn = 1; myprn < max_prn; myprn++)
|
||||||
|
{
|
||||||
|
gpstk::SatID prn( myprn, sat_type);
|
||||||
|
gpstk::CommonTime time = r_meas_data.time;
|
||||||
|
double sow(static_cast<gpstk::GPSWeekSecond>(time).sow);
|
||||||
|
gpstk::Rinex3ObsData::DataMap::iterator pointer = r_meas_data.obs.find(prn);
|
||||||
|
if( pointer == r_meas_data.obs.end() )
|
||||||
|
{
|
||||||
|
// PRN not present; do nothing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataobj = r_meas_data.getObs(prn, pr_string, r_meas_header);
|
||||||
|
double P1 = dataobj.data;
|
||||||
|
pseudorange_meas.at(myprn).insert_rows(pseudorange_meas.at(myprn).n_rows, arma::rowvec({sow, P1}));
|
||||||
|
if(set_pr_min || (P1 < pr_min))
|
||||||
|
{
|
||||||
|
set_pr_min = false;
|
||||||
|
pr_min = P1;
|
||||||
|
sow_insert = sow;
|
||||||
|
prn_min = static_cast<double>(myprn);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataobj = r_meas_data.getObs(prn, cp_string, r_meas_header);
|
||||||
|
double L1 = dataobj.data;
|
||||||
|
carrierphase_meas.at(myprn).insert_rows(carrierphase_meas.at(myprn).n_rows, arma::rowvec({sow, L1}));
|
||||||
|
|
||||||
|
dataobj = r_meas_data.getObs(prn, dp_string, r_meas_header);
|
||||||
|
double D1 = dataobj.data;
|
||||||
|
doppler_meas.at(myprn).insert_rows(doppler_meas.at(myprn).n_rows, arma::rowvec({sow, D1}));
|
||||||
|
|
||||||
|
meas_exist = true;
|
||||||
|
} // End of 'if( pointer == roe.obs.end() )'
|
||||||
|
} // end for
|
||||||
|
sow_prn_ref.insert_rows(sow_prn_ref.n_rows, arma::rowvec({sow_insert, pr_min, prn_min}));
|
||||||
|
} // end while
|
||||||
|
} // End of 'try' block
|
||||||
|
catch(const gpstk::FFStreamError& e)
|
||||||
|
{
|
||||||
|
std::cout << e;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
catch(const gpstk::Exception& e)
|
||||||
|
{
|
||||||
|
std::cout << e;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "unknown error. I don't feel so well..." << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(ref_exist) << "RINEX reference file does not contain " << signal_type_string << " information";
|
||||||
|
EXPECT_TRUE(meas_exist) << "RINEX generated file does not contain " << signal_type_string << " information";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::time_alignment_diff(
|
||||||
|
std::vector<arma::mat>& ref,
|
||||||
|
std::vector<arma::mat>& meas,
|
||||||
|
std::vector<arma::vec>& diff)
|
||||||
|
{
|
||||||
|
std::vector<arma::mat>::iterator iter_ref;
|
||||||
|
std::vector<arma::mat>::iterator iter_meas;
|
||||||
|
std::vector<arma::vec>::iterator iter_diff;
|
||||||
|
arma::mat mat_aux;
|
||||||
|
|
||||||
|
iter_ref = ref.begin();
|
||||||
|
iter_diff = diff.begin();
|
||||||
|
for(iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++)
|
||||||
|
{
|
||||||
|
if( !iter_meas->is_empty() && !iter_ref->is_empty() )
|
||||||
|
{
|
||||||
|
arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0));
|
||||||
|
arma::uword index_min = arma::min(index_);
|
||||||
|
index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0));
|
||||||
|
arma::uword index_max = arma::max(index_);
|
||||||
|
mat_aux = iter_meas->rows(index_min, index_max);
|
||||||
|
arma::vec ref_aligned;
|
||||||
|
arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned);
|
||||||
|
*iter_diff = ref_aligned - mat_aux.col(1);
|
||||||
|
}
|
||||||
|
iter_ref++;
|
||||||
|
iter_diff++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::time_alignment_diff_cp(
|
||||||
|
std::vector<arma::mat>& ref,
|
||||||
|
std::vector<arma::mat>& meas,
|
||||||
|
std::vector<arma::vec>& diff)
|
||||||
|
{
|
||||||
|
std::vector<arma::mat>::iterator iter_ref;
|
||||||
|
std::vector<arma::mat>::iterator iter_meas;
|
||||||
|
std::vector<arma::vec>::iterator iter_diff;
|
||||||
|
arma::mat mat_aux;
|
||||||
|
|
||||||
|
iter_ref = ref.begin();
|
||||||
|
iter_diff = diff.begin();
|
||||||
|
for(iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++)
|
||||||
|
{
|
||||||
|
if( !iter_meas->is_empty() && !iter_ref->is_empty() )
|
||||||
|
{
|
||||||
|
arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0));
|
||||||
|
arma::uword index_min = arma::min(index_);
|
||||||
|
index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0));
|
||||||
|
arma::uword index_max = arma::max(index_);
|
||||||
|
mat_aux = iter_meas->rows(index_min, index_max);
|
||||||
|
mat_aux.col(1) -= arma::min(mat_aux.col(1));
|
||||||
|
arma::vec ref_aligned;
|
||||||
|
arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned);
|
||||||
|
ref_aligned -= arma::min(ref_aligned);
|
||||||
|
*iter_diff = ref_aligned - mat_aux.col(1);
|
||||||
|
}
|
||||||
|
iter_ref++;
|
||||||
|
iter_diff++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::time_alignment_diff_pr(
|
||||||
|
std::vector<arma::mat>& ref,
|
||||||
|
std::vector<arma::mat>& meas,
|
||||||
|
std::vector<arma::vec>& diff,
|
||||||
|
arma::mat& sow_prn_ref)
|
||||||
|
{
|
||||||
|
std::vector<arma::mat>::iterator iter_ref;
|
||||||
|
std::vector<arma::mat>::iterator iter_meas;
|
||||||
|
std::vector<arma::vec>::iterator iter_diff;
|
||||||
|
arma::mat mat_aux;
|
||||||
|
arma::vec subtraction_meas;
|
||||||
|
arma::vec subtraction_ref;
|
||||||
|
|
||||||
|
arma::mat subtraction_pr_ref = sow_prn_ref;
|
||||||
|
arma::vec::iterator iter_vec0 = subtraction_pr_ref.begin_col(0);
|
||||||
|
arma::vec::iterator iter_vec1 = subtraction_pr_ref.begin_col(1);
|
||||||
|
arma::vec::iterator iter_vec2 = subtraction_pr_ref.begin_col(2);
|
||||||
|
|
||||||
|
for(iter_vec1 = subtraction_pr_ref.begin_col(1); iter_vec1 != subtraction_pr_ref.end_col(1); iter_vec1++)
|
||||||
|
{
|
||||||
|
arma::vec aux_pr; //vector with only 1 element
|
||||||
|
arma::vec aux_sow = {*iter_vec0}; //vector with only 1 element
|
||||||
|
arma::interp1(ref.at(static_cast<int>(*iter_vec2)).col(0),
|
||||||
|
ref.at(static_cast<int>(*iter_vec2)).col(1),
|
||||||
|
aux_sow,
|
||||||
|
aux_pr);
|
||||||
|
*iter_vec1 = aux_pr(0);
|
||||||
|
iter_vec0++;
|
||||||
|
iter_vec2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter_ref = ref.begin();
|
||||||
|
iter_diff = diff.begin();
|
||||||
|
for(iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++)
|
||||||
|
{
|
||||||
|
if( !iter_meas->is_empty() && !iter_ref->is_empty() )
|
||||||
|
{
|
||||||
|
arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0));
|
||||||
|
arma::uword index_min = arma::min(index_);
|
||||||
|
index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0));
|
||||||
|
arma::uword index_max = arma::max(index_);
|
||||||
|
mat_aux = iter_meas->rows(index_min, index_max);
|
||||||
|
arma::interp1(sow_prn_ref.col(0), sow_prn_ref.col(1), mat_aux.col(0), subtraction_meas);
|
||||||
|
mat_aux.col(1) -= subtraction_meas;
|
||||||
|
arma::vec ref_aligned;
|
||||||
|
arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned);
|
||||||
|
arma::interp1(subtraction_pr_ref.col(0), subtraction_pr_ref.col(1), mat_aux.col(0), subtraction_ref);
|
||||||
|
ref_aligned -= subtraction_ref;
|
||||||
|
*iter_diff = ref_aligned - mat_aux.col(1);
|
||||||
|
}
|
||||||
|
iter_ref++;
|
||||||
|
iter_diff++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ObsSystemTest::configure_receiver()
|
||||||
|
{
|
||||||
|
config = std::make_shared<FileConfiguration>(configuration_file_);
|
||||||
|
|
||||||
|
if( config->property("Channels_1C.count", 0) > 0 )
|
||||||
|
{gps_1C = true;}
|
||||||
|
if( config->property("Channels_1B.count", 0) > 0 )
|
||||||
|
{gal_1B = true;}
|
||||||
|
if( config->property("Channels_5X.count", 0) > 0 )
|
||||||
|
{gal_E5a = true;}
|
||||||
|
if( config->property("Channels_7X.count", 0) > 0 ) //NOT DEFINITIVE!!!!!
|
||||||
|
{gps_L5 = true;}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ObsSystemTest::run_receiver()
|
||||||
|
{
|
||||||
|
std::shared_ptr<ControlThread> control_thread;
|
||||||
|
control_thread = std::make_shared<ControlThread>(config);
|
||||||
|
// start receiver
|
||||||
|
try
|
||||||
|
{
|
||||||
|
control_thread->run();
|
||||||
|
}
|
||||||
|
catch(const boost::exception & e)
|
||||||
|
{
|
||||||
|
std::cout << "Boost exception: " << boost::diagnostic_information(e);
|
||||||
|
}
|
||||||
|
catch(const std::exception & ex)
|
||||||
|
{
|
||||||
|
std::cout << "STD exception: " << ex.what();
|
||||||
|
}
|
||||||
|
// Get the name of the RINEX obs file generated by the receiver
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||||
|
FILE *fp;
|
||||||
|
std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1");
|
||||||
|
char buffer[1035];
|
||||||
|
fp = popen(&argum2[0], "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to run command: " << argum2 << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while (fgets(buffer, sizeof(buffer), fp) != NULL)
|
||||||
|
{
|
||||||
|
std::string aux = std::string(buffer);
|
||||||
|
generated_rinex_obs = aux.erase(aux.length() - 1, 1);
|
||||||
|
internal_rinex_generation = true;
|
||||||
|
}
|
||||||
|
pclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::compute_pseudorange_error(
|
||||||
|
std::vector<arma::vec>& diff,
|
||||||
|
double error_th_mean, double error_th_std,
|
||||||
|
std::string signal_name)
|
||||||
|
{
|
||||||
|
int prn_id = 0;
|
||||||
|
std::vector<arma::vec>::iterator iter_diff;
|
||||||
|
std::vector<double> means;
|
||||||
|
std::vector<double> stddevs;
|
||||||
|
std::vector<double> prns;
|
||||||
|
for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++)
|
||||||
|
{
|
||||||
|
if(!iter_diff->is_empty())
|
||||||
|
{
|
||||||
|
double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff)));
|
||||||
|
means.push_back(d_mean);
|
||||||
|
double d_stddev = arma::stddev(*iter_diff);
|
||||||
|
stddevs.push_back(d_stddev);
|
||||||
|
prns.push_back(static_cast<double>(prn_id));
|
||||||
|
std::cout << "-- RMS pseudorange difference for sat " << prn_id << ": " << d_mean;
|
||||||
|
std::cout << " +/- " << d_stddev;
|
||||||
|
std::cout << " [m]" << std::endl;
|
||||||
|
EXPECT_LT(d_mean, error_th_mean);
|
||||||
|
EXPECT_LT(d_stddev, error_th_std);
|
||||||
|
}
|
||||||
|
prn_id++;
|
||||||
|
}
|
||||||
|
if(FLAGS_plot_obs_sys_test == true)
|
||||||
|
{
|
||||||
|
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
|
||||||
|
if(gnuplot_executable.empty())
|
||||||
|
{
|
||||||
|
std::cout << "WARNING: Although the flag plot_obs_sys_test has been set to TRUE," << std::endl;
|
||||||
|
std::cout << "gnuplot has not been found in your system." << std::endl;
|
||||||
|
std::cout << "Test results will not be plotted." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
boost::filesystem::path p(gnuplot_executable);
|
||||||
|
boost::filesystem::path dir = p.parent_path();
|
||||||
|
std::string gnuplot_path = dir.native();
|
||||||
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
|
Gnuplot g1("linespoints");
|
||||||
|
g1.set_title(signal_name + " Pseudorange error");
|
||||||
|
g1.set_grid();
|
||||||
|
g1.set_xlabel("PRN");
|
||||||
|
g1.set_ylabel("Pseudorange error [m]");
|
||||||
|
g1.plot_xy(prns, means, "RMS error");
|
||||||
|
g1.plot_xy(prns, stddevs, "Standard deviation");
|
||||||
|
//g1.savetops("FFT_execution_times_extended");
|
||||||
|
//g1.savetopdf("FFT_execution_times_extended", 18);
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
catch (const GnuplotException & ge)
|
||||||
|
{
|
||||||
|
std::cout << ge.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::compute_carrierphase_error(
|
||||||
|
std::vector<arma::vec>& diff,
|
||||||
|
double error_th_mean, double error_th_std,
|
||||||
|
std::string signal_name)
|
||||||
|
{
|
||||||
|
int prn_id = 0;
|
||||||
|
std::vector<double> means;
|
||||||
|
std::vector<double> stddevs;
|
||||||
|
std::vector<double> prns;
|
||||||
|
std::vector<arma::vec>::iterator iter_diff;
|
||||||
|
for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++)
|
||||||
|
{
|
||||||
|
if(!iter_diff->is_empty())
|
||||||
|
{
|
||||||
|
double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff)));
|
||||||
|
means.push_back(d_mean);
|
||||||
|
double d_stddev = arma::stddev(*iter_diff);
|
||||||
|
stddevs.push_back(d_stddev);
|
||||||
|
prns.push_back(static_cast<double>(prn_id));
|
||||||
|
std::cout << "-- RMS carrier phase difference for sat " << prn_id << ": " << d_mean;
|
||||||
|
std::cout << " +/- " << d_stddev;
|
||||||
|
std::cout << " whole cycles" << std::endl;
|
||||||
|
EXPECT_LT(d_mean, error_th_mean);
|
||||||
|
EXPECT_LT(d_stddev, error_th_std);
|
||||||
|
}
|
||||||
|
prn_id++;
|
||||||
|
}
|
||||||
|
if(FLAGS_plot_obs_sys_test == true)
|
||||||
|
{
|
||||||
|
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
|
||||||
|
if(gnuplot_executable.empty())
|
||||||
|
{
|
||||||
|
std::cout << "WARNING: Although the flag plot_obs_sys_test has been set to TRUE," << std::endl;
|
||||||
|
std::cout << "gnuplot has not been found in your system." << std::endl;
|
||||||
|
std::cout << "Test results will not be plotted." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
boost::filesystem::path p(gnuplot_executable);
|
||||||
|
boost::filesystem::path dir = p.parent_path();
|
||||||
|
std::string gnuplot_path = dir.native();
|
||||||
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
|
Gnuplot g1("linespoints");
|
||||||
|
g1.set_title(signal_name + " Carrier phase error");
|
||||||
|
g1.set_grid();
|
||||||
|
g1.set_xlabel("PRN");
|
||||||
|
g1.set_ylabel("Carrier phase error [whole cycles]");
|
||||||
|
g1.plot_xy(prns, means, "RMS error");
|
||||||
|
g1.plot_xy(prns, stddevs, "Standard deviation");
|
||||||
|
//g1.savetops("FFT_execution_times_extended");
|
||||||
|
//g1.savetopdf("FFT_execution_times_extended", 18);
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
catch (const GnuplotException & ge)
|
||||||
|
{
|
||||||
|
std::cout << ge.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::compute_doppler_error(
|
||||||
|
std::vector<arma::vec>& diff,
|
||||||
|
double error_th_mean, double error_th_std,
|
||||||
|
std::string signal_name)
|
||||||
|
{
|
||||||
|
int prn_id = 0;
|
||||||
|
std::vector<double> means;
|
||||||
|
std::vector<double> stddevs;
|
||||||
|
std::vector<double> prns;
|
||||||
|
std::vector<arma::vec>::iterator iter_diff;
|
||||||
|
for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++)
|
||||||
|
{
|
||||||
|
if(!iter_diff->is_empty())
|
||||||
|
{
|
||||||
|
double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff)));
|
||||||
|
means.push_back(d_mean);
|
||||||
|
double d_stddev = arma::stddev(*iter_diff);
|
||||||
|
stddevs.push_back(d_stddev);
|
||||||
|
prns.push_back(static_cast<double>(prn_id));
|
||||||
|
std::cout << "-- RMS Doppler difference for sat " << prn_id << ": " << d_mean;
|
||||||
|
std::cout << " +/- " << d_stddev;
|
||||||
|
std::cout << " [Hz]" << std::endl;
|
||||||
|
EXPECT_LT(d_mean, error_th_mean);
|
||||||
|
EXPECT_LT(d_stddev, error_th_std);
|
||||||
|
}
|
||||||
|
prn_id++;
|
||||||
|
}
|
||||||
|
if(FLAGS_plot_obs_sys_test == true)
|
||||||
|
{
|
||||||
|
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
|
||||||
|
if(gnuplot_executable.empty())
|
||||||
|
{
|
||||||
|
std::cout << "WARNING: Although the flag plot_obs_sys_test has been set to TRUE," << std::endl;
|
||||||
|
std::cout << "gnuplot has not been found in your system." << std::endl;
|
||||||
|
std::cout << "Test results will not be plotted." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
boost::filesystem::path p(gnuplot_executable);
|
||||||
|
boost::filesystem::path dir = p.parent_path();
|
||||||
|
std::string gnuplot_path = dir.native();
|
||||||
|
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||||
|
|
||||||
|
Gnuplot g1("linespoints");
|
||||||
|
g1.set_title(signal_name + " Doppler error");
|
||||||
|
g1.set_grid();
|
||||||
|
g1.set_xlabel("PRN");
|
||||||
|
g1.set_ylabel("Doppler error [Hz]");
|
||||||
|
g1.plot_xy(prns, means, "RMS error");
|
||||||
|
g1.plot_xy(prns, stddevs, "Standard deviation");
|
||||||
|
//g1.savetops("FFT_execution_times_extended");
|
||||||
|
//g1.savetopdf("FFT_execution_times_extended", 18);
|
||||||
|
g1.showonscreen(); // window output
|
||||||
|
}
|
||||||
|
catch (const GnuplotException & ge)
|
||||||
|
{
|
||||||
|
std::cout << ge.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObsSystemTest::check_results()
|
||||||
|
{
|
||||||
|
arma::mat sow_prn_ref;
|
||||||
|
if(gps_1C)
|
||||||
|
{
|
||||||
|
std::vector<arma::mat> pseudorange_ref(num_prn_gps);
|
||||||
|
std::vector<arma::mat> carrierphase_ref(num_prn_gps);
|
||||||
|
std::vector<arma::mat> doppler_ref(num_prn_gps);
|
||||||
|
|
||||||
|
std::vector<arma::mat> pseudorange_meas(num_prn_gps);
|
||||||
|
std::vector<arma::mat> carrierphase_meas(num_prn_gps);
|
||||||
|
std::vector<arma::mat> doppler_meas(num_prn_gps);
|
||||||
|
|
||||||
|
read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 0);
|
||||||
|
|
||||||
|
// Time alignment and difference computation
|
||||||
|
|
||||||
|
std::vector<arma::vec> pr_diff(num_prn_gps);
|
||||||
|
std::vector<arma::vec> cp_diff(num_prn_gps);
|
||||||
|
std::vector<arma::vec> dp_diff(num_prn_gps);
|
||||||
|
time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref);
|
||||||
|
time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff);
|
||||||
|
time_alignment_diff(doppler_ref, doppler_meas, dp_diff);
|
||||||
|
|
||||||
|
// Results
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "GPS L1 C/A obs. results" << std::endl;
|
||||||
|
|
||||||
|
// Compute pseudorange error
|
||||||
|
|
||||||
|
compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "GPS L1 C/A");
|
||||||
|
|
||||||
|
// Compute carrier phase error
|
||||||
|
|
||||||
|
compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "GPS L1 C/A");
|
||||||
|
|
||||||
|
// Compute Doppler error
|
||||||
|
|
||||||
|
compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "GPS L1 C/A");
|
||||||
|
}
|
||||||
|
if(gps_L5)
|
||||||
|
{
|
||||||
|
std::vector<arma::mat> pseudorange_ref(num_prn_gps);
|
||||||
|
std::vector<arma::mat> carrierphase_ref(num_prn_gps);
|
||||||
|
std::vector<arma::mat> doppler_ref(num_prn_gps);
|
||||||
|
|
||||||
|
std::vector<arma::mat> pseudorange_meas(num_prn_gps);
|
||||||
|
std::vector<arma::mat> carrierphase_meas(num_prn_gps);
|
||||||
|
std::vector<arma::mat> doppler_meas(num_prn_gps);
|
||||||
|
|
||||||
|
read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 2);
|
||||||
|
|
||||||
|
// Time alignment and difference computation
|
||||||
|
|
||||||
|
std::vector<arma::vec> pr_diff(num_prn_gps);
|
||||||
|
std::vector<arma::vec> cp_diff(num_prn_gps);
|
||||||
|
std::vector<arma::vec> dp_diff(num_prn_gps);
|
||||||
|
time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref);
|
||||||
|
time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff);
|
||||||
|
time_alignment_diff(doppler_ref, doppler_meas, dp_diff);
|
||||||
|
|
||||||
|
// Results
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "GPS L5 obs. results" << std::endl;
|
||||||
|
|
||||||
|
// Compute pseudorange error
|
||||||
|
|
||||||
|
compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "GPS L5");
|
||||||
|
|
||||||
|
// Compute carrier phase error
|
||||||
|
|
||||||
|
compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "GPS L5");
|
||||||
|
|
||||||
|
// Compute Doppler error
|
||||||
|
|
||||||
|
compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "GPS L5");
|
||||||
|
}
|
||||||
|
if(gal_1B)
|
||||||
|
{
|
||||||
|
std::vector<arma::mat> pseudorange_ref(num_prn_gal);
|
||||||
|
std::vector<arma::mat> carrierphase_ref(num_prn_gal);
|
||||||
|
std::vector<arma::mat> doppler_ref(num_prn_gal);
|
||||||
|
|
||||||
|
std::vector<arma::mat> pseudorange_meas(num_prn_gal);
|
||||||
|
std::vector<arma::mat> carrierphase_meas(num_prn_gal);
|
||||||
|
std::vector<arma::mat> doppler_meas(num_prn_gal);
|
||||||
|
|
||||||
|
read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 1);
|
||||||
|
|
||||||
|
// Time alignment and difference computation
|
||||||
|
|
||||||
|
std::vector<arma::vec> pr_diff(num_prn_gal);
|
||||||
|
std::vector<arma::vec> cp_diff(num_prn_gal);
|
||||||
|
std::vector<arma::vec> dp_diff(num_prn_gal);
|
||||||
|
time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref);
|
||||||
|
time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff);
|
||||||
|
time_alignment_diff(doppler_ref, doppler_meas, dp_diff);
|
||||||
|
|
||||||
|
// Results
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "Galileo E1B obs. results" << std::endl;
|
||||||
|
|
||||||
|
// Compute pseudorange error
|
||||||
|
|
||||||
|
compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "Galileo E1B");
|
||||||
|
|
||||||
|
// Compute carrier phase error
|
||||||
|
|
||||||
|
compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "Galileo E1B");
|
||||||
|
|
||||||
|
// Compute Doppler error
|
||||||
|
|
||||||
|
compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "Galileo E1B");
|
||||||
|
}
|
||||||
|
if(gal_E5a)
|
||||||
|
{
|
||||||
|
std::vector<arma::mat> pseudorange_ref(num_prn_gal);
|
||||||
|
std::vector<arma::mat> carrierphase_ref(num_prn_gal);
|
||||||
|
std::vector<arma::mat> doppler_ref(num_prn_gal);
|
||||||
|
|
||||||
|
std::vector<arma::mat> pseudorange_meas(num_prn_gal);
|
||||||
|
std::vector<arma::mat> carrierphase_meas(num_prn_gal);
|
||||||
|
std::vector<arma::mat> doppler_meas(num_prn_gal);
|
||||||
|
|
||||||
|
read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 3);
|
||||||
|
|
||||||
|
// Time alignment and difference computation
|
||||||
|
|
||||||
|
std::vector<arma::vec> pr_diff(num_prn_gal);
|
||||||
|
std::vector<arma::vec> cp_diff(num_prn_gal);
|
||||||
|
std::vector<arma::vec> dp_diff(num_prn_gal);
|
||||||
|
time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref);
|
||||||
|
time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff);
|
||||||
|
time_alignment_diff(doppler_ref, doppler_meas, dp_diff);
|
||||||
|
|
||||||
|
// Results
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "Galileo E5a obs. results" << std::endl;
|
||||||
|
|
||||||
|
// Compute pseudorange error
|
||||||
|
|
||||||
|
compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "Galileo E5a");
|
||||||
|
|
||||||
|
// Compute carrier phase error
|
||||||
|
|
||||||
|
compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "Galileo E5a");
|
||||||
|
|
||||||
|
// Compute Doppler error
|
||||||
|
|
||||||
|
compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "Galileo E5a");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(ObsSystemTest, Observables_system_test)
|
||||||
|
{
|
||||||
|
std::cout << "Validating input RINEX obs (TRUE) file: " << filename_rinex_obs << " ..." << std::endl;
|
||||||
|
bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs, 3);
|
||||||
|
ASSERT_EQ(true, is_rinex_obs_valid) << "The RINEX observation file " << filename_rinex_obs << " is not well formed. Only RINEX v. 3.00 files are allowed";
|
||||||
|
std::cout << "The file is valid." << std::endl;
|
||||||
|
// Configure receiver
|
||||||
|
configure_receiver();
|
||||||
|
if(generated_rinex_obs.compare("default_string") == 0)
|
||||||
|
{
|
||||||
|
// Run the receiver
|
||||||
|
ASSERT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator";
|
||||||
|
}
|
||||||
|
std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << generated_rinex_obs << " ..." << std::endl;
|
||||||
|
bool is_gen_rinex_obs_valid = false;
|
||||||
|
if(internal_rinex_generation)
|
||||||
|
{
|
||||||
|
is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + generated_rinex_obs, config->property("PVT.rinex_version", 3));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_gen_rinex_obs_valid = check_valid_rinex_obs(generated_rinex_obs, config->property("PVT.rinex_version", 3));
|
||||||
|
}
|
||||||
|
ASSERT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << generated_rinex_obs << ", generated by GNSS-SDR, is not well formed.";
|
||||||
|
std::cout << "The file is valid." << std::endl;
|
||||||
|
// Check results
|
||||||
|
check_results();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
std::cout << "Running GNSS-SDR in Space Observables validation test..." << std::endl;
|
||||||
|
int res = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
}
|
||||||
|
catch(...) {} // catch the "testing::internal::<unnamed>::ClassUniqueToAlwaysTrue" from gtest
|
||||||
|
|
||||||
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
|
||||||
|
// Run the Tests
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res = RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Unexpected catch";
|
||||||
|
}
|
||||||
|
google::ShutDownCommandLineFlags();
|
||||||
|
return res;
|
||||||
|
}
|
@ -60,6 +60,13 @@ concurrent_map<Gps_Acq_Assist> global_gps_acq_assist_map;
|
|||||||
class StaticPositionSystemTest: public ::testing::Test
|
class StaticPositionSystemTest: public ::testing::Test
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
int configure_generator();
|
||||||
|
int generate_signal();
|
||||||
|
int configure_receiver();
|
||||||
|
int run_receiver();
|
||||||
|
void check_results();
|
||||||
|
|
||||||
|
private:
|
||||||
std::string generator_binary;
|
std::string generator_binary;
|
||||||
std::string p1;
|
std::string p1;
|
||||||
std::string p2;
|
std::string p2;
|
||||||
@ -72,12 +79,6 @@ public:
|
|||||||
std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
|
std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
|
||||||
std::string filename_raw_data = FLAGS_filename_raw_data;
|
std::string filename_raw_data = FLAGS_filename_raw_data;
|
||||||
|
|
||||||
int configure_generator();
|
|
||||||
int generate_signal();
|
|
||||||
|
|
||||||
int configure_receiver();
|
|
||||||
int run_receiver();
|
|
||||||
void check_results();
|
|
||||||
void print_results(const std::vector<double> & east,
|
void print_results(const std::vector<double> & east,
|
||||||
const std::vector<double> & north,
|
const std::vector<double> & north,
|
||||||
const std::vector<double> & up);
|
const std::vector<double> & up);
|
||||||
@ -88,13 +89,12 @@ public:
|
|||||||
void geodetic2Enu(const double latitude, const double longitude, const double altitude,
|
void geodetic2Enu(const double latitude, const double longitude, const double altitude,
|
||||||
double* east, double* north, double* up);
|
double* east, double* north, double* up);
|
||||||
|
|
||||||
|
void geodetic2Ecef(const double latitude, const double longitude, const double altitude,
|
||||||
|
double* x, double* y, double* z);
|
||||||
|
|
||||||
std::shared_ptr<InMemoryConfiguration> config;
|
std::shared_ptr<InMemoryConfiguration> config;
|
||||||
std::shared_ptr<FileConfiguration> config_f;
|
std::shared_ptr<FileConfiguration> config_f;
|
||||||
std::string generated_kml_file;
|
std::string generated_kml_file;
|
||||||
|
|
||||||
private:
|
|
||||||
void geodetic2Ecef(const double latitude, const double longitude, const double altitude,
|
|
||||||
double* x, double* y, double* z);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -521,29 +521,41 @@ void StaticPositionSystemTest::check_results()
|
|||||||
double sum__u = std::accumulate(pos_u.begin(), pos_u.end(), 0.0);
|
double sum__u = std::accumulate(pos_u.begin(), pos_u.end(), 0.0);
|
||||||
double mean__u = sum__u / pos_u.size();
|
double mean__u = sum__u / pos_u.size();
|
||||||
|
|
||||||
|
std::stringstream stm;
|
||||||
|
std::ofstream position_test_file;
|
||||||
|
|
||||||
if(FLAGS_config_file_ptest.empty())
|
if(FLAGS_config_file_ptest.empty())
|
||||||
{
|
{
|
||||||
std::cout << "---- ACCURACY ----" << std::endl;
|
stm << "---- ACCURACY ----" << std::endl;
|
||||||
std::cout << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
|
stm << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
|
||||||
std::cout << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
|
stm << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
|
||||||
std::cout << "CEP = " << 0.62 * compute_stdev_accuracy(pos_n, 0.0) + 0.56 * compute_stdev_accuracy(pos_e, 0.0) << " [m]" << std::endl;
|
stm << "CEP = " << 0.62 * compute_stdev_accuracy(pos_n, 0.0) + 0.56 * compute_stdev_accuracy(pos_e, 0.0) << " [m]" << std::endl;
|
||||||
std::cout << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
stm << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
||||||
std::cout << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
stm << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
||||||
std::cout << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
stm << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
||||||
std::cout << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
stm << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
|
||||||
std::cout << "Bias 2D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0)) << " [m]" << std::endl;
|
stm << "Bias 2D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0)) << " [m]" << std::endl;
|
||||||
std::cout << "Bias 3D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0) + std::pow(mean__u, 2.0)) << " [m]" << std::endl;
|
stm << "Bias 3D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0) + std::pow(mean__u, 2.0)) << " [m]" << std::endl;
|
||||||
std::cout << std::endl;
|
stm << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "---- PRECISION ----" << std::endl;
|
stm << "---- PRECISION ----" << std::endl;
|
||||||
std::cout << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
|
stm << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
|
||||||
std::cout << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
|
stm << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
|
||||||
std::cout << "CEP = " << 0.62 * compute_stdev_precision(pos_n) + 0.56 * compute_stdev_precision(pos_e) << " [m]" << std::endl;
|
stm << "CEP = " << 0.62 * compute_stdev_precision(pos_n) + 0.56 * compute_stdev_precision(pos_e) << " [m]" << std::endl;
|
||||||
std::cout << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
stm << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
||||||
std::cout << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
stm << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
||||||
std::cout << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
stm << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
||||||
std::cout << "SEP = " << 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
stm << "SEP = " << 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
|
||||||
|
|
||||||
|
std::cout << stm.rdbuf();
|
||||||
|
std::string output_filename = "position_test_output_" + StaticPositionSystemTest::generated_kml_file.erase(StaticPositionSystemTest::generated_kml_file.length() - 3,3) + "txt";
|
||||||
|
position_test_file.open(output_filename.c_str());
|
||||||
|
if(position_test_file.is_open())
|
||||||
|
{
|
||||||
|
position_test_file << stm.str();
|
||||||
|
position_test_file.close();
|
||||||
|
}
|
||||||
|
|
||||||
// Sanity Check
|
// Sanity Check
|
||||||
double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision);
|
double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision);
|
||||||
|
@ -359,96 +359,58 @@ void TfttGpsL1CATest::print_TTFF_report(const std::vector<double> & ttff_v, std:
|
|||||||
std::string default_str = "default";
|
std::string default_str = "default";
|
||||||
source = config_->property("SignalSource.implementation", default_str);
|
source = config_->property("SignalSource.implementation", default_str);
|
||||||
|
|
||||||
|
std::stringstream stm;
|
||||||
|
|
||||||
|
stm << "---------------------------" << std::endl;
|
||||||
|
stm << " Time-To-First-Fix Report" << std::endl;
|
||||||
|
stm << "---------------------------" << std::endl;
|
||||||
|
stm << "Initial receiver status: ";
|
||||||
|
if (read_ephemeris)
|
||||||
|
{
|
||||||
|
stm << "Hot start." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stm << "Cold start." << std::endl;
|
||||||
|
}
|
||||||
|
stm << "A-GNSS: ";
|
||||||
|
if (agnss && read_ephemeris)
|
||||||
|
{
|
||||||
|
stm << "Enabled." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stm << "Disabled." << std::endl;
|
||||||
|
}
|
||||||
|
stm << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): ";
|
||||||
|
for(double ttff_ : ttff) stm << ttff_ << " ";
|
||||||
|
stm << std::endl;
|
||||||
|
stm << "TTFF mean: " << mean << " [s]" << std::endl;
|
||||||
|
if (ttff.size() > 0)
|
||||||
|
{
|
||||||
|
stm << "TTFF max: " << *max_ttff << " [s]" << std::endl;
|
||||||
|
stm << "TTFF min: " << *min_ttff << " [s]" << std::endl;
|
||||||
|
}
|
||||||
|
stm << "TTFF stdev: " << stdev << " [s]" << std::endl;
|
||||||
|
stm << "Operating System: " << std::string(HOST_SYSTEM) << std::endl;
|
||||||
|
stm << "Navigation mode: " << "3D" << std::endl;
|
||||||
|
|
||||||
|
if(source.compare("UHD_Signal_Source"))
|
||||||
|
{
|
||||||
|
stm << "Source: File" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stm << "Source: Live" << std::endl;
|
||||||
|
}
|
||||||
|
stm << "---------------------------" << std::endl;
|
||||||
|
|
||||||
|
std::cout << stm.rdbuf();
|
||||||
if (ttff_report_file.is_open())
|
if (ttff_report_file.is_open())
|
||||||
{
|
{
|
||||||
ttff_report_file << "---------------------------" << std::endl;
|
ttff_report_file << stm.str();
|
||||||
ttff_report_file << " Time-To-First-Fix Report" << std::endl;
|
|
||||||
ttff_report_file << "---------------------------" << std::endl;
|
|
||||||
ttff_report_file << "Initial receiver status: ";
|
|
||||||
if (read_ephemeris)
|
|
||||||
{
|
|
||||||
ttff_report_file << "Hot start." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ttff_report_file << "Cold start." << std::endl;
|
|
||||||
}
|
|
||||||
ttff_report_file << "A-GNSS: ";
|
|
||||||
if (agnss && read_ephemeris)
|
|
||||||
{
|
|
||||||
ttff_report_file << "Enabled." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ttff_report_file << "Disabled." << std::endl;
|
|
||||||
}
|
|
||||||
ttff_report_file << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): ";
|
|
||||||
for(double ttff_ : ttff) ttff_report_file << ttff_ << " ";
|
|
||||||
ttff_report_file << std::endl;
|
|
||||||
ttff_report_file << "TTFF mean: " << mean << " [s]" << std::endl;
|
|
||||||
if (ttff.size() > 0)
|
|
||||||
{
|
|
||||||
ttff_report_file << "TTFF max: " << *max_ttff << " [s]" << std::endl;
|
|
||||||
ttff_report_file << "TTFF min: " << *min_ttff << " [s]" << std::endl;
|
|
||||||
}
|
|
||||||
ttff_report_file << "TTFF stdev: " << stdev << " [s]" << std::endl;
|
|
||||||
ttff_report_file << "Operating System: " << std::string(HOST_SYSTEM) << std::endl;
|
|
||||||
ttff_report_file << "Navigation mode: " << "3D" << std::endl;
|
|
||||||
|
|
||||||
if(source.compare("UHD_Signal_Source"))
|
|
||||||
{
|
|
||||||
ttff_report_file << "Source: File" << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ttff_report_file << "Source: Live" << std::endl;
|
|
||||||
}
|
|
||||||
ttff_report_file << "---------------------------" << std::endl;
|
|
||||||
}
|
|
||||||
ttff_report_file.close();
|
ttff_report_file.close();
|
||||||
std::cout << "---------------------------" << std::endl;
|
|
||||||
std::cout << " Time-To-First-Fix Report" << std::endl;
|
|
||||||
std::cout << "---------------------------" << std::endl;
|
|
||||||
std::cout << "Initial receiver status: ";
|
|
||||||
if (read_ephemeris)
|
|
||||||
{
|
|
||||||
std::cout << "Hot start." << std::endl;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Cold start." << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << "A-GNSS: ";
|
|
||||||
if (agnss && read_ephemeris)
|
|
||||||
{
|
|
||||||
std::cout << "Enabled." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Disabled." << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): ";
|
|
||||||
for(double ttff_ : ttff) std::cout << ttff_ << " ";
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << "TTFF mean: " << mean << " [s]" << std::endl;
|
|
||||||
if (ttff.size() > 0)
|
|
||||||
{
|
|
||||||
std::cout << "TTFF max: " << *max_ttff << " [s]" << std::endl;
|
|
||||||
std::cout << "TTFF min: " << *min_ttff << " [s]" << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << "TTFF stdev: " << stdev << " [s]" << std::endl;
|
|
||||||
std::cout << "Operating System: " << std::string(HOST_SYSTEM) << std::endl;
|
|
||||||
std::cout << "Navigation mode: " << "3D" << std::endl;
|
|
||||||
|
|
||||||
if(source.compare("UHD_Signal_Source"))
|
|
||||||
{
|
|
||||||
std::cout << "Source: File" << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Source: Live" << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << "---------------------------" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,13 +35,13 @@
|
|||||||
|
|
||||||
function plot_acq_grid_gsoc_glonass(sat)
|
function plot_acq_grid_gsoc_glonass(sat)
|
||||||
|
|
||||||
file=['acquisition_R_1G_sat_' num2str(sat) '_doppler_0.dat'];
|
file=['/archive/acquisition_R_1G_sat_' num2str(sat) '_doppler_0.dat'];
|
||||||
|
|
||||||
% sampling_freq_Hz=62316000
|
% sampling_freq_Hz=62316000
|
||||||
sampling_freq_Hz=31.75e6
|
sampling_freq_Hz=6.625e6
|
||||||
Doppler_max_Hz = 10000
|
Doppler_max_Hz = 10000
|
||||||
Doppler_min_Hz = -10000
|
Doppler_min_Hz = -10000
|
||||||
Doppler_step_Hz = 500
|
Doppler_step_Hz = 250
|
||||||
|
|
||||||
|
|
||||||
% read files
|
% read files
|
||||||
|
Loading…
Reference in New Issue
Block a user