CodeSmoother.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: CodeSmoother.cpp 1325 2008-07-29 14:33:43Z architest $"
00002 
00009 //============================================================================
00010 //
00011 //  This file is part of GPSTk, the GPS Toolkit.
00012 //
00013 //  The GPSTk is free software; you can redistribute it and/or modify
00014 //  it under the terms of the GNU Lesser General Public License as published
00015 //  by the Free Software Foundation; either version 2.1 of the License, or
00016 //  any later version.
00017 //
00018 //  The GPSTk is distributed in the hope that it will be useful,
00019 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021 //  GNU Lesser General Public License for more details.
00022 //
00023 //  You should have received a copy of the GNU Lesser General Public
00024 //  License along with GPSTk; if not, write to the Free Software Foundation,
00025 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 //
00027 //  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2007, 2008
00028 //
00029 //============================================================================
00030 
00031 
00032 #include "CodeSmoother.hpp"
00033 
00034 
00035 namespace gpstk
00036 {
00037 
00038       // Index initially assigned to this class
00039    int CodeSmoother::classIndex = 2400000;
00040 
00041 
00042       // Returns an index identifying this object.
00043    int CodeSmoother::getIndex() const
00044    { return index; }
00045 
00046 
00047       // Returns a string identifying this object.
00048    std::string CodeSmoother::getClassName() const
00049    { return "CodeSmoother"; }
00050 
00051 
00052 
00053       /* Common constructor
00054        *
00055        * @param codeT         Type of code to be smoothed.
00056        * @param mwSize        Maximum  size of filter window, in samples.
00057        */
00058    CodeSmoother::CodeSmoother( const TypeID& codeT,
00059                                const int& mwSize )
00060       : codeType(codeT)
00061    {
00062 
00063          // Don't allow window sizes less than 1
00064       if (mwSize > 1)
00065       {
00066          maxWindowSize = mwSize;
00067       }
00068       else
00069       {
00070          maxWindowSize = 1;
00071       }
00072 
00073       switch ( codeT.type )
00074       {
00075 
00076          case TypeID::C1:
00077             phaseType   = TypeID::L1;
00078             csFlag      = TypeID::CSL1;
00079             resultType  = TypeID::C1;
00080             break;
00081 
00082          case TypeID::C2:
00083             phaseType   = TypeID::L2;
00084             csFlag      = TypeID::CSL2;
00085             resultType  = TypeID::C2;
00086             break;
00087 
00088          case TypeID::P1:
00089             phaseType   = TypeID::L1;
00090             csFlag      = TypeID::CSL1;
00091             resultType  = TypeID::P1;
00092             break;
00093 
00094          case TypeID::P2:
00095             phaseType   = TypeID::L2;
00096             csFlag      = TypeID::CSL2;
00097             resultType  = TypeID::P2;
00098             break;
00099 
00100          case TypeID::C5:
00101             phaseType   = TypeID::L5;
00102             csFlag      = TypeID::CSL5;
00103             resultType  = TypeID::C5;
00104             break;
00105 
00106          case TypeID::C6:
00107             phaseType   = TypeID::L6;
00108             csFlag      = TypeID::CSL6;
00109             resultType  = TypeID::C6;
00110             break;
00111 
00112          case TypeID::C7:
00113             phaseType   = TypeID::L7;
00114             csFlag      = TypeID::CSL7;
00115             resultType  = TypeID::C7;
00116             break;
00117 
00118          case TypeID::C8:
00119             phaseType   = TypeID::L8;
00120             csFlag      = TypeID::CSL8;
00121             resultType  = TypeID::C8;
00122             break;
00123 
00124          default:
00125             phaseType   = TypeID::L1;
00126             csFlag      = TypeID::CSL1;
00127             resultType  = TypeID::C1;
00128 
00129       }  // End of 'switch ( codeT.type )'
00130 
00131       setIndex();
00132 
00133    }  // End of 'CodeSmoother::CodeSmoother()'
00134 
00135 
00136 
00137       /* Returns a satTypeValueMap object, adding the new data generated
00138        * when calling this object.
00139        *
00140        * @param gData     Data object holding the data.
00141        */
00142    satTypeValueMap& CodeSmoother::Process(satTypeValueMap& gData)
00143       throw(ProcessingException)
00144    {
00145 
00146       try
00147       {
00148 
00149          double codeObs(0.0);
00150          double phaseObs(0.0);
00151          double flagObs(0.0);
00152 
00153          SatIDSet satRejectedSet;
00154 
00155             // Loop through all satellites
00156          satTypeValueMap::iterator it;
00157          for (it = gData.begin(); it != gData.end(); ++it)
00158          {
00159 
00160             try
00161             {
00162 
00163                   // Try to extract the values
00164                codeObs  = (*it).second(codeType);
00165                phaseObs = (*it).second(phaseType);
00166                flagObs  = (*it).second(csFlag);
00167 
00168             }
00169             catch(...)
00170             {
00171 
00172                   // If some value is missing, then schedule this satellite
00173                   // for removal
00174                satRejectedSet.insert( (*it).first );
00175 
00176                continue;
00177 
00178             }
00179 
00180                // If everything is OK, then call smoothing function
00181             (*it).second[resultType] = getSmoothing( (*it).first,
00182                                                      codeObs,
00183                                                      phaseObs,
00184                                                      flagObs );
00185          }
00186 
00187             // Remove satellites with missing data
00188          gData.removeSatID(satRejectedSet);
00189 
00190          return gData;
00191 
00192       }
00193       catch(Exception& u)
00194       {
00195             // Throw an exception if something unexpected happens
00196          ProcessingException e( getClassName() + ":"
00197                                 + StringUtils::asString( getIndex() ) + ":"
00198                                 + u.what() );
00199 
00200          GPSTK_THROW(e);
00201 
00202       }
00203 
00204    }  // End of method 'CodeSmoother::Process()'
00205 
00206 
00207 
00208       /* Method to set the maximum size of filter window, in samples.
00209        *
00210        * @param maxSize       Maximum size of filter window, in samples.
00211        */
00212    CodeSmoother& CodeSmoother::setMaxWindowSize(const int& maxSize)
00213    {
00214 
00215          // Don't allow window sizes less than 1
00216       if (maxSize > 1)
00217       {
00218          maxWindowSize = maxSize;
00219       }
00220       else
00221       {
00222          maxWindowSize = 1;
00223       }
00224 
00225       return (*this);
00226 
00227    }  // End of method 'CodeSmoother::setMaxWindowSize()'
00228 
00229 
00230 
00231       /* Compute the smoothed code observable.
00232        *
00233        * @param sat        Satellite object.
00234        * @param code       Code measurement.
00235        * @param phase      Phase measurement.
00236        * @param flag       Cycle slip flag.
00237        */
00238    double CodeSmoother::getSmoothing( const SatID& sat,
00239                                       const double& code,
00240                                       const double& phase,
00241                                       const double& flag )
00242    {
00243 
00244          // In case we have a cycle slip
00245       if ( flag != 0.0 )
00246       {
00247             // Prepare the structure for the next iteration
00248          SmoothingData[sat].previousCode = code;
00249          SmoothingData[sat].previousPhase = phase;
00250          SmoothingData[sat].windowSize = 1;
00251 
00252             // We don't need any further processing
00253          return code;
00254 
00255       }
00256 
00257          // In case we didn't have cycle slip
00258       double smoothedCode(0.0);
00259 
00260          // Increment size of window and check limit
00261       ++SmoothingData[sat].windowSize;
00262       if (SmoothingData[sat].windowSize > maxWindowSize)
00263       {
00264          SmoothingData[sat].windowSize = maxWindowSize;
00265       }
00266 
00267          // The formula used is the following:
00268          //
00269          // CSn = (1/n)*Cn + ((n-1)/n)*(CSn-1 + Ln - Ln-1)
00270          //
00271          // As window size "n" increases, the former formula gives more
00272          // weight to the previous smoothed code CSn-1 plus the phase bias
00273          // (Ln - Ln-1), and less weight to the current code observation Cn
00274       smoothedCode = ( code
00275                   + ((static_cast<double>(SmoothingData[sat].windowSize)) - 1.0)
00276                   * ( SmoothingData[sat].previousCode +
00277                        ( phase - SmoothingData[sat].previousPhase ) ) )
00278                   / (static_cast<double>(SmoothingData[sat].windowSize));
00279 
00280          // Store results for next iteration
00281       SmoothingData[sat].previousCode = smoothedCode;
00282       SmoothingData[sat].previousPhase = phase;
00283 
00284       return smoothedCode;
00285 
00286    }  // End of method 'CodeSmoother::getSmoothing()'
00287 
00288 
00289 }  // End of namespace gpstk

Generated on Thu Feb 9 03:30:55 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1