mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	Patch submitted by Marc Molina: Improving PCPS Acquisition with some VOLK instructions. Enabling the secondary spreading code in Galileo acquisition. Adding Signal Generator to GNSS-SDR.
git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@397 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
		| @@ -25,6 +25,7 @@ add_subdirectory(observables) | ||||
| add_subdirectory(telemetry_decoder) | ||||
| add_subdirectory(output_filter) | ||||
| add_subdirectory(resampler) | ||||
| add_subdirectory(signal_generator) | ||||
| add_subdirectory(signal_source) | ||||
| add_subdirectory(input_filter) | ||||
| add_subdirectory(tracking) | ||||
|   | ||||
| @@ -71,17 +71,20 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( | ||||
|             fs_in_ | ||||
|             / (Galileo_E1_CODE_CHIP_RATE_HZ | ||||
|                     / Galileo_E1_B_CODE_LENGTH_CHIPS)); | ||||
|  | ||||
|     int samples_per_ms = vector_length_ / 4; | ||||
|  | ||||
|     code_ = new gr_complex[vector_length_]; | ||||
|     vector_length_ = samples_per_ms * 4; | ||||
|  | ||||
|     code_ = new gr_complex[samples_per_ms*sampled_ms_]; | ||||
|  | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|         { | ||||
|             item_size_ = sizeof(gr_complex); | ||||
|             acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, | ||||
|                     shift_resolution_, if_, fs_in_, samples_per_ms, queue_, | ||||
|                     dump_, dump_filename_); | ||||
|             stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
|                     shift_resolution_, if_, fs_in_, samples_per_ms, vector_length_, | ||||
|                     queue_, dump_, dump_filename_); | ||||
|             stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, samples_per_ms * sampled_ms_); | ||||
|             DLOG(INFO) << "stream_to_vector(" | ||||
|                     << stream_to_vector_->unique_id() << ")"; | ||||
|             DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() | ||||
| @@ -115,6 +118,7 @@ GalileoE1PcpsAmbiguousAcquisition::set_channel(unsigned int channel) | ||||
| void | ||||
| GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) | ||||
| { | ||||
|  | ||||
| 	float pfa = configuration_->property(role_+ boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0); | ||||
|  | ||||
| 	if(pfa==0.0) pfa = configuration_->property(role_+".pfa", 0.0); | ||||
| @@ -124,7 +128,7 @@ GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) | ||||
| 		threshold_ = threshold; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|     { | ||||
| 		threshold_ = calculate_threshold(pfa); | ||||
| 	} | ||||
|  | ||||
| @@ -202,16 +206,32 @@ GalileoE1PcpsAmbiguousAcquisition::mag() | ||||
|  | ||||
| void | ||||
| GalileoE1PcpsAmbiguousAcquisition::init() | ||||
| { | ||||
|     acquisition_cc_->init(); | ||||
|     set_local_code(); | ||||
| } | ||||
|  | ||||
| void | ||||
| GalileoE1PcpsAmbiguousAcquisition::set_local_code() | ||||
| { | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|         { | ||||
|             bool cboc = configuration_->property( | ||||
|                     "Acquisition" + boost::lexical_cast<std::string>(channel_) | ||||
|                             + ".cboc", false); | ||||
|             galileo_e1_code_gen_complex_sampled(code_, gnss_synchro_->Signal, | ||||
|                     cboc, gnss_synchro_->PRN, fs_in_, 0); | ||||
|  | ||||
|             std::complex<float> * code = new std::complex<float>[vector_length_]; | ||||
|  | ||||
|             galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, | ||||
|                     cboc, gnss_synchro_->PRN, fs_in_, 0, false); | ||||
|  | ||||
|             for (unsigned int i = 0; i < sampled_ms_/4; i++) | ||||
|                 { | ||||
|                     memcpy(&(code_[i*vector_length_]), code, | ||||
|                            sizeof(gr_complex)*vector_length_); | ||||
|                 } | ||||
|  | ||||
|             acquisition_cc_->set_local_code(code_); | ||||
|             acquisition_cc_->init(); | ||||
|         } | ||||
| } | ||||
|  | ||||
| @@ -227,8 +247,6 @@ GalileoE1PcpsAmbiguousAcquisition::reset() | ||||
|  | ||||
| float GalileoE1PcpsAmbiguousAcquisition::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_) | ||||
| 	{ | ||||
|   | ||||
| @@ -113,6 +113,12 @@ public: | ||||
|      */ | ||||
|     void init(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Sets local code for Galileo E1 PCPS acquisition algorithm. | ||||
|      */ | ||||
|  | ||||
|     void set_local_code(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|   | ||||
| @@ -65,7 +65,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | ||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     if_ = configuration_->property(role + ".ifreq", 0); | ||||
|     dump_ = configuration_->property(role + ".dump", false); | ||||
|     shift_resolution_ = configuration_->property(role + ".doppler_max", 15); | ||||
|     shift_resolution_ = configuration_->property(role + ".doppler_max", 10000); | ||||
|     sampled_ms_ = configuration_->property(role + ".sampled_ms", 1); | ||||
|     dump_filename_ = configuration_->property(role + ".dump_filename", | ||||
|             default_dump_filename); | ||||
| @@ -74,16 +74,16 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | ||||
|     vector_length_ = round(fs_in_ | ||||
|             / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||
|  | ||||
|     code_= new gr_complex[vector_length_]; | ||||
|     code_= new gr_complex[vector_length_ * sampled_ms_]; | ||||
|  | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|     { | ||||
|         item_size_ = sizeof(gr_complex); | ||||
|         acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, | ||||
|                 shift_resolution_, if_, fs_in_, vector_length_, queue_, | ||||
|                 shift_resolution_, if_, fs_in_, vector_length_, vector_length_, queue_, | ||||
|                 dump_, dump_filename_); | ||||
|  | ||||
|         stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
|         stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_*sampled_ms_); | ||||
|  | ||||
|         DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() | ||||
|                 << ")"; | ||||
| @@ -123,13 +123,13 @@ void GpsL1CaPcpsAcquisition::set_threshold(float threshold) | ||||
|                  pfa = configuration_->property(role_+".pfa", 0.0); | ||||
|         } | ||||
| 	if(pfa==0.0) | ||||
| 	{ | ||||
| 		threshold_ = threshold; | ||||
| 	} | ||||
| 		{ | ||||
| 			threshold_ = threshold; | ||||
| 		} | ||||
| 	else | ||||
| 	{ | ||||
| 		threshold_ = calculate_threshold(pfa); | ||||
| 	} | ||||
| 		{ | ||||
| 			threshold_ = calculate_threshold(pfa); | ||||
| 		} | ||||
|  | ||||
| 	DLOG(INFO) <<"Channel "<<channel_<<" Threshold = " << threshold_; | ||||
|  | ||||
| @@ -195,15 +195,29 @@ signed int GpsL1CaPcpsAcquisition::mag() | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaPcpsAcquisition::init(){ | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|     { | ||||
|     	gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); | ||||
|     	acquisition_cc_->set_local_code(code_); | ||||
|         acquisition_cc_->init(); | ||||
|     } | ||||
| void GpsL1CaPcpsAcquisition::init() | ||||
| { | ||||
|     acquisition_cc_->init(); | ||||
|     set_local_code(); | ||||
| } | ||||
|  | ||||
| void GpsL1CaPcpsAcquisition::set_local_code() | ||||
| { | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|     { | ||||
|         std::complex<float>* code = new std::complex<float>[vector_length_]; | ||||
|  | ||||
|         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_); | ||||
|             } | ||||
|  | ||||
|         acquisition_cc_->set_local_code(code_); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void GpsL1CaPcpsAcquisition::reset() | ||||
| { | ||||
| @@ -238,9 +252,9 @@ float GpsL1CaPcpsAcquisition::calculate_threshold(float pfa) | ||||
| void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|     { | ||||
|         top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0); | ||||
|     } | ||||
|         { | ||||
|             top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0); | ||||
|         } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  * \authors <ul> | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          </ul> * | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
| @@ -116,6 +116,12 @@ public: | ||||
|      */ | ||||
|     void init(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Sets local code for GPS L1/CA PCPS acquisition algorithm. | ||||
|      */ | ||||
|  | ||||
|     void set_local_code(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|   | ||||
| @@ -146,10 +146,17 @@ signed int GpsL1CaPcpsAcquisitionFineDoppler::mag() | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaPcpsAcquisitionFineDoppler::init(){ | ||||
|     	gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); | ||||
|     	acquisition_cc_->set_local_code(code_); | ||||
|         acquisition_cc_->init(); | ||||
| void GpsL1CaPcpsAcquisitionFineDoppler::init() | ||||
| { | ||||
|     acquisition_cc_->init(); | ||||
|     set_local_code(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaPcpsAcquisitionFineDoppler::set_local_code() | ||||
| { | ||||
|     gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); | ||||
|     acquisition_cc_->set_local_code(code_); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -115,6 +115,8 @@ public: | ||||
|      */ | ||||
|     void init(); | ||||
|  | ||||
|     void set_local_code(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|   | ||||
| @@ -145,12 +145,17 @@ signed int GpsL1CaPcpsAssistedAcquisition::mag() | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaPcpsAssistedAcquisition::init(){ | ||||
|     	gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); | ||||
|     	acquisition_cc_->set_local_code(code_); | ||||
|         acquisition_cc_->init(); | ||||
| void GpsL1CaPcpsAssistedAcquisition::init() | ||||
| { | ||||
|     acquisition_cc_->init(); | ||||
|     set_local_code(); | ||||
| } | ||||
|  | ||||
| void GpsL1CaPcpsAssistedAcquisition::set_local_code() | ||||
| { | ||||
|     gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); | ||||
|     acquisition_cc_->set_local_code(code_); | ||||
| } | ||||
|  | ||||
| void GpsL1CaPcpsAssistedAcquisition::reset() | ||||
| { | ||||
|   | ||||
| @@ -115,6 +115,8 @@ public: | ||||
|      */ | ||||
|     void init(); | ||||
|  | ||||
|     void set_local_code(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  * \authors <ul> | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          <li> Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
| @@ -43,25 +44,25 @@ | ||||
| using google::LogMessage; | ||||
|  | ||||
| pcps_acquisition_cc_sptr pcps_make_acquisition_cc( | ||||
|         unsigned int sampled_ms, unsigned int doppler_max, long freq, | ||||
|         long fs_in, int samples_per_ms, gr::msg_queue::sptr queue, bool dump, | ||||
|         std::string dump_filename) | ||||
|         unsigned int sampled_ms, unsigned int doppler_max, | ||||
|         long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||
|         gr::msg_queue::sptr queue, bool dump, std::string dump_filename) | ||||
| { | ||||
|  | ||||
|     return pcps_acquisition_cc_sptr( | ||||
|             new pcps_acquisition_cc(sampled_ms, doppler_max, freq, | ||||
|                     fs_in, samples_per_ms, queue, dump, dump_filename)); | ||||
|             new pcps_acquisition_cc(sampled_ms, doppler_max, freq, fs_in, | ||||
|                     samples_per_ms, samples_per_code, queue, dump, dump_filename)); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| pcps_acquisition_cc::pcps_acquisition_cc( | ||||
|         unsigned int sampled_ms, unsigned int doppler_max, long freq, | ||||
|         long fs_in, int samples_per_ms, gr::msg_queue::sptr queue, bool dump, | ||||
|         std::string dump_filename) : | ||||
|         gr::block("pcps_acquisition_cc", | ||||
|         gr::io_signature::make(1, 1, sizeof(gr_complex) * sampled_ms * samples_per_ms), | ||||
|         gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) | ||||
|         unsigned int sampled_ms, unsigned int doppler_max, | ||||
|         long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||
|         gr::msg_queue::sptr queue, bool dump, std::string dump_filename) : | ||||
|     gr::block("pcps_acquisition_cc", | ||||
|     gr::io_signature::make(1, 1, sizeof(gr_complex) * sampled_ms * samples_per_ms), | ||||
|     gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) | ||||
| { | ||||
|     d_sample_counter = 0;    // SAMPLE COUNTER | ||||
|     d_active = false; | ||||
| @@ -69,15 +70,17 @@ pcps_acquisition_cc::pcps_acquisition_cc( | ||||
|     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_doppler_max = doppler_max; | ||||
|     d_fft_size = d_sampled_ms * d_samples_per_ms; | ||||
|     d_mag = 0; | ||||
|     d_input_power = 0.0; | ||||
|     d_num_doppler_bins = 0; | ||||
|  | ||||
|     //todo: do something if posix_memalign fails | ||||
|     if (posix_memalign((void**)&d_carrier, 16, d_fft_size * sizeof(gr_complex)) == 0){}; | ||||
|     if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){}; | ||||
|     if (posix_memalign((void**)&d_magnitude, 16, d_fft_size * sizeof(gr_complex)) == 0){}; | ||||
|  | ||||
|     // Direct FFT | ||||
|     d_fft_if = new gr::fft::fft_complex(d_fft_size, true); | ||||
| @@ -94,8 +97,22 @@ pcps_acquisition_cc::pcps_acquisition_cc( | ||||
|  | ||||
| pcps_acquisition_cc::~pcps_acquisition_cc() | ||||
| { | ||||
|     free(d_carrier); | ||||
|  | ||||
|  | ||||
|     for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) | ||||
|         { | ||||
|             free(d_grid_doppler_wipeoffs[doppler_index]); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     if (d_num_doppler_bins > 0) | ||||
|         { | ||||
|             delete[] d_grid_doppler_wipeoffs; | ||||
|         } | ||||
|  | ||||
|     free(d_fft_codes); | ||||
|     free(d_magnitude); | ||||
|  | ||||
|     delete d_ifft; | ||||
|     delete d_fft_if; | ||||
|     if (d_dump) | ||||
| @@ -108,7 +125,19 @@ pcps_acquisition_cc::~pcps_acquisition_cc() | ||||
|  | ||||
| void pcps_acquisition_cc::set_local_code(std::complex<float> * code) | ||||
| { | ||||
| 	memcpy(d_fft_if->get_inbuf(),code, sizeof(gr_complex)*d_fft_size); | ||||
|     memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex)*d_fft_size); | ||||
|  | ||||
|     d_fft_if->execute(); // We need the FFT of local code | ||||
|  | ||||
|     //Conjugate the local code | ||||
|     if (is_unaligned()) | ||||
|         { | ||||
|             volk_32fc_conjugate_32fc_u(d_fft_codes,d_fft_if->get_outbuf(),d_fft_size); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             volk_32fc_conjugate_32fc_a(d_fft_codes,d_fft_if->get_outbuf(),d_fft_size); | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -121,13 +150,18 @@ void pcps_acquisition_cc::init() | ||||
|     d_mag = 0.0; | ||||
|     d_input_power = 0.0; | ||||
|  | ||||
|     d_fft_if->execute(); // We need the FFT of local code | ||||
|     // Create the carrier Doppler wipeoff signals | ||||
|     d_num_doppler_bins=floor(2*std::abs((int)d_doppler_max)/d_doppler_step); | ||||
|     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++) | ||||
|         { | ||||
|             if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16, | ||||
|                                d_fft_size * sizeof(gr_complex)) == 0){}; | ||||
|  | ||||
|     //Conjugate the local code | ||||
|     for (unsigned int i = 0; i < d_fft_size; i++) | ||||
|     { | ||||
|         d_fft_codes[i] = std::complex<float>(conj(d_fft_if->get_outbuf()[i])); | ||||
|     } | ||||
|             int doppler=-(int)d_doppler_max+d_doppler_step*doppler_index; | ||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], | ||||
|                                  d_freq + doppler, d_fs_in, d_fft_size); | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -158,7 +192,6 @@ int pcps_acquisition_cc::general_work(int noutput_items, | ||||
|             int doppler; | ||||
|             unsigned int indext = 0; | ||||
|             float magt = 0.0; | ||||
|             float tmp_magt = 0.0; | ||||
|             const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer | ||||
|             bool positive_acquisition = false; | ||||
|             int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL | ||||
| @@ -175,35 +208,41 @@ int pcps_acquisition_cc::general_work(int noutput_items, | ||||
|             d_input_power = 0.0; | ||||
|  | ||||
|             DLOG(INFO) << "Channel: " << d_channel | ||||
|                        << " , doing acquisition of satellite: " << d_gnss_synchro->System | ||||
|                        << " "<< d_gnss_synchro->PRN | ||||
|                        << " ,sample stamp: " << d_sample_counter << ", threshold: " | ||||
|                        << d_threshold << ", doppler_max: " << d_doppler_max | ||||
|                        << ", doppler_step: " << d_doppler_step; | ||||
|                     << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN | ||||
|                     << " ,sample stamp: " << d_sample_counter << ", threshold: " | ||||
|                     << d_threshold << ", doppler_max: " << d_doppler_max | ||||
|                     << ", doppler_step: " << d_doppler_step; | ||||
|  | ||||
|             // 1- Compute the input signal power estimation | ||||
|             for (i = 0; i < d_fft_size; i++) | ||||
|             if (is_unaligned()) | ||||
|                 { | ||||
|                     d_input_power += std::norm(in[i]); | ||||
|                     volk_32fc_magnitude_squared_32f_u(d_magnitude, in, d_fft_size); | ||||
|                     for (i = 0; i < d_fft_size; i++) | ||||
|                         d_input_power += d_magnitude[i]; | ||||
|                 } | ||||
|             d_input_power = d_input_power / (float)d_fft_size; | ||||
|             else | ||||
|                 { | ||||
|                     volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_fft_size); | ||||
|                     volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_fft_size); | ||||
|                 } | ||||
|             d_input_power /= (float)d_fft_size; | ||||
|  | ||||
|             // 2- Doppler frequency search loop | ||||
|             for (doppler = (int)(-d_doppler_max); doppler <= (int)d_doppler_max; doppler += d_doppler_step) | ||||
|             for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++) | ||||
|                 { | ||||
|                     // doppler search steps | ||||
|             		//TODO: Create a run time lookup table with all the required Doppler wipe-off LO signals, by allocating a memory space (aligned) and by initializing it when the Doppler step is assigned | ||||
|             		// then, use the arrays to multiply the incomming signal, instead of computing the sine and cosine online. | ||||
|                     // Perform the carrier wipe-off | ||||
|                     complex_exp_gen_conj(d_carrier, d_freq + doppler, d_fs_in, d_fft_size); | ||||
|                     if (is_unaligned()==true) | ||||
|  | ||||
|                     doppler=-(int)d_doppler_max+d_doppler_step*doppler_index; | ||||
|  | ||||
|                     if (is_unaligned()) | ||||
|                         { | ||||
|                             volk_32fc_x2_multiply_32fc_u(d_fft_if->get_inbuf(), in, d_carrier, d_fft_size); | ||||
|                             volk_32fc_x2_multiply_32fc_u(d_fft_if->get_inbuf(), in, | ||||
|                                         d_grid_doppler_wipeoffs[doppler_index], d_fft_size); | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             //use directly the input vector | ||||
|                             volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in, d_carrier, d_fft_size); | ||||
|                             volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in, | ||||
|                                         d_grid_doppler_wipeoffs[doppler_index], d_fft_size); | ||||
|                         } | ||||
|  | ||||
|                     // 3- Perform the FFT-based convolution  (parallel time search) | ||||
| @@ -212,32 +251,52 @@ int pcps_acquisition_cc::general_work(int noutput_items, | ||||
|  | ||||
|                     // Multiply carrier wiped--off, Fourier transformed incoming signal | ||||
|                     // with the local FFT'd code reference using SIMD operations with VOLK library | ||||
|                     volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); | ||||
|                     if (is_unaligned()) | ||||
|                         { | ||||
|                             volk_32fc_x2_multiply_32fc_u(d_ifft->get_inbuf(), | ||||
|                                         d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(), | ||||
|                                         d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); | ||||
|                         } | ||||
|  | ||||
|                     // compute the inverse FFT | ||||
|                     d_ifft->execute(); | ||||
|  | ||||
|                     // Search maximum | ||||
|                     indext = 0; | ||||
|                     magt = 0; | ||||
|                     magt = 0.0; | ||||
|  | ||||
|                     fft_normalization_factor = (float)d_fft_size * (float)d_fft_size; | ||||
|                     for (i = 0; i < d_fft_size; i++) | ||||
|  | ||||
|                     if (is_unaligned()) | ||||
|                         { | ||||
|                             tmp_magt = std::norm(d_ifft->get_outbuf()[i]); | ||||
|                             if (tmp_magt > magt) | ||||
|                             volk_32fc_magnitude_squared_32f_u(d_magnitude, d_ifft->get_outbuf(), d_fft_size); | ||||
|                             for (i = 0; i < d_fft_size; i++) | ||||
|                                 { | ||||
|                                     magt = tmp_magt; | ||||
|                                     indext = i; | ||||
|                                     if(d_magnitude[i] > magt) | ||||
|                                         { | ||||
|                                             magt = d_magnitude[i]; | ||||
|                                             indext = i; | ||||
|                                         } | ||||
|                                 } | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             volk_32fc_magnitude_squared_32f_a(d_magnitude, d_ifft->get_outbuf(), d_fft_size); | ||||
|                             volk_32f_index_max_16u_a(&indext, d_magnitude, d_fft_size); | ||||
|                         } | ||||
|  | ||||
|                     // Normalize the maximum value to correct the scale factor introduced by FFTW | ||||
|                     magt = magt / (fft_normalization_factor * fft_normalization_factor); | ||||
|                     magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor); | ||||
|  | ||||
|                     // 4- record the maximum peak and the associated synchronization parameters | ||||
|                     if (d_mag < magt) | ||||
|                         { | ||||
|                             d_mag = magt; | ||||
|                             d_gnss_synchro->Acq_delay_samples = (double)indext; | ||||
|                             d_gnss_synchro->Acq_delay_samples = (double)(indext % d_samples_per_code); | ||||
|                             d_gnss_synchro->Acq_doppler_hz = (double)doppler; | ||||
|                         } | ||||
|  | ||||
| @@ -298,6 +357,7 @@ int pcps_acquisition_cc::general_work(int noutput_items, | ||||
|                 { | ||||
|                     acquisition_message = 2; | ||||
|                 } | ||||
|  | ||||
|             d_channel_internal_queue->push(acquisition_message); | ||||
|             consume_each(1); | ||||
|         } | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  * \authors <ul> | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          <li> Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
| @@ -65,8 +66,8 @@ class pcps_acquisition_cc; | ||||
| typedef boost::shared_ptr<pcps_acquisition_cc> pcps_acquisition_cc_sptr; | ||||
|  | ||||
| pcps_acquisition_cc_sptr | ||||
| pcps_make_acquisition_cc(unsigned int sampled_ms, | ||||
|         unsigned int doppler_max, long freq, long fs_in, int samples_per_ms, | ||||
| pcps_make_acquisition_cc(unsigned int sampled_ms, unsigned int doppler_max, | ||||
|         long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||
|         gr::msg_queue::sptr queue, bool dump, std::string dump_filename); | ||||
|  | ||||
| /*! | ||||
| @@ -79,47 +80,49 @@ class pcps_acquisition_cc: public gr::block | ||||
| { | ||||
| private: | ||||
|     friend pcps_acquisition_cc_sptr | ||||
|     pcps_make_acquisition_cc(unsigned int sampled_ms, | ||||
|             unsigned int doppler_max, long freq, long fs_in, | ||||
|             int samples_per_ms, gr::msg_queue::sptr queue, bool dump, | ||||
|             std::string dump_filename); | ||||
|     pcps_make_acquisition_cc(unsigned int sampled_ms, unsigned int doppler_max, | ||||
|             long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||
|             gr::msg_queue::sptr queue, bool dump, std::string dump_filename); | ||||
|  | ||||
|     pcps_acquisition_cc(unsigned int sampled_ms, | ||||
|             unsigned int doppler_max, long freq, long fs_in, | ||||
|             int samples_per_ms, gr::msg_queue::sptr d_queue, bool dump, | ||||
|             std::string dump_filename); | ||||
|     pcps_acquisition_cc(unsigned int sampled_ms, unsigned int doppler_max, | ||||
|             long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||
|             gr::msg_queue::sptr queue, bool dump, std::string dump_filename); | ||||
|  | ||||
|     void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift, | ||||
|             int doppler_offset); | ||||
|  | ||||
|     long d_fs_in; | ||||
|     long d_freq; | ||||
|     int d_samples_per_ms; | ||||
|     unsigned int d_doppler_resolution; | ||||
|     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_fft_size; | ||||
|     unsigned long int d_sample_counter; | ||||
|     gr_complex* d_carrier; | ||||
|     gr_complex* d_fft_codes; | ||||
|     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_input_power; | ||||
|     float d_test_statistics; | ||||
|  | ||||
| 	long d_fs_in; | ||||
| 	long d_freq; | ||||
| 	int d_samples_per_ms; | ||||
|     int d_samples_per_code; | ||||
| 	unsigned int d_doppler_resolution; | ||||
| 	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_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::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; | ||||
|     gr::msg_queue::sptr d_queue; | ||||
|     concurrent_queue<int> *d_channel_internal_queue; | ||||
|     std::ofstream d_dump_file; | ||||
|     bool d_active; | ||||
|     bool d_dump; | ||||
|     unsigned int d_channel; | ||||
|     std::string d_dump_filename; | ||||
| 	concurrent_queue<int> *d_channel_internal_queue; | ||||
| 	std::ofstream d_dump_file; | ||||
| 	bool d_active; | ||||
| 	bool d_dump; | ||||
| 	unsigned int d_channel; | ||||
| 	std::string d_dump_filename; | ||||
|  | ||||
| public: | ||||
|     /*! | ||||
|   | ||||
| @@ -76,7 +76,7 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, | ||||
|  | ||||
|     unsigned int doppler_step = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) | ||||
|     		+ ".doppler_step",0); | ||||
|     if(doppler_step==0)	doppler_step = configuration->property("Acquisition.doppler_step",0); | ||||
|     if(doppler_step==0)	doppler_step = configuration->property("Acquisition.doppler_step",500); | ||||
|  | ||||
|     DLOG(INFO) << "Channel "<< channel_<<" Doppler_step = " << doppler_step << std::endl; | ||||
|  | ||||
| @@ -88,6 +88,7 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, | ||||
|  | ||||
|     acq_->set_threshold(threshold); | ||||
|  | ||||
|     acq_->init(); | ||||
|  | ||||
|     repeat_ = configuration->property("Acquisition" + boost::lexical_cast< | ||||
|             std::string>(channel_) + ".repeat_satellite", false); | ||||
| @@ -184,7 +185,7 @@ void Channel::set_signal(Gnss_Signal gnss_signal) | ||||
|     gnss_synchro_.Signal[2] = 0; // make sure that string length is only two characters | ||||
|     gnss_synchro_.PRN = gnss_signal_.get_satellite().get_PRN(); | ||||
|     gnss_synchro_.System = gnss_signal_.get_satellite().get_system_short().c_str()[0]; | ||||
|     acq_->init(); | ||||
|     acq_->set_local_code(); | ||||
|     nav_->set_satellite(gnss_signal_.get_satellite()); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -53,7 +53,7 @@ galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn, | ||||
|                 { | ||||
|                     hex_to_binary_converter(&_dest[index], | ||||
|                             Galileo_E1_B_PRIMARY_CODE[prn].at(i)); | ||||
|                     index = index +4; | ||||
|                     index = index + 4; | ||||
|                 } | ||||
|  | ||||
|         } | ||||
| @@ -122,8 +122,8 @@ galileo_e1_gen(std::complex<float>* _dest, int* _prn, char _Signal[3]) | ||||
|     const float alpha = sqrt(10.0 / 11.0); | ||||
|     const float beta = sqrt(1.0 / 11.0); | ||||
|  | ||||
|     std::complex<float> sinboc_11[49152]; // 12*4096 (_codeLength not accepted by Clang ) | ||||
|     std::complex<float> sinboc_61[49152]; | ||||
|     std::complex<float> sinboc_11[_codeLength]; // 12*4092 (_codeLength not accepted by Clang ) | ||||
|     std::complex<float> sinboc_61[_codeLength]; | ||||
|  | ||||
|     galileo_e1_sinboc_11_gen(sinboc_11, _prn, _codeLength); //generate sinboc(1,1) 12 samples per chip | ||||
|     galileo_e1_sinboc_61_gen(sinboc_61, _prn, _codeLength); //generate sinboc(6,1) 12 samples per chip | ||||
| @@ -150,48 +150,88 @@ galileo_e1_gen(std::complex<float>* _dest, int* _prn, char _Signal[3]) | ||||
|  | ||||
| void | ||||
| galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3], | ||||
|         bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift) | ||||
|         bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift, | ||||
|         bool _secondary_flag) | ||||
| { | ||||
|     // This function is based on the GNU software GPS for MATLAB in the Kay Borre book | ||||
|  | ||||
|     // This function is based on the GNU software GPS for MATLAB in the Kay Borre bookç | ||||
|  | ||||
|     std::string _galileo_signal = _Signal; | ||||
|     unsigned int _samplesPerCode; | ||||
|     const unsigned int _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; //Hz | ||||
|     unsigned int _codeLength = Galileo_E1_B_CODE_LENGTH_CHIPS; | ||||
|     int primary_code_E1_chips[4096]; | ||||
|     int primary_code_E1_chips[(int)Galileo_E1_B_CODE_LENGTH_CHIPS]; | ||||
|     _samplesPerCode = round(_fs / (_codeFreqBasis / _codeLength)); | ||||
|     const int _samplesPerChip = (_cboc == true) ? 12 : 2; | ||||
|  | ||||
|     const unsigned int delay = (((int)Galileo_E1_B_CODE_LENGTH_CHIPS - _chip_shift) | ||||
|                                 % (int)Galileo_E1_B_CODE_LENGTH_CHIPS) | ||||
|                                 * _samplesPerCode / Galileo_E1_B_CODE_LENGTH_CHIPS; | ||||
|  | ||||
|     galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn, 0); //generate Galileo E1 code, 1 sample per chip | ||||
|  | ||||
|     std::complex<float>* _signal_E1; | ||||
|  | ||||
|     _codeLength = _samplesPerChip * Galileo_E1_B_CODE_LENGTH_CHIPS; | ||||
|     _signal_E1 = new std::complex<float>[_codeLength]; | ||||
|  | ||||
|     if (_cboc == true) | ||||
|         { | ||||
|             _codeLength = 12 * Galileo_E1_B_CODE_LENGTH_CHIPS; | ||||
|             if (_fs != 12 * _codeFreqBasis) | ||||
|                 { | ||||
|                     std::complex<float> _signal_E1[4096]; | ||||
|                     galileo_e1_gen(_signal_E1, primary_code_E1_chips, _Signal); //generate cboc 12 samples per chip | ||||
|                     resampler(_signal_E1, _dest, 12 * _codeFreqBasis, _fs, | ||||
|                             _codeLength, _samplesPerCode); //resamples code to fs | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     galileo_e1_gen(_dest, primary_code_E1_chips, _Signal); //generate cboc 12 samples per chip | ||||
|                 } | ||||
|             galileo_e1_gen(_signal_E1, primary_code_E1_chips, _Signal); //generate cboc 12 samples per chip | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             //--- Find number of samples per spreading code ---------------------------- | ||||
|             _codeLength = 2 * Galileo_E1_B_CODE_LENGTH_CHIPS; | ||||
|             if (_fs != 2 * _codeFreqBasis) | ||||
|                 { | ||||
|                     std::complex<float> _signal_E1[8192]; | ||||
|                     galileo_e1_sinboc_11_gen(_signal_E1, primary_code_E1_chips, | ||||
|                             _codeLength); //generate sinboc(1,1) 2 samples per chip | ||||
|                     resampler(_signal_E1, _dest, 2 * _codeFreqBasis, _fs, | ||||
|                             _codeLength, _samplesPerCode); //resamples code to fs | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     galileo_e1_sinboc_11_gen(_dest, primary_code_E1_chips, | ||||
|                             _codeLength); //generate sinboc(1,1) 2 samples per chip                } | ||||
|                 } | ||||
|             galileo_e1_sinboc_11_gen(_signal_E1, primary_code_E1_chips, | ||||
|                     _codeLength); //generate sinboc(1,1) 2 samples per chip | ||||
|         } | ||||
|  | ||||
|     if (_fs != _samplesPerChip * _codeFreqBasis) | ||||
|         { | ||||
|             std::complex<float>* _resampled_signal = new std::complex<float>[_samplesPerCode]; | ||||
|             resampler(_signal_E1, _resampled_signal, _samplesPerChip * _codeFreqBasis, _fs, | ||||
|                     _codeLength, _samplesPerCode); //resamples code to fs | ||||
|  | ||||
|             delete[] _signal_E1; | ||||
|             _signal_E1 = _resampled_signal; | ||||
|         } | ||||
|  | ||||
|  | ||||
|     if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag) | ||||
|     { | ||||
|  | ||||
|         std::complex<float>* _signal_E1C_secondary = new std::complex<float> | ||||
|                                                     [(int)Galileo_E1_C_SECONDARY_CODE_LENGTH | ||||
|                                                     * _samplesPerCode]; | ||||
|  | ||||
|         for (unsigned int i = 0; i < (int)Galileo_E1_C_SECONDARY_CODE_LENGTH; i++) | ||||
|             { | ||||
|                 for (unsigned k = 0; k < _samplesPerCode; k++) | ||||
|                     { | ||||
|                         _signal_E1C_secondary[i*_samplesPerCode + k] = _signal_E1[k] | ||||
|                                 * (Galileo_E1_C_SECONDARY_CODE.at(i) == '0' | ||||
|                                    ? std::complex<float>(1,0) : std::complex<float>(-1,0)); | ||||
|                     } | ||||
|             } | ||||
|  | ||||
|         _samplesPerCode *= (int)Galileo_E1_C_SECONDARY_CODE_LENGTH; | ||||
|  | ||||
|         delete[] _signal_E1; | ||||
|         _signal_E1 = _signal_E1C_secondary; | ||||
|     } | ||||
|  | ||||
|     for (unsigned int i = 0; i < _samplesPerCode; i++) | ||||
|         { | ||||
|             _dest[(i+delay)%_samplesPerCode] = _signal_E1[i]; | ||||
|         } | ||||
|  | ||||
|     delete[] _signal_E1; | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3], | ||||
|         bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift) | ||||
| { | ||||
|     galileo_e1_code_gen_complex_sampled(_dest, _Signal, _cboc, _prn, | ||||
|                                         _fs, _chip_shift, false); | ||||
| } | ||||
|   | ||||
| @@ -69,7 +69,13 @@ void galileo_e1_cboc_gen(std::complex<float>* _dest, int* _prn, char _Signal[3]) | ||||
|  * | ||||
|  */ | ||||
| void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3], | ||||
|         bool _cboc, unsigned int _prn, signed int _fs, | ||||
|         unsigned int _chip_shift); | ||||
|         bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift, | ||||
|         bool _secondary_flag); | ||||
|  | ||||
| /*! | ||||
|  * \brief galileo_e1_code_gen_complex_sampled without _secondary_flag for backward compatibility. | ||||
|  */ | ||||
| void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3], | ||||
|         bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift); | ||||
|  | ||||
| #endif /* GNSS_SDR_GALILEO_E1_SIGNAL_PROCESSING_H_ */ | ||||
|   | ||||
							
								
								
									
										20
									
								
								src/algorithms/signal_generator/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/algorithms/signal_generator/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| # Copyright (C) 2012-2013  (see AUTHORS file for a list of contributors) | ||||
