diff --git a/src/algorithms/acquisition/CMakeLists.txt b/src/algorithms/acquisition/CMakeLists.txt index d91502f0f..579bf4ba0 100644 --- a/src/algorithms/acquisition/CMakeLists.txt +++ b/src/algorithms/acquisition/CMakeLists.txt @@ -18,5 +18,7 @@ add_subdirectory(adapters) add_subdirectory(gnuradio_blocks) -#add_subdirectory(libs) +if(ENABLE_FPGA) + add_subdirectory(libs) +endif(ENABLE_FPGA) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc index d6859919c..ef86f55e7 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc @@ -198,7 +198,7 @@ signed int GalileoE1Pcps8msAmbiguousAcquisition::mag() void GalileoE1Pcps8msAmbiguousAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index 6f184c25e..b3a57497c 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -234,7 +234,7 @@ void GalileoE1PcpsAmbiguousAcquisition::init() acquisition_cc_->init(); } - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc index 690e3879d..167857d61 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc @@ -200,7 +200,7 @@ signed int GalileoE1PcpsCccwsrAmbiguousAcquisition::mag() void GalileoE1PcpsCccwsrAmbiguousAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc index e6be855d2..46faec6b4 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc @@ -240,7 +240,7 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc index dae111573..476a4b2a9 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc @@ -204,7 +204,7 @@ signed int GalileoE1PcpsTongAmbiguousAcquisition::mag() void GalileoE1PcpsTongAmbiguousAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc index e7701a513..223e737f6 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc @@ -206,7 +206,7 @@ signed int GalileoE5aNoncoherentIQAcquisitionCaf::mag() void GalileoE5aNoncoherentIQAcquisitionCaf::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index 8ae477856..2531cb8d3 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -230,7 +230,7 @@ void GpsL1CaPcpsAcquisition::init() acquisition_cc_->init(); } - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc index 254e71369..5f448e456 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc @@ -136,7 +136,7 @@ signed int GpsL1CaPcpsAcquisitionFineDoppler::mag() void GpsL1CaPcpsAcquisitionFineDoppler::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index 48dd946cb..ecbbfb3d9 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -34,18 +34,28 @@ #include "gps_l1_ca_pcps_acquisition_fpga.h" #include #include -#include "gps_sdr_signal_processing.h" #include "GPS_L1_CA.h" #include "configuration_interface.h" - using google::LogMessage; GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : - role_(role), in_streams_(in_streams), out_streams_(out_streams) + role_(role), in_streams_(in_streams), out_streams_(out_streams) { + unsigned int code_length; + bool bit_transition_flag; + bool use_CFAR_algorithm_flag; + unsigned int sampled_ms; + long fs_in; + long ifreq; + bool dump; + std::string dump_filename; + unsigned int nsamples_total; + unsigned int select_queue_Fpga; + std::string device_name; + configuration_ = configuration; std::string default_item_type = "cshort"; @@ -53,59 +63,69 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( DLOG(INFO) << "role " << role; - item_type_ = configuration_->property(role + ".item_type", default_item_type); + item_type_ = configuration_->property(role + ".item_type", + default_item_type); - fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); - if_ = configuration_->property(role + ".if", 0); - dump_ = configuration_->property(role + ".dump", false); + fs_in = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); + ifreq = configuration_->property(role + ".if", 0); + dump = configuration_->property(role + ".dump", false); doppler_max_ = configuration_->property(role + ".doppler_max", 5000); - sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); + sampled_ms = configuration_->property( + role + ".coherent_integration_time_ms", 1); // note : the FPGA is implemented according to bit transition flag = 0. Setting bit transition flag to 1 has no effect. - bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); + bit_transition_flag = configuration_->property( + role + ".bit_transition_flag", false); // note : the FPGA is implemented according to use_CFAR_algorithm = 0. Setting use_CFAR_algorithm to 1 has no effect. - use_CFAR_algorithm_flag_=configuration_->property(role + ".use_CFAR_algorithm", false); + use_CFAR_algorithm_flag = configuration_->property( + role + ".use_CFAR_algorithm", false); // note : the FPGA does not use the max_dwells variable. max_dwells_ = configuration_->property(role + ".max_dwells", 1); - dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); + dump_filename = configuration_->property(role + ".dump_filename", + default_dump_filename); //--- Find number of samples per spreading code ------------------------- - code_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); + code_length = round( + fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); // code length has the same value as d_fft_size - float nbits; - nbits = ceilf(log2f(code_length_)); - nsamples_total_ = pow(2,nbits); + float nbits; + nbits = ceilf(log2f(code_length)); + nsamples_total = pow(2, nbits); //vector_length_ = code_length_ * sampled_ms_; - vector_length_ = nsamples_total_ * sampled_ms_; + vector_length_ = nsamples_total * sampled_ms; + // if( bit_transition_flag_ ) + // { + // vector_length_ *= 2; + // } - if( bit_transition_flag_ ) - { - vector_length_ *= 2; - } + select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", + 0); - code_ = new gr_complex[vector_length_]; + std::string default_device_name = "/dev/uio0"; + device_name = configuration_->property(role + ".devicename", + default_device_name); - select_queue_Fpga_ = configuration_->property(role + ".select_queue_Fpga", 0); - - if (item_type_.compare("cshort") == 0 ) + if (item_type_.compare("cshort") == 0) { item_size_ = sizeof(lv_16sc_t); - gps_acquisition_fpga_sc_ = gps_pcps_make_acquisition_fpga_sc(sampled_ms_, max_dwells_, - doppler_max_, if_, fs_in_, code_length_, code_length_, vector_length_, - bit_transition_flag_, use_CFAR_algorithm_flag_, select_queue_Fpga_, dump_, dump_filename_); - DLOG(INFO) << "acquisition(" << gps_acquisition_fpga_sc_->unique_id() << ")"; - + gps_acquisition_fpga_sc_ = gps_pcps_make_acquisition_fpga_sc( + sampled_ms, max_dwells_, doppler_max_, ifreq, fs_in, + code_length, code_length, vector_length_, nsamples_total, + bit_transition_flag, use_CFAR_algorithm_flag, + select_queue_Fpga, device_name, dump, dump_filename); + DLOG(INFO) << "acquisition(" + << gps_acquisition_fpga_sc_->unique_id() << ")"; + } + else + { + LOG(FATAL) << item_type_ << " FPGA only accepts chsort"; } - else{ - LOG(FATAL) << item_type_ << " FPGA only accepts chsort"; - } - channel_ = 0; threshold_ = 0.0; @@ -116,16 +136,13 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( GpsL1CaPcpsAcquisitionFpga::~GpsL1CaPcpsAcquisitionFpga() { - delete[] code_; } void GpsL1CaPcpsAcquisitionFpga::set_channel(unsigned int channel) { channel_ = channel; - gps_acquisition_fpga_sc_->set_channel(channel_); - } @@ -133,7 +150,7 @@ void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold) { float pfa = configuration_->property(role_ + ".pfa", 0.0); - if(pfa == 0.0) + if (pfa == 0.0) { threshold_ = threshold; } @@ -143,101 +160,68 @@ void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold) } DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; - - gps_acquisition_fpga_sc_->set_threshold(threshold_); - } void GpsL1CaPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) { doppler_max_ = doppler_max; - gps_acquisition_fpga_sc_->set_doppler_max(doppler_max_); - } void GpsL1CaPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) { doppler_step_ = doppler_step; - gps_acquisition_fpga_sc_->set_doppler_step(doppler_step_); - } + void GpsL1CaPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) { gnss_synchro_ = gnss_synchro; - gps_acquisition_fpga_sc_->set_gnss_synchro(gnss_synchro_); } signed int GpsL1CaPcpsAcquisitionFpga::mag() { - - return gps_acquisition_fpga_sc_->mag(); + return gps_acquisition_fpga_sc_->mag(); } void GpsL1CaPcpsAcquisitionFpga::init() { - - gps_acquisition_fpga_sc_->init(); - + gps_acquisition_fpga_sc_->init(); set_local_code(); } void GpsL1CaPcpsAcquisitionFpga::set_local_code() { - - std::complex* code = new std::complex[vector_length_]; - - - //init to zeros for the zero padding of the fft - for (uint s=0;s(0, 0); - } - - gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_ , 0); - - for (unsigned int i = 0; i < sampled_ms_; i++) - { - memcpy(&(code_[i*vector_length_]), code, sizeof(gr_complex)*vector_length_); - - } - - gps_acquisition_fpga_sc_->set_local_code(code_); - - delete[] code; + gps_acquisition_fpga_sc_->set_local_code(); } void GpsL1CaPcpsAcquisitionFpga::reset() { - - gps_acquisition_fpga_sc_->set_active(true); - + gps_acquisition_fpga_sc_->set_active(true); } void GpsL1CaPcpsAcquisitionFpga::set_state(int state) { - - gps_acquisition_fpga_sc_->set_state(state); + gps_acquisition_fpga_sc_->set_state(state); } - float GpsL1CaPcpsAcquisitionFpga::calculate_threshold(float pfa) { //Calculate the threshold unsigned int frequency_bins = 0; - for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_) + for (int doppler = (int) (-doppler_max_); doppler <= (int) doppler_max_; + doppler += doppler_step_) { frequency_bins++; } @@ -246,39 +230,31 @@ float GpsL1CaPcpsAcquisitionFpga::calculate_threshold(float pfa) double exponent = 1 / static_cast(ncells); double val = pow(1.0 - pfa, exponent); double lambda = double(vector_length_); - boost::math::exponential_distribution mydist (lambda); - float threshold = (float)quantile(mydist,val); + boost::math::exponential_distribution mydist(lambda); + float threshold = (float) quantile(mydist, val); return threshold; } - void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) { - - //nothing to connect + //nothing to connect } void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) { - - //nothing to disconnect + //nothing to disconnect } gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block() { - - return gps_acquisition_fpga_sc_; - + return gps_acquisition_fpga_sc_; } gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_right_block() { - - return gps_acquisition_fpga_sc_; - + return gps_acquisition_fpga_sc_; } - diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index 95d7cc8dd..186d255e6 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -43,15 +43,13 @@ #include "complex_byte_to_float_x2.h" #include - - class ConfigurationInterface; /*! * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for GPS L1 C/A signals */ -class GpsL1CaPcpsAcquisitionFpga: public AcquisitionInterface +class GpsL1CaPcpsAcquisitionFpga : public AcquisitionInterface { public: GpsL1CaPcpsAcquisitionFpga(ConfigurationInterface* configuration, @@ -137,35 +135,19 @@ public: private: ConfigurationInterface* configuration_; gps_pcps_acquisition_fpga_sc_sptr gps_acquisition_fpga_sc_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; std::string item_type_; unsigned int vector_length_; - unsigned int code_length_; - bool bit_transition_flag_; - bool use_CFAR_algorithm_flag_; unsigned int channel_; float threshold_; unsigned int doppler_max_; unsigned int doppler_step_; - unsigned int sampled_ms_; unsigned int max_dwells_; - long fs_in_; - long if_; - bool dump_; - std::string dump_filename_; - std::complex * code_; Gnss_Synchro * gnss_synchro_; std::string role_; unsigned int in_streams_; unsigned int out_streams_; - unsigned int nsamples_total_; - - unsigned int select_queue_Fpga_; - float calculate_threshold(float pfa); }; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc index beb45c323..71feb0088 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc @@ -137,7 +137,7 @@ signed int GpsL1CaPcpsAssistedAcquisition::mag() void GpsL1CaPcpsAssistedAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } void GpsL1CaPcpsAssistedAcquisition::set_local_code() diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_multithread_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_multithread_acquisition.cc index 9bd8f8b3e..61f350eaa 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_multithread_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_multithread_acquisition.cc @@ -197,7 +197,7 @@ signed int GpsL1CaPcpsMultithreadAcquisition::mag() void GpsL1CaPcpsMultithreadAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc index ba2c6b68c..6dd529913 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc @@ -194,7 +194,7 @@ signed int GpsL1CaPcpsOpenClAcquisition::mag() void GpsL1CaPcpsOpenClAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc index f732b5aba..6ea3a8f9f 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc @@ -227,7 +227,7 @@ signed int GpsL1CaPcpsQuickSyncAcquisition::mag() void GpsL1CaPcpsQuickSyncAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc index e7a4bdb65..5fc39659b 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc @@ -186,7 +186,7 @@ signed int GpsL1CaPcpsTongAcquisition::mag() void GpsL1CaPcpsTongAcquisition::init() { acquisition_cc_->init(); - set_local_code(); + //set_local_code(); } void GpsL1CaPcpsTongAcquisition::set_local_code() diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index baf00ff1f..c77c86f54 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -233,7 +233,7 @@ void GpsL2MPcpsAcquisition::init() acquisition_cc_->init(); } - set_local_code(); + //set_local_code(); } diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt index 134db4b19..667e6f70f 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt @@ -67,7 +67,11 @@ add_library(acq_gr_blocks ${ACQ_GR_BLOCKS_SOURCES} ${ACQ_GR_BLOCKS_HEADERS}) source_group(Headers FILES ${ACQ_GR_BLOCKS_HEADERS}) #target_link_libraries(acq_gr_blocks gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} #target_link_libraries(acq_gr_blocks acquisition_lib gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_LIBRARIES} ${OPT_ACQUISITION_LIBRARIES}) -target_link_libraries(acq_gr_blocks gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_LIBRARIES} ${OPT_ACQUISITION_LIBRARIES}) +if(ENABLE_FPGA) + target_link_libraries(acq_gr_blocks acquisition_lib gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_LIBRARIES} ${OPT_ACQUISITION_LIBRARIES}) +else(ENABLE_FPGA) + target_link_libraries(acq_gr_blocks gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_LIBRARIES} ${OPT_ACQUISITION_LIBRARIES}) +endif(ENABLE_FPGA) if(NOT VOLK_GNSSSDR_FOUND) add_dependencies(acq_gr_blocks volk_gnsssdr_module) endif(NOT VOLK_GNSSSDR_FOUND) diff --git a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.cc b/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.cc index 7cb177ded..2d0833732 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.cc @@ -40,172 +40,87 @@ #include #include "control_message_factory.h" #include "GPS_L1_CA.h" //GPS_TWO_PI - using google::LogMessage; void wait3(int seconds) { - boost::this_thread::sleep_for(boost::chrono::seconds{seconds}); + boost::this_thread::sleep_for(boost::chrono::seconds + { seconds }); } gps_pcps_acquisition_fpga_sc_sptr gps_pcps_make_acquisition_fpga_sc( - unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long freq, long fs_in, - int samples_per_ms, int samples_per_code, int vector_length, - bool bit_transition_flag, bool use_CFAR_algorithm_flag, - unsigned int select_queue_Fpga, - bool dump, - std::string dump_filename) + unsigned int sampled_ms, unsigned int max_dwells, + unsigned int doppler_max, long freq, long fs_in, int samples_per_ms, + int samples_per_code, int vector_length, unsigned int nsamples_total, + bool bit_transition_flag, bool use_CFAR_algorithm_flag, + unsigned int select_queue_Fpga, std::string device_name, bool dump, + std::string dump_filename) { - return gps_pcps_acquisition_fpga_sc_sptr( - new gps_pcps_acquisition_fpga_sc(sampled_ms, max_dwells, doppler_max, freq, fs_in, samples_per_ms, - samples_per_code, vector_length, bit_transition_flag, use_CFAR_algorithm_flag, select_queue_Fpga, dump, dump_filename)); + new gps_pcps_acquisition_fpga_sc(sampled_ms, max_dwells, + doppler_max, freq, fs_in, samples_per_ms, samples_per_code, + vector_length, nsamples_total, bit_transition_flag, + use_CFAR_algorithm_flag, select_queue_Fpga, device_name, + dump, dump_filename)); } -gps_pcps_acquisition_fpga_sc::gps_pcps_acquisition_fpga_sc( - unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long freq, long fs_in, - int samples_per_ms, int samples_per_code, int vector_length, - bool bit_transition_flag, bool use_CFAR_algorithm_flag, - unsigned int select_queue_Fpga, - bool dump, - std::string dump_filename) : - gr::block("pcps_acquisition_fpga_sc",gr::io_signature::make(0, 0, sizeof(lv_16sc_t)),gr::io_signature::make(0, 0, 0)) +gps_pcps_acquisition_fpga_sc::gps_pcps_acquisition_fpga_sc( + unsigned int sampled_ms, unsigned int max_dwells, + unsigned int doppler_max, long freq, long fs_in, int samples_per_ms, + int samples_per_code, int vector_length, unsigned int nsamples_total, + bool bit_transition_flag, bool use_CFAR_algorithm_flag, + unsigned int select_queue_Fpga, std::string device_name, bool dump, + std::string dump_filename) : + + gr::block("pcps_acquisition_fpga_sc", + gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), + gr::io_signature::make(0, 0, 0)) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0; // SAMPLE COUNTER d_active = false; d_state = 0; - d_freq = freq; - d_fs_in = fs_in; - d_samples_per_ms = samples_per_ms; d_samples_per_code = samples_per_code; - d_sampled_ms = sampled_ms; - d_max_dwells = max_dwells; // Note : d_max_dwells is not used in the FPGA implementation + d_max_dwells = max_dwells; // Note : d_max_dwells is not used in the FPGA implementation d_well_count = 0; d_doppler_max = doppler_max; - d_fft_size = d_sampled_ms * d_samples_per_ms; + d_fft_size = sampled_ms * samples_per_ms; d_mag = 0; - d_input_power = 0.0; d_num_doppler_bins = 0; - d_bit_transition_flag = bit_transition_flag; // Note : bit transition flag is ignored and assumed 0 in the FPGA implementation - d_use_CFAR_algorithm_flag = use_CFAR_algorithm_flag; // Note : user CFAR algorithm flag is ignored and assumed 0 in the FPGA implementation + d_bit_transition_flag = bit_transition_flag; // Note : bit transition flag is ignored and assumed 0 in the FPGA implementation + d_use_CFAR_algorithm_flag = use_CFAR_algorithm_flag; // Note : user CFAR algorithm flag is ignored and assumed 0 in the FPGA implementation d_threshold = 0.0; d_doppler_step = 250; - d_code_phase = 0; - d_test_statistics = 0.0; d_channel = 0; - d_doppler_freq = 0.0; - - d_nsamples_total = vector_length; - - //if( d_bit_transition_flag ) - // { - // d_fft_size *= 2; - // d_max_dwells = 1; - // } - - d_fft_codes = static_cast(volk_gnsssdr_malloc(d_nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_magnitude = static_cast(volk_gnsssdr_malloc(d_nsamples_total * sizeof(float), volk_gnsssdr_get_alignment())); - //temporary storage for the input conversion from 16sc to float 32fc - d_in_32fc = static_cast(volk_gnsssdr_malloc(d_nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - - d_fft_codes_padded = static_cast(volk_gnsssdr_malloc(d_nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - - - // Direct FFT - d_fft_if = new gr::fft::fft_complex(d_nsamples_total, true); - - // Inverse FFT - d_ifft = new gr::fft::fft_complex(d_nsamples_total, false); - - // FPGA queue selection - d_select_queue_Fpga = select_queue_Fpga; // For dumping samples into a file d_dump = dump; d_dump_filename = dump_filename; d_gnss_synchro = 0; - d_grid_doppler_wipeoffs = 0; - - - - - + // instantiate HW accelerator class + acquisition_fpga_8sc = std::make_shared < gps_fpga_acquisition_8sc> + (device_name, vector_length, d_fft_size, nsamples_total, fs_in, freq, sampled_ms, select_queue_Fpga); } gps_pcps_acquisition_fpga_sc::~gps_pcps_acquisition_fpga_sc() { - if (d_num_doppler_bins > 0) - { - for (unsigned int i = 0; i < d_num_doppler_bins; i++) - { - volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]); - } - delete[] d_grid_doppler_wipeoffs; - } - - volk_gnsssdr_free(d_fft_codes); - volk_gnsssdr_free(d_magnitude); - volk_gnsssdr_free(d_in_32fc); - - delete d_ifft; - delete d_fft_if; - if (d_dump) { d_dump_file.close(); } - - - acquisition_fpga_8sc.free(); + acquisition_fpga_8sc->free(); } -void gps_pcps_acquisition_fpga_sc::set_local_code(std::complex * code) +void gps_pcps_acquisition_fpga_sc::set_local_code() { - // COD - // Here we want to create a buffer that looks like this: - // [ 0 0 0 ... 0 c_0 c_1 ... c_L] - // where c_i is the local code and there are L zeros and L chips - - - - - int offset = 0; -// if( d_bit_transition_flag ) -// { -// std::fill_n( d_fft_if->get_inbuf(), d_nsamples_total, gr_complex( 0.0, 0.0 ) ); -// offset = d_nsamples_total; -// } - - - - memcpy(d_fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * d_nsamples_total); - d_fft_if->execute(); // We need the FFT of local code - volk_32fc_conjugate_32fc(d_fft_codes_padded, d_fft_if->get_outbuf(), d_nsamples_total); - - acquisition_fpga_8sc.set_local_code(d_fft_codes_padded); - -} - - -void gps_pcps_acquisition_fpga_sc::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) -{ - - float phase_step_rad = GPS_TWO_PI * freq / static_cast(d_fs_in); - - float _phase[1]; - _phase[0] = 0; - volk_gnsssdr_s32f_sincos_32fc(carrier_vector, - phase_step_rad, _phase, correlator_length_samples); - + acquisition_fpga_8sc->set_local_code(d_gnss_synchro->PRN); } @@ -215,34 +130,22 @@ void gps_pcps_acquisition_fpga_sc::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - d_gnss_synchro->Flag_preamble = false; - d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; d_gnss_synchro->Acq_samplestamp_samples = 0; d_mag = 0.0; - d_input_power = 0.0; - - d_num_doppler_bins = ceil( static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step)); - - // Create the carrier Doppler wipeoff signals - d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins]; - for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) - { - d_grid_doppler_wipeoffs[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - int doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; - update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_freq + doppler); - } - acquisition_fpga_8sc.init(d_fft_size, d_nsamples_total, d_freq, d_doppler_max, d_doppler_step, d_num_doppler_bins, d_fs_in, d_select_queue_Fpga); - - + d_num_doppler_bins = ceil( + static_cast(static_cast(d_doppler_max) + - static_cast(-d_doppler_max)) + / static_cast(d_doppler_step)); + acquisition_fpga_8sc->open_device(); + acquisition_fpga_8sc->init(); } - void gps_pcps_acquisition_fpga_sc::set_state(int state) { d_state = state; @@ -253,172 +156,161 @@ void gps_pcps_acquisition_fpga_sc::set_state(int state) d_gnss_synchro->Acq_samplestamp_samples = 0; d_well_count = 0; d_mag = 0.0; - d_input_power = 0.0; - d_test_statistics = 0.0; } else if (d_state == 0) - {} + { + } else { LOG(ERROR) << "State can only be set to 0 or 1"; } - - - - - - } + void gps_pcps_acquisition_fpga_sc::set_active(bool active) { - - float temp_peak_to_noise_level = 0.0; - float peak_to_noise_level = 0.0; - acquisition_fpga_8sc.block_samples(); // block the samples to run the acquisition this is only necessary for the tests - + float temp_peak_to_noise_level = 0.0; + float peak_to_noise_level = 0.0; + float input_power; + float test_statistics = 0.0; + acquisition_fpga_8sc->block_samples(); // block the samples to run the acquisition this is only necessary for the tests d_active = active; + int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL -// while (d_well_count < d_max_dwells) -// { - int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL + d_state = 1; - d_state = 1; + // initialize acquisition algorithm + int doppler; + uint32_t indext = 0; + float magt = 0.0; + //int effective_fft_size = ( d_bit_transition_flag ? d_fft_size/2 : d_fft_size ); + int effective_fft_size = d_fft_size; + //float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); - // initialize acquisition algorithm - int doppler; - uint32_t indext = 0; - float magt = 0.0; - //int effective_fft_size = ( d_bit_transition_flag ? d_fft_size/2 : d_fft_size ); - int effective_fft_size = d_fft_size; - //float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); + d_mag = 0.0; - d_mag = 0.0; + unsigned int initial_sample; - unsigned int initial_sample; + d_well_count++; - d_well_count++; + DLOG(INFO) << "Channel: " << d_channel + << " , doing acquisition of satellite: " << d_gnss_synchro->System + << " " << d_gnss_synchro->PRN << " ,sample stamp: " + << d_sample_counter << ", threshold: " << ", threshold: " + << d_threshold << ", doppler_max: " << d_doppler_max + << ", doppler_step: " << d_doppler_step; - DLOG(INFO) << "Channel: " << d_channel - << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN - << " ,sample stamp: " << d_sample_counter << ", threshold: " - << ", threshold: " - << d_threshold << ", doppler_max: " << d_doppler_max - << ", doppler_step: " << d_doppler_step; + // Doppler frequency search loop + for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; + doppler_index++) + { - // Doppler frequency search loop - for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) - { + doppler = -static_cast(d_doppler_max) + + d_doppler_step * doppler_index; + acquisition_fpga_8sc->set_phase_step(doppler_index); + acquisition_fpga_8sc->run_acquisition(); // runs acquisition and waits until it is finished - doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; + acquisition_fpga_8sc->read_acquisition_results(&indext, &magt, + &initial_sample, &input_power); - acquisition_fpga_8sc.set_phase_step(doppler_index); - acquisition_fpga_8sc.run_acquisition(); // runs acquisition and waits until it is finished + d_sample_counter = initial_sample; - acquisition_fpga_8sc.read_acquisition_results(&indext, &magt, &initial_sample, &d_input_power); + temp_peak_to_noise_level = (float) (magt / input_power); + if (peak_to_noise_level < temp_peak_to_noise_level) + { + peak_to_noise_level = temp_peak_to_noise_level; + d_mag = magt; - d_sample_counter = initial_sample; + input_power = (input_power - d_mag) + / (effective_fft_size - 1); - temp_peak_to_noise_level = (float) (magt / d_input_power); - if (peak_to_noise_level < temp_peak_to_noise_level) - { - peak_to_noise_level = temp_peak_to_noise_level; - d_mag = magt; + d_gnss_synchro->Acq_delay_samples = + static_cast(indext % d_samples_per_code); + d_gnss_synchro->Acq_doppler_hz = + static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; + test_statistics = d_mag / input_power; + } - d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1); + // Record results to file if required + if (d_dump) + { + std::stringstream filename; + //std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write + filename.str(""); - //if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag) - // { - d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; - d_test_statistics = d_mag / d_input_power; - // } - } + boost::filesystem::path p = d_dump_filename; + filename << p.parent_path().string() + << boost::filesystem::path::preferred_separator + << p.stem().string() << "_" + << d_gnss_synchro->System << "_" + << d_gnss_synchro->Signal << "_sat_" + << d_gnss_synchro->PRN << "_doppler_" << doppler + << p.extension().string(); - // Record results to file if required - if (d_dump) - { - std::stringstream filename; - std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write - filename.str(""); + DLOG(INFO) << "Writing ACQ out to " << filename.str(); - boost::filesystem::path p = d_dump_filename; - filename << p.parent_path().string() - << boost::filesystem::path::preferred_separator - << p.stem().string() - << "_" << d_gnss_synchro->System - <<"_" << d_gnss_synchro->Signal << "_sat_" - << d_gnss_synchro->PRN << "_doppler_" - << doppler - << p.extension().string(); + d_dump_file.open(filename.str().c_str(), + std::ios::out | std::ios::binary); + d_dump_file.close(); + } + } - DLOG(INFO) << "Writing ACQ out to " << filename.str(); + if (test_statistics > d_threshold) + { + d_state = 2; // Positive acquisition - d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); - d_dump_file.write((char*)d_ifft->get_outbuf(), n); //write directly |abs(x)|^2 in this Doppler bin? - d_dump_file.close(); - } - } + // 6.1- Declare positive acquisition using a message port + DLOG(INFO) << "positive acquisition"; + DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " + << d_gnss_synchro->PRN; + DLOG(INFO) << "sample_stamp " << d_sample_counter; + DLOG(INFO) << "test statistics value " << test_statistics; + DLOG(INFO) << "test statistics threshold " << d_threshold; + DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples; + DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz; + DLOG(INFO) << "magnitude " << d_mag; + DLOG(INFO) << "input signal power " << input_power; + d_active = false; + d_state = 0; - if (d_test_statistics > d_threshold) - { - d_state = 2; // Positive acquisition + acquisition_message = 1; + this->message_port_pub(pmt::mp("events"), + pmt::from_long(acquisition_message)); + } + else + { + d_state = 3; // Negative acquisition - // 6.1- Declare positive acquisition using a message port - DLOG(INFO) << "positive acquisition"; - DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN; - DLOG(INFO) << "sample_stamp " << d_sample_counter; - DLOG(INFO) << "test statistics value " << d_test_statistics; - DLOG(INFO) << "test statistics threshold " << d_threshold; - DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples; - DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz; - DLOG(INFO) << "magnitude " << d_mag; - DLOG(INFO) << "input signal power " << d_input_power; + // 6.2- Declare negative acquisition using a message port + DLOG(INFO) << "negative acquisition"; + DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " + << d_gnss_synchro->PRN; + DLOG(INFO) << "sample_stamp " << d_sample_counter; + DLOG(INFO) << "test statistics value " << test_statistics; + DLOG(INFO) << "test statistics threshold " << d_threshold; + DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples; + DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz; + DLOG(INFO) << "magnitude " << d_mag; + DLOG(INFO) << "input signal power " << input_power; - d_active = false; - d_state = 0; + d_active = false; + d_state = 0; - acquisition_message = 1; - this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); + acquisition_message = 2; + this->message_port_pub(pmt::mp("events"), + pmt::from_long(acquisition_message)); + } -// break; + acquisition_fpga_8sc->unblock_samples(); - } - else //if (d_well_count == d_max_dwells) - { - d_state = 3; // Negative acquisition - - // 6.2- Declare negative acquisition using a message port - DLOG(INFO) << "negative acquisition"; - DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN; - DLOG(INFO) << "sample_stamp " << d_sample_counter; - DLOG(INFO) << "test statistics value " << d_test_statistics; - DLOG(INFO) << "test statistics threshold " << d_threshold; - DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples; - DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz; - DLOG(INFO) << "magnitude " << d_mag; - DLOG(INFO) << "input signal power " << d_input_power; - - d_active = false; - d_state = 0; - - acquisition_message = 2; - this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); - -// break; - } - -// } - - acquisition_fpga_8sc.unblock_samples(); + acquisition_fpga_8sc->close_device(); DLOG(INFO) << "Done. Consumed 1 item."; - } @@ -426,6 +318,6 @@ int gps_pcps_acquisition_fpga_sc::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items __attribute__((unused))) { - // general work not used with the acquisition + // general work not used with the acquisition return noutput_items; } diff --git a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.h b/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.h index a3b4c1b64..8e60689fd 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.h @@ -62,13 +62,13 @@ class gps_pcps_acquisition_fpga_sc; typedef boost::shared_ptr gps_pcps_acquisition_fpga_sc_sptr; gps_pcps_acquisition_fpga_sc_sptr -gps_pcps_make_acquisition_fpga_sc(unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long freq, long fs_in, - int samples_per_ms, int samples_per_code, int vector_length_, - bool bit_transition_flag, bool use_CFAR_algorithm_flag, - unsigned int select_queue_Fpga, - bool dump, - std::string dump_filename); +gps_pcps_make_acquisition_fpga_sc(unsigned int sampled_ms, + unsigned int max_dwells, unsigned int doppler_max, long freq, + long fs_in, int samples_per_ms, int samples_per_code, + int vector_length_, unsigned int nsamples_total_, + bool bit_transition_flag, bool use_CFAR_algorithm_flag, + unsigned int select_queue_Fpga, std::string device_name, bool dump, + std::string dump_filename); /*! * \brief This class implements a Parallel Code Phase Search Acquisition. @@ -76,163 +76,139 @@ gps_pcps_make_acquisition_fpga_sc(unsigned int sampled_ms, unsigned int max_dwel * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver", * Algorithm 1, for a pseudocode description of this implementation. */ -class gps_pcps_acquisition_fpga_sc: public gr::block +class gps_pcps_acquisition_fpga_sc : public gr::block { private: friend gps_pcps_acquisition_fpga_sc_sptr - gps_pcps_make_acquisition_fpga_sc(unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long freq, long fs_in, - int samples_per_ms, int samples_per_code, int vector_length, + gps_pcps_make_acquisition_fpga_sc(unsigned int sampled_ms, + unsigned int max_dwells, unsigned int doppler_max, long freq, + long fs_in, int samples_per_ms, int samples_per_code, + int vector_length, unsigned int nsamples_total, bool bit_transition_flag, bool use_CFAR_algorithm_flag, - unsigned int select_queue_Fpga, - bool dump, + unsigned int select_queue_Fpga, std::string device_name, bool dump, std::string dump_filename); - gps_pcps_acquisition_fpga_sc(unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long freq, long fs_in, - int samples_per_ms, int samples_per_code, int vector_length, + gps_pcps_acquisition_fpga_sc(unsigned int sampled_ms, + unsigned int max_dwells, unsigned int doppler_max, long freq, + long fs_in, int samples_per_ms, int samples_per_code, + int vector_length, unsigned int nsamples_total, bool bit_transition_flag, bool use_CFAR_algorithm_flag, - unsigned int select_queue_Fpga, - bool dump, + unsigned int select_queue_Fpga, std::string device_name, bool dump, std::string dump_filename); - void update_local_carrier(gr_complex* carrier_vector, - int correlator_length_samples, - float freq); - - long d_fs_in; - long d_freq; - int d_samples_per_ms; int d_samples_per_code; float d_threshold; - std::string d_satellite_str; unsigned int d_doppler_max; unsigned int d_doppler_step; - unsigned int d_sampled_ms; unsigned int d_max_dwells; unsigned int d_well_count; unsigned int d_fft_size; - unsigned int d_nsamples_total; // the closest power of two approximation to d_fft_size unsigned long int d_sample_counter; - gr_complex** d_grid_doppler_wipeoffs; unsigned int d_num_doppler_bins; - gr_complex* d_fft_codes; - gr_complex* d_fft_codes_padded; - gr_complex* d_in_32fc; - gr::fft::fft_complex* d_fft_if; - gr::fft::fft_complex* d_ifft; + Gnss_Synchro *d_gnss_synchro; - unsigned int d_code_phase; - float d_doppler_freq; - float d_mag; - float* d_magnitude; - float d_input_power; - float d_test_statistics; - bool d_bit_transition_flag; - bool d_use_CFAR_algorithm_flag; - std::ofstream d_dump_file; - bool d_active; - int d_state; - bool d_dump; + float d_mag;bool d_bit_transition_flag;bool d_use_CFAR_algorithm_flag; + std::ofstream d_dump_file;bool d_active; + int d_state;bool d_dump; unsigned int d_channel; - unsigned int d_select_queue_Fpga; std::string d_dump_filename; - gps_fpga_acquisition_8sc acquisition_fpga_8sc; + std::shared_ptr acquisition_fpga_8sc; public: /*! * \brief Default destructor. */ - ~gps_pcps_acquisition_fpga_sc(); + ~gps_pcps_acquisition_fpga_sc(); - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to exchange synchronization data between acquisition and tracking blocks. - * \param p_gnss_synchro Satellite information shared by the processing blocks. - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) - { - d_gnss_synchro = p_gnss_synchro; - } + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to exchange synchronization data between acquisition and tracking blocks. + * \param p_gnss_synchro Satellite information shared by the processing blocks. + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) + { + d_gnss_synchro = p_gnss_synchro; + } - /*! - * \brief Returns the maximum peak of grid search. - */ - unsigned int mag() - { - return d_mag; - } + /*! + * \brief Returns the maximum peak of grid search. + */ + unsigned int mag() + { + return d_mag; + } - /*! - * \brief Initializes acquisition algorithm. - */ - void init(); + /*! + * \brief Initializes acquisition algorithm. + */ + void init(); - /*! - * \brief Sets local code for PCPS acquisition algorithm. - * \param code - Pointer to the PRN code. - */ - void set_local_code(std::complex * code); + /*! + * \brief Sets local code for PCPS acquisition algorithm. + * \param code - Pointer to the PRN code. + */ + void set_local_code(); - /*! - * \brief Starts acquisition algorithm, turning from standby mode to - * active mode - * \param active - bool that activates/deactivates the block. - */ - void set_active(bool active); + /*! + * \brief Starts acquisition algorithm, turning from standby mode to + * active mode + * \param active - bool that activates/deactivates the block. + */ + void set_active(bool active); - /*! - * \brief If set to 1, ensures that acquisition starts at the - * first available sample. - * \param state - int=1 forces start of acquisition - */ - void set_state(int state); + /*! + * \brief If set to 1, ensures that acquisition starts at the + * first available sample. + * \param state - int=1 forces start of acquisition + */ + void set_state(int state); - /*! - * \brief Set acquisition channel unique ID - * \param channel - receiver channel. - */ - void set_channel(unsigned int channel) - { - d_channel = channel; - } + /*! + * \brief Set acquisition channel unique ID + * \param channel - receiver channel. + */ + void set_channel(unsigned int channel) + { + d_channel = channel; + } - /*! - * \brief Set statistics threshold of PCPS algorithm. - * \param threshold - Threshold for signal detection (check \ref Navitec2012, - * Algorithm 1, for a definition of this threshold). - */ - void set_threshold(float threshold) - { - d_threshold = threshold; - } + /*! + * \brief Set statistics threshold of PCPS algorithm. + * \param threshold - Threshold for signal detection (check \ref Navitec2012, + * Algorithm 1, for a definition of this threshold). + */ + void set_threshold(float threshold) + { + d_threshold = threshold; + } - /*! - * \brief Set maximum Doppler grid search - * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz]. - */ - void set_doppler_max(unsigned int doppler_max) - { - d_doppler_max = doppler_max; - } + /*! + * \brief Set maximum Doppler grid search + * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz]. + */ + void set_doppler_max(unsigned int doppler_max) + { + d_doppler_max = doppler_max; + acquisition_fpga_8sc->set_doppler_max(doppler_max); + } - /*! - * \brief Set Doppler steps for the grid search - * \param doppler_step - Frequency bin of the search grid [Hz]. - */ - void set_doppler_step(unsigned int doppler_step) - { - d_doppler_step = doppler_step; - } + /*! + * \brief Set Doppler steps for the grid search + * \param doppler_step - Frequency bin of the search grid [Hz]. + */ + void set_doppler_step(unsigned int doppler_step) + { + d_doppler_step = doppler_step; + acquisition_fpga_8sc->set_doppler_step(doppler_step); + } - - /*! - * \brief Parallel Code Phase Search Acquisition signal processing. - */ - int general_work(int noutput_items, gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + /*! + * \brief Parallel Code Phase Search Acquisition signal processing. + */ + int general_work(int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; diff --git a/src/algorithms/acquisition/libs/CMakeLists.txt b/src/algorithms/acquisition/libs/CMakeLists.txt index 01ab3de68..93d1f1e29 100644 --- a/src/algorithms/acquisition/libs/CMakeLists.txt +++ b/src/algorithms/acquisition/libs/CMakeLists.txt @@ -55,6 +55,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/core/system_parameters ${CMAKE_SOURCE_DIR}/src/core/interfaces ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/libs ${VOLK_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} diff --git a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.cc b/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.cc index df5713dfe..8fad0c8b0 100644 --- a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.cc +++ b/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.cc @@ -34,6 +34,7 @@ */ #include "gps_fpga_acquisition_8sc.h" +#include "gps_sdr_signal_processing.h" #include // allocate memory dynamically @@ -59,144 +60,135 @@ // logging #include +#include + #include "GPS_L1_CA.h" #define PAGE_SIZE 0x10000 -#define CODE_RESAMPLER_NUM_BITS_PRECISION 20 -#define CODE_PHASE_STEP_CHIPS_NUM_NBITS CODE_RESAMPLER_NUM_BITS_PRECISION -#define pwrtwo(x) (1 << (x)) -#define MAX_CODE_RESAMPLER_COUNTER pwrtwo(CODE_PHASE_STEP_CHIPS_NUM_NBITS) // 2^CODE_PHASE_STEP_CHIPS_NUM_NBITS -#define PHASE_CARR_NBITS 32 -#define PHASE_CARR_NBITS_INT 1 -#define PHASE_CARR_NBITS_FRAC PHASE_CARR_NBITS - PHASE_CARR_NBITS_INT - #define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31); +#define NUM_PRNs 32 +#define TEST_REGISTER_ACQ_WRITEVAL 0x55AA - -bool gps_fpga_acquisition_8sc::init(unsigned int fft_size, unsigned int nsamples_total, long freq, unsigned int doppler_max, unsigned int doppler_step, int num_doppler_bins, long fs_in, unsigned select_queue) +bool gps_fpga_acquisition_8sc::init() { - float phase_step_rad_fpga; + // configure the acquisition with the main initialization values + gps_fpga_acquisition_8sc::configure_acquisition(); + return true; +} - d_phase_step_rad_vector = new float[num_doppler_bins]; +bool gps_fpga_acquisition_8sc::set_local_code(unsigned int PRN) +{ - for (int doppler_index = 0; doppler_index < num_doppler_bins; doppler_index++) - { - int doppler = -static_cast(doppler_max) + doppler_step * doppler_index; - float phase_step_rad = GPS_TWO_PI * (freq + doppler) / static_cast(fs_in); - // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing - // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) - // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) - // while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x) - phase_step_rad_fpga = phase_step_rad / (GPS_TWO_PI / 2); - // avoid saturation of the fixed point representation in the fpga - // (only the positive value can saturate due to the 2's complement representation) - if (phase_step_rad_fpga == 1.0) - { - phase_step_rad_fpga = MAX_PHASE_STEP_RAD; - } - d_phase_step_rad_vector[doppler_index] = phase_step_rad_fpga; - } + // select the code with the chosen PRN + gps_fpga_acquisition_8sc::fpga_configure_acquisition_local_code( + &d_all_fft_codes[d_vector_length * PRN]); + return true; +} - // sanity check : check test register - unsigned writeval = 0x55AA; - unsigned readval; - readval = gps_fpga_acquisition_8sc::fpga_acquisition_test_register(writeval); - if (writeval != readval) - { - printf("test register fail\n"); - LOG(WARNING) << "Acquisition test register sanity check failed"; - } - else - { - printf("test register success\n"); - LOG(INFO) << "Acquisition test register sanity check success !"; - } +gps_fpga_acquisition_8sc::gps_fpga_acquisition_8sc(std::string device_name, + unsigned int vector_length, unsigned int nsamples, + unsigned int nsamples_total, long fs_in, long freq, + unsigned int sampled_ms, unsigned select_queue) +{ - d_nsamples = fft_size; - d_nsamples_total = nsamples_total; + // initial values + + d_device_name = device_name; + d_freq = freq; + d_fs_in = fs_in; + d_vector_length = vector_length; + d_nsamples = nsamples; // number of samples not including padding d_select_queue = select_queue; - gps_fpga_acquisition_8sc::configure_acquisition(); + d_doppler_max = 0; + d_doppler_step = 0; + d_fd = 0; // driver descriptor + d_map_base = nullptr; // driver memory map - return true; -} + // compute all the possible code ffts + // Direct FFT + d_fft_if = new gr::fft::fft_complex(vector_length, true); + // allocate memory to compute all the PRNs + // and compute all the possible codes + std::complex* code = new std::complex[nsamples_total]; // buffer for the local code + std::complex * code_total = new gr_complex[vector_length]; // buffer for the local code repeate every number of ms -bool gps_fpga_acquisition_8sc::set_local_code(gr_complex* fft_codes) -{ - unsigned int i; - float max = 0; - d_fft_codes = new lv_16sc_t[d_nsamples_total]; + gr_complex* d_fft_codes_padded = + static_cast(volk_gnsssdr_malloc( + vector_length * sizeof(gr_complex), + volk_gnsssdr_get_alignment())); - for (i=0;i max) + gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code + + for (unsigned int i = 0; i < sampled_ms; i++) { - max = std::abs(fft_codes[i].real()); + memcpy(&(code_total[i * nsamples_total]), code, + sizeof(gr_complex) * nsamples_total); // repeat for each ms } - if(std::abs(fft_codes[i].imag()) > max) + + int offset = 0; + + memcpy(d_fft_if->get_inbuf() + offset, code_total, + sizeof(gr_complex) * vector_length); // copy to FFT buffer + + d_fft_if->execute(); // Run the FFT of local code + + volk_32fc_conjugate_32fc(d_fft_codes_padded, d_fft_if->get_outbuf(), + vector_length); // conjugate values + + max = 0; // initialize maximum value + + for (unsigned int i = 0; i < vector_length; i++) // search for maxima { - max = std::abs(fft_codes[i].imag()); + if (std::abs(d_fft_codes_padded[i].real()) > max) + { + max = std::abs(d_fft_codes_padded[i].real()); + } + if (std::abs(d_fft_codes_padded[i].imag()) > max) + { + max = std::abs(d_fft_codes_padded[i].imag()); + } } + + for (unsigned int i = 0; i < vector_length; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + { + d_all_fft_codes[i + vector_length * PRN] = lv_16sc_t( + (int) (d_fft_codes_padded[i].real() + * (pow(2, 7) - 1) / max), + (int) (d_fft_codes_padded[i].imag() + * (pow(2, 7) - 1) / max)); + } + } - for (i=0;i(d_doppler_max) + + d_doppler_step * doppler_index; + float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) + / static_cast(d_fs_in); + // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing + // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) + // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) + // while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x) + phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); + // avoid saturation of the fixed point representation in the fpga + // (only the positive value can saturate due to the 2's complement representation) + if (phase_step_rad_real == 1.0) + { + phase_step_rad_real = MAX_PHASE_STEP_RAD; + } + phase_step_rad_int_temp = phase_step_rad_real * 4; // * 2^2 + phase_step_rad_int = (int32_t) (phase_step_rad_int_temp * (536870912)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings d_map_base[3] = phase_step_rad_int; } - -void gps_fpga_acquisition_8sc::read_acquisition_results(uint32_t* max_index, float* max_magnitude, unsigned *initial_sample, float *power_sum) +void gps_fpga_acquisition_8sc::read_acquisition_results(uint32_t* max_index, + float* max_magnitude, unsigned *initial_sample, float *power_sum) { unsigned readval = 0; readval = d_map_base[0]; @@ -280,18 +282,62 @@ void gps_fpga_acquisition_8sc::read_acquisition_results(uint32_t* max_index, flo *power_sum = (float) readval; readval = d_map_base[3]; *max_index = readval; -} +} void gps_fpga_acquisition_8sc::block_samples() { d_map_base[14] = 1; // block the samples } - void gps_fpga_acquisition_8sc::unblock_samples() { d_map_base[14] = 0; // unblock the samples } +void gps_fpga_acquisition_8sc::open_device() +{ + + if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << d_device_name; + } + d_map_base = (volatile unsigned *) mmap(NULL, PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0); + + if (d_map_base == (void *) -1) + { + LOG(WARNING) + << "Cannot map the FPGA acquisition module into user memory"; + } + + // sanity check : check test register + // we only nee to do this when the class is created + // but the device is not opened yet when the class is create + // because we need to open and close the device every time we run an acquisition + // since the same device may be used by more than one class (gps acquisition, galileo + // acquisition, etc ..) + unsigned writeval = TEST_REGISTER_ACQ_WRITEVAL; + unsigned readval; + readval = gps_fpga_acquisition_8sc::fpga_acquisition_test_register( + writeval); + if (writeval != readval) + { + LOG(WARNING) << "Acquisition test register sanity check failed"; + } + else + { + LOG(INFO) << "Acquisition test register sanity check success !"; + } + +} +void gps_fpga_acquisition_8sc::close_device() +{ + if (munmap((void*) d_map_base, PAGE_SIZE) == -1) + { + printf("Failed to unmap memory uio\n"); + } + close(d_fd); + +} diff --git a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.h b/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.h index b34566308..4f48af3bc 100644 --- a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.h +++ b/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.h @@ -39,7 +39,7 @@ #include #include - +#include /*! * \brief Class that implements carrier wipe-off and correlators. @@ -47,35 +47,56 @@ class gps_fpga_acquisition_8sc { public: - gps_fpga_acquisition_8sc(); - ~gps_fpga_acquisition_8sc(); - bool init(unsigned int fft_size, unsigned int nsamples_total, long d_freq, unsigned int doppler_max, unsigned int doppler_step, int num_doppler_bins, long fs_in, unsigned select_queue); - bool set_local_code(gr_complex* fft_codes); //int code_length_chips, const lv_16sc_t* local_code_in, float *shifts_chips); + gps_fpga_acquisition_8sc(std::string device_name, + unsigned int vector_length, unsigned int nsamples, + unsigned int nsamples_total, long fs_in, long freq, + unsigned int sampled_ms, unsigned select_queue); + ~gps_fpga_acquisition_8sc();bool init();bool set_local_code( + unsigned int PRN); //int code_length_chips, const lv_16sc_t* local_code_in, float *shifts_chips); bool free(); void run_acquisition(void); void set_phase_step(unsigned int doppler_index); - void read_acquisition_results(uint32_t* max_index, float* max_magnitude, unsigned *initial_sample, float *power_sum); + void read_acquisition_results(uint32_t* max_index, float* max_magnitude, + unsigned *initial_sample, float *power_sum); void block_samples(); void unblock_samples(); + void open_device(); + void close_device(); + + /*! + * \brief Set maximum Doppler grid search + * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz]. + */ + void set_doppler_max(unsigned int doppler_max) + { + d_doppler_max = doppler_max; + } + + /*! + * \brief Set Doppler steps for the grid search + * \param doppler_step - Frequency bin of the search grid [Hz]. + */ + void set_doppler_step(unsigned int doppler_step) + { + d_doppler_step = doppler_step; + } + private: - const lv_16sc_t *d_local_code_in; - lv_16sc_t *d_corr_out; - float *d_shifts_chips; - int d_code_length_chips; - int d_n_correlators; + + long d_freq; + long d_fs_in; + gr::fft::fft_complex* d_fft_if; // function used to run the fft of the local codes // data related to the hardware module and the driver - char d_device_io_name[11] = "/dev/uio13"; // driver io name - int d_fd; // driver descriptor - volatile unsigned *d_map_base; // driver memory map - - // configuration data received from the interface - lv_16sc_t *d_fft_codes = nullptr; - float *d_phase_step_rad_vector = nullptr; - - unsigned int d_nsamples_total; // total number of samples in the fft including padding + int d_fd; // driver descriptor + volatile unsigned *d_map_base; // driver memory map + lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts + unsigned int d_vector_length; // number of samples incluing padding and number of ms unsigned int d_nsamples; // number of samples not including padding unsigned int d_select_queue; // queue selection + std::string d_device_name; // HW device name + unsigned int d_doppler_max; // max doppler + unsigned int d_doppler_step; // doppler step // FPGA private functions unsigned fpga_acquisition_test_register(unsigned writeval); @@ -84,5 +105,4 @@ private: }; - #endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc index d947ebd94..c5b3f5262 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc @@ -32,20 +32,14 @@ #include #include #include -#include #include #include #include #include -float uniform() -{ - // Seed with a real random value, if available - std::random_device r; - std::default_random_engine e1(r()); - std::uniform_real_distribution<> uniform_dist(-1, 1); - return static_cast(uniform_dist(e1)); +float uniform() { + return 2.0f * ((float) rand() / RAND_MAX - 0.5f); // uniformly (-1, 1) } template @@ -57,9 +51,6 @@ void random_floats (t *buf, unsigned n) void load_random_data(void *data, volk_gnsssdr_type_t type, unsigned int n) { - std::random_device r; - std::default_random_engine e1(r()); - std::uniform_real_distribution uniform_dist(-1, 1); if(type.is_complex) n *= 2; if(type.is_float) { @@ -72,7 +63,7 @@ void load_random_data(void *data, volk_gnsssdr_type_t type, unsigned int n) if(type.is_signed) int_max /= 2.0; for(unsigned int i = 0; i < n; i++) { - float scaled_rand = static_cast(uniform_dist(e1)) * int_max; + float scaled_rand = (((float) (rand() - (RAND_MAX/2))) / static_cast((RAND_MAX/2))) * int_max; //man i really don't know how to do this in a more clever way, you have to cast down at some point switch(type.size) { diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc index e21b6bc04..7723b373e 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc @@ -36,19 +36,17 @@ * ------------------------------------------------------------------------- */ - #include "gps_l1_ca_dll_pll_c_aid_tracking_fpga.h" #include #include "GPS_L1_CA.h" #include "configuration_interface.h" - using google::LogMessage; GpsL1CaDllPllCAidTrackingFpga::GpsL1CaDllPllCAidTrackingFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : - role_(role), in_streams_(in_streams), out_streams_(out_streams) + role_(role), in_streams_(in_streams), out_streams_(out_streams) { DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## @@ -63,59 +61,65 @@ GpsL1CaDllPllCAidTrackingFpga::GpsL1CaDllPllCAidTrackingFpga( float dll_bw_hz; float dll_bw_narrow_hz; float early_late_space_chips; - item_type_ = configuration->property(role + ".item_type", default_item_type); + std::string device_name; + unsigned int device_base; + + item_type_ = configuration->property(role + ".item_type", + default_item_type); fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); f_if = configuration->property(role + ".if", 0); dump = configuration->property(role + ".dump", false); pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); - pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0); + pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", + 20.0); dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0); int extend_correlation_ms; - extend_correlation_ms = configuration->property(role + ".extend_correlation_ms", 1); + extend_correlation_ms = configuration->property( + role + ".extend_correlation_ms", 1); - early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); + early_late_space_chips = configuration->property( + role + ".early_late_space_chips", 0.5); std::string default_dump_filename = "./track_ch"; dump_filename = configuration->property(role + ".dump_filename", - default_dump_filename); //unused! - vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); + default_dump_filename); + std::string default_device_name = "/dev/uio"; + device_name = configuration->property(role + ".devicename", + default_device_name); + device_base = configuration->property(role + ".device_base", 1); + vector_length = std::round( + fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); //################# MAKE TRACKING GNURadio object ################### - if(item_type_.compare("cshort") == 0) + if (item_type_.compare("cshort") == 0) { item_size_ = sizeof(lv_16sc_t); tracking_fpga_sc = gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc( - f_if, - fs_in, - vector_length, - dump, - dump_filename, - pll_bw_hz, - dll_bw_hz, - pll_bw_narrow_hz, - dll_bw_narrow_hz, - extend_correlation_ms, - early_late_space_chips); - DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; + f_if, fs_in, vector_length, dump, dump_filename, pll_bw_hz, + dll_bw_hz, pll_bw_narrow_hz, dll_bw_narrow_hz, + extend_correlation_ms, early_late_space_chips, device_name, + device_base); + DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() + << ")"; } else { item_size_ = sizeof(lv_16sc_t); // LOG(WARNING) << item_type_ << " unknown tracking item type"; - LOG(WARNING) << item_type_ << " the tracking item type for the FPGA tracking test has to be cshort"; + LOG(WARNING) << item_type_ + << " the tracking item type for the FPGA tracking test has to be cshort"; } + channel_ = 0; } - GpsL1CaDllPllCAidTrackingFpga::~GpsL1CaDllPllCAidTrackingFpga() { LOG(INFO) << "gspl1cadllpllcaidtrackingfpga destructor called"; } - void GpsL1CaDllPllCAidTrackingFpga::start_tracking() { @@ -126,11 +130,11 @@ void GpsL1CaDllPllCAidTrackingFpga::start_tracking() else { // LOG(WARNING) << item_type_ << " unknown tracking item type"; - LOG(WARNING) << item_type_ << " the tracking item type for the FPGA tracking test has to be cshort"; + LOG(WARNING) << item_type_ + << " the tracking item type for the FPGA tracking test has to be cshort"; } } - /* * Set tracking channel unique ID */ @@ -145,12 +149,13 @@ void GpsL1CaDllPllCAidTrackingFpga::set_channel(unsigned int channel) else { // LOG(WARNING) << item_type_ << " unknown tracking item type"; - LOG(WARNING) << item_type_ << " the tracking item type for the FPGA tracking test has to be cshort"; + LOG(WARNING) << item_type_ + << " the tracking item type for the FPGA tracking test has to be cshort"; } } - -void GpsL1CaDllPllCAidTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +void GpsL1CaDllPllCAidTrackingFpga::set_gnss_synchro( + Gnss_Synchro* p_gnss_synchro) { if (item_type_.compare("cshort") == 0) { @@ -159,25 +164,27 @@ void GpsL1CaDllPllCAidTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchr else { // LOG(WARNING) << item_type_ << " unknown tracking item type"; - LOG(WARNING) << item_type_ << " the tracking item type for the FPGA tracking test has to be cshort"; + LOG(WARNING) << item_type_ + << " the tracking item type for the FPGA tracking test has to be cshort"; } } - void GpsL1CaDllPllCAidTrackingFpga::connect(gr::top_block_sptr top_block) { - if(top_block) { /* top_block is not null */}; + if (top_block) + { /* top_block is not null */ + }; //nothing to connect, now the tracking uses gr_sync_decimator } - void GpsL1CaDllPllCAidTrackingFpga::disconnect(gr::top_block_sptr top_block) { - if(top_block) { /* top_block is not null */}; + if (top_block) + { /* top_block is not null */ + }; //nothing to disconnect, now the tracking uses gr_sync_decimator } - // CONVERT TO SOURCE gr::basic_block_sptr GpsL1CaDllPllCAidTrackingFpga::get_left_block() { @@ -188,12 +195,12 @@ gr::basic_block_sptr GpsL1CaDllPllCAidTrackingFpga::get_left_block() else { //LOG(WARNING) << item_type_ << " unknown tracking item type"; - LOG(WARNING) << item_type_ << " the tracking item type for the FPGA tracking test has to be cshort"; + LOG(WARNING) << item_type_ + << " the tracking item type for the FPGA tracking test has to be cshort"; return nullptr; } } - gr::basic_block_sptr GpsL1CaDllPllCAidTrackingFpga::get_right_block() { if (item_type_.compare("cshort") == 0) @@ -203,7 +210,16 @@ gr::basic_block_sptr GpsL1CaDllPllCAidTrackingFpga::get_right_block() else { //LOG(WARNING) << item_type_ << " unknown tracking item type"; - LOG(WARNING) << item_type_ << " the tracking item type for the FPGA tracking test has to be cshort"; + LOG(WARNING) << item_type_ + << " the tracking item type for the FPGA tracking test has to be cshort"; return nullptr; } } + +void GpsL1CaDllPllCAidTrackingFpga::reset(void) +{ + + tracking_fpga_sc->reset(); + +} + diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.h index 8533220ff..6394d1a2c 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.h @@ -43,7 +43,6 @@ #include "tracking_interface.h" #include "gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h" - class ConfigurationInterface; /*! @@ -53,8 +52,7 @@ class GpsL1CaDllPllCAidTrackingFpga : public TrackingInterface { public: GpsL1CaDllPllCAidTrackingFpga(ConfigurationInterface* configuration, - std::string role, - unsigned int in_streams, + std::string role, unsigned int in_streams, unsigned int out_streams); virtual ~GpsL1CaDllPllCAidTrackingFpga(); @@ -80,7 +78,6 @@ public: gr::basic_block_sptr get_left_block(); gr::basic_block_sptr get_right_block(); - /*! * \brief Set tracking channel unique ID */ @@ -92,9 +89,10 @@ public: */ void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); - void start_tracking(); + void reset(void); + private: gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr tracking_fpga_sc; size_t item_size_; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc index 026fb3990..e466898a6 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc @@ -47,7 +47,6 @@ #include "GPS_L1_CA.h" #include "control_message_factory.h" - /*! * \todo Include in definition header file */ @@ -56,32 +55,29 @@ #define MAXIMUM_LOCK_FAIL_COUNTER 50 #define CARRIER_LOCK_THRESHOLD 0.85 - using google::LogMessage; -gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr -gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc( - long if_freq, - long fs_in, - unsigned int vector_length, - bool dump, - std::string dump_filename, - float pll_bw_hz, - float dll_bw_hz, - float pll_bw_narrow_hz, - float dll_bw_narrow_hz, - int extend_correlation_ms, - float early_late_space_chips) +gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc( + long if_freq, long fs_in, unsigned int vector_length, bool dump, + std::string dump_filename, float pll_bw_hz, float dll_bw_hz, + float pll_bw_narrow_hz, float dll_bw_narrow_hz, + int extend_correlation_ms, float early_late_space_chips, + std::string device_name, unsigned int device_base) { - return gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr(new gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc(if_freq, - fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, pll_bw_narrow_hz, dll_bw_narrow_hz, extend_correlation_ms, early_late_space_chips)); + return gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr( + new gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc(if_freq, fs_in, + vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, + pll_bw_narrow_hz, dll_bw_narrow_hz, extend_correlation_ms, + early_late_space_chips, device_name, device_base)); } -void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::msg_handler_preamble_index(pmt::pmt_t msg) +void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::msg_handler_preamble_index( + pmt::pmt_t msg) { - //pmt::print(msg); - DLOG(INFO) << "Extended correlation enabled for Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN); + DLOG(INFO) << "Extended correlation enabled for Tracking CH " + << d_channel << ": Satellite " + << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN); if (d_enable_extended_integration == false) //avoid re-setting preamble indicator { d_preamble_timestamp_s = pmt::to_double(msg); @@ -90,26 +86,24 @@ void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::msg_handler_preamble_index(pmt::p } } + gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc( - long if_freq, - long fs_in, - unsigned int vector_length, - bool dump, - std::string dump_filename, - float pll_bw_hz, - float dll_bw_hz, - float pll_bw_narrow_hz, - float dll_bw_narrow_hz, - int extend_correlation_ms, - float early_late_space_chips) : - gr::block("gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc", gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), + long if_freq, long fs_in, unsigned int vector_length, bool dump, + std::string dump_filename, float pll_bw_hz, float dll_bw_hz, + float pll_bw_narrow_hz, float dll_bw_narrow_hz, + int extend_correlation_ms, float early_late_space_chips, + std::string device_name, unsigned int device_base) : + gr::block("gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc", + gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // Telemetry bit synchronization message port input this->message_port_register_in(pmt::mp("preamble_timestamp_s")); this->set_msg_handler(pmt::mp("preamble_timestamp_s"), - boost::bind(&gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::msg_handler_preamble_index, this, _1)); + boost::bind( + &gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::msg_handler_preamble_index, + this, _1)); this->message_port_register_out(pmt::mp("events")); // initialize internal vars d_dump = dump; @@ -133,25 +127,34 @@ gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::gps_l1_ca_dll_pll_c_aid_tracking_fpga_ // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc( + static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), + volk_gnsssdr_get_alignment())); + d_ca_code_16sc = static_cast(volk_gnsssdr_malloc( + static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), + volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late - d_correlator_outs_16sc = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + d_correlator_outs_16sc = static_cast(volk_gnsssdr_malloc( + d_n_correlator_taps * sizeof(lv_16sc_t), + volk_gnsssdr_get_alignment())); for (int n = 0; n < d_n_correlator_taps; n++) { - d_correlator_outs_16sc[n] = lv_cmake(0,0); + d_correlator_outs_16sc[n] = lv_cmake(0, 0); } - d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(float), volk_gnsssdr_get_alignment())); + d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc( + d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment())); // Set TAPs delay values [chips] - d_local_code_shift_chips[0] = - d_early_late_spc_chips; + d_local_code_shift_chips[0] = -d_early_late_spc_chips; d_local_code_shift_chips[1] = 0.0; d_local_code_shift_chips[2] = d_early_late_spc_chips; - multicorrelator_fpga_8sc.init(d_n_correlator_taps); + // create multicorrelator class + multicorrelator_fpga_8sc = std::make_shared < fpga_multicorrelator_8sc + > (d_n_correlator_taps, device_name, device_base); //--- Perform initializations ------------------------------ // define initial code frequency basis of NCO @@ -214,54 +217,71 @@ void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::start_tracking() long int acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp);//-d_vector_length; - DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; - acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); + acq_trk_diff_samples = static_cast(d_sample_counter) + - static_cast(d_acq_sample_stamp); //-d_vector_length; + DLOG(INFO) << "Number of samples between Acquisition and Tracking =" + << acq_trk_diff_samples; + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) + / static_cast(d_fs_in); // Doppler effect // Fd=(C/(C+Vr))*F - double radial_velocity = (GPS_L1_FREQ_HZ + d_acq_carrier_doppler_hz) / GPS_L1_FREQ_HZ; + double radial_velocity = (GPS_L1_FREQ_HZ + d_acq_carrier_doppler_hz) + / GPS_L1_FREQ_HZ; // new chip and prn sequence periods based on acq Doppler double T_chip_mod_seconds; double T_prn_mod_seconds; double T_prn_mod_samples; d_code_freq_chips = radial_velocity * GPS_L1_CA_CODE_RATE_HZ; - d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in); + d_code_phase_step_chips = static_cast(d_code_freq_chips) + / static_cast(d_fs_in); T_chip_mod_seconds = 1.0 / d_code_freq_chips; T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; T_prn_mod_samples = T_prn_mod_seconds * static_cast(d_fs_in); d_correlation_length_samples = round(T_prn_mod_samples); - double T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ; - double T_prn_true_samples = T_prn_true_seconds * static_cast(d_fs_in); + double T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS + / GPS_L1_CA_CODE_RATE_HZ; + double T_prn_true_samples = T_prn_true_seconds + * static_cast(d_fs_in); double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds; double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds; double corrected_acq_phase_samples, delay_correction_samples; - corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * static_cast(d_fs_in)), T_prn_true_samples); + corrected_acq_phase_samples = fmod( + (d_acq_code_phase_samples + + T_prn_diff_seconds * N_prn_diff + * static_cast(d_fs_in)), + T_prn_true_samples); if (corrected_acq_phase_samples < 0) { - corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; + corrected_acq_phase_samples = T_prn_mod_samples + + corrected_acq_phase_samples; } - delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; + delay_correction_samples = d_acq_code_phase_samples + - corrected_acq_phase_samples; d_acq_code_phase_samples = corrected_acq_phase_samples; d_carrier_doppler_hz = d_acq_carrier_doppler_hz; - d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz + / static_cast(d_fs_in); // DLL/PLL filter initialization d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz); // The carrier loop filter implements the Doppler accumulator - d_code_loop_filter.initialize(); // initialize the code filter + d_code_loop_filter.initialize(); // initialize the code filter // generate local reference ALWAYS starting at chip 1 (1 sample per chip) gps_l1_ca_code_gen_complex(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); - volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS)); + volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, + static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS)); - multicorrelator_fpga_8sc.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); + multicorrelator_fpga_8sc->set_local_code_and_taps( + static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, + d_local_code_shift_chips); for (int n = 0; n < d_n_correlator_taps; n++) { - d_correlator_outs_16sc[n] = lv_16sc_t(0,0); + d_correlator_outs_16sc[n] = lv_16sc_t(0, 0); } d_carrier_lock_fail_counter = 0; @@ -273,11 +293,15 @@ void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::start_tracking() d_code_phase_samples = d_acq_code_phase_samples; std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0,1); + sys = sys_.substr(0, 1); // DEBUG OUTPUT - std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; - LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; + std::cout << "Tracking start on channel " << d_channel << " for satellite " + << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) + << std::endl; + LOG(INFO) << "Starting tracking of satellite " + << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) + << " on channel " << d_channel; // enable tracking d_pull_in = true; @@ -285,6 +309,9 @@ void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::start_tracking() d_enable_extended_integration = false; d_preamble_synchronized = false; + // lock the channel + multicorrelator_fpga_8sc->lock_channel(); + LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz << " Code Phase correction [samples]=" << delay_correction_samples << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; @@ -301,14 +328,19 @@ gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::~gps_l1_ca_dll_pll_c_aid_tracking_fpga volk_gnsssdr_free(d_correlator_outs_16sc); delete[] d_Prompt_buffer; - multicorrelator_fpga_8sc.free(); + multicorrelator_fpga_8sc->free(); } - -int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work( + int noutput_items __attribute__((unused)), + gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + // samples offset + int samples_offset; + // Block input data and block output stream pointers Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; @@ -326,35 +358,45 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; double acq_trk_shif_correction_samples; int acq_to_trk_delay_samples; - acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; - acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); - samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; + acq_to_trk_delay_samples = d_sample_counter + - d_acq_sample_stamp; + acq_trk_shif_correction_samples = + d_correlation_length_samples + - fmod( + static_cast(acq_to_trk_delay_samples), + static_cast(d_correlation_length_samples)); + samples_offset = round( + d_acq_code_phase_samples + + acq_trk_shif_correction_samples); + current_synchro_data.Tracking_sample_counter = + d_sample_counter + samples_offset; d_sample_counter += samples_offset; // count for the processed samples d_pull_in = false; - d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GPS_TWO_PI; - current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GPS_TWO_PI; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad + * samples_offset / GPS_TWO_PI; + current_synchro_data.Carrier_phase_rads = + d_acc_carrier_phase_cycles * GPS_TWO_PI; + current_synchro_data.Carrier_Doppler_hz = + d_carrier_doppler_hz; current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; - consume_each(samples_offset); // shift input to perform alignment with local replica - multicorrelator_fpga_8sc.set_initial_sample(samples_offset); + //consume_each(samples_offset); // shift input to perform alignment with local replica + multicorrelator_fpga_8sc->set_initial_sample( + samples_offset); return 1; } // ################# CARRIER WIPEOFF AND CORRELATORS ############################## // perform carrier wipe-off and compute Early, Prompt and Late correlation - //multicorrelator_fpga_8sc.set_input_output_vectors(d_correlator_outs_16sc, in); - multicorrelator_fpga_8sc.set_output_vectors(d_correlator_outs_16sc); - multicorrelator_fpga_8sc.Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad, - d_carrier_phase_step_rad, - d_rem_code_phase_chips, - d_code_phase_step_chips, - d_correlation_length_samples); + multicorrelator_fpga_8sc->set_output_vectors( + d_correlator_outs_16sc); + multicorrelator_fpga_8sc->Carrier_wipeoff_multicorrelator_resampler( + d_rem_carrier_phase_rad, d_carrier_phase_step_rad, + d_rem_code_phase_chips, d_code_phase_step_chips, + d_correlation_length_samples); // ####### coherent intergration extension // keep the last symbols @@ -372,60 +414,108 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ bool enable_dll_pll; if (d_enable_extended_integration == true) { - long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); - if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) + long int symbol_diff = round( + 1000.0 + * ((static_cast(d_sample_counter) + + d_rem_code_phase_samples) + / static_cast(d_fs_in) + - d_preamble_timestamp_s)); + if (symbol_diff > 0 + and symbol_diff % d_extend_correlation_ms == 0) { // compute coherent integration and enable tracking loop // perform coherent integration using correlator output history // std::cout<<"##### RESET COHERENT INTEGRATION ####"<PRN) - << " pll_bw = " << d_pll_bw_hz << " [Hz], pll_narrow_bw = " << d_pll_bw_narrow_hz << " [Hz]" << std::endl - << " dll_bw = " << d_dll_bw_hz << " [Hz], dll_narrow_bw = " << d_dll_bw_narrow_hz << " [Hz]" << std::endl; + std::cout << "Enabled " + << d_extend_correlation_ms + << " [ms] extended correlator for CH " + << d_channel << " : Satellite " + << Gnss_Satellite(systemName[sys], + d_acquisition_gnss_synchro->PRN) + << " pll_bw = " << d_pll_bw_hz + << " [Hz], pll_narrow_bw = " + << d_pll_bw_narrow_hz << " [Hz]" + << std::endl << " dll_bw = " + << d_dll_bw_hz + << " [Hz], dll_narrow_bw = " + << d_dll_bw_narrow_hz << " [Hz]" + << std::endl; } // UPDATE INTEGRATION TIME - CURRENT_INTEGRATION_TIME_S = static_cast(d_extend_correlation_ms) * GPS_L1_CA_CODE_PERIOD; + CURRENT_INTEGRATION_TIME_S = + static_cast(d_extend_correlation_ms) + * GPS_L1_CA_CODE_PERIOD; enable_dll_pll = true; } else { - if(d_preamble_synchronized == true) + if (d_preamble_synchronized == true) { // continue extended coherent correlation // Compute the next buffer length based on the period of the PRN sequence and the code phase error estimation - double T_chip_seconds = 1.0 / d_code_freq_chips; - double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; - double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double T_chip_seconds = 1.0 + / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds + * GPS_L1_CA_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds + * static_cast(d_fs_in); int K_prn_samples = round(T_prn_samples); - double K_T_prn_error_samples = K_prn_samples - T_prn_samples; + double K_T_prn_error_samples = K_prn_samples + - T_prn_samples; - d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; - d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples - d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; - d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = + d_rem_code_phase_samples + - K_T_prn_error_samples; + d_rem_code_phase_integer_samples = round( + d_rem_code_phase_samples); // round to a discrete number of samples + d_correlation_length_samples = K_prn_samples + + d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = + d_rem_code_phase_samples + - d_rem_code_phase_integer_samples; // code phase step (Code resampler phase increment per sample) [chips/sample] - d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + d_code_phase_step_chips = d_code_freq_chips + / static_cast(d_fs_in); // remnant code phase [chips] - d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast(d_fs_in)); - d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + d_carrier_phase_step_rad * static_cast(d_correlation_length_samples), GPS_TWO_PI); + d_rem_code_phase_chips = + d_rem_code_phase_samples + * (d_code_freq_chips + / static_cast(d_fs_in)); + d_rem_carrier_phase_rad = + fmod( + d_rem_carrier_phase_rad + + d_carrier_phase_step_rad + * static_cast(d_correlation_length_samples), + GPS_TWO_PI); // UPDATE ACCUMULATED CARRIER PHASE - CORRECTED_INTEGRATION_TIME_S = (static_cast(d_correlation_length_samples) / static_cast(d_fs_in)); - d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GPS_TWO_PI; + CORRECTED_INTEGRATION_TIME_S = + (static_cast(d_correlation_length_samples) + / static_cast(d_fs_in)); + d_acc_carrier_phase_cycles -= + d_carrier_phase_step_rad + * d_correlation_length_samples + / GPS_TWO_PI; // disable tracking loop and inform telemetry decoder enable_dll_pll = false; @@ -434,7 +524,9 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ { // perform basic (1ms) correlation // UPDATE INTEGRATION TIME - CURRENT_INTEGRATION_TIME_S = static_cast(d_correlation_length_samples) / static_cast(d_fs_in); + CURRENT_INTEGRATION_TIME_S = + static_cast(d_correlation_length_samples) + / static_cast(d_fs_in); enable_dll_pll = true; } } @@ -442,7 +534,9 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ else { // UPDATE INTEGRATION TIME - CURRENT_INTEGRATION_TIME_S = static_cast(d_correlation_length_samples) / static_cast(d_fs_in); + CURRENT_INTEGRATION_TIME_S = + static_cast(d_correlation_length_samples) + / static_cast(d_fs_in); enable_dll_pll = true; } @@ -450,98 +544,160 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ { // ################## PLL ########################################################## // Update PLL discriminator [rads/Ti -> Secs/Ti] - d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex(d_correlator_outs_16sc[1].real(),d_correlator_outs_16sc[1].imag())) / GPS_TWO_PI; //prompt output + d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan( + std::complex( + d_correlator_outs_16sc[1].real(), + d_correlator_outs_16sc[1].imag())) + / GPS_TWO_PI; //prompt output // Carrier discriminator filter // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // Input [s/Ti] -> output [Hz] - d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, d_carr_phase_error_secs_Ti, CURRENT_INTEGRATION_TIME_S); + d_carrier_doppler_hz = + d_carrier_loop_filter.get_carrier_error(0.0, + d_carr_phase_error_secs_Ti, + CURRENT_INTEGRATION_TIME_S); // PLL to DLL assistance [Secs/Ti] - d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / GPS_L1_FREQ_HZ; + d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz + * CURRENT_INTEGRATION_TIME_S) / GPS_L1_FREQ_HZ; // code Doppler frequency update - d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ); + d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) + / GPS_L1_FREQ_HZ); // ################## DLL ########################################################## // DLL discriminator - d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(std::complex(d_correlator_outs_16sc[0].real(),d_correlator_outs_16sc[0].imag()), std::complex(d_correlator_outs_16sc[2].real(),d_correlator_outs_16sc[2].imag())); // [chips/Ti] //early and late + d_code_error_chips_Ti = dll_nc_e_minus_l_normalized( + std::complex( + d_correlator_outs_16sc[0].real(), + d_correlator_outs_16sc[0].imag()), + std::complex( + d_correlator_outs_16sc[2].real(), + d_correlator_outs_16sc[2].imag())); // [chips/Ti] //early and late // Code discriminator filter - d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco(d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] - d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S; - code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti] + d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco( + d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] + d_code_error_filt_chips_Ti = d_code_error_filt_chips_s + * CURRENT_INTEGRATION_TIME_S; + code_error_filt_secs_Ti = d_code_error_filt_chips_Ti + / d_code_freq_chips; // [s/Ti] // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### // keep alignment parameters for the next input buffer // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation double T_chip_seconds = 1.0 / d_code_freq_chips; - double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; - double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double T_prn_seconds = T_chip_seconds + * GPS_L1_CA_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds + * static_cast(d_fs_in); double K_prn_samples = round(T_prn_samples); - double K_T_prn_error_samples = K_prn_samples - T_prn_samples; + double K_T_prn_error_samples = K_prn_samples + - T_prn_samples; - d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples + code_error_filt_secs_Ti * static_cast(d_fs_in); //(code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti) * static_cast(d_fs_in); - d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples - d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; - d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = d_rem_code_phase_samples + - K_T_prn_error_samples + + code_error_filt_secs_Ti + * static_cast(d_fs_in); //(code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti) * static_cast(d_fs_in); + d_rem_code_phase_integer_samples = round( + d_rem_code_phase_samples); // round to a discrete number of samples + d_correlation_length_samples = K_prn_samples + + d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = d_rem_code_phase_samples + - d_rem_code_phase_integer_samples; - //################### PLL COMMANDS ################################################# + //################### PLL COMMANDS ################################################# //carrier phase step (NCO phase increment per sample) [rads/sample] - d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); - d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GPS_TWO_PI; + d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz + / static_cast(d_fs_in); + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad + * d_correlation_length_samples / GPS_TWO_PI; // UPDATE ACCUMULATED CARRIER PHASE - CORRECTED_INTEGRATION_TIME_S = (static_cast(d_correlation_length_samples) / static_cast(d_fs_in)); + CORRECTED_INTEGRATION_TIME_S = + (static_cast(d_correlation_length_samples) + / static_cast(d_fs_in)); //remnant carrier phase [rad] - d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GPS_TWO_PI); + d_rem_carrier_phase_rad = fmod( + d_rem_carrier_phase_rad + + GPS_TWO_PI * d_carrier_doppler_hz + * CORRECTED_INTEGRATION_TIME_S, + GPS_TWO_PI); //################### DLL COMMANDS ################################################# //code phase step (Code resampler phase increment per sample) [chips/sample] - d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + d_code_phase_step_chips = d_code_freq_chips + / static_cast(d_fs_in); //remnant code phase [chips] - d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast(d_fs_in)); + d_rem_code_phase_chips = + d_rem_code_phase_samples + * (d_code_freq_chips + / static_cast(d_fs_in)); // ####### CN0 ESTIMATION AND LOCK DETECTORS ####################################### if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) { // fill buffer with prompt correlator output values - d_Prompt_buffer[d_cn0_estimation_counter] = lv_cmake(static_cast(d_correlator_outs_16sc[1].real()), static_cast(d_correlator_outs_16sc[1].imag()) ); // prompt + d_Prompt_buffer[d_cn0_estimation_counter] = + lv_cmake( + static_cast(d_correlator_outs_16sc[1].real()), + static_cast(d_correlator_outs_16sc[1].imag())); // prompt d_cn0_estimation_counter++; } else { d_cn0_estimation_counter = 0; // Code lock indicator - d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GPS_L1_CA_CODE_LENGTH_CHIPS); + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, + CN0_ESTIMATION_SAMPLES, d_fs_in, + GPS_L1_CA_CODE_LENGTH_CHIPS); // Carrier lock indicator - d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); + d_carrier_lock_test = carrier_lock_detector( + d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); // Loss of lock detection - if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) + if (d_carrier_lock_test + < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) { d_carrier_lock_fail_counter++; } else { - if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; + if (d_carrier_lock_fail_counter > 0) + { + d_carrier_lock_fail_counter--; + } } - if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) + if (d_carrier_lock_fail_counter + > MAXIMUM_LOCK_FAIL_COUNTER) { - std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; - LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; - this->message_port_pub(pmt::mp("events"), pmt::from_long(3));//3 -> loss of lock + std::cout << "Loss of lock in channel " + << d_channel << "!" << std::endl; + LOG(INFO) << "Loss of lock in channel " + << d_channel << "!"; + this->message_port_pub(pmt::mp("events"), + pmt::from_long(3)); //3 -> loss of lock d_carrier_lock_fail_counter = 0; d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine + multicorrelator_fpga_8sc->unlock_channel(); } } // ########### Output the tracking data to navigation and PVT ########## - current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); - current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; - current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.Prompt_I = + static_cast((d_correlator_outs_16sc[1]).real()); + current_synchro_data.Prompt_Q = + static_cast((d_correlator_outs_16sc[1]).imag()); + current_synchro_data.Tracking_sample_counter = + d_sample_counter + d_correlation_length_samples; + current_synchro_data.Code_phase_samples = + d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = GPS_TWO_PI + * d_acc_carrier_phase_cycles; + current_synchro_data.Carrier_Doppler_hz = + d_carrier_doppler_hz; current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; current_synchro_data.Flag_valid_symbol_output = true; if (d_preamble_synchronized == true) { - current_synchro_data.correlation_length_ms = d_extend_correlation_ms; + current_synchro_data.correlation_length_ms = + d_extend_correlation_ms; } else { @@ -550,12 +706,18 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ } else { - current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); - current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; - current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;// todo: project the carrier doppler + current_synchro_data.Prompt_I = + static_cast((d_correlator_outs_16sc[1]).real()); + current_synchro_data.Prompt_Q = + static_cast((d_correlator_outs_16sc[1]).imag()); + current_synchro_data.Tracking_sample_counter = + d_sample_counter + d_correlation_length_samples; + current_synchro_data.Code_phase_samples = + d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = GPS_TWO_PI + * d_acc_carrier_phase_cycles; + current_synchro_data.Carrier_Doppler_hz = + d_carrier_doppler_hz; // todo: project the carrier doppler current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; } } @@ -563,15 +725,17 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ { for (int n = 0; n < d_n_correlator_taps; n++) { - d_correlator_outs_16sc[n] = lv_cmake(0,0); + d_correlator_outs_16sc[n] = lv_cmake(0, 0); } - current_synchro_data.System = {'G'}; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.System = + { 'G'}; + current_synchro_data.Tracking_sample_counter = d_sample_counter + + d_correlation_length_samples; } current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; - if(d_dump) + if (d_dump) { // MULTIPLEXED FILE RECORDING - Record results to file float prompt_I; @@ -580,57 +744,88 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ double tmp_double; prompt_I = d_correlator_outs_16sc[1].real(); prompt_Q = d_correlator_outs_16sc[1].imag(); - tmp_E = std::abs(std::complex(d_correlator_outs_16sc[0].real(),d_correlator_outs_16sc[0].imag())); - tmp_P = std::abs(std::complex(d_correlator_outs_16sc[1].real(),d_correlator_outs_16sc[1].imag())); - tmp_L = std::abs(std::complex(d_correlator_outs_16sc[2].real(),d_correlator_outs_16sc[2].imag())); + tmp_E = std::abs( + std::complex(d_correlator_outs_16sc[0].real(), + d_correlator_outs_16sc[0].imag())); + tmp_P = std::abs( + std::complex(d_correlator_outs_16sc[1].real(), + d_correlator_outs_16sc[1].imag())); + tmp_L = std::abs( + std::complex(d_correlator_outs_16sc[2].real(), + d_correlator_outs_16sc[2].imag())); try - { + { // EPR - d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_E), + sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_P), + sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_L), + sizeof(float)); // PROMPT I and Q (to analyze navigation symbols) - d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); - d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_I), + sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_Q), + sizeof(float)); // PRN start sample stamp //tmp_float=(float)d_sample_counter; - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write( + reinterpret_cast(&d_sample_counter), + sizeof(unsigned long int)); // accumulated carrier phase - d_dump_file.write(reinterpret_cast(&d_acc_carrier_phase_cycles), sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_acc_carrier_phase_cycles), + sizeof(double)); // carrier and code frequency - d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); - d_dump_file.write(reinterpret_cast(&d_code_freq_chips), sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_carrier_doppler_hz), + sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_code_freq_chips), + sizeof(double)); //PLL commands - d_dump_file.write(reinterpret_cast(&d_carr_phase_error_secs_Ti), sizeof(double)); - d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_carr_phase_error_secs_Ti), + sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_carrier_doppler_hz), + sizeof(double)); //DLL commands - d_dump_file.write(reinterpret_cast(&d_code_error_chips_Ti), sizeof(double)); - d_dump_file.write(reinterpret_cast(&d_code_error_filt_chips_Ti), sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_code_error_chips_Ti), + sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_code_error_filt_chips_Ti), + sizeof(double)); // CN0 and carrier lock test - d_dump_file.write(reinterpret_cast(&d_CN0_SNV_dB_Hz), sizeof(double)); - d_dump_file.write(reinterpret_cast(&d_carrier_lock_test), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_CN0_SNV_dB_Hz), + sizeof(double)); + d_dump_file.write( + reinterpret_cast(&d_carrier_lock_test), + sizeof(double)); // AUX vars (for debug purposes) - tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - - // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); - } + tmp_double = d_code_error_chips_Ti + * CURRENT_INTEGRATION_TIME_S; + d_dump_file.write(reinterpret_cast(&tmp_double), + sizeof(double)); + tmp_double = static_cast(d_sample_counter + + d_correlation_length_samples); + d_dump_file.write(reinterpret_cast(&tmp_double), + sizeof(double)); + } catch (const std::ifstream::failure* e) - { - LOG(WARNING) << "Exception writing trk dump file " << e->what(); - } + { + LOG(WARNING) << "Exception writing trk dump file " + << e->what(); + } } - consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates + //consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_correlation_length_samples; //count for the processed samples return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false @@ -640,8 +835,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work (int noutput_items __ void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::set_channel(unsigned int channel) { d_channel = channel; - multicorrelator_fpga_8sc.set_channel(d_channel); - + multicorrelator_fpga_8sc->set_channel(d_channel); LOG(INFO) << "Tracking Channel set to " << d_channel; // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) @@ -649,23 +843,39 @@ void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::set_channel(unsigned int channel) if (d_dump_file.is_open() == false) { try - { - d_dump_filename.append(boost::lexical_cast(d_channel)); + { + d_dump_filename.append( + boost::lexical_cast( + d_channel)); d_dump_filename.append(".dat"); - d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); - } + d_dump_file.exceptions( + std::ifstream::failbit + | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str(), + std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " + << d_channel << " Log file: " + << d_dump_filename.c_str(); + } catch (const std::ifstream::failure* e) - { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e->what(); - } + { + LOG(WARNING) << "channel " << d_channel + << " Exception opening trk dump file " + << e->what(); + } } } } -void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::set_gnss_synchro( + Gnss_Synchro* p_gnss_synchro) { d_acquisition_gnss_synchro = p_gnss_synchro; } + + +void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::reset(void) +{ + multicorrelator_fpga_8sc->unlock_channel(); +} diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h index f4f85404b..444ffbc72 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h @@ -53,28 +53,19 @@ class gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc; -typedef boost::shared_ptr - gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr; +typedef boost::shared_ptr gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr; gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr -gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc(long if_freq, - long fs_in, unsigned - int vector_length, - bool dump, - std::string dump_filename, - float pll_bw_hz, - float dll_bw_hz, - float pll_bw_narrow_hz, - float dll_bw_narrow_hz, - int extend_correlation_ms, - float early_late_space_chips); - - +gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc(long if_freq, long fs_in, unsigned +int vector_length, bool dump, std::string dump_filename, float pll_bw_hz, + float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, + int extend_correlation_ms, float early_late_space_chips, + std::string device_name, unsigned int device_base); /*! * \brief This class implements a DLL + PLL tracking loop block */ -class gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc: public gr::block +class gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc : public gr::block { public: ~gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc(); @@ -83,38 +74,30 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); - int general_work (int noutput_items, gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + int general_work(int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset(void); private: friend gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr - gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc(long if_freq, - long fs_in, unsigned - int vector_length, - bool dump, - std::string dump_filename, - float pll_bw_hz, - float dll_bw_hz, - float pll_bw_narrow_hz, - float dll_bw_narrow_hz, - int extend_correlation_ms, - float early_late_space_chips); + gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc(long if_freq, long fs_in, + unsigned + int vector_length, bool dump, std::string dump_filename, + float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, + float dll_bw_narrow_hz, int extend_correlation_ms, + float early_late_space_chips, std::string device_name, + unsigned int device_base); - gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc(long if_freq, - long fs_in, unsigned - int vector_length, - bool dump, - std::string dump_filename, - float pll_bw_hz, - float dll_bw_hz, - float pll_bw_narrow_hz, - float dll_bw_narrow_hz, - int extend_correlation_ms, - float early_late_space_chips); + gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc(long if_freq, long fs_in, unsigned + int vector_length, bool dump, std::string dump_filename, float pll_bw_hz, + float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, + int extend_correlation_ms, float early_late_space_chips, + std::string device_name, unsigned int device_base); // tracking configuration vars - unsigned int d_vector_length; - bool d_dump; + unsigned int d_vector_length;bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; unsigned int d_channel; @@ -128,9 +111,9 @@ private: gr_complex* d_ca_code; lv_16sc_t* d_ca_code_16sc; float* d_local_code_shift_chips; - //gr_complex* d_correlator_outs; lv_16sc_t* d_correlator_outs_16sc; - fpga_multicorrelator_8sc multicorrelator_fpga_8sc; + //fpga_multicorrelator_8sc multicorrelator_fpga_8sc; + std::shared_ptr multicorrelator_fpga_8sc; // remaining code phase and carrier phase between tracking loops double d_rem_code_phase_samples; @@ -161,9 +144,7 @@ private: double d_carr_phase_error_secs_Ti; double d_code_error_chips_Ti; double d_preamble_timestamp_s; - int d_extend_correlation_ms; - bool d_enable_extended_integration; - bool d_preamble_synchronized; + int d_extend_correlation_ms;bool d_enable_extended_integration;bool d_preamble_synchronized; double d_code_error_filt_chips_s; double d_code_error_filt_chips_Ti; void msg_handler_preamble_index(pmt::pmt_t msg); @@ -189,8 +170,7 @@ private: int d_carrier_lock_fail_counter; // control vars - bool d_enable_tracking; - bool d_pull_in; + bool d_enable_tracking;bool d_pull_in; // file dump std::string d_dump_filename; diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.cc b/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.cc index 3ce33110e..7d86f59e2 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.cc +++ b/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.cc @@ -60,6 +60,9 @@ // logging #include +// string manipulation +#include + #define PAGE_SIZE 0x10000 #define MAX_LENGTH_DEVICEIO_NAME 50 #define CODE_RESAMPLER_NUM_BITS_PRECISION 20 @@ -69,31 +72,18 @@ #define PHASE_CARR_NBITS 32 #define PHASE_CARR_NBITS_INT 1 #define PHASE_CARR_NBITS_FRAC PHASE_CARR_NBITS - PHASE_CARR_NBITS_INT - - - -bool fpga_multicorrelator_8sc::init(int n_correlators) -{ - d_n_correlators = n_correlators; - - // instantiate variable length vectors - d_initial_index = static_cast(volk_gnsssdr_malloc(n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); - d_initial_interp_counter = static_cast(volk_gnsssdr_malloc(n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); - - return true; -} - +#define LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT 0x20000000 +#define LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER 0x10000000 +#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 +#define TEST_REGISTER_TRACK_WRITEVAL 0x55AA void fpga_multicorrelator_8sc::set_initial_sample(int samples_offset) { d_initial_sample_counter = samples_offset; } - -bool fpga_multicorrelator_8sc::set_local_code_and_taps( - int code_length_chips, - const lv_16sc_t* local_code_in, - float *shifts_chips) +bool fpga_multicorrelator_8sc::set_local_code_and_taps(int code_length_chips, + const lv_16sc_t* local_code_in, float *shifts_chips) { d_local_code_in = local_code_in; d_shifts_chips = shifts_chips; @@ -104,7 +94,6 @@ bool fpga_multicorrelator_8sc::set_local_code_and_taps( return true; } - bool fpga_multicorrelator_8sc::set_output_vectors(lv_16sc_t* corr_out) { // Save CPU pointers @@ -113,7 +102,6 @@ bool fpga_multicorrelator_8sc::set_output_vectors(lv_16sc_t* corr_out) return true; } - void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips) { d_rem_code_phase_chips = rem_code_phase_chips; @@ -122,12 +110,9 @@ void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips) fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(); } - bool fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( - float rem_carrier_phase_in_rad, - float phase_step_rad, - float rem_code_phase_chips, - float code_phase_step_chips, + float rem_carrier_phase_in_rad, float phase_step_rad, + float rem_code_phase_chips, float code_phase_step_chips, int signal_length_samples) { update_local_code(rem_code_phase_chips); @@ -144,7 +129,7 @@ bool fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( int irq_count; ssize_t nb; // wait for interrupt - nb=read(d_fd, &irq_count, sizeof(irq_count)); + nb = read(d_device_descriptor, &irq_count, sizeof(irq_count)); if (nb != sizeof(irq_count)) { printf("Tracking_module Read failed to retrive 4 bytes!\n"); @@ -156,26 +141,47 @@ bool fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( return true; } - -fpga_multicorrelator_8sc::fpga_multicorrelator_8sc() +fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators, + std::string device_name, unsigned int device_base) { + + d_n_correlators = n_correlators; + d_device_name = device_name; + d_device_base = device_base; + d_device_descriptor = 0; + d_map_base = nullptr; + + // instantiate variable length vectors + d_initial_index = static_cast(volk_gnsssdr_malloc( + n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); + d_initial_interp_counter = static_cast(volk_gnsssdr_malloc( + n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); + d_local_code_in = nullptr; d_shifts_chips = nullptr; d_corr_out = nullptr; d_code_length_chips = 0; - d_n_correlators = 0; -} + d_rem_code_phase_chips = 0; + d_code_phase_step_chips = 0; + d_rem_carrier_phase_in_rad = 0; + d_phase_step_rad = 0; + d_rem_carr_phase_rad_int = 0; + d_phase_step_rad_int = 0; + d_initial_sample_counter = 0; + d_channel = 0; + d_correlator_length_samples = 0; +} fpga_multicorrelator_8sc::~fpga_multicorrelator_8sc() { - close(d_fd); + close(d_device_descriptor); } - bool fpga_multicorrelator_8sc::free() { // unlock the hardware + fpga_multicorrelator_8sc::unlock_channel(); // unlock the channel // free the FPGA dynamically created variables @@ -194,29 +200,40 @@ bool fpga_multicorrelator_8sc::free() return true; } - void fpga_multicorrelator_8sc::set_channel(unsigned int channel) { + char device_io_name[MAX_LENGTH_DEVICEIO_NAME]; // driver io name + d_channel = channel; - snprintf(d_device_io_name, MAX_LENGTH_DEVICEIO_NAME, "/dev/uio%d",d_channel); - printf("Opening Device Name : %s\n", d_device_io_name); + // open the device corresponding to the assigned channel + std::string mergedname; + std::stringstream devicebasetemp; - if ((d_fd = open(d_device_io_name, O_RDWR | O_SYNC )) == -1) + int numdevice = d_device_base + d_channel; + devicebasetemp << numdevice; + mergedname = d_device_name + devicebasetemp.str(); + strcpy(device_io_name, mergedname.c_str()); + printf("Opening Device Name : %s\n", device_io_name); + if ((d_device_descriptor = open(device_io_name, O_RDWR | O_SYNC)) == -1) { - LOG(WARNING) << "Cannot open deviceio" << d_device_io_name; + LOG(WARNING) << "Cannot open deviceio" << device_io_name; } - d_map_base = (volatile unsigned *)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, d_fd,0); + + d_map_base = (volatile unsigned *) mmap(NULL, PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0); if (d_map_base == (void *) -1) { - LOG(WARNING) << "Cannot map the FPGA tracking module " << d_channel << "into user memory"; + LOG(WARNING) << "Cannot map the FPGA tracking module " + << d_channel << "into user memory"; } // sanity check : check test register - unsigned writeval = 0x55AA; + unsigned writeval = TEST_REGISTER_TRACK_WRITEVAL; unsigned readval; - readval = fpga_multicorrelator_8sc::fpga_acquisition_test_register(writeval); + readval = fpga_multicorrelator_8sc::fpga_acquisition_test_register( + writeval); if (writeval != readval) { LOG(WARNING) << "Test register sanity check failed"; @@ -228,8 +245,8 @@ void fpga_multicorrelator_8sc::set_channel(unsigned int channel) } - -unsigned fpga_multicorrelator_8sc::fpga_acquisition_test_register(unsigned writeval) +unsigned fpga_multicorrelator_8sc::fpga_acquisition_test_register( + unsigned writeval) { unsigned readval; // write value to test register @@ -240,113 +257,110 @@ unsigned fpga_multicorrelator_8sc::fpga_acquisition_test_register(unsigned write return readval; } - void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(void) { - int k,s; - unsigned temp; - unsigned *ena_write_signals; - ena_write_signals = new unsigned[d_n_correlators]; - ena_write_signals[0] = 0x00000000; - ena_write_signals[1] = 0x20000000; - for (s = 2; s < d_n_correlators; s++) - { - ena_write_signals[s]= ena_write_signals[s-1]*2; //0x40000000; - } + + int k, s; + unsigned code_chip; + unsigned select_fpga_correlator; + + select_fpga_correlator = 0; for (s = 0; s < d_n_correlators; s++) { - // clear memory address counter - d_map_base[11] = 0x10000000; - // write correlator 0 + + d_map_base[11] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; for (k = 0; k < d_code_length_chips; k++) { if (lv_creal(d_local_code_in[k]) == 1) { - temp = 1; + code_chip = 1; } else { - temp = 0; + code_chip = 0; } - d_map_base[11] = 0x0C000000 | (temp & 0xFFFF) | ena_write_signals[s]; + // copy the local code to the FPGA memory one by one + d_map_base[11] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY + | code_chip | select_fpga_correlator; } + select_fpga_correlator = select_fpga_correlator + + LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; } - - delete [] ena_write_signals; } - void fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(void) { - float tempvalues[3]; - float tempvalues2[3]; - float tempvalues3[3]; + float temp_calculation; int i; for (i = 0; i < d_n_correlators; i++) { // initial index calculation - tempvalues[i] = floor(d_shifts_chips[i] + d_rem_code_phase_chips); - if (tempvalues[i] < 0) + temp_calculation = floor( + d_shifts_chips[i] + d_rem_code_phase_chips); + if (temp_calculation < 0) { - tempvalues2[i] = tempvalues[i] + d_code_length_chips; // % operator does not work as in Matlab with negative numbers + temp_calculation = temp_calculation + d_code_length_chips; // % operator does not work as in Matlab with negative numbers } - else - { - tempvalues2[i] = tempvalues[i]; - } - d_initial_index[i] = (unsigned) ((int) tempvalues2[i]) % d_code_length_chips; + d_initial_index[i] = (unsigned) ((int) temp_calculation) + % d_code_length_chips; // initial interpolator counter calculation - tempvalues3[i] = fmod(d_shifts_chips[i]+ d_rem_code_phase_chips,1.0); - if (tempvalues3[i] < 0) + temp_calculation = fmod(d_shifts_chips[i] + d_rem_code_phase_chips, + 1.0); + if (temp_calculation < 0) { - tempvalues3[i] = tempvalues3[i] + 1.0; // fmod operator does not work as in Matlab with negative numbers + temp_calculation = temp_calculation + 1.0; // fmod operator does not work as in Matlab with negative numbers } - d_initial_interp_counter[i] = (unsigned) floor(MAX_CODE_RESAMPLER_COUNTER * tempvalues3[i]); + d_initial_interp_counter[i] = (unsigned) floor( + MAX_CODE_RESAMPLER_COUNTER * temp_calculation); } } - void fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(void) { int i; for (i = 0; i < d_n_correlators; i++) { - d_map_base[1+i] = d_initial_index[i]; + d_map_base[1 + i] = d_initial_index[i]; d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i]; } d_map_base[8] = d_code_length_chips - 1; // number of samples - 1 } - void fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void) { float d_rem_carrier_phase_in_rad_temp; - d_code_phase_step_chips_num = (unsigned) roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips); + d_code_phase_step_chips_num = (unsigned) roundf( + MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips); if (d_rem_carrier_phase_in_rad > M_PI) { - d_rem_carrier_phase_in_rad_temp = -2*M_PI + d_rem_carrier_phase_in_rad; + d_rem_carrier_phase_in_rad_temp = -2 * M_PI + + d_rem_carrier_phase_in_rad; } - else if (d_rem_carrier_phase_in_rad < - M_PI) + else if (d_rem_carrier_phase_in_rad < -M_PI) { - d_rem_carrier_phase_in_rad_temp = 2*M_PI + d_rem_carrier_phase_in_rad; + d_rem_carrier_phase_in_rad_temp = 2 * M_PI + + d_rem_carrier_phase_in_rad; } else { d_rem_carrier_phase_in_rad_temp = d_rem_carrier_phase_in_rad; } - d_rem_carr_phase_rad_int = (int) roundf((fabs(d_rem_carrier_phase_in_rad_temp)/M_PI)*pow(2, PHASE_CARR_NBITS_FRAC)); + d_rem_carr_phase_rad_int = (int) roundf( + (fabs(d_rem_carrier_phase_in_rad_temp) / M_PI) + * pow(2, PHASE_CARR_NBITS_FRAC)); if (d_rem_carrier_phase_in_rad_temp < 0) { d_rem_carr_phase_rad_int = -d_rem_carr_phase_rad_int; } - d_phase_step_rad_int = (int) roundf((fabs(d_phase_step_rad)/M_PI)*pow(2, PHASE_CARR_NBITS_FRAC)); // the FPGA accepts a range for the phase step between -pi and +pi + d_phase_step_rad_int = (int) roundf( + (fabs(d_phase_step_rad) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC)); // the FPGA accepts a range for the phase step between -pi and +pi if (d_phase_step_rad < 0) { @@ -354,68 +368,60 @@ void fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void) } } - void fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(void) { d_map_base[0] = d_code_phase_step_chips_num; d_map_base[7] = d_correlator_length_samples - 1; d_map_base[9] = d_rem_carr_phase_rad_int; d_map_base[10] = d_phase_step_rad_int; - d_map_base[12] = 0; // lock the channel d_map_base[13] = d_initial_sample_counter; } - void fpga_multicorrelator_8sc::fpga_launch_multicorrelator_fpga(void) { // enable interrupts int reenable = 1; - write(d_fd, (void *)&reenable, sizeof(int)); + write(d_device_descriptor, (void *) &reenable, sizeof(int)); d_map_base[14] = 0; // writing anything to reg 14 launches the tracking } - void fpga_multicorrelator_8sc::read_tracking_gps_results(void) { - int *readval_real; - int *readval_imag; + int readval_real; + int readval_imag; int k; - readval_real = new int[d_n_correlators]; - readval_imag = new int[d_n_correlators]; - - for (k =0 ; k < d_n_correlators; k++) - { - readval_real[k] = d_map_base[1 + k]; - if (readval_real[k] >= 1048576) // 0x100000 (21 bits two's complement) - { - readval_real[k] = -2097152 + readval_real[k]; - } - readval_real[k] = readval_real[k] * 2; // the results are shifted two bits to the left due to the complex multiplier in the FPGA - - } - for (k = 0; k < d_n_correlators; k++) - { - readval_imag[k] = d_map_base[1 + d_n_correlators + k]; - if (readval_imag[k] >= 1048576) // 0x100000 (21 bits two's complement) - { - readval_imag[k] = -2097152 + readval_imag[k]; - } - readval_imag[k] = readval_imag[k] * 2; // the results are shifted two bits to the left due to the complex multiplier in the FPGA - } for (k = 0; k < d_n_correlators; k++) { - d_corr_out[k] = lv_cmake(readval_real[k], readval_imag[k]); + readval_real = d_map_base[1 + k]; + if (readval_real >= 1048576) // 0x100000 (21 bits two's complement) + { + readval_real = -2097152 + readval_real; + } + readval_real = readval_real * 2; // the results are shifted two bits to the left due to the complex multiplier in the FPGA + + readval_imag = d_map_base[1 + d_n_correlators + k]; + if (readval_imag >= 1048576) // 0x100000 (21 bits two's complement) + { + readval_imag = -2097152 + readval_imag; + } + readval_imag = readval_imag * 2; // the results are shifted two bits to the left due to the complex multiplier in the FPGA + + d_corr_out[k] = lv_cmake(readval_real, readval_imag); } - delete[] readval_real; - delete[] readval_imag; } - void fpga_multicorrelator_8sc::unlock_channel(void) { // unlock the channel to let the next samples go through d_map_base[12] = 1; // unlock the channel } + +void fpga_multicorrelator_8sc::lock_channel(void) +{ + // lock the channel for processing + d_map_base[12] = 0; // lock the channel +} + diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.h b/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.h index 0655b26e0..801ae5332 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.h +++ b/src/algorithms/tracking/libs/fpga_multicorrelator_8sc.h @@ -39,7 +39,6 @@ #include - #define MAX_LENGTH_DEVICEIO_NAME 50 /*! @@ -48,17 +47,20 @@ class fpga_multicorrelator_8sc { public: - fpga_multicorrelator_8sc(); - ~fpga_multicorrelator_8sc(); - bool init(int n_correlators); - bool set_local_code_and_taps(int code_length_chips, const lv_16sc_t* local_code_in, float *shifts_chips); - bool set_output_vectors(lv_16sc_t* corr_out); - void update_local_code(float rem_code_phase_chips); - bool Carrier_wipeoff_multicorrelator_resampler(float rem_carrier_phase_in_rad, float phase_step_rad, float rem_code_phase_chips, float code_phase_step_chips, int signal_length_samples); - bool free(); + fpga_multicorrelator_8sc(int n_correlators, std::string device_name, + unsigned int device_base); + ~fpga_multicorrelator_8sc();bool set_local_code_and_taps( + int code_length_chips, const lv_16sc_t* local_code_in, + float *shifts_chips);bool set_output_vectors(lv_16sc_t* corr_out); + void update_local_code(float rem_code_phase_chips);bool Carrier_wipeoff_multicorrelator_resampler( + float rem_carrier_phase_in_rad, float phase_step_rad, + float rem_code_phase_chips, float code_phase_step_chips, + int signal_length_samples);bool free(); void set_channel(unsigned int channel); void set_initial_sample(int samples_offset); + void lock_channel(void); + void unlock_channel(void); private: const lv_16sc_t *d_local_code_in; @@ -68,38 +70,45 @@ private: int d_n_correlators; // data related to the hardware module and the driver - char d_device_io_name[MAX_LENGTH_DEVICEIO_NAME]; // driver io name - int d_fd; // driver descriptor - volatile unsigned *d_map_base; // driver memory map + int d_device_descriptor; // driver descriptor + volatile unsigned *d_map_base; // driver memory map // configuration data received from the interface - unsigned int d_channel; // channel number - unsigned d_ncorrelators; // number of correlators + unsigned int d_channel; // channel number + unsigned d_ncorrelators; // number of correlators unsigned d_correlator_length_samples; float d_rem_code_phase_chips; float d_code_phase_step_chips; float d_rem_carrier_phase_in_rad; float d_phase_step_rad; - + // configuration data computed in the format that the FPGA expects - unsigned *d_initial_index; - unsigned *d_initial_interp_counter; + unsigned *d_initial_index; + unsigned *d_initial_interp_counter; unsigned d_code_phase_step_chips_num; int d_rem_carr_phase_rad_int; int d_phase_step_rad_int; unsigned d_initial_sample_counter; + // driver + std::string d_device_name; + unsigned int d_device_base; + + // results + //int *d_readval_real; + //int *d_readval_imag; // FPGA private functions unsigned fpga_acquisition_test_register(unsigned writeval); - void fpga_configure_tracking_gps_local_code(void); + void fpga_configure_tracking_gps_local_code(void); void fpga_compute_code_shift_parameters(void); void fpga_configure_code_parameters_in_fpga(void); void fpga_compute_signal_parameters_in_fpga(void); void fpga_configure_signal_parameters_in_fpga(void); void fpga_launch_multicorrelator_fpga(void); void read_tracking_gps_results(void); - void unlock_channel(void); + + //void unlock_channel(void); + }; - #endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */ diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc index 17d905f98..c9e9e2e08 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc @@ -29,9 +29,6 @@ * ------------------------------------------------------------------------- */ - - - #include #include #include @@ -54,21 +51,21 @@ #include -#define DMA_ACQ_TRANSFER_SIZE 4000 +#define DMA_ACQ_TRANSFER_SIZE 2046 // DMA transfer size for the acquisition #define RX_SIGNAL_MAX_VALUE 127 // 2^7 - 1 for 8-bit signed values #define NTIMES_CYCLE_THROUGH_RX_SAMPLES_FILE 50 // number of times we cycle through the file containing the received samples #define ONE_SECOND 1000000 // one second in microseconds #define FLOAT_SIZE (sizeof(float)) // size of the float variable in characters - // thread that reads the file containing the received samples, scales the samples to the dynamic range of the fixed point values, sends // the samples to the DMA and finally it stops the top block -void thread_acquisition_send_rx_samples(gr::top_block_sptr top_block, const char * file_name) +void thread_acquisition_send_rx_samples(gr::top_block_sptr top_block, + const char * file_name) { - FILE *ptr_myfile; // file descriptor - int fileLen; // length of the file containing the received samples - int tx_fd; // DMA descriptor + FILE *rx_signal_file; // file descriptor + int file_length; // length of the file containing the received samples + int dma_descr; // DMA descriptor // sleep for 1 second to give some time to GNSS-SDR to activate the acquisition module. // the acquisition module does not block the RX buffer before activation. @@ -77,113 +74,112 @@ void thread_acquisition_send_rx_samples(gr::top_block_sptr top_block, const char // we want for the test usleep(ONE_SECOND); - char *buffer_temp; // temporary buffer to convert from binary char to float and from float to char - signed char *buffer_char; // temporary buffer to store the samples to be sent to the DMA - buffer_temp = (char *)malloc(FLOAT_SIZE); // allocate space for the temporary buffer - if (!buffer_temp) - { - fprintf(stderr, "Memory error!"); - } + char *buffer_float; // temporary buffer to convert from binary char to float and from float to char + signed char *buffer_DMA; // temporary buffer to store the samples to be sent to the DMA + buffer_float = (char *) malloc(FLOAT_SIZE); // allocate space for the temporary buffer + if (!buffer_float) + { + fprintf(stderr, "Memory error!"); + } - ptr_myfile = fopen(file_name,"rb"); // file containing the received signal - if (!ptr_myfile) - { - printf("Unable to open file!"); - } + rx_signal_file = fopen(file_name, "rb"); // file containing the received signal + if (!rx_signal_file) + { + printf("Unable to open file!"); + } - // determine the length of the file that contains the received signal - fseek(ptr_myfile, 0, SEEK_END); - fileLen = ftell(ptr_myfile); - fseek(ptr_myfile, 0, SEEK_SET); + // determine the length of the file that contains the received signal + fseek(rx_signal_file, 0, SEEK_END); + file_length = ftell(rx_signal_file); + fseek(rx_signal_file, 0, SEEK_SET); // first step: check for the maximum value of the received signal - float max = 0; - float *pointer_float; - pointer_float = (float *) &buffer_temp[0]; - for (int k=0;k max) - { - max = (pointer_float[0]); - } + if (fabs(pointer_float[0]) > max) + { + max = (pointer_float[0]); + } - } + } - // go back to the beginning of the file containing the received samples - fseek(ptr_myfile, 0, SEEK_SET); + // go back to the beginning of the file containing the received samples + fseek(rx_signal_file, 0, SEEK_SET); - // allocate memory for the samples to be transferred to the DMA + // allocate memory for the samples to be transferred to the DMA - buffer_char = (signed char *)malloc(DMA_ACQ_TRANSFER_SIZE); - if (!buffer_char) - { - fprintf(stderr, "Memory error!"); - } + buffer_DMA = (signed char *) malloc(DMA_ACQ_TRANSFER_SIZE); + if (!buffer_DMA) + { + fprintf(stderr, "Memory error!"); + } - // open the DMA descriptor - tx_fd = open("/dev/loop_tx", O_WRONLY); - if ( tx_fd < 0 ) - { - printf("can't open loop device\n"); - exit(1); - } + // open the DMA descriptor + dma_descr = open("/dev/loop_tx", O_WRONLY); + if (dma_descr < 0) + { + printf("can't open loop device\n"); + exit(1); + } + // cycle through the file containing the received samples - // cycle through the file containing the received samples + for (int k = 0; k < NTIMES_CYCLE_THROUGH_RX_SAMPLES_FILE; k++) + { - for (int k=0;k DMA_ACQ_TRANSFER_SIZE) + { - fseek(ptr_myfile, 0, SEEK_SET); + transfer_size = DMA_ACQ_TRANSFER_SIZE; + num_transferred_samples = num_transferred_samples + + DMA_ACQ_TRANSFER_SIZE; - int transfer_size; - int num_transferred_samples = 0; - while (num_transferred_samples < (int) (fileLen/FLOAT_SIZE)) - { - if (((fileLen/FLOAT_SIZE) - num_transferred_samples) > DMA_ACQ_TRANSFER_SIZE) - { + } + else + { + transfer_size = file_length / FLOAT_SIZE + - num_transferred_samples; + num_transferred_samples = file_length / FLOAT_SIZE; + } + for (int t = 0; t < transfer_size; t++) + { + fread(buffer_float, FLOAT_SIZE, 1, rx_signal_file); - transfer_size = DMA_ACQ_TRANSFER_SIZE; - num_transferred_samples = num_transferred_samples + DMA_ACQ_TRANSFER_SIZE; + // specify (float) (int) for a quantization maximizing the dynamic range + buffer_DMA[t] = (signed char) ((pointer_float[0] + * (RX_SIGNAL_MAX_VALUE - 1)) / max); - } - else - { - transfer_size = fileLen/FLOAT_SIZE - num_transferred_samples; - num_transferred_samples = fileLen/FLOAT_SIZE; - } + } + //send_acquisition_gps_input_samples(buffer_DMA, transfer_size, dma_descr); + assert( + transfer_size == write(dma_descr, &buffer_DMA[0], transfer_size)); + } - for (int t=0;tstop(); - - } // ######## GNURADIO BLOCK MESSAGE RECEVER ######### @@ -204,44 +200,44 @@ public: ~GpsL1CaPcpsAcquisitionTestFpga_msg_rx(); //!< Default destructor }; - GpsL1CaPcpsAcquisitionTest_msg_fpga_rx_sptr GpsL1CaPcpsAcquisitionTestFpga_msg_rx_make() { - return GpsL1CaPcpsAcquisitionTest_msg_fpga_rx_sptr(new GpsL1CaPcpsAcquisitionTestFpga_msg_rx()); + return GpsL1CaPcpsAcquisitionTest_msg_fpga_rx_sptr( + new GpsL1CaPcpsAcquisitionTestFpga_msg_rx()); } - void GpsL1CaPcpsAcquisitionTestFpga_msg_rx::msg_handler_events(pmt::pmt_t msg) { try - { + { long int message = pmt::to_long(msg); rx_message = message; - } - catch(boost::bad_any_cast& e) - { + } + catch (boost::bad_any_cast& e) + { LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; rx_message = 0; - } + } } - GpsL1CaPcpsAcquisitionTestFpga_msg_rx::GpsL1CaPcpsAcquisitionTestFpga_msg_rx() : - gr::block("GpsL1CaPcpsAcquisitionTestFpga_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) + gr::block("GpsL1CaPcpsAcquisitionTestFpga_msg_rx", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)) { this->message_port_register_in(pmt::mp("events")); - this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CaPcpsAcquisitionTestFpga_msg_rx::msg_handler_events, this, _1)); + this->set_msg_handler(pmt::mp("events"), + boost::bind( + &GpsL1CaPcpsAcquisitionTestFpga_msg_rx::msg_handler_events, + this, _1)); rx_message = 0; } - GpsL1CaPcpsAcquisitionTestFpga_msg_rx::~GpsL1CaPcpsAcquisitionTestFpga_msg_rx() -{} +{ +} - -// ########################################################### - -class GpsL1CaPcpsAcquisitionTestFpga: public ::testing::Test +class GpsL1CaPcpsAcquisitionTestFpga : public ::testing::Test { protected: GpsL1CaPcpsAcquisitionTestFpga() @@ -253,7 +249,8 @@ protected: } ~GpsL1CaPcpsAcquisitionTestFpga() - {} + { + } void init(); @@ -264,7 +261,6 @@ protected: size_t item_size; }; - void GpsL1CaPcpsAcquisitionTestFpga::init() { gnss_synchro.Channel_ID = 0; @@ -277,21 +273,24 @@ void GpsL1CaPcpsAcquisitionTestFpga::init() config->set_property("Acquisition.if", "0"); config->set_property("Acquisition.coherent_integration_time_ms", "1"); config->set_property("Acquisition.dump", "false"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition.implementation", + "GPS_L1_CA_PCPS_Acquisition"); config->set_property("Acquisition.threshold", "0.001"); config->set_property("Acquisition.doppler_max", "5000"); config->set_property("Acquisition.doppler_step", "500"); config->set_property("Acquisition.repeat_satellite", "false"); config->set_property("Acquisition.pfa", "0.0"); config->set_property("Acquisition.select_queue_Fpga", "0"); + config->set_property("Acquisition.devicename", "/dev/uio0"); + } - - TEST_F(GpsL1CaPcpsAcquisitionTestFpga, Instantiate) { init(); - boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition", 0, 1); + boost::shared_ptr acquisition = + boost::make_shared(config.get(), + "Acquisition", 0, 1); } TEST_F(GpsL1CaPcpsAcquisitionTestFpga, ValidationOfResults) @@ -305,84 +304,102 @@ TEST_F(GpsL1CaPcpsAcquisitionTestFpga, ValidationOfResults) double expected_doppler_hz = 1680; init(); - std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition", 0, 1); + std::shared_ptr < GpsL1CaPcpsAcquisitionFpga > acquisition = + std::make_shared < GpsL1CaPcpsAcquisitionFpga + > (config.get(), "Acquisition", 0, 1); - boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionTestFpga_msg_rx_make(); + boost::shared_ptr msg_rx = + GpsL1CaPcpsAcquisitionTestFpga_msg_rx_make(); - ASSERT_NO_THROW( { - acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + ASSERT_NO_THROW( + { + acquisition->set_channel(1); + })<< "Failure setting channel." << std::endl; - ASSERT_NO_THROW( { - acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + ASSERT_NO_THROW( + { + acquisition->set_gnss_synchro(&gnss_synchro); + })<< "Failure setting gnss_synchro." << std::endl; - ASSERT_NO_THROW( { - acquisition->set_threshold(0.1); - }) << "Failure setting threshold." << std::endl; + ASSERT_NO_THROW( + { + acquisition->set_threshold(0.1); + })<< "Failure setting threshold." << std::endl; - ASSERT_NO_THROW( { - acquisition->set_doppler_max(10000); - }) << "Failure setting doppler_max." << std::endl; + ASSERT_NO_THROW( + { + acquisition->set_doppler_max(10000); + })<< "Failure setting doppler_max." << std::endl; - ASSERT_NO_THROW( { - acquisition->set_doppler_step(250); - }) << "Failure setting doppler_step." << std::endl; + ASSERT_NO_THROW( + { + acquisition->set_doppler_step(250); + })<< "Failure setting doppler_step." << std::endl; - ASSERT_NO_THROW( { - acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + ASSERT_NO_THROW( + { + acquisition->connect(top_block); + })<< "Failure connecting acquisition to the top_block." << std::endl; // uncomment the next line to load the file from the current directory std::string file = "./GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; - // uncomment the next two lines to load the file from the signal samples subdirectory + // uncomment the next two lines to load the file from the signal samples subdirectory //std::string path = std::string(TEST_PATH); //std::string file = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; const char * file_name = file.c_str(); - ASSERT_NO_THROW( { - // for the unit test use dummy blocks to make the flowgraph work and allow the acquisition message to be sent. - // in the actual system there is a flowchart running in parallel so this is not needed + ASSERT_NO_THROW( + { + // for the unit test use dummy blocks to make the flowgraph work and allow the acquisition message to be sent. + // in the actual system there is a flowchart running in parallel so this is not needed - gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); - gr::blocks::null_sink::sptr null_sink = gr::blocks::null_sink::make(sizeof(gr_complex)); - gr::blocks::throttle::sptr throttle_block = gr::blocks::throttle::make(sizeof(gr_complex),1000); + gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); + gr::blocks::null_sink::sptr null_sink = gr::blocks::null_sink::make(sizeof(gr_complex)); + gr::blocks::throttle::sptr throttle_block = gr::blocks::throttle::make(sizeof(gr_complex),1000); - top_block->connect(file_source, 0, throttle_block, 0); - top_block->connect(throttle_block, 0, null_sink, 0); - top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + top_block->connect(file_source, 0, throttle_block, 0); + top_block->connect(throttle_block, 0, null_sink, 0); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + })<< "Failure connecting the blocks of acquisition test." << std::endl; - acquisition->set_state(1); // Ensure that acquisition starts at the first state + acquisition->set_state(1); // Ensure that acquisition starts at the first state acquisition->init(); - top_block->start(); // Start the top block + top_block->start(); // Start the top block // start thread that sends the DMA samples to the FPGA - boost::thread t3{thread_acquisition_send_rx_samples, top_block, file_name}; + boost::thread t3 + { thread_acquisition_send_rx_samples, top_block, file_name }; - EXPECT_NO_THROW( { - gettimeofday(&tv, NULL); - begin = tv.tv_sec * 1000000 + tv.tv_usec; - acquisition->reset(); // launch the tracking process - top_block->wait(); - gettimeofday(&tv, NULL); - end = tv.tv_sec * 1000000 + tv.tv_usec; - }) << "Failure running the top_block." << std::endl; + EXPECT_NO_THROW( + { + gettimeofday(&tv, NULL); + begin = tv.tv_sec * 1000000 + tv.tv_usec; + acquisition->reset(); // launch the tracking process + top_block->wait(); + gettimeofday(&tv, NULL); + end = tv.tv_sec * 1000000 + tv.tv_usec; + })<< "Failure running the top_block." << std::endl; t3.join(); - std::cout << "Ran GpsL1CaPcpsAcquisitionTestFpga in " << (end - begin) << " microseconds" << std::endl; + std::cout << "Ran GpsL1CaPcpsAcquisitionTestFpga in " << (end - begin) + << " microseconds" << std::endl; - ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; + ASSERT_EQ(1, msg_rx->rx_message) + << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; - double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro.Acq_delay_samples); - float delay_error_chips = (float)(delay_error_samples * 1023 / 4000); - double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); + double delay_error_samples = std::abs( + expected_delay_samples - gnss_synchro.Acq_delay_samples); + float delay_error_chips = (float) (delay_error_samples * 1023 / 4000); + double doppler_error_hz = std::abs( + expected_doppler_hz - gnss_synchro.Acq_doppler_hz); - EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; - EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; + EXPECT_LE(doppler_error_hz, 666) + << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; + EXPECT_LT(delay_error_chips, 0.5) + << "Delay error exceeds the expected value: 0.5 chips"; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc index 64d02fb40..41a317d56 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc @@ -31,7 +31,6 @@ * ------------------------------------------------------------------------- */ - #include #include #include @@ -63,43 +62,33 @@ #include "signal_generator_flags.h" #include "interleaved_byte_to_complex_short.h" +#define DMA_TRACK_TRANSFER_SIZE 2046 // DMA transfer size for tracking +#define MIN_SAMPLES_REMAINING 20000 // number of remaining samples in the DMA that causes the CPU to stop the flowgraph (it has to be a bit alrger than 2x max packet size) +#define FIVE_SECONDS 5000000 // five seconds in microseconds -#define MAX_NUM_TEST_CASES 20 -#define MAX_INPUT_SAMPLES_PER_TEST_CASE (8184) -#define MAX_INPUT_SAMPLES_TOTAL MAX_INPUT_SAMPLES_PER_TEST_CASE*MAX_NUM_TEST_CASES -#define DMA_TRANSFER_SIZE 2046 -#define MIN_SAMPLES_REMAINING 20000 // number of remaining samples in the DMA that causes the CPU to stop the flowgraph (it has to be a bit alrger than 2x max packet size) - - -void wait(int seconds) +void send_tracking_gps_input_samples(FILE *rx_signal_file, + int num_remaining_samples, gr::top_block_sptr top_block) { - boost::this_thread::sleep_for(boost::chrono::seconds{seconds}); -} - -void send_tracking_gps_input_samples(FILE *ptr_myfile, int num_remaining_samples, gr::top_block_sptr top_block) -{ - int num_samples_transferred = 0; - static int flowgraph_stopped = 0; - - char *buffer; - - // DMA descriptor - int tx_fd; - tx_fd = open("/dev/loop_tx", O_WRONLY); - if ( tx_fd < 0 ) + int num_samples_transferred = 0; // number of samples that have been transferred to the DMA so far + static int flowgraph_stopped = 0; // flag to indicate if the flowgraph is stopped already + char *buffer_DMA; // temporary buffer to store the samples to be sent to the DMA + int dma_descr; // DMA descriptor + dma_descr = open("/dev/loop_tx", O_WRONLY); + if (dma_descr < 0) { printf("can't open loop device\n"); exit(1); } - buffer = (char *)malloc(DMA_TRANSFER_SIZE); - if (!buffer) + buffer_DMA = (char *) malloc(DMA_TRACK_TRANSFER_SIZE); + if (!buffer_DMA) { fprintf(stderr, "Memory error!"); } - while(num_remaining_samples > 0) + while (num_remaining_samples > 0) { + if (num_remaining_samples < MIN_SAMPLES_REMAINING) { if (flowgraph_stopped == 0) @@ -109,66 +98,67 @@ void send_tracking_gps_input_samples(FILE *ptr_myfile, int num_remaining_samples flowgraph_stopped = 1; } } - if (num_remaining_samples > DMA_TRANSFER_SIZE) + if (num_remaining_samples > DMA_TRACK_TRANSFER_SIZE) { - fread(buffer, DMA_TRANSFER_SIZE, 1, ptr_myfile); + fread(buffer_DMA, DMA_TRACK_TRANSFER_SIZE, 1, + rx_signal_file); - assert( DMA_TRANSFER_SIZE == write(tx_fd, &buffer[0], DMA_TRANSFER_SIZE) ); - num_remaining_samples = num_remaining_samples - DMA_TRANSFER_SIZE; - num_samples_transferred = num_samples_transferred + DMA_TRANSFER_SIZE; + assert( + DMA_TRACK_TRANSFER_SIZE == write(dma_descr, &buffer_DMA[0], DMA_TRACK_TRANSFER_SIZE)); + num_remaining_samples = num_remaining_samples + - DMA_TRACK_TRANSFER_SIZE; + num_samples_transferred = num_samples_transferred + + DMA_TRACK_TRANSFER_SIZE; } else { - fread(buffer, num_remaining_samples, 1, ptr_myfile); + fread(buffer_DMA, num_remaining_samples, 1, rx_signal_file); - assert( num_remaining_samples == write(tx_fd, &buffer[0], num_remaining_samples) ); - num_samples_transferred = num_samples_transferred + num_remaining_samples; + assert( + num_remaining_samples == write(dma_descr, &buffer_DMA[0], num_remaining_samples)); + num_samples_transferred = num_samples_transferred + + num_remaining_samples; num_remaining_samples = 0; } } - free(buffer); - close(tx_fd); + free(buffer_DMA); + close(dma_descr); } - // thread that sends the samples to the FPGA void thread(gr::top_block_sptr top_block, const char * file_name) { // file descriptor - FILE *ptr_myfile; - int fileLen; + FILE *rx_signal_file; // file descriptor + int file_length; // length of the file containing the received samples - ptr_myfile = fopen(file_name,"rb"); - if (!ptr_myfile) + rx_signal_file = fopen(file_name, "rb"); + if (!rx_signal_file) { printf("Unable to open file!"); } - fseek(ptr_myfile, 0, SEEK_END); - fileLen = ftell(ptr_myfile); - fseek(ptr_myfile, 0, SEEK_SET); + fseek(rx_signal_file, 0, SEEK_END); + file_length = ftell(rx_signal_file); + fseek(rx_signal_file, 0, SEEK_SET); - wait(20); // wait for some time to give time to the other thread to program the device + usleep(FIVE_SECONDS); // wait for some time to give time to the other thread to program the device - //send_tracking_gps_input_samples(tx_fd, ptr_myfile, fileLen); - send_tracking_gps_input_samples(ptr_myfile, fileLen, top_block); + //send_tracking_gps_input_samples(dma_descr, rx_signal_file, file_length); + send_tracking_gps_input_samples(rx_signal_file, file_length, top_block); - fclose(ptr_myfile); + fclose(rx_signal_file); } - // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class GpsL1CADllPllTrackingTestFpga_msg_rx; - typedef boost::shared_ptr GpsL1CADllPllTrackingTestFpga_msg_rx_sptr; - GpsL1CADllPllTrackingTestFpga_msg_rx_sptr GpsL1CADllPllTrackingTestFpga_msg_rx_make(); - class GpsL1CADllPllTrackingTestFpga_msg_rx : public gr::block { private: @@ -181,44 +171,46 @@ public: ~GpsL1CADllPllTrackingTestFpga_msg_rx(); //!< Default destructor }; - GpsL1CADllPllTrackingTestFpga_msg_rx_sptr GpsL1CADllPllTrackingTestFpga_msg_rx_make() { - return GpsL1CADllPllTrackingTestFpga_msg_rx_sptr(new GpsL1CADllPllTrackingTestFpga_msg_rx()); + return GpsL1CADllPllTrackingTestFpga_msg_rx_sptr( + new GpsL1CADllPllTrackingTestFpga_msg_rx()); } - void GpsL1CADllPllTrackingTestFpga_msg_rx::msg_handler_events(pmt::pmt_t msg) { try - { + { long int message = pmt::to_long(msg); rx_message = message; - } - catch(boost::bad_any_cast& e) - { + } + catch (boost::bad_any_cast& e) + { LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; rx_message = 0; - } + } } - GpsL1CADllPllTrackingTestFpga_msg_rx::GpsL1CADllPllTrackingTestFpga_msg_rx() : - gr::block("GpsL1CADllPllTrackingTestFpga_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) + gr::block("GpsL1CADllPllTrackingTestFpga_msg_rx", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)) { this->message_port_register_in(pmt::mp("events")); - this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CADllPllTrackingTestFpga_msg_rx::msg_handler_events, this, _1)); + this->set_msg_handler(pmt::mp("events"), + boost::bind( + &GpsL1CADllPllTrackingTestFpga_msg_rx::msg_handler_events, + this, _1)); rx_message = 0; } - GpsL1CADllPllTrackingTestFpga_msg_rx::~GpsL1CADllPllTrackingTestFpga_msg_rx() -{} +{ +} // ########################################################### - -class GpsL1CADllPllTrackingTestFpga: public ::testing::Test +class GpsL1CADllPllTrackingTestFpga : public ::testing::Test { public: std::string generator_binary; @@ -235,18 +227,12 @@ public: int configure_generator(); int generate_signal(); - void check_results_doppler(arma::vec true_time_s, - arma::vec true_value, - arma::vec meas_time_s, - arma::vec meas_value); + void check_results_doppler(arma::vec true_time_s, arma::vec true_value, + arma::vec meas_time_s, arma::vec meas_value); void check_results_acc_carrier_phase(arma::vec true_time_s, - arma::vec true_value, - arma::vec meas_time_s, - arma::vec meas_value); - void check_results_codephase(arma::vec true_time_s, - arma::vec true_value, - arma::vec meas_time_s, - arma::vec meas_value); + arma::vec true_value, arma::vec meas_time_s, arma::vec meas_value); + void check_results_codephase(arma::vec true_time_s, arma::vec true_value, + arma::vec meas_time_s, arma::vec meas_value); GpsL1CADllPllTrackingTestFpga() { @@ -257,7 +243,8 @@ public: } ~GpsL1CADllPllTrackingTestFpga() - {} + { + } void configure_receiver(); @@ -268,33 +255,36 @@ public: size_t item_size; }; - int GpsL1CADllPllTrackingTestFpga::configure_generator() { // Configure signal generator generator_binary = FLAGS_generator_binary; p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; - if(FLAGS_dynamic_position.empty()) + if (FLAGS_dynamic_position.empty()) { - p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(FLAGS_duration * 10); + p2 = std::string("-static_position=") + FLAGS_static_position + + std::string(",") + std::to_string(FLAGS_duration * 10); } else { - p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position); + 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] + p5 = std::string("-sampling_freq=") + + std::to_string(baseband_sampling_freq); //Baseband sampling frequency [MSps] return 0; } - int GpsL1CADllPllTrackingTestFpga::generate_signal() { int child_status; - char *const parmList[] = { &generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], NULL }; + char * const parmList[] = + { &generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], + &p4[0], &p5[0], NULL }; int pid; if ((pid = fork()) == -1) @@ -302,17 +292,18 @@ int GpsL1CADllPllTrackingTestFpga::generate_signal() else if (pid == 0) { execv(&generator_binary[0], parmList); - std::cout << "Return not expected. Must be an execv err." << std::endl; + std::cout << "Return not expected. Must be an execv err." + << std::endl; std::terminate(); } waitpid(pid, &child_status, 0); - std::cout << "Signal and Observables RINEX and RAW files created." << std::endl; + std::cout << "Signal and Observables RINEX and RAW files created." + << std::endl; return 0; } - void GpsL1CADllPllTrackingTestFpga::configure_receiver() { gnss_synchro.Channel_ID = 0; @@ -321,9 +312,11 @@ void GpsL1CADllPllTrackingTestFpga::configure_receiver() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = FLAGS_test_satellite_PRN; - config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(baseband_sampling_freq)); + config->set_property("GNSS-SDR.internal_fs_hz", + std::to_string(baseband_sampling_freq)); // Set Tracking - config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking_Fpga"); + config->set_property("Tracking_1C.implementation", + "GPS_L1_CA_DLL_PLL_C_Aid_Tracking_Fpga"); config->set_property("Tracking_1C.item_type", "cshort"); config->set_property("Tracking_1C.if", "0"); config->set_property("Tracking_1C.dump", "true"); @@ -331,13 +324,12 @@ void GpsL1CADllPllTrackingTestFpga::configure_receiver() config->set_property("Tracking_1C.pll_bw_hz", "30.0"); config->set_property("Tracking_1C.dll_bw_hz", "2.0"); config->set_property("Tracking_1C.early_late_space_chips", "0.5"); + config->set_property("Tracking_1C.devicename", "/dev/uio"); + config->set_property("Tracking_1C.device_base", "1"); } - void GpsL1CADllPllTrackingTestFpga::check_results_doppler(arma::vec true_time_s, - arma::vec true_value, - arma::vec meas_time_s, - arma::vec meas_value) + arma::vec true_value, arma::vec meas_time_s, arma::vec meas_value) { //1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -360,14 +352,13 @@ void GpsL1CADllPllTrackingTestFpga::check_results_doppler(arma::vec true_time_s, //5. report std::cout << std::setprecision(10) << "TRK Doppler RMSE=" << rmse - << ", mean=" << error_mean - << ", stdev="<< sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; + << ", mean=" << error_mean << ", stdev=" << sqrt(error_var) + << " (max,min)=" << max_error << "," << min_error << " [Hz]" + << std::endl; } - -void GpsL1CADllPllTrackingTestFpga::check_results_acc_carrier_phase(arma::vec true_time_s, - arma::vec true_value, - arma::vec meas_time_s, +void GpsL1CADllPllTrackingTestFpga::check_results_acc_carrier_phase( + arma::vec true_time_s, arma::vec true_value, arma::vec meas_time_s, arma::vec meas_value) { //1. True value interpolation to match the measurement times @@ -391,15 +382,14 @@ void GpsL1CADllPllTrackingTestFpga::check_results_acc_carrier_phase(arma::vec tr //5. report std::cout << std::setprecision(10) << "TRK acc carrier phase RMSE=" << rmse - << ", mean=" << error_mean - << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; + << ", mean=" << error_mean << ", stdev=" << sqrt(error_var) + << " (max,min)=" << max_error << "," << min_error << " [Hz]" + << std::endl; } - -void GpsL1CADllPllTrackingTestFpga::check_results_codephase(arma::vec true_time_s, - arma::vec true_value, - arma::vec meas_time_s, +void GpsL1CADllPllTrackingTestFpga::check_results_codephase( + arma::vec true_time_s, arma::vec true_value, arma::vec meas_time_s, arma::vec meas_value) { //1. True value interpolation to match the measurement times @@ -422,11 +412,11 @@ void GpsL1CADllPllTrackingTestFpga::check_results_codephase(arma::vec true_time_ //5. report std::cout << std::setprecision(10) << "TRK code phase RMSE=" << rmse - << ", mean=" << error_mean - << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Chips]" << std::endl; + << ", mean=" << error_mean << ", stdev=" << sqrt(error_var) + << " (max,min)=" << max_error << "," << min_error << " [Chips]" + << std::endl; } - TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) { configure_generator(); @@ -447,69 +437,84 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); true_obs_file.append(".dat"); - ASSERT_NO_THROW({ - if (true_obs_data.open_obs_file(true_obs_file) == false) - { - throw std::exception(); - }; - }) << "Failure opening true observables file" << std::endl; + ASSERT_NO_THROW( + { + if (true_obs_data.open_obs_file(true_obs_file) == false) + { + throw std::exception(); + }; + })<< "Failure opening true observables file" << std::endl; top_block = gr::make_top_block("Tracking test"); - std::shared_ptr tracking = std::make_shared(config.get(), "Tracking_1C", 1, 1); + std::shared_ptr tracking = std::make_shared + < GpsL1CaDllPllCAidTrackingFpga + > (config.get(), "Tracking_1C", 1, 1); - boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTestFpga_msg_rx_make(); + boost::shared_ptr msg_rx = + GpsL1CADllPllTrackingTestFpga_msg_rx_make(); // load acquisition data based on the first epoch of the true observations - ASSERT_NO_THROW({ - if (true_obs_data.read_binary_obs() == false) - { - throw std::exception(); - }; - }) << "Failure reading true observables file" << std::endl; + ASSERT_NO_THROW( + { + if (true_obs_data.read_binary_obs() == false) + { + throw std::exception(); + }; + })<< "Failure reading true observables file" << std::endl; //restart the epoch counter true_obs_data.restart(); - std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; - gnss_synchro.Acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD; + std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz + << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips + << std::endl; + gnss_synchro.Acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS + - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) + * baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD; gnss_synchro.Acq_doppler_hz = true_obs_data.doppler_l1_hz; gnss_synchro.Acq_samplestamp_samples = 0; - ASSERT_NO_THROW( { - tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + ASSERT_NO_THROW( + { + tracking->set_channel(gnss_synchro.Channel_ID); + })<< "Failure setting channel." << std::endl; - ASSERT_NO_THROW( { - tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + ASSERT_NO_THROW( + { + tracking->set_gnss_synchro(&gnss_synchro); + })<< "Failure setting gnss_synchro." << std::endl; - ASSERT_NO_THROW( { - tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + ASSERT_NO_THROW( + { + tracking->connect(top_block); + })<< "Failure connecting tracking to the top_block." << std::endl; - ASSERT_NO_THROW( { - gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); - top_block->connect(tracking->get_right_block(), 0, sink, 0); - top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of tracking test." << std::endl; + ASSERT_NO_THROW( + { + gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); + top_block->connect(tracking->get_right_block(), 0, sink, 0); + top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + })<< "Failure connecting the blocks of tracking test." << std::endl; tracking->start_tracking(); // assemble again the file name in a null terminated string (not available by default in the main program flow) - std::string file = "./" + filename_raw_data; + std::string file = "./" + filename_raw_data; const char * file_name = file.c_str(); // start thread that sends the DMA samples to the FPGA - boost::thread t{thread, top_block, file_name}; + boost::thread t + { thread, top_block, file_name }; - EXPECT_NO_THROW( { - gettimeofday(&tv, NULL); - begin = tv.tv_sec * 1000000 + tv.tv_usec; - top_block->run(); // Start threads and wait - tracking.reset(); - gettimeofday(&tv, NULL); - end = tv.tv_sec * 1000000 + tv.tv_usec; - }) << "Failure running the top_block." << std::endl; + EXPECT_NO_THROW( + { + gettimeofday(&tv, NULL); + begin = tv.tv_sec * 1000000 + tv.tv_usec; + top_block->run(); // Start threads and wait + tracking->reset();// unlock the channel + gettimeofday(&tv, NULL); + end = tv.tv_sec * 1000000 + tv.tv_usec; + })<< "Failure running the top_block." << std::endl; // wait until child thread terminates t.join(); @@ -526,10 +531,11 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) arma::vec true_tow_s = arma::zeros(nepoch, 1); long int epoch_counter = 0; - while(true_obs_data.read_binary_obs()) + while (true_obs_data.read_binary_obs()) { true_timestamp_s(epoch_counter) = true_obs_data.signal_timestamp_s; - true_acc_carrier_phase_cycles(epoch_counter) = true_obs_data.acc_carrier_phase_cycles; + true_acc_carrier_phase_cycles(epoch_counter) = + true_obs_data.acc_carrier_phase_cycles; true_Doppler_Hz(epoch_counter) = true_obs_data.doppler_l1_hz; true_prn_delay_chips(epoch_counter) = true_obs_data.prn_delay_chips; true_tow_s(epoch_counter) = true_obs_data.tow; @@ -538,12 +544,13 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) //load the measured values tracking_dump_reader trk_dump; - ASSERT_NO_THROW({ - if (trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")) == false) - { - throw std::exception(); - }; - }) << "Failure opening tracking dump file" << std::endl; + ASSERT_NO_THROW( + { + if (trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")) == false) + { + throw std::exception(); + }; + })<< "Failure opening tracking dump file" << std::endl; nepoch = trk_dump.num_epochs(); std::cout << "Measured observation epochs=" << nepoch << std::endl; @@ -554,15 +561,23 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) arma::vec trk_prn_delay_chips = arma::zeros(nepoch, 1); epoch_counter = 0; - while(trk_dump.read_binary_obs()) + while (trk_dump.read_binary_obs()) { - trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(baseband_sampling_freq); - trk_acc_carrier_phase_cycles(epoch_counter) = trk_dump.acc_carrier_phase_rad / GPS_TWO_PI; + trk_timestamp_s(epoch_counter) = + static_cast(trk_dump.PRN_start_sample_count) + / static_cast(baseband_sampling_freq); + trk_acc_carrier_phase_cycles(epoch_counter) = + trk_dump.acc_carrier_phase_rad / GPS_TWO_PI; trk_Doppler_Hz(epoch_counter) = trk_dump.carrier_doppler_hz; - double delay_chips = GPS_L1_CA_CODE_LENGTH_CHIPS - - GPS_L1_CA_CODE_LENGTH_CHIPS - * (fmod((static_cast(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) /1.0e-3); + double delay_chips = + GPS_L1_CA_CODE_LENGTH_CHIPS + - GPS_L1_CA_CODE_LENGTH_CHIPS + * (fmod( + (static_cast(trk_dump.PRN_start_sample_count) + + trk_dump.aux1) + / static_cast(baseband_sampling_freq), + 1.0e-3) / 1.0e-3); trk_prn_delay_chips(epoch_counter) = delay_chips; epoch_counter++; @@ -570,16 +585,27 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) //Align initial measurements and cut the tracking pull-in transitory double pull_in_offset_s = 1.0; - arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first"); + arma::uvec initial_meas_point = arma::find( + trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, + "first"); - trk_timestamp_s = trk_timestamp_s.subvec(initial_meas_point(0), trk_timestamp_s.size() - 1); - trk_acc_carrier_phase_cycles = trk_acc_carrier_phase_cycles.subvec(initial_meas_point(0), trk_acc_carrier_phase_cycles.size() - 1); - trk_Doppler_Hz = trk_Doppler_Hz.subvec(initial_meas_point(0), trk_Doppler_Hz.size() - 1); - trk_prn_delay_chips = trk_prn_delay_chips.subvec(initial_meas_point(0), trk_prn_delay_chips.size() - 1); + trk_timestamp_s = trk_timestamp_s.subvec(initial_meas_point(0), + trk_timestamp_s.size() - 1); + trk_acc_carrier_phase_cycles = trk_acc_carrier_phase_cycles.subvec( + initial_meas_point(0), trk_acc_carrier_phase_cycles.size() - 1); + trk_Doppler_Hz = trk_Doppler_Hz.subvec(initial_meas_point(0), + trk_Doppler_Hz.size() - 1); + trk_prn_delay_chips = trk_prn_delay_chips.subvec(initial_meas_point(0), + trk_prn_delay_chips.size() - 1); - check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz); - check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips); - check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); + check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, + trk_Doppler_Hz); + check_results_codephase(true_timestamp_s, true_prn_delay_chips, + trk_timestamp_s, trk_prn_delay_chips); + check_results_acc_carrier_phase(true_timestamp_s, + true_acc_carrier_phase_cycles, trk_timestamp_s, + trk_acc_carrier_phase_cycles); - std::cout << "Signal tracking completed in " << (end - begin) << " microseconds" << std::endl; + std::cout << "Signal tracking completed in " << (end - begin) + << " microseconds" << std::endl; }