From 0bf9e44eb425304181bbd049954bd6c1c845968e Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Mon, 18 Mar 2013 18:27:44 +0000 Subject: [PATCH] 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 --- CMakeLists.txt | 2 +- conf/gnss-sdr.conf | 28 +- conf/gnss-sdr_gn3s_realtime.conf | 21 +- conf/master.conf | 12 + src/algorithms/PVT/libs/gps_l1_ca_ls_pvt.cc | 355 +++++++++--------- .../adapters/freq_xlating_fir_filter.cc | 1 + .../signal_source/adapters/CMakeLists.txt | 2 +- src/core/libs/gnss_sdr_supl_client.cc | 41 ++ src/core/libs/gnss_sdr_supl_client.h | 17 + src/core/libs/supl/supl.c | 2 +- src/core/receiver/CMakeLists.txt | 6 + src/core/receiver/control_thread.cc | 116 +++++- src/core/receiver/control_thread.h | 1 + src/core/system_parameters/gps_ephemeris.cc | 41 ++ src/core/system_parameters/gps_ephemeris.h | 50 +++ 15 files changed, 472 insertions(+), 223 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ea0e5de4..03a38d3cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,7 +206,7 @@ set(Boost_ADDITIONAL_VERSIONS ) set(Boost_USE_MULTITHREAD ON) 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) message(FATAL_ERROR "Fatal error: Boost (version >=1.42.0) required.") endif(NOT Boost_FOUND) diff --git a/conf/gnss-sdr.conf b/conf/gnss-sdr.conf index d7b3f0ced..da5e83ca8 100644 --- a/conf/gnss-sdr.conf +++ b/conf/gnss-sdr.conf @@ -12,6 +12,18 @@ GNSS-SDR.internal_fs_hz=4000000 ;######### CONTROL_THREAD CONFIG ############ 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 ############ ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) 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] Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold -Acquisition0.threshold=70 +Acquisition0.threshold=50 ;#doppler_max: Maximum expected Doppler shift [Hz] Acquisition0.doppler_max=10000 ;#doppler_max: Doppler step in the grid search [Hz] @@ -302,28 +314,28 @@ Acquisition0.doppler_step=250 ;######### ACQUISITION CH 1 CONFIG ############ Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition1.threshold=70 +Acquisition1.threshold=50 Acquisition1.doppler_max=10000 Acquisition1.doppler_step=250 ;######### ACQUISITION CH 2 CONFIG ############ Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition2.threshold=70 +Acquisition2.threshold=50 Acquisition2.doppler_max=10000 Acquisition2.doppler_step=250 ;######### ACQUISITION CH 3 CONFIG ############ Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition3.threshold=70 +Acquisition3.threshold=50 Acquisition3.doppler_max=10000 Acquisition3.doppler_step=250 ;######### ACQUISITION CH 4 CONFIG ############ Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition4.threshold=70 +Acquisition4.threshold=50 Acquisition4.doppler_max=10000 Acquisition4.doppler_step=250 @@ -337,21 +349,21 @@ Acquisition5.doppler_step=250 ;######### ACQUISITION CH 6 CONFIG ############ Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition6.threshold=70 +Acquisition6.threshold=50 Acquisition6.doppler_max=10000 Acquisition6.doppler_step=250 ;######### ACQUISITION CH 7 CONFIG ############ Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition7.threshold=70 +Acquisition7.threshold=50 Acquisition7.doppler_max=10000 Acquisition7.doppler_step=250 ;######### ACQUISITION CH 8 CONFIG ############ Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition8.threshold=70 +Acquisition8.threshold=50 Acquisition8.doppler_max=10000 Acquisition8.doppler_step=250 diff --git a/conf/gnss-sdr_gn3s_realtime.conf b/conf/gnss-sdr_gn3s_realtime.conf index 25eb00dda..07cfa8fe6 100644 --- a/conf/gnss-sdr_gn3s_realtime.conf +++ b/conf/gnss-sdr_gn3s_realtime.conf @@ -7,7 +7,7 @@ ;######### GLOBAL OPTIONS ################## ;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 ############ 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 ; 8183800/5 = 1636760 -; 8183800/4 = 2045950 +; 8183800/4 = 2727933.33 +; 8183800/3 = 2727933.33333333 InputFilter.sampling_frequency=8183800 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 ;#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 ############ ;#count: Number of available satellite channels. -Channels.count=7 +Channels.count=1 ;#in_acquisition: Number of channels simultaneously acquiring Channels.in_acquisition=1 @@ -299,7 +300,7 @@ Acquisition.sampled_ms=1 ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold -Acquisition0.threshold=70 +Acquisition0.threshold=50 ;#doppler_max: Maximum expected Doppler shift [Hz] Acquisition0.doppler_max=10000 ;#doppler_max: Doppler step in the grid search [Hz] @@ -309,21 +310,21 @@ Acquisition0.doppler_step=250 ;######### ACQUISITION CH 1 CONFIG ############ Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition1.threshold=70 +Acquisition1.threshold=30 Acquisition1.doppler_max=10000 Acquisition1.doppler_step=250 ;######### ACQUISITION CH 2 CONFIG ############ Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition2.threshold=70 +Acquisition2.threshold=30 Acquisition2.doppler_max=10000 Acquisition2.doppler_step=250 ;######### ACQUISITION CH 3 CONFIG ############ Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition3.threshold=70 +Acquisition3.threshold=30 Acquisition3.doppler_max=10000 Acquisition3.doppler_step=250 @@ -367,7 +368,7 @@ Acquisition8.doppler_step=250 ;######### TRACKING GLOBAL CONFIG ############ ;#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. Tracking.item_type=gr_complex diff --git a/conf/master.conf b/conf/master.conf index 67c4d0d49..89d979db7 100644 --- a/conf/master.conf +++ b/conf/master.conf @@ -12,6 +12,18 @@ GNSS-SDR.internal_fs_hz=4000000 ;######### CONTROL_THREAD CONFIG ############ 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 ############ ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) SignalSource.implementation=File_Signal_Source diff --git a/src/algorithms/PVT/libs/gps_l1_ca_ls_pvt.cc b/src/algorithms/PVT/libs/gps_l1_ca_ls_pvt.cc index 1617a9e3e..ce95a3ccf 100644 --- a/src/algorithms/PVT/libs/gps_l1_ca_ls_pvt.cc +++ b/src/algorithms/PVT/libs/gps_l1_ca_ls_pvt.cc @@ -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 gnss_pseudoranges_map, double GPS_current_time, bool flag_averaging) { - std::map::iterator gnss_pseudoranges_iter; + std::map::iterator gnss_pseudoranges_iter; + std::map::iterator gps_ephemeris_iter; + int valid_pseudoranges=gnss_pseudoranges_map.size(); - std::map::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 - arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector - arma::mat satpos = arma::zeros(3,valid_pseudoranges); //satellite positions matrix + d_flag_averaging = flag_averaging; - int GPS_week = 0; - double GPS_corrected_time = 0; - double utc = 0; + // ******************************************************************************** + // ****** PREPARE THE LEAST SQUARES DATA (SV POSITIONS MATRIX AND OBS VECTORS) **** + // ******************************************************************************** + 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="<first<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; + // ******************************************************************************** + // ****** SOLVE LEAST SQUARES****************************************************** + // ******************************************************************************** + d_valid_observations = valid_obs; + DLOG(INFO) << "(new)PVT: valid observations=" << valid_obs << std::endl; - // 2- compute the clock error including relativistic effects for this SV - GPS_corrected_time = gps_ephemeris_iter->second.sv_clock_correction(GPS_current_time); - //DLOG(INFO)<<"pseudorranges SV "<second.i_satellite_PRN - // << " tx_time-d_TOW="<second.d_TOW<second.i_satellite_PRN - // << " d_TOW_current_symbol="<second.d_TOW_at_current_symbol<= 4) + { + arma::vec mypos; + DLOG(INFO)<<"satpos="<second.i_satellite_PRN - // << " symbol_shift_from_preamble="<second.Pseudorange_symbol_shift<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="<first<::iterator it = taps_d.begin(); it != taps_d.end(); it++) { taps_.push_back(float(*it)); + std::cout<<"TAP="<(e->prn, gps_eph)); 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; // SV navigation model 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< +#include +#include +#include +#include +#include +#include extern "C" { #include "supl.h" @@ -101,6 +107,17 @@ public: * */ 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. */ diff --git a/src/core/libs/supl/supl.c b/src/core/libs/supl/supl.c index 02d8b89a4..08cc10207 100644 --- a/src/core/libs/supl/supl.c +++ b/src/core/libs/supl/supl.c @@ -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) req_adata->acquisitionAssistanceRequested = 0; // 1 req_adata->navigationModelRequested = 1; // 1 - req_adata->referenceTimeRequested = 0; + req_adata->referenceTimeRequested = 1; req_adata->utcModelRequested = 0; //1 req_adata->ionosphericModelRequested = 0; // 1 req_adata->referenceLocationRequested = 0; diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index db6fc4c05..12484c630 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -59,5 +59,11 @@ include_directories( ) 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}) 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) \ No newline at end of file diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 2b5e1a18b..da725b464 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -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 "<::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 "<first<second); + } + return false; + }else{ + std::cout<< "ERROR: SUPL client error reading XML"<property("SUPL_gps_enabled",false); + bool enable_gps_supl_assistance=configuration_->property("GNSS-SDR.SUPL_gps_enabled",false); if (enable_gps_supl_assistance==true) //SUPL SERVER TEST. Not operational yet! { + std::cout<< "SUPL RRLP GPS assistance enabled!"<property("SUPL_ephemeris_server",default_acq_server); - supl_client_acquisition_.server_name=configuration_->property("SUPL_acquisition_server",default_eph_server); - supl_client_ephemeris_.server_port=configuration_->property("SUPL_ephemeris_port",7275); - supl_client_acquisition_.server_port=configuration_->property("SUPL_acquisition_server",7275); + supl_client_ephemeris_.server_name=configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_server",default_acq_server); + supl_client_acquisition_.server_name=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server",default_eph_server); + supl_client_ephemeris_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port",7275); + supl_client_acquisition_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port",7275); - supl_mcc=configuration_->property("SUPL_MCC",244); - supl_mns=configuration_->property("SUPL_MNS",5); + supl_mcc=configuration_->property("GNSS-SDR.SUPL_MCC",244); + supl_mns=configuration_->property("GNSS-SDR.SUPL_MNS",5); std::string default_lac="0x59e2"; std::string default_ci="0x31b0"; try { - supl_lac = boost::lexical_cast(configuration_->property("SUPL_LAC",default_lac)); + supl_lac = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_LAC",default_lac)); } catch(boost::bad_lexical_cast &) { supl_lac=0x59e2; } try { - supl_ci = boost::lexical_cast(configuration_->property("SUPL_CI",default_ci)); + supl_ci = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_CI",default_ci)); } catch(boost::bad_lexical_cast &) { supl_ci=0x31b0; } - supl_client_ephemeris_.request=0; - int error=supl_client_ephemeris_.get_assistance(supl_mcc,supl_mns,supl_lac,supl_ci); + bool SUPL_read_gps_assistance_xml=configuration_->property("GNSS-SDR.SUPL_read_gps_assistance_xml",false); + 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.."<::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<<"Received Ephemeris for SV "<first<first<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"<::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 "<first<second); + } + if (supl_client_ephemeris_.gps_iono.valid==true) + { + std::cout<<"SUPL: Received GPS Iono"< gps_eph_old.i_GPS_week) { + std::cout << "Ephemeris record updated (GPS week="<gps_eph_old.d_TOW) + if (gps_eph.d_Toe>gps_eph_old.d_Toe) { + std::cout << "Ephemeris record updated (Toe="< #include #include "boost/assign.hpp" +#include #include "GPS_L1_CA.h" @@ -131,6 +132,55 @@ public: std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus + template + /* + * \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 * Implementation of Table 20-IV (IS-GPS-200E)