mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	SUPL assistance support in progress:
- New SUPL parameters available in GNSS-SDR.conf - Ephemeris assistance for real-time operation is now functional - SUPL client now stores the received ephemeris in XML file. This file can be loaded on request to enable post-processing SUPL assistance and to enable SUPL assistance without internet connection. -> thowards a complete warm start GNSS-SDR. BUG FIXES: - GN3S driver firmware file copy operation in CmakeLists.txt had an error that mismatches the gn3s_firmware.ihx file location and prevents the correct firmware loading for GN3S SiGe USB dongles. git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@351 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
		| @@ -206,7 +206,7 @@ set(Boost_ADDITIONAL_VERSIONS | |||||||
| ) | ) | ||||||
| set(Boost_USE_MULTITHREAD ON) | set(Boost_USE_MULTITHREAD ON) | ||||||
| set(Boost_USE_STATIC_LIBS OFF) | set(Boost_USE_STATIC_LIBS OFF) | ||||||
| find_package(Boost COMPONENTS date_time system filesystem thread REQUIRED)  | find_package(Boost COMPONENTS date_time system filesystem thread serialization REQUIRED)  | ||||||
| if(NOT Boost_FOUND) | if(NOT Boost_FOUND) | ||||||
|      message(FATAL_ERROR "Fatal error: Boost (version >=1.42.0) required.") |      message(FATAL_ERROR "Fatal error: Boost (version >=1.42.0) required.") | ||||||
| endif(NOT Boost_FOUND) | endif(NOT Boost_FOUND) | ||||||
|   | |||||||
| @@ -12,6 +12,18 @@ GNSS-SDR.internal_fs_hz=4000000 | |||||||
| ;######### CONTROL_THREAD CONFIG ############ | ;######### CONTROL_THREAD CONFIG ############ | ||||||
| ControlThread.wait_for_flowgraph=false | ControlThread.wait_for_flowgraph=false | ||||||
|  |  | ||||||
|  | ;######### SUPL RRLP GPS assistance configuration ##### | ||||||
|  | GNSS-SDR.SUPL_gps_enabled=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.google.com | ||||||
|  | GNSS-SDR.SUPL_gps_acquisition_port=7275 | ||||||
|  | GNSS-SDR.SUPL_MCC=244 | ||||||
|  | GNSS-SDR.SUPL_MNS=5 | ||||||
|  | GNSS-SDR.SUPL_LAC=0x59e2 | ||||||
|  | GNSS-SDR.SUPL_CI=0x31b0 | ||||||
|  |  | ||||||
| ;######### SIGNAL_SOURCE CONFIG ############ | ;######### SIGNAL_SOURCE CONFIG ############ | ||||||
| ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) | ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) | ||||||
| SignalSource.implementation=File_Signal_Source | SignalSource.implementation=File_Signal_Source | ||||||
| @@ -292,7 +304,7 @@ Acquisition.sampled_ms=1 | |||||||
| ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] | ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] | ||||||
| Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| ;#threshold: Acquisition threshold | ;#threshold: Acquisition threshold | ||||||
| Acquisition0.threshold=70 | Acquisition0.threshold=50 | ||||||
| ;#doppler_max: Maximum expected Doppler shift [Hz] | ;#doppler_max: Maximum expected Doppler shift [Hz] | ||||||
| Acquisition0.doppler_max=10000 | Acquisition0.doppler_max=10000 | ||||||
| ;#doppler_max: Doppler step in the grid search [Hz] | ;#doppler_max: Doppler step in the grid search [Hz] | ||||||
| @@ -302,28 +314,28 @@ Acquisition0.doppler_step=250 | |||||||
|  |  | ||||||
| ;######### ACQUISITION CH 1 CONFIG ############ | ;######### ACQUISITION CH 1 CONFIG ############ | ||||||
| Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition1.threshold=70 | Acquisition1.threshold=50 | ||||||
| Acquisition1.doppler_max=10000 | Acquisition1.doppler_max=10000 | ||||||
| Acquisition1.doppler_step=250 | Acquisition1.doppler_step=250 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CH 2 CONFIG ############ | ;######### ACQUISITION CH 2 CONFIG ############ | ||||||
| Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition2.threshold=70 | Acquisition2.threshold=50 | ||||||
| Acquisition2.doppler_max=10000 | Acquisition2.doppler_max=10000 | ||||||
| Acquisition2.doppler_step=250 | Acquisition2.doppler_step=250 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CH 3 CONFIG ############ | ;######### ACQUISITION CH 3 CONFIG ############ | ||||||
| Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition3.threshold=70 | Acquisition3.threshold=50 | ||||||
| Acquisition3.doppler_max=10000 | Acquisition3.doppler_max=10000 | ||||||
| Acquisition3.doppler_step=250 | Acquisition3.doppler_step=250 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CH 4 CONFIG ############ | ;######### ACQUISITION CH 4 CONFIG ############ | ||||||
| Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition4.threshold=70 | Acquisition4.threshold=50 | ||||||
| Acquisition4.doppler_max=10000 | Acquisition4.doppler_max=10000 | ||||||
| Acquisition4.doppler_step=250 | Acquisition4.doppler_step=250 | ||||||
|  |  | ||||||
| @@ -337,21 +349,21 @@ Acquisition5.doppler_step=250 | |||||||
|  |  | ||||||
| ;######### ACQUISITION CH 6 CONFIG ############ | ;######### ACQUISITION CH 6 CONFIG ############ | ||||||
| Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition6.threshold=70 | Acquisition6.threshold=50 | ||||||
| Acquisition6.doppler_max=10000 | Acquisition6.doppler_max=10000 | ||||||
| Acquisition6.doppler_step=250 | Acquisition6.doppler_step=250 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CH 7 CONFIG ############ | ;######### ACQUISITION CH 7 CONFIG ############ | ||||||
| Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition7.threshold=70 | Acquisition7.threshold=50 | ||||||
| Acquisition7.doppler_max=10000 | Acquisition7.doppler_max=10000 | ||||||
| Acquisition7.doppler_step=250 | Acquisition7.doppler_step=250 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CH 8 CONFIG ############ | ;######### ACQUISITION CH 8 CONFIG ############ | ||||||
| Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition8.threshold=70 | Acquisition8.threshold=50 | ||||||
| Acquisition8.doppler_max=10000 | Acquisition8.doppler_max=10000 | ||||||
| Acquisition8.doppler_step=250 | Acquisition8.doppler_step=250 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  |  | ||||||
| ;######### GLOBAL OPTIONS ################## | ;######### GLOBAL OPTIONS ################## | ||||||
| ;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. | ;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. | ||||||
| GNSS-SDR.internal_fs_hz=2045950 | GNSS-SDR.internal_fs_hz=2727933.33 | ||||||
|  |  | ||||||
| ;######### CONTROL_THREAD CONFIG ############ | ;######### CONTROL_THREAD CONFIG ############ | ||||||
| ControlThread.wait_for_flowgraph=false | ControlThread.wait_for_flowgraph=false | ||||||
| @@ -138,11 +138,12 @@ InputFilter.grid_density=16 | |||||||
| ;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz | ;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz | ||||||
|  |  | ||||||
| ; 8183800/5 = 1636760 | ; 8183800/5 = 1636760 | ||||||
| ; 8183800/4 = 2045950 | ; 8183800/4 = 2727933.33 | ||||||
|  | ; 8183800/3 = 2727933.33333333 | ||||||
| InputFilter.sampling_frequency=8183800 | InputFilter.sampling_frequency=8183800 | ||||||
| InputFilter.IF=38400 | InputFilter.IF=38400 | ||||||
|  |  | ||||||
| InputFilter.decimation_factor=4 | InputFilter.decimation_factor=3 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -167,12 +168,12 @@ Resampler.item_type=gr_complex | |||||||
| Resampler.sample_freq_in=8183800 | Resampler.sample_freq_in=8183800 | ||||||
|  |  | ||||||
| ;#sample_freq_out: the desired sample frequency of the output signal | ;#sample_freq_out: the desired sample frequency of the output signal | ||||||
| Resampler.sample_freq_out=1636760 | Resampler.sample_freq_out=2727933.33 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### CHANNELS GLOBAL CONFIG ############ | ;######### CHANNELS GLOBAL CONFIG ############ | ||||||
| ;#count: Number of available satellite channels. | ;#count: Number of available satellite channels. | ||||||
| Channels.count=7 | Channels.count=1 | ||||||
| ;#in_acquisition: Number of channels simultaneously acquiring | ;#in_acquisition: Number of channels simultaneously acquiring | ||||||
| Channels.in_acquisition=1 | Channels.in_acquisition=1 | ||||||
|  |  | ||||||
| @@ -299,7 +300,7 @@ Acquisition.sampled_ms=1 | |||||||
| ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] | ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] | ||||||
| Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| ;#threshold: Acquisition threshold | ;#threshold: Acquisition threshold | ||||||
| Acquisition0.threshold=70 | Acquisition0.threshold=50 | ||||||
| ;#doppler_max: Maximum expected Doppler shift [Hz] | ;#doppler_max: Maximum expected Doppler shift [Hz] | ||||||
| Acquisition0.doppler_max=10000 | Acquisition0.doppler_max=10000 | ||||||
| ;#doppler_max: Doppler step in the grid search [Hz] | ;#doppler_max: Doppler step in the grid search [Hz] | ||||||
| @@ -309,21 +310,21 @@ Acquisition0.doppler_step=250 | |||||||
|  |  | ||||||
| ;######### ACQUISITION CH 1 CONFIG ############ | ;######### ACQUISITION CH 1 CONFIG ############ | ||||||
| Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition1.threshold=70 | Acquisition1.threshold=30 | ||||||
| Acquisition1.doppler_max=10000 | Acquisition1.doppler_max=10000 | ||||||
| Acquisition1.doppler_step=250 | Acquisition1.doppler_step=250 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CH 2 CONFIG ############ | ;######### ACQUISITION CH 2 CONFIG ############ | ||||||
| Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition2.threshold=70 | Acquisition2.threshold=30 | ||||||
| Acquisition2.doppler_max=10000 | Acquisition2.doppler_max=10000 | ||||||
| Acquisition2.doppler_step=250 | Acquisition2.doppler_step=250 | ||||||
|  |  | ||||||
|  |  | ||||||
| ;######### ACQUISITION CH 3 CONFIG ############ | ;######### ACQUISITION CH 3 CONFIG ############ | ||||||
| Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition3.threshold=70 | Acquisition3.threshold=30 | ||||||
| Acquisition3.doppler_max=10000 | Acquisition3.doppler_max=10000 | ||||||
| Acquisition3.doppler_step=250 | Acquisition3.doppler_step=250 | ||||||
|  |  | ||||||
| @@ -367,7 +368,7 @@ Acquisition8.doppler_step=250 | |||||||
| ;######### TRACKING GLOBAL CONFIG ############ | ;######### TRACKING GLOBAL CONFIG ############ | ||||||
|  |  | ||||||
| ;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] | ;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] | ||||||
| Tracking.implementation=GPS_L1_CA_DLL_PLL_Tracking | Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking | ||||||
| ;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. | ;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. | ||||||
| Tracking.item_type=gr_complex | Tracking.item_type=gr_complex | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,6 +12,18 @@ GNSS-SDR.internal_fs_hz=4000000 | |||||||
| ;######### CONTROL_THREAD CONFIG ############ | ;######### CONTROL_THREAD CONFIG ############ | ||||||
| ControlThread.wait_for_flowgraph=false | ControlThread.wait_for_flowgraph=false | ||||||
|  |  | ||||||
|  | ;######### SUPL RRLP GPS assistance configuration ##### | ||||||
|  | GNSS-SDR.SUPL_gps_enabled=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.google.com | ||||||
|  | GNSS-SDR.SUPL_gps_acquisition_port=7275 | ||||||
|  | GNSS-SDR.SUPL_MCC=244 | ||||||
|  | GNSS-SDR.SUPL_MNS=5 | ||||||
|  | GNSS-SDR.SUPL_LAC=0x59e2 | ||||||
|  | GNSS-SDR.SUPL_CI=0x31b0 | ||||||
|  |  | ||||||
| ;######### SIGNAL_SOURCE CONFIG ############ | ;######### SIGNAL_SOURCE CONFIG ############ | ||||||
| ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) | ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) | ||||||
| SignalSource.implementation=File_Signal_Source | SignalSource.implementation=File_Signal_Source | ||||||
|   | |||||||
| @@ -240,204 +240,191 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma | |||||||
|  |  | ||||||
| bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map, double GPS_current_time, bool flag_averaging) | bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map, double GPS_current_time, bool flag_averaging) | ||||||
| { | { | ||||||
| 	   std::map<int,Gnss_Synchro>::iterator gnss_pseudoranges_iter; | 	std::map<int,Gnss_Synchro>::iterator gnss_pseudoranges_iter; | ||||||
|  | 	std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter; | ||||||
|  | 	int valid_pseudoranges=gnss_pseudoranges_map.size(); | ||||||
|  |  | ||||||
| 	   std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter; | 	arma::mat W = arma::eye(valid_pseudoranges,valid_pseudoranges); //channels weights matrix | ||||||
|  | 	arma::vec obs = arma::zeros(valid_pseudoranges);         // pseudoranges observation vector | ||||||
|  | 	arma::mat satpos = arma::zeros(3,valid_pseudoranges);    //satellite positions matrix | ||||||
|  |  | ||||||
| 	   int valid_pseudoranges=gnss_pseudoranges_map.size(); | 	int GPS_week = 0; | ||||||
|  | 	double GPS_corrected_time = 0; | ||||||
|  | 	double utc = 0; | ||||||
|  |  | ||||||
| 	    arma::mat W = arma::eye(valid_pseudoranges,valid_pseudoranges); //channels weights matrix | 	d_flag_averaging = flag_averaging; | ||||||
| 	    arma::vec obs = arma::zeros(valid_pseudoranges);         // pseudoranges observation vector |  | ||||||
| 	    arma::mat satpos = arma::zeros(3,valid_pseudoranges);    //satellite positions matrix |  | ||||||
|  |  | ||||||
| 	    int GPS_week = 0; | 	// ******************************************************************************** | ||||||
| 	    double GPS_corrected_time = 0; | 	// ****** PREPARE THE LEAST SQUARES DATA (SV POSITIONS MATRIX AND OBS VECTORS) **** | ||||||
| 	    double utc = 0; | 	// ******************************************************************************** | ||||||
|  | 	int valid_obs = 0; //valid observations counter | ||||||
|  | 	int obs_counter=0; | ||||||
|  | 	for(gnss_pseudoranges_iter = gnss_pseudoranges_map.begin(); | ||||||
|  | 			gnss_pseudoranges_iter != gnss_pseudoranges_map.end(); | ||||||
|  | 			gnss_pseudoranges_iter++) | ||||||
|  | 	{ | ||||||
|  | 		// 1- find the ephemeris for the current SV observation. The SV PRN ID is the map key | ||||||
|  | 		gps_ephemeris_iter = gps_ephemeris_map.find(gnss_pseudoranges_iter->first); | ||||||
|  | 		if (gps_ephemeris_iter != gps_ephemeris_map.end()) | ||||||
|  | 		{ | ||||||
|  |  | ||||||
| 	    d_flag_averaging = flag_averaging; | 			/*! | ||||||
|  | 			 * \todo Place here the satellite CN0 (power level, or weight factor) | ||||||
|  | 			 */ | ||||||
|  | 			W(obs_counter,obs_counter) = 1; | ||||||
|  | 			// 2- compute the clock error including relativistic effects for this SV | ||||||
|  | 			GPS_corrected_time = gps_ephemeris_iter->second.sv_clock_correction(GPS_current_time); | ||||||
|  | 			GPS_week = gps_ephemeris_iter->second.i_GPS_week; | ||||||
|  | 			// 3- compute the UTC time for this SV | ||||||
|  | 			//TODO: check if the utc time model is valid (or it is empty (not received yet!) and no corrections are available) | ||||||
|  | 			utc = gps_utc_model.utc_time(GPS_corrected_time,GPS_week); | ||||||
|  | 			// 4- compute the current ECEF position for this SV | ||||||
|  | 			gps_ephemeris_iter->second.satellitePosition(GPS_corrected_time); | ||||||
|  | 			satpos(0,obs_counter) = gps_ephemeris_iter->second.d_satpos_X; | ||||||
|  | 			satpos(1,obs_counter) = gps_ephemeris_iter->second.d_satpos_Y; | ||||||
|  | 			satpos(2,obs_counter) = gps_ephemeris_iter->second.d_satpos_Z; | ||||||
|  | 			// 5- fill the observations vector with the corrected pseudorranges | ||||||
|  | 			obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + gps_ephemeris_iter->second.d_satClkCorr*GPS_C_m_s; | ||||||
|  | 			d_visible_satellites_IDs[valid_obs] = gps_ephemeris_iter->second.i_satellite_PRN; | ||||||
|  | 			d_visible_satellites_CN0_dB[valid_obs]  =gnss_pseudoranges_iter->second.CN0_dB_hz; | ||||||
|  | 			valid_obs++; | ||||||
|  | 			// SV ECEF DEBUG OUTPUT | ||||||
|  | 			DLOG(INFO) << "(new)ECEF satellite SV ID=" << gps_ephemeris_iter->second.i_satellite_PRN | ||||||
|  | 					<< " X=" << gps_ephemeris_iter->second.d_satpos_X | ||||||
|  | 					<< " [m] Y=" << gps_ephemeris_iter->second.d_satpos_Y | ||||||
|  | 					<< " [m] Z=" << gps_ephemeris_iter->second.d_satpos_Z | ||||||
|  | 					<< " [m] PR_obs="<<obs(obs_counter)<<"[m]"<< std::endl; | ||||||
|  | 		}else{ // the ephemeris are not available for this SV | ||||||
|  | 			// no valid pseudorange for the current SV | ||||||
|  | 			W(obs_counter,obs_counter) = 0; // SV de-activated | ||||||
|  | 			obs(obs_counter) = 1; // to avoid algorithm problems (divide by zero) | ||||||
|  | 			DLOG(INFO)<<"No ephemeris data for SV "<<gnss_pseudoranges_iter->first<<std::endl; | ||||||
|  | 		} | ||||||
|  | 		obs_counter++; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	    // ******************************************************************************** | 	// ******************************************************************************** | ||||||
| 	    // ****** PREPARE THE LEAST SQUARES DATA (SV POSITIONS MATRIX AND OBS VECTORS) **** | 	// ****** SOLVE LEAST SQUARES****************************************************** | ||||||
| 	    // ******************************************************************************** | 	// ******************************************************************************** | ||||||
| 	    int valid_obs = 0; //valid observations counter | 	d_valid_observations = valid_obs; | ||||||
| 	    int obs_counter=0; | 	DLOG(INFO) << "(new)PVT: valid observations=" << valid_obs << std::endl; | ||||||
| 	    for(gnss_pseudoranges_iter = gnss_pseudoranges_map.begin(); |  | ||||||
| 	            gnss_pseudoranges_iter != gnss_pseudoranges_map.end(); |  | ||||||
| 	            gnss_pseudoranges_iter++) |  | ||||||
|         { |  | ||||||
|             // 1- find the ephemeris for the current SV observation. The SV PRN ID is the map key |  | ||||||
|             gps_ephemeris_iter = gps_ephemeris_map.find(gnss_pseudoranges_iter->first); |  | ||||||
|             if (gps_ephemeris_iter != gps_ephemeris_map.end()) |  | ||||||
|             { |  | ||||||
|             	// Ephemeris available in the ephemeris map |  | ||||||
|                 /*! |  | ||||||
|                  * \todo Place here the satellite CN0 (power level, or weight factor) |  | ||||||
|                  */ |  | ||||||
|                 W(obs_counter,obs_counter) = 1; |  | ||||||
|  |  | ||||||
|                 // 2- compute the clock error including relativistic effects for this SV | 	if (valid_obs >= 4) | ||||||
|                 GPS_corrected_time = gps_ephemeris_iter->second.sv_clock_correction(GPS_current_time); | 	{ | ||||||
|                 //DLOG(INFO)<<"pseudorranges SV "<<gps_ephemeris_iter->second.i_satellite_PRN | 		arma::vec mypos; | ||||||
|                 //		<< " tx_time-d_TOW="<<GPS_corrected_time-gnss_pseudoranges_iter->second.d_TOW<<std::endl; | 		DLOG(INFO)<<"satpos="<<satpos<<std::endl; | ||||||
|                 //DLOG(INFO)<<"pseudorranges SV "<<gps_ephemeris_iter->second.i_satellite_PRN | 		DLOG(INFO)<<"obs="<<obs<<std::endl; | ||||||
|                 //		<< " d_TOW_current_symbol="<<gnss_pseudoranges_iter->second.d_TOW_at_current_symbol<<std::endl; | 		DLOG(INFO)<<"W="<<W<<std::endl; | ||||||
|  | 		mypos=leastSquarePos(satpos,obs,W); | ||||||
|  | 		DLOG(INFO) << "(new)Position at TOW=" << GPS_current_time << " in ECEF (X,Y,Z) = " << mypos << std::endl; | ||||||
|  | 		gps_l1_ca_ls_pvt::cart2geo(mypos(0), mypos(1), mypos(2), 4); | ||||||
|  |  | ||||||
|                 GPS_week = gps_ephemeris_iter->second.i_GPS_week; | 		// Compute UTC time and print PVT solution | ||||||
|                 // 3- compute the UTC time for this SV | 		double secondsperweek = 604800.0; // number of seconds in one week (7*24*60*60) | ||||||
|                 //TODO: check if the utc time model is valid (or it is empty (not received yet!) and no corrections are available) | 		boost::posix_time::time_duration t = boost::posix_time::seconds(utc + secondsperweek*(double)GPS_week); | ||||||
|                 utc = gps_utc_model.utc_time(GPS_corrected_time,GPS_week); | 		// 22 August 1999 last GPS time roll over | ||||||
|                 //DLOG(INFO)<<"pseudorranges SV "<<gps_ephemeris_iter->second.i_satellite_PRN | 		boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); | ||||||
|                 //		<< " symbol_shift_from_preamble="<<gnss_pseudoranges_iter->second.Pseudorange_symbol_shift<<std::endl; | 		d_position_UTC_time = p_time; | ||||||
|  | 		GPS_current_time = GPS_corrected_time; | ||||||
|  |  | ||||||
|                 // 4- compute the current ECEF position for this SV | 		DLOG(INFO) << "(new)Position at " << boost::posix_time::to_simple_string(p_time) | ||||||
|                 gps_ephemeris_iter->second.satellitePosition(GPS_corrected_time); | 		<< " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d | ||||||
|                 satpos(0,obs_counter) = gps_ephemeris_iter->second.d_satpos_X; | 		<< " [deg], Height= " << d_height_m << " [m]" << std::endl; | ||||||
|                 satpos(1,obs_counter) = gps_ephemeris_iter->second.d_satpos_Y; |  | ||||||
|                 satpos(2,obs_counter) = gps_ephemeris_iter->second.d_satpos_Z; |  | ||||||
|                 // 5- fill the observations vector with the corrected pseudorranges |  | ||||||
|                 obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + gps_ephemeris_iter->second.d_satClkCorr*GPS_C_m_s; |  | ||||||
|                 d_visible_satellites_IDs[valid_obs] = gps_ephemeris_iter->second.i_satellite_PRN; |  | ||||||
|                 d_visible_satellites_CN0_dB[valid_obs]  =gnss_pseudoranges_iter->second.CN0_dB_hz; |  | ||||||
|                 valid_obs++; |  | ||||||
|                 // SV ECEF DEBUG OUTPUT |  | ||||||
|                 DLOG(INFO) << "(new)ECEF satellite SV ID=" << gps_ephemeris_iter->second.i_satellite_PRN |  | ||||||
|                         << " X=" << gps_ephemeris_iter->second.d_satpos_X |  | ||||||
|                         << " [m] Y=" << gps_ephemeris_iter->second.d_satpos_Y |  | ||||||
|                         << " [m] Z=" << gps_ephemeris_iter->second.d_satpos_Z |  | ||||||
|                         << " [m] PR_obs="<<obs(obs_counter)<<"[m]"<< std::endl; |  | ||||||
|  |  | ||||||
|             }else{ // the ephemeris are not available for this SV | 		// ######## LOG FILE ######### | ||||||
|                 // no valid pseudorange for the current SV | 		if(d_flag_dump_enabled == true) | ||||||
|                 W(obs_counter,obs_counter) = 0; // SV de-activated | 		{ | ||||||
|                 obs(obs_counter) = 1; // to avoid algorithm problems (divide by zero) | 			// MULTIPLEXED FILE RECORDING - Record results to file | ||||||
|                 DLOG(INFO)<<"No ephemeris data for SV "<<gnss_pseudoranges_iter->first<<std::endl; | 			try | ||||||
|             } | 			{ | ||||||
|             obs_counter++; | 				double tmp_double; | ||||||
|  | 				//  PVT GPS time | ||||||
|  | 				tmp_double = GPS_current_time; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// ECEF User Position East [m] | ||||||
|  | 				tmp_double = mypos(0); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// ECEF User Position North [m] | ||||||
|  | 				tmp_double = mypos(1); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// ECEF User Position Up [m] | ||||||
|  | 				tmp_double = mypos(2); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// User clock offset [s] | ||||||
|  | 				tmp_double = mypos(3); | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// GEO user position Latitude [deg] | ||||||
|  | 				tmp_double = d_latitude_d; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// GEO user position Longitude [deg] | ||||||
|  | 				tmp_double = d_longitude_d; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 				// GEO user position Height [m] | ||||||
|  | 				tmp_double = d_height_m; | ||||||
|  | 				d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  | 			} | ||||||
|  | 			catch (std::ifstream::failure e) | ||||||
|  | 			{ | ||||||
|  | 				std::cout << "Exception writing PVT LS dump file "<< e.what() << std::endl; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|         } | 		// MOVING AVERAGE PVT | ||||||
|  | 		if (flag_averaging == true) | ||||||
|  | 		{ | ||||||
|  | 			if (d_hist_longitude_d.size() == (unsigned int)d_averaging_depth) | ||||||
|  | 			{ | ||||||
|  | 				// Pop oldest value | ||||||
|  | 				d_hist_longitude_d.pop_back(); | ||||||
|  | 				d_hist_latitude_d.pop_back(); | ||||||
|  | 				d_hist_height_m.pop_back(); | ||||||
|  | 				// Push new values | ||||||
|  | 				d_hist_longitude_d.push_front(d_longitude_d); | ||||||
|  | 				d_hist_latitude_d.push_front(d_latitude_d); | ||||||
|  | 				d_hist_height_m.push_front(d_height_m); | ||||||
|  |  | ||||||
| 	    // ******************************************************************************** | 				d_avg_latitude_d = 0; | ||||||
| 	    // ****** SOLVE LEAST SQUARES****************************************************** | 				d_avg_longitude_d = 0; | ||||||
| 	    // ******************************************************************************** | 				d_avg_height_m = 0; | ||||||
| 	    d_valid_observations = valid_obs; | 				for (unsigned int i=0; i<d_hist_longitude_d.size(); i++) | ||||||
| 	       DLOG(INFO) << "(new)PVT: valid observations=" << valid_obs << std::endl; | 				{ | ||||||
|  | 					d_avg_latitude_d = d_avg_latitude_d + d_hist_latitude_d.at(i); | ||||||
|  | 					d_avg_longitude_d = d_avg_longitude_d + d_hist_longitude_d.at(i); | ||||||
|  | 					d_avg_height_m  = d_avg_height_m + d_hist_height_m.at(i); | ||||||
|  | 				} | ||||||
|  | 				d_avg_latitude_d = d_avg_latitude_d / (double)d_averaging_depth; | ||||||
|  | 				d_avg_longitude_d = d_avg_longitude_d / (double)d_averaging_depth; | ||||||
|  | 				d_avg_height_m = d_avg_height_m / (double)d_averaging_depth; | ||||||
|  | 				b_valid_position = true; | ||||||
|  | 				return true; //indicates that the returned position is valid | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				//int current_depth=d_hist_longitude_d.size(); | ||||||
|  | 				// Push new values | ||||||
|  | 				d_hist_longitude_d.push_front(d_longitude_d); | ||||||
|  | 				d_hist_latitude_d.push_front(d_latitude_d); | ||||||
|  | 				d_hist_height_m.push_front(d_height_m); | ||||||
|  |  | ||||||
| 	       if (valid_obs >= 4) | 				d_avg_latitude_d = d_latitude_d; | ||||||
| 	           { | 				d_avg_longitude_d = d_longitude_d; | ||||||
| 	               arma::vec mypos; | 				d_avg_height_m = d_height_m; | ||||||
| 	               DLOG(INFO)<<"satpos="<<satpos<<std::endl; | 				b_valid_position = false; | ||||||
| 	               DLOG(INFO)<<"obs="<<obs<<std::endl; | 				return false; //indicates that the returned position is not valid yet | ||||||
| 	               DLOG(INFO)<<"W="<<W<<std::endl; | 			} | ||||||
| 	               mypos=leastSquarePos(satpos,obs,W); | 		} | ||||||
| 	               DLOG(INFO) << "(new)Position at TOW=" << GPS_current_time << " in ECEF (X,Y,Z) = " << mypos << std::endl; | 		else | ||||||
| 	               gps_l1_ca_ls_pvt::cart2geo(mypos(0), mypos(1), mypos(2), 4); | 		{ | ||||||
|  | 			b_valid_position = true; | ||||||
| 	               // Compute UTC time and print PVT solution | 			return true; //indicates that the returned position is valid | ||||||
| 	               double secondsperweek = 604800.0; // number of seconds in one week (7*24*60*60) | 		} | ||||||
| 	               boost::posix_time::time_duration t = boost::posix_time::seconds(utc + secondsperweek*(double)GPS_week); | 	} | ||||||
| 	               // 22 August 1999 last GPS time roll over | 	else | ||||||
| 	               boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); | 	{ | ||||||
| 	               d_position_UTC_time = p_time; | 		b_valid_position = false; | ||||||
| 	               GPS_current_time = GPS_corrected_time; | 		return false; | ||||||
|  | 	} | ||||||
| 	               DLOG(INFO) << "(new)Position at " << boost::posix_time::to_simple_string(p_time) |  | ||||||
| 	               << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d |  | ||||||
| 	               << " [deg], Height= " << d_height_m << " [m]" << std::endl; |  | ||||||
|  |  | ||||||
| 	               // ######## LOG FILE ######### |  | ||||||
| 	               if(d_flag_dump_enabled == true) |  | ||||||
| 	                   { |  | ||||||
| 	                       // MULTIPLEXED FILE RECORDING - Record results to file |  | ||||||
| 	                       try |  | ||||||
| 	                       { |  | ||||||
| 	                               double tmp_double; |  | ||||||
| 	                               //  PVT GPS time |  | ||||||
| 	                               tmp_double = GPS_current_time; |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                               // ECEF User Position East [m] |  | ||||||
| 	                               tmp_double = mypos(0); |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                               // ECEF User Position North [m] |  | ||||||
| 	                               tmp_double = mypos(1); |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                               // ECEF User Position Up [m] |  | ||||||
| 	                               tmp_double = mypos(2); |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                               // User clock offset [s] |  | ||||||
| 	                               tmp_double = mypos(3); |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                               // GEO user position Latitude [deg] |  | ||||||
| 	                               tmp_double = d_latitude_d; |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                               // GEO user position Longitude [deg] |  | ||||||
| 	                               tmp_double = d_longitude_d; |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                               // GEO user position Height [m] |  | ||||||
| 	                               tmp_double = d_height_m; |  | ||||||
| 	                               d_dump_file.write((char*)&tmp_double, sizeof(double)); |  | ||||||
| 	                       } |  | ||||||
| 	                       catch (std::ifstream::failure e) |  | ||||||
| 	                       { |  | ||||||
| 	                               std::cout << "Exception writing PVT LS dump file "<< e.what() << std::endl; |  | ||||||
| 	                       } |  | ||||||
| 	                   } |  | ||||||
|  |  | ||||||
| 	               // MOVING AVERAGE PVT |  | ||||||
| 	               if (flag_averaging == true) |  | ||||||
| 	                   { |  | ||||||
| 	                       if (d_hist_longitude_d.size() == (unsigned int)d_averaging_depth) |  | ||||||
| 	                           { |  | ||||||
| 	                               // Pop oldest value |  | ||||||
| 	                               d_hist_longitude_d.pop_back(); |  | ||||||
| 	                               d_hist_latitude_d.pop_back(); |  | ||||||
| 	                               d_hist_height_m.pop_back(); |  | ||||||
| 	                               // Push new values |  | ||||||
| 	                               d_hist_longitude_d.push_front(d_longitude_d); |  | ||||||
| 	                               d_hist_latitude_d.push_front(d_latitude_d); |  | ||||||
| 	                               d_hist_height_m.push_front(d_height_m); |  | ||||||
|  |  | ||||||
| 	                               d_avg_latitude_d = 0; |  | ||||||
| 	                               d_avg_longitude_d = 0; |  | ||||||
| 	                               d_avg_height_m = 0; |  | ||||||
| 	                               for (unsigned int i=0; i<d_hist_longitude_d.size(); i++) |  | ||||||
| 	                                   { |  | ||||||
| 	                                       d_avg_latitude_d = d_avg_latitude_d + d_hist_latitude_d.at(i); |  | ||||||
| 	                                       d_avg_longitude_d = d_avg_longitude_d + d_hist_longitude_d.at(i); |  | ||||||
| 	                                       d_avg_height_m  = d_avg_height_m + d_hist_height_m.at(i); |  | ||||||
| 	                                   } |  | ||||||
| 	                               d_avg_latitude_d = d_avg_latitude_d / (double)d_averaging_depth; |  | ||||||
| 	                               d_avg_longitude_d = d_avg_longitude_d / (double)d_averaging_depth; |  | ||||||
| 	                               d_avg_height_m = d_avg_height_m / (double)d_averaging_depth; |  | ||||||
| 	                               b_valid_position = true; |  | ||||||
| 	                               return true; //indicates that the returned position is valid |  | ||||||
| 	                           } |  | ||||||
| 	                       else |  | ||||||
| 	                           { |  | ||||||
| 	                               //int current_depth=d_hist_longitude_d.size(); |  | ||||||
| 	                               // Push new values |  | ||||||
| 	                               d_hist_longitude_d.push_front(d_longitude_d); |  | ||||||
| 	                               d_hist_latitude_d.push_front(d_latitude_d); |  | ||||||
| 	                               d_hist_height_m.push_front(d_height_m); |  | ||||||
|  |  | ||||||
| 	                               d_avg_latitude_d = d_latitude_d; |  | ||||||
| 	                               d_avg_longitude_d = d_longitude_d; |  | ||||||
| 	                               d_avg_height_m = d_height_m; |  | ||||||
| 	                               b_valid_position = false; |  | ||||||
| 	                               return false; //indicates that the returned position is not valid yet |  | ||||||
| 	                           } |  | ||||||
| 	                   } |  | ||||||
| 	               else |  | ||||||
| 	                   { |  | ||||||
| 	                       b_valid_position = true; |  | ||||||
| 	                       return true; //indicates that the returned position is valid |  | ||||||
| 	                   } |  | ||||||
| 	           } |  | ||||||
| 	       else |  | ||||||
| 	           { |  | ||||||
| 	               b_valid_position = false; |  | ||||||
| 	               return false; |  | ||||||
| 	           } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -180,5 +180,6 @@ void FreqXlatingFirFilter::init() | |||||||
|     for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++) |     for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++) | ||||||
|         { |         { | ||||||
|             taps_.push_back(float(*it)); |             taps_.push_back(float(*it)); | ||||||
|  |             std::cout<<"TAP="<<float(*it)<<std::endl; | ||||||
|         } |         } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ if($ENV{GN3S_DRIVER}) | |||||||
|      #  Copy GN3S firmware binary file to install folder |      #  Copy GN3S firmware binary file to install folder | ||||||
|      message(STATUS "Copying the GN3S firmware binary file to install folder")     |      message(STATUS "Copying the GN3S firmware binary file to install folder")     | ||||||
|      file(COPY ${CMAKE_SOURCE_DIR}/firmware/GN3S_v2/bin/gn3s_firmware.ihx  |      file(COPY ${CMAKE_SOURCE_DIR}/firmware/GN3S_v2/bin/gn3s_firmware.ihx  | ||||||
|           DESTINATION ${CMAKE_SOURCE_DIR}/install/gn3s_firmware.ihx  |           DESTINATION ${CMAKE_SOURCE_DIR}/install/ | ||||||
|      )      |      )      | ||||||
| endif($ENV{GN3S_DRIVER}) | endif($ENV{GN3S_DRIVER}) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -244,6 +244,14 @@ void gnss_sdr_supl_client::read_supl_data() | |||||||
| 				gps_ephemeris_map.insert(std::pair<int,Gps_Ephemeris>(e->prn, gps_eph)); | 				gps_ephemeris_map.insert(std::pair<int,Gps_Ephemeris>(e->prn, gps_eph)); | ||||||
| 				gps_eph_iterator=this->gps_ephemeris_map.find(e->prn); | 				gps_eph_iterator=this->gps_ephemeris_map.find(e->prn); | ||||||
| 			} | 			} | ||||||
|  | 			if (gps_time.valid) | ||||||
|  | 			{ | ||||||
|  | 				gps_eph_iterator->second.i_GPS_week=assist.time.gps_week; | ||||||
|  | 				gps_eph_iterator->second.d_TOW=assist.time.gps_tow; | ||||||
|  | 			}else{ | ||||||
|  | 				gps_eph_iterator->second.i_GPS_week=0; | ||||||
|  | 				gps_eph_iterator->second.d_TOW=0; | ||||||
|  | 			} | ||||||
| 			gps_eph_iterator->second.i_satellite_PRN=e->prn; | 			gps_eph_iterator->second.i_satellite_PRN=e->prn; | ||||||
| 			// SV navigation model | 			// SV navigation model | ||||||
| 			gps_eph_iterator->second.i_code_on_L2=e->bits; | 			gps_eph_iterator->second.i_code_on_L2=e->bits; | ||||||
| @@ -307,3 +315,36 @@ void gnss_sdr_supl_client::read_supl_data() | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool gnss_sdr_supl_client::load_ephemeris_xml(const std::string file_name) | ||||||
|  |  | ||||||
|  | { | ||||||
|  | 	try { | ||||||
|  | 		std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in); | ||||||
|  | 		boost::archive::xml_iarchive xml(ifs); | ||||||
|  | 		gps_ephemeris_map.clear(); | ||||||
|  | 		xml >> boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", gps_ephemeris_map); | ||||||
|  | 		ifs.close(); | ||||||
|  | 	}catch (std::exception& e) | ||||||
|  | 		  { | ||||||
|  | 		LOG_AT_LEVEL(ERROR)<< e.what() << "File: "<< file_name<<std::endl; | ||||||
|  | 		return false; | ||||||
|  | 		  } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool gnss_sdr_supl_client::save_ephemeris_xml(const std::string file_name) | ||||||
|  |  | ||||||
|  | { | ||||||
|  | 	try { | ||||||
|  | 		std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); | ||||||
|  | 	    boost::archive::xml_oarchive xml(ofs); | ||||||
|  | 	    xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", gps_ephemeris_map); | ||||||
|  | 	    ofs.close(); | ||||||
|  | 	}catch (std::exception& e) | ||||||
|  | 		  { | ||||||
|  | 		LOG_AT_LEVEL(ERROR)<< e.what() << std::endl; | ||||||
|  | 		return false; | ||||||
|  | 		  } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -35,6 +35,12 @@ | |||||||
| #define GNSS_SDR_SUPL_CLIENT_H_ | #define GNSS_SDR_SUPL_CLIENT_H_ | ||||||
|  |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | #include <fstream> | ||||||
|  | #include <boost/archive/xml_oarchive.hpp> | ||||||
|  | #include <boost/archive/xml_iarchive.hpp> | ||||||
|  | #include <boost/serialization/map.hpp> | ||||||
|  | #include <glog/log_severity.h> | ||||||
|  | #include <glog/logging.h> | ||||||
|  |  | ||||||
| extern "C" { | extern "C" { | ||||||
| #include "supl.h" | #include "supl.h" | ||||||
| @@ -101,6 +107,17 @@ public: | |||||||
| 	 * | 	 * | ||||||
| 	 */ | 	 */ | ||||||
| 	void read_supl_data(); | 	void read_supl_data(); | ||||||
|  |  | ||||||
|  | 	/*! | ||||||
|  | 	 * \brief Read ephemeris map from XML file | ||||||
|  | 	 */ | ||||||
|  | 	bool load_ephemeris_xml(const std::string file_name); | ||||||
|  |  | ||||||
|  | 	/*! | ||||||
|  | 	 * \brief Save ephemeris map to XML file. | ||||||
|  | 	 */ | ||||||
|  | 	bool save_ephemeris_xml(const std::string file_name); | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Prints SUPL data to std::cout. Use it for debug purposes only. | 	 * Prints SUPL data to std::cout. Use it for debug purposes only. | ||||||
| 	 */ | 	 */ | ||||||
|   | |||||||
| @@ -421,7 +421,7 @@ static int pdu_make_ulp_pos_init(supl_ctx_t *ctx, supl_ulp_t *pdu) { | |||||||
|   case 1: // request Navigation Model (Ephemeris) |   case 1: // request Navigation Model (Ephemeris) | ||||||
| 	  req_adata->acquisitionAssistanceRequested = 0; // 1 | 	  req_adata->acquisitionAssistanceRequested = 0; // 1 | ||||||
| 	  req_adata->navigationModelRequested = 1; // 1 | 	  req_adata->navigationModelRequested = 1; // 1 | ||||||
| 	  req_adata->referenceTimeRequested = 0; | 	  req_adata->referenceTimeRequested = 1; | ||||||
| 	  req_adata->utcModelRequested = 0; //1 | 	  req_adata->utcModelRequested = 0; //1 | ||||||
| 	  req_adata->ionosphericModelRequested = 0; // 1 | 	  req_adata->ionosphericModelRequested = 0; // 1 | ||||||
| 	  req_adata->referenceLocationRequested = 0; | 	  req_adata->referenceLocationRequested = 0; | ||||||
|   | |||||||
| @@ -59,5 +59,11 @@ include_directories( | |||||||
| ) | ) | ||||||
| link_directories(${Boost_LIBRARY_DIR}) | link_directories(${Boost_LIBRARY_DIR}) | ||||||
|  |  | ||||||
|  | #Enable GN3S module if the driver is present | ||||||
|  | if( $ENV{GN3S_DRIVER} ) | ||||||
|  |     message( "Precompiler GN3S_DRIVER enabled" ) | ||||||
|  | 	add_definitions(-DGN3S_DRIVER) | ||||||
|  | endif($ENV{GN3S_DRIVER} ) | ||||||
|  |  | ||||||
| add_library(gnss_rx ${GNSS_RECEIVER_SOURCES}) | add_library(gnss_rx ${GNSS_RECEIVER_SOURCES}) | ||||||
| target_link_libraries(gnss_rx ${Boost_LIBRARIES} ${ARMADILLO_LIBRARIES} ${GNURADIO_CORE_LIBRARIES} gnss_system_parameters gnss_sp_libs signal_source_adapters datatype_adapters input_filter_adapters conditioner_adapters resampler_adapters acq_adapters tracking_lib tracking_adapters channel_adapters telemetry_decoder_adapters obs_adapters pvt_adapters pvt_lib out_adapters rx_core_lib) | target_link_libraries(gnss_rx ${Boost_LIBRARIES} ${ARMADILLO_LIBRARIES} ${GNURADIO_CORE_LIBRARIES} gnss_system_parameters gnss_sp_libs signal_source_adapters datatype_adapters input_filter_adapters conditioner_adapters resampler_adapters acq_adapters tracking_lib tracking_adapters channel_adapters telemetry_decoder_adapters obs_adapters pvt_adapters pvt_lib out_adapters rx_core_lib) | ||||||
| @@ -163,6 +163,27 @@ void ControlThread::set_control_queue(gr_msg_queue_sptr control_queue) | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool ControlThread::read_assistance_from_XML() | ||||||
|  | { | ||||||
|  | 	std::string eph_xml_filename="gps_ephemeris.xml"; | ||||||
|  | 	std::cout<< "SUPL: Try read GPS ephemeris from XML file "<<eph_xml_filename<<std::endl; | ||||||
|  | 	if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename)==true) | ||||||
|  | 	{ | ||||||
|  | 		std::map<int,Gps_Ephemeris>::iterator gps_eph_iter; | ||||||
|  | 		for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin(); | ||||||
|  | 				gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end(); | ||||||
|  | 				gps_eph_iter++) | ||||||
|  | 		{ | ||||||
|  | 			std::cout<<"SUPL: Read XML Ephemeris for GPS SV "<<gps_eph_iter->first<<std::endl; | ||||||
|  | 			global_gps_ephemeris_queue.push(gps_eph_iter->second); | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	}else{ | ||||||
|  | 		std::cout<< "ERROR: SUPL client error reading XML"<<std::endl; | ||||||
|  | 		std::cout<< "Disabling SUPL assistance.."<<std::endl; | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| void ControlThread::init() | void ControlThread::init() | ||||||
| { | { | ||||||
|     // Instantiates a control queue, a GNSS flowgraph, and a control message factory |     // Instantiates a control queue, a GNSS flowgraph, and a control message factory | ||||||
| @@ -174,50 +195,106 @@ void ControlThread::init() | |||||||
|     applied_actions_ = 0; |     applied_actions_ = 0; | ||||||
|  |  | ||||||
|     // GNSS Assistance configuration |     // GNSS Assistance configuration | ||||||
|     bool enable_gps_supl_assistance=configuration_->property("SUPL_gps_enabled",false); |     bool enable_gps_supl_assistance=configuration_->property("GNSS-SDR.SUPL_gps_enabled",false); | ||||||
|     if (enable_gps_supl_assistance==true) |     if (enable_gps_supl_assistance==true) | ||||||
|     	//SUPL SERVER TEST. Not operational yet! |     	//SUPL SERVER TEST. Not operational yet! | ||||||
|     { |     { | ||||||
|  |     	std::cout<< "SUPL RRLP GPS assistance enabled!"<<std::endl; | ||||||
| 		std::string default_acq_server="supl.nokia.com"; | 		std::string default_acq_server="supl.nokia.com"; | ||||||
| 		std::string default_eph_server="supl.google.com"; | 		std::string default_eph_server="supl.google.com"; | ||||||
| 		supl_client_ephemeris_.server_name=configuration_->property("SUPL_ephemeris_server",default_acq_server); | 		supl_client_ephemeris_.server_name=configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_server",default_acq_server); | ||||||
| 		supl_client_acquisition_.server_name=configuration_->property("SUPL_acquisition_server",default_eph_server); | 		supl_client_acquisition_.server_name=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server",default_eph_server); | ||||||
| 		supl_client_ephemeris_.server_port=configuration_->property("SUPL_ephemeris_port",7275); | 		supl_client_ephemeris_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port",7275); | ||||||
| 		supl_client_acquisition_.server_port=configuration_->property("SUPL_acquisition_server",7275); | 		supl_client_acquisition_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port",7275); | ||||||
|  |  | ||||||
| 		supl_mcc=configuration_->property("SUPL_MCC",244); | 		supl_mcc=configuration_->property("GNSS-SDR.SUPL_MCC",244); | ||||||
| 		supl_mns=configuration_->property("SUPL_MNS",5); | 		supl_mns=configuration_->property("GNSS-SDR.SUPL_MNS",5); | ||||||
|  |  | ||||||
| 		std::string default_lac="0x59e2"; | 		std::string default_lac="0x59e2"; | ||||||
| 		std::string default_ci="0x31b0"; | 		std::string default_ci="0x31b0"; | ||||||
| 		try { | 		try { | ||||||
| 			supl_lac = boost::lexical_cast<int>(configuration_->property("SUPL_LAC",default_lac)); | 			supl_lac = boost::lexical_cast<int>(configuration_->property("GNSS-SDR.SUPL_LAC",default_lac)); | ||||||
| 		} catch(boost::bad_lexical_cast &) { | 		} catch(boost::bad_lexical_cast &) { | ||||||
| 			supl_lac=0x59e2; | 			supl_lac=0x59e2; | ||||||
| 		} | 		} | ||||||
| 		try { | 		try { | ||||||
| 		supl_ci = boost::lexical_cast<int>(configuration_->property("SUPL_CI",default_ci)); | 		supl_ci = boost::lexical_cast<int>(configuration_->property("GNSS-SDR.SUPL_CI",default_ci)); | ||||||
| 		} catch(boost::bad_lexical_cast &) { | 		} catch(boost::bad_lexical_cast &) { | ||||||
| 			supl_ci=0x31b0; | 			supl_ci=0x31b0; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		supl_client_ephemeris_.request=0; | 		bool SUPL_read_gps_assistance_xml=configuration_->property("GNSS-SDR.SUPL_read_gps_assistance_xml",false); | ||||||
| 		int error=supl_client_ephemeris_.get_assistance(supl_mcc,supl_mns,supl_lac,supl_ci); | 		if (SUPL_read_gps_assistance_xml==true) | ||||||
|  | 		{ | ||||||
|  | 			// read assistance from file | ||||||
|  | 			read_assistance_from_XML(); | ||||||
|  | 		}else{ | ||||||
|  |  | ||||||
|  | 		// Request ephemeris from SUPL server | ||||||
|  | 		int error; | ||||||
|  | 		supl_client_ephemeris_.request=1; | ||||||
|  | 		std::cout<< "SUPL: Try read GPS ephemeris from SUPL server.."<<std::endl; | ||||||
|  | 		error=supl_client_ephemeris_.get_assistance(supl_mcc,supl_mns,supl_lac,supl_ci); | ||||||
| 		if (error==0) | 		if (error==0) | ||||||
| 		{ | 		{ | ||||||
| 			std::cout<< "Try read ephemeris from GPS ephemeris data queue"<<std::endl; |  | ||||||
| 			std::map<int,Gps_Ephemeris>::iterator gps_eph_iter; | 			std::map<int,Gps_Ephemeris>::iterator gps_eph_iter; | ||||||
| 			for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin(); | 			for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin(); | ||||||
| 					gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end(); | 					gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end(); | ||||||
| 					gps_eph_iter++) | 					gps_eph_iter++) | ||||||
| 			{ | 			{ | ||||||
| 				std::cout<<"Received Ephemeris for SV "<<gps_eph_iter->first<<std::endl; | 				std::cout<<"SUPL: Received Ephemeris for GPS SV "<<gps_eph_iter->first<<std::endl; | ||||||
| 				std::cout<<"OMEGA="<<gps_eph_iter->second.d_OMEGA<<std::endl; | 				global_gps_ephemeris_queue.push(gps_eph_iter->second); | ||||||
|  | 			} | ||||||
|  | 			//Save ephemeris to XML file | ||||||
|  | 			std::string eph_xml_filename="gps_ephemeris.xml"; | ||||||
|  | 			if (supl_client_ephemeris_.save_ephemeris_xml(eph_xml_filename)==true) | ||||||
|  | 			{ | ||||||
|  | 				std::cout<<"SUPL: XML Ephemeris file created"<<std::endl; | ||||||
| 			} | 			} | ||||||
| 		}else{ | 		}else{ | ||||||
| 			std::cout<< "SUPL client for Ephemeris returned "<<error<<std::endl; | 			std::cout<< "ERROR: SUPL client for Ephemeris returned "<<error<<std::endl; | ||||||
|  | 			std::cout<< "Please check internet connection and SUPL server configuration"<<error<<std::endl; | ||||||
|  | 			std::cout<< "Trying to read ephemeris from XML file"<<std::endl; | ||||||
|  | 			if (read_assistance_from_XML()==false) | ||||||
|  | 			{ | ||||||
|  | 				std::cout<< "ERROR: Could not read Ephemeris file: Disabling SUPL assistance.."<<std::endl; | ||||||
|  | 				enable_gps_supl_assistance=false; | ||||||
|  | 				stop_=true; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Request almanac , IONO and UTC Model | ||||||
|  | 		supl_client_ephemeris_.request=0; | ||||||
|  | 		std::cout<< "SUPL: Try read Almanac, Iono, Utc Model, Ref Time and Ref Location from SUPL server.."<<std::endl; | ||||||
|  | 		error=supl_client_ephemeris_.get_assistance(supl_mcc,supl_mns,supl_lac,supl_ci); | ||||||
|  | 		if (error==0) | ||||||
|  | 		{ | ||||||
|  | 			std::map<int,Gps_Almanac>::iterator gps_alm_iter; | ||||||
|  | 			for(gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.begin(); | ||||||
|  | 					gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.end(); | ||||||
|  | 					gps_alm_iter++) | ||||||
|  | 			{ | ||||||
|  | 				std::cout<<"SUPL: Received Almanac for GPS SV "<<gps_alm_iter->first<<std::endl; | ||||||
|  | 				global_gps_almanac_queue.push(gps_alm_iter->second); | ||||||
|  | 			} | ||||||
|  | 			if (supl_client_ephemeris_.gps_iono.valid==true) | ||||||
|  | 			{ | ||||||
|  | 				std::cout<<"SUPL: Received GPS Iono"<<std::endl; | ||||||
|  | 				global_gps_iono_queue.push(supl_client_ephemeris_.gps_iono); | ||||||
|  | 			} | ||||||
|  | 			if (supl_client_ephemeris_.gps_utc.valid==true) | ||||||
|  | 			{ | ||||||
|  | 				std::cout<<"SUPL: Received GPS UTC Model"<<std::endl; | ||||||
|  | 				global_gps_utc_model_queue.push(supl_client_ephemeris_.gps_utc); | ||||||
|  | 			} | ||||||
|  | 		}else{ | ||||||
|  | 			std::cout<< "ERROR: SUPL client for Almanac returned "<<error<<std::endl; | ||||||
|  | 			std::cout<< "Please check internet connection and SUPL server configuration"<<error<<std::endl; | ||||||
|  | 			std::cout<< "Disabling SUPL assistance.."<<std::endl; | ||||||
|  | 			enable_gps_supl_assistance=false; | ||||||
| 			stop_=true; | 			stop_=true; | ||||||
| 		} | 		} | ||||||
|  | 		} | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -292,7 +369,7 @@ void ControlThread::gps_ephemeris_data_collector() | |||||||
| 		global_gps_ephemeris_queue.wait_and_pop(gps_eph); | 		global_gps_ephemeris_queue.wait_and_pop(gps_eph); | ||||||
|  |  | ||||||
| 			// DEBUG MESSAGE | 			// DEBUG MESSAGE | ||||||
| 			std::cout << "New ephemeris record has arrived from SAT ID " | 			std::cout << "Ephemeris record has arrived from SAT ID " | ||||||
| 					<< gps_eph.i_satellite_PRN << " (Block " | 					<< gps_eph.i_satellite_PRN << " (Block " | ||||||
| 					<<  gps_eph.satelliteBlock[gps_eph.i_satellite_PRN] | 					<<  gps_eph.satelliteBlock[gps_eph.i_satellite_PRN] | ||||||
| 					                           << ")" << std::endl; | 					                           << ")" << std::endl; | ||||||
| @@ -302,18 +379,21 @@ void ControlThread::gps_ephemeris_data_collector() | |||||||
| 				// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris | 				// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris | ||||||
| 				if (gps_eph.i_GPS_week > gps_eph_old.i_GPS_week) | 				if (gps_eph.i_GPS_week > gps_eph_old.i_GPS_week) | ||||||
| 				{ | 				{ | ||||||
|  | 					std::cout << "Ephemeris record updated (GPS week="<<gps_eph.i_GPS_week<<std::endl; | ||||||
| 					global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph); | 					global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph); | ||||||
| 				}else{ | 				}else{ | ||||||
| 					if (gps_eph.d_TOW>gps_eph_old.d_TOW) | 					if (gps_eph.d_Toe>gps_eph_old.d_Toe) | ||||||
| 					{ | 					{ | ||||||
|  | 						std::cout << "Ephemeris record updated (Toe="<<gps_eph.d_Toe<<std::endl; | ||||||
| 						global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph); | 						global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph); | ||||||
| 					}else{ | 					}else{ | ||||||
| 						std::cout<<"not updating the existing ephemeris"<<std::endl; | 						std::cout<<"Not updating the existing ephemeris"<<std::endl; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 			}else{ | 			}else{ | ||||||
| 				// insert new ephemeris record | 				// insert new ephemeris record | ||||||
|  | 				std::cout << "New Ephemeris record inserted with Toe="<<gps_eph.d_Toe<<" and GPS Week="<<gps_eph.i_GPS_week<<std::endl; | ||||||
| 				global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph); | 				global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph); | ||||||
| 			} | 			} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -117,6 +117,7 @@ private: | |||||||
| 	int supl_ci; // Cell Identity (16 bits, 0-65535 are valid values). | 	int supl_ci; // Cell Identity (16 bits, 0-65535 are valid values). | ||||||
|  |  | ||||||
|     void init(); |     void init(); | ||||||
|  |     bool read_assistance_from_XML(); | ||||||
|     void read_control_messages(); |     void read_control_messages(); | ||||||
|     void process_control_messages(); |     void process_control_messages(); | ||||||
|     void gps_ephemeris_data_collector(); |     void gps_ephemeris_data_collector(); | ||||||
|   | |||||||
| @@ -35,6 +35,47 @@ | |||||||
| Gps_Ephemeris::Gps_Ephemeris() | Gps_Ephemeris::Gps_Ephemeris() | ||||||
| { | { | ||||||
|  |  | ||||||
|  |     i_satellite_PRN=0; | ||||||
|  |     d_TOW=0; | ||||||
|  |     d_Crs=0; | ||||||
|  |     d_Delta_n=0; | ||||||
|  |     d_M_0=0; | ||||||
|  |     d_Cuc=0; | ||||||
|  |     d_e_eccentricity=0; | ||||||
|  |     d_Cus=0; | ||||||
|  |     d_sqrt_A=0; | ||||||
|  |     d_Toe=0; | ||||||
|  |     d_Toc=0; | ||||||
|  |     d_Cic=0; | ||||||
|  |     d_OMEGA0=0; | ||||||
|  |     d_Cis=0; | ||||||
|  |     d_i_0=0; | ||||||
|  |     d_Crc=0; | ||||||
|  |     d_OMEGA=0; | ||||||
|  |     d_OMEGA_DOT=0; | ||||||
|  |     d_IDOT=0; | ||||||
|  |     i_code_on_L2=0; | ||||||
|  |     i_GPS_week=0; | ||||||
|  |     b_L2_P_data_flag=false; | ||||||
|  |     i_SV_accuracy=0; | ||||||
|  |     i_SV_health=0; | ||||||
|  |     d_TGD=0;            //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] | ||||||
|  |     d_IODC=0;           //!< Issue of Data, Clock | ||||||
|  |     i_AODO=0;              //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] | ||||||
|  |  | ||||||
|  |     b_fit_interval_flag=false;//!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. | ||||||
|  |     d_spare1=0; | ||||||
|  |     d_spare2=0; | ||||||
|  |  | ||||||
|  |     d_A_f0=0;          //!< Coefficient 0 of code phase offset model [s] | ||||||
|  |     d_A_f1=0;          //!< Coefficient 1 of code phase offset model [s/s] | ||||||
|  |     d_A_f2=0;          //!< Coefficient 2 of code phase offset model [s/s^2] | ||||||
|  |  | ||||||
|  |     b_integrity_status_flag=false; | ||||||
|  |     b_alert_flag=false;      //!< If true, indicates  that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk. | ||||||
|  |     b_antispoofing_flag=false;  //!<  If true, the AntiSpoofing mode is ON in that SV | ||||||
|  |  | ||||||
|  |  | ||||||
| 	//Plane A (info from http://www.navcen.uscg.gov/?Do=constellationStatus) | 	//Plane A (info from http://www.navcen.uscg.gov/?Do=constellationStatus) | ||||||
| 	satelliteBlock[9] = "IIA"; | 	satelliteBlock[9] = "IIA"; | ||||||
| 	satelliteBlock[31] = "IIR-M"; | 	satelliteBlock[31] = "IIR-M"; | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ | |||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <map> | #include <map> | ||||||
| #include "boost/assign.hpp" | #include "boost/assign.hpp" | ||||||
|  | #include <boost/serialization/nvp.hpp> | ||||||
|  |  | ||||||
| #include "GPS_L1_CA.h" | #include "GPS_L1_CA.h" | ||||||
|  |  | ||||||
| @@ -131,6 +132,55 @@ public: | |||||||
|     std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus |     std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     template<class Archive> | ||||||
|  |     /* | ||||||
|  |      * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. | ||||||
|  |      */ | ||||||
|  |     void serialize(Archive& archive, const unsigned int version) | ||||||
|  |     { | ||||||
|  |         using boost::serialization::make_nvp; | ||||||
|  |  | ||||||
|  |         archive & make_nvp("i_satellite_PRN",i_satellite_PRN); // SV PRN NUMBER | ||||||
|  |         archive & make_nvp("d_TOW",d_TOW); //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] | ||||||
|  |         archive & make_nvp("d_Crs",d_Crs);            //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m] | ||||||
|  |         archive & make_nvp("d_Delta_n",d_Delta_n);        //!< Mean Motion Difference From Computed Value [semi-circles/s] | ||||||
|  |         archive & make_nvp("d_M_0",d_M_0);            //!< Mean Anomaly at Reference Time [semi-circles] | ||||||
|  |         archive & make_nvp("d_Cuc",d_Cuc);            //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] | ||||||
|  |         archive & make_nvp("d_e_eccentricity",d_e_eccentricity); //!< Eccentricity [dimensionless] | ||||||
|  |         archive & make_nvp("d_Cus",d_Cus);            //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] | ||||||
|  |         archive & make_nvp("d_sqrt_A",d_sqrt_A);         //!< Square Root of the Semi-Major Axis [sqrt(m)] | ||||||
|  |         archive & make_nvp("d_Toe",d_Toe);            //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] | ||||||
|  |         archive & make_nvp("d_Toc",d_Toe);            //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] | ||||||
|  |         archive & make_nvp("d_Cic",d_Cic);            //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] | ||||||
|  |         archive & make_nvp("d_OMEGA0",d_OMEGA0);         //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] | ||||||
|  |         archive & make_nvp("d_Cis",d_Cis);            //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad] | ||||||
|  |         archive & make_nvp("d_i_0",d_i_0);            //!< Inclination Angle at Reference Time [semi-circles] | ||||||
|  |         archive & make_nvp("d_Crc",d_Crc);            //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m] | ||||||
|  |         archive & make_nvp("d_OMEGA",d_OMEGA);          //!< Argument of Perigee [semi-cicles] | ||||||
|  |         archive & make_nvp("d_OMEGA_DOT",d_OMEGA_DOT);      //!< Rate of Right Ascension [semi-circles/s] | ||||||
|  |         archive & make_nvp("d_IDOT",d_IDOT);           //!< Rate of Inclination Angle [semi-circles/s] | ||||||
|  |         archive & make_nvp("i_code_on_L2",i_code_on_L2);        //!< If 1, P code ON in L2;  if 2, C/A code ON in L2; | ||||||
|  |         archive & make_nvp("i_GPS_week",i_GPS_week);          //!< GPS week number, aka WN [week] | ||||||
|  |         archive & make_nvp("b_L2_P_data_flag",b_L2_P_data_flag);   //!< When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel | ||||||
|  |         archive & make_nvp("i_SV_accuracy",i_SV_accuracy);       //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E) | ||||||
|  |         archive & make_nvp("i_SV_health",i_SV_health); | ||||||
|  |         archive & make_nvp("d_TGD",d_TGD);           //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] | ||||||
|  |         archive & make_nvp("d_IODC",d_IODC);           //!< Issue of Data, Clock | ||||||
|  |         archive & make_nvp("i_AODO",i_AODO);              //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] | ||||||
|  |  | ||||||
|  |         archive & make_nvp("b_fit_interval_flag",b_fit_interval_flag);//!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. | ||||||
|  |         archive & make_nvp("d_spare1",d_spare1); | ||||||
|  |         archive & make_nvp("d_spare2",d_spare2); | ||||||
|  |  | ||||||
|  |         archive & make_nvp("d_A_f0",d_A_f0);          //!< Coefficient 0 of code phase offset model [s] | ||||||
|  |         archive & make_nvp("d_A_f1",d_A_f1);          //!< Coefficient 1 of code phase offset model [s/s] | ||||||
|  |         archive & make_nvp("d_A_f2",d_A_f2);          //!< Coefficient 2 of code phase offset model [s/s^2] | ||||||
|  |  | ||||||
|  |         archive & make_nvp("b_integrity_status_flag",b_integrity_status_flag); | ||||||
|  |         archive & make_nvp("b_alert_flag",b_alert_flag);     //!< If true, indicates  that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk. | ||||||
|  |         archive & make_nvp("b_antispoofing_flag",b_antispoofing_flag); //!<  If true, the AntiSpoofing mode is ON in that SV | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /*! |     /*! | ||||||
|      * \brief Compute the ECEF SV coordinates and ECEF velocity |      * \brief Compute the ECEF SV coordinates and ECEF velocity | ||||||
|      * Implementation of Table 20-IV (IS-GPS-200E) |      * Implementation of Table 20-IV (IS-GPS-200E) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas