Question

Hi, GPSTk users/developers!

I've read Octavian Andrei's artical "Ionosphere effect mitigation for single-frequency precise point positioning". And I want to just do the same static PPP experiment as mentioned in the paper.

I've rewritten the example 9 of GPSTk to do single frequency PPP. In my code I use the your class IonexStore to correct ionospheric errors and combination L1prefit and P1prefit. Unfortunately, the accuracy of estimated position is worse than I expected.The bias is 0.1553m 0.0525m 0.3746m seperately for NEU direction and daily solution.

Is there some problem in my code? Or that is the actual accuracy the single-frequency PPP technique could reach? Could you tell me what's wrong in my code?

The observation file is cedu0100.07o from IGS networks, and the configuration file is singleconf.txt. The related SP3 files are igs14092.sp3,igs14093.sp3, and igs14094.sp3. The output of my program was saved in file cedu0100.out and all gds variable in cedu0100.model.

Thank you!

Frank Wong

Here are my raw code, and I've attached my complete code:

// Method that will really process information

void example9::process()

{

RinexObsStream rin;

// Enable exceptions

rin.exceptions(ios::failbit);

// Open Rinex observations file in read-only mode

rin.open( confReader("rinexObsFile", station), std::ios::in );

// Declare a "SP3EphemerisStore" object to handle precise ephemeris

SP3EphemerisStore SP3EphList;

.....skip some detail

double xn(-9e9),yn(-9e9),zn(-9e9);

// Load station nominal position form configure file

xn=(confReader.fetchListValueAsDouble("nominalPosition",station));

yn=(confReader.fetchListValueAsDouble("nominalPosition",station));

zn=(confReader.fetchListValueAsDouble("nominalPosition",station));

Position nominalPos( xn, yn, zn );

ProcessingList pList;

RequireObservables requireObs;

requireObs.addRequiredType(TypeID::L1);

// This object will check that code observations are within reasonable limits

SimpleFilter pObsFilter;

// Read if we should use C1 instead of P1

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

}

// Add 'requireObs' to processing list (it is the first)

pList.push_back(requireObs);

pList.push_back(pObsFilter); // Add to processing list

// This object defines several handy linear combinations

LinearCombinations comb;

// Object to compute linear combinations for cycle slip detection

ComputeLinear linear1;

OneFreqCSDetector markCSC1;

pList.push_back(markCSC1); // Add to processing list

// Object to keep track of satellite arcs

SatArcMarker markArc;

markArc.setDeleteUnstableSats(true);

markArc.setUnstablePeriod(151.0);

pList.push_back(markArc); // Add to processing list

// Object to decimate data

Decimate decimateData(

confReader.getValueAsDouble( "decimationInterval", station ),

confReader.getValueAsDouble( "decimationTolerance", station ),

SP3EphList.getInitialTime() );

pList.push_back(decimateData); // Add to processing list

BasicModel basic;

......skip some detail

// If we are going to use P1 instead of C1, we must reconfigure 'basic'

if ( usingC1 ) {

basic.setDefaultObservable(TypeID::P1);

}

// Add to processing list

pList.push_back(basic);

// Object to remove eclipsed satellites

EclipsedSatFilter eclipsedSV;

pList.push_back(eclipsedSV); // Add to processing list

// Object to compute gravitational delay effects

GravitationalDelay grDelay(nominalPos);

pList.push_back(grDelay); // Add to processing list

// Temp stores the ARP values

Triple offsetARP;

// If read ARP value from RINEX header

double uARP(hdr.antennaOffset[0]);

double eARP(hdr.antennaOffset[0]);

double nARP(hdr.antennaOffset[0]);

offsetARP=Triple(uARP,eARP,nARP);

// Declare some antenna-related variables

Triple offsetL1( 0.0, 0.0, 0.0 ), offsetL2( 0.0, 0.0, 0.0 );

AntexReader antexReader;

Antenna receiverAntenna;

......skip some detail

// Object to compute satellite antenna phase center effect

ComputeSatPCenter svPcenter(nominalPos);

pList.push_back(svPcenter); // Add to processing list

