diff --git a/src/algorithms/libs/gnss_sdr_valve.cc b/src/algorithms/libs/gnss_sdr_valve.cc index b49ab50f9..3b8b3a56d 100644 --- a/src/algorithms/libs/gnss_sdr_valve.cc +++ b/src/algorithms/libs/gnss_sdr_valve.cc @@ -2,6 +2,7 @@ * \file gnss_sdr_valve.cc * \brief Implementation of a GNU Radio block that sends a STOP message to the * control queue right after a specific number of samples have passed through it. + * \author Javier Arribas, 2018. jarribas(at)cttc.es * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com * * @@ -39,42 +40,65 @@ gnss_sdr_valve::gnss_sdr_valve(size_t sizeof_stream_item, unsigned long long nitems, - gr::msg_queue::sptr queue) : gr::sync_block("valve", - gr::io_signature::make(1, 1, sizeof_stream_item), - gr::io_signature::make(1, 1, sizeof_stream_item)), - d_nitems(nitems), - d_ncopied_items(0), - d_queue(queue) + gr::msg_queue::sptr queue, bool stop_flowgraph) : gr::sync_block("valve", + gr::io_signature::make(1, 1, sizeof_stream_item), + gr::io_signature::make(1, 1, sizeof_stream_item)), + d_nitems(nitems), + d_ncopied_items(0), + d_queue(queue), + d_stop_flowgraph(stop_flowgraph) { + d_open_valve = false; } -boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue) +boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue, bool stop_flowgraph) { - boost::shared_ptr valve_(new gnss_sdr_valve(sizeof_stream_item, nitems, queue)); + boost::shared_ptr valve_(new gnss_sdr_valve(sizeof_stream_item, nitems, queue, stop_flowgraph)); return valve_; } +boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue) +{ + boost::shared_ptr valve_(new gnss_sdr_valve(sizeof_stream_item, nitems, queue, false)); + return valve_; +} +void gnss_sdr_valve::open_valve() +{ + d_open_valve = true; +} int gnss_sdr_valve::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - if (d_ncopied_items >= d_nitems) + if (d_open_valve == false) { - ControlMessageFactory *cmf = new ControlMessageFactory(); - d_queue->handle(cmf->GetQueueMessage(200, 0)); - LOG(INFO) << "Stopping receiver, " << d_ncopied_items << " samples processed"; - delete cmf; - return -1; // Done! + if (d_ncopied_items >= d_nitems) + { + ControlMessageFactory *cmf = new ControlMessageFactory(); + d_queue->handle(cmf->GetQueueMessage(200, 0)); + LOG(INFO) << "Stopping receiver, " << d_ncopied_items << " samples processed"; + delete cmf; + if (d_stop_flowgraph) + { + return -1; // Done! + } + else + { + usleep(1000000); + return 0; //do not produce or consume + } + } + unsigned long long n = std::min(d_nitems - d_ncopied_items, static_cast(noutput_items)); + if (n == 0) return 0; + memcpy(output_items[0], input_items[0], n * input_signature()->sizeof_stream_item(0)); + d_ncopied_items += n; + return n; + } + else + { + memcpy(output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item(0)); + return noutput_items; } - unsigned long long n = std::min(d_nitems - d_ncopied_items, static_cast(noutput_items)); - if (n == 0) return 0; - memcpy(output_items[0], input_items[0], n * input_signature()->sizeof_stream_item(0)); - //for(long long i = 0; i++; i #include - boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue); +boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, + unsigned long long nitems, + gr::msg_queue::sptr queue, + bool stop_flowgraph); /*! * \brief Implementation of a GNU Radio block that sends a STOP message to the * control queue right after a specific number of samples have passed through it. @@ -50,14 +54,24 @@ class gnss_sdr_valve : public gr::sync_block friend boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue); - gnss_sdr_valve(size_t sizeof_stream_item, + friend boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, - gr::msg_queue::sptr queue); + gr::msg_queue::sptr queue, + bool stop_flowgraph); + + unsigned long long d_nitems; unsigned long long d_ncopied_items; gr::msg_queue::sptr d_queue; + bool d_stop_flowgraph; + bool d_open_valve; public: + gnss_sdr_valve(size_t sizeof_stream_item, + unsigned long long nitems, + gr::msg_queue::sptr queue, bool stop_flowgraph); + void open_valve(); + int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/src/tests/common-files/tracking_tests_flags.h b/src/tests/common-files/tracking_tests_flags.h index 6050ccd5c..2ff85dabf 100644 --- a/src/tests/common-files/tracking_tests_flags.h +++ b/src/tests/common-files/tracking_tests_flags.h @@ -67,6 +67,9 @@ DEFINE_double(acq_Delay_error_chips_start, 2.0, "Acquisition Code Delay error st DEFINE_double(acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Chips]"); DEFINE_double(acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Chips]"); +DEFINE_double(acq_to_trk_delay_s, 0.0, "Acquisition to Tracking delay value [s]"); + + DEFINE_int64(skip_samples, 0, "Skip an initial transitory in the processed signal file capture [samples]"); DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc index 0daa3cf59..6b33a2c33 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc @@ -33,7 +33,9 @@ #include "GPS_L1_CA.h" #include "gnss_block_factory.h" +#include "control_message_factory.h" #include "tracking_interface.h" +#include "gnss_sdr_valve.h" #include "gps_l2_m_pcps_acquisition.h" #include "gps_l1_ca_pcps_acquisition.h" #include "gps_l1_ca_pcps_acquisition_fine_doppler.h" @@ -56,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -186,6 +189,8 @@ public: std::shared_ptr config; Gnss_Synchro gnss_synchro; size_t item_size; + + gr::msg_queue::sptr queue; }; @@ -658,6 +663,18 @@ TEST_F(TrackingPullInTest, ValidationOfResults) << " [Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]" << " Acquisition SampleStamp is " << acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second << std::endl; } + + // create the msg queue for valve + + queue = gr::msg_queue::make(0); + boost::shared_ptr reseteable_valve; + long long int acq_to_trk_delay_samples = ceil(static_cast(FLAGS_fs_gen_sps) * FLAGS_acq_to_trk_delay_s); + boost::shared_ptr resetable_valve_(new gnss_sdr_valve(sizeof(gr_complex), acq_to_trk_delay_samples, queue, false)); + + std::shared_ptr control_message_factory_; + std::shared_ptr>> control_messages_; + + //CN0 LOOP std::vector> pull_in_results_v_v; @@ -710,7 +727,15 @@ TEST_F(TrackingPullInTest, ValidationOfResults) gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); top_block->connect(gr_interleaved_char_to_complex, 0, head_samples, 0); - top_block->connect(head_samples, 0, tracking->get_left_block(), 0); + if (acq_to_trk_delay_samples > 0) + { + top_block->connect(head_samples, 0, resetable_valve_, 0); + top_block->connect(resetable_valve_, 0, tracking->get_left_block(), 0); + } + else + { + top_block->connect(head_samples, 0, tracking->get_left_block(), 0); + } top_block->connect(tracking->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample @@ -721,18 +746,46 @@ TEST_F(TrackingPullInTest, ValidationOfResults) //***** STEP 5: Perform the signal tracking and read the results ***** //******************************************************************** std::cout << "--- START TRACKING WITH PULL-IN ERROR: " << acq_doppler_error_hz_values.at(current_acq_doppler_error_idx) << " [Hz] and " << acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) << " [Chips] ---" << std::endl; - tracking->start_tracking(); std::chrono::time_point start, end; - EXPECT_NO_THROW({ - start = std::chrono::system_clock::now(); - top_block->run(); // Start threads and wait - end = std::chrono::system_clock::now(); - }) << "Failure running the top_block."; + if (acq_to_trk_delay_samples > 0) + { + EXPECT_NO_THROW({ + start = std::chrono::system_clock::now(); + std::cout << "--- SIMULATING A PULL-IN DELAY OF " << FLAGS_acq_to_trk_delay_s << " SECONDS ---\n"; + top_block->start(); + std::cout << " Waiting for valve...\n"; + //wait the valve message indicating the circulation of the amount of samples of the delay + gr::message::sptr queue_message = queue->delete_head(); + if (queue_message != 0) + { + control_messages_ = control_message_factory_->GetControlMessages(queue_message); + } + else + { + control_messages_->clear(); + } + std::cout << " Starting tracking...\n"; + tracking->start_tracking(); + resetable_valve_->open_valve(); + std::cout << " Waiting flowgraph..\n"; + top_block->wait(); + end = std::chrono::system_clock::now(); + }) << "Failure running the top_block."; + } + else + { + tracking->start_tracking(); + std::chrono::time_point start, end; + EXPECT_NO_THROW({ + start = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + }) << "Failure running the top_block."; + } std::chrono::duration elapsed_seconds = end - start; std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; - pull_in_results_v.push_back(msg_rx->rx_message != 3); //save last asynchronous tracking message in order to detect a loss of lock //********************************