CorrectObservables.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: CorrectObservables.cpp 1770 2009-03-04 13:10: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, 2009
00028 //
00029 //============================================================================
00030 
00031 
00032 #include "CorrectObservables.hpp"
00033 
00034 
00035 namespace gpstk
00036 {
00037 
00038       // Index initially assigned to this class
00039    int CorrectObservables::classIndex = 4300000;
00040 
00041 
00042       // Returns an index identifying this object.
00043    int CorrectObservables::getIndex() const
00044    { return index; }
00045 
00046 
00047       // Returns a string identifying this object.
00048    std::string CorrectObservables::getClassName() const
00049    { return "CorrectObservables"; }
00050 
00051 
00052 
00053       /* Returns a satTypeValueMap object, adding the new data generated
00054        * when calling this object.
00055        *
00056        * @param time      Epoch corresponding to the data.
00057        * @param gData     Data object holding the data.
00058        */
00059    satTypeValueMap& CorrectObservables::Process( const DayTime& time,
00060                                                  satTypeValueMap& gData )
00061       throw(ProcessingException)
00062    {
00063 
00064       try
00065       {
00066 
00067             // Compute station latitude and longitude
00068          double lat(nominalPos.geodeticLatitude());
00069          double lon(nominalPos.longitude());
00070 
00071             // Define station position as a Triple, in ECEF
00072          Triple staPos( nominalPos.getX(),
00073                         nominalPos.getY(),
00074                         nominalPos.getZ() );
00075 
00076 
00077             // Compute initial displacement vectors, in meters [UEN]
00078          Triple initialBias( extraBiases + monumentVector );
00079          Triple dispL1( initialBias );
00080          Triple dispL2( initialBias );
00081          Triple dispL5( initialBias );
00082          Triple dispL6( initialBias );
00083          Triple dispL7( initialBias );
00084          Triple dispL8( initialBias );
00085 
00086 
00087             // Check if we have a valid Antenna object
00088          if( antenna.isValid() )
00089          {
00090                // Compute phase center offsets
00091             L1PhaseCenter = antenna.getAntennaEccentricity( Antenna::G01 );
00092             L2PhaseCenter = antenna.getAntennaEccentricity( Antenna::G02 );
00093          }
00094 
00095 
00096 
00097             // Define a Triple that will hold satellite position, in ECEF
00098          Triple svPos(0.0, 0.0, 0.0);
00099 
00100          SatIDSet satRejectedSet;
00101 
00102             // Loop through all the satellites
00103          satTypeValueMap::iterator it;
00104          for (it = gData.begin(); it != gData.end(); ++it)
00105          {
00106 
00107                // Use ephemeris if satellite position is not already computed
00108             if( ( (*it).second.find(TypeID::satX) == (*it).second.end() ) ||
00109                 ( (*it).second.find(TypeID::satY) == (*it).second.end() ) ||
00110                 ( (*it).second.find(TypeID::satZ) == (*it).second.end() ) )
00111             {
00112 
00113                if(pEphemeris==NULL)
00114                {
00115 
00116                   // If ephemeris is missing, then remove all satellites
00117                   satRejectedSet.insert( (*it).first );
00118 
00119                   continue;
00120                }
00121                else
00122                {
00123                      // Try to get satellite position
00124                      // if it is not already computed
00125                   try
00126                   {
00127                         // For our purposes, position at receive time
00128                         // is fine enough
00129                      Xvt svPosVel(pEphemeris->getXvt( (*it).first, time ));
00130 
00131                         // If everything is OK, then continue processing.
00132                      svPos[0] = svPosVel.x.theArray[0];
00133                      svPos[1] = svPosVel.x.theArray[1];
00134                      svPos[2] = svPosVel.x.theArray[2];
00135 
00136                   }
00137                   catch(...)
00138                   {
00139 
00140                         // If satellite is missing, then schedule it
00141                         // for removal
00142                      satRejectedSet.insert( (*it).first );
00143 
00144                      continue;
00145 
00146                   }
00147                }
00148 
00149             }  // End of 'if( ( (*it).second.find(TypeID::satX) == ...'
00150             else
00151             {
00152 
00153                   // Get satellite position out of GDS
00154                svPos[0] = (*it).second[TypeID::satX];
00155                svPos[1] = (*it).second[TypeID::satY];
00156                svPos[2] = (*it).second[TypeID::satZ];
00157 
00158             }
00159 
00160 
00161                // Declare the variables where antenna PC variations
00162                // will be stored. Only values for L1 and L2 will be
00163                // computed, in UEN system
00164             Triple L1Var( 0.0, 0.0, 0.0 );
00165             Triple L2Var( 0.0, 0.0, 0.0 );
00166 
00167                // Check if we have a valid Antenna object
00168             if( antenna.isValid() )
00169             {
00170 
00171                   // Check if we have elevation information
00172                if( (*it).second.find(TypeID::elevation) != (*it).second.end() )
00173                {
00174 
00175                      // Get elevation value
00176                   double elev( (*it).second[TypeID::elevation] );
00177 
00178                      // Check if azimuth is also required
00179                   if( !useAzimuth )
00180                   {
00181 
00182                         // In this case, use methods that only need elevation
00183                      try
00184                      {
00185 
00186                            // Compute phase center variation values
00187                         L1Var = antenna.getAntennaPCVariation( Antenna::G01,
00188                                                                elev );
00189                         L2Var = antenna.getAntennaPCVariation( Antenna::G02,
00190                                                                elev );
00191 
00192                      }
00193                      catch(InvalidRequest& ir)
00194                      {
00195                            // Throw an exception if something unexpected
00196                            // happens
00197                         ProcessingException e( getClassName() + ":"
00198                            + StringUtils::asString( getIndex() ) + ":"
00199                            + "Unexpected problem found when trying to "
00200                            + "compute antenna offsets" );
00201 
00202                         GPSTK_THROW(e);
00203                      }  // End fo 'try'
00204 
00205                   }
00206                   else
00207                   {
00208 
00209                         // Check if we have azimuth information
00210                      if( (*it).second.find(TypeID::azimuth) !=
00211                                                             (*it).second.end() )
00212                      {
00213 
00214                            // Get azimuth value
00215                         double azim( (*it).second[TypeID::azimuth] );
00216 
00217                            // Use a gentle fallback mechanism to get antenna
00218                            // phase center variations
00219                         try
00220                         {
00221                               // Compute phase center variation values
00222                            L1Var = antenna.getAntennaPCVariation( Antenna::G01,
00223                                                                   elev,
00224                                                                   azim );
00225 
00226                            L2Var = antenna.getAntennaPCVariation( Antenna::G02,
00227                                                                   elev,
00228                                                                   azim );
00229 
00230                         }
00231                         catch(InvalidRequest& ir)
00232                         {
00233                               // We  "graceful degrade" to a simpler mechanism
00234                            try
00235                            {
00236 
00237                                  // Compute phase center variation values
00238                               L1Var =
00239                                  antenna.getAntennaPCVariation( Antenna::G01,
00240                                                                 elev );
00241 
00242                               L2Var =
00243                                  antenna.getAntennaPCVariation( Antenna::G02,
00244                                                                 elev );
00245 
00246                            }
00247                            catch(InvalidRequest& ir)
00248                            {
00249                                  // Throw an exception if something unexpected
00250                                  // happens
00251                               ProcessingException e( getClassName() + ":"
00252                                  + StringUtils::asString( getIndex() ) + ":"
00253                                  + "Unexpected problem found when trying to "
00254                                  + "compute antenna offsets" );
00255 
00256                               GPSTK_THROW(e);
00257                            }  // End fo 'try'
00258 
00259                         }  // End fo 'try'
00260 
00261                      }
00262                      else
00263                      {
00264 
00265                            // Throw an exception if something unexpected happens
00266                         ProcessingException e( getClassName() + ":"
00267                                  + StringUtils::asString( getIndex() ) + ":"
00268                                  + "Azimuth information could not be found, "
00269                                  + "so antenna PC offsets can not be computed");
00270 
00271                         GPSTK_THROW(e);
00272 
00273                      }  // End of 'if( (*it).second.find(TypeID::azimuth) !=...'
00274 
00275                   }  // End of 'if( !useAzimuth )'
00276 
00277                }
00278                else
00279                {
00280 
00281                      // Throw an exception if there is no elevation data
00282                   ProcessingException e( getClassName() + ":"
00283                               + StringUtils::asString( getIndex() ) + ":"
00284                               + "Elevation information could not be found, "
00285                               + "so antenna PC offsets can not be computed" );
00286 
00287                   GPSTK_THROW(e);
00288 
00289                }  // End of 'if( (*it).second.find(TypeID::elevation) != ...'
00290 
00291 
00292             }  // End of 'if( antenna.isValid() )...'
00293 
00294 
00295                // Update displacement vectors with current phase centers
00296             Triple dL1( dispL1 + L1PhaseCenter - L1Var );
00297             Triple dL2( dispL2 + L2PhaseCenter - L2Var );
00298             Triple dL5( dispL5 + L5PhaseCenter );
00299             Triple dL6( dispL6 + L6PhaseCenter );
00300             Triple dL7( dispL7 + L7PhaseCenter );
00301             Triple dL8( dispL8 + L8PhaseCenter );
00302 
00303                // Compute vector station-satellite, in ECEF
00304             Triple ray(svPos - staPos);
00305 
00306                // Rotate vector ray to UEN reference frame
00307             ray = (ray.R3(lon)).R2(-lat);
00308 
00309                // Convert ray to an unitary vector
00310             ray = ray.unitVector();
00311 
00312                // Compute corrections = displacement vectors components
00313                // along ray direction.
00314             double corrL1(dL1.dot(ray));
00315             double corrL2(dL2.dot(ray));
00316             double corrL5(dL5.dot(ray));
00317             double corrL6(dL6.dot(ray));
00318             double corrL7(dL7.dot(ray));
00319             double corrL8(dL8.dot(ray));
00320 
00321 
00322                // Find which observables are present, and then
00323                // apply corrections
00324 
00325                // Look for C1
00326             if( (*it).second.find(TypeID::C1) != (*it).second.end() )
00327             {
00328                (*it).second[TypeID::C1] = (*it).second[TypeID::C1] + corrL1;
00329             };
00330 
00331                // Look for P1
00332             if( (*it).second.find(TypeID::P1) != (*it).second.end() )
00333             {
00334                (*it).second[TypeID::P1] = (*it).second[TypeID::P1] + corrL1;
00335             };
00336 
00337                // Look for L1
00338             if( (*it).second.find(TypeID::L1) != (*it).second.end() )
00339             {
00340                (*it).second[TypeID::L1] = (*it).second[TypeID::L1] + corrL1;
00341             };
00342 
00343                // Look for C2
00344             if( (*it).second.find(TypeID::C2) != (*it).second.end() )
00345             {
00346                (*it).second[TypeID::C2] = (*it).second[TypeID::C2] + corrL2;
00347             };
00348 
00349                // Look for P2
00350             if( (*it).second.find(TypeID::P2) != (*it).second.end() )
00351             {
00352                (*it).second[TypeID::P2] = (*it).second[TypeID::P2] + corrL2;
00353             };
00354 
00355                // Look for L2
00356             if( (*it).second.find(TypeID::L2) != (*it).second.end() )
00357             {
00358                (*it).second[TypeID::L2] = (*it).second[TypeID::L2] + corrL2;
00359             };
00360 
00361                // Look for C5
00362             if( (*it).second.find(TypeID::C5) != (*it).second.end() )
00363             {
00364                (*it).second[TypeID::C5] = (*it).second[TypeID::C5] + corrL5;
00365             };
00366 
00367                // Look for L5
00368             if( (*it).second.find(TypeID::L5) != (*it).second.end() )
00369             {
00370                (*it).second[TypeID::L5] = (*it).second[TypeID::L5] + corrL5;
00371             };
00372 
00373                // Look for C6
00374             if( (*it).second.find(TypeID::C6) != (*it).second.end() )
00375             {
00376                (*it).second[TypeID::C6] = (*it).second[TypeID::C6] + corrL6;
00377             };
00378 
00379                // Look for L6
00380             if( (*it).second.find(TypeID::L6) != (*it).second.end() )
00381             {
00382                (*it).second[TypeID::L6] = (*it).second[TypeID::L6] + corrL6;
00383             };
00384 
00385                // Look for C7
00386             if( (*it).second.find(TypeID::C7) != (*it).second.end() )
00387             {
00388                (*it).second[TypeID::C7] = (*it).second[TypeID::C7] + corrL7;
00389             };
00390 
00391                // Look for L7
00392             if( (*it).second.find(TypeID::L7) != (*it).second.end() )
00393             {
00394                (*it).second[TypeID::L7] = (*it).second[TypeID::L7] + corrL7;
00395             };
00396 
00397                // Look for C8
00398             if( (*it).second.find(TypeID::C8) != (*it).second.end() )
00399             {
00400                (*it).second[TypeID::C8] = (*it).second[TypeID::C8] + corrL8;
00401             };
00402 
00403                // Look for L8
00404             if( (*it).second.find(TypeID::L8) != (*it).second.end() )
00405             {
00406                (*it).second[TypeID::L8] = (*it).second[TypeID::L8] + corrL8;
00407             };
00408 
00409          }
00410 
00411             // Remove satellites with missing data
00412          gData.removeSatID(satRejectedSet);
00413 
00414          return gData;
00415 
00416       }
00417       catch(Exception& u)
00418       {
00419             // Throw an exception if something unexpected happens
00420          ProcessingException e( getClassName() + ":"
00421                                 + StringUtils::asString( getIndex() ) + ":"
00422                                 + u.what() );
00423 
00424          GPSTK_THROW(e);
00425 
00426       }
00427 
00428    }  // End of method 'CorrectObservables::Process()'
00429 
00430 
00431 }  // End of namespace gpstk

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