2018-06-19 07:15:46 +00:00
/*!
2018-07-10 16:43:36 +00:00
* \ file acq_performance_test . cc
2018-06-19 07:15:46 +00:00
* \ brief This class implements an acquisition performance test
* \ author Carles Fernandez - Prades , 2018. cfernandez ( at ) cttc . cat
*
*
2020-07-28 14:57:15 +00:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2018-06-19 07:15:46 +00:00
*
2020-12-30 12:35:06 +00:00
* GNSS - SDR is a Global Navigation Satellite System software - defined receiver .
2018-06-19 07:15:46 +00:00
* This file is part of GNSS - SDR .
*
2020-12-30 12:35:06 +00:00
* Copyright ( C ) 2010 - 2020 ( see AUTHORS file for a list of contributors )
2020-02-08 00:20:02 +00:00
* SPDX - License - Identifier : GPL - 3.0 - or - later
2018-06-19 07:15:46 +00:00
*
2020-07-28 14:57:15 +00:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2018-06-19 07:15:46 +00:00
*/
2019-08-31 09:37:29 +00:00
# include "GPS_L1_CA.h"
2018-12-09 21:00:09 +00:00
# include "acquisition_dump_reader.h"
# include "display.h"
# include "file_configuration.h"
2018-07-10 16:43:36 +00:00
# include "galileo_e1_pcps_ambiguous_acquisition.h"
# include "galileo_e5a_pcps_acquisition.h"
# include "glonass_l1_ca_pcps_acquisition.h"
# include "glonass_l2_ca_pcps_acquisition.h"
2020-11-03 19:51:57 +00:00
# include "gnss_block_interface.h"
2021-01-16 13:37:19 +00:00
# include "gnss_sdr_filesystem.h"
2018-12-09 21:00:09 +00:00
# include "gnss_sdr_valve.h"
# include "gnuplot_i.h"
# include "gps_l1_ca_pcps_acquisition.h"
# include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
2018-07-10 16:43:36 +00:00
# include "gps_l2_m_pcps_acquisition.h"
# include "gps_l5i_pcps_acquisition.h"
2018-09-07 12:36:11 +00:00
# include "in_memory_configuration.h"
2018-07-10 16:43:36 +00:00
# include "signal_generator_flags.h"
# include "test_flags.h"
# include "tracking_true_obs_reader.h"
# include "true_observables_reader.h"
2018-09-07 12:36:11 +00:00
# include <gnuradio/blocks/file_source.h>
# include <gnuradio/blocks/interleaved_char_to_complex.h>
2018-07-16 18:58:33 +00:00
# include <gnuradio/blocks/skiphead.h>
2018-12-09 21:00:09 +00:00
# include <gnuradio/top_block.h>
2019-07-17 13:56:30 +00:00
# include <pmt/pmt.h>
2024-04-29 06:27:33 +00:00
# include <cstdint>
# include <string>
2019-02-24 22:11:19 +00:00
# include <thread>
2019-02-11 17:38:42 +00:00
# include <utility>
2018-07-10 16:43:36 +00:00
2020-04-26 06:41:49 +00:00
# if HAS_GENERIC_LAMBDA
# else
2020-06-06 21:41:38 +00:00
# include <boost/bind/bind.hpp>
2020-04-26 06:41:49 +00:00
# endif
2021-10-30 03:43:22 +00:00
# if PMT_USES_BOOST_ANY
namespace wht = boost ;
# else
namespace wht = std ;
# endif
2019-06-12 18:39:29 +00:00
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
DEFINE_string ( config_file_ptest , std : : string ( " " ) , " File containing alternative configuration parameters for the acquisition performance test. " ) ;
DEFINE_string ( acq_test_input_file , std : : string ( " " ) , " File containing raw signal data, must be in int8_t format. The signal generator will not be used. " ) ;
2018-07-10 16:43:36 +00:00
DEFINE_string ( acq_test_implementation , std : : string ( " GPS_L1_CA_PCPS_Acquisition " ) , " Acquisition block implementation under test. Alternatives: GPS_L1_CA_PCPS_Acquisition, GPS_L1_CA_PCPS_Acquisition_Fine_Doppler, Galileo_E1_PCPS_Ambiguous_Acquisition, GLONASS_L1_CA_PCPS_Acquisition, GLONASS_L2_CA_PCPS_Acquisition, GPS_L2_M_PCPS_Acquisition, Galileo_E5a_Pcps_Acquisition, GPS_L5i_PCPS_Acquisition " ) ;
2018-06-29 18:43:09 +00:00
DEFINE_int32 ( acq_test_doppler_max , 5000 , " Maximum Doppler, in Hz " ) ;
DEFINE_int32 ( acq_test_doppler_step , 125 , " Doppler step, in Hz. " ) ;
2018-06-29 11:33:53 +00:00
DEFINE_int32 ( acq_test_coherent_time_ms , 1 , " Acquisition coherent time, in ms " ) ;
2018-07-13 09:50:31 +00:00
DEFINE_int32 ( acq_test_max_dwells , 1 , " Number of non-coherent integrations. " ) ;
DEFINE_bool ( acq_test_bit_transition_flag , false , " Bit transition flag. " ) ;
DEFINE_bool ( acq_test_make_two_steps , false , " Perform second step in a thinner grid. " ) ;
DEFINE_int32 ( acq_test_second_nbins , 4 , " If --acq_test_make_two_steps is set to true, this parameter sets the number of bins done in the acquisition refinement stage. " ) ;
DEFINE_int32 ( acq_test_second_doppler_step , 10 , " If --acq_test_make_two_steps is set to true, this parameter sets the Doppler step applied in the acquisition refinement stage, in Hz. " ) ;
2018-06-29 18:43:09 +00:00
DEFINE_int32 ( acq_test_signal_duration_s , 2 , " Generated signal duration, in s " ) ;
DEFINE_int32 ( acq_test_num_meas , 0 , " Number of measurements per run. 0 means the complete file. " ) ;
2018-08-24 10:34:36 +00:00
DEFINE_double ( acq_test_cn0_init , 30.0 , " Initial CN0, in dBHz. " ) ;
2018-06-29 18:43:09 +00:00
DEFINE_double ( acq_test_cn0_final , 45.0 , " Final CN0, in dBHz. " ) ;
DEFINE_double ( acq_test_cn0_step , 3.0 , " CN0 step, in dB. " ) ;
2018-07-12 22:16:57 +00:00
DEFINE_double ( acq_test_threshold_init , 3.0 , " Initial acquisition threshold " ) ;
DEFINE_double ( acq_test_threshold_final , 4.0 , " Final acquisition threshold " ) ;
DEFINE_double ( acq_test_threshold_step , 0.5 , " Acquisition threshold step " ) ;
2018-06-29 18:43:09 +00:00
DEFINE_double ( acq_test_pfa_init , 1e-5 , " Set initial threshold via probability of false alarm. Disable with -1.0 " ) ;
2018-06-29 11:33:53 +00:00
DEFINE_int32 ( acq_test_PRN , 1 , " PRN number of a present satellite " ) ;
DEFINE_int32 ( acq_test_fake_PRN , 33 , " PRN number of a non-present satellite " ) ;
2018-06-29 18:43:09 +00:00
DEFINE_int32 ( acq_test_iterations , 1 , " Number of iterations (same signal, different noise realization) " ) ;
2018-06-29 11:33:53 +00:00
DEFINE_bool ( plot_acq_test , false , " Plots results with gnuplot, if available " ) ;
2018-07-16 18:58:33 +00:00
DEFINE_int32 ( acq_test_skiphead , 0 , " Number of samples to skip in the input file " ) ;
2024-04-29 06:27:33 +00:00
# else
ABSL_FLAG ( std : : string , config_file_ptest , std : : string ( " " ) , " File containing alternative configuration parameters for the acquisition performance test. " ) ;
ABSL_FLAG ( std : : string , acq_test_input_file , std : : string ( " " ) , " File containing raw signal data, must be in int8_t format. The signal generator will not be used. " ) ;
ABSL_FLAG ( std : : string , acq_test_implementation , std : : string ( " GPS_L1_CA_PCPS_Acquisition " ) , " Acquisition block implementation under test. Alternatives: GPS_L1_CA_PCPS_Acquisition, GPS_L1_CA_PCPS_Acquisition_Fine_Doppler, Galileo_E1_PCPS_Ambiguous_Acquisition, GLONASS_L1_CA_PCPS_Acquisition, GLONASS_L2_CA_PCPS_Acquisition, GPS_L2_M_PCPS_Acquisition, Galileo_E5a_Pcps_Acquisition, GPS_L5i_PCPS_Acquisition " ) ;
ABSL_FLAG ( int32_t , acq_test_doppler_max , 5000 , " Maximum Doppler, in Hz " ) ;
ABSL_FLAG ( int32_t , acq_test_doppler_step , 125 , " Doppler step, in Hz. " ) ;
ABSL_FLAG ( int32_t , acq_test_coherent_time_ms , 1 , " Acquisition coherent time, in ms " ) ;
ABSL_FLAG ( int32_t , acq_test_max_dwells , 1 , " Number of non-coherent integrations. " ) ;
ABSL_FLAG ( bool , acq_test_bit_transition_flag , false , " Bit transition flag. " ) ;
ABSL_FLAG ( bool , acq_test_make_two_steps , false , " Perform second step in a thinner grid. " ) ;
ABSL_FLAG ( int32_t , acq_test_second_nbins , 4 , " If --acq_test_make_two_steps is set to true, this parameter sets the number of bins done in the acquisition refinement stage. " ) ;
ABSL_FLAG ( int32_t , acq_test_second_doppler_step , 10 , " If --acq_test_make_two_steps is set to true, this parameter sets the Doppler step applied in the acquisition refinement stage, in Hz. " ) ;
ABSL_FLAG ( int32_t , acq_test_signal_duration_s , 2 , " Generated signal duration, in s " ) ;
ABSL_FLAG ( int32_t , acq_test_num_meas , 0 , " Number of measurements per run. 0 means the complete file. " ) ;
ABSL_FLAG ( double , acq_test_cn0_init , 30.0 , " Initial CN0, in dBHz. " ) ;
ABSL_FLAG ( double , acq_test_cn0_final , 45.0 , " Final CN0, in dBHz. " ) ;
ABSL_FLAG ( double , acq_test_cn0_step , 3.0 , " CN0 step, in dB. " ) ;
ABSL_FLAG ( double , acq_test_threshold_init , 3.0 , " Initial acquisition threshold " ) ;
ABSL_FLAG ( double , acq_test_threshold_final , 4.0 , " Final acquisition threshold " ) ;
ABSL_FLAG ( double , acq_test_threshold_step , 0.5 , " Acquisition threshold step " ) ;
ABSL_FLAG ( double , acq_test_pfa_init , 1e-5 , " Set initial threshold via probability of false alarm. Disable with -1.0 " ) ;
ABSL_FLAG ( int32_t , acq_test_PRN , 1 , " PRN number of a present satellite " ) ;
ABSL_FLAG ( int32_t , acq_test_fake_PRN , 33 , " PRN number of a non-present satellite " ) ;
ABSL_FLAG ( int32_t , acq_test_iterations , 1 , " Number of iterations (same signal, different noise realization) " ) ;
ABSL_FLAG ( bool , plot_acq_test , false , " Plots results with gnuplot, if available " ) ;
ABSL_FLAG ( int32_t , acq_test_skiphead , 0 , " Number of samples to skip in the input file " ) ;
# endif
2018-06-19 07:15:46 +00:00
// ######## GNURADIO BLOCK MESSAGE RECEVER #########
2018-06-21 07:53:47 +00:00
class AcqPerfTest_msg_rx ;
2018-06-24 22:56:11 +00:00
2020-11-03 19:51:57 +00:00
using AcqPerfTest_msg_rx_sptr = gnss_shared_ptr < AcqPerfTest_msg_rx > ;
2018-06-24 22:56:11 +00:00
2019-02-22 14:57:15 +00:00
AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make ( Concurrent_Queue < int > & queue ) ;
2018-06-24 22:56:11 +00:00
2018-06-21 07:53:47 +00:00
class AcqPerfTest_msg_rx : public gr : : block
{
private :
2019-02-22 14:57:15 +00:00
friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make ( Concurrent_Queue < int > & queue ) ;
2020-08-03 06:13:21 +00:00
void msg_handler_channel_events ( const pmt : : pmt_t msg ) ;
2019-08-23 19:25:44 +00:00
explicit AcqPerfTest_msg_rx ( Concurrent_Queue < int > & queue ) ;
2019-02-22 14:57:15 +00:00
Concurrent_Queue < int > & channel_internal_queue ;
2018-06-21 07:53:47 +00:00
public :
int rx_message ;
2018-06-24 22:56:11 +00:00
~ AcqPerfTest_msg_rx ( ) ;
2018-06-21 07:53:47 +00:00
} ;
2019-02-22 14:57:15 +00:00
AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make ( Concurrent_Queue < int > & queue )
2018-06-21 07:53:47 +00:00
{
2018-06-24 08:53:12 +00:00
return AcqPerfTest_msg_rx_sptr ( new AcqPerfTest_msg_rx ( queue ) ) ;
2018-06-21 07:53:47 +00:00
}
2020-08-03 06:13:21 +00:00
void AcqPerfTest_msg_rx : : msg_handler_channel_events ( const pmt : : pmt_t msg )
2018-06-21 07:53:47 +00:00
{
try
{
2019-02-11 17:38:42 +00:00
int64_t message = pmt : : to_long ( std : : move ( msg ) ) ;
2018-06-21 07:53:47 +00:00
rx_message = message ;
2018-06-24 08:53:12 +00:00
channel_internal_queue . push ( rx_message ) ;
2018-06-21 07:53:47 +00:00
}
2021-10-30 03:43:22 +00:00
catch ( const wht : : bad_any_cast & e )
2018-06-21 07:53:47 +00:00
{
2020-08-03 06:13:21 +00:00
LOG ( WARNING ) < < " msg_handler_channel_events Bad any_cast: " < < e . what ( ) ;
2018-06-21 07:53:47 +00:00
rx_message = 0 ;
}
}
2019-02-22 14:57:15 +00:00
AcqPerfTest_msg_rx : : AcqPerfTest_msg_rx ( Concurrent_Queue < int > & queue ) : gr : : block ( " AcqPerfTest_msg_rx " , gr : : io_signature : : make ( 0 , 0 , 0 ) , gr : : io_signature : : make ( 0 , 0 , 0 ) ) , channel_internal_queue ( queue )
2018-06-21 07:53:47 +00:00
{
this - > message_port_register_in ( pmt : : mp ( " events " ) ) ;
2020-04-25 21:03:44 +00:00
this - > set_msg_handler ( pmt : : mp ( " events " ) ,
2020-04-26 07:10:53 +00:00
# if HAS_GENERIC_LAMBDA
2020-08-03 06:13:21 +00:00
[ this ] ( auto & & PH1 ) { msg_handler_channel_events ( PH1 ) ; } ) ;
2020-04-25 21:03:44 +00:00
# else
2020-06-12 22:32:40 +00:00
# if USE_BOOST_BIND_PLACEHOLDERS
2020-08-03 06:13:21 +00:00
boost : : bind ( & AcqPerfTest_msg_rx : : msg_handler_channel_events , this , boost : : placeholders : : _1 ) ) ;
2020-05-18 20:50:34 +00:00
# else
2020-08-03 06:13:21 +00:00
boost : : bind ( & AcqPerfTest_msg_rx : : msg_handler_channel_events , this , _1 ) ) ;
2020-05-18 20:50:34 +00:00
# endif
2020-04-25 21:03:44 +00:00
# endif
2018-06-21 07:53:47 +00:00
rx_message = 0 ;
}
2019-02-11 20:13:02 +00:00
AcqPerfTest_msg_rx : : ~ AcqPerfTest_msg_rx ( ) = default ;
2018-06-21 07:53:47 +00:00
// -----------------------------------------
2018-06-19 07:15:46 +00:00
class AcquisitionPerformanceTest : public : : testing : : Test
{
protected :
AcquisitionPerformanceTest ( )
{
config = std : : make_shared < InMemoryConfiguration > ( ) ;
item_size = sizeof ( gr_complex ) ;
gnss_synchro = Gnss_Synchro ( ) ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
doppler_max = static_cast < unsigned int > ( FLAGS_acq_test_doppler_max ) ;
doppler_step = static_cast < unsigned int > ( FLAGS_acq_test_doppler_step ) ;
2024-04-29 06:27:33 +00:00
# else
doppler_max = static_cast < unsigned int > ( absl : : GetFlag ( FLAGS_acq_test_doppler_max ) ) ;
doppler_step = static_cast < unsigned int > ( absl : : GetFlag ( FLAGS_acq_test_doppler_step ) ) ;
# endif
2018-06-24 08:53:12 +00:00
stop = false ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
if ( FLAGS_acq_test_input_file . empty ( ) )
{
cn0_vector . push_back ( FLAGS_acq_test_cn0_init ) ;
double aux = FLAGS_acq_test_cn0_init + FLAGS_acq_test_cn0_step ;
while ( aux < = FLAGS_acq_test_cn0_final )
{
cn0_vector . push_back ( aux ) ;
aux = aux + FLAGS_acq_test_cn0_step ;
}
}
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_input_file ) . empty ( ) )
{
cn0_vector . push_back ( absl : : GetFlag ( FLAGS_acq_test_cn0_init ) ) ;
double aux = absl : : GetFlag ( FLAGS_acq_test_cn0_init ) + absl : : GetFlag ( FLAGS_acq_test_cn0_step ) ;
while ( aux < = absl : : GetFlag ( FLAGS_acq_test_cn0_final ) )
{
cn0_vector . push_back ( aux ) ;
aux = aux + absl : : GetFlag ( FLAGS_acq_test_cn0_step ) ;
}
}
# endif
2018-06-29 18:43:09 +00:00
else
{
cn0_vector = { 0.0 } ;
}
2018-07-10 16:43:36 +00:00
2019-02-11 17:38:42 +00:00
if ( implementation = = " GPS_L1_CA_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
signal_id = " 1C " ;
system_id = ' G ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-12 22:16:57 +00:00
min_integration_ms = 1 ;
2018-07-10 16:43:36 +00:00
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GPS_L1_CA_PCPS_Acquisition_Fine_Doppler " )
2018-07-10 16:43:36 +00:00
{
signal_id = " 1C " ;
system_id = ' G ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-12 22:16:57 +00:00
min_integration_ms = 1 ;
2018-07-10 16:43:36 +00:00
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " Galileo_E1_PCPS_Ambiguous_Acquisition " )
2018-07-10 16:43:36 +00:00
{
signal_id = " 1B " ;
system_id = ' E ' ;
2018-07-12 22:16:57 +00:00
min_integration_ms = 4 ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
if ( FLAGS_acq_test_coherent_time_ms = = 1 )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) = = 1 )
# endif
2018-07-11 12:51:34 +00:00
{
coherent_integration_time_ms = 4 ;
}
else
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-11 12:51:34 +00:00
}
2018-07-10 16:43:36 +00:00
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GLONASS_L1_CA_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
signal_id = " 1G " ;
system_id = ' R ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-12 22:16:57 +00:00
min_integration_ms = 1 ;
2018-07-10 16:43:36 +00:00
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GLONASS_L2_CA_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
signal_id = " 2G " ;
system_id = ' R ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-12 22:16:57 +00:00
min_integration_ms = 1 ;
2018-07-10 16:43:36 +00:00
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GPS_L2_M_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
signal_id = " 2S " ;
system_id = ' G ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
if ( FLAGS_acq_test_coherent_time_ms = = 1 )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) = = 1 )
# endif
2018-07-11 12:51:34 +00:00
{
coherent_integration_time_ms = 20 ;
}
else
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-11 12:51:34 +00:00
}
2018-07-12 22:16:57 +00:00
min_integration_ms = 20 ;
2018-07-10 16:43:36 +00:00
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " Galileo_E5a_Pcps_Acquisition " )
2018-07-10 16:43:36 +00:00
{
signal_id = " 5X " ;
system_id = ' E ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-12 22:16:57 +00:00
min_integration_ms = 1 ;
2018-07-10 16:43:36 +00:00
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GPS_L5i_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
signal_id = " L5 " ;
system_id = ' G ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-10 16:43:36 +00:00
}
else
{
signal_id = " 1C " ;
system_id = ' G ' ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-11 12:51:34 +00:00
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms ;
2024-04-29 06:27:33 +00:00
# else
coherent_integration_time_ms = absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) ;
# endif
2018-07-12 22:16:57 +00:00
min_integration_ms = 1 ;
2018-07-10 16:43:36 +00:00
}
2018-06-24 08:53:12 +00:00
init ( ) ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
if ( FLAGS_acq_test_pfa_init > 0.0 )
2018-06-29 11:33:53 +00:00
{
2018-06-29 18:43:09 +00:00
pfa_vector . push_back ( FLAGS_acq_test_pfa_init ) ;
float aux = 1.0 ;
while ( ( FLAGS_acq_test_pfa_init * std : : pow ( 10 , aux ) ) < 1 )
{
pfa_vector . push_back ( FLAGS_acq_test_pfa_init * std : : pow ( 10 , aux ) ) ;
aux = aux + 1.0 ;
}
2021-12-28 18:15:43 +00:00
pfa_vector . push_back ( 0.999 ) ;
2018-06-29 11:33:53 +00:00
}
2018-06-29 18:43:09 +00:00
else
{
2019-02-11 17:38:42 +00:00
auto aux = static_cast < float > ( FLAGS_acq_test_threshold_init ) ;
2018-06-29 18:43:09 +00:00
pfa_vector . push_back ( aux ) ;
aux = aux + static_cast < float > ( FLAGS_acq_test_threshold_step ) ;
while ( aux < = static_cast < float > ( FLAGS_acq_test_threshold_final ) )
{
pfa_vector . push_back ( aux ) ;
aux = aux + static_cast < float > ( FLAGS_acq_test_threshold_step ) ;
}
}
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_pfa_init ) > 0.0 )
{
pfa_vector . push_back ( absl : : GetFlag ( FLAGS_acq_test_pfa_init ) ) ;
float aux = 1.0 ;
while ( ( absl : : GetFlag ( FLAGS_acq_test_pfa_init ) * std : : pow ( 10 , aux ) ) < 1 )
{
pfa_vector . push_back ( absl : : GetFlag ( FLAGS_acq_test_pfa_init ) * std : : pow ( 10 , aux ) ) ;
aux = aux + 1.0 ;
}
pfa_vector . push_back ( 0.999 ) ;
}
else
{
auto aux = static_cast < float > ( absl : : GetFlag ( FLAGS_acq_test_threshold_init ) ) ;
pfa_vector . push_back ( aux ) ;
aux = aux + static_cast < float > ( absl : : GetFlag ( FLAGS_acq_test_threshold_step ) ) ;
while ( aux < = static_cast < float > ( absl : : GetFlag ( FLAGS_acq_test_threshold_final ) ) )
{
pfa_vector . push_back ( aux ) ;
aux = aux + static_cast < float > ( absl : : GetFlag ( FLAGS_acq_test_threshold_step ) ) ;
}
}
# endif
2018-06-29 18:43:09 +00:00
2018-06-29 11:33:53 +00:00
num_thresholds = pfa_vector . size ( ) ;
2018-06-29 18:43:09 +00:00
2021-12-17 14:40:46 +00:00
// the gnss simulator does not dump the trk observables for the last 100 ms of generated signal
2021-12-21 11:39:41 +00:00
int aux2 ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2021-12-21 11:39:41 +00:00
if ( FLAGS_acq_test_bit_transition_flag )
{
aux2 = floor ( ( generated_signal_duration_s * ms_per_s - 100 ) / ( FLAGS_acq_test_coherent_time_ms * 2.0 ) - 1 ) ;
}
else
{
aux2 = floor ( ( generated_signal_duration_s * ms_per_s - 100 ) / ( FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells ) - 1 ) ;
}
2021-12-28 18:15:43 +00:00
if ( ( FLAGS_acq_test_num_meas > 0 ) & & ( FLAGS_acq_test_num_meas < aux2 ) )
2018-06-29 18:43:09 +00:00
{
num_of_measurements = static_cast < unsigned int > ( FLAGS_acq_test_num_meas ) ;
}
else
{
num_of_measurements = static_cast < unsigned int > ( aux2 ) ;
}
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_bit_transition_flag ) )
{
aux2 = floor ( ( generated_signal_duration_s * ms_per_s - 100 ) / ( absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) * 2.0 ) - 1 ) ;
}
else
{
aux2 = floor ( ( generated_signal_duration_s * ms_per_s - 100 ) / ( absl : : GetFlag ( FLAGS_acq_test_coherent_time_ms ) * absl : : GetFlag ( FLAGS_acq_test_max_dwells ) ) - 1 ) ;
}
if ( ( absl : : GetFlag ( FLAGS_acq_test_num_meas ) > 0 ) & & ( absl : : GetFlag ( FLAGS_acq_test_num_meas ) < aux2 ) )
{
num_of_measurements = static_cast < unsigned int > ( absl : : GetFlag ( FLAGS_acq_test_num_meas ) ) ;
}
else
{
num_of_measurements = static_cast < unsigned int > ( aux2 ) ;
}
# endif
2018-06-29 11:33:53 +00:00
Pd . resize ( cn0_vector . size ( ) ) ;
2019-02-11 20:13:02 +00:00
for ( int i = 0 ; i < static_cast < int > ( cn0_vector . size ( ) ) ; i + + )
{
Pd [ i ] . reserve ( num_thresholds ) ;
}
2018-06-29 11:33:53 +00:00
Pfa . resize ( cn0_vector . size ( ) ) ;
2019-02-11 20:13:02 +00:00
for ( int i = 0 ; i < static_cast < int > ( cn0_vector . size ( ) ) ; i + + )
{
Pfa [ i ] . reserve ( num_thresholds ) ;
}
2018-06-29 11:33:53 +00:00
Pd_correct . resize ( cn0_vector . size ( ) ) ;
2019-02-11 20:13:02 +00:00
for ( int i = 0 ; i < static_cast < int > ( cn0_vector . size ( ) ) ; i + + )
{
Pd_correct [ i ] . reserve ( num_thresholds ) ;
}
2018-06-19 07:15:46 +00:00
}
2019-02-11 20:13:02 +00:00
~ AcquisitionPerformanceTest ( ) = default ;
2018-06-19 07:15:46 +00:00
2018-06-29 18:43:09 +00:00
std : : vector < double > cn0_vector ;
2018-06-29 11:33:53 +00:00
std : : vector < float > pfa_vector ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-27 06:07:42 +00:00
int N_iterations = FLAGS_acq_test_iterations ;
2024-04-29 06:27:33 +00:00
# else
int N_iterations = absl : : GetFlag ( FLAGS_acq_test_iterations ) ;
# endif
2018-06-19 07:15:46 +00:00
void init ( ) ;
int configure_generator ( double cn0 ) ;
int generate_signal ( ) ;
2018-06-26 06:43:22 +00:00
int configure_receiver ( double cn0 , float pfa , unsigned int iter ) ;
2018-06-24 08:53:12 +00:00
void start_queue ( ) ;
void wait_message ( ) ;
void process_message ( ) ;
void stop_queue ( ) ;
2018-06-19 07:15:46 +00:00
int run_receiver ( ) ;
2018-06-24 22:56:11 +00:00
int count_executions ( const std : : string & basename , unsigned int sat ) ;
2018-06-19 07:15:46 +00:00
void check_results ( ) ;
2018-06-28 14:30:36 +00:00
void plot_results ( ) ;
2018-06-24 08:53:12 +00:00
2019-02-22 14:57:15 +00:00
Concurrent_Queue < int > channel_internal_queue ;
2018-06-24 08:53:12 +00:00
2019-07-16 15:41:12 +00:00
std : : shared_ptr < Concurrent_Queue < pmt : : pmt_t > > queue ;
2018-06-19 07:15:46 +00:00
gr : : top_block_sptr top_block ;
2018-07-05 19:33:08 +00:00
std : : shared_ptr < AcquisitionInterface > acquisition ;
2018-06-24 08:53:12 +00:00
std : : shared_ptr < InMemoryConfiguration > config ;
std : : shared_ptr < FileConfiguration > config_f ;
2018-06-19 07:15:46 +00:00
Gnss_Synchro gnss_synchro ;
size_t item_size ;
unsigned int doppler_max ;
unsigned int doppler_step ;
2018-06-24 08:53:12 +00:00
bool stop ;
int message ;
2019-02-24 22:11:19 +00:00
std : : thread ch_thread ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-04 11:05:44 +00:00
std : : string implementation = FLAGS_acq_test_implementation ;
2018-06-22 10:24:39 +00:00
const double baseband_sampling_freq = static_cast < double > ( FLAGS_fs_gen_sps ) ;
2024-04-29 06:27:33 +00:00
# else
std : : string implementation = absl : : GetFlag ( FLAGS_acq_test_implementation ) ;
const double baseband_sampling_freq = static_cast < double > ( absl : : GetFlag ( FLAGS_fs_gen_sps ) ) ;
# endif
2018-07-11 12:51:34 +00:00
int coherent_integration_time_ms ;
2018-06-24 08:53:12 +00:00
const int in_acquisition = 1 ;
2018-06-24 22:56:11 +00:00
const int dump_channel = 0 ;
2018-06-24 08:53:12 +00:00
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-24 22:56:11 +00:00
int generated_signal_duration_s = FLAGS_acq_test_signal_duration_s ;
2024-04-29 06:27:33 +00:00
# else
int generated_signal_duration_s = absl : : GetFlag ( FLAGS_acq_test_signal_duration_s ) ;
# endif
2018-06-29 18:43:09 +00:00
unsigned int num_of_measurements ;
unsigned int measurement_counter = 0 ;
2018-06-19 07:15:46 +00:00
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-24 22:56:11 +00:00
unsigned int observed_satellite = FLAGS_acq_test_PRN ;
2024-04-29 06:27:33 +00:00
# else
unsigned int observed_satellite = absl : : GetFlag ( FLAGS_acq_test_PRN ) ;
# endif
2018-06-26 06:43:22 +00:00
std : : string path_str = " ./acq-perf-test " ;
2018-06-29 11:33:53 +00:00
int num_thresholds ;
2018-07-12 22:16:57 +00:00
unsigned int min_integration_ms ;
2018-06-26 06:43:22 +00:00
std : : vector < std : : vector < float > > Pd ;
std : : vector < std : : vector < float > > Pfa ;
2018-06-27 06:07:42 +00:00
std : : vector < std : : vector < float > > Pd_correct ;
2018-06-26 06:43:22 +00:00
2018-07-10 16:43:36 +00:00
std : : string signal_id ;
2018-06-19 07:15:46 +00:00
private :
2021-12-17 14:40:46 +00:00
static const uint32_t ms_per_s = 1000 ;
2018-06-19 07:15:46 +00:00
std : : string generator_binary ;
std : : string p1 ;
std : : string p2 ;
std : : string p3 ;
std : : string p4 ;
std : : string p5 ;
std : : string p6 ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-19 07:15:46 +00:00
std : : string filename_rinex_obs = FLAGS_filename_rinex_obs ;
std : : string filename_raw_data = FLAGS_filename_raw_data ;
2024-04-29 06:27:33 +00:00
# else
std : : string filename_rinex_obs = absl : : GetFlag ( FLAGS_filename_rinex_obs ) ;
std : : string filename_raw_data = absl : : GetFlag ( FLAGS_filename_raw_data ) ;
# endif
2018-07-10 16:43:36 +00:00
char system_id ;
2018-06-19 07:15:46 +00:00
double compute_stdev_precision ( const std : : vector < double > & vec ) ;
double compute_stdev_accuracy ( const std : : vector < double > & vec , double ref ) ;
} ;
void AcquisitionPerformanceTest : : init ( )
{
gnss_synchro . Channel_ID = 0 ;
2018-07-10 16:43:36 +00:00
gnss_synchro . System = system_id ;
std : : string signal = signal_id ;
2018-06-19 07:15:46 +00:00
signal . copy ( gnss_synchro . Signal , 2 , 0 ) ;
2018-06-24 22:56:11 +00:00
gnss_synchro . PRN = observed_satellite ;
2018-06-24 08:53:12 +00:00
message = 0 ;
2018-06-29 18:43:09 +00:00
measurement_counter = 0 ;
2018-06-24 08:53:12 +00:00
}
void AcquisitionPerformanceTest : : start_queue ( )
{
stop = false ;
2019-02-24 22:11:19 +00:00
ch_thread = std : : thread ( & AcquisitionPerformanceTest : : wait_message , this ) ;
2018-06-24 08:53:12 +00:00
}
void AcquisitionPerformanceTest : : wait_message ( )
{
while ( ! stop )
{
channel_internal_queue . wait_and_pop ( message ) ;
process_message ( ) ;
}
}
void AcquisitionPerformanceTest : : process_message ( )
{
2018-06-29 18:43:09 +00:00
measurement_counter + + ;
2018-06-24 22:56:11 +00:00
acquisition - > reset ( ) ;
2018-07-05 19:33:08 +00:00
acquisition - > set_state ( 1 ) ;
2018-06-29 18:43:09 +00:00
std : : cout < < " Progress: " < < round ( static_cast < float > ( measurement_counter ) / static_cast < float > ( num_of_measurements ) * 100.0 ) < < " % \r " < < std : : flush ;
if ( measurement_counter = = num_of_measurements )
2018-06-24 08:53:12 +00:00
{
stop_queue ( ) ;
top_block - > stop ( ) ;
}
}
void AcquisitionPerformanceTest : : stop_queue ( )
{
stop = true ;
2018-06-19 07:15:46 +00:00
}
int AcquisitionPerformanceTest : : configure_generator ( double cn0 )
{
// Configure signal generator
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-19 07:15:46 +00:00
generator_binary = FLAGS_generator_binary ;
p1 = std : : string ( " -rinex_nav_file= " ) + FLAGS_rinex_nav_file ;
if ( FLAGS_dynamic_position . empty ( ) )
{
2018-06-24 08:53:12 +00:00
p2 = std : : string ( " -static_position= " ) + FLAGS_static_position + std : : string ( " , " ) + std : : to_string ( std : : min ( generated_signal_duration_s * 10 , 3000 ) ) ;
2018-06-19 07:15:46 +00:00
}
else
{
p2 = std : : string ( " -obs_pos_file= " ) + std : : string ( FLAGS_dynamic_position ) ;
}
p3 = std : : string ( " -rinex_obs_file= " ) + FLAGS_filename_rinex_obs ; // RINEX 2.10 observation file output
p4 = std : : string ( " -sig_out_file= " ) + FLAGS_filename_raw_data ; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples
p5 = std : : string ( " -sampling_freq= " ) + std : : to_string ( baseband_sampling_freq ) ; // Baseband sampling frequency [MSps]
p6 = std : : string ( " -CN0_dBHz= " ) + std : : to_string ( cn0 ) ;
2024-04-29 06:27:33 +00:00
# else
generator_binary = absl : : GetFlag ( FLAGS_generator_binary ) ;
p1 = std : : string ( " -rinex_nav_file= " ) + absl : : GetFlag ( FLAGS_rinex_nav_file ) ;
if ( absl : : GetFlag ( FLAGS_dynamic_position ) . empty ( ) )
{
p2 = std : : string ( " -static_position= " ) + absl : : GetFlag ( FLAGS_static_position ) + std : : string ( " , " ) + std : : to_string ( std : : min ( generated_signal_duration_s * 10 , 3000 ) ) ;
}
else
{
p2 = std : : string ( " -obs_pos_file= " ) + std : : string ( absl : : GetFlag ( FLAGS_dynamic_position ) ) ;
}
p3 = std : : string ( " -rinex_obs_file= " ) + absl : : GetFlag ( FLAGS_filename_rinex_obs ) ; // RINEX 2.10 observation file output
p4 = std : : string ( " -sig_out_file= " ) + absl : : GetFlag ( FLAGS_filename_raw_data ) ; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples
p5 = std : : string ( " -sampling_freq= " ) + std : : to_string ( baseband_sampling_freq ) ; // Baseband sampling frequency [MSps]
p6 = std : : string ( " -CN0_dBHz= " ) + std : : to_string ( cn0 ) ;
# endif
2018-06-19 07:15:46 +00:00
return 0 ;
}
int AcquisitionPerformanceTest : : generate_signal ( )
{
pid_t wait_result ;
int child_status ;
2020-07-07 16:53:50 +00:00
std : : cout < < " Generating signal for " < < p6 < < " ... \n " ;
2019-02-11 17:38:42 +00:00
char * const parmList [ ] = { & generator_binary [ 0 ] , & generator_binary [ 0 ] , & p1 [ 0 ] , & p2 [ 0 ] , & p3 [ 0 ] , & p4 [ 0 ] , & p5 [ 0 ] , & p6 [ 0 ] , nullptr } ;
2018-06-19 07:15:46 +00:00
int pid ;
if ( ( pid = fork ( ) ) = = - 1 )
2019-02-11 20:13:02 +00:00
{
perror ( " fork error " ) ;
}
2018-06-19 07:15:46 +00:00
else if ( pid = = 0 )
{
execv ( & generator_binary [ 0 ] , parmList ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " Return not expected. Must be an execv error. \n " ;
2018-06-19 07:15:46 +00:00
std : : terminate ( ) ;
}
wait_result = waitpid ( pid , & child_status , 0 ) ;
2019-02-11 20:13:02 +00:00
if ( wait_result = = - 1 )
{
perror ( " waitpid error " ) ;
}
2018-06-19 07:15:46 +00:00
return 0 ;
}
2018-06-26 06:43:22 +00:00
int AcquisitionPerformanceTest : : configure_receiver ( double cn0 , float pfa , unsigned int iter )
2018-06-19 07:15:46 +00:00
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-19 07:15:46 +00:00
if ( FLAGS_config_file_ptest . empty ( ) )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_config_file_ptest ) . empty ( ) )
# endif
2018-06-19 07:15:46 +00:00
{
config = std : : make_shared < InMemoryConfiguration > ( ) ;
const int sampling_rate_internal = baseband_sampling_freq ;
config - > set_property ( " GNSS-SDR.internal_fs_sps " , std : : to_string ( sampling_rate_internal ) ) ;
// Set Acquisition
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.implementation " , implementation ) ;
config - > set_property ( " Acquisition.item_type " , " gr_complex " ) ;
config - > set_property ( " Acquisition.doppler_max " , std : : to_string ( doppler_max ) ) ;
config - > set_property ( " Acquisition.doppler_min " , std : : to_string ( - doppler_max ) ) ;
config - > set_property ( " Acquisition.doppler_step " , std : : to_string ( doppler_step ) ) ;
config - > set_property ( " Acquisition.threshold " , std : : to_string ( pfa ) ) ;
2019-08-18 23:29:04 +00:00
// if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition.pfa", std::to_string(pfa));
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
if ( FLAGS_acq_test_pfa_init > 0.0 )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_pfa_init ) > 0.0 )
# endif
2018-06-29 18:43:09 +00:00
{
2018-07-10 16:43:36 +00:00
config - > supersede_property ( " Acquisition.pfa " , std : : to_string ( pfa ) ) ;
2018-06-29 18:43:09 +00:00
}
2018-06-19 07:15:46 +00:00
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.coherent_integration_time_ms " , std : : to_string ( coherent_integration_time_ms ) ) ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-24 22:56:11 +00:00
if ( FLAGS_acq_test_bit_transition_flag )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_bit_transition_flag ) )
# endif
2018-06-24 22:56:11 +00:00
{
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.bit_transition_flag " , " true " ) ;
2018-06-24 22:56:11 +00:00
}
else
{
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.bit_transition_flag " , " false " ) ;
2018-06-24 22:56:11 +00:00
}
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.max_dwells " , std : : to_string ( FLAGS_acq_test_max_dwells ) ) ;
2024-04-29 06:27:33 +00:00
# else
config - > set_property ( " Acquisition.max_dwells " , std : : to_string ( absl : : GetFlag ( FLAGS_acq_test_max_dwells ) ) ) ;
# endif
2018-06-19 07:15:46 +00:00
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.repeat_satellite " , " true " ) ;
2018-06-19 07:15:46 +00:00
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.blocking " , " true " ) ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-13 09:50:31 +00:00
if ( FLAGS_acq_test_make_two_steps )
{
config - > set_property ( " Acquisition.make_two_steps " , " true " ) ;
config - > set_property ( " Acquisition.second_nbins " , std : : to_string ( FLAGS_acq_test_second_nbins ) ) ;
config - > set_property ( " Acquisition.second_doppler_step " , std : : to_string ( FLAGS_acq_test_second_doppler_step ) ) ;
}
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_make_two_steps ) )
{
config - > set_property ( " Acquisition.make_two_steps " , " true " ) ;
config - > set_property ( " Acquisition.second_nbins " , std : : to_string ( absl : : GetFlag ( FLAGS_acq_test_second_nbins ) ) ) ;
config - > set_property ( " Acquisition.second_doppler_step " , std : : to_string ( absl : : GetFlag ( FLAGS_acq_test_second_doppler_step ) ) ) ;
}
# endif
2018-07-13 09:50:31 +00:00
else
{
config - > set_property ( " Acquisition.make_two_steps " , " false " ) ;
}
2021-12-04 17:07:25 +00:00
config - > set_property ( " Acquisition.dump " , " true " ) ;
2018-06-24 22:56:11 +00:00
2021-10-30 03:43:22 +00:00
// std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa);
std : : string dump_file = path_str + std : : string ( " /acquisition_ " ) + std : : to_string ( static_cast < int > ( cn0 ) ) + " _ " + std : : to_string ( iter ) + " _ " + std : : to_string ( static_cast < int > ( pfa * 1.0e5 ) ) ;
2018-07-10 16:43:36 +00:00
config - > set_property ( " Acquisition.dump_filename " , dump_file ) ;
config - > set_property ( " Acquisition.dump_channel " , std : : to_string ( dump_channel ) ) ;
config - > set_property ( " Acquisition.blocking_on_standby " , " true " ) ;
2018-06-19 07:15:46 +00:00
2019-02-11 17:38:42 +00:00
config_f = nullptr ;
2018-06-19 07:15:46 +00:00
}
else
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-19 07:15:46 +00:00
config_f = std : : make_shared < FileConfiguration > ( FLAGS_config_file_ptest ) ;
2024-04-29 06:27:33 +00:00
# else
config_f = std : : make_shared < FileConfiguration > ( absl : : GetFlag ( FLAGS_config_file_ptest ) ) ;
# endif
2019-02-11 17:38:42 +00:00
config = nullptr ;
2018-06-19 07:15:46 +00:00
}
return 0 ;
}
int AcquisitionPerformanceTest : : run_receiver ( )
2018-06-21 07:53:47 +00:00
{
2018-06-29 18:43:09 +00:00
std : : string file ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
if ( FLAGS_acq_test_input_file . empty ( ) )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_input_file ) . empty ( ) )
# endif
2018-06-29 18:43:09 +00:00
{
file = " ./ " + filename_raw_data ;
}
else
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
file = FLAGS_acq_test_input_file ;
2024-04-29 06:27:33 +00:00
# else
file = absl : : GetFlag ( FLAGS_acq_test_input_file ) ;
# endif
2018-06-29 18:43:09 +00:00
}
2018-06-21 07:53:47 +00:00
const char * file_name = file . c_str ( ) ;
gr : : blocks : : file_source : : sptr file_source = gr : : blocks : : file_source : : make ( sizeof ( int8_t ) , file_name , false ) ;
2018-06-24 08:53:12 +00:00
gr : : blocks : : interleaved_char_to_complex : : sptr gr_interleaved_char_to_complex = gr : : blocks : : interleaved_char_to_complex : : make ( ) ;
2018-06-21 07:53:47 +00:00
2018-06-24 08:53:12 +00:00
top_block = gr : : make_top_block ( " Acquisition test " ) ;
2020-04-02 21:59:35 +00:00
auto msg_rx = AcqPerfTest_msg_rx_make ( channel_internal_queue ) ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-16 18:58:33 +00:00
gr : : blocks : : skiphead : : sptr skiphead = gr : : blocks : : skiphead : : make ( sizeof ( gr_complex ) , FLAGS_acq_test_skiphead ) ;
2024-04-29 06:27:33 +00:00
# else
gr : : blocks : : skiphead : : sptr skiphead = gr : : blocks : : skiphead : : make ( sizeof ( gr_complex ) , absl : : GetFlag ( FLAGS_acq_test_skiphead ) ) ;
# endif
2018-06-21 07:53:47 +00:00
2019-07-17 13:56:30 +00:00
queue = std : : make_shared < Concurrent_Queue < pmt : : pmt_t > > ( ) ;
2018-06-24 08:53:12 +00:00
gnss_synchro = Gnss_Synchro ( ) ;
init ( ) ;
2018-06-24 22:56:11 +00:00
2018-06-24 08:53:12 +00:00
int nsamples = floor ( config - > property ( " GNSS-SDR.internal_fs_sps " , 2000000 ) * generated_signal_duration_s ) ;
2020-06-18 09:49:28 +00:00
auto valve = gnss_sdr_make_valve ( sizeof ( gr_complex ) , nsamples , queue . get ( ) ) ;
2019-02-11 17:38:42 +00:00
if ( implementation = = " GPS_L1_CA_PCPS_Acquisition " )
2018-07-04 11:05:44 +00:00
{
2018-07-10 16:43:36 +00:00
acquisition = std : : make_shared < GpsL1CaPcpsAcquisition > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GPS_L1_CA_PCPS_Acquisition_Fine_Doppler " )
2018-07-10 16:43:36 +00:00
{
acquisition = std : : make_shared < GpsL1CaPcpsAcquisitionFineDoppler > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " Galileo_E1_PCPS_Ambiguous_Acquisition " )
2018-07-10 16:43:36 +00:00
{
acquisition = std : : make_shared < GalileoE1PcpsAmbiguousAcquisition > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GLONASS_L1_CA_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
acquisition = std : : make_shared < GlonassL1CaPcpsAcquisition > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GLONASS_L2_CA_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
acquisition = std : : make_shared < GlonassL2CaPcpsAcquisition > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GPS_L2_M_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
acquisition = std : : make_shared < GpsL2MPcpsAcquisition > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " Galileo_E5a_Pcps_Acquisition " )
2018-07-10 16:43:36 +00:00
{
acquisition = std : : make_shared < GalileoE5aPcpsAcquisition > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
}
2019-02-11 17:38:42 +00:00
else if ( implementation = = " GPS_L5i_PCPS_Acquisition " )
2018-07-10 16:43:36 +00:00
{
acquisition = std : : make_shared < GpsL5iPcpsAcquisition > ( config . get ( ) , " Acquisition " , 1 , 0 ) ;
2018-07-04 11:05:44 +00:00
}
else
{
2018-07-10 16:43:36 +00:00
bool aux = false ;
EXPECT_EQ ( true , aux ) ;
2018-07-04 11:05:44 +00:00
}
2018-06-24 08:53:12 +00:00
acquisition - > set_gnss_synchro ( & gnss_synchro ) ;
acquisition - > set_channel ( 0 ) ;
2018-07-10 16:43:36 +00:00
acquisition - > set_doppler_max ( config - > property ( " Acquisition.doppler_max " , 10000 ) ) ;
acquisition - > set_doppler_step ( config - > property ( " Acquisition.doppler_step " , 500 ) ) ;
acquisition - > set_threshold ( config - > property ( " Acquisition.threshold " , 0.0 ) ) ;
2018-07-05 19:33:08 +00:00
acquisition - > init ( ) ;
acquisition - > set_local_code ( ) ;
acquisition - > set_state ( 1 ) ; // Ensure that acquisition starts at the first sample
2018-06-24 08:53:12 +00:00
acquisition - > connect ( top_block ) ;
2018-07-05 08:51:23 +00:00
acquisition - > reset ( ) ;
2018-06-24 08:53:12 +00:00
top_block - > connect ( file_source , 0 , gr_interleaved_char_to_complex , 0 ) ;
2018-07-16 18:58:33 +00:00
top_block - > connect ( gr_interleaved_char_to_complex , 0 , skiphead , 0 ) ;
top_block - > connect ( skiphead , 0 , valve , 0 ) ;
2018-06-24 08:53:12 +00:00
top_block - > connect ( valve , 0 , acquisition - > get_left_block ( ) , 0 ) ;
2018-07-05 08:51:23 +00:00
top_block - > msg_connect ( acquisition - > get_right_block ( ) , pmt : : mp ( " events " ) , msg_rx , pmt : : mp ( " events " ) ) ;
2018-06-24 22:56:11 +00:00
2018-06-24 08:53:12 +00:00
start_queue ( ) ;
2018-06-24 22:56:11 +00:00
2018-06-24 08:53:12 +00:00
top_block - > run ( ) ; // Start threads and wait
2018-06-24 22:56:11 +00:00
2019-02-24 22:11:19 +00:00
ch_thread . join ( ) ;
2018-06-21 07:53:47 +00:00
return 0 ;
}
2018-06-24 22:56:11 +00:00
int AcquisitionPerformanceTest : : count_executions ( const std : : string & basename , unsigned int sat )
{
FILE * fp ;
2018-06-29 11:33:53 +00:00
std : : string argum2 = std : : string ( " /usr/bin/find " ) + path_str + std : : string ( " -maxdepth 1 -name " ) + basename . substr ( path_str . length ( ) + 1 , basename . length ( ) - path_str . length ( ) ) + std : : string ( " * | grep sat_ " ) + std : : to_string ( sat ) + std : : string ( " | wc -l " ) ;
2018-06-24 22:56:11 +00:00
char buffer [ 1024 ] ;
fp = popen ( & argum2 [ 0 ] , " r " ) ;
int num_executions = 1 ;
2019-02-11 17:38:42 +00:00
if ( fp = = nullptr )
2018-06-24 22:56:11 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Failed to run command: " < < argum2 < < ' \n ' ;
2018-06-24 22:56:11 +00:00
return 0 ;
}
2019-02-11 17:38:42 +00:00
while ( fgets ( buffer , sizeof ( buffer ) , fp ) ! = nullptr )
2018-06-24 22:56:11 +00:00
{
std : : string aux = std : : string ( buffer ) ;
EXPECT_EQ ( aux . empty ( ) , false ) ;
num_executions = std : : stoi ( aux ) ;
}
pclose ( fp ) ;
return num_executions ;
}
2018-06-28 14:30:36 +00:00
void AcquisitionPerformanceTest : : plot_results ( )
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-28 14:30:36 +00:00
if ( FLAGS_plot_acq_test = = true )
{
const std : : string gnuplot_executable ( FLAGS_gnuplot_executable ) ;
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_plot_acq_test ) = = true )
{
const std : : string gnuplot_executable ( absl : : GetFlag ( FLAGS_gnuplot_executable ) ) ;
# endif
2018-06-28 14:30:36 +00:00
if ( gnuplot_executable . empty ( ) )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE, \n " ;
std : : cout < < " gnuplot has not been found in your system. \n " ;
std : : cout < < " Test results will not be plotted. \n " ;
2018-06-28 14:30:36 +00:00
}
else
{
try
{
2019-06-10 19:41:13 +00:00
fs : : path p ( gnuplot_executable ) ;
fs : : path dir = p . parent_path ( ) ;
2019-02-11 17:38:42 +00:00
const std : : string & gnuplot_path = dir . native ( ) ;
2018-06-28 14:30:36 +00:00
Gnuplot : : set_GNUPlotPath ( gnuplot_path ) ;
Gnuplot g1 ( " linespoints " ) ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-05 19:33:08 +00:00
if ( FLAGS_show_plots )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_show_plots ) )
# endif
2018-07-05 19:33:08 +00:00
{
g1 . showonscreen ( ) ; // window output
}
else
{
g1 . disablescreen ( ) ;
}
2018-06-29 18:43:09 +00:00
g1 . cmd ( " set font \" Times,18 \" " ) ;
g1 . set_title ( " Receiver Operating Characteristic for GPS L1 C/A acquisition " ) ;
2019-02-11 17:38:42 +00:00
g1 . cmd ( " set label 1 \" " + std : : string ( " Coherent integration time: " ) + std : : to_string ( config - > property ( " Acquisition.coherent_integration_time_ms " , 1 ) ) + " ms, Non-coherent integrations: " + std : : to_string ( config - > property ( " Acquisition.max_dwells " , 1 ) ) + R " ( " at screen 0.12 , 0.83 font " Times,16 " ) " );
2018-06-28 14:30:36 +00:00
g1 . cmd ( " set logscale x " ) ;
g1 . cmd ( " set yrange [0:1] " ) ;
2018-06-29 18:43:09 +00:00
g1 . cmd ( " set xrange[0.0001:1] " ) ;
g1 . cmd ( " set grid mxtics " ) ;
g1 . cmd ( " set grid ytics " ) ;
2018-06-28 14:30:36 +00:00
g1 . set_xlabel ( " Pfa " ) ;
g1 . set_ylabel ( " Pd " ) ;
2018-06-29 11:33:53 +00:00
g1 . set_grid ( ) ;
g1 . cmd ( " show grid " ) ;
for ( int i = 0 ; i < static_cast < int > ( cn0_vector . size ( ) ) ; i + + )
2018-06-28 14:30:36 +00:00
{
std : : vector < float > Pd_i ;
std : : vector < float > Pfa_i ;
for ( int k = 0 ; k < num_thresholds ; k + + )
{
Pd_i . push_back ( Pd [ i ] [ k ] ) ;
2021-10-30 03:43:22 +00:00
Pfa_i . push_back ( pfa_vector [ k ] ) ;
2018-06-28 14:30:36 +00:00
}
2018-06-29 11:33:53 +00:00
g1 . plot_xy ( Pfa_i , Pd_i , " CN0 = " + std : : to_string ( static_cast < int > ( cn0_vector [ i ] ) ) + " dBHz " ) ;
2018-06-28 14:30:36 +00:00
}
g1 . set_legend ( ) ;
g1 . savetops ( " ROC " ) ;
g1 . savetopdf ( " ROC " , 18 ) ;
2018-06-29 11:33:53 +00:00
Gnuplot g2 ( " linespoints " ) ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-07-05 19:33:08 +00:00
if ( FLAGS_show_plots )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_show_plots ) )
# endif
2018-07-05 19:33:08 +00:00
{
g2 . showonscreen ( ) ; // window output
}
else
{
g2 . disablescreen ( ) ;
}
2018-06-29 18:43:09 +00:00
g2 . cmd ( " set font \" Times,18 \" " ) ;
g2 . set_title ( " Receiver Operating Characteristic for GPS L1 C/A valid acquisition " ) ;
2019-02-11 17:38:42 +00:00
g2 . cmd ( " set label 1 \" " + std : : string ( " Coherent integration time: " ) + std : : to_string ( config - > property ( " Acquisition.coherent_integration_time_ms " , 1 ) ) + " ms, Non-coherent integrations: " + std : : to_string ( config - > property ( " Acquisition.max_dwells " , 1 ) ) + R " ( " at screen 0.12 , 0.83 font " Times,16 " ) " );
2018-06-29 11:33:53 +00:00
g2 . cmd ( " set logscale x " ) ;
g2 . cmd ( " set yrange [0:1] " ) ;
2018-06-29 18:43:09 +00:00
g2 . cmd ( " set xrange[0.0001:1] " ) ;
g2 . cmd ( " set grid mxtics " ) ;
g2 . cmd ( " set grid ytics " ) ;
2018-06-29 11:33:53 +00:00
g2 . set_xlabel ( " Pfa " ) ;
g2 . set_ylabel ( " Valid Pd " ) ;
g2 . set_grid ( ) ;
g2 . cmd ( " show grid " ) ;
for ( int i = 0 ; i < static_cast < int > ( cn0_vector . size ( ) ) ; i + + )
2018-06-28 14:30:36 +00:00
{
2018-06-29 11:33:53 +00:00
std : : vector < float > Pd_i_correct ;
std : : vector < float > Pfa_i ;
for ( int k = 0 ; k < num_thresholds ; k + + )
2018-06-28 14:30:36 +00:00
{
2018-06-29 11:33:53 +00:00
Pd_i_correct . push_back ( Pd_correct [ i ] [ k ] ) ;
2021-10-30 03:43:22 +00:00
Pfa_i . push_back ( pfa_vector [ k ] ) ;
2018-06-28 14:30:36 +00:00
}
2018-06-29 11:33:53 +00:00
g2 . plot_xy ( Pfa_i , Pd_i_correct , " CN0 = " + std : : to_string ( static_cast < int > ( cn0_vector [ i ] ) ) + " dBHz " ) ;
2018-06-28 14:30:36 +00:00
}
2018-06-29 11:33:53 +00:00
g2 . set_legend ( ) ;
g2 . savetops ( " ROC-valid-detection " ) ;
g2 . savetopdf ( " ROC-valid-detection " , 18 ) ;
2018-06-28 14:30:36 +00:00
}
catch ( const GnuplotException & ge )
{
2020-07-07 16:53:50 +00:00
std : : cout < < ge . what ( ) < < ' \n ' ;
2018-06-28 14:30:36 +00:00
}
}
}
}
TEST_F ( AcquisitionPerformanceTest , ROC )
2018-06-19 07:15:46 +00:00
{
2019-02-22 14:57:15 +00:00
Tracking_True_Obs_Reader true_trk_data ;
2018-06-26 06:43:22 +00:00
2019-06-10 19:41:13 +00:00
if ( fs : : exists ( path_str ) )
2018-06-26 06:43:22 +00:00
{
2021-10-30 03:43:22 +00:00
std : : cout < < " Deleting old files at " < < path_str < < " ... \n " ;
2019-06-10 19:41:13 +00:00
fs : : remove_all ( path_str ) ;
2018-06-26 06:43:22 +00:00
}
2019-06-10 19:41:13 +00:00
errorlib : : error_code ec ;
ASSERT_TRUE ( fs : : create_directory ( path_str , ec ) ) < < " Could not create the " < < path_str < < " folder. " ;
2018-06-27 06:07:42 +00:00
2018-06-26 06:43:22 +00:00
unsigned int cn0_index = 0 ;
2019-02-11 17:38:42 +00:00
for ( double it : cn0_vector )
2018-06-19 07:15:46 +00:00
{
2018-06-26 06:43:22 +00:00
std : : vector < double > meas_Pd_ ;
std : : vector < double > meas_Pd_correct_ ;
std : : vector < double > meas_Pfa_ ;
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2019-02-11 20:13:02 +00:00
if ( FLAGS_acq_test_input_file . empty ( ) )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_input_file ) . empty ( ) )
# endif
2019-02-11 20:13:02 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Execution for CN0 = " < < it < < " dB-Hz \n " ;
2019-02-11 20:13:02 +00:00
}
2018-06-29 11:33:53 +00:00
// Do N_iterations of the experiment
for ( int pfa_iter = 0 ; pfa_iter < static_cast < int > ( pfa_vector . size ( ) ) ; pfa_iter + + )
2018-06-27 06:07:42 +00:00
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-29 18:43:09 +00:00
if ( FLAGS_acq_test_pfa_init > 0.0 )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_pfa_init ) > 0.0 )
# endif
2018-06-29 18:43:09 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Setting threshold for Pfa = " < < pfa_vector [ pfa_iter ] < < ' \n ' ;
2018-06-29 18:43:09 +00:00
}
else
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Setting threshold to " < < pfa_vector [ pfa_iter ] < < ' \n ' ;
2018-06-29 18:43:09 +00:00
}
2024-04-29 06:27:33 +00:00
// Configure the signal generator
# if USE_GLOG_AND_GFLAGS
2019-02-11 20:13:02 +00:00
if ( FLAGS_acq_test_input_file . empty ( ) )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_input_file ) . empty ( ) )
# endif
2019-02-11 20:13:02 +00:00
{
configure_generator ( it ) ;
}
2018-06-29 18:43:09 +00:00
2018-06-27 06:07:42 +00:00
for ( int iter = 0 ; iter < N_iterations ; iter + + )
2018-06-21 17:26:46 +00:00
{
2024-04-29 06:27:33 +00:00
// Generate signal raw signal samples and observations RINEX file
# if USE_GLOG_AND_GFLAGS
2019-02-11 20:13:02 +00:00
if ( FLAGS_acq_test_input_file . empty ( ) )
2024-04-29 06:27:33 +00:00
# else
if ( absl : : GetFlag ( FLAGS_acq_test_input_file ) . empty ( ) )
# endif
2019-02-11 20:13:02 +00:00
{
generate_signal ( ) ;
}
2018-06-22 10:24:39 +00:00
2018-06-26 06:43:22 +00:00
for ( unsigned k = 0 ; k < 2 ; k + + )
2018-06-22 10:24:39 +00:00
{
2018-06-26 06:43:22 +00:00
if ( k = = 0 )
2018-06-24 22:56:11 +00:00
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-26 06:43:22 +00:00
observed_satellite = FLAGS_acq_test_PRN ;
2024-04-29 06:27:33 +00:00
# else
observed_satellite = absl : : GetFlag ( FLAGS_acq_test_PRN ) ;
# endif
2018-06-24 22:56:11 +00:00
}
else
{
2024-04-29 06:27:33 +00:00
# if USE_GLOG_AND_GFLAGS
2018-06-26 06:43:22 +00:00
observed_satellite = FLAGS_acq_test_fake_PRN ;
2024-04-29 06:27:33 +00:00
# else
observed_satellite = absl : : GetFlag ( FLAGS_acq_test_fake_PRN ) ;
# endif
2018-06-24 22:56:11 +00:00
}
2018-06-26 06:43:22 +00:00
init ( ) ;
2018-06-24 22:56:11 +00:00
2018-06-26 06:43:22 +00:00
// Configure the receiver
2019-02-11 17:38:42 +00:00
configure_receiver ( it , pfa_vector [ pfa_iter ] , iter ) ;
2018-06-22 10:24:39 +00:00
2018-06-26 06:43:22 +00:00
// Run it
run_receiver ( ) ;
2018-06-22 10:24:39 +00:00
2018-06-26 06:43:22 +00:00
// count executions
2021-12-04 17:07:25 +00:00
std : : string basename = path_str + std : : string ( " /acquisition_ " ) + std : : to_string ( static_cast < int > ( it ) ) + " _ " + std : : to_string ( iter ) + " _ " + std : : to_string ( static_cast < int > ( pfa_vector [ pfa_iter ] * 1.0e5 ) ) + " _ " + gnss_synchro . System + " _ " + gnss_synchro . Signal ;
2018-06-26 06:43:22 +00:00
int num_executions = count_executions ( basename , observed_satellite ) ;
2018-06-22 10:24:39 +00:00
2018-06-26 06:43:22 +00:00
// Read measured data
2018-07-10 16:43:36 +00:00
int ch = config - > property ( " Acquisition.dump_channel " , 0 ) ;
2018-06-26 06:43:22 +00:00
arma : : vec meas_timestamp_s = arma : : zeros ( num_executions , 1 ) ;
arma : : vec meas_doppler = arma : : zeros ( num_executions , 1 ) ;
arma : : vec positive_acq = arma : : zeros ( num_executions , 1 ) ;
arma : : vec meas_acq_delay_chips = arma : : zeros ( num_executions , 1 ) ;
2018-07-10 16:43:36 +00:00
double coh_time_ms = config - > property ( " Acquisition.coherent_integration_time_ms " , 1 ) ;
2018-06-26 06:43:22 +00:00
2020-07-07 16:53:50 +00:00
std : : cout < < " Num executions: " < < num_executions < < ' \n ' ;
2018-07-12 22:16:57 +00:00
unsigned int fft_size = 0 ;
unsigned int d_consumed_samples = coh_time_ms * config - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) * 0.001 ; // * (config->property("Acquisition.bit_transition_flag", false) ? 2 : 1);
if ( coh_time_ms = = min_integration_ms )
{
fft_size = d_consumed_samples ;
}
else
{
fft_size = d_consumed_samples * 2 ;
}
2018-06-26 06:43:22 +00:00
for ( int execution = 1 ; execution < = num_executions ; execution + + )
2018-06-24 22:56:11 +00:00
{
2019-02-22 14:57:15 +00:00
Acquisition_Dump_Reader acq_dump ( basename ,
2018-07-12 22:16:57 +00:00
observed_satellite ,
config - > property ( " Acquisition.doppler_max " , 0 ) ,
config - > property ( " Acquisition.doppler_step " , 0 ) ,
fft_size ,
ch ,
execution ) ;
2018-06-26 06:43:22 +00:00
acq_dump . read_binary_acq ( ) ;
if ( acq_dump . positive_acq )
2018-06-24 22:56:11 +00:00
{
2020-07-07 16:53:50 +00:00
// std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD_S / GPS_L1_CA_CODE_LENGTH_CHIPS) << '\n';
2018-06-26 06:43:22 +00:00
meas_timestamp_s ( execution - 1 ) = acq_dump . sample_counter / baseband_sampling_freq ;
meas_doppler ( execution - 1 ) = acq_dump . acq_doppler_hz ;
2019-08-31 09:37:29 +00:00
meas_acq_delay_chips ( execution - 1 ) = acq_dump . acq_delay_samples / ( baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD_S / GPS_L1_CA_CODE_LENGTH_CHIPS ) ;
2018-06-26 06:43:22 +00:00
positive_acq ( execution - 1 ) = acq_dump . positive_acq ;
2018-06-24 22:56:11 +00:00
}
2018-06-26 06:43:22 +00:00
else
2018-06-24 22:56:11 +00:00
{
2020-07-07 16:53:50 +00:00
// std::cout << "Failed acquisition.\n";
2018-06-26 06:43:22 +00:00
meas_timestamp_s ( execution - 1 ) = arma : : datum : : inf ;
meas_doppler ( execution - 1 ) = arma : : datum : : inf ;
meas_acq_delay_chips ( execution - 1 ) = arma : : datum : : inf ;
positive_acq ( execution - 1 ) = acq_dump . positive_acq ;
2018-06-24 22:56:11 +00:00
}
}
2018-06-26 06:43:22 +00:00
// Read reference data
std : : string true_trk_file = std : : string ( " ./gps_l1_ca_obs_prn " ) ;
true_trk_file . append ( std : : to_string ( observed_satellite ) ) ;
true_trk_file . append ( " .dat " ) ;
true_trk_data . close_obs_file ( ) ;
true_trk_data . open_obs_file ( true_trk_file ) ;
// load the true values
2018-08-10 19:16:10 +00:00
int64_t n_true_epochs = true_trk_data . num_epochs ( ) ;
2018-06-26 06:43:22 +00:00
arma : : vec true_timestamp_s = arma : : zeros ( n_true_epochs , 1 ) ;
arma : : vec true_acc_carrier_phase_cycles = arma : : zeros ( n_true_epochs , 1 ) ;
arma : : vec true_Doppler_Hz = arma : : zeros ( n_true_epochs , 1 ) ;
arma : : vec true_prn_delay_chips = arma : : zeros ( n_true_epochs , 1 ) ;
arma : : vec true_tow_s = arma : : zeros ( n_true_epochs , 1 ) ;
2018-08-10 19:16:10 +00:00
int64_t epoch_counter = 0 ;
2018-06-26 06:43:22 +00:00
int num_clean_executions = 0 ;
while ( true_trk_data . read_binary_obs ( ) )
2018-06-24 22:56:11 +00:00
{
2018-06-26 06:43:22 +00:00
true_timestamp_s ( epoch_counter ) = true_trk_data . signal_timestamp_s ;
true_acc_carrier_phase_cycles ( epoch_counter ) = true_trk_data . acc_carrier_phase_cycles ;
true_Doppler_Hz ( epoch_counter ) = true_trk_data . doppler_l1_hz ;
true_prn_delay_chips ( epoch_counter ) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data . prn_delay_chips ;
true_tow_s ( epoch_counter ) = true_trk_data . tow ;
epoch_counter + + ;
2020-07-07 16:53:50 +00:00
// std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << '\n';
2018-06-24 22:56:11 +00:00
}
2018-06-26 06:43:22 +00:00
// Process results
arma : : vec clean_doppler_estimation_error ;
arma : : vec clean_delay_estimation_error ;
2018-06-27 06:07:42 +00:00
2018-06-26 06:43:22 +00:00
if ( epoch_counter > 2 )
2018-06-24 22:56:11 +00:00
{
2018-06-26 06:43:22 +00:00
arma : : vec true_interpolated_doppler = arma : : zeros ( num_executions , 1 ) ;
arma : : vec true_interpolated_prn_delay_chips = arma : : zeros ( num_executions , 1 ) ;
interp1 ( true_timestamp_s , true_Doppler_Hz , meas_timestamp_s , true_interpolated_doppler ) ;
interp1 ( true_timestamp_s , true_prn_delay_chips , meas_timestamp_s , true_interpolated_prn_delay_chips ) ;
2018-06-24 22:56:11 +00:00
2018-06-26 06:43:22 +00:00
arma : : vec doppler_estimation_error = true_interpolated_doppler - meas_doppler ;
2019-08-31 09:37:29 +00:00
arma : : vec delay_estimation_error = true_interpolated_prn_delay_chips - ( meas_acq_delay_chips - ( ( 1.0 / baseband_sampling_freq ) / GPS_L1_CA_CHIP_PERIOD_S ) ) ; // compensate 1 sample delay
2018-06-26 06:43:22 +00:00
// Cut measurements without reference
2018-06-27 06:07:42 +00:00
for ( int i = 0 ; i < num_executions ; i + + )
2018-06-26 06:43:22 +00:00
{
2021-12-28 18:15:43 +00:00
if ( ! std : : isnan ( doppler_estimation_error ( i ) ) & & ! std : : isnan ( delay_estimation_error ( i ) ) )
2018-06-26 06:43:22 +00:00
{
num_clean_executions + + ;
}
}
clean_doppler_estimation_error = arma : : zeros ( num_clean_executions , 1 ) ;
clean_delay_estimation_error = arma : : zeros ( num_clean_executions , 1 ) ;
num_clean_executions = 0 ;
2018-06-27 06:07:42 +00:00
for ( int i = 0 ; i < num_executions ; i + + )
2018-06-26 06:43:22 +00:00
{
2021-12-28 18:15:43 +00:00
if ( ! std : : isnan ( doppler_estimation_error ( i ) ) & & ! std : : isnan ( delay_estimation_error ( i ) ) )
2018-06-26 06:43:22 +00:00
{
clean_doppler_estimation_error ( num_clean_executions ) = doppler_estimation_error ( i ) ;
clean_delay_estimation_error ( num_clean_executions ) = delay_estimation_error ( i ) ;
num_clean_executions + + ;
}
}
2018-06-29 11:33:53 +00:00
/* std::cout << "Doppler estimation error [Hz]: ";
2018-06-26 06:43:22 +00:00
for ( int i = 0 ; i < num_executions - 1 ; i + + )
{
std : : cout < < doppler_estimation_error ( i ) < < " " ;
}
2020-07-07 16:53:50 +00:00
std : : cout < < ' \n ' ;
2018-06-24 22:56:11 +00:00
2018-06-26 06:43:22 +00:00
std : : cout < < " Delay estimation error [chips]: " ;
for ( int i = 0 ; i < num_executions - 1 ; i + + )
{
std : : cout < < delay_estimation_error ( i ) < < " " ;
2018-06-29 11:33:53 +00:00
2018-06-26 06:43:22 +00:00
}
2020-07-07 16:53:50 +00:00
std : : cout < < ' \n ' ; */
2018-06-26 06:43:22 +00:00
}
if ( k = = 0 )
{
double detected = arma : : accu ( positive_acq ) ;
2018-06-27 06:07:42 +00:00
double computed_Pd = detected / static_cast < double > ( num_executions ) ;
if ( num_executions > 0 )
{
meas_Pd_ . push_back ( computed_Pd ) ;
}
else
{
meas_Pd_ . push_back ( 0.0 ) ;
}
2021-10-30 03:43:22 +00:00
std : : cout < < TEXT_BOLD_BLUE < < " Probability of detection for channel= " < < ch < < " , CN0= " < < it < < " dBHz "
2020-07-07 16:53:50 +00:00
< < " : " < < ( num_executions > 0 ? computed_Pd : 0.0 ) < < TEXT_RESET < < ' \n ' ;
2018-06-26 06:43:22 +00:00
}
if ( num_clean_executions > 0 )
2018-06-22 10:24:39 +00:00
{
2018-06-26 06:43:22 +00:00
arma : : vec correct_acq = arma : : zeros ( num_executions , 1 ) ;
double correctly_detected = 0.0 ;
2021-12-28 18:15:43 +00:00
for ( int i = 0 ; i < num_clean_executions ; i + + )
2018-06-24 22:56:11 +00:00
{
2021-12-28 18:15:43 +00:00
if ( abs ( clean_delay_estimation_error ( i ) ) < 0.5 & & abs ( clean_doppler_estimation_error ( i ) ) < static_cast < float > ( config - > property ( " Acquisition.doppler_step " , 1 ) ) )
2018-06-26 06:43:22 +00:00
{
correctly_detected = correctly_detected + 1.0 ;
}
2018-06-24 22:56:11 +00:00
}
2018-06-27 06:07:42 +00:00
double computed_Pd_correct = correctly_detected / static_cast < double > ( num_clean_executions ) ;
meas_Pd_correct_ . push_back ( computed_Pd_correct ) ;
2021-10-30 03:43:22 +00:00
std : : cout < < TEXT_BOLD_BLUE < < " Probability of correct detection for channel= " < < ch < < " , CN0= " < < it < < " dBHz "
2020-07-07 16:53:50 +00:00
< < " : " < < computed_Pd_correct < < TEXT_RESET < < ' \n ' ;
2018-06-22 10:24:39 +00:00
}
2018-06-26 06:43:22 +00:00
else
{
2020-07-07 16:53:50 +00:00
// std::cout << "No reference data has been found. Maybe a non-present satellite?" << num_executions << '\n';
2018-06-26 06:43:22 +00:00
if ( k = = 1 )
{
double wrongly_detected = arma : : accu ( positive_acq ) ;
2018-06-27 06:07:42 +00:00
double computed_Pfa = wrongly_detected / static_cast < double > ( num_executions ) ;
if ( num_executions > 0 )
{
meas_Pfa_ . push_back ( computed_Pfa ) ;
}
else
{
meas_Pfa_ . push_back ( 0.0 ) ;
}
2021-10-30 03:43:22 +00:00
std : : cout < < TEXT_BOLD_BLUE < < " Probability of false alarm for channel= " < < ch < < " , CN0= " < < it < < " dBHz "
2020-07-07 16:53:50 +00:00
< < " : " < < ( num_executions > 0 ? computed_Pfa : 0.0 ) < < TEXT_RESET < < ' \n ' ;
2018-06-26 06:43:22 +00:00
}
}
true_trk_data . restart ( ) ;
2018-06-22 10:24:39 +00:00
}
2018-06-27 06:07:42 +00:00
}
true_trk_data . close_obs_file ( ) ;
float sum_pd = static_cast < float > ( std : : accumulate ( meas_Pd_ . begin ( ) , meas_Pd_ . end ( ) , 0.0 ) ) ;
float sum_pd_correct = static_cast < float > ( std : : accumulate ( meas_Pd_correct_ . begin ( ) , meas_Pd_correct_ . end ( ) , 0.0 ) ) ;
float sum_pfa = static_cast < float > ( std : : accumulate ( meas_Pfa_ . begin ( ) , meas_Pfa_ . end ( ) , 0.0 ) ) ;
2021-12-28 18:15:43 +00:00
if ( ! meas_Pd_ . empty ( ) & & ! meas_Pfa_ . empty ( ) )
2018-06-27 06:07:42 +00:00
{
Pd [ cn0_index ] [ pfa_iter ] = sum_pd / static_cast < float > ( meas_Pd_ . size ( ) ) ;
Pfa [ cn0_index ] [ pfa_iter ] = sum_pfa / static_cast < float > ( meas_Pfa_ . size ( ) ) ;
}
else
{
2019-02-11 17:38:42 +00:00
if ( ! meas_Pd_ . empty ( ) )
2018-06-27 06:07:42 +00:00
{
Pd [ cn0_index ] [ pfa_iter ] = sum_pd / static_cast < float > ( meas_Pd_ . size ( ) ) ;
}
else
{
Pd [ cn0_index ] [ pfa_iter ] = 0.0 ;
}
2019-02-11 17:38:42 +00:00
if ( ! meas_Pfa_ . empty ( ) )
2018-06-27 06:07:42 +00:00
{
Pfa [ cn0_index ] [ pfa_iter ] = sum_pfa / static_cast < float > ( meas_Pfa_ . size ( ) ) ;
}
else
{
Pfa [ cn0_index ] [ pfa_iter ] = 0.0 ;
}
}
2019-02-11 17:38:42 +00:00
if ( ! meas_Pd_correct_ . empty ( ) )
2018-06-27 06:07:42 +00:00
{
Pd_correct [ cn0_index ] [ pfa_iter ] = sum_pd_correct / static_cast < float > ( meas_Pd_correct_ . size ( ) ) ;
}
else
{
Pd_correct [ cn0_index ] [ pfa_iter ] = 0.0 ;
2018-06-24 08:53:12 +00:00
}
2018-06-28 07:18:37 +00:00
meas_Pd_ . clear ( ) ;
meas_Pfa_ . clear ( ) ;
meas_Pd_correct_ . clear ( ) ;
2018-06-19 07:15:46 +00:00
}
2018-06-27 06:07:42 +00:00
cn0_index + + ;
2018-06-22 10:24:39 +00:00
}
2018-06-27 06:07:42 +00:00
// Compute results
2018-06-26 06:43:22 +00:00
unsigned int aux_index = 0 ;
2019-02-11 17:38:42 +00:00
for ( double it : cn0_vector )
2018-06-26 06:43:22 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Results for CN0 = " < < it < < " dBHz: \n " ;
2018-06-26 06:43:22 +00:00
std : : cout < < " Pd = " ;
2018-06-27 06:07:42 +00:00
for ( int pfa_iter = 0 ; pfa_iter < num_thresholds ; pfa_iter + + )
2018-06-26 06:43:22 +00:00
{
std : : cout < < Pd [ aux_index ] [ pfa_iter ] < < " " ;
}
2020-07-07 16:53:50 +00:00
std : : cout < < ' \n ' ;
2018-06-27 06:07:42 +00:00
std : : cout < < " Pd_correct = " ;
for ( int pfa_iter = 0 ; pfa_iter < num_thresholds ; pfa_iter + + )
{
std : : cout < < Pd_correct [ aux_index ] [ pfa_iter ] < < " " ;
}
2020-07-07 16:53:50 +00:00
std : : cout < < ' \n ' ;
2018-06-27 06:07:42 +00:00
std : : cout < < " Pfa = " ;
for ( int pfa_iter = 0 ; pfa_iter < num_thresholds ; pfa_iter + + )
{
std : : cout < < Pfa [ aux_index ] [ pfa_iter ] < < " " ;
}
2020-07-07 16:53:50 +00:00
std : : cout < < ' \n ' ;
2018-06-27 06:07:42 +00:00
2018-06-26 06:43:22 +00:00
aux_index + + ;
}
2018-06-28 14:30:36 +00:00
plot_results ( ) ;
2018-06-19 07:15:46 +00:00
}