| # | ||||
| # This file is part of GNSS-SDR. | ||||
| # | ||||
| # GNSS-SDR is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # at your option) any later version. | ||||
| # | ||||
| # GNSS-SDR is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
| # | ||||
|  | ||||
| add_subdirectory(adapters) | ||||
| add_subdirectory(gnuradio_blocks) | ||||
							
								
								
									
										34
									
								
								src/algorithms/signal_generator/adapters/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/algorithms/signal_generator/adapters/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| # Copyright (C) 2012-2013  (see AUTHORS file for a list of contributors) | ||||
| # | ||||
| # This file is part of GNSS-SDR. | ||||
| # | ||||
| # GNSS-SDR is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # at your option) any later version. | ||||
| # | ||||
| # GNSS-SDR is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
| # | ||||
|  | ||||
| set(SIGNAL_GENERATOR_ADAPTER_SOURCES signal_generator.cc) | ||||
|  | ||||
| include_directories( | ||||
|      $(CMAKE_CURRENT_SOURCE_DIR) | ||||
|      ${CMAKE_SOURCE_DIR}/src/core/system_parameters | ||||
|      ${CMAKE_SOURCE_DIR}/src/core/interfaces | ||||
|      ${CMAKE_SOURCE_DIR}/src/core/receiver | ||||
|      ${CMAKE_SOURCE_DIR}/src/algorithms/signal_generator/gnuradio_blocks | ||||
|      ${CMAKE_SOURCE_DIR}/src/algorithms/libs | ||||
|      ${GLOG_INCLUDE_DIRS} | ||||
|      ${GFlags_INCLUDE_DIRS} | ||||
|      ${GNURADIO_RUNTIME_INCLUDE_DIRS} | ||||
| ) | ||||
|  | ||||
| add_library(signal_generator_adapters ${SIGNAL_GENERATOR_ADAPTER_SOURCES}) | ||||
| target_link_libraries(signal_generator_adapters gnss_sp_libs signal_generator_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES}) | ||||
							
								
								
									
										167
									
								
								src/algorithms/signal_generator/adapters/signal_generator.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/algorithms/signal_generator/adapters/signal_generator.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | ||||
