mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Added PVT solver utility in /src/utils/gpstk/gnsspvt that uses the GpsTk satellite navigation library. It can be used to process GNSS-SDR RINEX files.
git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@288 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
		
							
								
								
									
										49
									
								
								src/utils/gpstk/gnsspvt/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/utils/gpstk/gnsspvt/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | # CMAKE for GPSTK by Javier Arribas 2012 | ||||||
|  | cmake_minimum_required (VERSION 2.6) | ||||||
|  | project (gnsspvt_project) | ||||||
|  |  | ||||||
|  | include_directories(${gnsspvt_project_SOURCE_DIR}/src) | ||||||
|  |  | ||||||
|  | add_library (kml_printer_gpstk ${gnsspvt_project_SOURCE_DIR}/src/kml_printer_gpstk.cpp) | ||||||
|  | add_executable(gnsspvt ${gnsspvt_project_SOURCE_DIR}/src/gnsspvt.cpp) | ||||||
|  |  | ||||||
|  | target_link_libraries (gnsspvt kml_printer_gpstk) | ||||||
|  |  | ||||||
|  | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules/") | ||||||
|  |  | ||||||
|  | find_package(GPSTK REQUIRED) | ||||||
|  |  | ||||||
|  | if ( NOT GPSTK_FOUND ) | ||||||
|  |   message(FATAL_ERROR "GPSTK library not found!") | ||||||
|  | endif( NOT GPSTK_FOUND ) | ||||||
|  |  | ||||||
|  | find_package(GLOG REQUIRED) | ||||||
|  | if ( NOT GLOG_FOUND ) | ||||||
|  |   message(FATAL_ERROR "GLOG library not found!") | ||||||
|  | endif( NOT GLOG_FOUND ) | ||||||
|  |  | ||||||
|  | include_directories(${GLOG_INCLUDE_DIRS}) | ||||||
|  |  | ||||||
|  | # IMPORTANT NOTICE: The GPSTK linking order is critical. First it is required to link agains libprocframe to avoid vtable errors | ||||||
|  | include_directories(${GPSTK_INCLUDE_DIR}/gpstk ${GEOMATICS_INCLUDE_DIR} ${PROCFRAME_INCLUDE_DIR} ${VDRAW_INCLUDE_DIR} ${VPLOT_INCLUDE_DIR} ${RXIO_INCLUDE_DIR}) | ||||||
|  | # set(LIBS ${LIBS} ${GPSTK_LIBRARIES} ${GEOMATICS_LIBRARIES} ${VDRAW_LIBRARIES} ${VPLOT_LIBRARIES} ${RXIO_LIBRARIES}) | ||||||
|  | set(LIBS ${LIBS} ${PROCFRAME_LIBRARIES} ${GPSTK_LIBRARIES} ${GEOMATICS_LIBRARIES} ${GLOG_LIBRARIES}) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | target_link_libraries(gnsspvt ${LIBS}) | ||||||
|  |  | ||||||
|  | message(STATUS "GPSTK_INCLUDE_DIR="${GLOG_LIBRARIES}) | ||||||
|  | #message(STATUS "GPSTK_LIBRARIES=${GPSTK_LIBRARIES}") | ||||||
|  | #message(STATUS "LIBS=${LIBS}") | ||||||
|  |  | ||||||
|  | # debug info: print all variables | ||||||
|  | #get_cmake_property(_variableNames VARIABLES) | ||||||
|  | #foreach (_variableName ${_variableNames}) | ||||||
|  | #    message(STATUS "${_variableName}=${${_variableName}}") | ||||||
|  | #endforeach() | ||||||
|  |  | ||||||
|  | #get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) | ||||||
|  | #foreach(dir ${dirs}) | ||||||
|  | #  message(STATUS "INCLUDE_DIRECTORIES='${dir}'") | ||||||
|  | #endforeach() | ||||||
|  |  | ||||||
							
								
								
									
										103
									
								
								src/utils/gpstk/gnsspvt/CMakeModules/FindGLOG.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/utils/gpstk/gnsspvt/CMakeModules/FindGLOG.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | # - Try to find the Google Glog library | ||||||
