#pragma ident "$Id$"
#include <iostream>
#include <iomanip>
#include <fstream>
#include "BasicFramework.hpp"
#include "RinexObsStream.hpp"
#include "SP3EphemerisStore.hpp"
#include "ProcessingList.hpp"
#include "BasicModel.hpp"
#include "TropModel.hpp"
#include "DataStructures.hpp"
#include "RequireObservables.hpp"
#include "SimpleFilter.hpp"
#include "XYZ2NEU.hpp"
#include "LICSDetector2.hpp"
#include "LICSDetector.hpp"
#include "MWCSDetector.hpp"
#include "SolidTides.hpp"
#include "OceanLoading.hpp"
#include "PoleTides.hpp"
#include "CorrectObservables.hpp"
#include "Antenna.hpp"
#include "AntexReader.hpp"
#include "ComputeWindUp.hpp"
#include "ComputeSatPCenter.hpp"
#include "ComputeTropModel.hpp"
#include "ComputeLinear.hpp"
#include "LinearCombinations.hpp"
#include "ComputeDOP.hpp"
#include "SatArcMarker.hpp"
#include "GravitationalDelay.hpp"
#include "PhaseCodeAlignment.hpp"
#include "EclipsedSatFilter.hpp"
#include "SolverGeneral.hpp"
#include "ConfDataReader.hpp"
using namespace std;
using namespace gpstk;
class example14 : public BasicFramework
{
public:
example14(char* arg0);
protected:
virtual void process();
virtual void spinUp();
virtual void shutDown();
private:
CommandOptionWithArg confFile;
ConfDataReader confReader;
void printModel( ofstream& modelfile,
const gnssRinex& gData,
int precision = 5 );
std::map<SourceID, double> tropoMap;
SourceID master;
std::set<SourceID> refStationSet;
SourceID rover;
gnssDataMap gdsMap;
};
example14::example14(char* arg0)
:
BasicFramework( arg0,
"\nThis program reads GPS receiver data from a configuration file and\n"
"process such data applying a 'Precise Orbits Positioning' strategy.\n\n"
"The output file format is as follows:\n\n"
" 1) Seconds of day\n"
" 2) dLat (m)\n"
" 3) dLon (m)\n"
" 4) dH (m)\n"
" 5) Zenital Tropospheric Delay - zpd (m)\n" ),
confFile( CommandOption::stdType,
'c',
"conffile",
" [-c|--conffile] Name of configuration file ('popconf.txt' by default).",
false )
{
confFile.setMaxCount(1);
}
void example14::printModel( ofstream& modelfile,
const gnssRinex& gData,
int precision )
{
modelfile << fixed << setprecision( precision );
DayTime time(gData.header.epoch);
for ( satTypeValueMap::const_iterator it = gData.body.begin();
it!= gData.body.end();
it++ )
{
modelfile << time.year() << " ";
modelfile << time.DOY() << " ";
modelfile << time.DOYsecond() << " ";
modelfile << (*it).first << " ";
for( typeValueMap::const_iterator itObs = (*it).second.begin();
itObs != (*it).second.end();
itObs++ )
{
modelfile << (*itObs).first << " ";
modelfile << (*itObs).second << " ";
}
modelfile << endl;
}
}
void example14::spinUp()
{
if ( confFile.getCount() > 0 )
{
confReader.exceptions(ios::failbit);
try
{
confReader.open( confFile.getValue()[0] );
}
catch(...)
{
cerr << "Problem opening file "
<< confFile.getValue()[0]
<< endl;
cerr << "Maybe it doesn't exist or you don't have proper "
<< "read permissions." << endl;
exit (-1);
}
}
else
{
try
{
confReader.open( "popconf.txt" );
}
catch(...)
{
cerr << "Problem opening default configuration file 'pop.conf'"
<< endl;
cerr << "Maybe it doesn't exist or you don't have proper read "
<< "permissions. Try providing a configuration file with "
<< "option '-c'."
<< endl;
exit (-1);
}
}
confReader.setFallback2Default(true);
}
void example14::process()
{
SP3EphemerisStore SP3EphList;
SP3EphList.rejectBadPositions(true);
SP3EphList.rejectBadClocks(true);
if ( confReader.getValueAsBoolean( "checkGaps", "DEFAULT" ) )
{
SP3EphList.enableDataGapCheck();
SP3EphList.setGapInterval(
confReader.getValueAsDouble("SP3GapInterval", "DEFAULT" ) );
}
if ( confReader.getValueAsBoolean( "checkInterval", "DEFAULT" ) )
{
SP3EphList.enableIntervalCheck();
SP3EphList.setMaxInterval(
confReader.getValueAsDouble("maxSP3Interval", "DEFAULT" ) );
}
string sp3File;
while ( (sp3File = confReader.fetchListValue("SP3List", "DEFAULT" ) ) != "" )
{
try
{
SP3EphList.loadFile( sp3File );
}
catch (FileMissingException& e)
{
cerr << "SP3 file '" << sp3File << "' doesn't exist or you don't "
<< "have permission to read it. Skipping it." << endl;
continue;
}
}
SolidTides solid;
OceanLoading ocean;
ocean.setFilename( confReader.getValue( "oceanLoadingFile", "DEFAULT" ) );
double xp( confReader.fetchListValueAsDouble( "poleDisplacements",
"DEFAULT" ) );
double yp( confReader.fetchListValueAsDouble( "poleDisplacements",
"DEFAULT" ) );
PoleTides pole;
pole.setXY( xp, yp );
string station;
while ( (station = confReader.getEachSection()) != "" )
{
if( station == "DEFAULT" )
{
continue;
}
cerr << "Starting processing for station: '" << station << "'." << endl;
RinexObsStream rin;
rin.exceptions(ios::failbit);
try
{
rin.open( confReader("rinexObsFile", station), std::ios::in );
}
catch(...)
{
cerr << "Problem opening file '"
<< confReader.getValue("rinexObsFile", station)
<< "'." << endl;
cerr << "Maybe it doesn't exist or you don't have "
<< "proper read permissions."
<< endl;
cerr << "Skipping receiver '" << station << "'."
<< endl;
rin.close();
continue;
}
double xn(confReader.fetchListValueAsDouble("nominalPosition",station));
double yn(confReader.fetchListValueAsDouble("nominalPosition",station));
double zn(confReader.fetchListValueAsDouble("nominalPosition",station));
Position nominalPos( xn, yn, zn );
ProcessingList pList;
RequireObservables requireObs;
requireObs.addRequiredType(TypeID::P2);
requireObs.addRequiredType(TypeID::L1);
requireObs.addRequiredType(TypeID::L2);
SimpleFilter pObsFilter;
pObsFilter.setFilteredType(TypeID::P2);
bool usingC1( confReader.getValueAsBoolean( "useC1", station ) );
if ( usingC1 )
{
requireObs.addRequiredType(TypeID::C1);
pObsFilter.addFilteredType(TypeID::C1);
}
else
{
requireObs.addRequiredType(TypeID::P1);
pObsFilter.addFilteredType(TypeID::P1);
}
pList.push_back(requireObs);
bool filterCode( confReader.getValueAsBoolean( "filterCode", station ) );
if( filterCode )
{
pList.push_back(pObsFilter);
}
LinearCombinations comb;
ComputeLinear linear1;
if ( usingC1 )
{
linear1.addLinear(comb.pdeltaCombWithC1);
linear1.addLinear(comb.mwubbenaCombWithC1);
}
else
{
linear1.addLinear(comb.pdeltaCombination);
linear1.addLinear(comb.mwubbenaCombination);
}
linear1.addLinear(comb.ldeltaCombination);
linear1.addLinear(comb.liCombination);
pList.push_back(linear1);
LICSDetector2 markCSLI2;
pList.push_back(markCSLI2);
MWCSDetector markCSMW;
pList.push_back(markCSMW);
SatArcMarker markArc;
markArc.setDeleteUnstableSats(true);
markArc.setUnstablePeriod(151.0);
pList.push_back(markArc);
BasicModel basic(nominalPos, SP3EphList);
basic.setMinElev(confReader.getValueAsDouble("cutOffElevation",station));
if ( !usingC1 )
{
basic.setDefaultObservable(TypeID::P1);
}
pList.push_back(basic);
EclipsedSatFilter eclipsedSV;
pList.push_back(eclipsedSV);
GravitationalDelay grDelay(nominalPos);
pList.push_back(grDelay);
double uARP(confReader.fetchListValueAsDouble( "offsetARP", station ) );
double eARP(confReader.fetchListValueAsDouble( "offsetARP", station ) );
double nARP(confReader.fetchListValueAsDouble( "offsetARP", station ) );
Triple offsetARP( uARP, eARP, nARP );
Triple offsetL1( 0.0, 0.0, 0.0 ), offsetL2( 0.0, 0.0, 0.0 );
AntexReader antexReader;
Antenna receiverAntenna;
bool useantex( confReader.getValueAsBoolean( "useAntex", station ) );
if( useantex )
{
antexReader.open( confReader.getValue( "antexFile", station ) );
receiverAntenna =
antexReader.getAntenna( confReader.getValue( "antennaModel",
station ) );
}
ComputeSatPCenter svPcenter(nominalPos);
if( useantex )
{
svPcenter.setAntexReader( antexReader );
}
pList.push_back(svPcenter);
CorrectObservables corr(SP3EphList);
corr.setNominalPosition(nominalPos);
corr.setMonument( offsetARP );
bool usepatterns(confReader.getValueAsBoolean("usePCPatterns", station ));
if( useantex && usepatterns )
{
corr.setAntenna( receiverAntenna );
corr.setUseAzimuth(confReader.getValueAsBoolean("useAzim", station));
}
else
{
offsetL1[0] = confReader.fetchListValueAsDouble("offsetL1", station);
offsetL1[1] = confReader.fetchListValueAsDouble("offsetL1", station);
offsetL1[2] = confReader.fetchListValueAsDouble("offsetL1", station);
offsetL2[0] = confReader.fetchListValueAsDouble("offsetL2", station);
offsetL2[1] = confReader.fetchListValueAsDouble("offsetL2", station);
offsetL2[2] = confReader.fetchListValueAsDouble("offsetL2", station);
corr.setL1pc( offsetL1 );
corr.setL2pc( offsetL2 );
}
pList.push_back(corr);
ComputeWindUp windup( SP3EphList,
nominalPos,
confReader.getValue( "satDataFile", station ) );
pList.push_back(windup);
NeillTropModel neillTM( nominalPos.getAltitude(),
nominalPos.getGeodeticLatitude(),
confReader.getValueAsInt("dayOfYear", station) );
ComputeTropModel computeTropo(neillTM);
pList.push_back(computeTropo);
ComputeLinear linear2;
if ( usingC1 )
{
linear2.addLinear(comb.pcCombWithC1);
}
else
{
linear2.addLinear(comb.pcCombination);
}
linear2.addLinear(comb.lcCombination);
pList.push_back(linear2);
SimpleFilter pcFilter;
pcFilter.setFilteredType(TypeID::PC);
bool filterPC( confReader.getValueAsBoolean( "filterPC", station ) );
if( filterPC )
{
pList.push_back(pcFilter);
}
PhaseCodeAlignment phaseAlign;
pList.push_back(phaseAlign);
ComputeLinear linear3(comb.pcPrefit);
linear3.addLinear(comb.lcPrefit);
pList.push_back(linear3);
XYZ2NEU baseChange(nominalPos);
pList.push_back(baseChange);
ComputeDOP cDOP;
pList.push_back(cDOP);
gnssRinex gRin;
bool printmodel( confReader.getValueAsBoolean( "printModel", station ) );
string modelName;
ofstream modelfile;
if( printmodel )
{
modelName = confReader.getValue( "modelFile", station );
modelfile.open( modelName.c_str(), ios::out );
}
while(rin >> gRin)
{
DayTime time(gRin.header.epoch);
Triple tides( solid.getSolidTide( time, nominalPos ) +
ocean.getOceanLoading( station, time ) +
pole.getPoleTide( time, nominalPos ) );
corr.setExtraBiases(tides);
try
{
gRin >> pList;
}
catch(Exception& e)
{
cerr << "Exception for receiver '" << station <<
"' at epoch: " << time << "; " << e << endl;
continue;
}
catch(...)
{
cerr << "Unknown exception for receiver '" << station <<
" at epoch: " << time << endl;
continue;
}
if ( printmodel )
{
printModel( modelfile,
gRin );
}
gdsMap.addGnssRinex(gRin);
}
SourceID source( gRin.header.source );
tropoMap[ source ] = neillTM.dry_zenith_delay();
if( confReader.getValueAsBoolean( "masterStation", station ) )
{
master = source;
}
else
{
if( confReader.getValueAsBoolean( "roverStation", station ) )
{
rover = source;
}
else
{
if( confReader.getValueAsBoolean( "refStation", station ) )
{
refStationSet.insert( source );
}
}
}
rin.close();
if ( printmodel )
{
modelfile.close();
}
cerr << "Processing finished for station: '" << station;
if ( printmodel )
{
cerr << "'. Model in file: '" << modelName;
}
cerr << "'." << endl;
}
SP3EphList.clear();
return;
}
void example14::shutDown()
{
WhiteNoiseModel coordinatesModel(100.0);
TropoRandomWalkModel tropoModel;
PhaseAmbiguityModel ambiModel;
Variable dLat( TypeID::dLat, &coordinatesModel, true, false, 100.0 );
Variable dLon( TypeID::dLon, &coordinatesModel, true, false, 100.0 );
Variable dH( TypeID::dH, &coordinatesModel, true, false, 100.0 );
Variable cdt( TypeID::cdt );
cdt.setDefaultForced(true);
Variable tropo( TypeID::wetMap, &tropoModel, true, false, 10.0 );
Variable ambi( TypeID::BLC, &ambiModel, true, true );
ambi.setDefaultForced(true);
Variable satClock( TypeID::dtSat );
satClock.setSourceIndexed(false);
satClock.setSatIndexed(true);
satClock.setDefaultForced(true);
Variable prefitC( TypeID::prefitC );
Variable prefitL( TypeID::prefitL );
Equation equPCRover( prefitC );
equPCRover.addVariable(dLat);
equPCRover.addVariable(dLon);
equPCRover.addVariable(dH);
equPCRover.addVariable(cdt);
equPCRover.addVariable(tropo);
equPCRover.addVariable(satClock);
equPCRover.header.equationSource = rover;
Equation equLCRover( prefitL );
equLCRover.addVariable(dLat);
equLCRover.addVariable(dLon);
equLCRover.addVariable(dH);
equLCRover.addVariable(cdt);
equLCRover.addVariable(tropo);
equLCRover.addVariable(ambi);
equLCRover.addVariable(satClock);
equLCRover.setWeight(10000.0);
equLCRover.header.equationSource = rover;
Equation equPCRef( prefitC );
equPCRef.addVariable(cdt);
equPCRef.addVariable(tropo);
equPCRef.addVariable(satClock);
equPCRef.header.equationSource = Variable::someSources;
Equation equLCRef( prefitL );
equLCRef.addVariable(cdt);
equLCRef.addVariable(tropo);
equLCRef.addVariable(ambi);
equLCRef.addVariable(satClock);
equLCRef.setWeight(10000.0);
equLCRef.header.equationSource = Variable::someSources;
for( std::set<SourceID>::const_iterator itSet = refStationSet.begin();
itSet != refStationSet.end();
++itSet )
{
equPCRef.addSource2Set( (*itSet) );
equLCRef.addSource2Set( (*itSet) );
}
Equation equPCMaster( prefitC );
equPCMaster.addVariable(tropo);
equPCMaster.addVariable(satClock);
equPCMaster.header.equationSource = master;
Equation equLCMaster( prefitL );
equLCMaster.addVariable(tropo);
equLCMaster.addVariable(ambi);
equLCMaster.addVariable(satClock);
equLCMaster.setWeight(10000.0);
equLCMaster.header.equationSource = master;
EquationSystem system;
system.addEquation(equPCRover);
system.addEquation(equLCRover);
system.addEquation(equPCRef);
system.addEquation(equLCRef);
system.addEquation(equPCMaster);
system.addEquation(equLCMaster);
SolverGeneral solverGen(system);
int precision( confReader.getValueAsInt( "precision", "DEFAULT" ) );
cout << fixed << setprecision( precision );
while( !gdsMap.empty() )
{
gnssDataMap gds( gdsMap.frontEpoch() );
gdsMap.pop_front_epoch();
DayTime workEpoch( (*gds.begin()).first );
solverGen.Process( gds );
try
{
cout << workEpoch.DOYsecond() << " "
<< solverGen.getSolution( TypeID::dLat, rover ) << " "
<< solverGen.getSolution( TypeID::dLon, rover ) << " "
<< solverGen.getSolution( TypeID::dH, rover ) << " "
<< solverGen.getSolution( TypeID::wetMap, rover )
+ 0.1 + tropoMap[ rover ] << endl;
}
catch(...)
{
cerr << "Exception for receiver '" << rover <<
" at epoch: " << workEpoch.DOYsecond() << endl;
continue;
}
}
}
int main(int argc, char* argv[])
{
try
{
example14 program(argv[0]);
if ( !program.initialize(argc, argv, false) )
{
return 0;
}
if ( !program.run() )
{
return 1;
}
return 0;
}
catch(Exception& e)
{
cerr << "Problem: " << e << endl;
return 1;
}
catch(...)
{
cerr << "Unknown error." << endl;
return 1;
}
return 0;
}