| /*! | ||||
|  * \file signal_generator.cc | ||||
|  * \brief Signal generator. | ||||
|  * \author Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2013  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "signal_generator.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "Galileo_E1.h" | ||||
| #include "GPS_L1_CA.h" | ||||
| #include <glog/log_severity.h> | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| SignalGenerator::SignalGenerator(ConfigurationInterface* configuration, | ||||
|             std::string role, unsigned int in_stream, | ||||
|             unsigned int out_stream, boost::shared_ptr<gr::msg_queue> queue) : | ||||
|         role_(role), in_stream_(in_stream), out_stream_(out_stream), queue_(queue) | ||||
| { | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     std::string default_dump_file = "./data/gen_source.dat"; | ||||
|     std::string default_system = "G"; | ||||
|  | ||||
|     item_type_ = configuration->property(role + ".item_type", default_item_type); | ||||
|     dump_ = configuration->property(role + ".dump", false); | ||||
|     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); | ||||
|  | ||||
|     unsigned int fs_in = configuration->property("SignalSource.fs_hz", 4e6); | ||||
|     bool data_flag = configuration->property("SignalSource.data_flag", false); | ||||
|     bool noise_flag = configuration->property("SignalSource.noise_flag", false); | ||||
|     float BW_BB = configuration->property("SignalSource.BW_BB", 1.0); | ||||
|     unsigned int num_satellites = configuration->property("SignalSource.num_satellites", 1); | ||||
|  | ||||
|     std::vector<std::string> system; | ||||
|     std::vector<unsigned int> PRN; | ||||
|     std::vector<float> CN0_dB; | ||||
|     std::vector<float> doppler_Hz; | ||||
|     std::vector<unsigned int> delay_chips; | ||||
|  | ||||
|     for (unsigned int sat_idx = 0; sat_idx < num_satellites; sat_idx++) | ||||
|         { | ||||
|             std::string sat = std::to_string(sat_idx); | ||||
|             system.push_back(configuration->property("SignalSource.system_" + sat, default_system)); | ||||
|             PRN.push_back(configuration->property("SignalSource.PRN_" + sat, 1)); | ||||
|             CN0_dB.push_back(configuration->property("SignalSource.CN0_dB_" + sat, 10)); | ||||
|             doppler_Hz.push_back(configuration->property("SignalSource.doppler_Hz_" + sat, 0)); | ||||
|             delay_chips.push_back(configuration->property("SignalSource.delay_chips_" + sat, 0)); | ||||
|         } | ||||
|  | ||||
|     // If Gallileo signal is present                             -> vector duration = 100 ms (25 * 4 ms) | ||||
|     // If there is only GPS signal (Gallileo signal not present) -> vector duration = 1 ms | ||||
|     unsigned int vector_length = 0; | ||||
|     if (std::find(system.begin(), system.end(), "E") != system.end()) | ||||
|     { | ||||
|         vector_length = round((float)fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ | ||||
|                                   / Galileo_E1_B_CODE_LENGTH_CHIPS)) | ||||
|                                   * Galileo_E1_C_SECONDARY_CODE_LENGTH; | ||||
|     } | ||||
|     else if (std::find(system.begin(), system.end(), "G") != system.end()) | ||||
|     { | ||||
|         vector_length = round((float)fs_in | ||||
|                  / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||
|     } | ||||
|  | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|         { | ||||
|             item_size_ = sizeof(gr_complex); | ||||
|             DLOG(INFO) << "Item size " << item_size_; | ||||
|             gen_source_ = signal_make_generator_c(system, PRN, CN0_dB, doppler_Hz, delay_chips, | ||||
|                                              data_flag, noise_flag, fs_in, vector_length, BW_BB); | ||||
|  | ||||
|             vector_to_stream_ = gr::blocks::vector_to_stream::make(item_size_, vector_length); | ||||
|  | ||||
|             DLOG(INFO) << "vector_to_stream(" << vector_to_stream_->unique_id() << ")"; | ||||
|             DLOG(INFO) << "gen_source(" << gen_source_->unique_id() << ")"; | ||||
|         } | ||||
|  | ||||
|     else | ||||
|         { | ||||
|             LOG_AT_LEVEL(WARNING) << item_type_ | ||||
|                     << " unrecognized item type for resampler"; | ||||
|             item_size_ = sizeof(short); | ||||
|         } | ||||
|  | ||||
|     if (dump_) | ||||
|         { | ||||
|             DLOG(INFO) << "Dumping output into file " << dump_filename_; | ||||
|             file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); | ||||
|         } | ||||
|     if (dump_) | ||||
|         { | ||||
|             DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| SignalGenerator::~SignalGenerator() | ||||
| {} | ||||
|  | ||||
|  | ||||
| void SignalGenerator::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|         { | ||||
|             top_block->connect(gen_source_, 0, vector_to_stream_, 0); | ||||
|             DLOG(INFO) << "connected gen_source to vector_to_stream"; | ||||
|  | ||||
|             if (dump_) | ||||
|             { | ||||
|                 top_block->connect(vector_to_stream_, 0, file_sink_, 0); | ||||
|                 DLOG(INFO) << "connected vector_to_stream_ to file sink"; | ||||
|             } | ||||
|  | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| void SignalGenerator::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (item_type_.compare("gr_complex") == 0) | ||||
|         { | ||||
|             top_block->disconnect(gen_source_, 0, vector_to_stream_, 0); | ||||
|             if (dump_) | ||||
|             { | ||||
|                 top_block->disconnect(vector_to_stream_, 0, file_sink_, 0); | ||||
|             } | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr SignalGenerator::get_left_block() | ||||
| { | ||||
|     LOG_AT_LEVEL(WARNING) << "Left block of a signal source should not be retrieved"; | ||||
|     return gr::block_sptr(); | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr SignalGenerator::get_right_block() | ||||
| { | ||||
|     return vector_to_stream_; | ||||
| } | ||||
							
								
								
									
										96
									
								
								src/algorithms/signal_generator/adapters/signal_generator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/algorithms/signal_generator/adapters/signal_generator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /*! | ||||
|  * \file signal_generator.h | ||||
|  * \brief Adapter of a class that generates synthesized GNSS signal. | ||||
|  * \author Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2013  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef GNSS_SDR_SIGNAL_GENERATOR_H_ | ||||
| #define GNSS_SDR_SIGNAL_GENERATOR_H_ | ||||
|  | ||||
| #include <gnuradio/blocks/file_sink.h> | ||||
| #include <gnuradio/hier_block2.h> | ||||
| #include <gnuradio/msg_queue.h> | ||||
| #include <gnuradio/blocks/vector_to_stream.h> | ||||
|  | ||||
| #include "gnss_block_interface.h" | ||||
| #include "signal_generator_c.h" | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class generates synthesized GNSS signal. | ||||
|  * | ||||
|  */ | ||||
| class SignalGenerator: public GNSSBlockInterface | ||||
| { | ||||
| public: | ||||
|     SignalGenerator(ConfigurationInterface* configuration, | ||||
|             std::string role, unsigned int in_stream, | ||||
|             unsigned int out_stream, boost::shared_ptr<gr::msg_queue> queue); | ||||
|  | ||||
|     virtual ~SignalGenerator(); | ||||
|     std::string role() | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns "SignalGenerator". | ||||
|      */ | ||||
|     std::string implementation() | ||||
|     { | ||||
|         return "GNSSSignalGenerator"; | ||||
|     } | ||||
|     size_t item_size() | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block); | ||||
|     void disconnect(gr::top_block_sptr top_block); | ||||
|     gr::basic_block_sptr get_left_block(); | ||||
|     gr::basic_block_sptr get_right_block(); | ||||
|  | ||||
|  | ||||
| private: | ||||
|     std::string role_; | ||||
|     unsigned int in_stream_; | ||||
|     unsigned int out_stream_; | ||||
|     std::string item_type_; | ||||
|     size_t item_size_; | ||||
|     bool dump_; | ||||
|     std::string dump_filename_; | ||||
|     boost::shared_ptr<gr::block> gen_source_; | ||||
|     gr::blocks::vector_to_stream::sptr vector_to_stream_; | ||||
|     gr::blocks::file_sink::sptr file_sink_; | ||||
|     boost::shared_ptr<gr::msg_queue> queue_; | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif /*GNSS_SDR_SIGNAL_GENERATOR_H_*/ | ||||
| @@ -0,0 +1,35 @@ | ||||
| # Copyright (C) 2012-2013  (see AUTHORS file for a list of contributors) | ||||
| # | ||||
| # This file is part of GNSS-SDR. | ||||
| # | ||||
| # GNSS-SDR is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # at your option) any later version. | ||||
| # | ||||
| # GNSS-SDR is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
| # | ||||
|  | ||||
| set(SIGNAL_GENERATOR_BLOCK_SOURCES signal_generator_c.cc) | ||||
|  | ||||
| include_directories( | ||||
|      $(CMAKE_CURRENT_SOURCE_DIR) | ||||
|      ${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 | ||||
|      ${GLOG_INCLUDE_DIRS} | ||||
|      ${GFlags_INCLUDE_DIRS} | ||||
|      ${GNURADIO_RUNTIME_INCLUDE_DIRS} | ||||
| ) | ||||
|  | ||||
| add_library(signal_generator_blocks ${SIGNAL_GENERATOR_BLOCK_SOURCES}) | ||||
| target_link_libraries(signal_generator_blocks gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES}) | ||||
|  | ||||
|  | ||||
| @@ -0,0 +1,335 @@ | ||||
| /*! | ||||
|  * \file signal_generator_c.h | ||||
|  * \brief GNU Radio source block that generates synthesized GNSS signal. | ||||
|  * \author Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2012  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif | ||||
|  | ||||
| #include "signal_generator_c.h" | ||||
| #include <gnuradio/io_signature.h> | ||||
| #include "gps_sdr_signal_processing.h" | ||||
| #include "galileo_e1_signal_processing.h" | ||||
| #include <volk/volk.h> | ||||
| #include "nco_lib.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Create a new instance of signal_generator_c and return | ||||
|  * a boost shared_ptr.  This is effectively the public constructor. | ||||
|  */ | ||||
| signal_generator_c_sptr | ||||
| signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN, | ||||
|                     const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz, | ||||
|                     const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag, | ||||
|                     unsigned int fs_in, unsigned int vector_length, float BW_BB) | ||||
| { | ||||
|     return gnuradio::get_initial_sptr(new signal_generator_c(system, PRN, CN0_dB, doppler_Hz, delay_chips, | ||||
|                                                         data_flag, noise_flag, fs_in, vector_length, BW_BB)); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The private constructor | ||||
|  */ | ||||
| signal_generator_c::signal_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN, | ||||
|                               const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz, | ||||
|                               const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag, | ||||
|                               unsigned int fs_in, unsigned int vector_length, float BW_BB) : | ||||
|  | ||||
|   gr::block ("signal_gen_cc", gr::io_signature::make(0, 0, sizeof(gr_complex)), | ||||
|                               gr::io_signature::make(1, 1, sizeof(gr_complex)*vector_length)), | ||||
|   system_(system), | ||||
|   PRN_(PRN), | ||||
|   CN0_dB_(CN0_dB), | ||||
|   doppler_Hz_(doppler_Hz), | ||||
|   delay_chips_(delay_chips), | ||||
|   data_flag_(data_flag), | ||||
|   noise_flag_(noise_flag), | ||||
|   fs_in_(fs_in), | ||||
|   num_sats_(PRN.size()), | ||||
|   vector_length_(vector_length), | ||||
|   BW_BB_(BW_BB*(float)fs_in/2) | ||||
| { | ||||
|     init(); | ||||
|     generate_codes(); | ||||
| } | ||||
|  | ||||
| void signal_generator_c::init() | ||||
| { | ||||
|     if (posix_memalign((void**)&complex_phase_, 16, vector_length_ * sizeof(gr_complex)) == 0){}; | ||||
|  | ||||
|     // True if Gallileo satellites are present | ||||
|     bool gallileo_signal = std::find(system_.begin(), system_.end(), "E") != system_.end(); | ||||
|  | ||||
|     for (unsigned int sat = 0; sat < num_sats_; sat++) | ||||
|         { | ||||
|             start_phase_rad_.push_back(0); | ||||
|             current_data_bits_.push_back(gr_complex(1,0)); | ||||
|             ms_counter_.push_back(0); | ||||
|  | ||||
|             if (system_[sat] == "G") | ||||
|                 { | ||||
|                     samples_per_code_.push_back(round((float)fs_in_ | ||||
|                             / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); | ||||
|  | ||||
|                     num_of_codes_per_vector_.push_back(gallileo_signal ? 4*(int)Galileo_E1_C_SECONDARY_CODE_LENGTH : 1); | ||||
|                     data_bit_duration_ms_.push_back(1e3/GPS_CA_TELEMETRY_RATE_BITS_SECOND); | ||||
|                 } | ||||
|             else if (system_[sat] == "E") | ||||
|                 { | ||||
|                     samples_per_code_.push_back(round((float)fs_in_ / (Galileo_E1_CODE_CHIP_RATE_HZ | ||||
|                                         / Galileo_E1_B_CODE_LENGTH_CHIPS))); | ||||
|  | ||||
|                     num_of_codes_per_vector_.push_back((int)Galileo_E1_C_SECONDARY_CODE_LENGTH); | ||||
|                     data_bit_duration_ms_.push_back(1e3/Galileo_E1_B_SYMBOL_RATE_BPS); | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     random_ = new gr::random(); | ||||
|  | ||||
| //    std::cout << "fs_in: " << fs_in_ << std::endl; | ||||
| //    std::cout << "data_flag: " << data_flag_ << std::endl; | ||||
| //    std::cout << "noise_flag_: " << noise_flag_ << std::endl; | ||||
| //    std::cout << "num_sats_: " << num_sats_ << std::endl; | ||||
| //    std::cout << "vector_length_: " << vector_length_ << std::endl; | ||||
| //    std::cout << "BW_BB_: " << BW_BB_ << std::endl; | ||||
|  | ||||
| //    for (unsigned int i = 0; i < num_sats_; i++) | ||||
| //    { | ||||
| //        std::cout << "Sat " << i << ": " << std::endl; | ||||
| //        std::cout << "System " << system_[i] << ": " << std::endl; | ||||
| //        std::cout << "  PRN: " << PRN_[i] << std::endl; | ||||
| //        std::cout << "  CN0: " << CN0_dB_[i] << std::endl; | ||||
| //        std::cout << "  Doppler: " << doppler_Hz_[i] << std::endl; | ||||
| //        std::cout << "  Delay: " << delay_chips_[i] << std::endl; | ||||
| //        std::cout << "Samples per code = " << samples_per_code_[i] << std::endl; | ||||
| //        std::cout << "codes per vector = " << num_of_codes_per_vector_[i] << std::endl; | ||||
| //        std::cout << "data_bit_duration = " << data_bit_duration_ms_[i] << std::endl; | ||||
| //    } | ||||
| } | ||||
|  | ||||
| void signal_generator_c::generate_codes() | ||||
| { | ||||
|     sampled_code_data_.reset(new gr_complex*[num_sats_]); | ||||
|     sampled_code_pilot_.reset(new gr_complex*[num_sats_]); | ||||
|  | ||||
|     for (unsigned int sat = 0; sat < num_sats_; sat++) | ||||
|         { | ||||
|             if (posix_memalign((void**)&(sampled_code_data_[sat]), 16, | ||||
|                                vector_length_ * sizeof(gr_complex)) == 0){}; | ||||
|  | ||||
|             gr_complex code[samples_per_code_[sat]]; | ||||
|  | ||||
|             if (system_[sat] == "G") | ||||
|                 { | ||||
|                     // Generate one code-period of 1C signal | ||||
|                     gps_l1_ca_code_gen_complex_sampled(code, PRN_[sat], fs_in_, | ||||
|                                     (int)GPS_L1_CA_CODE_LENGTH_CHIPS-delay_chips_[sat]); | ||||
|  | ||||
|                     // Obtain the desired CN0 assuming that Pn = 1. | ||||
|                     for (unsigned int i = 0; i < samples_per_code_[sat]; i++) | ||||
|                         { | ||||
|                             code[i] *= sqrt(pow(10,CN0_dB_[sat]/10)/BW_BB_); | ||||
|                         } | ||||
|  | ||||
|                     // Concatenate "num_of_codes_per_vector_" codes | ||||
|                     for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++) | ||||
|                         { | ||||
|                             memcpy(&(sampled_code_data_[sat][i*samples_per_code_[sat]]), | ||||
|                                    code, sizeof(gr_complex)*samples_per_code_[sat]); | ||||
|                         } | ||||
|                 } | ||||
|             else if (system_[sat] == "E") | ||||
|                 { | ||||
|                     // Generate one code-period of E1B signal | ||||
|                     bool cboc = true; | ||||
|                     char signal[3]; | ||||
|                     strcpy(signal, "1B"); | ||||
|  | ||||
|                     galileo_e1_code_gen_complex_sampled(code, signal, cboc, PRN_[sat], fs_in_, | ||||
|                                     (int)Galileo_E1_B_CODE_LENGTH_CHIPS-delay_chips_[sat]); | ||||
|  | ||||
|                     // Obtain the desired CN0 assuming that Pn = 1. | ||||
|                     for (unsigned int i = 0; i < samples_per_code_[sat]; i++) | ||||
|                         { | ||||
|                             code[i] *= sqrt(pow(10,CN0_dB_[sat]/10)/BW_BB_/2); | ||||
|                         } | ||||
|  | ||||
|                     // Concatenate "num_of_codes_per_vector_" codes | ||||
|                     for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++) | ||||
|                         { | ||||
|                             memcpy(&(sampled_code_data_[sat][i*samples_per_code_[sat]]), | ||||
|                                    code, sizeof(gr_complex)*samples_per_code_[sat]); | ||||
|                         } | ||||
|  | ||||
|                     // Generate E1C signal (25 code-periods, with secondary code) | ||||
|                     if (posix_memalign((void**)&(sampled_code_pilot_[sat]), 16, | ||||
|                                        vector_length_ * sizeof(gr_complex)) == 0){}; | ||||
|  | ||||
|                     strcpy(signal, "1C"); | ||||
|  | ||||
|                     galileo_e1_code_gen_complex_sampled(sampled_code_pilot_[sat], signal, cboc, PRN_[sat], fs_in_, | ||||
|                                                         (int)Galileo_E1_B_CODE_LENGTH_CHIPS-delay_chips_[sat], true); | ||||
|  | ||||
|                     // Obtain the desired CN0 assuming that Pn = 1. | ||||
|                     for (unsigned int i = 0; i < vector_length_; i++) | ||||
|                         { | ||||
|                             sampled_code_pilot_[sat][i] *= sqrt(pow(10,CN0_dB_[sat]/10)/BW_BB_/2); | ||||
|                         } | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Our virtual destructor. | ||||
|  */ | ||||
| signal_generator_c::~signal_generator_c() | ||||
| { | ||||
|     for (unsigned int sat = 0; sat < num_sats_; sat++) | ||||
|         { | ||||
|             free(sampled_code_data_[sat]); | ||||
|             if (system_[sat] == "E") | ||||
|                 { | ||||
|                     free(sampled_code_pilot_[sat]); | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     delete random_; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| signal_generator_c::general_work (int noutput_items, | ||||
|                    gr_vector_int &ninput_items, | ||||
| 			       gr_vector_const_void_star &input_items, | ||||
| 			       gr_vector_void_star &output_items) | ||||
| { | ||||
|     gr_complex *out = (gr_complex *) output_items[0]; | ||||
|  | ||||
|     unsigned int out_idx = 0; | ||||
|     unsigned int i = 0; | ||||
|     unsigned int k = 0; | ||||
|  | ||||
|     for (out_idx = 0; out_idx < vector_length_; out_idx++) | ||||
|         { | ||||
|             out[out_idx] = gr_complex(0.0,0.0); | ||||
|         } | ||||
|  | ||||
|     for (unsigned int sat = 0; sat < num_sats_; sat++) | ||||
|         { | ||||
|  | ||||
|             float phase_step_rad = -(float)GPS_TWO_PI*doppler_Hz_[sat] / (float)fs_in_; | ||||
|             fxp_nco(complex_phase_, vector_length_, start_phase_rad_[sat], phase_step_rad); | ||||
|             start_phase_rad_[sat] += vector_length_ * phase_step_rad; | ||||
|  | ||||
|             out_idx = 0; | ||||
|  | ||||
|             if (system_[sat] == "G") | ||||
|                 { | ||||
|                     unsigned int delay_samples = (delay_chips_[sat] % (int)GPS_L1_CA_CODE_LENGTH_CHIPS) | ||||
|                                                     * samples_per_code_[sat] / GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||
|  | ||||
|                     for (i = 0; i < num_of_codes_per_vector_[sat]; i++) | ||||
|                         { | ||||
|                             gr_complex prev_data_bit = current_data_bits_[sat]; | ||||
|                             if (ms_counter_[sat] == 0 && data_flag_) | ||||
|                                  { | ||||
|                                      // New random data bit | ||||
|                                      current_data_bits_[sat] = gr_complex((rand()%2) == 0 ? 1 : -1, 0); | ||||
|                                  } | ||||
|  | ||||
|                             for (k = 0; k < delay_samples; k++) | ||||
|                                 { | ||||
|                                     out[out_idx] += sampled_code_data_[sat][out_idx] | ||||
|                                                     * prev_data_bit | ||||
|                                                     * complex_phase_[out_idx]; | ||||
|                                     out_idx++; | ||||
|                                 } | ||||
|  | ||||
|                             for (k = delay_samples; k < samples_per_code_[sat]; k++) | ||||
|                                 { | ||||
|                                     out[out_idx] += sampled_code_data_[sat][out_idx] | ||||
|                                                     * current_data_bits_[sat] | ||||
|                                                     * complex_phase_[out_idx]; | ||||
|                                     out_idx++; | ||||
|                                 } | ||||
|  | ||||
|                             ms_counter_[sat] = (ms_counter_[sat] + (int)round(1e3*GPS_L1_CA_CODE_PERIOD)) | ||||
|                                                 % data_bit_duration_ms_[sat]; | ||||
|                         } | ||||
|                 } | ||||
|  | ||||
|             else if (system_[sat] == "E") | ||||
|                 { | ||||
|                     unsigned int delay_samples = (delay_chips_[sat] % (int)Galileo_E1_B_CODE_LENGTH_CHIPS) | ||||
|                                                     * samples_per_code_[sat] / Galileo_E1_B_CODE_LENGTH_CHIPS; | ||||
|  | ||||
|                     for (i = 0; i < num_of_codes_per_vector_[sat]; i++) | ||||
|                         { | ||||
|                             gr_complex prev_data_bit = current_data_bits_[sat]; | ||||
|                             if (ms_counter_[sat] == 0 && data_flag_) | ||||
|                                 { | ||||
|                                     // New random data bit | ||||
|                                     current_data_bits_[sat] = gr_complex((rand()%2) == 0 ? -1 : 1, 0); | ||||
|                                 } | ||||
|  | ||||
|                             for (k = 0; k < delay_samples; k++) | ||||
|                                 { | ||||
|                                     out[out_idx] += (sampled_code_data_[sat][out_idx] * prev_data_bit | ||||
|                                                     -  sampled_code_pilot_[sat][out_idx]) | ||||
|                                                     * complex_phase_[out_idx]; | ||||
|                                     out_idx++; | ||||
|                                 } | ||||
|  | ||||
|                             for (k = delay_samples; k < samples_per_code_[sat]; k++) | ||||
|                                 { | ||||
|                                     out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat] | ||||
|                                                     - sampled_code_pilot_[sat][out_idx]) | ||||
|                                                     * complex_phase_[out_idx]; | ||||
|                                     out_idx++; | ||||
|                                 } | ||||
|  | ||||
|                             ms_counter_[sat] = (ms_counter_[sat] + (int)round(1e3*Galileo_E1_CODE_PERIOD)) | ||||
|                                                 % data_bit_duration_ms_[sat]; | ||||
|                         } | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     if (noise_flag_) | ||||
|         { | ||||
|             for (out_idx = 0; out_idx < vector_length_; out_idx++) | ||||
|                 { | ||||
|                     out[out_idx] += gr_complex(random_->gasdev(),random_->gasdev()); | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     // Tell runtime system how many output items we produced. | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,129 @@ | ||||
| /*! | ||||
|  * \file signal_generator_c.h | ||||
|  * \brief GNU Radio source block that generates synthesized GNSS signal. | ||||
|  * \author Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2013  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
| #ifndef GNSS_SDR_SIGNAL_GENERATOR_C_H | ||||
| #define GNSS_SDR_SIGNAL_GENERATOR_C_H | ||||
|  | ||||
| #include "gnss_signal.h" | ||||
| #include <gnuradio/random.h> | ||||
| #include <gnuradio/block.h> | ||||
| #include <boost/scoped_array.hpp> | ||||
|  | ||||
|  | ||||
| class signal_generator_c; | ||||
|  | ||||
| /* | ||||
|  * We use boost::shared_ptr's instead of raw pointers for all access | ||||
|  * to gr_blocks (and many other data structures).  The shared_ptr gets | ||||
|  * us transparent reference counting, which greatly simplifies storage | ||||
|  * management issues.  This is especially helpful in our hybrid | ||||
|  * C++ / Python system. | ||||
|  * | ||||
|  * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm | ||||
|  * | ||||
|  * As a convention, the _sptr suffix indicates a boost::shared_ptr | ||||
|  */ | ||||
| typedef boost::shared_ptr<signal_generator_c> signal_generator_c_sptr; | ||||
|  | ||||
| /*! | ||||
|  * \brief Return a shared_ptr to a new instance of gen_source. | ||||
|  * | ||||
|  * To avoid accidental use of raw pointers, gen_source's | ||||
|  * constructor is private. signal_make_generator_c is the public | ||||
|  * interface for creating new instances. | ||||
|  */ | ||||
| signal_generator_c_sptr | ||||
| signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN, | ||||
|                     const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz, | ||||
|                     const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag, | ||||
|                     unsigned int fs_in, unsigned int vector_length, float BW_BB); | ||||
|  | ||||
| /*! | ||||
|  * \brief This class generates synthesized GNSS signal. | ||||
|  * \ingroup block | ||||
|  * | ||||
|  * \sa gen_source for a version that subclasses gr_block. | ||||
|  */ | ||||
| class signal_generator_c : public gr::block | ||||
| { | ||||
| private: | ||||
|   // The friend declaration allows gen_source to | ||||
|   // access the private constructor. | ||||
|  | ||||
|   /* Create the signal_generator_c object*/ | ||||
|   friend signal_generator_c_sptr | ||||
|   signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN, | ||||
|                       const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz, | ||||
|                       const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag, | ||||
|                       unsigned int fs_in, unsigned int vector_length, float BW_BB); | ||||
|  | ||||
|   signal_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN, | ||||
|                  const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz, | ||||
|                  const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag, | ||||
|                  unsigned int fs_in, unsigned int vector_length, float BW_BB); | ||||
|  | ||||
|   void init(); | ||||
|   void generate_codes(); | ||||
|  | ||||
|   std::vector<std::string> system_; | ||||
|   std::vector<unsigned int> PRN_; | ||||
|   std::vector<float> CN0_dB_; | ||||
|   std::vector<float> doppler_Hz_; | ||||
|   std::vector<unsigned int> delay_chips_; | ||||
|   bool data_flag_; | ||||
|   bool noise_flag_; | ||||
|   unsigned int fs_in_; | ||||
|   unsigned int num_sats_; | ||||
|   unsigned int vector_length_; | ||||
|   float BW_BB_; | ||||
|  | ||||
|   std::vector<unsigned int> samples_per_code_; | ||||
|   std::vector<unsigned int> num_of_codes_per_vector_; | ||||
|   std::vector<unsigned int> data_bit_duration_ms_; | ||||
|   std::vector<unsigned int> ms_counter_; | ||||
|   std::vector<float> start_phase_rad_; | ||||
|   std::vector<gr_complex> current_data_bits_; | ||||
|  | ||||
|   boost::scoped_array<gr_complex*> sampled_code_data_; | ||||
|   boost::scoped_array<gr_complex*> sampled_code_pilot_; | ||||
|   gr::random* random_; | ||||
|   gr_complex* complex_phase_; | ||||
|  | ||||
|  public: | ||||
|   ~signal_generator_c ();	// public destructor | ||||
|  | ||||
|   // Where all the action really happens | ||||
|  | ||||
|   int general_work (int noutput_items, | ||||
| 		    gr_vector_int &ninput_items, | ||||
| 		    gr_vector_const_void_star &input_items, | ||||
| 		    gr_vector_void_star &output_items); | ||||
| }; | ||||
|  | ||||
| #endif /* GNSS_SDR_SIGNAL_GENERATOR_C_H */ | ||||
| @@ -74,7 +74,7 @@ if(RTLSDR_DRIVER) | ||||
|     set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${RTL_DRIVER_INCLUDE_DIRS})  | ||||
| endif(RTLSDR_DRIVER) | ||||
|  | ||||
| set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc uhd_signal_source.cc ${OPT_DRIVER_SOURCES}) | ||||
| set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc gen_signal_source.cc uhd_signal_source.cc ${OPT_DRIVER_SOURCES}) | ||||
|  | ||||
|  | ||||
| include_directories( | ||||
|   | ||||
							
								
								
									
										115
									
								
								src/algorithms/signal_source/adapters/gen_signal_source.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/algorithms/signal_source/adapters/gen_signal_source.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /*! | ||||
|  * \file gen_signal_source.cc | ||||
|  * \brief It wraps blocks that generates synthesized GNSS signal and filters | ||||
|  *  it. | ||||
|  * \author Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2013  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "gen_signal_source.h" | ||||
| //#include "gnss_flowgraph.h" | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <boost/thread/thread.hpp> | ||||
| #include <gnuradio/io_signature.h> | ||||
| #include <gnuradio/message.h> | ||||
| #include <glog/log_severity.h> | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| // Constructor | ||||
| GenSignalSource::GenSignalSource(ConfigurationInterface *configuration, | ||||
|         GNSSBlockInterface *signal_generator, GNSSBlockInterface *filter, | ||||
|         std::string role, boost::shared_ptr<gr::msg_queue> queue) : | ||||
|     signal_generator_(signal_generator), | ||||
|     filter_(filter), | ||||
|     role_(role), | ||||
|     queue_(queue) | ||||
| { | ||||
|     connected_ = false; | ||||
| } | ||||
|  | ||||
|  | ||||
| // Destructor | ||||
| GenSignalSource::~GenSignalSource() | ||||
| { | ||||
|     delete signal_generator_; | ||||
|     delete filter_; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GenSignalSource::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (connected_) | ||||
|         { | ||||
|             LOG_AT_LEVEL(WARNING) << "Signal conditioner already connected internally"; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|     signal_generator_->connect(top_block); | ||||
|     filter_->connect(top_block); | ||||
|  | ||||
|     top_block->connect(signal_generator_->get_right_block(), 0, | ||||
|                        filter_->get_left_block(), 0); | ||||
|  | ||||
|     DLOG(INFO) << "signal_generator -> filter"; | ||||
|  | ||||
|     connected_ = true; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GenSignalSource::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (!connected_) | ||||
|         { | ||||
|             LOG_AT_LEVEL(WARNING) << "Signal conditioner already disconnected internally"; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|     top_block->disconnect(signal_generator_->get_right_block(), 0, | ||||
|                           filter_->get_left_block(), 0); | ||||
|  | ||||
|     signal_generator_->disconnect(top_block); | ||||
|     filter_->disconnect(top_block); | ||||
|  | ||||
|     connected_ = false; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GenSignalSource::get_left_block() | ||||
| { | ||||
|     return signal_generator_->get_left_block(); | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GenSignalSource::get_right_block() | ||||
| { | ||||
|     return filter_->get_right_block(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										80
									
								
								src/algorithms/signal_source/adapters/gen_signal_source.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/algorithms/signal_source/adapters/gen_signal_source.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /*! | ||||
|  * \file gen_signal_source.h | ||||
|  * \brief It wraps blocks that generates synthesized GNSS signal and filters | ||||
|  *  it. | ||||
|  * \author Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2013  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GEN_SIGNAL_SOURCE_H_ | ||||
| #define GNSS_SDR_GEN_SIGNAL_SOURCE_H_ | ||||
|  | ||||
| #include <gnuradio/msg_queue.h> | ||||
| #include "gnss_block_interface.h" | ||||
|  | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class wraps blocks that generates synthesized GNSS signal and | ||||
|  * filters the signal. | ||||
|  */ | ||||
| class GenSignalSource: public GNSSBlockInterface | ||||
| { | ||||
| public: | ||||
|     //! Constructor | ||||
|     GenSignalSource(ConfigurationInterface *configuration, | ||||
|             GNSSBlockInterface *signal_generator, GNSSBlockInterface *filter, | ||||
|             std::string role, boost::shared_ptr<gr::msg_queue> queue); | ||||
|  | ||||
|     //! Virtual destructor | ||||
|     virtual ~GenSignalSource(); | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block); | ||||
|     void disconnect(gr::top_block_sptr top_block); | ||||
|     gr::basic_block_sptr get_left_block(); | ||||
|     gr::basic_block_sptr get_right_block(); | ||||
|  | ||||
|     std::string role(){ return role_; } | ||||
|  | ||||
|     //! Returns "Signal Source" | ||||
|     std::string implementation(){ return "Signal Source"; } | ||||
|     size_t item_size(){ return 0; } | ||||
|  | ||||
|     GNSSBlockInterface *signal_generator(){ return signal_generator_; } | ||||
|     GNSSBlockInterface *output_filter(){ return filter_; } | ||||
|  | ||||
| private: | ||||
|     GNSSBlockInterface *signal_generator_; | ||||
|     GNSSBlockInterface *filter_; | ||||
|     std::string role_; | ||||
|     std::string implementation_; | ||||
|     bool connected_; | ||||
|     boost::shared_ptr<gr::msg_queue> queue_; | ||||
| }; | ||||
|  | ||||
| #endif /*GNSS_SDR_GEN_SIGNAL_SOURCE_H*/ | ||||
| @@ -61,6 +61,7 @@ public: | ||||
|     virtual void set_doppler_step(unsigned int doppler_step) = 0; | ||||
|     virtual void set_channel_queue(concurrent_queue<int> *channel_internal_queue) = 0; | ||||
|     virtual void init() = 0; | ||||
|     virtual void set_local_code() = 0; | ||||
|     virtual signed int mag() = 0; | ||||
|     virtual void reset() = 0; | ||||
| }; | ||||
|   | ||||
| @@ -48,7 +48,7 @@ const double Galileo_E1_SUB_CARRIER_A_RATE_HZ = 1.023e6; //!< Galileo E1 sub-car | ||||
| const double Galileo_E1_SUB_CARRIER_B_RATE_HZ = 6.138e6; //!< Galileo E1 sub-carrier 'b' rate [Hz] | ||||
| const double Galileo_E1_B_CODE_LENGTH_CHIPS = 4092.0; //!< Galileo E1-B code length [chips] | ||||
| const double Galileo_E1_B_SYMBOL_RATE_BPS = 250.0; //!< Galileo E1-B symbol rate [bits/second] | ||||
|  | ||||
| const double Galileo_E1_C_SECONDARY_CODE_LENGTH = 25.0; //!< Galileo E1-C secondary code length [chips] | ||||
| const int Galileo_E1_NUMBER_OF_CODES = 50; | ||||
|  | ||||
| // Galileo INAV Telemetry structure | ||||
| @@ -188,4 +188,8 @@ const std::string Galileo_E1_C_PRIMARY_CODE[Galileo_E1_NUMBER_OF_CODES] = { | ||||
| 		"CD7AAC98501F29507EA4E0183E8A40D2E5117E47BB5D18D01A3732DE4C821DFE86521CBEA7DB29BE1148BD544ECC681689BCD1B41EAF755310B7659342F8EE11CB41550CC30E566E192796B66C1A83C0B28BACCFA6C393043A0A2CB89712BC1CCB174DE58E66896AF39C1CEED1E05B0435F8CF6FD920D100F51584FE24879987399481DBF27DDB6286B6353919E552E669290CE02AB4CD5113D7F484229F379C7332767EC69E4336439B05DE1C1E3563DD303A4F580BFF20A40E49CB0822F715ED0221EBCDB5DBAD751124B1715E82F37488265135B6C8BBCF4F801ECC4D3525FF189493AD4EFF0C042B070C4CA8FB1FDF43D79F06A6E4E3D35D7B07D4B728D5DC54EEDACBBBA1EDDCDC07ADF7DFCFEF835E44DF1FF66DAF2A7BAEBE218AC3B15E183044D6A8A89B3C101B40BED97ED5DF93BBC1B84931D56B8C822A6D058AC74CFA4C85D8B456698E82D5B7574C17B041E5F4BEED09F75012355CBC322B822C63F10C18A8F279E9A0E18E1FEF183D23E13894E31F6D046956FE8A647558228F6D4D6910151EC03937876B6ED7A078D33DAEB3F2239353BB8181E62B286BBC41588DE10F478A5CE5B508F205A41820356767B0A0ED4B8DB9EFE348362E9A90D6C30218B295B338B51C09239D02FC8A1E7DAAAB60AC37F5E67CFC88EEF69567B5C81A03B449F4ED38B9D295A36AA3503173F6F6F66D93CE72D753076040FACDE", | ||||
| 		"ADDCEDB50E907D20E826E6E8A0D30C20C74B2DF204EA784BAE9F618CAE33A3C937729DF9CB10BA2A4C33E0182A37200C0CC509729D828B8A2A20F283AC4F9306596684EA3FB5492A4C9F2DB459E7531C9F9C0950E7D9E93B3EE5912AE7E39AC8F4EC14B18F24E325003F477E347C5AC1B67CDB11AF3BBBBCD0AC3703024B5767AA67A208254F798684BFD1D3EACD757EEC77254950A146620400DB95E694574F739A991EBA771EBBDFF1056BB39A77DBE0636A032E17141332F951C57C6C90F348F165E3ABDD60D429D5D6BEC7E3E3463806F819EB2D212B3528A5EDE51F235AD100A35E890955F8A1DC51FDCB53EABCA2540997DD054C1F5B29462995B876B44D085904E55E1B838BEF600A992EB49CE078DF75AF3D0F137685AC0D07F0BE1EB87B63A41E74DDE869C8A683BDE60AF5D77FF18F7137495BCEFD0ED28F62F9C3E25D332B5F861D999FCDC0B4851A984A4DBB53401FD40351ADA4335C702BCC8D900C737507B990BDDBE91D201E3A0946DC968D43FD10D04B0B76667FF5B4291C2124B0124C6B710A6D1BCFAEB016B9DEEB0F7A4FE044CA4EA0CCD84B7682617C3A545071EC295B0663B3F577D562DE1D9DD80DE6A1EFD6D5991EB5246F1597B86D0E9A90CF6DB0EB2B8E7BAE9431E567F01AA98502C773742246467ABF911A91A51F6C1B9E0C3233DC1A37D17DB91A5F0F661B0EB5886964456C7818601BD0C" | ||||
| }; | ||||
|  | ||||
| const std::string Galileo_E1_C_SECONDARY_CODE = | ||||
|         "0011100000001010110110010"; | ||||
|  | ||||
| #endif /* GNSS_SDR_GALILEO_E1_H_ */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Luis Esteve
					Luis Esteve