ComputeWindUp.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: ComputeWindUp.cpp 2579 2011-04-27 04:02:02Z architest $"
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 ). 2007, 2008, 2009, 2011
00027 //
00028 //============================================================================
00029 
00030 
00031 #include "ComputeWindUp.hpp"
00032 
00033 
00034 namespace gpstk
00035 {
00036 
00037       // Index initially assigned to this class
00038    int ComputeWindUp::classIndex = 4500000;
00039 
00040 
00041       // Returns an index identifying this object.
00042    int ComputeWindUp::getIndex() const
00043    { return index; }
00044 
00045 
00046       // Returns a string identifying this object.
00047    std::string ComputeWindUp::getClassName() const
00048    { return "ComputeWindUp"; }
00049 
00050 
00051 
00052       /* Returns a satTypeValueMap object, adding the new data generated when
00053        * calling this object.
00054        *
00055        * @param time      Epoch corresponding to the data.
00056        * @param gData     Data object holding the data.
00057        */
00058    satTypeValueMap& ComputeWindUp::Process( const DayTime& time,
00059                                             satTypeValueMap& gData )
00060       throw(ProcessingException)
00061    {
00062 
00063       try
00064       {
00065 
00066             // Compute Sun position at this epoch
00067          SunPosition sunPosition;
00068          Triple sunPos(sunPosition.getPosition(time));
00069 
00070             // Define a Triple that will hold satellite position, in ECEF
00071          Triple svPos(0.0, 0.0, 0.0);
00072 
00073          SatIDSet satRejectedSet;
00074 
00075             // Loop through all the satellites
00076          for ( satTypeValueMap::iterator it = gData.begin();
00077                it != gData.end();
00078                ++it )
00079          {
00080 
00081                // First check if this satellite has previous arc information
00082             if( satArcMap.find( (*it).first ) == satArcMap.end() )
00083             {
00084                   // If it doesn't have an entry, insert one
00085                satArcMap[ (*it).first ] = 0.0;
00086             };
00087 
00088                // Then, check both if there is arc information, and if current
00089                // arc number is different from arc number in storage (which
00090                // means a cycle slip happened)
00091             if ( (*it).second.find(TypeID::satArc) != (*it).second.end() &&
00092                  (*it).second(TypeID::satArc) != satArcMap[ (*it).first ] )
00093             {
00094                   // If different, update satellite arc in storage
00095                satArcMap[ (*it).first ] = (*it).second(TypeID::satArc);
00096 
00097                   // Reset phase information
00098                phase_satellite[ (*it).first ].previousPhase = 0.0;
00099                phase_station[ (*it).first ].previousPhase = 0.0;
00100 
00101             }
00102 
00103 
00104                // Use ephemeris if satellite position is not already computed
00105             if( ( (*it).second.find(TypeID::satX) == (*it).second.end() ) ||
00106                 ( (*it).second.find(TypeID::satY) == (*it).second.end() ) ||
00107                 ( (*it).second.find(TypeID::satZ) == (*it).second.end() ) )
00108             {
00109 
00110                if(pEphemeris==NULL)
00111                {
00112 
00113                      // If ephemeris is missing, then remove all satellites
00114                   satRejectedSet.insert( (*it).first );
00115 
00116                   continue;
00117 
00118                }
00119                else
00120                {
00121 
00122                      // Try to get satellite position
00123                      // if it is not already computed
00124                   try
00125                   {
00126                         // For our purposes, position at receive time
00127                         // is fine enough
00128                      Xvt svPosVel(pEphemeris->getXvt( (*it).first, time ));
00129 
00130                         // If everything is OK, then continue processing.
00131                      svPos[0] = svPosVel.x.theArray[0];
00132                      svPos[1] = svPosVel.x.theArray[1];
00133                      svPos[2] = svPosVel.x.theArray[2];
00134 
00135                   }
00136                   catch(...)
00137                   {
00138 
00139                         // If satellite is missing, then schedule it
00140                         // for removal
00141                      satRejectedSet.insert( (*it).first );
00142 
00143                      continue;
00144 
00145                   }
00146 
00147                }
00148 
00149             }
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             }  // End of 'if( ( (*it).second.find(TypeID::satX) == ...'
00159 
00160 
00161                // Let's get wind-up value in radians, and insert it
00162                // into GNSS data structure.
00163             (*it).second[TypeID::windUp] =
00164                getWindUp((*it).first, time, svPos, sunPos);
00165 
00166          }  // End of 'for (it = gData.begin(); it != gData.end(); ++it)'
00167 
00168             // Remove satellites with missing data
00169          gData.removeSatID(satRejectedSet);
00170 
00171          return gData;
00172 
00173       }
00174       catch(Exception& u)
00175       {
00176             // Throw an exception if something unexpected happens
00177          ProcessingException e( getClassName() + ":"
00178                                 + StringUtils::asString( getIndex() ) + ":"
00179                                 + u.what() );
00180 
00181          GPSTK_THROW(e);
00182 
00183       }
00184 
00185    }  // End of method 'ComputeWindUp::Process()'
00186 
00187 
00188 
00189       /* Sets name of "PRN_GPS"-like file containing satellite data.
00190        * @param name      Name of satellite data file.
00191        */
00192    ComputeWindUp& ComputeWindUp::setFilename(const string& name)
00193    {
00194 
00195       fileData = name;
00196       satData.open(fileData);
00197 
00198       return (*this);
00199 
00200    }  // End of method 'ComputeWindUp::setFilename()'
00201 
00202 
00203 
00204       /* Compute the value of the wind-up, in radians.
00205        * @param sat       Satellite IDmake
00206        * @param time      Epoch of interest
00207        * @param satpos    Satellite position, as a Triple
00208        * @param sunpos    Sun position, as a Triple
00209        *
00210        * @return Wind-up computation, in radians
00211        */
00212    double ComputeWindUp::getWindUp( const SatID& satid,
00213                                     const DayTime& time,
00214                                     const Triple& sat,
00215                                     const Triple& sunPosition )
00216    {
00217 
00218          // Get satellite rotation angle
00219 
00220          // Get vector from Earth mass center to receiver
00221       Triple rxPos(nominalPos.X(), nominalPos.Y(), nominalPos.Z());
00222 
00223          // Vector from SV to Sun center of mass
00224       Triple gps_sun( sunPosition-sat );
00225 
00226          // Define rk: Unitary vector from satellite to Earth mass center
00227       Triple rk( ( (-1.0)*(sat.unitVector()) ) );
00228 
00229          // Define rj: rj = rk x gps_sun, then make sure it is unitary
00230       Triple rj( (rk.cross(gps_sun)).unitVector() );
00231 
00232          // Define ri: ri = rj x rk, then make sure it is unitary
00233          // Now, ri, rj, rk form a base in the satellite body reference
00234          // frame, expressed in the ECEF reference frame
00235       Triple ri( (rj.cross(rk)).unitVector() );
00236 
00237 
00238          // Compute unitary vector vector from satellite to RECEIVER
00239       Triple rrho( (rxPos-sat).unitVector() );
00240 
00241          // Projection of "rk" vector to line of sight vector (rrho)
00242       double zk(rrho.dot(rk));
00243 
00244          // Get a vector without components on rk (i.e., belonging
00245          // to ri, rj plane)
00246       Triple dpp(rrho-zk*rk);
00247 
00248          // Compute dpp components in ri, rj plane
00249       double xk(dpp.dot(ri));
00250       double yk(dpp.dot(rj));
00251 
00252          // Compute satellite rotation angle, in radians
00253       double alpha1(std::atan2(yk,xk));
00254 
00255 
00256          // Get receiver rotation angle
00257 
00258          // Redefine rk: Unitary vector from Receiver to Earth mass center
00259       rk = (-1.0)*(rxPos.unitVector());
00260 
00261          // Let's define a NORTH unitary vector in the Up, East, North
00262          // (UEN) topocentric reference frame
00263       Triple delta(0.0, 0.0, 1.0);
00264 
00265          // Rotate delta to XYZ reference frame
00266       delta =
00267          (delta.R2(nominalPos.geodeticLatitude())).R3(-nominalPos.longitude());
00268 
00269 
00270          // Computation of reference trame unitary vectors for receiver
00271          // rj = rk x delta, and make it unitary
00272       rj = (rk.cross(delta)).unitVector();
00273 
00274          // ri = rj x rk, and make it unitary
00275       ri = (rj.cross(rk)).unitVector();
00276 
00277          // Projection of "rk" vector to line of sight vector (rrho)
00278       zk = rrho.dot(rk);
00279 
00280          // Get a vector without components on rk (i.e., belonging
00281          // to ri, rj plane)
00282       dpp = rrho-zk*rk;
00283 
00284          // Compute dpp components in ri, rj plane
00285       xk = dpp.dot(ri);
00286       yk = dpp.dot(rj);
00287 
00288          // Compute receiver rotation angle, in radians
00289       double alpha2(std::atan2(yk,xk));
00290 
00291       double wind_up(0.0);
00292 
00293          // Find out if satellite belongs to block "IIR", because
00294          // satellites of block IIR have a 180 phase shift
00295       if(satData.getBlock( satid, time ) == "IIR")
00296       {
00297          wind_up = PI;
00298       }
00299 
00300       alpha1 = alpha1 + wind_up;
00301 
00302       double da1(alpha1-phase_satellite[satid].previousPhase);
00303 
00304       double da2(alpha2-phase_station[satid].previousPhase);
00305 
00306          // Let's avoid problems when passing from 359 to 0 degrees.
00307       phase_satellite[satid].previousPhase += std::atan2( std::sin(da1),
00308                                                           std::cos(da1) );
00309 
00310       phase_station[satid].previousPhase += std::atan2( std::sin(da2),
00311                                                         std::cos(da2) );
00312 
00313          // Compute wind up effect in radians
00314       wind_up = phase_satellite[satid].previousPhase -
00315                 phase_station[satid].previousPhase;
00316 
00317       return wind_up;
00318 
00319    }  // End of method 'ComputeWindUp::getWindUp()'
00320 
00321 
00322 
00323 }  // End of namespace gpstk

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