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 //------------------------------------------------------------------------------------
1.3.9.1