mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Mara Branzanti GSoC commit: Galileo PVT block skeleton. Not usable yet!
git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@419 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
		| @@ -16,7 +16,10 @@ | ||||
| # along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
| # | ||||
|  | ||||
| set(PVT_ADAPTER_SOURCES gps_l1_ca_pvt.cc) | ||||
| set(PVT_ADAPTER_SOURCES  | ||||
| 	gps_l1_ca_pvt.cc | ||||
| 	galileo_e1_pvt.cc | ||||
| ) | ||||
|  | ||||
| include_directories( | ||||
|      $(CMAKE_CURRENT_SOURCE_DIR) | ||||
|   | ||||
							
								
								
									
										109
									
								
								src/algorithms/PVT/adapters/galileo_e1_pvt.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/algorithms/PVT/adapters/galileo_e1_pvt.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_pvt.cc | ||||
|  * \brief  Implementation of an adapter of a GALILEO E1 PVT solver block to a | ||||
|  * PvtInterface | ||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2012  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "galileo_e1_pvt.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "galileo_e1_pvt_cc.h" | ||||
| #include <glog/log_severity.h> | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GalileoE1Pvt::GalileoE1Pvt(ConfigurationInterface* configuration, | ||||
|         std::string role, | ||||
|         unsigned int in_streams, | ||||
|         unsigned int out_streams, | ||||
|         boost::shared_ptr<gr::msg_queue> queue) : | ||||
|                 role_(role), | ||||
|                 in_streams_(in_streams), | ||||
|                 out_streams_(out_streams), | ||||
|                 queue_(queue) | ||||
| { | ||||
|     // dump parameters | ||||
|     std::string default_dump_filename = "./pvt.dat"; | ||||
|     std::string default_nmea_dump_filename = "./nmea_pvt.nmea"; | ||||
|     std::string default_nmea_dump_devname = "/dev/tty1"; | ||||
|     DLOG(INFO) << "role " << role; | ||||
|     dump_ = configuration->property(role + ".dump", false); | ||||
|     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); | ||||
|     // moving average depth parameters | ||||
|     int averaging_depth; | ||||
|     averaging_depth = configuration->property(role + ".averaging_depth", 10); | ||||
|     bool flag_averaging; | ||||
|     flag_averaging = configuration->property(role + ".flag_averaging", false); | ||||
|     // output rate | ||||
|     int output_rate_ms; | ||||
|     output_rate_ms = configuration->property(role + ".output_rate_ms", 500); | ||||
|     // display rate | ||||
|     int display_rate_ms; | ||||
|     display_rate_ms = configuration->property(role + ".display_rate_ms", 500); | ||||
|     // NMEA Printer settings | ||||
|     bool flag_nmea_tty_port; | ||||
|     flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false); | ||||
|     std::string nmea_dump_filename; | ||||
|     nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename); | ||||
|     std::string nmea_dump_devname; | ||||
|     nmea_dump_devname = configuration->property(role + ".nmea_dump_devname", default_nmea_dump_devname); | ||||
|     // make PVT object | ||||
|     pvt_ = galileo_e1_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname); | ||||
|     DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")"; | ||||
| } | ||||
|  | ||||
|  | ||||
| GalileoE1Pvt::~GalileoE1Pvt() | ||||
| {} | ||||
|  | ||||
|  | ||||
| void GalileoE1Pvt::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     // Nothing to connect internally | ||||
|     DLOG(INFO) << "nothing to connect internally"; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1Pvt::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     // Nothing to disconnect | ||||
| } | ||||
|  | ||||
| gr::basic_block_sptr GalileoE1Pvt::get_left_block() | ||||
| { | ||||
|     return pvt_; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE1Pvt::get_right_block() | ||||
| { | ||||
|     return pvt_; | ||||
| } | ||||
|  | ||||
							
								
								
									
										97
									
								
								src/algorithms/PVT/adapters/galileo_e1_pvt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/algorithms/PVT/adapters/galileo_e1_pvt.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_pvt.h | ||||
|  * \brief Interface of an adapter of a GALILEO E1 PVT solver block to a | ||||
|  * PvtInterface | ||||
|  * Position Velocity and Time | ||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2013  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifndef GNSS_SDR_GALILEO_E1_PVT_H_ | ||||
| #define GNSS_SDR_GALILEO_E1_PVT_H_ | ||||
|  | ||||
| #include "pvt_interface.h" | ||||
| #include "galileo_e1_pvt_cc.h" | ||||
| #include <gnuradio/msg_queue.h> | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class implements a PvtInterface for GPS L1 C/A | ||||
|  */ | ||||
| class GalileoE1Pvt : public PvtInterface | ||||
| { | ||||
| public: | ||||
| 	GalileoE1Pvt(ConfigurationInterface* configuration, | ||||
|             std::string role, | ||||
|             unsigned int in_streams, | ||||
|             unsigned int out_streams, | ||||
|             boost::shared_ptr<gr::msg_queue> queue); | ||||
|  | ||||
|     virtual ~GalileoE1Pvt(); | ||||
|  | ||||
|     std::string role() | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     //!  Returns "GPS_L1_CA_PVT" | ||||
|     std::string implementation() | ||||
|     { | ||||
|         return "GALILEO_E1_PVT"; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block); | ||||
|     void disconnect(gr::top_block_sptr top_block); | ||||
|     gr::basic_block_sptr get_left_block(); | ||||
|     gr::basic_block_sptr get_right_block(); | ||||
|  | ||||
|     void reset() | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     //! All blocks must have an item_size() function implementation. Returns sizeof(gr_complex) | ||||
|     size_t item_size() | ||||
|     { | ||||
|         return sizeof(gr_complex); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     galileo_e1_pvt_cc_sptr pvt_; | ||||
|     bool dump_; | ||||
|     unsigned int fs_in_; | ||||
|     std::string dump_filename_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|     boost::shared_ptr<gr::msg_queue> queue_; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -16,7 +16,10 @@ | ||||
| # along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
| # | ||||
|  | ||||
| set(PVT_GR_BLOCKS_SOURCES gps_l1_ca_pvt_cc.cc) | ||||
| set(PVT_GR_BLOCKS_SOURCES  | ||||
| 	gps_l1_ca_pvt_cc.cc | ||||
| 	galileo_e1_pvt_cc.cc | ||||
| ) | ||||
|  | ||||
| include_directories( | ||||
|      $(CMAKE_CURRENT_SOURCE_DIR) | ||||
|   | ||||
							
								
								
									
										250
									
								
								src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,250 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_pvt_cc.cc | ||||
|  * \brief Implementation of a Position Velocity and Time computation block for GPS L1 C/A | ||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2012  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "galileo_e1_pvt_cc.h" | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <vector> | ||||
| #include <map> | ||||
| #include <algorithm> | ||||
| #include <bitset> | ||||
| #include <gnuradio/gr_complex.h> | ||||
| #include <gnuradio/io_signature.h> | ||||
| #include <glog/log_severity.h> | ||||
| #include <glog/logging.h> | ||||
| #include "control_message_factory.h" | ||||
| #include "boost/date_time/posix_time/posix_time.hpp" | ||||
| #include "gnss_synchro.h" | ||||
| #include "concurrent_map.h" | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| extern concurrent_map<Galileo_Ephemeris> global_galileo_ephemeris_map; | ||||
| extern concurrent_map<Galileo_Iono> global_galileo_iono_map; | ||||
| extern concurrent_map<Galileo_Utc_Model> global_galileo_utc_model_map; | ||||
|  | ||||
| galileo_e1_pvt_cc_sptr | ||||
| galileo_e1_make_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname) | ||||
| { | ||||
|     return galileo_e1_pvt_cc_sptr(new galileo_e1_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname)); | ||||
| } | ||||
|  | ||||
|  | ||||
| galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname) : | ||||
| 		                		        gr::block("galileo_e1_pvt_cc", gr::io_signature::make(nchannels, nchannels,  sizeof(Gnss_Synchro)), | ||||
| 		                		                gr::io_signature::make(1, 1, sizeof(gr_complex))) | ||||
| { | ||||
|  | ||||
|     d_output_rate_ms = output_rate_ms; | ||||
|     d_display_rate_ms = display_rate_ms; | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
|     d_nchannels = nchannels; | ||||
|     d_dump_filename = dump_filename; | ||||
|     std::string dump_ls_pvt_filename = dump_filename; | ||||
|  | ||||
|     //initialize kml_printer | ||||
|     std::string kml_dump_filename; | ||||
|     kml_dump_filename = d_dump_filename; | ||||
|     kml_dump_filename.append(".kml"); | ||||
|     d_kml_dump.set_headers(kml_dump_filename); | ||||
|  | ||||
|     //initialize nmea_printer | ||||
|     d_nmea_printer = new Nmea_Printer(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname); | ||||
|  | ||||
|     d_dump_filename.append("_raw.dat"); | ||||
|     dump_ls_pvt_filename.append("_ls_pvt.dat"); | ||||
|     d_averaging_depth = averaging_depth; | ||||
|     d_flag_averaging = flag_averaging; | ||||
|  | ||||
|     d_ls_pvt = new galileo_e1_ls_pvt(nchannels,dump_ls_pvt_filename,d_dump); | ||||
|     d_ls_pvt->set_averaging_depth(d_averaging_depth); | ||||
|  | ||||
|     d_sample_counter = 0; | ||||
|     d_last_sample_nav_output = 0; | ||||
|     d_rx_time = 0.0; | ||||
|  | ||||
|     b_rinex_header_writen = false; | ||||
|     rp = new Rinex_Printer(); | ||||
|  | ||||
|     // ############# ENABLE DATA FILE LOG ################# | ||||
|     if (d_dump == true) | ||||
|         { | ||||
|             if (d_dump_file.is_open() == false) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                             d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); | ||||
|                             d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | ||||
|                             std::cout << "PVT dump enabled Log file: " << d_dump_filename.c_str() << std::endl; | ||||
|                     } | ||||
|                     catch (std::ifstream::failure e) | ||||
|                     { | ||||
|                             std::cout << "Exception opening PVT dump file " << e.what() << std::endl; | ||||
|                     } | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| galileo_e1_pvt_cc::~galileo_e1_pvt_cc() | ||||
| { | ||||
|     d_kml_dump.close_file(); | ||||
|     delete d_ls_pvt; | ||||
|     delete rp; | ||||
|     delete d_nmea_printer; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| bool galileo_e1_pvt_cc::pseudoranges_pairCompare_min( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b) | ||||
| { | ||||
|     return (a.second.Pseudorange_m) < (b.second.Pseudorange_m); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | ||||
|         gr_vector_const_void_star &input_items,	gr_vector_void_star &output_items) | ||||
| { | ||||
|     d_sample_counter++; | ||||
|  | ||||
|     std::map<int,Gnss_Synchro> gnss_pseudoranges_map; | ||||
|  | ||||
|     Gnss_Synchro **in = (Gnss_Synchro **)  &input_items[0]; //Get the input pointer | ||||
|  | ||||
|     for (unsigned int i=0; i<d_nchannels; i++) | ||||
|         { | ||||
|             if (in[i][0].Flag_valid_pseudorange == true) | ||||
|                 { | ||||
|                     gnss_pseudoranges_map.insert(std::pair<int,Gnss_Synchro>(in[i][0].PRN, in[i][0])); // store valid pseudoranges in a map | ||||
|                     d_rx_time = in[i][0].d_TOW_at_current_symbol; // all the channels have the same RX timestamp (common RX time pseudoranges) | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     // ############ 1. READ EPHEMERIS/UTC_MODE/IONO FROM GLOBAL MAPS #### | ||||
|  | ||||
|     d_ls_pvt->galileo_ephemeris_map = global_galileo_ephemeris_map.get_map_copy(); | ||||
|  | ||||
|     if (global_galileo_utc_model_map.size()>0) | ||||
|         { | ||||
|             // UTC MODEL data is shared for all the Galileo satellites. Read always at ID=0 | ||||
|             global_galileo_utc_model_map.read(0,d_ls_pvt->galileo_utc_model); | ||||
|         } | ||||
|  | ||||
|     if (global_galileo_iono_map.size()>0) | ||||
|         { | ||||
|             // IONO data is shared for all the Galileo satellites. Read always at ID=0 | ||||
|             global_galileo_iono_map.read(0,d_ls_pvt->galileo_iono); | ||||
|         } | ||||
|  | ||||
|     // ############ 2 COMPUTE THE PVT ################################ | ||||
| //    if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->gps_ephemeris_map.size() >0) | ||||
| //        { | ||||
| //            // compute on the fly PVT solution | ||||
| //            //mod 8/4/2012 Set the PVT computation rate in this block | ||||
| //            if ((d_sample_counter % d_output_rate_ms) == 0) | ||||
| //                { | ||||
| //                    bool pvt_result; | ||||
| //                    pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging); | ||||
| //                    if (pvt_result==true) | ||||
| //                        { | ||||
| //                            d_kml_dump.print_position(d_ls_pvt, d_flag_averaging); | ||||
| //                            d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging); | ||||
| // | ||||
| //                            if (!b_rinex_header_writen) //  & we have utc data in nav message! | ||||
| //                                { | ||||
| //                                    std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter; | ||||
| //                                    gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin(); | ||||
| //                                    if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) | ||||
| //                                        { | ||||
| //                                            rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second,d_rx_time); | ||||
| //                                            rp->rinex_nav_header(rp->navFile,d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); | ||||
| //                                            b_rinex_header_writen = true; // do not write header anymore | ||||
| //                                        } | ||||
| //                                } | ||||
| //                            if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s) | ||||
| //                                { | ||||
| //                                    // Limit the RINEX navigation output rate to 1/6 seg | ||||
| //                                    // Notice that d_sample_counter period is 1ms (for GPS correlators) | ||||
| //                                    if ((d_sample_counter-d_last_sample_nav_output)>=6000) | ||||
| //                                        { | ||||
| //                                            rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); | ||||
| //                                            d_last_sample_nav_output=d_sample_counter; | ||||
| //                                        } | ||||
| //                                    std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter; | ||||
| //                                    gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin(); | ||||
| //                                    if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) | ||||
| //                                        { | ||||
| //                                            rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map); | ||||
| //                                        } | ||||
| //                                } | ||||
| //                        } | ||||
| //                } | ||||
| // | ||||
| //            // DEBUG MESSAGE: Display position in console output | ||||
| //            if (((d_sample_counter % d_display_rate_ms) == 0) and d_ls_pvt->b_valid_position == true) | ||||
| //                { | ||||
| //                    std::cout << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time) | ||||
| //                    << " is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d | ||||
| //                    << " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl; | ||||
| // | ||||
| //                    std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time) | ||||
| //                    << " is HDOP = " << d_ls_pvt->d_HDOP << " VDOP = " << | ||||
| //                    d_ls_pvt->d_VDOP <<" TDOP = " << d_ls_pvt->d_TDOP << | ||||
| //                    " GDOP = " << d_ls_pvt->d_GDOP <<std::endl; | ||||
| //                } | ||||
| //            // MULTIPLEXED FILE RECORDING - Record results to file | ||||
| //            if(d_dump == true) | ||||
| //                { | ||||
| //                    try | ||||
| //                    { | ||||
| //                            double tmp_double; | ||||
| //                            for (unsigned int i=0; i<d_nchannels ; i++) | ||||
| //                                { | ||||
| //                                    tmp_double = in[i][0].Pseudorange_m; | ||||
| //                                    d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||
| //                                    tmp_double = 0; | ||||
| //                                    d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||
| //                                    d_dump_file.write((char*)&d_rx_time, sizeof(double)); | ||||
| //                                } | ||||
| //                    } | ||||
| //                    catch (std::ifstream::failure e) | ||||
| //                    { | ||||
| //                            std::cout << "Exception writing observables dump file " << e.what() << std::endl; | ||||
| //                    } | ||||
| //                } | ||||
| //        } | ||||
| // | ||||
| //    consume_each(1); //one by one | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										96
									
								
								src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /*! | ||||
|  * \file gps_l1_ca_pvt_cc.h | ||||
|  * \brief Interface of a Position Velocity and Time computation block for Galileo E1 | ||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2012  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GALILEO_E1_PVT_CC_H | ||||
| #define	GNSS_SDR_GALILEO_E1_PVT_CC_H | ||||
|  | ||||
| #include <fstream> | ||||
| #include <gnuradio/block.h> | ||||
| #include <gnuradio/msg_queue.h> | ||||
| #include <queue> | ||||
| #include <boost/thread/mutex.hpp> | ||||
| #include <boost/thread/thread.hpp> | ||||
| #include "galileo_navigation_message.h" | ||||
| #include "galileo_ephemeris.h" | ||||
| #include "galileo_utc_model.h" | ||||
| #include "galileo_iono.h" | ||||
| #include "nmea_printer.h" | ||||
| #include "kml_printer.h" | ||||
| #include "rinex_printer.h" | ||||
| #include "galileo_e1_ls_pvt.h" //this file is just a copy of gps | ||||
| #include "GPS_L1_CA.h" | ||||
| #include "Galileo_E1.h" | ||||
|  | ||||
|  | ||||
| class galileo_e1_pvt_cc; | ||||
|  | ||||
| typedef boost::shared_ptr<galileo_e1_pvt_cc> galileo_e1_pvt_cc_sptr; | ||||
|  | ||||
| galileo_e1_pvt_cc_sptr | ||||
| galileo_e1_make_pvt_cc(unsigned int n_channels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname); | ||||
|  | ||||
| /*! | ||||
|  * \brief This class implements a block that computes the PVT solution | ||||
|  */ | ||||
| class galileo_e1_pvt_cc : public gr::block | ||||
| { | ||||
| private: | ||||
|     friend galileo_e1_pvt_cc_sptr | ||||
|     galileo_e1_make_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname); | ||||
|     galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname); | ||||
|     boost::shared_ptr<gr::msg_queue> d_queue; | ||||
|     bool d_dump; | ||||
|     bool b_rinex_header_writen; | ||||
|     Rinex_Printer *rp; | ||||
|     unsigned int d_nchannels; | ||||
|     std::string d_dump_filename; | ||||
|     std::ofstream d_dump_file; | ||||
|     int d_averaging_depth; | ||||
|     bool d_flag_averaging; | ||||
|     int d_output_rate_ms; | ||||
|     int d_display_rate_ms; | ||||
|     long unsigned int d_sample_counter; | ||||
|     long unsigned int d_last_sample_nav_output; | ||||
|     Kml_Printer d_kml_dump; | ||||
|     Nmea_Printer *d_nmea_printer; | ||||
|     double d_rx_time; | ||||
|     galileo_e1_ls_pvt *d_ls_pvt;  /*modify PVT/libs/galileo_e1_ls_pvt*/ | ||||
|  | ||||
|     bool pseudoranges_pairCompare_min( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b); | ||||
| public: | ||||
|     ~galileo_e1_pvt_cc (); //!< Default destructor | ||||
|     /*! | ||||
|      * \brief Set the queue for getting navigation messages from the GpsL1CaTelemetryDecoder | ||||
|      */ | ||||
|  | ||||
|     int general_work (int noutput_items, gr_vector_int &ninput_items, | ||||
|             gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); //!< PVT Signal Processing | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -18,6 +18,7 @@ | ||||
|  | ||||
| set(PVT_LIB_SOURCES  | ||||
|      gps_l1_ca_ls_pvt.cc | ||||
|      galileo_e1_ls_pvt.cc | ||||
|      kml_printer.cc | ||||
|      rinex_printer.cc | ||||
|      nmea_printer.cc     | ||||
|   | ||||
							
								
								
									
										719
									
								
								src/algorithms/PVT/libs/galileo_e1_ls_pvt.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										719
									
								
								src/algorithms/PVT/libs/galileo_e1_ls_pvt.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,719 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_ls_pvt.cc | ||||
|  * \brief Implementation of a Least Squares Position, Velocity, and Time | ||||
|  * (PVT) solver, based on K.Borre's Matlab receiver. | ||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2012  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include <armadillo> | ||||
| #include "galileo_e1_ls_pvt.h" | ||||
|  | ||||
| #include "GPS_L1_CA.h" | ||||
| #include <glog/log_severity.h> | ||||
| #include <glog/logging.h> | ||||
| #include "boost/date_time/posix_time/posix_time.hpp" | ||||
| #include "gnss_synchro.h" | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| galileo_e1_ls_pvt::galileo_e1_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file) | ||||
| { | ||||
|     // init empty ephemeris for all the available GNSS channels | ||||
|     d_nchannels = nchannels; | ||||
|     d_ephemeris = new Galileo_Navigation_Message[nchannels]; | ||||
|     d_dump_filename = dump_filename; | ||||
|     d_flag_dump_enabled = flag_dump_to_file; | ||||
|     d_averaging_depth = 0; | ||||
|     d_galileo_current_time = 0; | ||||
|     b_valid_position = false; | ||||
|     // ############# ENABLE DATA FILE LOG ################# | ||||
|     if (d_flag_dump_enabled == true) | ||||
|         { | ||||
|             if (d_dump_file.is_open() == false) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                             d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit); | ||||
|                             d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | ||||
|                             std::cout << "PVT lib dump enabled Log file: " << d_dump_filename.c_str() << std::endl; | ||||
|                     } | ||||
|                     catch (std::ifstream::failure e) | ||||
|                     { | ||||
|                             std::cout << "Exception opening PVT lib dump file " << e.what() << std::endl; | ||||
|                     } | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| void galileo_e1_ls_pvt::set_averaging_depth(int depth) | ||||
| { | ||||
|     d_averaging_depth = depth; | ||||
| } | ||||
|  | ||||
|  | ||||
| galileo_e1_ls_pvt::~galileo_e1_ls_pvt() | ||||
| { | ||||
|     d_dump_file.close(); | ||||
|     delete[] d_ephemeris; | ||||
| } | ||||
|  | ||||
|  | ||||
| arma::vec galileo_e1_ls_pvt::rotateSatellite(double traveltime, arma::vec X_sat) | ||||
| { | ||||
|     /* | ||||
|      *  Returns rotated satellite ECEF coordinates due to Earth | ||||
|      * rotation during signal travel time | ||||
|      * | ||||
|      *   Inputs: | ||||
|      *       travelTime  - signal travel time | ||||
|      *       X_sat       - satellite's ECEF coordinates | ||||
|      * | ||||
|      *   Returns: | ||||
|      *       X_sat_rot   - rotated satellite's coordinates (ECEF) | ||||
|      */ | ||||
|  | ||||
|     //--- Find rotation angle -------------------------------------------------- | ||||
|     double omegatau; | ||||
|     omegatau = OMEGA_EARTH_DOT * traveltime; | ||||
|  | ||||
|     //--- Build a rotation matrix ---------------------------------------------- | ||||
|     arma::mat R3 = arma::zeros(3,3); | ||||
|     R3(0, 0) = cos(omegatau); | ||||
|     R3(0, 1) = sin(omegatau); | ||||
|     R3(0, 2) = 0.0; | ||||
|     R3(1, 0) = -sin(omegatau); | ||||
|     R3(1, 1) = cos(omegatau); | ||||
|     R3(1, 2) = 0.0; | ||||
|     R3(2, 0) = 0.0; | ||||
|     R3(2, 1) = 0.0; | ||||
|     R3(2, 2) = 1; | ||||
|  | ||||
|     //--- Do the rotation ------------------------------------------------------ | ||||
|     arma::vec X_sat_rot; | ||||
|     X_sat_rot = R3 * X_sat; | ||||
|     return X_sat_rot; | ||||
| } | ||||
|  | ||||
|  | ||||
| arma::vec galileo_e1_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma::mat w) | ||||
| { | ||||
|     /* Computes the Least Squares Solution. | ||||
|      *   Inputs: | ||||
|      *       satpos      - Satellites positions in ECEF system: [X; Y; Z;] | ||||
|      *       obs         - Observations - the pseudorange measurements to each satellite | ||||
|      *       w           - weigths vector | ||||
|      * | ||||
|      *   Returns: | ||||
|      *       pos         - receiver position and receiver clock error | ||||
|      *                   (in ECEF system: [X, Y, Z, dt]) | ||||
|      */ | ||||
|  | ||||
|     //=== Initialization ======================================================= | ||||
|     int nmbOfIterations = 10; // TODO: include in config | ||||
|     int nmbOfSatellites; | ||||
|     nmbOfSatellites = satpos.n_cols;	//Armadillo | ||||
|     arma::vec pos = "0.0 0.0 0.0 0.0"; | ||||
|     arma::mat A; | ||||
|     arma::mat omc; | ||||
|     arma::mat az; | ||||
|     arma::mat el; | ||||
|     A = arma::zeros(nmbOfSatellites, 4); | ||||
|     omc = arma::zeros(nmbOfSatellites, 1); | ||||
|     az = arma::zeros(1, nmbOfSatellites); | ||||
|     el = arma::zeros(1, nmbOfSatellites); | ||||
|     for (int i = 0; i < nmbOfSatellites; i++) | ||||
|         { | ||||
|             for (int j = 0; j < 4; j++) | ||||
|                 { | ||||
|                     A(i, j) = 0.0; //Armadillo | ||||
|                 } | ||||
|             omc(i, 0) = 0.0; | ||||
|             az(0, i) = 0.0; | ||||
|         } | ||||
|     el = az; | ||||
|     arma::mat X = satpos; | ||||
|     arma::vec Rot_X; | ||||
|     double rho2; | ||||
|     double traveltime; | ||||
|     double trop; | ||||
|     arma::mat mat_tmp; | ||||
|     arma::vec x; | ||||
|  | ||||
|     //=== Iteratively find receiver position =================================== | ||||
|     for (int iter = 0; iter < nmbOfIterations; iter++) | ||||
|         { | ||||
|             for (int i = 0; i < nmbOfSatellites; i++) | ||||
|                 { | ||||
|                     if (iter == 0) | ||||
|                         { | ||||
|                             //--- Initialize variables at the first iteration -------------- | ||||
|                             Rot_X = X.col(i); //Armadillo | ||||
|                             trop = 0.0; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             //--- Update equations ----------------------------------------- | ||||
|                             rho2 = (X(0, i) - pos(0)) * | ||||
|                                     (X(0, i) - pos(0))  + (X(1, i) - pos(1)) * | ||||
|                                     (X(1, i) - pos(1)) + (X(2,i) - pos(2)) * | ||||
|                                     (X(2,i) - pos(2)); | ||||
|                             traveltime = sqrt(rho2) / GPS_C_m_s; | ||||
|  | ||||
|                             //--- Correct satellite position (do to earth rotation) -------- | ||||
|                             Rot_X = rotateSatellite(traveltime, X.col(i)); //armadillo | ||||
|  | ||||
|                             //--- Find DOA and range of satellites | ||||
|                             topocent(&d_visible_satellites_Az[i], &d_visible_satellites_El[i], | ||||
|                                     &d_visible_satellites_Distance[i], pos.subvec(0,2), Rot_X - pos.subvec(0,2)); | ||||
|                             //[az(i), el(i), dist] = topocent(pos(1:3, :), Rot_X - pos(1:3, :)); | ||||
|  | ||||
|                         } | ||||
|                     //--- Apply the corrections ---------------------------------------- | ||||
|                     omc(i) = (obs(i) - norm(Rot_X - pos.subvec(0,2),2) - pos(3) - trop); // Armadillo | ||||
|  | ||||
|                     //--- Construct the A matrix --------------------------------------- | ||||
|                     //Armadillo | ||||
|                     A(i,0) = (-(Rot_X(0) - pos(0))) / obs(i); | ||||
|                     A(i,1) = (-(Rot_X(1) - pos(1))) / obs(i); | ||||
|                     A(i,2) = (-(Rot_X(2) - pos(2))) / obs(i); | ||||
|                     A(i,3) = 1.0; | ||||
|                 } | ||||
|                  | ||||
|             //--- Find position update --------------------------------------------- | ||||
|             x = arma::solve(w*A, w*omc); // Armadillo | ||||
|  | ||||
|             //--- Apply position update -------------------------------------------- | ||||
|             pos = pos + x; | ||||
|             if (arma::norm(x,2)<1e-4) | ||||
|             { | ||||
|             	break; // exit the loop because we assume that the LS algorithm has converged (err < 0.1 cm) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     try | ||||
|     { | ||||
|             //-- compute the Dilution Of Precision values | ||||
|             //arma::mat Q; | ||||
|             d_Q       = arma::inv(arma::htrans(A)*A); | ||||
|     } | ||||
|     catch(std::exception& e) | ||||
|     { | ||||
|             d_Q=arma::zeros(4,4); | ||||
|     } | ||||
|     return pos; | ||||
| } | ||||
|  | ||||
|  | ||||
| bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map, double galileo_current_time, bool flag_averaging) | ||||
| { | ||||
| //    std::map<int,Gnss_Synchro>::iterator gnss_pseudoranges_iter; | ||||
| //    std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter; | ||||
| //    int valid_pseudoranges = gnss_pseudoranges_map.size(); | ||||
| // | ||||
| //    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 GPS_week = 0; | ||||
| //    double utc = 0; | ||||
| //    double SV_clock_drift_s = 0; | ||||
| //    double SV_relativistic_clock_corr_s = 0; | ||||
| //    double TX_time_corrected_s; | ||||
| //    double SV_clock_bias_s = 0; | ||||
| // | ||||
| //    d_flag_averaging = flag_averaging; | ||||
| // | ||||
| //    // ******************************************************************************** | ||||
| //    // ****** 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()) | ||||
| //                { | ||||
| //                    /*! | ||||
| //                     * \todo Place here the satellite CN0 (power level, or weight factor) | ||||
| //                     */ | ||||
| //                    W(obs_counter, obs_counter) = 1; | ||||
| // | ||||
| //                    // COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files) | ||||
| //                    // first estimate of transmit time | ||||
| //                    double Rx_time = GPS_current_time; | ||||
| //                    double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GPS_C_m_s; | ||||
| // | ||||
| //                    // 2- compute the clock drift using the clock model (broadcast) for this SV | ||||
| //                    SV_clock_drift_s = gps_ephemeris_iter->second.sv_clock_drift(Tx_time); | ||||
| // | ||||
| //                    // 3- compute the relativistic clock drift using the clock model (broadcast) for this SV | ||||
| //                    SV_relativistic_clock_corr_s = gps_ephemeris_iter->second.sv_clock_relativistic_term(Tx_time); | ||||
| // | ||||
| //                    // 4- compute the current ECEF position for this SV using corrected TX time | ||||
| //                    SV_clock_bias_s = SV_clock_drift_s + SV_relativistic_clock_corr_s - gps_ephemeris_iter->second.d_TGD; | ||||
| //                    TX_time_corrected_s = Tx_time - SV_clock_bias_s; | ||||
| //                    gps_ephemeris_iter->second.satellitePosition(TX_time_corrected_s); | ||||
| // | ||||
| //                    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 + SV_clock_bias_s*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; | ||||
| // | ||||
| //                    // compute the UTC time for this SV (just to print the asociated UTC timestamp) | ||||
| //                    GPS_week = gps_ephemeris_iter->second.i_GPS_week; | ||||
| //                    utc = gps_utc_model.utc_time(TX_time_corrected_s, GPS_week); | ||||
| // | ||||
| //                } | ||||
| //            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++; | ||||
| //        } | ||||
| // | ||||
| //    // ******************************************************************************** | ||||
| //    // ****** SOLVE LEAST SQUARES****************************************************** | ||||
| //    // ******************************************************************************** | ||||
| //    d_valid_observations = valid_obs; | ||||
| //    DLOG(INFO) << "(new)PVT: valid observations=" << valid_obs << std::endl; | ||||
| // | ||||
| //    if (valid_obs >= 4) | ||||
| //        { | ||||
| //            arma::vec mypos; | ||||
| //            DLOG(INFO) << "satpos=" << satpos << std::endl; | ||||
| //            DLOG(INFO) << "obs="<< obs << 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); | ||||
| //            //ToDo: Find an Observables/PVT random bug with some satellite configurations that gives an erratic PVT solution (i.e. height>50 km) | ||||
| //            if (d_height_m>50000) | ||||
| //            { | ||||
| //            	b_valid_position=false; | ||||
| //            	return false; //erratic PVT | ||||
| //            } | ||||
| //            // Compute UTC time and print PVT solution | ||||
| //            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 | ||||
| //            boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); | ||||
| //            d_position_UTC_time = p_time; | ||||
| // | ||||
| //            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; | ||||
| // | ||||
| //            // ###### Compute DOPs ######## | ||||
| // | ||||
| //            // 1- Rotation matrix from ECEF coordinates to ENU coordinates | ||||
| //            // ref: http://www.navipedia.net/index.php/Transformations_between_ECEF_and_ENU_coordinates | ||||
| // | ||||
| //			arma::mat F=arma::zeros(3,3); | ||||
| //			F(0,0)=-sin(GPS_TWO_PI*(d_longitude_d/360.0)); | ||||
| //			F(0,1)=-sin(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0)); | ||||
| //			F(0,2)=cos(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0)); | ||||
| // | ||||
| //			F(1,0)=cos((GPS_TWO_PI*d_longitude_d)/360.0); | ||||
| //			F(1,1)=-sin((GPS_TWO_PI*d_latitude_d)/360.0)*sin((GPS_TWO_PI*d_longitude_d)/360.0); | ||||
| //			F(1,2)=cos((GPS_TWO_PI*d_latitude_d/360.0))*sin((GPS_TWO_PI*d_longitude_d)/360.0); | ||||
| // | ||||
| //			F(2,0)=0; | ||||
| //			F(2,1)=cos((GPS_TWO_PI*d_latitude_d)/360.0); | ||||
| //			F(2,2)=sin((GPS_TWO_PI*d_latitude_d/360.0)); | ||||
| // | ||||
| //			// 2- Apply the rotation to the latest covariance matrix (available in ECEF from LS) | ||||
| // | ||||
| //			arma::mat Q_ECEF=d_Q.submat( 0, 0, 2, 2); | ||||
| //			arma::mat DOP_ENU=arma::zeros(3,3); | ||||
| // | ||||
| //		    try | ||||
| //		    { | ||||
| //		    	DOP_ENU=arma::htrans(F)*Q_ECEF*F; | ||||
| //				d_GDOP  = sqrt(arma::trace(DOP_ENU));                 // Geometric DOP | ||||
| //				d_PDOP  = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1) + DOP_ENU(2,2));       // PDOP | ||||
| //				d_HDOP  = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1));                // HDOP | ||||
| //				d_VDOP  = sqrt(DOP_ENU(2,2));                         // VDOP | ||||
| //				d_TDOP  = sqrt(d_Q(3,3));	// TDOP | ||||
| //		    }catch(std::exception& ex) | ||||
| //		    { | ||||
| //				d_GDOP  = -1;                 // Geometric DOP | ||||
| //				d_PDOP  = -1;       // PDOP | ||||
| //				d_HDOP  = -1;               // HDOP | ||||
| //				d_VDOP  = -1;                        // VDOP | ||||
| //				d_TDOP  = -1;	// TDOP | ||||
| //		    } | ||||
| // | ||||
| //            // ######## 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; | ||||
| //        } | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
|  | ||||
| void galileo_e1_ls_pvt::cart2geo(double X, double Y, double Z, int elipsoid_selection) | ||||
| { | ||||
|     /* Conversion of Cartesian coordinates (X,Y,Z) to geographical | ||||
|      coordinates (latitude, longitude, h) on a selected reference ellipsoid. | ||||
|  | ||||
|        Choices of Reference Ellipsoid for Geographical Coordinates | ||||
|                  0. International Ellipsoid 1924 | ||||
|                  1. International Ellipsoid 1967 | ||||
|                  2. World Geodetic System 1972 | ||||
|                  3. Geodetic Reference System 1980 | ||||
|                  4. World Geodetic System 1984 | ||||
|      */ | ||||
|  | ||||
|     const double a[5] = {6378388, 6378160, 6378135, 6378137, 6378137}; | ||||
|     const double f[5] = {1/297, 1/298.247, 1/298.26, 1/298.257222101, 1/298.257223563}; | ||||
|  | ||||
|     double lambda  = atan2(Y,X); | ||||
|     double ex2 = (2 - f[elipsoid_selection]) * f[elipsoid_selection] / ((1 - f[elipsoid_selection])*(1 -f[elipsoid_selection])); | ||||
|     double c = a[elipsoid_selection] * sqrt(1+ex2); | ||||
|     double phi = atan(Z / ((sqrt(X*X + Y*Y)*(1 - (2 - f[elipsoid_selection])) * f[elipsoid_selection]))); | ||||
|  | ||||
|     double h = 0.1; | ||||
|     double oldh = 0; | ||||
|     double N; | ||||
|     int iterations = 0; | ||||
|     do | ||||
|         { | ||||
|             oldh = h; | ||||
|             N = c / sqrt(1 + ex2 * (cos(phi) * cos(phi))); | ||||
|             phi = atan(Z / ((sqrt(X*X + Y*Y) * (1 - (2 -f[elipsoid_selection]) * f[elipsoid_selection] *N / (N + h) )))); | ||||
|             h = sqrt(X*X + Y*Y) / cos(phi) - N; | ||||
|             iterations = iterations + 1; | ||||
|             if (iterations > 100) | ||||
|                 { | ||||
|                     std::cout << "Failed to approximate h with desired precision. h-oldh= " << h - oldh << std::endl; | ||||
|                     break; | ||||
|                 } | ||||
|         } | ||||
|     while (abs(h - oldh) > 1.0e-12); | ||||
|     d_latitude_d = phi * 180.0 / GPS_PI; | ||||
|     d_longitude_d = lambda * 180 / GPS_PI; | ||||
|     d_height_m = h; | ||||
| } | ||||
|  | ||||
|  | ||||
| void galileo_e1_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z) | ||||
| { | ||||
|     /* Subroutine to calculate geodetic coordinates latitude, longitude, | ||||
| 	height given Cartesian coordinates X,Y,Z, and reference ellipsoid | ||||
| 	values semi-major axis (a) and the inverse of flattening (finv). | ||||
|  | ||||
| 	 The output units of angular quantities will be in decimal degrees | ||||
| 	  (15.5 degrees not 15 deg 30 min). The output units of h will be the | ||||
| 	  same as the units of X,Y,Z,a. | ||||
|  | ||||
| 	   Inputs: | ||||
| 	       a           - semi-major axis of the reference ellipsoid | ||||
| 	       finv        - inverse of flattening of the reference ellipsoid | ||||
| 	       X,Y,Z       - Cartesian coordinates | ||||
|  | ||||
| 	   Outputs: | ||||
| 	       dphi        - latitude | ||||
| 	       dlambda     - longitude | ||||
| 	       h           - height above reference ellipsoid | ||||
|  | ||||
| 	       Based in a Matlab function by Kai Borre | ||||
|      */ | ||||
|  | ||||
|     *h = 0; | ||||
|     double tolsq = 1.e-10;  // tolerance to accept convergence | ||||
|     int maxit = 10;         // max number of iterations | ||||
|     double rtd =  180/GPS_PI; | ||||
|  | ||||
|     // compute square of eccentricity | ||||
|     double esq; | ||||
|     if (finv < 1.0E-20) | ||||
|         { | ||||
|             esq = 0; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             esq = (2 - 1/finv) / finv; | ||||
|         } | ||||
|  | ||||
|     // first guess | ||||
|  | ||||
|     double P = sqrt(X*X + Y*Y); // P is distance from spin axis | ||||
|     //direct calculation of longitude | ||||
|     if (P > 1.0E-20) | ||||
|         { | ||||
|             *dlambda = atan2(Y,X) * rtd; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             *dlambda = 0; | ||||
|         } | ||||
|     // correct longitude bound | ||||
|     if (*dlambda < 0) | ||||
|         { | ||||
|             *dlambda = *dlambda + 360.0; | ||||
|         } | ||||
|     double r = sqrt(P*P + Z*Z); // r is distance from origin (0,0,0) | ||||
|  | ||||
|     double sinphi; | ||||
|     if (r > 1.0E-20) | ||||
|         { | ||||
|             sinphi = Z/r; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             sinphi = 0; | ||||
|         } | ||||
|     *dphi = asin(sinphi); | ||||
|  | ||||
|     // initial value of height  =  distance from origin minus | ||||
|     // approximate distance from origin to surface of ellipsoid | ||||
|     if (r < 1.0E-20) | ||||
|         { | ||||
|             *h = 0; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|     *h = r - a*(1-sinphi*sinphi/finv); | ||||
|  | ||||
|     // iterate | ||||
|     double cosphi; | ||||
|     double N_phi; | ||||
|     double dP; | ||||
|     double dZ; | ||||
|     double oneesq = 1 - esq; | ||||
|  | ||||
|     for (int i=0; i<maxit; i++) | ||||
|         { | ||||
|             sinphi  = sin(*dphi); | ||||
|             cosphi  = cos(*dphi); | ||||
|  | ||||
|             //     compute radius of curvature in prime vertical direction | ||||
|             N_phi   = a / sqrt(1 - esq*sinphi*sinphi); | ||||
|  | ||||
|             //    compute residuals in P and Z | ||||
|             dP      = P - (N_phi + (*h)) * cosphi; | ||||
|             dZ      = Z - (N_phi*oneesq + (*h)) * sinphi; | ||||
|  | ||||
|             //    update height and latitude | ||||
|             *h       = *h + (sinphi*dZ + cosphi*dP); | ||||
|             *dphi    = *dphi + (cosphi*dZ - sinphi*dP)/(N_phi + (*h)); | ||||
|  | ||||
|             //     test for convergence | ||||
|             if ((dP*dP + dZ*dZ) < tolsq) | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
|             if (i == (maxit-1)) | ||||
|                 { | ||||
|                     DLOG(INFO) << "The computation of geodetic coordinates did not converge"; | ||||
|                 } | ||||
|         } | ||||
|     *dphi = (*dphi) * rtd; | ||||
| } | ||||
|  | ||||
|  | ||||
| void galileo_e1_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx) | ||||
| { | ||||
|     /*  Transformation of vector dx into topocentric coordinate | ||||
| 	system with origin at x | ||||
| 	   Inputs: | ||||
| 	      x           - vector origin coordinates (in ECEF system [X; Y; Z;]) | ||||
| 	      dx          - vector ([dX; dY; dZ;]). | ||||
|  | ||||
| 	   Outputs: | ||||
| 	      D           - vector length. Units like the input | ||||
| 	      Az          - azimuth from north positive clockwise, degrees | ||||
| 	      El          - elevation angle, degrees | ||||
|  | ||||
| 	      Based on a Matlab function by Kai Borre | ||||
|      */ | ||||
|  | ||||
|     double lambda; | ||||
|     double phi; | ||||
|     double h; | ||||
|     double dtr = GPS_PI/180.0; | ||||
|     double a = 6378137.0;        // semi-major axis of the reference ellipsoid WGS-84 | ||||
|     double finv = 298.257223563; // inverse of flattening of the reference ellipsoid WGS-84 | ||||
|  | ||||
|     // Transform x into geodetic coordinates | ||||
|     togeod(&phi, &lambda, &h, a, finv, x(0), x(1), x(2)); | ||||
|  | ||||
|     double cl  = cos(lambda * dtr); | ||||
|     double sl  = sin(lambda * dtr); | ||||
|     double cb  = cos(phi * dtr); | ||||
|     double sb  = sin(phi * dtr); | ||||
|  | ||||
|     arma::mat F = arma::zeros(3,3); | ||||
|  | ||||
|     F(0,0) = -sl; | ||||
|     F(0,1) = -sb*cl; | ||||
|     F(0,2) = cb*cl; | ||||
|  | ||||
|     F(1,0) = cl; | ||||
|     F(1,1) = -sb*sl; | ||||
|     F(1,2) = cb*sl; | ||||
|  | ||||
|     F(2,0) = 0; | ||||
|     F(2,1) = cb; | ||||
|     F(2,2) = sb; | ||||
|  | ||||
|     arma::vec local_vector; | ||||
|  | ||||
|     local_vector = arma::htrans(F) * dx; | ||||
|  | ||||
|     double E = local_vector(0); | ||||
|     double N = local_vector(1); | ||||
|     double U = local_vector(2); | ||||
|  | ||||
|     double hor_dis; | ||||
|     hor_dis = sqrt(E*E + N*N); | ||||
|  | ||||
|     if (hor_dis < 1.0E-20) | ||||
|         { | ||||
|             *Az = 0; | ||||
|             *El = 90; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             *Az = atan2(E, N)/dtr; | ||||
|             *El = atan2(U, hor_dis)/dtr; | ||||
|         } | ||||
|  | ||||
|     if (*Az < 0) | ||||
|         { | ||||
|             *Az = *Az + 360.0; | ||||
|         } | ||||
|  | ||||
|     *D   = sqrt(dx(0)*dx(0) + dx(1)*dx(1) + dx(2)*dx(2)); | ||||
| } | ||||
							
								
								
									
										147
									
								
								src/algorithms/PVT/libs/galileo_e1_ls_pvt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/algorithms/PVT/libs/galileo_e1_ls_pvt.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_ls_pvt.h | ||||
|  * \brief Interface of a Least Squares Position, Velocity, and Time (PVT) | ||||
|  * solver, based on K.Borre's Matlab receiver. | ||||
|  * \author Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2012  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
| #ifndef GNSS_SDR_GALILEO_E1_LS_PVT_H_ | ||||
| #define GNSS_SDR_GALILEO_E1_LS_PVT_H_ | ||||
|  | ||||
| #include <fstream> | ||||
| #include <string> | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <sys/time.h> | ||||
| #include <time.h> | ||||
| //#include <math.h> | ||||
| #include <cmath> | ||||
| #include <map> | ||||
| #include <algorithm> | ||||
| #include "GPS_L1_CA.h" | ||||
| #include "galileo_navigation_message.h" | ||||
| #include "armadillo" | ||||
| #include "boost/date_time/posix_time/posix_time.hpp" | ||||
|  | ||||
| #include "gnss_synchro.h" | ||||
| #include "galileo_ephemeris.h" | ||||
| #include "galileo_utc_model.h" | ||||
| #define PVT_MAX_CHANNELS 24 | ||||
|  | ||||
| /*! | ||||
|  * \brief This class implements a simple PVT Least Squares solution | ||||
|  */ | ||||
| class galileo_e1_ls_pvt | ||||
| { | ||||
| private: | ||||
|     arma::vec leastSquarePos(arma::mat satpos, arma::vec obs, arma::mat w); | ||||
|     arma::vec rotateSatellite(double traveltime, arma::vec X_sat); | ||||
|     void topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx); | ||||
|     void togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z); | ||||
| public: | ||||
|     int d_nchannels;      //! Number of available channels for positioning | ||||
|     int d_valid_observations; //! Number of valid pseudorange observations (valid satellites) | ||||
|     int d_visible_satellites_IDs[PVT_MAX_CHANNELS]; //! Array with the IDs of the valid satellites | ||||
|     double d_visible_satellites_El[PVT_MAX_CHANNELS]; //! Array with the LOS Elevation of the valid satellites | ||||
|     double d_visible_satellites_Az[PVT_MAX_CHANNELS]; //! Array with the LOS Azimuth of the valid satellites | ||||
|     double d_visible_satellites_Distance[PVT_MAX_CHANNELS]; //! Array with the LOS Distance of the valid satellites | ||||
|     double d_visible_satellites_CN0_dB[PVT_MAX_CHANNELS]; //! Array with the IDs of the valid satellites | ||||
|  | ||||
|     Galileo_Navigation_Message* d_ephemeris; | ||||
|  | ||||
|     // new ephemeris storage | ||||
|     std::map<int,Galileo_Ephemeris> galileo_ephemeris_map; | ||||
|     // new utc_model storage | ||||
|     Galileo_Utc_Model galileo_utc_model; | ||||
|     // new iono storage | ||||
|     Galileo_Iono galileo_iono; | ||||
|  | ||||
|     //double d_GPS_current_time; | ||||
|     double d_galileo_current_time; | ||||
|     boost::posix_time::ptime d_position_UTC_time; | ||||
|  | ||||
|     bool b_valid_position; | ||||
|  | ||||
|     double d_latitude_d;  //! Latitude in degrees | ||||
|     double d_longitude_d; //! Longitude in degrees | ||||
|     double d_height_m;    //! Height [m] | ||||
|  | ||||
|     //averaging | ||||
|     std::deque<double> d_hist_latitude_d; | ||||
|     std::deque<double> d_hist_longitude_d; | ||||
|     std::deque<double> d_hist_height_m; | ||||
|     int d_averaging_depth;    //! Length of averaging window | ||||
|  | ||||
|     double d_avg_latitude_d;  //! Averaged latitude in degrees | ||||
|     double d_avg_longitude_d; //! Averaged longitude in degrees | ||||
|     double d_avg_height_m;    //! Averaged height [m] | ||||
|  | ||||
|     double d_x_m; | ||||
|     double d_y_m; | ||||
|     double d_z_m; | ||||
|  | ||||
|     // DOP estimations | ||||
|  | ||||
|     arma::mat d_Q; | ||||
|     double d_GDOP; | ||||
|     double d_PDOP; | ||||
|     double d_HDOP; | ||||
|     double d_VDOP; | ||||
|     double d_TDOP; | ||||
|  | ||||
|     bool d_flag_dump_enabled; | ||||
|     bool d_flag_averaging; | ||||
|  | ||||
|     std::string d_dump_filename; | ||||
|     std::ofstream d_dump_file; | ||||
|  | ||||
|     void set_averaging_depth(int depth); | ||||
|  | ||||
|     galileo_e1_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file); | ||||
|     ~galileo_e1_ls_pvt(); | ||||
|  | ||||
|     bool get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map, double galileo_current_time, bool flag_averaging); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Conversion of Cartesian coordinates (X,Y,Z) to geographical | ||||
|      * coordinates (d_latitude_d, d_longitude_d, d_height_m) on a selected reference ellipsoid. | ||||
|      * | ||||
|      * \param[in] X [m] Cartesian coordinate | ||||
|      * \param[in] Y [m] Cartesian coordinate | ||||
|      * \param[in] Z [m] Cartesian coordinate | ||||
|      * \param[in] elipsoid_selection. Choices of Reference Ellipsoid for Geographical Coordinates: | ||||
|      * 0 - International Ellipsoid 1924. | ||||
|      * 1 - International Ellipsoid 1967. | ||||
|      * 2 - World Geodetic System 1972. | ||||
|      * 3 - Geodetic Reference System 1980. | ||||
|      * 4 - World Geodetic System 1984. | ||||
|      * | ||||
|      */ | ||||
|     void cart2geo(double X, double Y, double Z, int elipsoid_selection); | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -72,6 +72,7 @@ | ||||
| #include "gps_l1_ca_observables.h" | ||||
| #include "galileo_e1_observables.h" | ||||
| #include "gps_l1_ca_pvt.h" | ||||
| #include "galileo_e1_pvt.h" | ||||
|  | ||||
| #if GN3S_DRIVER | ||||
| 	#include "gn3s_signal_source.h" | ||||
| @@ -436,7 +437,11 @@ GNSSBlockInterface* GNSSBlockFactory::GetBlock( | ||||
|             block = new GpsL1CaPvt(configuration, role, in_streams, | ||||
|                     out_streams, queue); | ||||
|         } | ||||
|  | ||||
|     else if (implementation.compare("GALILEO_E1_PVT") == 0) | ||||
|         { | ||||
|             block = new GalileoE1Pvt(configuration, role, in_streams, | ||||
|                     out_streams, queue); | ||||
|         } | ||||
|     // OUTPUT FILTERS -------------------------------------------------------------- | ||||
|     else if (implementation.compare("Null_Sink_Output_Filter") == 0) | ||||
|         { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas