Exemplo n.º 1
0
  void Spice::ComputeSolarLongitude(double et) {
    NaifStatus::CheckErrors();
    
    if (iString(Target()).UpCase() == "SKY") {
      p_solarLongitude = -999.0;
      return;
    } 

    if (p_bodyRotation->IsCached()) return;

    double tipm[3][3], npole[3];
    char frameName[32];
    SpiceInt frameCode;
    SpiceBoolean found;

    cidfrm_c (p_spkBodyCode, sizeof(frameName), &frameCode, frameName, &found);

    if ( found ) {
      pxform_c("J2000",frameName,et,tipm);
    }
    else {
      tipbod_c("J2000",p_spkBodyCode,et,tipm);
    }
 
    for (int i=0; i<3; i++) {
      npole[i] = tipm[2][i];
    }

    double state[6], lt;
    spkez_c(p_spkBodyCode,et,"J2000","NONE",10,state,&lt);

    double uavel[3];
    ucrss_c(state,&state[3],uavel);

    double x[3], y[3], z[3];
    vequ_c(uavel,z);
    ucrss_c(npole,z,x);
    ucrss_c(z,x,y);

    double trans[3][3];
    for (int i=0; i<3; i++) {
      trans[0][i] = x[i];
      trans[1][i] = y[i];
      trans[2][i] = z[i];
    }

    spkez_c(10,et,"J2000","LT+S",p_spkBodyCode,state,&lt);

    double pos[3];
    mxv_c(trans,state,pos);

    double radius, ls, lat;
    reclat_c(pos,&radius,&ls,&lat);
    ls *= 180.0 / Isis::PI;
    if (ls < 0.0) ls += 360.0;
    else if (ls > 360.0) ls -= 360.0;
    p_solarLongitude = ls;

    NaifStatus::CheckErrors();
  }
Exemplo n.º 2
0
	//function to find the body state vector at epoch
	int body::locate_body(const double& epoch, double* state, const bool& need_deriv, missionoptions* options)
	{
		double DT, n, M, E, V[6];

		switch (body_ephemeris_source)
		{
			case 1: //SPICE
				double LT_dump;
				spkez_c(spice_ID, epoch - (51544.5 * 86400.0), "J2000", "NONE", this->central_body_spice_ID, state, &LT_dump);

				if (need_deriv)
				{
					double statepert[6];
					spkez_c(spice_ID, epoch - (51544.5 * 86400.0) + 10.0, "J2000", "NONE", this->central_body_spice_ID, statepert, &LT_dump);
					state[6] = (statepert[3] - state[3]) / (10.0);
					state[7] = (statepert[4] - state[4]) / (10.0);
					state[8] = (statepert[5] - state[5]) / (10.0);
				}

				break;
			case 0: //static ephemeris
					//TODO static ephemeris is not ready!
					//note, always should give in Earth equatorial J2000 coordinates for internal processing

					DT = ( epoch - this->reference_epoch );
					

					if (this->SMA > 0.0)
						n = sqrt(this->universe_mu / (this->SMA*this->SMA*this->SMA));
					else
						n = sqrt(this->universe_mu / (-this->SMA*this->SMA*this->SMA));
					
					M = this->MA + n*DT;
					M = fmod(M, 2 * EMTG::math::PI);

					E = Kepler::KeplerLaguerreConway(this->ECC, M);
					V[0] = this->SMA; 
					V[1] = this->ECC;
					V[2] = this->INC;
					V[3] = this->RAAN;
					V[4] = this->AOP;

					true_anomaly = 2.0*atan(sqrt((1.0 + this->ECC) / (1.0 - this->ECC))*tan(E / 2.0));
					V[5] = true_anomaly;


					COE2inertial(V, this->universe_mu, state);

					if (need_deriv)
					{
						double r = sqrt(state[0]*state[0] + state[1]*state[1] + state[2]*state[2]);
						double r3 = r*r*r;
						state[6] = -universe_mu/r3 * state[0];
						state[7] = -universe_mu/r3 * state[1];
						state[8] = -universe_mu/r3 * state[2];
					}
				break;
			default:
				cout << "Invalid ephemeris source " << body_ephemeris_source << " for object " << name << endl;
				cout << "Program halted. Press enter to quit." << endl;
#ifndef BACKGROUND_MODE
				cin.ignore();
#endif
		}

		return 0;
	}
Exemplo n.º 3
0
	//function to load new data into the body
	void body::load_body_data(const int& ibody_code, const string& iname, const string& ishortname, const int& ispice_ID, const double& imininum_altitude, const double& imass, const double& iradius, const double& iepoch, vector<double>& ireference_angles, vector<double>& iclassical_orbit_elements, const double& iuniverse_mu, const int& icentral_body_SPICE_ID, const string& icentral_body_name, const double& icentral_body_radius, missionoptions* options)
	{
		//copy information from the inputs into the body
		this->name = iname;
		this->short_name = ishortname;
		this->universe_mu = iuniverse_mu;
		this->body_code = ibody_code;
		this->central_body_spice_ID = icentral_body_SPICE_ID;
		this->central_body_name = icentral_body_name;
		this->central_body_radius = icentral_body_radius;

		this->spice_ID = ispice_ID;
		this->minimum_safe_flyby_altitude = imininum_altitude;
		this->mass = imass;
		this->radius = iradius;
		this->reference_epoch = iepoch;
		this->SMA = iclassical_orbit_elements[0];
		this->ECC = iclassical_orbit_elements[1];
		this->INC = iclassical_orbit_elements[2] * EMTG::math::PI / 180.0;
		this->RAAN = iclassical_orbit_elements[3] * EMTG::math::PI / 180.0;
		this->AOP = iclassical_orbit_elements[4] * EMTG::math::PI / 180.0;
		this->MA = iclassical_orbit_elements[5] * EMTG::math::PI / 180.0;
		


		//compute additional values
		mu = options->G * mass;
		if (ECC < 0.2)
			r_SOI = SMA * pow(mu / universe_mu, 0.4);
		else
			r_SOI = SMA * (1 - ECC) * pow(mu / (3.0 * universe_mu), 0.333333333333333333333333);

		//determine which ephemeris to draw from
		if (options->ephemeris_source == 0)
		{
			body_ephemeris_source = 0; //use static ephemeris
			ephemeris_start_date = -0;
			ephemeris_end_date = 1e+10;
		}
		else if (options->ephemeris_source == 1)
		{
			//first, check to see if the body exists in the currently loaded SPICE kernels
			double temp_state[6];
			double LT_dump;
			spkez_c (spice_ID, reference_epoch - (51544.5 * 86400.0), "J2000", "NONE", central_body_spice_ID, temp_state, &LT_dump);
			if (failed_c())
				reset_c();


			if (fabs(temp_state[0]) > 1.0e-6 && fabs(temp_state[0]) < 1.0e+50)
			{
				body_ephemeris_source = 1; //body can be located using SPICE
			}
			else
			{
				cout << "Warning, body " << name << " does not have a SPICE ephemeris file." << endl;
				body_ephemeris_source = 0; //use static ephemeris
				ephemeris_start_date = 0;
				ephemeris_end_date = 1e+10;
			}
		}

		J2000_body_equatorial_frame.initialize(ireference_angles[0], ireference_angles[1], ireference_angles[2], ireference_angles[3], ireference_angles[4], ireference_angles[5]);
	}