PhaseWindup.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: PhaseWindup.cpp 2741 2011-06-22 16:37:02Z nwu $"
00002 
00003 //============================================================================
00004 //
00005 //  This file is part of GPSTk, the GPS Toolkit.
00006 //
00007 //  The GPSTk is free software; you can redistribute it and/or modify
00008 //  it under the terms of the GNU Lesser General Public License as published
00009 //  by the Free Software Foundation; either version 2.1 of the License, or
00010 //  any later version.
00011 //
00012 //  The GPSTk is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU Lesser General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU Lesser General Public
00018 //  License along with GPSTk; if not, write to the Free Software Foundation,
00019 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 //  Copyright 2004, The University of Texas at Austin
00022 //
00023 //============================================================================
00024 
00025 //============================================================================
00026 //
00027 //This software developed by Applied Research Laboratories at the University of
00028 //Texas at Austin, under contract to an agency or agencies within the U.S.
00029 //Department of Defense. The U.S. Government retains all rights to use,
00030 //duplicate, distribute, disclose, or release this software.
00031 //
00032 //Pursuant to DoD Directive 523024
00033 //
00034 // DISTRIBUTION STATEMENT A: This software has been approved for public
00035 //                           release, distribution is unlimited.
00036 //
00037 //=============================================================================
00038 
00045 // -----------------------------------------------------------------------------------
00046 // GPSTk includes
00047 #include "Matrix.hpp"
00048 #include "geometry.hpp"             // DEG_TO_RAD
00049 #include "icd_200_constants.hpp"    // TWO_PI
00050 // geomatics
00051 #include "PhaseWindup.hpp"
00052 #include "SunEarthSatGeometry.hpp"
00053 
00054 using namespace std;
00055 
00056 namespace gpstk
00057 {
00058 
00059 // -----------------------------------------------------------------------------------
00060 // Compute the phase windup, in cycles, given the time, the unit vector from receiver
00061 // to transmitter, and the west and north unit vectors at the receiver, all in ECEF.
00062 // YR is the West unit vector, XR is the North unit vector, at the receiver.
00063 // shadow is the fraction of the sun's area not visible at the satellite.
00064 // Previous value is needed to ensure continuity and prevent 1-cycle ambiguities.
00065 double PhaseWindup(double& prev,         // previous return value
00066                    DayTime& tt,          // epoch of interest
00067                    Position& SV,         // satellite position
00068                    Position& Rx2Tx,      // unit vector from receiver to satellite
00069                    Position& YR,         // west unit vector at receiver
00070                    Position& XR,         // north unit vector at receiver
00071                    SolarSystem& SSEph,   // solar system ephemeris
00072                    EarthOrientation& EO, // earth orientation at tt
00073                    double& shadow,       // fraction of sun not visible at satellite
00074                    bool isBlockR)        // true for Block IIR satellites
00075    throw(Exception)
00076 {
00077 try {
00078    double d,windup;
00079    Position DR,DT;
00080    Position TR = -1.0 * Rx2Tx;         // transmitter to receiver
00081 
00082    // get satellite attitude
00083    Position XT,YT,ZT;
00084    Matrix<double> Att = SatelliteAttitude(tt, SV, SSEph, EO, shadow);
00085    XT = Position(Att(0,0),Att(0,1),Att(0,2));      // Cartesian is default
00086    YT = Position(Att(1,0),Att(1,1),Att(1,2));
00087    ZT = Position(Att(2,0),Att(2,1),Att(2,2));
00088 
00089    // NB. Block IIR has X (ie the effective dipole orientation) in the -XT direction.
00090    // Ref. Kouba(2009) GPS Solutions 13, pp1-12.
00091    // In fact it should be a rotation by pi about Z, producing a constant offset.
00092    //if(isBlockR) {
00093    //   XT = Position(-Att(0,0),-Att(0,1),-Att(0,2));
00094    //   YT = Position(-Att(1,0),-Att(1,1),-Att(1,2));
00095    //}
00096 
00097    // compute effective dipoles at receiver and transmitter
00098    // Ref Kouba(2009) Using IGS Products; note sign diff. <=> East(ref) West(here)
00099    // NB. switching second sign between the two eqns <=> overall sign windup
00100    DR = XR - TR * TR.dot(XR) + Position(TR.cross(YR));
00101    DT = XT - TR * TR.dot(XT) - Position(TR.cross(YT));
00102 
00103    // normalize
00104    d = 1.0/DR.mag();
00105    DR = d * DR;
00106    d = 1.0/DT.mag();
00107    DT = d * DT;
00108 
00109    windup = ::acos(DT.dot(DR)) / TWO_PI;             // cycles
00110    if(TR.dot(DR.cross(DT)) < 0.) windup *= -1.0;
00111 
00112    // adjust by 2pi if necessary
00113    d = windup-prev;
00114    windup -= int(d + (d < 0.0 ? -0.5 : 0.5));
00115 
00116    return windup;
00117 }
00118 catch(Exception& e) { GPSTK_RETHROW(e); }
00119 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00120 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00121 }
00122 
00123 // -----------------------------------------------------------------------------------
00124 // Version without JPL solar system ephemeris - uses a lower quality solar position.
00125 // Compute the phase windup, in cycles, given the time, the unit vector from receiver
00126 // to transmitter, and the west and north unit vectors at the receiver, all in ECEF.
00127 // YR is the West unit vector, XR is the North unit vector, at the receiver.
00128 // shadow is the fraction of the sun's area not visible at the satellite.
00129 double PhaseWindup(double& prev,       // previous return value
00130                    DayTime& tt,        // epoch of interest
00131                    Position& SV,       // satellite position
00132                    Position& Rx2Tx,    // unit vector from receiver to satellite
00133                    Position& YR,       // west unit vector at receiver
00134                    Position& XR,       // north unit vector at receiver
00135                    double& shadow,     // fraction of sun not visible at satellite
00136                    bool isBlockR)        // true for Block IIR satellites
00137    throw(Exception)
00138 {
00139 try {
00140    double d,windup=0.0;
00141    Position DR,DT;
00142    Position TR = -1.0 * Rx2Tx;         // transmitter to receiver
00143 
00144    // get satellite attitude
00145    Position XT,YT,ZT;
00146    Matrix<double> Att = SatelliteAttitude(tt, SV, shadow);
00147    XT = Position(Att(0,0),Att(0,1),Att(0,2));      // Cartesian is default
00148    YT = Position(Att(1,0),Att(1,1),Att(1,2));
00149    ZT = Position(Att(2,0),Att(2,1),Att(2,2));
00150 
00151    // NB. Block IIR has X (ie the effective dipole orientation) in the -XT direction.
00152    // Ref. Kouba(2009) GPS Solutions 13, pp1-12.
00153    if(isBlockR) XT = Position(-Att(0,0),-Att(0,1),-Att(0,2));
00154 
00155    // compute effective dipoles at receiver and transmitter
00156    // Ref Kouba(2009) Using IGS Products; note sign diff. <=> East(ref) West(here)
00157    // NB. switching second sign between the two eqns <=> overall sign windup
00158    DR = XR - TR * TR.dot(XR) + Position(TR.cross(YR));
00159    DT = XT - TR * TR.dot(XT) - Position(TR.cross(YT));
00160 
00161    // normalize
00162    d = 1.0/DR.mag();
00163    DR = d * DR;
00164    d = 1.0/DT.mag();
00165    DT = d * DT;
00166 
00167    windup = ::acos(DT.dot(DR)) / TWO_PI;
00168    if(TR.dot(DR.cross(DT)) < 0.) windup *= -1.0;
00169 
00170    // adjust by 2pi if necessary
00171    d = windup-prev;
00172    windup -= int(d + (d < 0.0 ? -0.5 : 0.5));
00173 
00174    return windup;
00175 }
00176 catch(Exception& e) { GPSTK_RETHROW(e); }
00177 catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
00178 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
00179 }
00180 
00181 } // end namespace gpstk
00182 //------------------------------------------------------------------------------------
00183 //------------------------------------------------------------------------------------

Generated on Wed Feb 8 03:31:01 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1