Пример #1
0
   void SolarRadiationPressure::doCompute(UTCTime utc, EarthBody& rb, Spacecraft& sc)
   {
      crossArea = sc.getDragArea();
      dryMass = sc.getDryMass();
      reflectCoeff = sc.getReflectCoeff();

      Vector<double> r_sun = ReferenceFrames::getJ2kPosition(utc.asTDB(),SolarSystem::Sun);
      Vector<double> r_moon = ReferenceFrames::getJ2kPosition(utc.asTDB(),SolarSystem::Moon);
      
      // from km to m
      r_sun = r_sun*1000.0;
      r_moon = r_moon*1000.0;

      // a
      a = accelSRP(sc.R(),r_sun)*getShadowFunction(sc.R(),r_sun,r_moon,SM_CONICAL);

      // da_dr   reference to Montenbruck P248
      // and it's in the same way as the gravitational attraction of the sun
      da_dr.resize(3,3,0.0);

      double au2 = ASConstant::AU * ASConstant::AU;
      double factor = -1.0*reflectCoeff * (crossArea/dryMass) * ASConstant::P_Sol*au2;

      Vector<double> d = sc.R() - r_sun;
      double dmag = norm(d);
      double dcubed = dmag * dmag *dmag;

      Vector<double> temp1 = d / dcubed;         //  detRJ/detRJ^3

      double muod3 = factor / dcubed;
      double jk = 3.0 * muod3/dmag/dmag; 

      double xx = d(0);
      double yy = d(1);
      double zz = d(2);

      da_dr(0,0) = jk * xx * xx - muod3;
      da_dr(0,1) = jk * xx * yy;
      da_dr(0,2) = jk * xx * zz;

      da_dr(1,0) = da_dr(0,1);
      da_dr(1,1) = jk * yy * yy - muod3;
      da_dr(1,2) = jk * yy * zz;

      da_dr(2,0) = da_dr(0,2);
      da_dr(2,1) = da_dr(1,2);
      da_dr(2,2) = jk * zz * zz - muod3;

      // da_dv
      da_dv.resize(3,3,0.0);

      // da_dp
      dadcr.resize(3,0.0);
      dadcr = a /reflectCoeff;

      da_dcr(0,0) = dadcr(0);
      da_dcr(1,0) = dadcr(1);
      da_dcr(2,0) = dadcr(2);

   }  // End of method 'SolarRadiationPressure::doCompute()'
Пример #2
0
      /* Call the relevant methods to compute the acceleration.
      * @param t Time reference class
      * @param bRef Body reference class
      * @param sc Spacecraft parameters and state
      * @return the acceleration [m/s^s]
      */
   void MoonForce::doCompute(UTCTime utc, EarthBody& rb, Spacecraft& sc)
   {
      /* Oliver P69 and P248
       * a = GM*( (s-r)/norm(s-r)^3 - s/norm(s)^3 )
       *
       * da/dr = -GM*( I/norm(r-s)^3 - 3(r-s)transpose(r-s)/norm(r-s)^5)
       */

      Vector<double> r_moon = ReferenceFrames::getJ2kPosition(utc.asTDB(), SolarSystem::Moon);
      
      r_moon = r_moon * 1000.0;         // from km to m

      Vector<double> d = sc.R() - r_moon;
      double dmag = norm(d);
      double dcubed = dmag * dmag *dmag;

      Vector<double> temp1 = d / dcubed;         //  detRJ/detRJ^3

      double smag = norm(r_moon);
      double scubed = smag * smag * smag;

      Vector<double> temp2 = r_moon / scubed;   //  Rj/Rj^3

      Vector<double> sum = temp1 + temp2;
      a = sum * (-mu);                          // a

      // da_dr
      da_dr.resize(3,3,0.0);
      double muod3 = mu / dcubed;
      double jk = 3.0 * muod3/dmag/dmag; 

      double xx = d(0);
      double yy = d(1);
      double zz = d(2);

      da_dr(0,0) = jk * xx * xx - muod3;
      da_dr(0,1) = jk * xx * yy;
      da_dr(0,2) = jk * xx * zz;

      da_dr(1,0) = da_dr(0,1);
      da_dr(1,1) = jk * yy * yy - muod3;
      da_dr(1,2) = jk * yy * zz;

      da_dr(2,0) = da_dr(0,2);
      da_dr(2,1) = da_dr(1,2);
      da_dr(2,2) = jk * zz * zz - muod3;

      // da_dv
      da_dv.resize(3,3,0.0);


      //da_dp
      
   }  // End of method 'MoonForce::doCompute()'