|  | # | ||||||
|  | # This module defines the following variables | ||||||
|  | # | ||||||
|  | # GLOG_FOUND - Was Glog found | ||||||
|  | # GLOG_INCLUDE_DIRS - the Glog include directories | ||||||
|  | # GLOG_LIBRARIES - Link to this | ||||||
|  | # | ||||||
|  | # This module accepts the following variables | ||||||
|  | # | ||||||
|  | # GLOG_ROOT - Can be set to Glog install path or Windows build path | ||||||
|  | # | ||||||
|  | #============================================================================= | ||||||
|  | # FindGlog.cmake, adapted from FindBullet.cmake which has the following | ||||||
|  | # copyright - | ||||||
|  | #----------------------------------------------------------------------------- | ||||||
|  | # Copyright 2009 Kitware, Inc. | ||||||
|  | # Copyright 2009 Philip Lowman <philip@yhbt.com> | ||||||
|  | # | ||||||
|  | # Distributed under the OSI-approved BSD License (the "License"); | ||||||
|  | # see accompanying file Copyright.txt for details. | ||||||
|  | # | ||||||
|  | # This software is distributed WITHOUT ANY WARRANTY; without even the | ||||||
|  | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||||
|  | # See the License for more information. | ||||||
|  | #============================================================================= | ||||||
|  | # (To distribute this file outside of CMake, substitute the full | ||||||
|  | # License text for the above reference.) | ||||||
|  |  | ||||||
|  | if (NOT DEFINED GLOG_ROOT) | ||||||
|  | set (GLOG_ROOT /usr /usr/local) | ||||||
|  | endif (NOT DEFINED GLOG_ROOT) | ||||||
|  |  | ||||||
|  | if(MSVC) | ||||||
|  | set(LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/Release) | ||||||
|  | else(MSVC) | ||||||
|  | set (LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/lib) | ||||||
|  | endif(MSVC) | ||||||
|  |  | ||||||
|  | macro(_FIND_GLOG_LIBRARIES _var) | ||||||
|  | find_library(${_var} | ||||||
|  | NAMES | ||||||
|  | ${ARGN} | ||||||
|  | PATHS | ||||||
|  | ${LIB_PATHS} | ||||||
|  | PATH_SUFFIXES lib | ||||||
|  | ) | ||||||
|  | mark_as_advanced(${_var}) | ||||||
|  | endmacro() | ||||||
|  |  | ||||||
|  | macro(_GLOG_APPEND_LIBRARIES _list _release) | ||||||
|  | set(_debug ${_release}_DEBUG) | ||||||
|  | if(${_debug}) | ||||||
|  | set(${_list} ${${_list}} optimized ${${_release}} debug ${${_debug}}) | ||||||
|  | else() | ||||||
|  | set(${_list} ${${_list}} ${${_release}}) | ||||||
|  | endif() | ||||||
|  | endmacro() | ||||||
|  |  | ||||||
|  | if(MSVC) | ||||||
|  | find_path(GLOG_INCLUDE_DIR NAMES raw_logging.h | ||||||
|  | PATHS | ||||||
|  | ${GLOG_ROOT}/src/windows | ||||||
|  | ${GLOG_ROOT}/src/windows/glog | ||||||
|  | ) | ||||||
|  | else(MSVC) | ||||||
|  | # Linux/OS X builds | ||||||
|  | find_path(GLOG_INCLUDE_DIR NAMES raw_logging.h | ||||||
|  | PATHS | ||||||
|  | ${GLOG_ROOT}/include/glog | ||||||
|  | ) | ||||||
|  | endif(MSVC) | ||||||
|  |  | ||||||
|  | # Find the libraries | ||||||
|  | if(MSVC) | ||||||
|  | _FIND_GLOG_LIBRARIES(GLOG_LIBRARIES libglog.lib) | ||||||
|  | else(MSVC) | ||||||
|  | # Linux/OS X builds | ||||||
|  | _FIND_GLOG_LIBRARIES(GLOG_LIBRARIES libglog.so) | ||||||
|  | endif(MSVC) | ||||||
|  |  | ||||||
|  | message("glog library = " ${GLOG_LIBRARIES}) | ||||||
|  |  | ||||||
|  | # handle the QUIETLY and REQUIRED arguments and set GLOG_FOUND to TRUE if | ||||||
|  | # all listed variables are TRUE | ||||||
|  | include("${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake") | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Glog DEFAULT_MSG | ||||||
|  | GLOG_LIBRARIES) | ||||||
|  |  | ||||||
|  | if(MSVC) | ||||||
|  | string(REGEX REPLACE "/glog$" "" VAR_WITHOUT ${GLOG_INCLUDE_DIR}) | ||||||
|  | string(REGEX REPLACE "/windows$" "" VAR_WITHOUT ${VAR_WITHOUT}) | ||||||
|  | set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS} "${VAR_WITHOUT}") | ||||||
|  | string(REGEX REPLACE "/libglog.lib" "" GLOG_LIBRARIES_DIR ${GLOG_LIBRARIES}) | ||||||
|  | else(MSVC) | ||||||
|  | # Linux/OS X builds | ||||||
|  | set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR}) | ||||||
|  | string(REGEX REPLACE "/libglog.so" "" GLOG_LIBRARIES_DIR ${GLOG_LIBRARIES}) | ||||||
|  | endif(MSVC) | ||||||
|  |  | ||||||
|  | if(GLOG_FOUND) | ||||||
|  | # _GLOG_APPEND_LIBRARIES(GLOG GLOG_LIBRARIES) | ||||||
|  | endif() | ||||||
							
								
								
									
										87
									
								
								src/utils/gpstk/gnsspvt/CMakeModules/FindGPSTK.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/utils/gpstk/gnsspvt/CMakeModules/FindGPSTK.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | |||||||
|  | # - Find gpstk library | ||||||
|  | # Find the native gpstk includes and library | ||||||
|  | # This module defines | ||||||
|  | #  GPSTK_INCLUDE_DIR, where to find tiff.h, etc. | ||||||
|  | #  GPSTK_LIBRARIES, libraries to link against to use GPSTK. | ||||||
|  | #  GPSTK_FOUND, If false, do not try to use GPSTK. | ||||||
|  | # also defined, but not for general use are | ||||||
|  | #  GPSTK_LIBRARY, where to find the GPSTK library. | ||||||
|  |  | ||||||
|  | FIND_PATH(GPSTK_INCLUDE_DIR gpstk/Matrix.hpp) | ||||||
|  | FIND_PATH(GEOMATICS_INCLUDE_DIR gpstk/random.hpp) | ||||||
|  | FIND_PATH(PROCFRAME_INCLUDE_DIR gpstk/SolverWMS.hpp) | ||||||
|  | FIND_PATH(VDRAW_INCLUDE_DIR gpstk/Layout.hpp) | ||||||
|  | FIND_PATH(VPLOT_INCLUDE_DIR gpstk/ScatterPlot.hpp) | ||||||
|  | FIND_PATH(RXIO_INCLUDE_DIR gpstk/EphReader.hpp) | ||||||
|  |  | ||||||
|  | SET(GPSTK_NAMES ${GPSTK_NAMES} gpstk libgpstk) | ||||||
|  | FIND_LIBRARY(GPSTK_LIBRARY NAMES ${GPSTK_NAMES} ) | ||||||
|  |  | ||||||
|  | SET(GEOMATICS_NAMES ${GEOMATICS_NAMES} geomatics libgeomatics) | ||||||
|  | FIND_LIBRARY(GEOMATICS_LIBRARY NAMES ${GEOMATICS_NAMES} ) | ||||||
|  |  | ||||||
|  | SET(PROCFRAME_NAMES ${PROCFRAME_NAMES} procframe libprocframe) | ||||||
|  | FIND_LIBRARY(PROCFRAME_LIBRARY NAMES ${PROCFRAME_NAMES} ) | ||||||
|  |  | ||||||
|  | SET(VDRAW_NAMES ${VDRAW_NAMES} vdraw libvdraw) | ||||||
|  | FIND_LIBRARY(VDRAW_LIBRARY NAMES ${VDRAW_NAMES} ) | ||||||
|  |  | ||||||
|  | SET(VPLOT_NAMES ${VPLOT_NAMES} vplot libvplot) | ||||||
|  | FIND_LIBRARY(VPLOT_LIBRARY NAMES ${VPLOT_NAMES} ) | ||||||
|  |  | ||||||
|  | SET(RXIO_NAMES ${RXIO_NAMES} rxio librxio) | ||||||
|  | FIND_LIBRARY(RXIO_LIBRARY NAMES ${RXIO_NAMES} ) | ||||||
|  |  | ||||||
|  | # handle the QUIETLY and REQUIRED arguments and set GPSTK_FOUND to TRUE if  | ||||||
|  | # all listed variables are TRUE | ||||||
|  | INCLUDE(FindPackageHandleStandardArgs) | ||||||
|  |  | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GPSTK  DEFAULT_MSG  GPSTK_LIBRARY  GPSTK_INCLUDE_DIR) | ||||||
|  |  | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GEOMATICS  DEFAULT_MSG  GEOMATICS_LIBRARY  GEOMATICS_INCLUDE_DIR) | ||||||
|  |  | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROCFRAME  DEFAULT_MSG  PROCFRAME_LIBRARY  PROCFRAME_INCLUDE_DIR) | ||||||
|  |  | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(VDRAW  DEFAULT_MSG  VDRAW_LIBRARY  VDRAW_INCLUDE_DIR) | ||||||
|  |  | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(VPLOT  DEFAULT_MSG  VPLOT_LIBRARY  VPLOT_INCLUDE_DIR) | ||||||
|  |  | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(RXIO  DEFAULT_MSG  RXIO_LIBRARY  RXIO_INCLUDE_DIR) | ||||||
|  |  | ||||||
|  | IF(GPSTK_FOUND) | ||||||
|  |   SET( GPSTK_LIBRARIES ${GPSTK_LIBRARY} ) | ||||||
|  | ENDIF(GPSTK_FOUND) | ||||||
|  |  | ||||||
|  | IF(GEOMATICS_FOUND) | ||||||
|  |   SET( GEOMATICS_LIBRARIES ${GEOMATICS_LIBRARY} ) | ||||||
|  | ENDIF(GEOMATICS_FOUND) | ||||||
|  |  | ||||||
|  | IF(PROCFRAME_FOUND) | ||||||
|  |   SET( PROCFRAME_LIBRARIES ${PROCFRAME_LIBRARY} ) | ||||||
|  | ENDIF(PROCFRAME_FOUND) | ||||||
|  |  | ||||||
|  | IF(VDRAW_FOUND) | ||||||
|  |   SET( VDRAW_LIBRARIES ${VDRAW_LIBRARY} ) | ||||||
|  | ENDIF(VDRAW_FOUND) | ||||||
|  |  | ||||||
|  | IF(VPLOT_FOUND) | ||||||
|  |   SET( VPLOT_LIBRARIES ${VPLOT_LIBRARY} ) | ||||||
|  | ENDIF(VPLOT_FOUND) | ||||||
|  |  | ||||||
|  | IF(RXIO_FOUND) | ||||||
|  |   SET( RXIO_LIBRARIES ${RXIO_LIBRARY} ) | ||||||
|  | ENDIF(RXIO_FOUND) | ||||||
|  |  | ||||||
|  | MARK_AS_ADVANCED(GPSTK_INCLUDE_DIR GPSTK_LIBRARY) | ||||||
|  |  | ||||||
|  | MARK_AS_ADVANCED(GEOMATICS_INCLUDE_DIR GEOMATICS_LIBRARY) | ||||||
|  |  | ||||||
|  | MARK_AS_ADVANCED(PROCFRAME_INCLUDE_DIR PROCFRAME_LIBRARY) | ||||||
|  |  | ||||||
|  | MARK_AS_ADVANCED(VDRAW_INCLUDE_DIR VDRAW_LIBRARY) | ||||||
|  |  | ||||||
|  | MARK_AS_ADVANCED(VPLOT_INCLUDE_DIR VPLOT_LIBRARY) | ||||||
|  |  | ||||||
|  | MARK_AS_ADVANCED(RXIO_INCLUDE_DIR RXIO_LIBRARY) | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										62
									
								
								src/utils/gpstk/gnsspvt/src/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/utils/gpstk/gnsspvt/src/README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | ABOUT GNSSPVT | ||||||
