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:
Javier Arribas 2012-12-18 18:01:19 +00:00
parent 4adeef7aec
commit c3e2e2e1d9
7 changed files with 1089 additions and 0 deletions

View 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()

View 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()

View 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)

View 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

View 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()'

View 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 () {}

View 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