Пример #3
0
      // this is the real one
   void AtmosphericDrag::doCompute(UTCTime utc, EarthBody& rb, Spacecraft& sc)
   {
      // To consist with STK
      double omega_e = 7.292115E-05;  // IERS 1996 conventions
      //double omega_e = rb.getSpinRate(utc);

      Vector<double> r = sc.R();   // satellite position in m
      Vector<double> v = sc.V();   // satellite velocity in m/s

      const double cd = sc.getDragCoeff();
      const double area = sc.getDragArea();
      const double mass = sc.getDryMass();

      double rmag = norm(r);
      double beta = cd * area / mass;  // [m^2/kg]

      // compute the atmospheric density
      double rho = computeDensity(utc, rb, r, v);   // [kg/m^3]

      // debuging...
      //rho  = 6.3097802844338E-12;
      
      // compute the relative velocity vector and magnitude
      Vector<double> we(3,0.0);
      we(2)= omega_e;

      Vector<double> wxr = cross(we,r);
      Vector<double> vr = v - wxr;
      double vrmag = norm(vr);
      
      // form -1/2 (Cd*A/m) rho
      double coeff = -0.5 * beta * rho;
      double coeff2 = coeff * vrmag;

      // compute the acceleration in ECI frame (km/s^2)
      a = vr * coeff2;                                  ///////// a

      // Partial reference: Montenbruck,P248

      // form partial of drag wrt v  
      // da_dv = -0.5*Cd*(A/M)*p*(vr*transpose(vr)/vr+vr1)
      Matrix<double> tr(3,1,0.0);
      tr(0,0)=vr(0);
      tr(1,0)=vr(1);
      tr(2,0)=vr(2);

      Matrix<double> vrvrt = tr*transpose(tr); 
      vrvrt = vrvrt / vrmag;
      
      double eye3[3*3] = {1,0,0,0,1,0,0,0,1};
      Matrix<double> vrm(3,3,0.0);
      vrm = eye3;

      vrm = vrm * vrmag;
      da_dv = (vrvrt + vrm) * coeff;               //////// da_dv

      // da_dr
      // da_dr = -0.5*Cd*(A/M)*vr*dp_dr-da_dv*X(w)
      da_dr.resize(3,3,0.0);

      Matrix<double> X(3,3,0.0);
      X(0,1) = -we(2);      // -wz
      X(0,2) = +we(1);      //  wy
      X(1,0) = +we(2);      // +wz
      X(1,2) = -we(0);      // -wx
      X(2,0) = -we(1);      // -wy
      X(2,1) = +we(0);      // +wx
      
      Matrix<double> part1(3,3,0.0);
      Matrix<double> part2(3,3,0.0);
      
   
      // Get the J2000 to TOD transformation
      Matrix<double> N = ReferenceFrames::J2kToTODMatrix(utc);

      // Transform r from J2000 to TOD
      Vector<double> r_tod = N * r;
      Position geoidPos(r_tod(0),r_tod(1),r_tod(3));
      
      // Satellite height
      double height = geoidPos.getAltitude()/1000.0;              //  convert to [km]
      
      const int n = CIRA_SIZE; ;

      int bracket = 0;

      if (height >= h0[n-1]) 
      {
         bracket = n - 1;
      }
      else 
      {
         for (int i = 0; i < (n-1); i++) 
         {
            if ((height >= h0[i]) && (height < h0[i+1]))
            {
               bracket = i;
            }
         }
      }  // End 'if (height >= h0[n-1]) '
      
      double Hh = H[bracket];
      double coeff4 = -1.0 / (Hh * rmag);

      Vector<double> drhodr = r*coeff4;
      
      Matrix<double> tr2(3,1,0.0);
      tr2(0,0) = drhodr(0);
      tr2(1,0) = drhodr(1);
      tr2(2,0) = drhodr(2);

      part1 = tr*transpose(tr2);      // //Matrix part1 = vr.outerProduct(drhodr);
      part1 = part1*coeff2;

      //part1 = dp_dr*a/rho;
      part2 =-da_dv*X;
      da_dr = part1-part2;

      // form partial of drag wrt cd
      double coeff3 = coeff2 / cd;
      this->dadcd = vr*coeff3;                        ////////   da_dcd

      this->da_dcd(0,0) = dadcd(0);
      this->da_dcd(1,0) = dadcd(1);
      this->da_dcd(2,0) = dadcd(2);

   }  // End of method 'AtmosphericDrag::doCompute()'
Пример #4
0
   // this is the real one
   void RelativityEffect::doCompute(UTCTime utc, EarthBody& rb, Spacecraft& sc)
   {
      /* reference: Jisheng,Li P110 Bernese5 GENREL.f
         a_rl = a_rl1 + a_rl2 + a_rl3

         a_rl2 and a_rl3 are ignored for precise orbit determination
      */
      const double GM = ASConstant::GM_Earth;
      const double C = ASConstant::SPEED_OF_LIGHT;
      
      Vector<double> r = sc.R();
      Vector<double> v = sc.V();

      double beta = 1.0;
      double gama = 1.0;
      
      double c2 = C * C;
      double r2 = dot(r,r);
      double v2 = dot(v,v);

      double r_mag = norm(r);
      double r3 = r2 * r_mag;
      
      double p = GM/c2/r3;
      
      // a
      a.resize(3,0.0);
      
      double pr = 2.0 * (beta + gama) * GM / r_mag - gama * v2;
      double pv = 2.0 * (1.0 + gama) * dot(r,v);
      
      a = p * ( pr * r + pv * v );

      // da_dr
      da_dr.resize(3,3,0.0);

      double prr = -(GM/r_mag)*(GM/r_mag)*(2.0*(beta+gama)/c2);
      double pvv = (GM/r3)*(2.0*(1.0+gama)/c2);
      double par = -3.0/r2;
      double ppr = (GM/r3)*((GM/r_mag)*(2.0*(beta+gama)/c2)-gama*v2/c2);

      for(int i=0; i<3; i++)
      {
         for(int j=0; j<3; j++)
         {
            double det = (i == j) ? 1.0 : 0.0;
            
            da_dr(i,j) = prr*r(i)*r(j)
               + pvv*v(i)*v(j)
               + par*a(i)*r(j)
               + ppr*det;
         }
      }
      
      // da_dv
      da_dv.resize(3,3,0.0);
      
      double prv = -(GM/r3)*(2.0*gama/c2);
      double pvr = (GM/r3)*(2.0*(1.0+gama)/c2);
      double ppv = pvr*dot(r,v);

      for(int i=0;i<3;i++)
      {
         for(int j=0;j<3;j++)
         {
            double det = (i == j) ? 1.0 : 0.0;

            da_dr(i,j) = prv*r(i)*v(j)
               + pvr*v(i)*r(j)
               + ppv*det;
         }
      }

      // da_dp  add it later...
      //da_GM da_dbeta da_gama
      
   }  // End of method 'RelativityEffect::doCompute()'