mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	front-end-cal code cleaning, documentation and tunning tasks
git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@400 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| ; Default configuration file | ||||
| ; You can define your own receiver and invoke it by doing | ||||
| ; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf | ||||
| ; You can define your own front-end calibration tool configuration and invoke it by doing | ||||
| ; ./front-end-cal --config_file=my_GNSS_SDR_configuration.conf | ||||
| ; | ||||
|  | ||||
| [GNSS-SDR] | ||||
| @@ -20,12 +20,9 @@ GNSS-SDR.init_altitude_m=329.11968943169342 | ||||
| ;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. | ||||
| GNSS-SDR.internal_fs_hz=2000000 | ||||
|  | ||||
| ;######### CONTROL_THREAD CONFIG ############ | ||||
| ControlThread.wait_for_flowgraph=false | ||||
|  | ||||
| ;######### SUPL RRLP GPS assistance configuration ##### | ||||
| GNSS-SDR.SUPL_gps_enabled=true | ||||
| GNSS-SDR.SUPL_read_gps_assistance_xml=false | ||||
| GNSS-SDR.SUPL_read_gps_assistance_xml=true | ||||
| GNSS-SDR.SUPL_gps_ephemeris_server=supl.nokia.com | ||||
| GNSS-SDR.SUPL_gps_ephemeris_port=7275 | ||||
| GNSS-SDR.SUPL_gps_acquisition_server=supl.nokia.com | ||||
| @@ -44,7 +41,8 @@ SignalSource.AGC_enabled=false | ||||
| ;#filename: path to file with the captured GNSS signal samples to be processed | ||||
| ;SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/cap_-90dBm_IF15_RF40_EzCap.dat | ||||
| ;SignalSource.filename=/media/DATALOGGER_/signals/Agilent GPS Generator/New York/2msps.dat | ||||
| SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/cap_ventana_CTTC_amplif_IF15_RF40usb_peq.dat | ||||
| ;SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/cap_ventana_CTTC_amplif_IF15_RF40usb_peq.dat | ||||
| SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/cap_-90dBm_IF15_RF40_usb_peq.dat | ||||
|  | ||||
| ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. | ||||
| SignalSource.item_type=gr_complex | ||||
| @@ -66,10 +64,10 @@ SignalSource.subdevice=B:0 | ||||
| ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. | ||||
| SignalSource.samples=0 | ||||
|  | ||||
| ;#repeat: Repeat the processing file. Disable this option in this version | ||||
| ;#repeat: Repeat the processing file. | ||||
| SignalSource.repeat=false | ||||
|  | ||||
| ;#dump: Dump the Signal source data to a file. Disable this option in this version | ||||
| ;#dump: Dump the Signal source data to a file. | ||||
| SignalSource.dump=false | ||||
|  | ||||
| SignalSource.dump_filename=../data/signal_source.dat | ||||
| @@ -183,7 +181,7 @@ Acquisition.if=0 | ||||
| ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] | ||||
| Acquisition.sampled_ms=1 | ||||
| ;#threshold: Acquisition threshold | ||||
| Acquisition.threshold=0.009 | ||||
| Acquisition.threshold=0.015 | ||||
| ;#doppler_max: Maximum expected Doppler shift [Hz] | ||||
| Acquisition.doppler_max=100000 | ||||
| ;#doppler_max: Maximum expected Doppler shift [Hz] | ||||
| @@ -191,5 +189,5 @@ Acquisition.doppler_min=-100000 | ||||
| ;#doppler_step Doppler step in the grid search [Hz] | ||||
| Acquisition.doppler_step=500 | ||||
| ;#maximum dwells | ||||
| Acquisition.max_dwells=20 | ||||
| Acquisition.max_dwells=15 | ||||
|  | ||||
|   | ||||
| @@ -318,7 +318,7 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star | ||||
| { | ||||
|  | ||||
| 	// Direct FFT | ||||
| 	int zero_padding_factor=8; | ||||
| 	int zero_padding_factor=16; | ||||
| 	int fft_size_extended=d_fft_size*zero_padding_factor; | ||||
| 	gr::fft::fft_complex *fft_operator=new gr::fft::fft_complex(fft_size_extended,true); | ||||
| 	//zero padding the entire vector | ||||
| @@ -364,13 +364,13 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star | ||||
|  | ||||
| 	for (int k=0;k<(fft_size_extended/2);k++) | ||||
| 	{ | ||||
| 		fftFreqBins[counter]=((d_fs_in/2)*k)/(fft_size_extended/2); | ||||
| 		fftFreqBins[counter]=(((float)d_fs_in/2.0)*(float)k)/((float)fft_size_extended/2.0); | ||||
| 		counter++; | ||||
| 	} | ||||
|  | ||||
| 	for (int k=fft_size_extended/2;k>0;k--) | ||||
| 	{ | ||||
| 		fftFreqBins[counter]=((-d_fs_in/2)*k)/(fft_size_extended/2); | ||||
| 		fftFreqBins[counter]=((-(float)d_fs_in/2)*(float)k)/((float)fft_size_extended/2.0); | ||||
| 		counter++; | ||||
| 	} | ||||
|  | ||||
| @@ -380,7 +380,8 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler(gr_vector_const_void_star | ||||
| 		d_gnss_synchro->Acq_doppler_hz=(double)fftFreqBins[tmp_index_freq]; | ||||
| 		//std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl; | ||||
| 	}else{ | ||||
| 		//std::cout<<"Error estimating fine frequency Doppler"<<std::endl; | ||||
| 		DLOG(INFO)<<"Abs(Grid Doppler - FFT Doppler)="<<abs(fftFreqBins[tmp_index_freq]-d_gnss_synchro->Acq_doppler_hz)<<std::endl; | ||||
| 		DLOG(INFO)<<std::endl<<"Error estimating fine frequency Doppler"<<std::endl; | ||||
| 		//debug log | ||||
| // | ||||
| //		std::cout<<"FFT maximum present at "<<fftFreqBins[tmp_index_freq]<<" [Hz]"<<std::endl; | ||||
|   | ||||
| @@ -35,6 +35,9 @@ | ||||
| #endif | ||||
|  | ||||
| #include <boost/filesystem.hpp> | ||||
| #include <boost/exception/diagnostic_information.hpp> | ||||
| #include <boost/exception_ptr.hpp> | ||||
|  | ||||
| #include <gflags/gflags.h> | ||||
| #include <glog/log_severity.h> | ||||
| #include <glog/logging.h> | ||||
| @@ -150,8 +153,16 @@ int main(int argc, char** argv) | ||||
|     gettimeofday(&tv, NULL); | ||||
|     long long int begin = tv.tv_sec * 1000000 + tv.tv_usec; | ||||
|  | ||||
|     control_thread->run(); | ||||
|  | ||||
|     try{ | ||||
|     	control_thread->run(); | ||||
|     }catch( boost::exception & e ) | ||||
|     { | ||||
|     	DLOG(FATAL) << "Boost exception: " << boost::diagnostic_information(e); | ||||
|     } | ||||
|     catch(std::exception const&  ex) | ||||
|     { | ||||
|     	DLOG(FATAL) <<"STD exception: "<<ex.what(); | ||||
|     } | ||||
|     // report the elapsed time | ||||
|     gettimeofday(&tv, NULL); | ||||
|     long long int end = tv.tv_sec * 1000000 + tv.tv_usec; | ||||
|   | ||||
| @@ -226,13 +226,6 @@ bool FrontEndCal::get_ephemeris() | ||||
|  | ||||
| arma::vec FrontEndCal::lla2ecef(arma::vec lla) | ||||
| { | ||||
| //	%  LLA2ECEF Convert geodetic coordinates to Earth-centered Earth-fixed | ||||
| //	%  (ECEF)  coordinates. | ||||
| //	%   P = LLA2ECEF( LLA ) converts an M-by-3 array of geodetic coordinates | ||||
| //	%   (latitude, longitude and altitude), LLA, to an M-by-3 array of ECEF | ||||
| //	%   coordinates, P.  LLA is in [degrees degrees meters].  P is in meters. | ||||
| //	%   The default ellipsoid planet is WGS84. | ||||
|  | ||||
|  | ||||
| 	// WGS84 flattening | ||||
| 	double f; | ||||
| @@ -258,36 +251,6 @@ arma::vec FrontEndCal::lla2ecef(arma::vec lla) | ||||
|  | ||||
| arma::vec FrontEndCal::geodetic2ecef(double phi, double lambda, double h, arma::vec ellipsoid) | ||||
| { | ||||
| //%GEODETIC2ECEF Convert geodetic to geocentric (ECEF) coordinates | ||||
| //% | ||||
| //%   [X, Y, Z] = GEODETIC2ECEF(PHI, LAMBDA, H, ELLIPSOID) converts geodetic | ||||
| //%   point locations specified by the coordinate arrays PHI (geodetic | ||||
| //%   latitude in radians), LAMBDA (longitude in radians), and H (ellipsoidal | ||||
| //%   height) to geocentric Cartesian coordinates X, Y, and Z.  The geodetic | ||||
| //%   coordinates refer to the reference ellipsoid specified by ELLIPSOID (a | ||||
| //%   row vector with the form [semimajor axis, eccentricity]).  H must use | ||||
| //%   the same units as the semimajor axis;  X, Y, and Z will be expressed in | ||||
| //%   these units also. | ||||
| //% | ||||
| //%   The geocentric Cartesian coordinate system is fixed with respect to the | ||||
| //%   Earth, with its origin at the center of the ellipsoid and its X-, Y-, | ||||
| //%   and Z-axes intersecting the surface at the following points: | ||||
| //% | ||||
| //%                PHI  LAMBDA | ||||
| //%      X-axis:    0     0      (Equator at the Prime Meridian) | ||||
| //%      Y-axis:    0   pi/2     (Equator at 90-degrees East) | ||||
| //%      Z-axis:  pi/2    0      (North Pole) | ||||
| //% | ||||
| //%   A common synonym is Earth-Centered, Earth-Fixed coordinates, or ECEF. | ||||
| //% | ||||
| //%   See also ECEF2GEODETIC, ECEF2LV, GEODETIC2GEOCENTRICLAT, LV2ECEF. | ||||
| //% Copyright 2004-2009 The MathWorks, Inc. | ||||
| //% $Revision: 1.1.6.4 $  $Date: 2009/04/15 23:34:46 $ | ||||
|  | ||||
| //% Reference | ||||
| //% --------- | ||||
| //% Paul R. Wolf and Bon A. Dewitt, "Elements of Photogrammetry with | ||||
| //% Applications in GIS," 3rd Ed., McGraw-Hill, 2000 (Appendix F-3). | ||||
|  | ||||
| 	double a; | ||||
| 	a  = ellipsoid(0); | ||||
| @@ -380,18 +343,8 @@ double FrontEndCal::estimate_doppler_from_eph(unsigned int PRN, double TOW, doub | ||||
|  | ||||
| void FrontEndCal::GPS_L1_front_end_model_E4000(double f_bb_true_Hz,double f_bb_meas_Hz,double fs_nominal_hz, double *estimated_fs_Hz, double *estimated_f_if_Hz, double *f_osc_err_ppm ) | ||||
| { | ||||
| //	%   Inputs: | ||||
| //	%       f_bb_true_Hz  - Ideal output frequency in baseband [Hz] | ||||
| //	%       f_in_bb_meas_Hz       - measured output frequency in baseband [Hz] | ||||
| //	% | ||||
| //	%   Outputs: | ||||
| //	%       estimated_fs_Hz  - Sampling frequency estimation based on the | ||||
| //	%       measurements and the front-end model | ||||
| //	%       estimated_f_if_bb_Hz    - Equivalent bb if frequency estimation based on the | ||||
| //	%       measurements and the front-end model | ||||
|  | ||||
| 	// Front-end TUNNER Elonics E4000 + RTL2832 sampler | ||||
| 	//For GPS L1 1575.42 MHz | ||||
|  | ||||
|  | ||||
| 	double f_osc_n=28.8e6; | ||||
| 	//PLL registers settings (according to E4000 datasheet) | ||||
|   | ||||
| @@ -5,16 +5,95 @@ class FrontEndCal | ||||
| { | ||||
| private: | ||||
| 	ConfigurationInterface *configuration_; | ||||
|  | ||||
| 	/*! | ||||
| 	 * \brief LLA2ECEF Convert geodetic coordinates to Earth-centered Earth-fixed | ||||
| 	 * (ECEF)  coordinates. P = LLA2ECEF( LLA ) converts an M-by-3 array of geodetic coordinates | ||||
| 	 * (latitude, longitude and altitude), LLA, to an M-by-3 array of ECEF | ||||
| 	 * coordinates, P.  LLA is in [degrees degrees meters].  P is in meters. | ||||
| 	 * The default ellipsoid planet is WGS84. Original copyright (c) by Kai Borre. | ||||
| 	 */ | ||||
| 	arma::vec lla2ecef(arma::vec lla); | ||||
| 	/*! | ||||
| 	 * GEODETIC2ECEF Convert geodetic to geocentric (ECEF) coordinates | ||||
| 	 * [X, Y, Z] = GEODETIC2ECEF(PHI, LAMBDA, H, ELLIPSOID) converts geodetic | ||||
| 	 * point locations specified by the coordinate arrays PHI (geodetic | ||||
| 	 * latitude in radians), LAMBDA (longitude in radians), and H (ellipsoidal | ||||
| 	 * height) to geocentric Cartesian coordinates X, Y, and Z.  The geodetic | ||||
| 	 * coordinates refer to the reference ellipsoid specified by ELLIPSOID (a | ||||
| 	 * row vector with the form [semimajor axis, eccentricity]).  H must use | ||||
| 	 * the same units as the semimajor axis;  X, Y, and Z will be expressed in | ||||
| 	 * these units also. | ||||
| 	 * | ||||
| 	 * The geocentric Cartesian coordinate system is fixed with respect to the | ||||
| 	 * Earth, with its origin at the center of the ellipsoid and its X-, Y-, | ||||
| 	 * and Z-axes intersecting the surface at the following points: | ||||
| 	 * PHI  LAMBDA | ||||
| 	 * X-axis:    0     0      (Equator at the Prime Meridian) | ||||
| 	 * Y-axis:    0   pi/2     (Equator at 90-degrees East | ||||
| 	 * Z-axis:  pi/2    0      (North Pole) | ||||
| 	 * | ||||
| 	 * A common synonym is Earth-Centered, Earth-Fixed coordinates, or ECEF. | ||||
| 	 * | ||||
| 	 * See also ECEF2GEODETIC, ECEF2LV, GEODETIC2GEOCENTRICLAT, LV2ECEF. | ||||
| 	 * | ||||
| 	 * Copyright 2004-2009 The MathWorks, Inc. | ||||
| 	 * $Revision: 1.1.6.4 $  $Date: 2009/04/15 23:34:46 $ | ||||
| 	 * Reference | ||||
| 	 * --------- | ||||
| 	 * Paul R. Wolf and Bon A. Dewitt, "Elements of Photogrammetry with | ||||
| 	 * Applications in GIS," 3rd Ed., McGraw-Hill, 2000 (Appendix F-3). | ||||
| 	 */ | ||||
| 	arma::vec geodetic2ecef(double phi, double lambda, double h, arma::vec ellipsoid); | ||||
| 	/*! | ||||
| 	 * \brief Reads the ephemeris data from an external XML file | ||||
| 	 * | ||||
| 	 */ | ||||
| 	bool read_assistance_from_XML(); | ||||
| 	/*! | ||||
| 	 * \brief Connects to Secure User Location Protocol (SUPL) server to obtain | ||||
| 	 * the current GPS ephemeris and GPS assistance data. | ||||
| 	 * | ||||
| 	 */ | ||||
| 	int Get_SUPL_Assist(); | ||||
| public: | ||||
|  | ||||
| 	bool read_assistance_from_XML(); | ||||
| 	int Get_SUPL_Assist(); | ||||
|  | ||||
| 	/*! | ||||
| 	 * \brief Sets the configuration data required by get_ephemeris function | ||||
| 	 * | ||||
| 	 */ | ||||
| 	void set_configuration(ConfigurationInterface *configuration); | ||||
| 	/*! | ||||
| 	 * \brief This function connects to a Secure User Location Protocol (SUPL) server to obtain | ||||
| 	 * the current GPS ephemeris and GPS assistance data. It requires the configuration parameters set by | ||||
| 	 * set_configuration function. | ||||
| 	 * | ||||
| 	 */ | ||||
| 	bool get_ephemeris(); | ||||
| 	/*! | ||||
| 	 * \brief This function estimates the GPS L1 satellite Doppler frequency [Hz] using the following data: | ||||
| 	 * 1- Orbital model from the ephemeris | ||||
| 	 * 2- Approximate GPS Time of Week (TOW) | ||||
| 	 * 3- Approximate receiver Latitude and Longitude (WGS-84) | ||||
| 	 * | ||||
| 	 */ | ||||
| 	double estimate_doppler_from_eph(unsigned int PRN, double TOW, double lat, double lon, double height); | ||||
| 	/*! | ||||
| 	 * \brief This function models the Elonics E4000 + RTL2832 front-end | ||||
| 	 * Inputs: | ||||
| 	 *  f_bb_true_Hz  - Ideal output frequency in baseband [Hz] | ||||
| 	 *  f_in_bb_meas_Hz       - measured output frequency in baseband [Hz] | ||||
| 	 * Outputs: | ||||
| 	 *  estimated_fs_Hz  - Sampling frequency estimation based on the | ||||
| 	 *  measurements and the front-end model | ||||
| 	 *  estimated_f_if_bb_Hz    - Equivalent bb if frequency estimation based on the | ||||
| 	 *  measurements and the front-end model | ||||
| 	 *  Front-end TUNNER Elonics E4000 + RTL2832 sampler For GPS L1 1575.42 MHz | ||||
| 	 * | ||||
| 	 */ | ||||
| 	void GPS_L1_front_end_model_E4000(double f_bb_true_Hz,double f_bb_meas_Hz,double fs_nominal_hz, double *estimated_fs_Hz, double *estimated_f_if_Hz, double *f_osc_err_ppm ); | ||||
|  | ||||
| 	FrontEndCal(); | ||||
| 	~FrontEndCal(); | ||||
| }; | ||||
|   | ||||
| @@ -265,7 +265,6 @@ int main(int argc, char** argv) | ||||
|     	std::cout<<"Failure connecting to SUPL server"<<std::endl; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // 3. Capture some front-end samples to hard disk | ||||
|  | ||||
|     if (front_end_capture(configuration)) | ||||
| @@ -357,7 +356,6 @@ int main(int argc, char** argv) | ||||
|             for (std::vector<Gnss_Synchro>::iterator it = gnss_sync_vector.begin() ; it != gnss_sync_vector.end(); ++it) | ||||
|               { | ||||
|             	doppler_measurement_hz+=(*it).Acq_doppler_hz; | ||||
|             	//std::cout << "Doppler (SV=" << (*it).PRN<<")="<<(*it).Acq_doppler_hz<<"[Hz]"<<std::endl; | ||||
|               } | ||||
|             doppler_measurement_hz=doppler_measurement_hz/gnss_sync_vector.size(); | ||||
|             doppler_measurements_map.insert(std::pair<int,double>(PRN,doppler_measurement_hz)); | ||||
| @@ -474,12 +472,30 @@ int main(int argc, char** argv) | ||||
|     mean_fs_Hz/=n_elements; | ||||
|     mean_osc_err_ppm/=n_elements; | ||||
|  | ||||
| 	std::cout <<std::setiosflags(std::ios::fixed)<<std::setprecision(2)<<"FE parameters estimation for Elonics E4000 Front-End:"<<std::endl; | ||||
| 	std::cout <<std::setiosflags(std::ios::fixed)<<std::setprecision(2)<<"Parameters estimation for Elonics E4000 Front-End:"<<std::endl; | ||||
|  | ||||
| 	std::cout<<"Sampling frequency ="<<mean_fs_Hz<<" [Hz]"<<std::endl; | ||||
| 	std::cout<<"IF bias present in baseband="<<mean_f_if_Hz<<" [Hz]"<<std::endl; | ||||
| 	std::cout<<"Reference oscillator error ="<<mean_osc_err_ppm<<" [ppm]"<<std::endl; | ||||
|  | ||||
|  | ||||
|     std::cout <<std::setiosflags(std::ios::fixed)<<std::setprecision(2)<< | ||||
| 			"Corrected Doppler vs. Predicted"<<std::endl; | ||||
|     std::cout << "SV ID  Corrected [Hz]   Predicted [Hz]" <<std::endl; | ||||
|  | ||||
|  | ||||
|     for (std::map<int,double>::iterator it = doppler_measurements_map.begin() ; it != doppler_measurements_map.end(); ++it) | ||||
|       { | ||||
|     	try{ | ||||
|     		double doppler_estimated_hz; | ||||
|     		doppler_estimated_hz=front_end_cal.estimate_doppler_from_eph(it->first,current_TOW,lat_deg,lon_deg,altitude_m); | ||||
|     		std::cout << "  "<<it->first<<"   "<<it->second -mean_f_if_Hz<<"   "<<doppler_estimated_hz<<std::endl; | ||||
|     	}catch(int ex) | ||||
|     	{ | ||||
|     		std::cout << "  "<<it->first<<"   "<<it->second-mean_f_if_Hz<<"  (Eph not found)"<<std::endl; | ||||
|     	} | ||||
|       } | ||||
|  | ||||
|     // 8. Generate GNSS-SDR config file. | ||||
|  | ||||
|     delete configuration; | ||||
| @@ -488,14 +504,4 @@ int main(int argc, char** argv) | ||||
|  | ||||
|     google::ShutDownCommandLineFlags(); | ||||
|     std::cout << "GNSS-SDR Front-end calibration program ended." << std::endl; | ||||
|  | ||||
| //    if (global_gps_acq_assist_map.size()>0) | ||||
| //    { | ||||
| //    	std::map<int,Gps_Acq_Assist> Acq_Assist_map; | ||||
| //    	Acq_Assist_map=global_gps_acq_assist_map.get_map_copy(); | ||||
| //    	current_TOW=Acq_Assist_map.begin()->second.d_TOW; | ||||
| //    	std::cout<<"Current TOW obtained from acquisition assistance = "<<current_TOW<<std::endl; | ||||
| //    }else{ | ||||
| //    	std::cout<<"Unable to get acquisition assistance information. TOW is unknown!"<<std::endl; | ||||
| //    } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas