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()'
/* 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()'
// 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()'
// 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()'