|  | ---------------------- | ||||||
|  | This program uses the high level GpsTk classes to implement a simple PVT solver | ||||||
|  | that uses RINEX files as an input. | ||||||
|  | The output is written both in the console and in a Google Earth KML file. | ||||||
|  |  | ||||||
|  | HOW TO BUILD GNSSPVT | ||||||
|  | ---------------------- | ||||||
|  |  | ||||||
|  | Installation in Ubuntu 11.04, 11.10, 12.04 (32 and 64 bits) | ||||||
|  | ----------------------------------------------------------- | ||||||
|  |  | ||||||
|  | - Install CMake through your OS's package manager or by some other means. | ||||||
|  |  | ||||||
|  | - Install GpsTk: | ||||||
|  |  | ||||||
|  |  The following procedure will build and install the GPSTk. | ||||||
|  |  | ||||||
|  |     Ensure that prerequisites such as jam have been installed. | ||||||
|  |     Download the GPSTk source distribution from http://www.gpstk.org/bin/view/Documentation/GPSTkDownloads | ||||||
|  |     Extract the GPSTk tarball. For example, using GNU tar | ||||||
|  |  | ||||||
|  |     tar xvzf gpstk.tar.gz | ||||||
|  |  | ||||||
|  |     Change into the gpstk/dev directory (if using Subversion) or the gpstk/ directory (if using the tarball)and type | ||||||
|  |  | ||||||
|  |     jam | ||||||
|  |  | ||||||
|  |     To build the source documentation using doxygen: | ||||||
|  |  | ||||||
|  |     doxygen  | ||||||
|  |  | ||||||
|  |     To install GPSTk as a system library in /usr/local, assume root privileges then execute | ||||||
|  |  | ||||||
|  |     jam install | ||||||
|  |  | ||||||
|  |     To install to a different directory, define the environment variable PREFIX to point to the root of the installation | ||||||
|  |      | ||||||
|  |  | ||||||
|  | - Download, unzip, configure, build and install glog, a Google's library that implements application-level logging: | ||||||
|  |  | ||||||
|  | $ wget http://google-glog.googlecode.com/files/glog-0.3.2.tar.gz  | ||||||
|  | $ tar xvfz glog-0.3.2.tar.gz  | ||||||
|  | $ cd  glog-0.3.2 | ||||||
|  | $ ./configure | ||||||
|  | $ make | ||||||
|  | $ sudo make install | ||||||
|  |  | ||||||
|  | - Go to GNSSPVT root directory and compile the gnsspvt: | ||||||
|  |  | ||||||
|  | $ cd gnss-sdr/src/utils/gpstk/gnsspvt/ | ||||||
|  | $ mkdir build | ||||||
|  | $ cd build | ||||||
|  | $ cmake ../ | ||||||
|  | $ make | ||||||
|  |  | ||||||
|  | If everything goes well, the executable file is available in the build directory. | ||||||
|  |  | ||||||
|  | USAGE | ||||||
|  | ---------------------- | ||||||
|  |  | ||||||
|  | ./gnsspvt -i path_to_rinex_observable_file -n path_to_rinex_navigation_file -k path_to_kml_output_file | ||||||
							
								
								
									
										593
									
								
								src/utils/gpstk/gnsspvt/src/gnsspvt.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										593
									
								
								src/utils/gpstk/gnsspvt/src/gnsspvt.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,593 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gnsspvt.cpp | ||||||
