/* Returns the effect of solid Earth tides (meters) at the given * position and epoch, in the Up-East-Down (UEN) reference frame. * * @param[in] t Epoch to look up * @param[in] p Position of interest * * @return a Triple with the solid tidal effect, in meters and in * the UED reference frame. * * @throw InvalidRequest If the request can not be completed for any * reason, this is thrown. The text may have additional information * as to why the request failed. */ Triple SolidTides::getSolidTide(const CommonTime& t, const Position& p) const throw(InvalidRequest) { // We will store here the results Triple res; // Objects to compute Sun and Moon positions SunPosition sunPosition; MoonPosition moonPosition; try { // Variables to hold Sun and Moon positions Triple sunPos(sunPosition.getPosition(t)); Triple moonPos(moonPosition.getPosition(t)); // Compute the factors for the Sun double rpRs( p.X()*sunPos.theArray[0] + p.Y()*sunPos.theArray[1] + p.Z()*sunPos.theArray[2]); double Rs2(sunPos.theArray[0]*sunPos.theArray[0] + sunPos.theArray[1]*sunPos.theArray[1] + sunPos.theArray[2]*sunPos.theArray[2]); double rp2( p.X()*p.X() + p.Y()*p.Y() + p.Z()*p.Z() ); double xy2p( p.X()*p.X() + p.Y()*p.Y() ); double sqxy2p( std::sqrt(xy2p) ); double sqRs2(std::sqrt(Rs2)); double fac_s( 3.0*MU_SUN*rp2/(sqRs2*sqRs2*sqRs2*sqRs2*sqRs2) ); double g1sun( fac_s*(rpRs*rpRs/2.0 - rp2*Rs2/6.0) ); double g2sun( fac_s * rpRs * (sunPos.theArray[1]*p.X() - sunPos.theArray[0]*p.Y()) * std::sqrt(rp2)/sqxy2p ); double g3sun( fac_s * rpRs * ( sqxy2p* sunPos.theArray[2] - p.Z()/sqxy2p * (p.X()*sunPos.theArray[0] + p.Y()*sunPos.theArray[1]) ) ); // Compute the factors for the Moon double rpRm( p.X()*moonPos.theArray[0] + p.Y()*moonPos.theArray[1] + p.Z()*moonPos.theArray[2]); double Rm2(moonPos.theArray[0]*moonPos.theArray[0] + moonPos.theArray[1]*moonPos.theArray[1] + moonPos.theArray[2]*moonPos.theArray[2]); double sqRm2(std::sqrt(Rm2)); double fac_m( 3.0*MU_MOON*rp2/(sqRm2*sqRm2*sqRm2*sqRm2*sqRm2) ); double g1moon( fac_m*(rpRm*rpRm/2.0 - rp2*Rm2/6.0) ); double g2moon( fac_m * rpRm * (moonPos.theArray[1]*p.X() - moonPos.theArray[0]*p.Y()) * std::sqrt(rp2)/sqxy2p ); double g3moon( fac_m * rpRm * ( sqxy2p* moonPos.theArray[2] - p.Z()/sqxy2p * (p.X()*moonPos.theArray[0] + p.Y()*moonPos.theArray[1]) ) ); // Effects due to the Sun double delta_sun1(H_LOVE*g1sun); double delta_sun2(L_LOVE*g2sun); double delta_sun3(L_LOVE*g3sun); // Effects due to the Moon double delta_moon1(H_LOVE*g1moon); double delta_moon2(L_LOVE*g2moon); double delta_moon3(L_LOVE*g3moon); // Combined effect res.theArray[0] = delta_sun1 + delta_moon1; res.theArray[1] = delta_sun2 + delta_moon2; res.theArray[2] = delta_sun3 + delta_moon3; } // End of try block catch(InvalidRequest& ir) { GPSTK_RETHROW(ir); } return res; } // End SolidTides::getSolidTide
/* Returns a satTypeValueMap object, adding the new data generated when * calling this object. * * @param time Epoch corresponding to the data. * @param gData Data object holding the data. */ satTypeValueMap& ComputeSatPCenter::Process(const DayTime& time, satTypeValueMap& gData) throw(ProcessingException) { try { // Compute Sun position at this epoch SunPosition sunPosition; Triple sunPos(sunPosition.getPosition(time)); // Define a Triple that will hold satellite position, in ECEF Triple svPos(0.0, 0.0, 0.0); SatIDSet satRejectedSet; // Loop through all the satellites satTypeValueMap::iterator it; for (it = gData.begin(); it != gData.end(); ++it) { // Use ephemeris if satellite position is not already computed if( ( (*it).second.find(TypeID::satX) == (*it).second.end() ) || ( (*it).second.find(TypeID::satY) == (*it).second.end() ) || ( (*it).second.find(TypeID::satZ) == (*it).second.end() ) ) { if(pEphemeris==NULL) { // If ephemeris is missing, then remove all satellites satRejectedSet.insert( (*it).first ); continue; } else { // Try to get satellite position // if it is not already computed try { // For our purposes, position at receive time // is fine enough Xvt svPosVel(pEphemeris->getXvt( (*it).first, time )); // If everything is OK, then continue processing. svPos[0] = svPosVel.x.theArray[0]; svPos[1] = svPosVel.x.theArray[1]; svPos[2] = svPosVel.x.theArray[2]; } catch(...) { // If satellite is missing, then schedule it // for removal satRejectedSet.insert( (*it).first ); continue; } } } else { // Get satellite position out of GDS svPos[0] = (*it).second[TypeID::satX]; svPos[1] = (*it).second[TypeID::satY]; svPos[2] = (*it).second[TypeID::satZ]; } // End of 'if( ( (*it).second.find(TypeID::satX) == ...' // Let's get the satellite antenna phase correction value in // meters, and insert it in the GNSS data structure. (*it).second[TypeID::satPCenter] = getSatPCenter((*it).first, time, svPos, sunPos); } // End of 'for (it = gData.begin(); it != gData.end(); ++it)' // Remove satellites with missing data gData.removeSatID(satRejectedSet); return gData; } catch(Exception& u) { // Throw an exception if something unexpected happens ProcessingException e( getClassName() + ":" + StringUtils::asString( getIndex() ) + ":" + u.what() ); GPSTK_THROW(e); } } // End of method 'ComputeSatPCenter::Process()'
/* Returns a satTypeValueMap object, adding the new data generated * when calling this object. * * @param epoch Time of observations. * @param gData Data object holding the data. */ satTypeValueMap& EclipsedSatFilter::Process( const CommonTime& epoch, satTypeValueMap& gData ) throw(ProcessingException) { try { SatIDSet satRejectedSet; // Set the threshold to declare that satellites are in eclipse // threshold = cos(180 - coneAngle/2) double threshold( std::cos(PI - coneAngle/2.0*DEG_TO_RAD) ); // Compute Sun position at this epoch, and store it in a Triple SunPosition sunPosition; Triple sunPos(sunPosition.getPosition(epoch)); // Define a Triple that will hold satellite position, in ECEF Triple svPos(0.0, 0.0, 0.0); // Loop through all the satellites satTypeValueMap::iterator it; for (it = gData.begin(); it != gData.end(); ++it) { // Check if satellite position is not already computed if( ( (*it).second.find(TypeID::satX) == (*it).second.end() ) || ( (*it).second.find(TypeID::satY) == (*it).second.end() ) || ( (*it).second.find(TypeID::satZ) == (*it).second.end() ) ) { // If satellite position is missing, then schedule this // satellite for removal satRejectedSet.insert( (*it).first ); continue; } else { // Get satellite position out of GDS svPos[0] = (*it).second[TypeID::satX]; svPos[1] = (*it).second[TypeID::satY]; svPos[2] = (*it).second[TypeID::satZ]; } // Unitary vector from Earth mass center to satellite Triple rk( svPos.unitVector() ); // Unitary vector from Earth mass center to Sun Triple ri( sunPos.unitVector() ); // Get dot product between unitary vectors = cosine(angle) double cosAngle(ri.dot(rk)); // Check if satellite is within shadow if(cosAngle <= threshold) { // If satellite is eclipsed, then schedule it for removal satRejectedSet.insert( (*it).first ); // Keep track of last known epoch the satellite was in eclipse shadowEpoch[(*it).first] = epoch; continue; } else { // Maybe the satellite is out fo shadow, but it was recently // in eclipse. Check also that. if( shadowEpoch.find( (*it).first ) != shadowEpoch.end() ) { // If satellite was recently in eclipse, check if elapsed // time is less or equal than postShadowPeriod if( std::abs( ( epoch - shadowEpoch[(*it).first] ) ) <= postShadowPeriod ) { // Satellite left shadow, but too recently. Delete it satRejectedSet.insert( (*it).first ); } else { // If satellite left shadow a long time ago, set it free shadowEpoch.erase( (*it).first ); } } } } // Remove satellites with missing data gData.removeSatID(satRejectedSet); return gData; } catch(Exception& u) { // Throw an exception if something unexpected happens ProcessingException e( getClassName() + ":" + u.what() ); GPSTK_THROW(e); } } // End of 'EclipsedSatFilter::Process()'