CorrectObservables corr(SP3EphList);

corr.setNominalPosition(nominalPos);

corr.setMonument( offsetARP );

......skip some detail

pList.push_back(corr); // Add to processing list

// Object to compute wind-up effect

ComputeWindUp windup( SP3EphList,

nominalPos,

confReader.getValue( "satDataFile", station ) );

pList.push_back(windup); // Add to processing list

NeillTropModel neillTM1;

ComputeTropModel computeTropo;

double drytropo(0);

double wettropo(0);

......skip some detail

pList.push_back(computeTropo); // Add to processing list

//Load IONEX file

IonexStore IonexMapList;

IonexMapList.loadFile(confReader.getValue("IonoFile", station));

IonexModel preSin(nominalPos, IonexMapList);

pList.push_back(preSin); // Object to align phase with code measurements

PhaseCodeAlignment phaseAlign;

phaseAlign.setPhaseType(TypeID::L1);

phaseAlign.setCodeType(TypeID::P1);

phaseAlign.setPhaseWavelength( L1_WAVELENGTH);

pList.push_back(phaseAlign); // Add to processing list

// Object to compute prefit-residuals

ComputeLinear linear3(comb.l1Prefit);

if (usingC1)

linear3.addLinear(comb.c1Prefit);

else

linear3.addLinear(comb.p1Prefit);

pList.push_back(linear3); // Add to processing list、

// Declare a base-changing object: From ECEF to North-East-Up (NEU)

XYZ2NEU baseChange(nominalPos);

// We always need both ECEF and NEU data for 'ComputeDOP', so add this

pList.push_back(baseChange);

// Object to compute DOP values

ComputeDOP cDOP;

pList.push_back(cDOP); // Add to processing list

// Get if we want results in ECEF or NEU reference system

bool isNEU( confReader.getValueAsBoolean( "USENEU", station ) );

// we will continue use SolverPPP for single frequency PPP

// because the observation equation system is not changed in single frequency PPP

// and we have already insert the prefitC1 and prefitP1 in GDS

SolverPPP SingleSolver(isNEU);

// for now we will not do forward-back filter

SolverPPPFB fbSingleSolver(isNEU);

// Get if we want 'forwards-backwards' or 'forwards' processing only

int cycles( confReader.getValueAsInt("forwardBackwardCycles", station) );

// Get if we want to process coordinates as white noise

bool isWN( confReader.getValueAsBoolean( "coordinatesAsWhiteNoise",

station ) );

// White noise stochastic model

WhiteNoiseModel wnM(100.0); // 100 m of sigma

......skip some detail

while(rin >> gRin) { // Store current epoch

DayTime time(gRin.header.epoch);

// Compute solid, oceanic and pole tides effects at this epoch

Triple tides( solid.getSolidTide( time, nominalPos ) +

ocean.getOceanLoading( station, time ) +

pole.getPoleTide( time, nominalPos ) );

// Update observable correction object with tides information

corr.setExtraBiases(tides);

gRin >> pList;

***************skip follow on************* -- WongM - 05 Jun 2012

Answer

ALERT! If you answer a question - or have a question you asked answered by someone - please remember to edit the page and set the status to answered. The status is in a drop-down list below the edit box.

-- WongM - 05 Jul 2013

-- WongM - 05 Jul 2013 No such template def TMPL:DEF{PROMPT:supportquery}
Topic attachments
I Attachment Action Size Date Who Comment
cedu0100.07o07o cedu0100.07o manage 4239.2 K 05 Jun 2012 - 13:40 WongM observation file
cedu0100.outout cedu0100.out manage 16.1 K 05 Jun 2012 - 13:37 WongM output result
igs14093.sp3sp3 igs14093.sp3 manage 239.3 K 05 Jun 2012 - 13:36 WongM related sp3 file
singleTest.cppcpp singleTest.cpp manage 39.2 K 05 Jun 2012 - 13:34 WongM source code adapted from example 9
singleconf.txttxt singleconf.txt manage 2.5 K 05 Jun 2012 - 13:34 WongM configuration file
Topic revision: r2 - 05 Jul 2013, WongM
 

This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback