mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-30 23:03:05 +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(telemetry_decoder) | ||||||
| add_subdirectory(output_filter) | add_subdirectory(output_filter) | ||||||
| add_subdirectory(resampler) | add_subdirectory(resampler) | ||||||
|  | add_subdirectory(signal_generator) | ||||||
| add_subdirectory(signal_source) | add_subdirectory(signal_source) | ||||||
| add_subdirectory(input_filter) | add_subdirectory(input_filter) | ||||||
| add_subdirectory(tracking) | add_subdirectory(tracking) | ||||||
|   | |||||||
| @@ -71,17 +71,20 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( | |||||||
|             fs_in_ |             fs_in_ | ||||||
|             / (Galileo_E1_CODE_CHIP_RATE_HZ |             / (Galileo_E1_CODE_CHIP_RATE_HZ | ||||||
|                     / Galileo_E1_B_CODE_LENGTH_CHIPS)); |                     / Galileo_E1_B_CODE_LENGTH_CHIPS)); | ||||||
|  |  | ||||||
|     int samples_per_ms = vector_length_ / 4; |     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) |     if (item_type_.compare("gr_complex") == 0) | ||||||
|         { |         { | ||||||
|             item_size_ = sizeof(gr_complex); |             item_size_ = sizeof(gr_complex); | ||||||
|             acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, |             acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, | ||||||
|                     shift_resolution_, if_, fs_in_, samples_per_ms, queue_, |                     shift_resolution_, if_, fs_in_, samples_per_ms, vector_length_, | ||||||
|                     dump_, dump_filename_); |                     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_, samples_per_ms * sampled_ms_); | ||||||
|             DLOG(INFO) << "stream_to_vector(" |             DLOG(INFO) << "stream_to_vector(" | ||||||
|                     << stream_to_vector_->unique_id() << ")"; |                     << stream_to_vector_->unique_id() << ")"; | ||||||
|             DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() |             DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() | ||||||
| @@ -115,6 +118,7 @@ GalileoE1PcpsAmbiguousAcquisition::set_channel(unsigned int channel) | |||||||
| void | void | ||||||
| GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) | GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|  |  | ||||||
| 	float pfa = configuration_->property(role_+ boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0); | 	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); | 	if(pfa==0.0) pfa = configuration_->property(role_+".pfa", 0.0); | ||||||
| @@ -124,7 +128,7 @@ GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) | |||||||
| 		threshold_ = threshold; | 		threshold_ = threshold; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ |     { | ||||||
| 		threshold_ = calculate_threshold(pfa); | 		threshold_ = calculate_threshold(pfa); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -202,16 +206,32 @@ GalileoE1PcpsAmbiguousAcquisition::mag() | |||||||
|  |  | ||||||
| void | void | ||||||
| GalileoE1PcpsAmbiguousAcquisition::init() | GalileoE1PcpsAmbiguousAcquisition::init() | ||||||
|  | { | ||||||
|  |     acquisition_cc_->init(); | ||||||
|  |     set_local_code(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | GalileoE1PcpsAmbiguousAcquisition::set_local_code() | ||||||
| { | { | ||||||
|     if (item_type_.compare("gr_complex") == 0) |     if (item_type_.compare("gr_complex") == 0) | ||||||
|         { |         { | ||||||
|             bool cboc = configuration_->property( |             bool cboc = configuration_->property( | ||||||
|                     "Acquisition" + boost::lexical_cast<std::string>(channel_) |                     "Acquisition" + boost::lexical_cast<std::string>(channel_) | ||||||
|                             + ".cboc", false); |                             + ".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_->set_local_code(code_); | ||||||
|             acquisition_cc_->init(); |  | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -227,8 +247,6 @@ GalileoE1PcpsAmbiguousAcquisition::reset() | |||||||
|  |  | ||||||
| float GalileoE1PcpsAmbiguousAcquisition::calculate_threshold(float pfa) | float GalileoE1PcpsAmbiguousAcquisition::calculate_threshold(float pfa) | ||||||
| { | { | ||||||
| 	//Calculate the threshold |  | ||||||
|  |  | ||||||
| 	unsigned int frequency_bins = 0; | 	unsigned int frequency_bins = 0; | ||||||
| 	for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_) | 	for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
| @@ -113,6 +113,12 @@ public: | |||||||
|      */ |      */ | ||||||
|     void init(); |     void init(); | ||||||
|  |  | ||||||
|  |     /*! | ||||||
|  |      * \brief Sets local code for Galileo E1 PCPS acquisition algorithm. | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     void set_local_code(); | ||||||
|  |  | ||||||
|     /*! |     /*! | ||||||
|      * \brief Returns the maximum peak of grid search |      * \brief Returns the maximum peak of grid search | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | |||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||||
|     if_ = configuration_->property(role + ".ifreq", 0); |     if_ = configuration_->property(role + ".ifreq", 0); | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |     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); |     sampled_ms_ = configuration_->property(role + ".sampled_ms", 1); | ||||||
|     dump_filename_ = configuration_->property(role + ".dump_filename", |     dump_filename_ = configuration_->property(role + ".dump_filename", | ||||||
|             default_dump_filename); |             default_dump_filename); | ||||||
| @@ -74,16 +74,16 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | |||||||
|     vector_length_ = round(fs_in_ |     vector_length_ = round(fs_in_ | ||||||
|             / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); |             / (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) |     if (item_type_.compare("gr_complex") == 0) | ||||||
|     { |     { | ||||||
|         item_size_ = sizeof(gr_complex); |         item_size_ = sizeof(gr_complex); | ||||||
|         acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, |         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_); |                 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() |         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); |                  pfa = configuration_->property(role_+".pfa", 0.0); | ||||||
|         } |         } | ||||||
| 	if(pfa==0.0) | 	if(pfa==0.0) | ||||||
| 	{ | 		{ | ||||||
| 		threshold_ = threshold; | 			threshold_ = threshold; | ||||||
| 	} | 		} | ||||||
| 	else | 	else | ||||||
| 	{ | 		{ | ||||||
| 		threshold_ = calculate_threshold(pfa); | 			threshold_ = calculate_threshold(pfa); | ||||||
| 	} | 		} | ||||||
|  |  | ||||||
| 	DLOG(INFO) <<"Channel "<<channel_<<" Threshold = " << threshold_; | 	DLOG(INFO) <<"Channel "<<channel_<<" Threshold = " << threshold_; | ||||||
|  |  | ||||||
| @@ -195,15 +195,29 @@ signed int GpsL1CaPcpsAcquisition::mag() | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL1CaPcpsAcquisition::init(){ | void GpsL1CaPcpsAcquisition::init() | ||||||
|     if (item_type_.compare("gr_complex") == 0) | { | ||||||
|     { |     acquisition_cc_->init(); | ||||||
|     	gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); |     set_local_code(); | ||||||
|     	acquisition_cc_->set_local_code(code_); |  | ||||||
|         acquisition_cc_->init(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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() | void GpsL1CaPcpsAcquisition::reset() | ||||||
| { | { | ||||||
| @@ -238,9 +252,9 @@ float GpsL1CaPcpsAcquisition::calculate_threshold(float pfa) | |||||||
| void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_.compare("gr_complex") == 0) |     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> |  * \authors <ul> | ||||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es |  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com |  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||||
|  *          </ul> * |  *          </ul> | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  * |  * | ||||||
| @@ -116,6 +116,12 @@ public: | |||||||
|      */ |      */ | ||||||
|     void init(); |     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 |      * \brief Returns the maximum peak of grid search | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -146,10 +146,17 @@ signed int GpsL1CaPcpsAcquisitionFineDoppler::mag() | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL1CaPcpsAcquisitionFineDoppler::init(){ | 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(); | ||||||
|         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 init(); | ||||||
|  |  | ||||||
|  |     void set_local_code(); | ||||||
|  |  | ||||||
|     /*! |     /*! | ||||||
|      * \brief Returns the maximum peak of grid search |      * \brief Returns the maximum peak of grid search | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -145,12 +145,17 @@ signed int GpsL1CaPcpsAssistedAcquisition::mag() | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL1CaPcpsAssistedAcquisition::init(){ | 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(); | ||||||
|         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() | void GpsL1CaPcpsAssistedAcquisition::reset() | ||||||
| { | { | ||||||
|   | |||||||
| @@ -115,6 +115,8 @@ public: | |||||||
|      */ |      */ | ||||||
|     void init(); |     void init(); | ||||||
|  |  | ||||||
|  |     void set_local_code(); | ||||||
|  |  | ||||||
|     /*! |     /*! | ||||||
|      * \brief Returns the maximum peak of grid search |      * \brief Returns the maximum peak of grid search | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
|  * \authors <ul> |  * \authors <ul> | ||||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es |  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com |  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||||
|  |  *          <li> Marc Molina, 2013. marc.molina.pena@gmail.com | ||||||
|  *          </ul> |  *          </ul> | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
| @@ -43,25 +44,25 @@ | |||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| pcps_acquisition_cc_sptr pcps_make_acquisition_cc( | pcps_acquisition_cc_sptr pcps_make_acquisition_cc( | ||||||
|         unsigned int sampled_ms, unsigned int doppler_max, long freq, |         unsigned int sampled_ms, unsigned int doppler_max, | ||||||
|         long fs_in, int samples_per_ms, gr::msg_queue::sptr queue, bool dump, |         long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||||
|         std::string dump_filename) |         gr::msg_queue::sptr queue, bool dump, std::string dump_filename) | ||||||
| { | { | ||||||
|  |  | ||||||
|     return pcps_acquisition_cc_sptr( |     return pcps_acquisition_cc_sptr( | ||||||
|             new pcps_acquisition_cc(sampled_ms, doppler_max, freq, |             new pcps_acquisition_cc(sampled_ms, doppler_max, freq, fs_in, | ||||||
|                     fs_in, samples_per_ms, queue, dump, dump_filename)); |                     samples_per_ms, samples_per_code, queue, dump, dump_filename)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| pcps_acquisition_cc::pcps_acquisition_cc( | pcps_acquisition_cc::pcps_acquisition_cc( | ||||||
|         unsigned int sampled_ms, unsigned int doppler_max, long freq, |         unsigned int sampled_ms, unsigned int doppler_max, | ||||||
|         long fs_in, int samples_per_ms, gr::msg_queue::sptr queue, bool dump, |         long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||||
|         std::string dump_filename) : |         gr::msg_queue::sptr queue, bool dump, std::string dump_filename) : | ||||||
|         gr::block("pcps_acquisition_cc", |     gr::block("pcps_acquisition_cc", | ||||||
|         gr::io_signature::make(1, 1, sizeof(gr_complex) * sampled_ms * samples_per_ms), |     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)) |     gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) | ||||||
| { | { | ||||||
|     d_sample_counter = 0;    // SAMPLE COUNTER |     d_sample_counter = 0;    // SAMPLE COUNTER | ||||||
|     d_active = false; |     d_active = false; | ||||||
| @@ -69,15 +70,17 @@ pcps_acquisition_cc::pcps_acquisition_cc( | |||||||
|     d_freq = freq; |     d_freq = freq; | ||||||
|     d_fs_in = fs_in; |     d_fs_in = fs_in; | ||||||
|     d_samples_per_ms = samples_per_ms; |     d_samples_per_ms = samples_per_ms; | ||||||
|  |     d_samples_per_code = samples_per_code; | ||||||
|     d_sampled_ms = sampled_ms; |     d_sampled_ms = sampled_ms; | ||||||
|     d_doppler_max = doppler_max; |     d_doppler_max = doppler_max; | ||||||
|     d_fft_size = d_sampled_ms * d_samples_per_ms; |     d_fft_size = d_sampled_ms * d_samples_per_ms; | ||||||
|     d_mag = 0; |     d_mag = 0; | ||||||
|     d_input_power = 0.0; |     d_input_power = 0.0; | ||||||
|  |     d_num_doppler_bins = 0; | ||||||
|  |  | ||||||
|     //todo: do something if posix_memalign fails |     //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_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 |     // Direct FFT | ||||||
|     d_fft_if = new gr::fft::fft_complex(d_fft_size, true); |     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() | 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_fft_codes); | ||||||
|  |     free(d_magnitude); | ||||||
|  |  | ||||||
|     delete d_ifft; |     delete d_ifft; | ||||||
|     delete d_fft_if; |     delete d_fft_if; | ||||||
|     if (d_dump) |     if (d_dump) | ||||||
| @@ -108,7 +125,19 @@ pcps_acquisition_cc::~pcps_acquisition_cc() | |||||||
|  |  | ||||||
| void pcps_acquisition_cc::set_local_code(std::complex<float> * code) | 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_mag = 0.0; | ||||||
|     d_input_power = 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 |             int doppler=-(int)d_doppler_max+d_doppler_step*doppler_index; | ||||||
|     for (unsigned int i = 0; i < d_fft_size; i++) |             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], | ||||||
|     { |                                  d_freq + doppler, d_fs_in, d_fft_size); | ||||||
|         d_fft_codes[i] = std::complex<float>(conj(d_fft_if->get_outbuf()[i])); |         } | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -158,7 +192,6 @@ int pcps_acquisition_cc::general_work(int noutput_items, | |||||||
|             int doppler; |             int doppler; | ||||||
|             unsigned int indext = 0; |             unsigned int indext = 0; | ||||||
|             float magt = 0.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 |             const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer | ||||||
|             bool positive_acquisition = false; |             bool positive_acquisition = false; | ||||||
|             int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL |             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; |             d_input_power = 0.0; | ||||||
|  |  | ||||||
|             DLOG(INFO) << "Channel: " << d_channel |             DLOG(INFO) << "Channel: " << d_channel | ||||||
|                        << " , doing acquisition of satellite: " << d_gnss_synchro->System |                     << " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN | ||||||
|                        << " "<< d_gnss_synchro->PRN |                     << " ,sample stamp: " << d_sample_counter << ", threshold: " | ||||||
|                        << " ,sample stamp: " << d_sample_counter << ", threshold: " |                     << d_threshold << ", doppler_max: " << d_doppler_max | ||||||
|                        << d_threshold << ", doppler_max: " << d_doppler_max |                     << ", doppler_step: " << d_doppler_step; | ||||||
|                        << ", doppler_step: " << d_doppler_step; |  | ||||||
|  |  | ||||||
|             // 1- Compute the input signal power estimation |             // 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 |             // 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 |                     // 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. |                     doppler=-(int)d_doppler_max+d_doppler_step*doppler_index; | ||||||
|                     // Perform the carrier wipe-off |  | ||||||
|                     complex_exp_gen_conj(d_carrier, d_freq + doppler, d_fs_in, d_fft_size); |                     if (is_unaligned()) | ||||||
|                     if (is_unaligned()==true) |  | ||||||
|                         { |                         { | ||||||
|                             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 |                     else | ||||||
|                         { |                         { | ||||||
|                             //use directly the input vector |                             volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in, | ||||||
|                             volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), in, d_carrier, d_fft_size); |                                         d_grid_doppler_wipeoffs[doppler_index], d_fft_size); | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                     // 3- Perform the FFT-based convolution  (parallel time search) |                     // 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 |                     // Multiply carrier wiped--off, Fourier transformed incoming signal | ||||||
|                     // with the local FFT'd code reference using SIMD operations with VOLK library |                     // 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 |                     // compute the inverse FFT | ||||||
|                     d_ifft->execute(); |                     d_ifft->execute(); | ||||||
|  |  | ||||||
|                     // Search maximum |                     // Search maximum | ||||||
|                     indext = 0; |                     indext = 0; | ||||||
|                     magt = 0; |                     magt = 0.0; | ||||||
|  |  | ||||||
|                     fft_normalization_factor = (float)d_fft_size * (float)d_fft_size; |                     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]); |                             volk_32fc_magnitude_squared_32f_u(d_magnitude, d_ifft->get_outbuf(), d_fft_size); | ||||||
|                             if (tmp_magt > magt) |                             for (i = 0; i < d_fft_size; i++) | ||||||
|                                 { |                                 { | ||||||
|                                     magt = tmp_magt; |                                     if(d_magnitude[i] > magt) | ||||||
|                                     indext = i; |                                         { | ||||||
|  |                                             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 |                     // 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 |                     // 4- record the maximum peak and the associated synchronization parameters | ||||||
|                     if (d_mag < magt) |                     if (d_mag < magt) | ||||||
|                         { |                         { | ||||||
|                             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; |                             d_gnss_synchro->Acq_doppler_hz = (double)doppler; | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
| @@ -298,6 +357,7 @@ int pcps_acquisition_cc::general_work(int noutput_items, | |||||||
|                 { |                 { | ||||||
|                     acquisition_message = 2; |                     acquisition_message = 2; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|             d_channel_internal_queue->push(acquisition_message); |             d_channel_internal_queue->push(acquisition_message); | ||||||
|             consume_each(1); |             consume_each(1); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  * \authors <ul> |  * \authors <ul> | ||||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es |  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com |  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||||
|  |  *          <li> Marc Molina, 2013. marc.molina.pena@gmail.com | ||||||
|  *          </ul> |  *          </ul> | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
| @@ -65,8 +66,8 @@ class pcps_acquisition_cc; | |||||||
| typedef boost::shared_ptr<pcps_acquisition_cc> pcps_acquisition_cc_sptr; | typedef boost::shared_ptr<pcps_acquisition_cc> pcps_acquisition_cc_sptr; | ||||||
|  |  | ||||||
| pcps_acquisition_cc_sptr | pcps_acquisition_cc_sptr | ||||||
| pcps_make_acquisition_cc(unsigned int sampled_ms, | pcps_make_acquisition_cc(unsigned int sampled_ms, unsigned int doppler_max, | ||||||
|         unsigned int doppler_max, long freq, long fs_in, int samples_per_ms, |         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::msg_queue::sptr queue, bool dump, std::string dump_filename); | ||||||
|  |  | ||||||
| /*! | /*! | ||||||
| @@ -79,47 +80,49 @@ class pcps_acquisition_cc: public gr::block | |||||||
| { | { | ||||||
| private: | private: | ||||||
|     friend pcps_acquisition_cc_sptr |     friend pcps_acquisition_cc_sptr | ||||||
|     pcps_make_acquisition_cc(unsigned int sampled_ms, |     pcps_make_acquisition_cc(unsigned int sampled_ms, unsigned int doppler_max, | ||||||
|             unsigned int doppler_max, long freq, long fs_in, |             long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||||
|             int samples_per_ms, gr::msg_queue::sptr queue, bool dump, |             gr::msg_queue::sptr queue, bool dump, std::string dump_filename); | ||||||
|             std::string dump_filename); |  | ||||||
|  |  | ||||||
|     pcps_acquisition_cc(unsigned int sampled_ms, |     pcps_acquisition_cc(unsigned int sampled_ms, unsigned int doppler_max, | ||||||
|             unsigned int doppler_max, long freq, long fs_in, |             long freq, long fs_in, int samples_per_ms, int samples_per_code, | ||||||
|             int samples_per_ms, gr::msg_queue::sptr d_queue, bool dump, |             gr::msg_queue::sptr queue, bool dump, std::string dump_filename); | ||||||
|             std::string dump_filename); |  | ||||||
|  |  | ||||||
|     void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift, |     void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift, | ||||||
|             int doppler_offset); |             int doppler_offset); | ||||||
|  |  | ||||||
|     long d_fs_in; |  | ||||||
|     long d_freq; | 	long d_fs_in; | ||||||
|     int d_samples_per_ms; | 	long d_freq; | ||||||
|     unsigned int d_doppler_resolution; | 	int d_samples_per_ms; | ||||||
|     float d_threshold; |     int d_samples_per_code; | ||||||
|     std::string d_satellite_str; | 	unsigned int d_doppler_resolution; | ||||||
|     unsigned int d_doppler_max; | 	float d_threshold; | ||||||
|     unsigned int d_doppler_step; | 	std::string d_satellite_str; | ||||||
|     unsigned int d_sampled_ms; | 	unsigned int d_doppler_max; | ||||||
|     unsigned int d_fft_size; | 	unsigned int d_doppler_step; | ||||||
|     unsigned long int d_sample_counter; | 	unsigned int d_sampled_ms; | ||||||
|     gr_complex* d_carrier; | 	unsigned int d_fft_size; | ||||||
|     gr_complex* d_fft_codes; | 	unsigned long int d_sample_counter; | ||||||
|     gr::fft::fft_complex* d_fft_if; |     gr_complex** d_grid_doppler_wipeoffs; | ||||||
|     gr::fft::fft_complex* d_ifft; |     unsigned int d_num_doppler_bins; | ||||||
|     Gnss_Synchro *d_gnss_synchro; | 	gr_complex* d_fft_codes; | ||||||
|     unsigned int d_code_phase; | 	gr::fft::fft_complex* d_fft_if; | ||||||
|     float d_doppler_freq; | 	gr::fft::fft_complex* d_ifft; | ||||||
|     float d_mag; | 	Gnss_Synchro *d_gnss_synchro; | ||||||
|     float d_input_power; | 	unsigned int d_code_phase; | ||||||
|     float d_test_statistics; | 	float d_doppler_freq; | ||||||
|  | 	float d_mag; | ||||||
|  |     float* d_magnitude; | ||||||
|  | 	float d_input_power; | ||||||
|  | 	float d_test_statistics; | ||||||
|     gr::msg_queue::sptr d_queue; |     gr::msg_queue::sptr d_queue; | ||||||
|     concurrent_queue<int> *d_channel_internal_queue; | 	concurrent_queue<int> *d_channel_internal_queue; | ||||||
|     std::ofstream d_dump_file; | 	std::ofstream d_dump_file; | ||||||
|     bool d_active; | 	bool d_active; | ||||||
|     bool d_dump; | 	bool d_dump; | ||||||
|     unsigned int d_channel; | 	unsigned int d_channel; | ||||||
|     std::string d_dump_filename; | 	std::string d_dump_filename; | ||||||
|  |  | ||||||
| public: | 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_) |     unsigned int doppler_step = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) | ||||||
|     		+ ".doppler_step",0); |     		+ ".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; |     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_->set_threshold(threshold); | ||||||
|  |  | ||||||
|  |     acq_->init(); | ||||||
|  |  | ||||||
|     repeat_ = configuration->property("Acquisition" + boost::lexical_cast< |     repeat_ = configuration->property("Acquisition" + boost::lexical_cast< | ||||||
|             std::string>(channel_) + ".repeat_satellite", false); |             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_.Signal[2] = 0; // make sure that string length is only two characters | ||||||
|     gnss_synchro_.PRN = gnss_signal_.get_satellite().get_PRN(); |     gnss_synchro_.PRN = gnss_signal_.get_satellite().get_PRN(); | ||||||
|     gnss_synchro_.System = gnss_signal_.get_satellite().get_system_short().c_str()[0]; |     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()); |     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], |                     hex_to_binary_converter(&_dest[index], | ||||||
|                             Galileo_E1_B_PRIMARY_CODE[prn].at(i)); |                             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 alpha = sqrt(10.0 / 11.0); | ||||||
|     const float beta = sqrt(1.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_11[_codeLength]; // 12*4092 (_codeLength not accepted by Clang ) | ||||||
|     std::complex<float> sinboc_61[49152]; |     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_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 |     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 | void | ||||||
| galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3], | 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; |     unsigned int _samplesPerCode; | ||||||
|     const unsigned int _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; //Hz |     const unsigned int _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; //Hz | ||||||
|     unsigned int _codeLength = Galileo_E1_B_CODE_LENGTH_CHIPS; |     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)); |     _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 |     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) |     if (_cboc == true) | ||||||
|         { |         { | ||||||
|             _codeLength = 12 * Galileo_E1_B_CODE_LENGTH_CHIPS; |             galileo_e1_gen(_signal_E1, primary_code_E1_chips, _Signal); //generate cboc 12 samples per chip | ||||||
|             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 |  | ||||||
|                 } |  | ||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
|             //--- Find number of samples per spreading code ---------------------------- |             galileo_e1_sinboc_11_gen(_signal_E1, primary_code_E1_chips, | ||||||
|             _codeLength = 2 * Galileo_E1_B_CODE_LENGTH_CHIPS; |                     _codeLength); //generate sinboc(1,1) 2 samples per chip | ||||||
|             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                } |  | ||||||
|                 } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |     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], | void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3], | ||||||
|         bool _cboc, unsigned int _prn, signed int _fs, |         bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift, | ||||||
|         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_ */ | #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})  |     set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${RTL_DRIVER_INCLUDE_DIRS})  | ||||||
| endif(RTLSDR_DRIVER) | 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( | 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_doppler_step(unsigned int doppler_step) = 0; | ||||||
|     virtual void set_channel_queue(concurrent_queue<int> *channel_internal_queue) = 0; |     virtual void set_channel_queue(concurrent_queue<int> *channel_internal_queue) = 0; | ||||||
|     virtual void init() = 0; |     virtual void init() = 0; | ||||||
|  |     virtual void set_local_code() = 0; | ||||||
|     virtual signed int mag() = 0; |     virtual signed int mag() = 0; | ||||||
|     virtual void reset() = 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_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_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_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; | const int Galileo_E1_NUMBER_OF_CODES = 50; | ||||||
|  |  | ||||||
| // Galileo INAV Telemetry structure | // Galileo INAV Telemetry structure | ||||||
| @@ -188,4 +188,8 @@ const std::string Galileo_E1_C_PRIMARY_CODE[Galileo_E1_NUMBER_OF_CODES] = { | |||||||
| 		"CD7AAC98501F29507EA4E0183E8A40D2E5117E47BB5D18D01A3732DE4C821DFE86521CBEA7DB29BE1148BD544ECC681689BCD1B41EAF755310B7659342F8EE11CB41550CC30E566E192796B66C1A83C0B28BACCFA6C393043A0A2CB89712BC1CCB174DE58E66896AF39C1CEED1E05B0435F8CF6FD920D100F51584FE24879987399481DBF27DDB6286B6353919E552E669290CE02AB4CD5113D7F484229F379C7332767EC69E4336439B05DE1C1E3563DD303A4F580BFF20A40E49CB0822F715ED0221EBCDB5DBAD751124B1715E82F37488265135B6C8BBCF4F801ECC4D3525FF189493AD4EFF0C042B070C4CA8FB1FDF43D79F06A6E4E3D35D7B07D4B728D5DC54EEDACBBBA1EDDCDC07ADF7DFCFEF835E44DF1FF66DAF2A7BAEBE218AC3B15E183044D6A8A89B3C101B40BED97ED5DF93BBC1B84931D56B8C822A6D058AC74CFA4C85D8B456698E82D5B7574C17B041E5F4BEED09F75012355CBC322B822C63F10C18A8F279E9A0E18E1FEF183D23E13894E31F6D046956FE8A647558228F6D4D6910151EC03937876B6ED7A078D33DAEB3F2239353BB8181E62B286BBC41588DE10F478A5CE5B508F205A41820356767B0A0ED4B8DB9EFE348362E9A90D6C30218B295B338B51C09239D02FC8A1E7DAAAB60AC37F5E67CFC88EEF69567B5C81A03B449F4ED38B9D295A36AA3503173F6F6F66D93CE72D753076040FACDE", | 		"CD7AAC98501F29507EA4E0183E8A40D2E5117E47BB5D18D01A3732DE4C821DFE86521CBEA7DB29BE1148BD544ECC681689BCD1B41EAF755310B7659342F8EE11CB41550CC30E566E192796B66C1A83C0B28BACCFA6C393043A0A2CB89712BC1CCB174DE58E66896AF39C1CEED1E05B0435F8CF6FD920D100F51584FE24879987399481DBF27DDB6286B6353919E552E669290CE02AB4CD5113D7F484229F379C7332767EC69E4336439B05DE1C1E3563DD303A4F580BFF20A40E49CB0822F715ED0221EBCDB5DBAD751124B1715E82F37488265135B6C8BBCF4F801ECC4D3525FF189493AD4EFF0C042B070C4CA8FB1FDF43D79F06A6E4E3D35D7B07D4B728D5DC54EEDACBBBA1EDDCDC07ADF7DFCFEF835E44DF1FF66DAF2A7BAEBE218AC3B15E183044D6A8A89B3C101B40BED97ED5DF93BBC1B84931D56B8C822A6D058AC74CFA4C85D8B456698E82D5B7574C17B041E5F4BEED09F75012355CBC322B822C63F10C18A8F279E9A0E18E1FEF183D23E13894E31F6D046956FE8A647558228F6D4D6910151EC03937876B6ED7A078D33DAEB3F2239353BB8181E62B286BBC41588DE10F478A5CE5B508F205A41820356767B0A0ED4B8DB9EFE348362E9A90D6C30218B295B338B51C09239D02FC8A1E7DAAAB60AC37F5E67CFC88EEF69567B5C81A03B449F4ED38B9D295A36AA3503173F6F6F66D93CE72D753076040FACDE", | ||||||
| 		"ADDCEDB50E907D20E826E6E8A0D30C20C74B2DF204EA784BAE9F618CAE33A3C937729DF9CB10BA2A4C33E0182A37200C0CC509729D828B8A2A20F283AC4F9306596684EA3FB5492A4C9F2DB459E7531C9F9C0950E7D9E93B3EE5912AE7E39AC8F4EC14B18F24E325003F477E347C5AC1B67CDB11AF3BBBBCD0AC3703024B5767AA67A208254F798684BFD1D3EACD757EEC77254950A146620400DB95E694574F739A991EBA771EBBDFF1056BB39A77DBE0636A032E17141332F951C57C6C90F348F165E3ABDD60D429D5D6BEC7E3E3463806F819EB2D212B3528A5EDE51F235AD100A35E890955F8A1DC51FDCB53EABCA2540997DD054C1F5B29462995B876B44D085904E55E1B838BEF600A992EB49CE078DF75AF3D0F137685AC0D07F0BE1EB87B63A41E74DDE869C8A683BDE60AF5D77FF18F7137495BCEFD0ED28F62F9C3E25D332B5F861D999FCDC0B4851A984A4DBB53401FD40351ADA4335C702BCC8D900C737507B990BDDBE91D201E3A0946DC968D43FD10D04B0B76667FF5B4291C2124B0124C6B710A6D1BCFAEB016B9DEEB0F7A4FE044CA4EA0CCD84B7682617C3A545071EC295B0663B3F577D562DE1D9DD80DE6A1EFD6D5991EB5246F1597B86D0E9A90CF6DB0EB2B8E7BAE9431E567F01AA98502C773742246467ABF911A91A51F6C1B9E0C3233DC1A37D17DB91A5F0F661B0EB5886964456C7818601BD0C" | 		"ADDCEDB50E907D20E826E6E8A0D30C20C74B2DF204EA784BAE9F618CAE33A3C937729DF9CB10BA2A4C33E0182A37200C0CC509729D828B8A2A20F283AC4F9306596684EA3FB5492A4C9F2DB459E7531C9F9C0950E7D9E93B3EE5912AE7E39AC8F4EC14B18F24E325003F477E347C5AC1B67CDB11AF3BBBBCD0AC3703024B5767AA67A208254F798684BFD1D3EACD757EEC77254950A146620400DB95E694574F739A991EBA771EBBDFF1056BB39A77DBE0636A032E17141332F951C57C6C90F348F165E3ABDD60D429D5D6BEC7E3E3463806F819EB2D212B3528A5EDE51F235AD100A35E890955F8A1DC51FDCB53EABCA2540997DD054C1F5B29462995B876B44D085904E55E1B838BEF600A992EB49CE078DF75AF3D0F137685AC0D07F0BE1EB87B63A41E74DDE869C8A683BDE60AF5D77FF18F7137495BCEFD0ED28F62F9C3E25D332B5F861D999FCDC0B4851A984A4DBB53401FD40351ADA4335C702BCC8D900C737507B990BDDBE91D201E3A0946DC968D43FD10D04B0B76667FF5B4291C2124B0124C6B710A6D1BCFAEB016B9DEEB0F7A4FE044CA4EA0CCD84B7682617C3A545071EC295B0663B3F577D562DE1D9DD80DE6A1EFD6D5991EB5246F1597B86D0E9A90CF6DB0EB2B8E7BAE9431E567F01AA98502C773742246467ABF911A91A51F6C1B9E0C3233DC1A37D17DB91A5F0F661B0EB5886964456C7818601BD0C" | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const std::string Galileo_E1_C_SECONDARY_CODE = | ||||||
|  |         "0011100000001010110110010"; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_GALILEO_E1_H_ */ | #endif /* GNSS_SDR_GALILEO_E1_H_ */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Luis Esteve
					Luis Esteve