VariableSet GeneralConstraint::getVariables( const SatID& sat, const TypeIDSet& typeSet ) { VariableSet vset; VariableSet varSet = getVariables(sat); for(VariableSet::iterator itv=varSet.begin(); itv!=varSet.end(); ++itv) { TypeIDSet::const_iterator it = typeSet.find(itv->getType()); if( (it!=typeSet.end()) ) vset.insert(*itv); } return vset; } // End of method 'GeneralConstraint::getVariables(...'
VariableSet GeneralConstraint::getVariables( const SourceID& source, const TypeIDSet& typeSet ) { VariableSet vset; VariableSet varSet = getVariables(source); for(VariableSet::iterator itv=varSet.begin(); itv!=varSet.end(); ++itv) { TypeIDSet::const_iterator it = typeSet.find(itv->getType()); if( (it!=typeSet.end()) && itv->getSourceIndexed() ) { vset.insert(*itv); } } return vset; } // End of method 'GeneralConstraint::getVariables'
int main(void) { /////////////////// INITIALIZATION PART ///////////////////// cout << fixed << setprecision(4); // Set a proper output format // Create the input observation file stream RinexObsStream rin("ebre0300.02o"); // Create the input observation file stream for REFERENCE STATION RinexObsStream rinRef("bell0300.02o"); //// Broadcast ephemeris part // Create the input navigation file stream RinexNavStream rnavin("brdc0300.02n"); RinexNavData rNavData; // Object to store Rinex navigation data GPSEphemerisStore bceStore; // Object to store satellites ephemeris // Storing the ephemeris in "bceStore" while (rnavin >> rNavData) { bceStore.addEphemeris(rNavData); } bceStore.SearchUser(); // This is the default //// // EBRE station nominal position Position nominalPos(4833520.1852, 41537.0453, 4147461.4963); // BELL station nominal position Position BnominalPos(4775849.4262, 116814.3084, 4213018.9143); // Declare a NeillTropModel object, setting the defaults NeillTropModel neillTM( nominalPos.getAltitude(), nominalPos.getGeodeticLatitude(), 30); // Declare a NeillTropModel object, setting the defaults (Ref. station) NeillTropModel BneillTM( BnominalPos.getAltitude(), BnominalPos.getGeodeticLatitude(), 30); // This is the GNSS data structure that will hold all the // GNSS-related information gnssRinex gRin; gnssRinex gRef; // Declare base-changing objects: From ECEF to North-East-Up (NEU) XYZ2NEU baseChange(nominalPos); XYZ2NEU BbaseChange(BnominalPos); // Declare a simple filter object to screen PC SimpleFilter pcFilter; pcFilter.setFilteredType(TypeID::PC); // Declare a couple of basic modelers BasicModel basic(nominalPos, bceStore); BasicModel Bbasic(BnominalPos, bceStore); // Objects to mark cycle slips LICSDetector2 markCSLI; // Checks LI cycle slips MWCSDetector markCSMW; // Checks Merbourne-Wubbena cycle slips LICSDetector2 BmarkCSLI; // Checks LI cycle slips MWCSDetector BmarkCSMW; // Checks Merbourne-Wubbena cycle slips // Object to compute tidal effects SolidTides solid; // Ocean loading model OceanLoading ocean("OCEAN-GOT00.dat"); // Numerical values are x,y pole displacements for Jan/30/2002 (arcsec). PoleTides pole(-0.17153, 0.38661); // Vector from EBRE antenna ARP to L1 phase center [UEN] Triple offsetL1(0.110, 0.000, 0.000); // Units in meters // Vector from EBRE antenna ARP to L2 phase center [UEN] Triple offsetL2(0.128, 0.0000, 0.000); // Units in meters // Vector from monument to antenna ARP [UEN] for EBRE station Triple offsetARP(0.0, 0.0, 0.0); // Units in meters // Vector from BELL antenna ARP to L1 phase center [UEN] (TRM29659.00) Triple BoffsetL1(0.110, 0.000, 0.000); // Units in meters // Vector from BELL antenna ARP to L2 phase center [UEN] (TRM29659.00) Triple BoffsetL2(0.128, 0.0000, 0.000); // Units in meters // Vector from monument to antenna ARP [UEN] for BELL station Triple BoffsetARP(0.054, 0.0, 0.0); // Units in meters // Declare an object to correct observables to monument CorrectObservables corr(bceStore); ((corr.setNominalPosition(nominalPos)).setL1pc(offsetL1)).setL2pc(offsetL2); corr.setMonument(offsetARP); // Declare an object to correct observables to monument (Ref. station) CorrectObservables Bcorr(bceStore); Bcorr.setNominalPosition(BnominalPos); Bcorr.setL1pc(BoffsetL1); Bcorr.setL2pc(BoffsetL2); Bcorr.setMonument(BoffsetARP); // Objects to compute wind-up effect ComputeWindUp windup(bceStore, nominalPos, "PRN_GPS"); ComputeWindUp Bwindup(bceStore, BnominalPos, "PRN_GPS"); // Objects to compute satellite antenna phase center effect ComputeSatPCenter svPcenter(nominalPos); ComputeSatPCenter BsvPcenter(BnominalPos); // Objects to compute the tropospheric data ComputeTropModel computeTropo(neillTM); ComputeTropModel BcomputeTropo(BneillTM); // This object defines several handy linear combinations LinearCombinations comb; // Object to compute linear combinations of data ComputeLinear linear1(comb.pcCombWithC1); linear1.addLinear(comb.lcCombination); linear1.addLinear(comb.pdeltaCombWithC1); linear1.addLinear(comb.ldeltaCombination); linear1.addLinear(comb.mwubbenaCombWithC1); linear1.addLinear(comb.liCombination); // Let's use a different object to compute prefit residuals ComputeLinear linear2(comb.pcPrefit); linear2.addLinear(comb.lcPrefit); // Declare an object to process the data using PPP. It is set // to use a NEU system SolverPPP pppSolver(true); // The current processing strategy is "static". // The real test for a PPP processing program is to handle coordinates // as white noise. In such case, position error should be about 0.25 m or // better. Uncomment the following couple of lines to test this. // WhiteNoiseModel wnM(100.0); // 100 m of sigma // pppSolver.setCoordinatesModel(&wnM); // Object to keep track of satellite arcs SatArcMarker markArc; markArc.setDeleteUnstableSats(true); markArc.setUnstablePeriod(151.0); // Objects to compute gravitational delay effects GravitationalDelay grDelay(nominalPos); GravitationalDelay BgrDelay(BnominalPos); // Object to align phase with code measurements PhaseCodeAlignment phaseAlign; // Object to compute DOP values ComputeDOP cDOP; // Object to remove eclipsed satellites EclipsedSatFilter eclipsedSV; // Statistical summary objects PowerSum errorVectorStats; TypeIDSet tset; tset.insert(TypeID::prefitC); tset.insert(TypeID::prefitL); // Create an object to compute the single differences of prefit residuals DeltaOp delta; // By default, it will work on code prefit residuals, so we must change // the default and provide a set of types to be differenced delta.setDiffTypeSet(tset); // Create an object to synchronize rover and reference station // data streams. This object will take data out from "rinRef" until // it is synchronized with data in "gOriginal". Default synchronization // tolerance is 1 s. Synchronize synchro(rinRef, gRin); /////////////////// PROCESING PART ///////////////////// // Use this variable to select between position printing or model printing bool printPosition(true); // By default, print position and associated // parameters // Loop over all data epochs while(rin >> gRin) { CommonTime time(gRin.header.epoch); // Compute the effect of solid, oceanic and pole tides Triple tides( solid.getSolidTide(time, nominalPos) + ocean.getOceanLoading("EBRE", time) + pole.getPoleTide(time, nominalPos) ); // Compute the effect of solid, oceanic and pole tides Triple Btides( solid.getSolidTide(time, BnominalPos) + ocean.getOceanLoading("BELL", time) + pole.getPoleTide(time, BnominalPos) ); // Update observable correction object with tides information corr.setExtraBiases(tides); // Update observable correction object with tides information Bcorr.setExtraBiases(Btides); try { // First, process reference station gRef >> synchro // Synchronize data streams >> Bbasic // Compute the basic components of model >> eclipsedSV // Remove satellites in eclipse >> BgrDelay // Compute gravitational delay >> BsvPcenter // Compute the effect of satellite phase >> Bcorr // Correct observables from tides, etc. >> Bwindup // Compute wind-up effect >> BcomputeTropo // Compute tropospheric effect >> linear1 // Compute common linear combinations >> pcFilter // Filter out spurious data >> BmarkCSLI // Mark cycle slips: LI algorithm >> BmarkCSMW // Mark cycle slips: Melbourne-Wubbena >> markArc // Keep track of satellite arcs >> linear2; // Compute prefit residuals delta.setRefData(gRef.body); } catch(SynchronizeException& e) // THIS IS VERY IMPORTANT IN ORDER TO { // MANAGE A POSSIBLE DESYNCHRONIZATION!! continue; } catch(...) { cerr << "Exception when processing reference station data at epoch: " << gRef.header.epoch << endl; } // Rover data processing is done here: try { // The following lines are indeed just one line gRin >> basic // Compute the basic components of model >> eclipsedSV // Remove satellites in eclipse >> grDelay // Compute gravitational delay >> svPcenter // Compute the effect of satellite phase center >> corr // Correct observables from tides, etc. >> windup // Compute wind-up effect >> computeTropo // Compute tropospheric effect >> linear1 // Compute common linear combinations >> pcFilter // Filter out spurious data >> markCSLI // Mark cycle slips: LI algorithm >> markCSMW // Mark cycle slips: Melbourne-Wubbena >> markArc // Keep track of satellite arcs >> phaseAlign // Align phases with codes >> linear2 // Compute prefit residuals >> delta >> baseChange // Prepare to use North-East-UP reference frame >> cDOP // Compute DOP figures >> pppSolver; // Solve equations with a Kalman filter } catch(Exception& e) { cerr << "Exception at epoch: " << time << "; " << e << endl; continue; } catch(...) { cerr << "Unknown exception at epoch: " << time << endl; continue; } // Check if we want to print model or position if(printPosition) { // Print here the position results cout << static_cast<YDSTime>(time).sod << " "; // Epoch - Output field #1 cout << pppSolver.getSolution(TypeID::dLat) << " "; // dLat - #2 cout << pppSolver.getSolution(TypeID::dLon) << " "; // dLon - #3 cout << pppSolver.getSolution(TypeID::dH) << " "; // dH - #4 cout << pppSolver.getSolution(TypeID::wetMap) << " "; // Tropo - #5 cout << pppSolver.getVariance(TypeID::dLat) << " "; // Cov dLat - #6 cout << pppSolver.getVariance(TypeID::dLon) << " "; // Cov dLon - #7 cout << pppSolver.getVariance(TypeID::dH) << " "; // Cov dH - #8 cout << pppSolver.getVariance(TypeID::wetMap) << " ";//Cov Tropo- #9 cout << gRin.numSats() << " "; // Satellite number - #10 cout << cDOP.getGDOP() << " "; // GDOP - #11 cout << cDOP.getPDOP() << " "; // PDOP - #12 cout << cDOP.getTDOP() << " "; // TDOP - #13 cout << cDOP.getHDOP() << " "; // HDOP - #14 cout << cDOP.getVDOP() << " "; // VDOP - #15 cout << endl; // For statistical purposes we discard the first two hours of data if (static_cast<YDSTime>(time).sod > 7200.0) { // Statistical summary double errorV( pppSolver.solution[1]*pppSolver.solution[1] + pppSolver.solution[2]*pppSolver.solution[2] + pppSolver.solution[3]*pppSolver.solution[3] ); // Get module of position error vector errorV = std::sqrt(errorV); // Add to statistical summary object errorVectorStats.add(errorV); } } // End of position printing else { // Print here the model results // First, define types we want to keep TypeIDSet types; types.insert(TypeID::L1); types.insert(TypeID::L2); types.insert(TypeID::P1); types.insert(TypeID::P2); types.insert(TypeID::PC); types.insert(TypeID::LC); types.insert(TypeID::rho); types.insert(TypeID::dtSat); types.insert(TypeID::rel); types.insert(TypeID::gravDelay); types.insert(TypeID::tropo); types.insert(TypeID::dryTropo); types.insert(TypeID::dryMap); types.insert(TypeID::wetTropo); types.insert(TypeID::wetMap); types.insert(TypeID::tropoSlant); types.insert(TypeID::windUp); types.insert(TypeID::satPCenter); types.insert(TypeID::satX); types.insert(TypeID::satY); types.insert(TypeID::satZ); types.insert(TypeID::elevation); types.insert(TypeID::azimuth); types.insert(TypeID::satArc); types.insert(TypeID::prefitC); types.insert(TypeID::prefitL); types.insert(TypeID::dx); types.insert(TypeID::dy); types.insert(TypeID::dz); types.insert(TypeID::dLat); types.insert(TypeID::dLon); types.insert(TypeID::dH); types.insert(TypeID::cdt); gRin.keepOnlyTypeID(types); // Delete the types not in 'types' // Iterate through the GNSS Data Structure satTypeValueMap::const_iterator it; for (it = gRin.body.begin(); it!= gRin.body.end(); it++) { // Print epoch cout << static_cast<YDSTime>(time).year << " "; cout << static_cast<YDSTime>(time).doy << " "; cout << static_cast<YDSTime>(time).sod << " "; cout << cDOP.getGDOP() << " "; // GDOP #4 cout << cDOP.getPDOP() << " "; // PDOP #5 cout << cDOP.getTDOP() << " "; // TDOP #6 cout << cDOP.getHDOP() << " "; // HDOP #7 cout << cDOP.getVDOP() << " "; // VDOP #8 // Print satellite information (system and PRN) cout << (*it).first << " "; // Print model values typeValueMap::const_iterator itObs; for( itObs = (*it).second.begin(); itObs != (*it).second.end(); itObs++ ) { bool printNames(true); // Whether print types' names or not if (printNames) { cout << (*itObs).first << " "; } cout << (*itObs).second << " "; } // End for( itObs = ... ) cout << endl; } // End for (it = gRin.body.begin(); ... ) } // End of model printing } // End of 'while(rin >> gRin)...' // Print statistical summary in cerr if(printPosition) { cerr << "Module of error vector: Average = " << errorVectorStats.average() << " m Std. dev. = " << std::sqrt(errorVectorStats.variance()) << " m" << endl; } exit(0); // End of program }
// Compute hMatrix and rMatrix void EquationSystem::getGeometryWeights( gnssDataMap& gdsMap ) { // Resize hMatrix and rMatrix hMatrix.resize( measVector.size(), varUnknowns.size(), 0.0); rMatrix.resize( measVector.size(), measVector.size(), 0.0); // Let's work with the first element of the data structure gnssDataMap gds2( gdsMap.frontEpoch() ); // Let's fill weights and geometry matrices int row(0); // Declare a counter for row number for( std::list<Equation>::const_iterator itRow = currentEquationsList.begin(); itRow != currentEquationsList.end(); ++itRow ) { // Create temporal GDS objects SourceID source( (*itRow).header.equationSource ); SatID sat( (*itRow).header.equationSat ); // Get a TypeIDSet with all the data types present in current GDS // Declare an appropriate object TypeIDSet typeSet; // We need a flag bool found( false ); // Iterate through data structure for( gnssDataMap::const_iterator itGDS = gds2.begin(); itGDS != gds2.end() && !found; ++itGDS ) { // Look for source sourceDataMap::const_iterator itSDM = (*itGDS).second.find(source); if( itSDM != (*itGDS).second.end() ) { // Get the types typeSet = (*itSDM).second.getTypeID(); found = true; } } // First, fill weights matrix // Check if current GDS has weight info. If you don't want those // weights to get into equations, please don't put them in GDS if( typeSet.find(TypeID::weight) != typeSet.end() ) { // Weights matrix = Equation weight * observation weight rMatrix(row,row) = (*itRow).header.constWeight * gds2.getValue(source, sat, TypeID::weight); } else { // Weights matrix = Equation weight rMatrix(row,row) = (*itRow).header.constWeight; } // Second, fill geometry matrix: Look for equation coefficients int col(0); // Declare a counter for column number for( VariableSet::const_iterator itCol = varUnknowns.begin(); itCol != varUnknowns.end(); ++itCol ) { // Check if unknown is in current equation and also is marked // as a current unknown if( (*itRow).body.find( (*itCol) ) != (*itRow).body.end() && currentUnknowns.find( (*itCol) ) != currentUnknowns.end() ) { // Check if '(*itCol)' unknown variable enforces a specific // coefficient if( (*itCol).isDefaultForced() ) { // Use default coefficient hMatrix(row,col) = (*itCol).getDefaultCoefficient(); } else { // Look the coefficient in provided data // Get type of current varUnknown TypeID type( (*itCol).getType() ); // Check if this type has an entry in current GDS type set if( typeSet.find(type) != typeSet.end() ) { // If type was found, insert value into hMatrix hMatrix(row,col) = gds2.getValue(source, sat, type); } else { // If value for current type is not in gdsMap, then // insert default coefficient for this variable hMatrix(row,col) = (*itCol).getDefaultCoefficient(); } } // End of 'if( (*itCol).isDefaultForced() ) ...' } // End of 'if( (*itRow).body.find( (*itCol) ) != ...' // Increment column counter ++col; } // End of 'for( VariableSet::const_iterator itCol = ...' // Handle type index variable for( VariableSet::const_iterator itCol = (*itRow).body.begin(); itCol != (*itRow).body.end(); ++itCol ) { VariableSet::const_iterator itr = rejectUnknowns.find( (*itCol) ); if( itr == rejectUnknowns.end() || (*itr).getTypeIndexed()) continue; Variable var(*itr); col = 0; for( VariableSet::const_iterator it = varUnknowns.begin(); it != varUnknowns.end(); it++) { if(((*itCol).getType() == (*it).getType()) && ((*itCol).getModel() == (*it).getModel()) && ((*itCol).getSourceIndexed() == (*it).getSourceIndexed())&& ((*itCol).getSatIndexed() == (*it).getSatIndexed()) && ((*itCol).getSource() == (*it).getSource()) && ((*itCol).getSatellite() == (*it).getSatellite()) ) { break; } col++; } // Check if '(*itCol)' unknown variable enforces a specific // coefficient if( (*itCol).isDefaultForced() ) { // Use default coefficient hMatrix(row,col) = (*itCol).getDefaultCoefficient(); } else { // Look the coefficient in provided data // Get type of current varUnknown TypeID type( (*itCol).getType() ); // Check if this type has an entry in current GDS type set if( typeSet.find(type) != typeSet.end() ) { // If type was found, insert value into hMatrix hMatrix(row,col) = gds2.getValue(source, sat, type); } else { // If value for current type is not in gdsMap, then // insert default coefficient for this variable hMatrix(row,col) = (*itCol).getDefaultCoefficient(); } } // End of 'if( (*itCol).isDefaultForced() ) ...' } // Increment row number ++row; } // End of 'std::list<Equation>::const_iterator itRow = ...' } // End of method 'EquationSystem::getGeometryWeights()'