Differentiator.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id$"
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 ). 2011
00027 //
00028 //============================================================================
00029 
00030 
00031 #include "Differentiator.hpp"
00032 
00033 
00034 namespace gpstk
00035 {
00036 
00037       // Index initially assigned to this class
00038    int Differentiator::classIndex = 9900000;
00039 
00040 
00041       // Returns an index identifying this object.
00042    int Differentiator::getIndex() const
00043    { return index; }
00044 
00045 
00046 
00047       // Returns a string identifying this object.
00048    std::string Differentiator::getClassName() const
00049    { return "Differentiator"; }
00050 
00051 
00052 
00053       /* Common constructor.
00054        *
00055        * @param inType           TypeID to be differentiated.
00056        * @param outType          TypeID to store the derivative of inType.
00057        * @param samplingPeriod   Sampling period, in seconds.
00058        * @param tol              Tolerance, in seconds.
00059        * @param useArc           Whether satellite arcs will be used or not.
00060        */
00061    Differentiator::Differentiator( const TypeID& inType,
00062                                    const TypeID& outType,
00063                                    double samplingPeriod,
00064                                    double tol,
00065                                    bool useArc )
00066       : inputType(inType), outputType(outType), useSatArcs(useArc),
00067         watchCSFlag(TypeID::CSL1)
00068    {
00069 
00070       setSamplingPeriod(samplingPeriod);
00071       setTolerance(tol);
00072       setIndex();
00073 
00074    }  // End of 'Differentiator::Differentiator()'
00075 
00076 
00077 
00078       /* Method to set the sampling period to be used, in seconds.
00079        *
00080        * @param samplingPeriod      Sampling period, in seconds.
00081        */
00082    Differentiator& Differentiator::setSamplingPeriod(double samplingPeriod)
00083    {
00084 
00085          // Check that samplingPeriod is bigger than zero
00086       if (samplingPeriod > 0.0)
00087       {
00088          Ts = samplingPeriod;
00089       }
00090       else
00091       {
00092          Ts = 1.0;                              // By default, 1 s
00093       }
00094 
00095          // Update delay
00096       delay = Ts * 5.0;           // Actualizar si se cambia el diferenciador
00097 
00098       return (*this);
00099 
00100    }  // End of 'Differentiator::setSamplingPeriod()'
00101 
00102 
00103 
00104       /* Method to set the tolerance to be used, in seconds.
00105        *
00106        * @param tol              Tolerance, in seconds.
00107        */
00108    Differentiator& Differentiator::setTolerance(double tol)
00109    {
00110 
00111          // Check that tolerance is bigger than zero
00112       if (tol > 0.0)
00113       {
00114          tolerance = tol;
00115       }
00116       else
00117       {
00118          tolerance = 0.005;                        // By default, 0.005 s
00119       }
00120 
00121       return (*this);
00122 
00123    }  // End of 'Differentiator::setTolerance()'
00124 
00125 
00126 
00127       /* Returns the data value (double) corresponding to provided SourceID
00128        * and SatID.
00129        *
00130        * @param source        Source to be looked for.
00131        * @param satellite     Satellite to be looked for.
00132        */
00133    double Differentiator::getValue( const SourceID& source,
00134                                     const SatID& satellite ) const
00135       throw( SourceIDNotFound, SatIDNotFound )
00136    {
00137 
00138          // Look for the SourceID
00139       std::map<SourceID, std::map<SatID, double> >::const_iterator itObs(
00140                                                 svDerivativesMap.find(source) );
00141       if( itObs != svDerivativesMap.end() )
00142       {
00143 
00144             // Look for the SatID
00145          std::map<SatID, double>::const_iterator itSat(
00146                                              (*itObs).second.find(satellite) );
00147          if( itSat != (*itObs).second.end() )
00148          {
00149             return (*itSat).second;
00150          }
00151          else
00152          {
00153             GPSTK_THROW(SatIDNotFound("SatID not found in map"));
00154          }
00155 
00156       }
00157       else
00158       {
00159          GPSTK_THROW(SourceIDNotFound("SourceID not found in map"));
00160       }
00161 
00162    }  // End of method 'Differentiator::getValue()'
00163 
00164 
00165 
00166       /* Computes the derivatives, which will be stored in
00167        * field 'svDerivativesMap'.
00168        *
00169        * @param epoch     Time of observations.
00170        * @param source    Source of the observations.
00171        * @param gData     Data object holding the data.
00172        */
00173    void Differentiator::Compute( const DayTime& epoch,
00174                                  const SourceID& source,
00175                                  const satTypeValueMap& gData )
00176       throw(ProcessingException)
00177    {
00178 
00179          // Clear the std::map with the derivatives
00180       svDerivativesMap.clear();
00181 
00182       try
00183       {
00184 
00185             // Loop through all the satellites
00186          for( satTypeValueMap::const_iterator it = gData.begin();
00187               it != gData.end();
00188               ++it )
00189          {
00190 
00191                // Get the value to be differentiated
00192             double value(0.0);
00193 
00194             try
00195             {
00196                   // Try to extract value
00197                value = (*it).second.getValue(inputType);
00198             }
00199             catch(...)
00200             {
00201 
00202                   // If value is missing, skip this satellite
00203                continue;
00204 
00205             }
00206 
00207                // Check if satellite currently has entries
00208             std::map<SatID, filterData>::const_iterator itDat(
00209                                        svData[ source ].find( (*it).first ) );
00210             if( itDat == svData[source].end() )
00211             {
00212 
00213                   // If it doesn't have an entry, insert one
00214                filterData fData;
00215 
00216                   // Configure with sampling period
00217                fData.filter.setT(Ts);
00218 
00219                   // Insert into map
00220                svData[ source ][ (*it).first ] = fData;
00221 
00222             }
00223 
00224 
00225                // Place to store if there was a cycle slip. False by default
00226             bool csflag(false);
00227 
00228 
00229                // Check if we want to use satellite arcs of cycle slip flags
00230             if(useSatArcs)
00231             {
00232 
00233                double arcN(0.0);
00234 
00235                try
00236                {
00237 
00238                      // Try to extract satellite's arc value
00239                   arcN = (*it).second.getValue(TypeID::satArc);
00240 
00241                }
00242                catch(...)
00243                {
00244 
00245                      // If data is missing we will ignore this satellite
00246                   continue;
00247 
00248                }
00249 
00250 
00251                   // Check if satellite arc has changed
00252                if( svData[ source ][ (*it).first ].arcNumber != arcN )
00253                {
00254 
00255                      // Set flag
00256                   csflag = true;
00257 
00258                      // Update satellite arc information
00259                   svData[ source ][(*it).first].arcNumber = arcN;
00260                }
00261 
00262             }  // End of first part of 'if(useSatArcs)'
00263             else
00264             {
00265 
00266                double flag(0.0);
00267 
00268                try
00269                {
00270 
00271                      // Try to extract satellite's cycle slip flag
00272                   flag = (*it).second.getValue(watchCSFlag);
00273 
00274                }
00275                catch(...)
00276                {
00277 
00278                      // If data is missing we will ignore this satellite
00279                   continue;
00280 
00281                }
00282 
00283                   // Check if there was a cycle slip
00284                if( flag > 0.0)
00285                {
00286                      // Set flag
00287                   csflag = true;
00288                }
00289 
00290             }  // End of second part of 'if(useSatArcs)...'
00291 
00292                // Compute time difference (in seconds) between this epoch and
00293                // previous epoch.
00294             double tDiff( std::abs(epoch -
00295                               svData[ source ][ (*it).first ].previousEpoch) );
00296 
00297                // If there was an arc change or cycle slip, or there was a
00298                // data gap (time difference bigger than sampling time), let's
00299                // reset the differentiator
00300             if( ( csflag ) ||
00301                 ( std::abs( tDiff - Ts ) > tolerance ) )
00302             {
00303 
00304                   // Filter is reset, and method 'isValid()' will return false
00305                svData[ source ][ (*it).first ].filter.Reset();
00306             }
00307 
00308                // Update 'previousEpoch'
00309             svData[ source ][ (*it).first ].previousEpoch = epoch;
00310 
00311                // Compute derivative
00312             double result( svData[source][(*it).first].filter.Compute(value) );
00313 
00314                // If result is valid, insert value in derivatives map
00315             if( svData[ source ][ (*it).first ].filter.isValid() )
00316             {
00317                svDerivativesMap[ source ][ (*it).first ] = result;
00318             }
00319 
00320          }
00321 
00322             // Let's return
00323          return;
00324 
00325       }
00326       catch(Exception& u)
00327       {
00328             // Throw an exception if something unexpected happens
00329          ProcessingException e( getClassName() + ":"
00330                                 + StringUtils::asString( getIndex() ) + ":"
00331                                 + u.what() );
00332 
00333          GPSTK_THROW(e);
00334 
00335       }
00336 
00337    }  // End of method 'Differentiator::Process()'
00338 
00339 
00340 
00341       /* Returns a gnnsSatTypeValue object, adding the new data generated
00342        *  when calling this object.
00343        *
00344        * @param gData    Data object holding the data.
00345        */
00346    gnssSatTypeValue& Differentiator::Process(gnssSatTypeValue& gData)
00347       throw(ProcessingException)
00348    {
00349 
00350       try
00351       {
00352 
00353          Compute(gData.header.epoch, gData.header.source, gData.body);
00354 
00355          return gData;
00356 
00357       }
00358       catch(Exception& u)
00359       {
00360             // Throw an exception if something unexpected happens
00361          ProcessingException e( getClassName() + ":"
00362                                 + StringUtils::asString( getIndex() ) + ":"
00363                                 + u.what() );
00364 
00365          GPSTK_THROW(e);
00366 
00367       }
00368 
00369    }  // End of method 'Differentiator::Process()'
00370 
00371 
00372 
00373       /* Returns a gnnsRinex object, adding the new data generated when
00374        *  calling this object.
00375        *
00376        * @param gData    Data object holding the data.
00377        */
00378    gnssRinex& Differentiator::Process(gnssRinex& gData)
00379       throw(ProcessingException)
00380    {
00381 
00382       try
00383       {
00384 
00385          Compute(gData.header.epoch, gData.header.source, gData.body);
00386 
00387          return gData;
00388 
00389       }
00390       catch(Exception& u)
00391       {
00392             // Throw an exception if something unexpected happens
00393          ProcessingException e( getClassName() + ":"
00394                                 + StringUtils::asString( getIndex() ) + ":"
00395                                 + u.what() );
00396 
00397          GPSTK_THROW(e);
00398 
00399       }
00400 
00401    }  // End of method 'Differentiator::Process()'
00402 
00403 
00404 
00405       /* Returns a gnssDataMap object, adding the new data generated when
00406        * calling this object.
00407        *
00408        * @param gData    Data object holding the data.
00409        */
00410    gnssDataMap& Differentiator::Process(gnssDataMap& gData)
00411       throw(ProcessingException)
00412    {
00413 
00414       try
00415       {
00416 
00417             // Iterate through all the data structure
00418          for( gnssDataMap::iterator itGdata = gData.begin();
00419               itGdata != gData.end();
00420               ++itGdata )
00421          {
00422 
00423                // Get epoch
00424             DayTime workEpoch( (*itGdata).first );
00425 
00426                // Get a set with the SourceID in current data element
00427             SourceIDSet sourceSet( (*itGdata).second.getSourceIDSet() );
00428 
00429                // Loop through all the SourceID's
00430             for( SourceIDSet::const_iterator itSource = sourceSet.begin();
00431                  itSource != sourceSet.end();
00432                  ++itSource )
00433             {
00434 
00435                   // Compute the derivatives
00436                Compute( workEpoch,
00437                        (*itSource),
00438                        (*itGdata).second[ (*itSource) ] );
00439 
00440                   // We have the derivatives, so let's insert them into GDS
00441                for( std::map<SatID, double>::const_iterator
00442                               itSat = svDerivativesMap[ (*itSource) ].begin();
00443                     itSat != svDerivativesMap[ (*itSource) ].end();
00444                     ++itSat )
00445                {
00446 
00447                   double value( svDerivativesMap[(*itSource)][(*itSat).first] );
00448 
00449                      // Insert the derivatives in the right place
00450                   try
00451                   {
00452 
00453                         // We must take into account the delay
00454                      gData.insertValue( (workEpoch - delay),
00455                                         (*itSource),
00456                                         (*itSat).first,
00457                                         outputType,
00458                                         value );
00459 
00460                   }
00461                   catch(...)
00462                   {
00463                         // If it wasn't possible to introduce the derivative,
00464                         // let's continue
00465                      continue;
00466                   }
00467 
00468                }  // End of 'for( std::map<SatID, double>::const_iterator itSat'
00469 
00470             }  // End of 'for( SourceIDSet::const_iterator itSource = ...'
00471 
00472          }  // End of 'for( gnssDataMap::iterator itGdata = gData.begin();'
00473 
00474             // Let's return
00475          return gData;
00476 
00477       }
00478       catch(Exception& u)
00479       {
00480             // Throw an exception if something unexpected happens
00481          ProcessingException e( getClassName() + ":"
00482                                 + StringUtils::asString( getIndex() ) + ":"
00483                                 + u.what() );
00484 
00485          GPSTK_THROW(e);
00486 
00487       }
00488 
00489    }  // End of method 'Differentiator::Process()'
00490 
00491 
00492 
00493 }  // End of namespace gpstk

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