Esempio n. 1
0
// -----------------------------------------------------------------------------------
// Compute the satellite attitude, given the time and the satellite position SV.
// Return a 3x3 Matrix which contains, as rows, the unit (ECEF) vectors X,Y,Z in the
// body frame of the satellite, namely
//    Z = along the boresight (i.e. towards Earth center),
//    Y = perpendicular to both Z and the satellite-sun direction, and
//    X completing the orthonormal triad. X will generally point toward the sun.
// Also return the shadow factor = fraction of sun's area not visible to satellite.
Matrix<double> SatelliteAttitude(DayTime& tt, Position& SV, double& sf)
{
try {
   int i;
   double d,svrange,lat,lon,DistSun,Radsun,Radearth,dES;
   Position X,Y,Z,T;
   Matrix<double> R(3,3);

   // Z points from satellite to Earth center - along the antenna boresight
   Z = SV;
   Z.transformTo(Position::Cartesian);
   svrange = Z.mag();
   d = -1.0/Z.mag();
   Z = d * Z;                                // reverse and normalize Z

   // T points from satellite to sun
   SolarPosition(tt, lat, lon, DistSun, Radsun);
   Radsun *= DEG_TO_RAD;                     // angular radius of sun at satellite
   Radearth = ::asin(6378137.0/svrange);     // angular radius of earth at sat

   T.setGeocentric(lat,lon,DistSun);         // vector earth to sun
   T.transformTo(Position::Cartesian);
   T = T - SV;                               // sat to sun=(E to sun)-(E to sat)
   d = 1.0/T.mag();
   T = d * T;                                // normalize T

   dES = ::acos(Z.dot(T));                   // apparent angular distance, earth
                                             // to sun, as seen at satellite

   sf = shadowFactor(Radearth, Radsun, dES); // is satellite in eclipse?
   //if(sf > 0.999) { ;    // total eclipse }
   //else if(sf > 0.0) { ; // partial eclipse }
   //else { ;              // no eclipse }

   // Y is perpendicular to Z and T, such that ...
   Y = Z.cross(T);
   d = 1.0/Y.mag();
   Y = d * Y;                                // normalize Y

   // ... X points generally in the direction of the sun
   X = Y.cross(Z);                           // X will be unit vector
   if(X.dot(T) < 0) {                        // need to reverse X, hence Y also
      X = -1.0 * X;
      Y = -1.0 * Y;
   }

   // fill the matrix and return it
   for(i=0; i<3; i++) {
      R(0,i) = X[i];
      R(1,i) = Y[i];
      R(2,i) = Z[i];
   }

   return R;
}
catch(Exception& e) { GPSTK_RETHROW(e); }
catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
}
Esempio n. 2
0
// -----------------------------------------------------------------------------------
// Compute the satellite attitude, given the time and the satellite position SV.
// If the SolarSystem is valid, use it; otherwise use SolarPosition.
// See two versions of SatelliteAttitude() for the user interface.
// Return a 3x3 Matrix which contains, as rows, the unit (ECEF) vectors X,Y,Z in the
// body frame of the satellite, namely
//    Z = along the boresight (i.e. towards Earth center),
//    Y = perpendicular to both Z and the satellite-sun direction, and
//    X = completing the orthonormal triad. X will generally point toward the sun.
// Thus this rotation matrix R * (ECEF XYZ vector) = components in body frame, and
// R.transpose() * (sat. body. frame vector) = ECEF XYZ components.
// Also return the shadow factor = fraction of sun's area not visible to satellite.
Matrix<double> doSatAtt(const CommonTime& tt, const Position& SV,
                        const SolarSystem& SSEph, const EarthOrientation& EO,
                        double& sf)
   throw(Exception)
{
   try {
      int i;
      double d,svrange,DistSun,AngRadSun,AngRadEarth,AngSeparation;
      Position X,Y,Z,T,S,Sun;
      Matrix<double> R(3,3);

      // Z points from satellite to Earth center - along the antenna boresight
      Z = SV;
      Z.transformTo(Position::Cartesian);
      svrange = Z.mag();
      d = -1.0/Z.mag();
      Z = d * Z;                                // reverse and normalize Z

      // get the Sun's position
      if(SSEph.JPLNumber() > -1) {
         //SolarSystem& mySSEph=const_cast<SolarSystem&>(SSEph);
         Sun = const_cast<SolarSystem&>(SSEph).WGS84Position(SolarSystem::Sun,tt,EO);
      }
      else {
         double AR;
         Sun = SolarPosition(tt, AR);
      }
      DistSun = Sun.radius();

      // apparent angular radius of sun = 0.2666/distance in AU (deg)
      AngRadSun = 0.2666/(DistSun/149598.0e6);
      AngRadSun *= DEG_TO_RAD;

      // angular radius of earth at sat
      AngRadEarth = ::asin(6378137.0/svrange);

      // T points from satellite to sun
      T = Sun;                                  // vector earth to sun
      T.transformTo(Position::Cartesian);
      S = SV;
      S.transformTo(Position::Cartesian);
      T = T - S;                                // sat to sun=(E to sun)-(E to sat)
      d = 1.0/T.mag();
      T = d * T;                                // normalize T

      AngSeparation = ::acos(Z.dot(T));         // apparent angular distance, earth
                                                // to sun, as seen at satellite
      // is satellite in eclipse?
      try { sf = ShadowFactor(AngRadEarth, AngRadSun, AngSeparation); }
      catch(Exception& e) { GPSTK_RETHROW(e); }

      // Y is perpendicular to Z and T, such that ...
      Y = Z.cross(T);
      d = 1.0/Y.mag();
      Y = d * Y;                                // normalize Y

      // ... X points generally in the direction of the sun
      X = Y.cross(Z);                           // X will be unit vector
      if(X.dot(T) < 0) {                        // need to reverse X, hence Y also
         X = -1.0 * X;
         Y = -1.0 * Y;
      }

      // fill the matrix and return it
      for(i=0; i<3; i++) {
         R(0,i) = X[i];
         R(1,i) = Y[i];
         R(2,i) = Z[i];
      }

      return R;
   }
   catch(Exception& e) { GPSTK_RETHROW(e); }
   catch(exception& e) {Exception E("std except: "+string(e.what())); GPSTK_THROW(E);}
   catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
}