1
0
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:
Gastd 2017-11-11 21:13:51 -02:00
commit e66457e438
14 changed files with 1323 additions and 167 deletions

View File

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

View 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

View 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.**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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