|  |  * \brief Adapted version of high level gpstk PVT solver to read RINEX files, | ||||||
|  |  *  compute the position, velocity and time solution, and write Google Earth KML output file. | ||||||
|  |  *  The input Observables and Navigation files can be RINEX 2.10 or RINEX 3.00. | ||||||
|  |  *  It is a modified version of the example5.cpp code provided in gpstk source code. | ||||||
|  |  * | ||||||
|  |  * \author Javier Arribas, 2012. 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/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | // Modified Example program Nro 5 for GPSTk | ||||||
|  | // This program shows how to use some high-level GPSTk classes | ||||||
|  |  | ||||||
|  |    // Basic input/output C++ class | ||||||
|  | #include <iostream> | ||||||
|  |  | ||||||
|  |    // Classes for handling observations RINEX files (data) | ||||||
|  | #include "gpstk/Rinex3ObsData.hpp" | ||||||
|  | #include "gpstk/Rinex3ObsStream.hpp" | ||||||
|  |  | ||||||
|  |    // Class to easily extract data from Rinex3ObsData objects | ||||||
|  | #include "gpstk/ExtractData.hpp" | ||||||
|  |  | ||||||
|  |    // Classes for handling satellite navigation parameters RINEX files | ||||||
|  |    // (Broadcast ephemerides) | ||||||
|  | #include "gpstk/Rinex3NavHeader.hpp" | ||||||
|  | #include "gpstk/Rinex3NavData.hpp" | ||||||
|  | #include "gpstk/Rinex3NavStream.hpp" | ||||||
|  |  | ||||||
|  |    // Class to store satellite broadcast navigation data | ||||||
|  | #include "gpstk/GPSEphemerisStore.hpp" | ||||||
|  |  | ||||||
|  |    // Class to model GPS data for a mobile receiver | ||||||
|  | #include "gpstk/ModeledPR.hpp" | ||||||
|  |  | ||||||
|  | #include "gpstk/GNSSconstants.hpp" | ||||||
|  | #include "gpstk/CommonTime.hpp" | ||||||
|  | #include "gpstk/SatID.hpp" | ||||||
|  | #include "gpstk/Matrix.hpp" | ||||||
|  | #include "gpstk/XvtStore.hpp" | ||||||
|  | #include "gpstk/TropModel.hpp" | ||||||
|  |  | ||||||
|  |    // Class to model the tropospheric delays | ||||||
|  | #include "gpstk/TropModel.hpp" | ||||||
|  |  | ||||||
|  |    // Classes to model ans store ionospheric delays | ||||||
|  | #include "gpstk/IonoModel.hpp" | ||||||
|  | #include "gpstk/IonoModelStore.hpp" | ||||||
|  |  | ||||||
|  |    // Class to solve the equations system using a Weighted Least Mean Square method | ||||||
|  | #include "gpstk/SolverWMS.hpp" | ||||||
|  |  | ||||||
|  |    // Class to compute the weights to be used for each satellite | ||||||
|  | #include "gpstk/MOPSWeight.hpp" | ||||||
|  |  | ||||||
|  |    // Basic framework for programs in the GPSTk. The 'process()' method MUST | ||||||
|  |    // be implemented | ||||||
|  | #include "gpstk/BasicFramework.hpp" | ||||||
|  |  | ||||||
|  | #include "gpstk/geometry.hpp"                   // DEG_TO_RAD | ||||||
|  |  | ||||||
|  |    // Time-class year-day-second | ||||||
|  | #include "gpstk/YDSTime.hpp" | ||||||
|  |  | ||||||
|  | #include "kml_printer_gpstk.h" | ||||||
|  |  | ||||||
|  | using namespace std; | ||||||
|  | using namespace gpstk; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    // A new class is declared that will handle program behaviour | ||||||
|  |    // This class inherits from BasicFramework | ||||||
|  | class gpstk_solver : public BasicFramework | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |  | ||||||
|  |       // Constructor declaration | ||||||
|  |    gpstk_solver(char* arg0); | ||||||
|  |    ~gpstk_solver(); | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |  | ||||||
|  |       // Method that will take care of processing | ||||||
|  |    virtual void process(); | ||||||
|  |  | ||||||
|  |       // Method that hold code to be run BEFORE processing | ||||||
|  |    virtual void spinUp(); | ||||||
|  |  | ||||||
|  |    virtual int Prepare( const CommonTime& Tr, | ||||||
|  |                            std::vector<SatID>& Satellite, | ||||||
|  |                            std::vector<double>& Pseudorange, | ||||||
|  |                            const XvtStore<SatID>& Eph ); | ||||||
|  |    virtual int Prepare2( const CommonTime& Tr, | ||||||
|  |                            const Vector<SatID>& Satellite, | ||||||
|  |                            const Vector<double>& Pseudorange, | ||||||
|  |                            const XvtStore<SatID>& Eph ); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |  | ||||||
|  |       // These field represent options at command line interface (CLI) | ||||||
|  |    CommandOptionWithArg dataFile; | ||||||
|  |    CommandOptionWithArg navFile; | ||||||
|  |    CommandOptionWithArg kmlFile; | ||||||
|  |  | ||||||
|  |    Kml_Printer_gpstk kml_printer; | ||||||
|  |  | ||||||
|  |       // If you want to share objects and variables among methods, you'd | ||||||
|  |       // better declare them here | ||||||
|  |    Rinex3ObsStream rObsFile;     // Object to read Rinex observation data files | ||||||
|  |    Rinex3ObsData rData;          // Object to store Rinex observation data | ||||||
|  |    Rinex3NavStream rNavFile;     // Object to read Rinex navigation data files | ||||||
|  |    Rinex3NavData rNavData;       // Object to store Rinex navigation data | ||||||
|  |    Rinex3NavHeader rNavHeader;   // Object to read the header of Rinex | ||||||
|  |                                  // navigation data files | ||||||
|  |    IonoModelStore ionoStore;     // Object to store ionospheric models | ||||||
|  |    GPSEphemerisStore bceStore;   // Object to store ephemeris | ||||||
|  |    ModeledPR modelPR;            // Declare a ModeledReferencePR object | ||||||
|  |    MOPSTropModel mopsTM;         // Declare a MOPSTropModel object | ||||||
|  |    ExtractData obsC1;            // Declare an ExtractData object | ||||||
|  |    int indexC1;                  // Index to "C1" observation | ||||||
|  |    bool useFormerPos;            // Flag indicating if we have an a priori | ||||||
|  |                                  // position | ||||||
|  |    Position formerPosition;      // Object to store the former position | ||||||
|  |    IonoModel ioModel;            // Declare a Ionospheric Model object | ||||||
|  |    SolverWMS solver;             // Declare an object to apply WMS method | ||||||
|  |    MOPSWeight mopsWeights;       // Object to compute satellites' weights | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    // Let's implement constructor details | ||||||
|  | gpstk_solver::gpstk_solver(char* arg0) | ||||||
|  |    : BasicFramework(arg0, "\nProgram to print the position solution in ECEF " | ||||||
|  |                            "and longitude, latitude, height, based in C1 and " | ||||||
|  |                            "given a RINEX observations file and a RINEX " | ||||||
|  |                            "broadcast navigation file.\n\n" | ||||||
|  |                            "The output is: \n" | ||||||
|  |                            "  Time(sec)  X(m)  Y(m) Z(m)  Lon(deg)  " | ||||||
|  |                            "  Lat(deg)  Height(m)\n"), | ||||||
|  |       // Option initialization. "true" means a mandatory option | ||||||
|  |    dataFile(CommandOption::stdType, 'i', "datainput", | ||||||
|  |               " [-i|--datainput]      Name of RINEX observations file.", true), | ||||||
|  |    navFile(CommandOption::stdType, 'n', "navinput", | ||||||
|  |         " [-n|--navinput]      Name of RINEX broadcast navigation file.", true), | ||||||
|  |    kmlFile(CommandOption::stdType, 'k', "kmloutput", | ||||||
|  |              " [-n|--navinput]      Name of KML output file.", true) | ||||||
|  | { | ||||||
|  |       // These options may appear just once at CLI | ||||||
|  |    dataFile.setMaxCount(1); | ||||||
|  |    navFile.setMaxCount(1); | ||||||
|  |    kmlFile.setMaxCount(1); | ||||||
|  | }  // End of constructor details | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |       /* Method to set an a priori position of receiver using | ||||||
|  |        * Bancroft's method. | ||||||
|  |        * | ||||||
|  |        * @param Tr            Time of observation | ||||||
|  |        * @param Satellite     std::vector of satellites in view | ||||||
|  |        * @param Pseudorange   std::vector of pseudoranges measured from | ||||||
|  |        *                      rover station to satellites | ||||||
|  |        * @param Eph           Satellites Ephemeris | ||||||
|  |        * | ||||||
|  |        * @return | ||||||
|  |        *  0 if OK | ||||||
|  |        *  -1 if problems arose | ||||||
|  |        */ | ||||||
|  |    int gpstk_solver::Prepare( const CommonTime& Tr, | ||||||
|  |                            std::vector<SatID>& Satellite, | ||||||
|  |                            std::vector<double>& Pseudorange, | ||||||
|  |                            const XvtStore<SatID>& Eph ) | ||||||
|  |    { | ||||||
|  |  | ||||||
|  |       Matrix<double> SVP; | ||||||
|  |       Bancroft Ban; | ||||||
|  |       Vector<double> vPos; | ||||||
|  |       PRSolution2 raimObj; | ||||||
|  |  | ||||||
|  |       try | ||||||
|  |       { | ||||||
|  | 	 cerr << "Tr=" <<Tr<<std::endl; | ||||||
|  |             for (std::vector<SatID>::iterator it = Satellite.begin() ; it != Satellite.end(); ++it) | ||||||
|  |             { | ||||||
|  |               cerr << "SatID=" << *it<<endl; | ||||||
|  | 	      cerr << "EphemerisStore Sat XYZ= " << bceStore.getXvt(*it,rData.time).x<<std::endl; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             for (std::vector<double>::iterator it = Pseudorange.begin() ; it != Pseudorange.end(); ++it) | ||||||
|  |             { | ||||||
|  |               cerr << "PseudoRanges=" << *it<<endl; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  | 	 //cerr << "Eph=" << Eph <<std::endl; | ||||||
|  | 	 //cerr << "SVP=" << SVP <<std::endl; | ||||||
|  |          raimObj.PrepareAutonomousSolution( Tr, | ||||||
|  |                                             Satellite, | ||||||
|  |                                             Pseudorange, | ||||||
|  |                                             Eph, | ||||||
|  |                                             SVP ); | ||||||
|  |  | ||||||
|  |          if( Ban.Compute(SVP, vPos) < 0 ) | ||||||
|  |          { | ||||||
|  | 	    cerr << "Error 1" <<std::endl; | ||||||
|  |             cerr << "SVP="<<SVP<<std::endl; | ||||||
|  | 	    cerr << "vPos=" << vPos <<std::endl; | ||||||
|  |             return -1; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |       catch(Exception &error) | ||||||
|  |       { | ||||||
|  |          cerr << "Excepción 1: "<<error; | ||||||
|  |          return -1; | ||||||
|  |       } | ||||||
|  |       cerr << "OK prepare"<<endl; | ||||||
|  |       return 1; | ||||||
|  |  | ||||||
|  |    }  // End of method 'ModeledPR::Prepare()' | ||||||
|  |  | ||||||
|  |       /* Method to set an a priori position of receiver using | ||||||
|  |        * Bancroft's method. | ||||||
|  |        * | ||||||
|  |        * @param Tr            Time of observation | ||||||
|  |        * @param Satellite     Vector of satellites in view | ||||||
|  |        * @param Pseudorange   Pseudoranges measured from rover station to | ||||||
|  |        *                      satellites | ||||||
|  |        * @param Eph           Satellites Ephemeris | ||||||
|  |        * | ||||||
|  |        * @return | ||||||
|  |        *  0 if OK | ||||||
|  |        *  -1 if problems arose | ||||||
|  |        */ | ||||||
|  |    int gpstk_solver::Prepare2( const CommonTime& Tr, | ||||||
|  |                            const Vector<SatID>& Satellite, | ||||||
|  |                            const Vector<double>& Pseudorange, | ||||||
|  |                            const XvtStore<SatID>& Eph ) | ||||||
|  |    { | ||||||
|  |  | ||||||
|  |       int i; | ||||||
|  |       std::vector<SatID> vSat; | ||||||
|  |       std::vector<double> vPR; | ||||||
|  |  | ||||||
|  |          // Convert from gpstk::Vector to std::vector | ||||||
|  |       for (i = 0; i < (int)Satellite.size(); i++) | ||||||
|  |       { | ||||||
|  |          vSat.push_back(Satellite[i]); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       for (i = 0; i < (int)Pseudorange.size(); i++) | ||||||
|  |       { | ||||||
|  |          vPR.push_back(Pseudorange[i]); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       return Prepare(Tr, vSat, vPR, Eph); | ||||||
|  |  | ||||||
|  |    }  // End of method 'ModeledPR::Prepare()' | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    // Method that will be executed AFTER initialization but BEFORE processing | ||||||
|  | void gpstk_solver::spinUp() | ||||||
|  | { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    //open KML output file | ||||||
|  |    if (kml_printer.set_headers(kmlFile.getValue()[0].c_str())!=true) | ||||||
|  |    { | ||||||
|  | 	   cerr << "Problem creating the kml file "<<kmlFile.getValue()[0].c_str(); | ||||||
|  | 	   exit (-1); | ||||||
|  |    } | ||||||
|  |       // From now on, some parts may look similar to 'example3.cpp' and | ||||||
|  |       // 'example4.cpp' | ||||||
|  |       // Activate failbit to enable exceptions | ||||||
|  |    rObsFile.exceptions(ios::failbit); | ||||||
|  |  | ||||||
|  |       // First, data RINEX reading object | ||||||
|  |    try | ||||||
|  |    { | ||||||
|  |       rObsFile.open(dataFile.getValue()[0].c_str(), std::ios::in); | ||||||
|  |    } | ||||||
|  |    catch(...) | ||||||
|  |    { | ||||||
|  |       cerr << "Problem opening file " << dataFile.getValue()[0].c_str() | ||||||
|  |            << endl; | ||||||
|  |       cerr << "Maybe it doesn't exist or you don't have proper read " | ||||||
|  |            << "permissions." << endl; | ||||||
|  |  | ||||||
|  |       exit (-1); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |       // We need to read the header of the observations file | ||||||
|  |    Rinex3ObsHeader roh; | ||||||
|  |    rObsFile >> roh; | ||||||
|  |  | ||||||
|  |       // We need the index pointing to C1-type observations | ||||||
|  |    try | ||||||
|  |    { | ||||||
|  |       indexC1 = roh.getObsIndex( "C1" ); | ||||||
|  |    } | ||||||
|  |    catch(...) | ||||||
|  |    { | ||||||
|  |       cerr << "The observation file doesn't have C1 pseudoranges." << endl; | ||||||
|  |       exit(1); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |       // Activate failbit to enable exceptions | ||||||
|  |    rNavFile.exceptions(ios::failbit); | ||||||
|  |  | ||||||
|  |       // Read nav file and store unique list of ephemerides | ||||||
|  |    try | ||||||
|  |    { | ||||||
|  |       rNavFile.open(navFile.getValue()[0].c_str(), std::ios::in); | ||||||
|  |    } | ||||||
|  |    catch(...) | ||||||
|  |    { | ||||||
|  |       cerr << "Problem opening file " << navFile.getValue()[0].c_str() << endl; | ||||||
|  |       cerr << "Maybe it doesn't exist or you don't have proper read " | ||||||
|  |            << "permissions." << endl; | ||||||
|  |  | ||||||
|  |       exit (-1); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |       // We will need to read ionospheric parameters (Klobuchar model) from | ||||||
|  |       // the file header | ||||||
|  |    rNavFile >> rNavHeader; | ||||||
|  |  | ||||||
|  |       // Let's feed the ionospheric model (Klobuchar type) from data in the | ||||||
|  |       // navigation (ephemeris) file header. First, we must check if there are | ||||||
|  |       // valid ionospheric correction parameters in the header | ||||||
|  |    if(rNavHeader.valid & Rinex3NavHeader::validIonoCorrGPS) | ||||||
|  |    { | ||||||
|  |          // Extract the Alpha and Beta parameters from the header | ||||||
|  |       double* ionAlpha = rNavHeader.mapIonoCorr["GPSA"].param; | ||||||
|  |       double* ionBeta  = rNavHeader.mapIonoCorr["GPSB"].param; | ||||||
|  |  | ||||||
|  |          // Feed the ionospheric model with the parameters | ||||||
|  |       ioModel.setModel(ionAlpha, ionBeta); | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       cerr << "WARNING: Navigation file " << navFile.getValue()[0].c_str() | ||||||
|  |            << " doesn't have valid ionospheric correction parameters." << endl; | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |       // WARNING-WARNING-WARNING: In this case, the same model will be used | ||||||
|  |       // for the full data span | ||||||
|  |    ionoStore.addIonoModel(CommonTime::BEGINNING_OF_TIME, ioModel); | ||||||
|  |  | ||||||
|  |       // Storing the ephemeris in "bceStore" | ||||||
|  |    while (rNavFile >> rNavData) | ||||||
|  | 	   { | ||||||
|  | 	   	   bceStore.addEphemeris(rNavData); | ||||||
|  | 	   	   rNavData.dump(cerr); | ||||||
|  | 	   	   cerr<<endl; | ||||||
|  | 	   } | ||||||
|  |  | ||||||
|  |       // Setting the criteria for looking up ephemeris | ||||||
|  |    bceStore.SearchPast();  // This is the default | ||||||
|  |  | ||||||
|  |       // This is set to true if the former computed positon will be used as | ||||||
|  |       // a priori position | ||||||
|  |    useFormerPos = false;   // At first, we don't have an a priori position | ||||||
|  |  | ||||||
|  |       // Prepare for printing later on | ||||||
|  |    cout << fixed << setprecision(8); | ||||||
|  |  | ||||||
|  | }  // End of gpstk_solver::spinUp() | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    // Method that will really process information | ||||||
|  | void gpstk_solver::process() | ||||||
|  | { | ||||||
|  |  | ||||||
|  |       // Let's read the observations RINEX, epoch by epoch | ||||||
|  |    while( rObsFile >> rData ) | ||||||
|  |    { | ||||||
|  |  | ||||||
|  |          // Begin usable data with enough number of satellites | ||||||
|  |       if( (rData.epochFlag == 0 || rData.epochFlag == 1) && | ||||||
|  |           (rData.numSVs > 3) ) | ||||||
|  |       { | ||||||
|  |  | ||||||
|  |             // Number of satellites with valid data in this epoch | ||||||
|  |          int validSats = 0; | ||||||
|  |          int prepareResult; | ||||||
|  |          double rxAltitude;  // Receiver altitude for tropospheric model | ||||||
|  |          double rxLatitude;  // Receiver latitude for tropospheric model | ||||||
|  |  | ||||||
|  |             // We need to extract C1 data from this epoch. Skip epoch if not | ||||||
|  |             // enough data (4 SV at least) is available | ||||||
|  |          if( obsC1.getData(rData, indexC1) < 4 ) | ||||||
|  |          { | ||||||
|  |                // The former position will not be valid next time | ||||||
|  |             useFormerPos = false; | ||||||
|  |             continue; | ||||||
|  |          } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             // If possible, use former position as a priori | ||||||
|  |          if( useFormerPos ) | ||||||
|  |          { | ||||||
|  |  | ||||||
|  |             prepareResult = modelPR.Prepare(formerPosition); | ||||||
|  |  | ||||||
|  |                // We need to seed this kind of tropospheric model with | ||||||
|  |                // receiver altitude | ||||||
|  |             rxAltitude = formerPosition.getAltitude(); | ||||||
|  |             rxLatitude = formerPosition.getGeodeticLatitude(); | ||||||
|  |  | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |                // Use Bancroft method is no a priori position is available | ||||||
|  |             cerr << "Bancroft method was used at epoch " | ||||||
|  |                  << static_cast<YDSTime>(rData.time).sod << endl; | ||||||
|  |  | ||||||
|  |             Prepare2( rData.time,obsC1.availableSV,obsC1.obsData,bceStore ); | ||||||
|  |             prepareResult = modelPR.Prepare( rData.time, | ||||||
|  |                                              obsC1.availableSV, | ||||||
|  |                                              obsC1.obsData, | ||||||
|  |                                              bceStore ); | ||||||
|  |  | ||||||
|  |                // We need to seed this kind of tropospheric model with | ||||||
|  |                // receiver altitude | ||||||
|  |             rxAltitude = modelPR.rxPos.getAltitude(); | ||||||
|  |             rxLatitude = modelPR.rxPos.getGeodeticLatitude(); | ||||||
|  |          } | ||||||
|  |  | ||||||
|  |             // If there were problems with Prepare(), skip this epoch | ||||||
|  |          if( prepareResult ) | ||||||
|  |          { | ||||||
|  |                // The former position will not be valid next time | ||||||
|  |             useFormerPos = false; | ||||||
|  |             continue; | ||||||
|  |          } | ||||||
|  |  | ||||||
|  |             // If there were no problems, let's feed the tropospheric model | ||||||
|  |          mopsTM.setReceiverHeight(rxAltitude); | ||||||
|  |          mopsTM.setReceiverLatitude(rxLatitude); | ||||||
|  |          mopsTM.setDayOfYear(static_cast<YDSTime>(rData.time).doy); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             // Now, let's compute the GPS model for our observable (C1) | ||||||
|  |          validSats = modelPR.Compute( rData.time, | ||||||
|  |                                       obsC1.availableSV, | ||||||
|  |                                       obsC1.obsData, | ||||||
|  |                                       bceStore, | ||||||
|  |                                       &mopsTM, | ||||||
|  |                                       &ionoStore ); | ||||||
|  |  | ||||||
|  |             // Only get into further computations if there are enough | ||||||
|  |             // satellites | ||||||
|  |          if( validSats >= 4 ) | ||||||
|  |          { | ||||||
|  |  | ||||||
|  |                // Now let's solve the navigation equations using the WMS method | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                   // First, compute the satellites' weights | ||||||
|  |                int goodSv = mopsWeights.getWeights( rData.time, | ||||||
|  |                                                     modelPR.availableSV, | ||||||
|  |                                                     bceStore, | ||||||
|  |                                                     modelPR.ionoCorrections, | ||||||
|  |                                                     modelPR.elevationSV, | ||||||
|  |                                                     modelPR.azimuthSV, | ||||||
|  |                                                     modelPR.rxPos ); | ||||||
|  |  | ||||||
|  |                   // Some minimum checking is in order | ||||||
|  |                if ( goodSv != (int)modelPR.prefitResiduals.size() ) continue; | ||||||
|  |  | ||||||
|  |                   // Then, solve the system | ||||||
|  |                solver.Compute( modelPR.prefitResiduals, | ||||||
|  |                                modelPR.geoMatrix, | ||||||
|  |                                mopsWeights.weightsVector ); | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |             catch( InvalidSolver& e ) | ||||||
|  |             { | ||||||
|  |                cerr << "Couldn't solve equations system at epoch " | ||||||
|  |                     << static_cast<YDSTime>(rData.time).sod << endl; | ||||||
|  |                cerr << e << endl; | ||||||
|  |  | ||||||
|  |                   // The former position will not be valid next time | ||||||
|  |                useFormerPos = false; | ||||||
|  |                continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |                // With "solver", we got the difference vector between the | ||||||
|  |                // a priori position and the computed, 'real' position. Then, | ||||||
|  |                // let's convert the solution to a Position object | ||||||
|  |             Position solPos( (modelPR.rxPos.X() + solver.solution[0]), | ||||||
|  |                              (modelPR.rxPos.Y() + solver.solution[1]), | ||||||
|  |                              (modelPR.rxPos.Z() + solver.solution[2]) ); | ||||||
|  |  | ||||||
|  |                // Print results | ||||||
|  |             cout << static_cast<YDSTime>(rData.time).sod | ||||||
|  |                  << "   ";   // Output field #1 | ||||||
|  |             cout << "X="<<solPos.X() << ";   ";                // Output field #2 | ||||||
|  |             cout << "Y="<<solPos.Y() << ";   ";                // Output field #3 | ||||||
|  |             cout << "Z="<<solPos.Z() << ";   ";                // Output field #4 | ||||||
|  |             cout << solPos.longitude() << "   ";        // Output field #5 | ||||||
|  |             cout << solPos.geodeticLatitude() << "   "; // Output field #6 | ||||||
|  |             cout << solPos.height() << "   ";           // Output field #7 | ||||||
|  |             cout << endl; | ||||||
|  |  | ||||||
|  |             cout << "Geocentric Latitude="<< solPos.geocentricLatitude() << "   ";        // Output field #5 | ||||||
|  |             cout << endl; | ||||||
|  |  | ||||||
|  |             // write KML PVT line | ||||||
|  |             kml_printer.print_position(solPos); | ||||||
|  |  | ||||||
|  |             formerPosition = solPos; | ||||||
|  |  | ||||||
|  |                // Next time, former position will be used as a priori | ||||||
|  |             useFormerPos = true; | ||||||
|  |  | ||||||
|  |          }  // End of 'if( validSats >= 4 )' | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |                // The former position will not be valid next time | ||||||
|  |             useFormerPos = false; | ||||||
|  |          } | ||||||
|  |  | ||||||
|  |       }  // End of 'if( (rData.epochFlag == 0 || rData.epochFlag == 1) &&...' | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |             // The former position will not be valid next time | ||||||
|  |          useFormerPos = false; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |    }  // End of 'while( rObsFile >> rData )' | ||||||
|  |  | ||||||
|  |    return; | ||||||
|  |  | ||||||
|  | }  // End of 'gpstk_solver::process()' | ||||||
|  |  | ||||||
|  | gpstk_solver::~gpstk_solver() | ||||||
|  | { | ||||||
|  | 	kml_printer.close_file(); | ||||||
|  | } | ||||||
|  |    // Main function | ||||||
|  | int main(int argc, char* argv[]) | ||||||
|  | { | ||||||
|  |  | ||||||
|  |    try | ||||||
|  |    { | ||||||
|  |       gpstk_solver program(argv[0]); | ||||||
|  |       if (!program.initialize(argc, argv)) | ||||||
|  |          return 0; | ||||||
|  |       if (!program.run()) | ||||||
|  |          return 1; | ||||||
|  |  | ||||||
|  |       return 0; | ||||||
|  |    } | ||||||
|  |    catch(Exception& e) | ||||||
|  |    { | ||||||
|  |       cout << "Problem: " << e << endl; | ||||||
|  |       return 1; | ||||||
|  |    } | ||||||
|  |    catch(...) | ||||||
|  |    { | ||||||
|  |       cout << "Unknown error." << endl; | ||||||
|  |       return 1; | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    return 0; | ||||||
|  |  | ||||||
|  | }  // End of 'main()' | ||||||
							
								
								
									
										136
									
								
								src/utils/gpstk/gnsspvt/src/kml_printer_gpstk.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/utils/gpstk/gnsspvt/src/kml_printer_gpstk.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | |||||||
|  | /*! | ||||||
|  |  * \file kml_printer.cc | ||||||
|  |  * \brief Implementation of a class that prints PVT information to a kml file | ||||||
|  |  * for GPSTK data structures | ||||||
|  |  * \author Javier Arribas, 2012. 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 "kml_printer_gpstk.h" | ||||||
|  | #include <glog/log_severity.h> | ||||||
|  | #include <glog/logging.h> | ||||||
|  | #include <time.h> | ||||||
|  |  | ||||||
|  | bool Kml_Printer_gpstk::set_headers(std::string filename) | ||||||
|  | { | ||||||
|  |     time_t rawtime; | ||||||
|  |     struct tm * timeinfo; | ||||||
|  |     time ( &rawtime ); | ||||||
|  |     timeinfo = localtime ( &rawtime ); | ||||||
|  |     kml_file.open(filename.c_str()); | ||||||
|  |     if (kml_file.is_open()) | ||||||
|  |         { | ||||||
|  |             DLOG(INFO) << "KML printer writing on " << filename.c_str(); | ||||||
|  |             // Set iostream numeric format and precision | ||||||
|  |             kml_file.setf(kml_file.fixed,kml_file.floatfield); | ||||||
|  |             kml_file << std::setprecision(14); | ||||||
|  |             kml_file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl | ||||||
|  |                     << "<kml xmlns=\"http://www.opengis.net/kml/2.2\">" << std::endl | ||||||
|  |                     << "	<Document>" << std::endl | ||||||
|  |                     << "	<name>GNSS Track</name>" << std::endl | ||||||
|  |                     << "	<description>GNSS-SDR Receiver position log file created at " << asctime (timeinfo) | ||||||
|  |                     << "	</description>" << std::endl | ||||||
|  |                     << "<Style id=\"yellowLineGreenPoly\">" << std::endl | ||||||
|  |                     << " <LineStyle>" << std::endl | ||||||
|  |                     << " 	<color>7f00ffff</color>" << std::endl | ||||||
|  |                     << "		<width>1</width>" << std::endl | ||||||
|  |                     << "	</LineStyle>" << std::endl | ||||||
|  |                     << "<PolyStyle>" << std::endl | ||||||
|  |                     << "	<color>7f00ff00</color>" << std::endl | ||||||
|  |                     << "</PolyStyle>" << std::endl | ||||||
|  |                     << "</Style>" << std::endl | ||||||
|  |                     << "<Placemark>" << std::endl | ||||||
|  |                     << "<name>GNSS-SDR PVT</name>" << std::endl | ||||||
|  |                     << "<description>GNSS-SDR position log</description>" << std::endl | ||||||
|  |                     << "<styleUrl>#yellowLineGreenPoly</styleUrl>" << std::endl | ||||||
|  |                     << "<LineString>" << std::endl | ||||||
|  |                     << "<extrude>0</extrude>" << std::endl | ||||||
|  |                     << "<tessellate>1</tessellate>" << std::endl | ||||||
|  |                     << "<altitudeMode>absolute</altitudeMode>" << std::endl | ||||||
|  |                     << "<coordinates>" << std::endl; | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Kml_Printer_gpstk::print_position(gpstk::Position position) | ||||||
|  | { | ||||||
|  | 	double latitude; | ||||||
|  | 	double longitude; | ||||||
|  | 	double height; | ||||||
|  | 	latitude = position.geodeticLatitude(); | ||||||
|  | 	longitude = position.getLongitude(); | ||||||
|  | 	if (longitude>190) | ||||||
|  | 	{ | ||||||
|  | 		longitude=longitude-360; | ||||||
|  | 	} | ||||||
|  | 	height = position.getHeight(); | ||||||
|  |  | ||||||
|  | 	if (kml_file.is_open()) | ||||||
|  | 	{ | ||||||
|  | 		kml_file << longitude << "," << latitude << "," << height << std::endl; | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Kml_Printer_gpstk::close_file() | ||||||
|  | { | ||||||
|  |     if (kml_file.is_open()) | ||||||
|  |         { | ||||||
|  |             kml_file << "</coordinates>" << std::endl | ||||||
|  |                      << "</LineString>" << std::endl | ||||||
|  |                      << "</Placemark>" << std::endl | ||||||
|  |                      << "</Document>" << std::endl | ||||||
|  |                      << "</kml>"; | ||||||
|  |             kml_file.close(); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Kml_Printer_gpstk::Kml_Printer_gpstk () {} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Kml_Printer_gpstk::~Kml_Printer_gpstk () {} | ||||||
|  |  | ||||||
							
								
								
									
										59
									
								
								src/utils/gpstk/gnsspvt/src/kml_printer_gpstk.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/utils/gpstk/gnsspvt/src/kml_printer_gpstk.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | /*! | ||||||
|  |  * \file kml_printer.h | ||||||
|  |  * \brief Interface of a class that prints PVT information to a kml file | ||||||
|  |  * for GPSTK data structures | ||||||
|  |  * \author Javier Arribas, 2012. 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_KML_PRINTER_H_ | ||||||
|  | #define	GNSS_SDR_KML_PRINTER_H_ | ||||||
|  |  | ||||||
|  | #include <iostream> | ||||||
|  | #include <fstream> | ||||||
|  | #include "gpstk/Position.hpp" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Prints PVT information to OGC KML format file (can be viewed with Google Earth) | ||||||
|  |  * | ||||||
|  |  * See http://www.opengeospatial.org/standards/kml | ||||||
|  |  */ | ||||||
|  | class Kml_Printer_gpstk | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     std::ofstream kml_file; | ||||||
|  | public: | ||||||
|  |     bool set_headers(std::string filename); | ||||||
|  |     bool print_position(gpstk::Position position); | ||||||
|  |     bool close_file(); | ||||||
|  |     Kml_Printer_gpstk(); | ||||||
|  |     ~Kml_Printer_gpstk(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas