SolverPPPFB.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: SolverPPPFB.cpp 2346 2010-03-13 15:55:58Z yanweignss $"
00002 
00008 //============================================================================
00009 //
00010 //  This file is part of GPSTk, the GPS Toolkit.
00011 //
00012 //  The GPSTk is free software; you can redistribute it and/or modify
00013 //  it under the terms of the GNU Lesser General Public License as published
00014 //  by the Free Software Foundation; either version 2.1 of the License, or
00015 //  any later version.
00016 //
00017 //  The GPSTk is distributed in the hope that it will be useful,
00018 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //  GNU Lesser General Public License for more details.
00021 //
00022 //  You should have received a copy of the GNU Lesser General Public
00023 //  License along with GPSTk; if not, write to the Free Software Foundation,
00024 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 //
00026 //  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2008, 2009
00027 //
00028 //============================================================================
00029 
00030 
00031 #include "SolverPPPFB.hpp"
00032 
00033 
00034 namespace gpstk
00035 {
00036 
00037       // Index initially assigned to this class
00038    int SolverPPPFB::classIndex = 9400000;
00039 
00040 
00041       // Returns an index identifying this object.
00042    int SolverPPPFB::getIndex() const
00043    { return index; }
00044 
00045 
00046       // Returns a string identifying this object.
00047    std::string SolverPPPFB::getClassName() const
00048    { return "SolverPPPFB"; }
00049 
00050 
00051       /* Common constructor.
00052        *
00053        * @param useNEU   If true, will compute dLat, dLon, dH coordinates;
00054        *                 if false (the default), will compute dx, dy, dz.
00055        */
00056    SolverPPPFB::SolverPPPFB(bool useNEU)
00057       : firstIteration(true)
00058    {
00059 
00060          // Initialize the counter of processed measurements
00061       processedMeasurements = 0;
00062 
00063          // Initialize the counter of rejected measurements
00064       rejectedMeasurements = 0;
00065 
00066          // Set the equation system structure
00067       SolverPPP::setNEU(useNEU);
00068 
00069          // Set the class index
00070       setIndex();
00071 
00072 
00073          // Indicate the TypeID's that we want to keep
00074       keepTypeSet.insert(TypeID::wetMap);
00075 
00076       if (useNEU)
00077       {
00078          keepTypeSet.insert(TypeID::dLat);
00079          keepTypeSet.insert(TypeID::dLon);
00080          keepTypeSet.insert(TypeID::dH);
00081       }
00082       else
00083       {
00084          keepTypeSet.insert(TypeID::dx);
00085          keepTypeSet.insert(TypeID::dy);
00086          keepTypeSet.insert(TypeID::dz);
00087       }
00088 
00089       keepTypeSet.insert(TypeID::cdt);
00090       keepTypeSet.insert(TypeID::prefitC);
00091       keepTypeSet.insert(TypeID::prefitL);
00092       keepTypeSet.insert(TypeID::weight);
00093       keepTypeSet.insert(TypeID::CSL1);
00094       keepTypeSet.insert(TypeID::satArc);
00095 
00096 
00097    }  // End of 'SolverPPPFB::SolverPPPFB()'
00098 
00099 
00100 
00101       /* Returns a reference to a gnnsSatTypeValue object after
00102        * solving the previously defined equation system.
00103        *
00104        * @param gData    Data object holding the data.
00105        */
00106    gnssSatTypeValue& SolverPPPFB::Process(gnssSatTypeValue& gData)
00107       throw(ProcessingException)
00108    {
00109 
00110       try
00111       {
00112 
00113             // Build a gnssRinex object and fill it with data
00114          gnssRinex g1;
00115          g1.header = gData.header;
00116          g1.body = gData.body;
00117 
00118             // Call the Process() method with the appropriate input object
00119          Process(g1);
00120 
00121             // Update the original gnssSatTypeValue object with the results
00122          gData.body = g1.body;
00123 
00124          return gData;
00125 
00126       }
00127       catch(Exception& u)
00128       {
00129             // Throw an exception if something unexpected happens
00130          ProcessingException e( getClassName() + ":"
00131                                 + StringUtils::asString( getIndex() ) + ":"
00132                                 + u.what() );
00133 
00134          GPSTK_THROW(e);
00135 
00136       }
00137 
00138    }  // End of method 'SolverPPPFB::Process()'
00139 
00140 
00141 
00142       /* Returns a reference to a gnnsRinex object after solving
00143        * the previously defined equation system.
00144        *
00145        * @param gData     Data object holding the data.
00146        */
00147    gnssRinex& SolverPPPFB::Process(gnssRinex& gData)
00148       throw(ProcessingException)
00149    {
00150 
00151       try
00152       {
00153 
00154          SolverPPP::Process(gData);
00155 
00156 
00157             // Before returning, store the results for a future iteration
00158          if(firstIteration)
00159          {
00160 
00161                // Create a new gnssRinex structure with just the data we need
00162             gnssRinex gBak(gData.extractTypeID(keepTypeSet));
00163 
00164                // Store observation data
00165             ObsData.push_back(gBak);
00166 
00167             // Update the number of processed measurements
00168             processedMeasurements += gData.numSats();
00169 
00170          }
00171 
00172          return gData;
00173 
00174       }
00175       catch(Exception& u)
00176       {
00177             // Throw an exception if something unexpected happens
00178          ProcessingException e( getClassName() + ":"
00179                                 + StringUtils::asString( getIndex() ) + ":"
00180                                 + u.what() );
00181 
00182          GPSTK_THROW(e);
00183 
00184       }
00185 
00186    }  // End of method 'SolverPPPFB::Process()'
00187 
00188 
00189 
00190       /* Reprocess the data stored during a previous 'Process()' call.
00191        *
00192        * @param cycles     Number of forward-backward cycles, 1 by default.
00193        *
00194        * \warning The minimum number of cycles allowed is "1". In fact, if
00195        * you introduce a smaller number, 'cycles' will be set to "1".
00196        */
00197    void SolverPPPFB::ReProcess(int cycles)
00198       throw(ProcessingException)
00199    {
00200 
00201          // Check number of cycles. The minimum allowed is "1".
00202       if (cycles < 1)
00203       {
00204          cycles = 1;
00205       }
00206 
00207          // This will prevent further storage of input data when calling
00208          // method 'Process()'
00209       firstIteration = false;
00210 
00211       try
00212       {
00213 
00214          std::list<gnssRinex>::iterator pos;
00215          std::list<gnssRinex>::reverse_iterator rpos;
00216 
00217             // Backwards iteration. We must do this at least once
00218          for (rpos = ObsData.rbegin(); rpos != ObsData.rend(); ++rpos)
00219          {
00220 
00221             SolverPPP::Process( (*rpos) );
00222 
00223          }
00224 
00225             // If 'cycles > 1', let's do the other iterations
00226          for (int i=0; i<(cycles-1); i++)
00227          {
00228 
00229                // Forwards iteration
00230             for (pos = ObsData.begin(); pos != ObsData.end(); ++pos)
00231             {
00232                SolverPPP::Process( (*pos) );
00233             }
00234 
00235                // Backwards iteration.
00236             for (rpos = ObsData.rbegin(); rpos != ObsData.rend(); ++rpos)
00237             {
00238                SolverPPP::Process( (*rpos) );
00239             }
00240 
00241          }  // End of 'for (int i=0; i<(cycles-1), i++)'
00242 
00243          return;
00244 
00245       }
00246       catch(Exception& u)
00247       {
00248             // Throw an exception if something unexpected happens
00249          ProcessingException e( getClassName() + ":"
00250                                 + StringUtils::asString( getIndex() ) + ":"
00251                                 + u.what() );
00252 
00253          GPSTK_THROW(e);
00254 
00255       }
00256 
00257    }  // End of method 'SolverPPPFB::ReProcess()'
00258 
00259 
00260 
00261       /* Reprocess the data stored during a previous 'Process()' call.
00262        *
00263        * This method will reprocess data trimming satellites whose postfit
00264        * residual is bigger than the limits indicated by limitsCodeList and
00265        * limitsPhaseList.
00266        */
00267    void SolverPPPFB::ReProcess( void )
00268       throw(ProcessingException)
00269    {
00270 
00271          // Let's use a copy of the lists
00272       std::list<double> codeList( limitsCodeList );
00273       std::list<double> phaseList( limitsPhaseList );
00274 
00275          // Get maximum size
00276       int maxSize( codeList.size() );
00277       if( maxSize < phaseList.size() ) maxSize = phaseList.size();
00278 
00279          // This will prevent further storage of input data when calling
00280          // method 'Process()'
00281       firstIteration = false;
00282 
00283       try
00284       {
00285 
00286          std::list<gnssRinex>::iterator pos;
00287          std::list<gnssRinex>::reverse_iterator rpos;
00288 
00289             // Backwards iteration. We must do this at least once
00290          for (rpos = ObsData.rbegin(); rpos != ObsData.rend(); ++rpos)
00291          {
00292 
00293             SolverPPP::Process( (*rpos) );
00294 
00295          }
00296 
00297             // If both sizes are '0', let's return
00298          if( maxSize == 0 )
00299          {
00300             return;
00301          }
00302 
00303             // We will store the limits here. By default we use very big values
00304          double codeLimit( 1000000.0 );
00305          double phaseLimit( 1000000.0 );
00306 
00307             // If 'maxSize > 0', let's do the other iterations
00308          for (int i = 0; i < maxSize; i++)
00309          {
00310 
00311                // Update current limits, if available
00312             if( codeList.size() > 0 )
00313             {
00314                   // Get the first element from the list
00315                codeLimit = codeList.front();
00316 
00317                   // Delete the first element from the list
00318                codeList.pop_front();
00319             }
00320 
00321             if( phaseList.size() > 0 )
00322             {
00323                   // Get the first element from the list
00324                phaseLimit = phaseList.front();
00325 
00326                   // Delete the first element from the list
00327                phaseList.pop_front();
00328             }
00329 
00330 
00331                // Forwards iteration
00332             for (pos = ObsData.begin(); pos != ObsData.end(); ++pos)
00333             {
00334                   // Let's check limits
00335                checkLimits( (*pos), codeLimit, phaseLimit );
00336 
00337                   // Process data
00338                SolverPPP::Process( (*pos) );
00339             }
00340 
00341                // Backwards iteration.
00342             for (rpos = ObsData.rbegin(); rpos != ObsData.rend(); ++rpos)
00343             {
00344                   // Let's check limits
00345                checkLimits( (*rpos), codeLimit, phaseLimit );
00346 
00347                   // Process data
00348                SolverPPP::Process( (*rpos) );
00349             }
00350 
00351          }  // End of 'for (int i=0; i<(cycles-1), i++)'
00352 
00353          return;
00354 
00355       }
00356       catch(Exception& u)
00357       {
00358             // Throw an exception if something unexpected happens
00359          ProcessingException e( getClassName() + ":"
00360                                 + StringUtils::asString( getIndex() ) + ":"
00361                                 + u.what() );
00362 
00363          GPSTK_THROW(e);
00364 
00365       }
00366 
00367    }  // End of method 'SolverPPPFB::ReProcess()'
00368 
00369 
00370 
00371       /* Process the data stored during a previous 'ReProcess()' call, one
00372        * item at a time, and always in forward mode.
00373        *
00374        * @param gData      Data object that will hold the resulting data.
00375        *
00376        * @return FALSE when all data is processed, TRUE otherwise.
00377        */
00378    bool SolverPPPFB::LastProcess(gnssSatTypeValue& gData)
00379       throw(ProcessingException)
00380    {
00381 
00382       try
00383       {
00384 
00385             // Declare a gnssRinex object
00386          gnssRinex g1;
00387 
00388             // Call the 'LastProcess()' method and store the result
00389          bool result( LastProcess(g1) );
00390 
00391          if(result)
00392          {
00393                // Convert from 'gnssRinex' to 'gnnsSatTypeValue'
00394             gData.header = g1.header;
00395             gData.body   = g1.body;
00396 
00397          }
00398 
00399          return result;
00400 
00401       }
00402       catch(Exception& u)
00403       {
00404             // Throw an exception if something unexpected happens
00405          ProcessingException e( getClassName() + ":"
00406                                 + StringUtils::asString( getIndex() ) + ":"
00407                                 + u.what() );
00408 
00409          GPSTK_THROW(e);
00410 
00411       }
00412 
00413    }  // End of method 'SolverPPPFB::LastProcess()'
00414 
00415 
00416 
00417       /* Process the data stored during a previous 'ReProcess()' call, one
00418        * item at a time, and always in forward mode.
00419        *
00420        * @param gData      Data object that will hold the resulting data.
00421        *
00422        * @return FALSE when all data is processed, TRUE otherwise.
00423        */
00424    bool SolverPPPFB::LastProcess(gnssRinex& gData)
00425       throw(ProcessingException)
00426    {
00427 
00428       try
00429       {
00430 
00431             // Keep processing while 'ObsData' is not empty
00432          if( !(ObsData.empty()) )
00433          {
00434 
00435                // Get the first data epoch in 'ObsData' and process it. The
00436                // result will be stored in 'gData'
00437             gData = SolverPPP::Process( ObsData.front() );
00438 
00439                // Remove the first data epoch in 'ObsData', freeing some
00440                // memory and preparing for next epoch
00441             ObsData.pop_front();
00442 
00443 
00444                // Update some inherited fields
00445             solution = SolverPPP::solution;
00446             covMatrix = SolverPPP::covMatrix;
00447             postfitResiduals = SolverPPP::postfitResiduals;
00448 
00449                // If everything is fine so far, then results should be valid
00450             valid = true;
00451 
00452             return true;
00453 
00454          }
00455          else
00456          {
00457 
00458                // There are no more data
00459             return false;
00460 
00461          }  // End of 'if( !(ObsData.empty()) )'
00462 
00463       }
00464       catch(Exception& u)
00465       {
00466             // Throw an exception if something unexpected happens
00467          ProcessingException e( getClassName() + ":"
00468                                 + StringUtils::asString( getIndex() ) + ":"
00469                                 + u.what() );
00470 
00471          GPSTK_THROW(e);
00472 
00473       }
00474 
00475    }  // End of method 'SolverPPPFB::LastProcess()'
00476 
00477 
00478 
00479       // This method checks the limits and modifies 'gData' accordingly.
00480    void SolverPPPFB::checkLimits( gnssRinex& gData,
00481                                   double codeLimit,
00482                                   double phaseLimit )
00483    {
00484 
00485          // Set to store rejected satellites
00486       SatIDSet satRejectedSet;
00487 
00488          // Let's check limits
00489       for( satTypeValueMap::iterator it = gData.body.begin();
00490            it != gData.body.end();
00491            ++it )
00492       {
00493 
00494             // Check postfit values and mark satellites as rejected
00495          if( std::abs((*it).second( TypeID::postfitC )) > codeLimit )
00496          {
00497             satRejectedSet.insert( (*it).first );
00498          }
00499 
00500          if( std::abs((*it).second( TypeID::postfitL )) > phaseLimit )
00501          {
00502             satRejectedSet.insert( (*it).first );
00503          }
00504 
00505       }  // End of 'for( satTypeValueMap::iterator it = gds.body.begin();...'
00506 
00507 
00508          // Update the number of rejected measurements
00509       rejectedMeasurements += satRejectedSet.size();
00510 
00511          // Remove satellites with missing data
00512       gData.removeSatID(satRejectedSet);
00513 
00514       return;
00515 
00516    }  // End of method 'SolverPPPFB::checkLimits()'
00517 
00518 
00519 
00520       /* Sets if a NEU system will be used.
00521        *
00522        * @param useNEU  Boolean value indicating if a NEU system will
00523        *                be used
00524        *
00525        */
00526    SolverPPPFB& SolverPPPFB::setNEU( bool useNEU )
00527    {
00528 
00529          // Set the SolverPPP filter
00530       SolverPPP::setNEU(useNEU);
00531 
00532 
00533          // Clear current 'keepTypeSet' and indicate the TypeID's that
00534          // we want to keep
00535       keepTypeSet.clear();
00536 
00537       keepTypeSet.insert(TypeID::wetMap);
00538 
00539       if (useNEU)
00540       {
00541          keepTypeSet.insert(TypeID::dLat);
00542          keepTypeSet.insert(TypeID::dLon);
00543          keepTypeSet.insert(TypeID::dH);
00544       }
00545       else
00546       {
00547          keepTypeSet.insert(TypeID::dx);
00548          keepTypeSet.insert(TypeID::dy);
00549          keepTypeSet.insert(TypeID::dz);
00550       }
00551 
00552       keepTypeSet.insert(TypeID::cdt);
00553       keepTypeSet.insert(TypeID::prefitC);
00554       keepTypeSet.insert(TypeID::prefitL);
00555       keepTypeSet.insert(TypeID::weight);
00556       keepTypeSet.insert(TypeID::CSL1);
00557       keepTypeSet.insert(TypeID::satArc);
00558 
00559 
00560          // Return this object
00561       return (*this);
00562 
00563    }  // End of method 'SolverPPPFB::setNEU()'
00564 
00565 
00566 
00567 }  // End of namespace gpstk

Generated on Tue May 22 03:31:01 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1