Beispiel #1
0
void Galaxy::Serialize(SerializableNodeObject* node)
{
	if (!impl)
		return;

	/*if (impl->serializeObject)
	{
		delete impl->serializeObject;
		impl->serializeObject = nullptr;
	}

	impl->serializeObject = new SerializableNodeObject();*/

	//SerializableNodeObject *root = impl->serializeObject;

	SerializableNodeArray* celestialBodies = new SerializableNodeArray("celestialBodies");

	for (size_t i = 0; i < impl->celestialBodies.size(); ++i)
	{
		CelestialBody* body = impl->celestialBodies[i];

		SerializableNodeObject* bodyNode = new SerializableNodeObject();
		body->Serialize(bodyNode);
		celestialBodies->AddChild(bodyNode);
	}

	node->AddChild(celestialBodies);

	//return impl->serializeObject;
}
//------------------------------------------------------------------------------
// void OnComboBoxChange(wxCommandEvent& event)
//------------------------------------------------------------------------------
void GroundTrackPlotPanel::OnComboBoxChange(wxCommandEvent& event)
{    
   if (event.GetEventObject() == mSolverIterComboBox)
   {
      mHasDataOptionChanged = true;
   }
   else if (event.GetEventObject() == mCentralBodyComboBox)
   {
      mHasCentralBodyChanged = true;
      wxString bodyTexture;
      if (mCentralBodyComboBox->GetValue() == mCentralBody)
      {
         bodyTexture = mTextureFile;
      }
      else
      {
         // Update texture map to corresponding body
         CelestialBody *body = (CelestialBody*)
            theGuiInterpreter->GetConfiguredObject(mCentralBodyComboBox->GetValue().c_str());
         Integer id = body->GetParameterID("TextureMapFileName");
         bodyTexture = body->GetStringParameter(id).c_str();
      }
      #ifdef DEBUG_CENTRAL_BODY
      MessageInterface::ShowMessage
         ("OnComboBoxChange(), bodyTexture = '%s'\n", bodyTexture.c_str());
      #endif
      mTextureMapTextCtrl->SetValue(bodyTexture);
      mTextureMapTextCtrl->SetInsertionPointEnd();
   }
   EnableUpdate(true);
}
Beispiel #3
0
//------------------------------------------------------------------------------
bool SolarPowerSystem::Initialize()
{
   #ifdef DEBUG_SOLAR_POWER
      MessageInterface::ShowMessage("Calling Initialization on %s\n",
            instanceName.c_str());
      MessageInterface::ShowMessage("number of shadow bodies = %d\n",
            (Integer) shadowBodyNames.size());
   #endif
   PowerSystem::Initialize();

   // Solar System is set by the spacecraft to which this is attached
   if (!solarSystem)
   {
      std::string errmsg = "SolarSystem has not been set on PowerSystem ";
      errmsg            += instanceName + ".\n";
      throw HardwareException(errmsg);
   }

   // if no names were added to the ShadowBodies list, add the Default body
   // This will cause "ShadowBodies = {'Earth'} to be written to the script <<
   if ((shadowBodyNames.empty()) && (!settingNoBodies))
      shadowBodyNames = defaultShadowBodyNames;
//      shadowBodyNames.push_back("Earth");

   // Set up the list of shadowBodies using current solarSystem
   shadowBodies.clear();
   for (unsigned int ii = 0; ii < shadowBodyNames.size(); ii++)
   {
      CelestialBody *body = solarSystem->GetBody(shadowBodyNames.at(ii));
      if (!body)
      {
         std::string errmsg = "SolarPowerSystem ";
         errmsg += instanceName + " cannot find body ";
         errmsg += shadowBodyNames.at(ii) + ".  ShadowBodies must be ";
         errmsg += "Celestial Bodies.\n";
         throw HardwareException(errmsg);
      }
      shadowBodies.push_back(body);
      #ifdef DEBUG_SOLAR_POWER
         MessageInterface::ShowMessage("Adding shadow body %s to %s\n",
               body->GetName().c_str(), instanceName.c_str());
      #endif
   }

   if (!shadowState)
      shadowState = new ShadowState();

   shadowState->SetSolarSystem(solarSystem);

   return isInitialized;
}
void  EphemerisEngine::_updateData( 
        const EphemerisData &ephemData, 
        const CelestialBody &cb, 
        double rsn,
        double & cbAzimuth, double & cbAlt )
{
    _RADecElevToAzimAlt(
            cb.getRightAscension(),
            cb.getDeclination(),
            ephemData.latitude,
            ephemData.localSiderealTime,
            ephemData.altitude,
            rsn,
            cbAzimuth,
            cbAlt );
}
Beispiel #5
0
// a single Euler-Cromer step (parameter = step length)
void Solvers::Euler(double step)
{
	int n = this->_euler->n(); // number of celestial bodies

	// calculate forces/accelerations based on current postions
	this->_euler->setForces();

	for (int j = 0; j < n; j++) // for each celestial body
	{
		CelestialBody* cb = this->_euler->body(j);

		if (!cb->fixed) // a fixed celestial body will never move
		{
			// acc -> velocity (Euler-Cromer, for testing only)
			*(cb->velocity) += step * cb->acc();

			// velocity -> position (Euler-Cromer, for testing only)
			*(cb->position) += step * *(cb->velocity);
		}
	}
}
Beispiel #6
0
// a single Leapfrog step (parameter = step length)
void Solvers::Leapfrog(double step)
{
	int n = this->_leapfrog->n(); // number of celestial bodies

	double halfStep = (step / 2.0);

	// calculate forces/accelerations based on current postions
	this->_leapfrog->setForces();

	for (int j = 0; j < n; j++) // for each celestial body
	{
		CelestialBody* cb = this->_leapfrog->body(j);

		if (!cb->fixed) // a fixed celestial body will never move
		{
			// Leapfrog algorithm, step 1
			*(cb->velocity) += halfStep * cb->acc();

			// Leapfrog algorithm, step 2
			*(cb->position) += step * *(cb->velocity);
		}
	}

	// calculate the forces using the new positions
	this->_leapfrog->setForces();

	for (int j = 0; j < n; j++) // for each celestial body
	{
		CelestialBody* cb = this->_leapfrog->body(j);

		if (!cb->fixed) // a fixed celestial body will never move
		{
			// Leapfrog algorithm, step 3
			*(cb->velocity) += halfStep * cb->acc();
		}
	}
}
Beispiel #7
0
//------------------------------------------------------------------------------
bool GravityField::GetDerivatives(Real * state, Real dt, Integer dvorder,
      const Integer id)
{
   #ifdef DEBUG_FIRST_CALL
      if (firstCallFired == false)
      {
         MessageInterface::ShowMessage(
            "GravityField(%s) inputs:\n"
            "   state = [%.10lf %.10lf %.10lf %.16lf %.16lf %.16lf]\n"
            "   dt = %.10lf\n   dvorder = %d\n",
            instanceName.c_str(), state[0], state[1], state[2], state[3],
            state[4], state[5], dt, dvorder);
      }
   #endif

   // We may want to do this down the road:
//   if (fabs(state[0]) + fabs(state[1]) + fabs(state[2]) < minimumDistance)
//      throw ODEModelException("A harmonic gravity field is being computed "
//            "inside of the " + bodyName + ", which is not allowed");

   if ((dvorder > 2) || (dvorder < 1))
      return false;

   #ifdef DEBUG_GRAVITY_FIELD
      MessageInterface::ShowMessage("%s %d %s %le %s  %le %le %le %le %le %le\n",
          "Entered GravityField::GetDerivatives with order", dvorder, "dt = ",
          dt, "and state\n",
          state[0], state[1], state[2], state[3], state[4], state[5]);
      MessageInterface::ShowMessage("cartesianCount = %d, stmCount = %d, aMatrixCount = %d\n",
            cartesianCount, stmCount, aMatrixCount);
      MessageInterface::ShowMessage("fillCartesian = %s, fillSTM = %s, fillAMatrix = %s\n",
            (fillCartesian? "true" : "false"), (fillSTM? "true" : "false"), (fillAMatrix? "true" : "false"));
      MessageInterface::ShowMessage("cartesianStart = %d, stmStart = %d, aMatrixStart = %d\n",
            cartesianStart, stmStart, aMatrixStart);
   #endif

/// @todo Optimize this code -- May be possible to make GravityField calculations more efficient


   if ((cartesianCount < 1)  && (stmCount < 1) && (aMatrixCount < 1))
      throw ODEModelException(
         "GravityField requires at least one spacecraft.");

   // todo: Move into header; this flag is used to decide if the velocity terms
   // are copied into the position derivatives for first order integrators, so
   // when the GravityField is set to work at non-central bodies, the detection
   // will need to happen in initialization.
   Real satState[6];
   Integer nOffset;

   now = epoch + dt/GmatTimeConstants::SECS_PER_DAY;

   #ifdef DEBUG_GRAV_COORD_SYSTEM
       MessageInterface::ShowMessage(
         "------ body = %s\n------ inputCS = %s\n------ targetCS = %s"
         "\n------ fixedCS = %s\n",
         body->GetName().c_str(),     (inputCS == NULL? "NULL" : inputCS->GetName().c_str()),
         (targetCS == NULL? "NULL" : targetCS->GetName().c_str()), (fixedCS == NULL? "NULL" : fixedCS->GetName().c_str()));
   #endif



   #ifdef DEBUG_FIRST_CALL
      if (firstCallFired == false)
      {
    	 CelestialBody *targetBody = (CelestialBody*) targetCS->GetOrigin();
    	 CelestialBody *fixedBody  = (CelestialBody*) fixedCS->GetOrigin();
         MessageInterface::ShowMessage(
            "   Epoch = %.12lf\n   targetBody = %s\n   fixedBody = %s\n",
            now.Get(), targetBody->GetName().c_str(),
            fixedBody->GetName().c_str());
         MessageInterface::ShowMessage(
            "------ body = %s\n------ inputCS = %s\n------ targetCS = %s\n"
            "------ fixedCS = %s\n",
            body->GetName().c_str(),     inputCS->GetName().c_str(),
            targetCS->GetName().c_str(), fixedCS->GetName().c_str());
      }
   #endif


   if (fillCartesian || fillAMatrix || fillSTM)
   {
      // See assumption 1, above
      if ((cartesianCount < stmCount) || (cartesianCount < aMatrixCount))
      {
         throw ODEModelException("GetDerivatives: cartesianCount < stmCount or aMatrixCount\n");
      }
      Real originacc[3] = { 0.0,0.0,0.0 };  // JPD code
      Rmatrix33 origingrad (0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
      Rmatrix33 emptyGradient(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
      Rmatrix33 gradnew (0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
      if (body != forceOrigin)
      {
         Real originstate[6] = { 0.0,0.0,0.0,0.0,0.0,0.0 };
         Calculate(dt,originstate,originacc,origingrad);
#ifdef DEBUG_DERIVATIVES
      MessageInterface::ShowMessage("---------> origingrad = %s\n", origingrad.ToString().c_str());
#endif
      }

      for (Integer n = 0; n < cartesianCount; ++n)
      {
         nOffset = cartesianStart + n * stateSize;
         for (Integer i = 0; i < 6; ++i)
            satState[i] = state[i+nOffset];

         Real accnew[3];  // JPD code
         gradnew = emptyGradient;
         Calculate(dt,satState,accnew,gradnew);
         if (body != forceOrigin)
         {
            for (Integer i=0;  i<=2;  ++i)
               accnew[i] -= originacc[i];
            gradnew -= origingrad;
#ifdef DEBUG_DERIVATIVES
      MessageInterface::ShowMessage("---------> body not equal to forceOrigin\n");
#endif
         }
#ifdef DEBUG_DERIVATIVES
      MessageInterface::ShowMessage("---------> gradnew (%d) = %s\n", n, gradnew.ToString().c_str());
#endif
         
         // Fill Derivatives
         switch (dvorder)
         {
            case 1:
               deriv[0+nOffset] = satState[3];
               deriv[1+nOffset] = satState[4];
               deriv[2+nOffset] = satState[5];
               deriv[3+nOffset] = accnew[0];
               deriv[4+nOffset] = accnew[1];
               deriv[5+nOffset] = accnew[2];
               break;

            case 2:
               deriv[0+nOffset] = accnew[0];
               deriv[1+nOffset] = accnew[1];
               deriv[2+nOffset] = accnew[2];
               deriv[3+nOffset] = 0.0;
               deriv[4+nOffset] = 0.0;
               deriv[5+nOffset] = 0.0;
               break;
         }

#ifdef DEBUG_DERIVATIVES
         for (Integer ii = 0 + nOffset; ii < 6+nOffset; ii++)
                     MessageInterface::ShowMessage("------ deriv[%d] = %12.10f\n", ii, deriv[ii]);
#endif
         if (fillSTM)
         {
            Real aTilde[36];
            Integer element;
            // @todo Add the use of the GetAssociateIndex() method here to get index into state array
            //       (See assumption 1, above)
            if (n <= stmCount)
            {
               Integer i6 = stmStart + n * 36;

               // Calculate A-tilde
               aTilde[ 0] = aTilde[ 1] = aTilde[ 2] =
               aTilde[ 3] = aTilde[ 4] = aTilde[ 5] =
               aTilde[ 6] = aTilde[ 7] = aTilde[ 8] =
               aTilde[ 9] = aTilde[10] = aTilde[11] =
               aTilde[12] = aTilde[13] = aTilde[14] =
               aTilde[15] = aTilde[16] = aTilde[17] =
               aTilde[21] = aTilde[22] = aTilde[23] =
               aTilde[27] = aTilde[28] = aTilde[29] =
               aTilde[33] = aTilde[34] = aTilde[35] = 0.0;

               // fill in the lower left quadrant with the calculated gradient values
               aTilde[18] = gradnew(0,0);
               aTilde[19] = gradnew(0,1);
               aTilde[20] = gradnew(0,2);
               aTilde[24] = gradnew(1,0);
               aTilde[25] = gradnew(1,1);
               aTilde[26] = gradnew(1,2);
               aTilde[30] = gradnew(2,0);
               aTilde[31] = gradnew(2,1);
               aTilde[32] = gradnew(2,2);

               for (Integer j = 0; j < 6; j++)
               {
                  for (Integer k = 0; k < 6; k++)
                  {
                     element = j * 6 + k;
#ifdef DEBUG_DERIVATIVES
                     MessageInterface::ShowMessage("------ deriv[%d] = %12.10f\n", (i6+element), aTilde[element]);
#endif
                     deriv[i6+element] = aTilde[element];
                  }
               }
            }
         }

         if (fillAMatrix)
         {
            Real aTilde[36];
            Integer element;
            // @todo Add the use of the GetAssociateIndex() method here to get index into state array
            //       (See assumption 1, above)
            if (n <= aMatrixCount)
            {
               Integer i6 = aMatrixStart + n * 36;

               // Calculate A-tilde
               aTilde[ 0] = aTilde[ 1] = aTilde[ 2] =
               aTilde[ 3] = aTilde[ 4] = aTilde[ 5] =
               aTilde[ 6] = aTilde[ 7] = aTilde[ 8] =
               aTilde[ 9] = aTilde[10] = aTilde[11] =
               aTilde[12] = aTilde[13] = aTilde[14] =
               aTilde[15] = aTilde[16] = aTilde[17] =
               aTilde[21] = aTilde[22] = aTilde[23] =
               aTilde[27] = aTilde[28] = aTilde[29] =
               aTilde[33] = aTilde[34] = aTilde[35] = 0.0;

               // fill in the lower left quadrant with the calculated gradient values
               aTilde[18] = gradnew(0,0);
               aTilde[19] = gradnew(0,1);
               aTilde[20] = gradnew(0,2);
               aTilde[24] = gradnew(1,0);
               aTilde[25] = gradnew(1,1);
               aTilde[26] = gradnew(1,2);
               aTilde[30] = gradnew(2,0);
               aTilde[31] = gradnew(2,1);
               aTilde[32] = gradnew(2,2);

               for (Integer j = 0; j < 6; j++)
               {
                  for (Integer k = 0; k < 6; k++)
                  {
                     element = j * 6 + k;
#ifdef DEBUG_DERIVATIVES
                     MessageInterface::ShowMessage("------ deriv[%d] = %12.10f\n", (i6+element), aTilde[element]);
#endif
                     deriv[i6+element] = aTilde[element];
                  }
               }
            }
         }

      }  // end for
   }

   #ifdef DEBUG_FIRST_CALL
      if (firstCallFired == false)
      {
         if (body->GetName() == "Mars")
         {
         MessageInterface::ShowMessage(
            "   GravityField[%s <> %s] --> mu = %lf, origin = %s, [%.10lf %.10lf "
            "%.10lf %.16lf %.16lf %.16lf]\n",
            instanceName.c_str(), body->GetName().c_str(), mu,
            targetCS->GetOriginName().c_str(),
            deriv[0], deriv[1], deriv[2], deriv[3], deriv[4], deriv[5]);
         firstCallFired = true;
         }
      }
   #endif

   return true;
}
Beispiel #8
0
//------------------------------------------------------------------------------
void GravityField::Calculate (Real dt, Real state[6], 
                              Real acc[3], Rmatrix33& grad)
{
   #ifdef DEBUG_CALCULATE
      MessageInterface::ShowMessage(
            "Entering Calculate with dt = %12.10f, state = %12.10f  %12.10f  %12.10f  %12.10f  %12.10f  %12.10f\n",
            dt, state[0], state[1], state[2], state[3], state[4], state[5]);
      MessageInterface::ShowMessage("   acc = %12.10f  %12.10f  %12.10f\n", acc[0], acc[1], acc[2]);
   #endif
   Real jday = epoch + GmatTimeConstants::JD_JAN_5_1941 +
               dt/GmatTimeConstants::SECS_PER_DAY;
   // convert to body fixed coordinate system
   Real now = epoch + dt/GmatTimeConstants::SECS_PER_DAY;
   Real tmpState[6];
//   CoordinateConverter cc; - move back to class, for performance
   cc.Convert(now, state, inputCS, tmpState, fixedCS);  // which CSs to use here???
   #ifdef DEBUG_CALCULATE
      MessageInterface::ShowMessage(
            "After Convert, jday = %12.10f, now = %12.10f, and tmpState = %12.10f  %12.10f  %12.10f  %12.10f  %12.10f  %12.10f\n",
            jday, now, tmpState[0], tmpState[1], tmpState[2], tmpState[3], tmpState[4], tmpState[5]);
   #endif
   Rmatrix33 rotMatrix = cc.GetLastRotationMatrix();
#ifdef DEBUG_DERIVATIVES
   MessageInterface::ShowMessage("---->>>> rotMatrix = %s\n", rotMatrix.ToString().c_str());
#endif
   // calculate sun and moon pos
   Real sunpos[3]   = {0.0,0.0,0.0};
   Real moonpos[3]  = {0.0,0.0,0.0};
   Real sunMass     = 0.0;
   Real moonMass    = 0.0;
   // Acceleration
   Real      rotacc[3];
   Rmatrix33 rotgrad;
   bool      useTides;
   // for now, "None" and "SolidAndPole" are the only valid EarthTideModel values
   if ((bodyName == GmatSolarSystemDefaults::EARTH_NAME) && (GmatStringUtil::ToUpper(earthTideModel) == "SOLIDANDPOLE"))
   {
      Real ep = epoch + dt / GmatTimeConstants::SECS_PER_DAY;  // isn't this the same as now?
      CelestialBody* theSun  = solarSystem->GetBody(SolarSystem::SUN_NAME);
      CelestialBody* theMoon = solarSystem->GetBody(SolarSystem::MOON_NAME);
      if (!theSun || !theMoon)
         throw ODEModelException("Solar system does not contain the Sun or Moon for Tide model.");
      Rvector6 sunstateinertial  = theSun->GetState(ep);
      Rvector6 moonstateinertial = theMoon->GetState(ep);
      
      Rvector6 sunstate;
      Rvector6 moonstate;
      cc.Convert(now, sunstateinertial, inputCS, sunstate, fixedCS);
      cc.Convert(now, moonstateinertial, inputCS, moonstate, fixedCS);
      sunstate.GetR(sunpos);
      moonstate.GetR(moonpos);

      sunMass     = theSun->GetMass();
      moonMass    = theMoon->GetMass();
      useTides = true;
   }
   else
      useTides = false;
   #ifdef DEBUG_GRAVITY_EARTH_TIDE
      MessageInterface::ShowMessage("Calling gravityModel->CalculateFullField with useTides = %s\n",
            (useTides? "true" : "false"));
   #endif
   // Get xp and yp from the EOP file
   Real xp, yp, lod;
   Real utcmjd  = TimeConverterUtil::Convert(now, TimeConverterUtil::A1MJD, TimeConverterUtil::UTCMJD,
                 GmatTimeConstants::JD_JAN_5_1941);
   eop->GetPolarMotionAndLod(utcmjd, xp, yp, lod);
   bool computeMatrix = fillAMatrix || fillSTM;

   gravityModel->CalculateFullField(jday, tmpState, degree, order, useTides, sunpos, moonpos, sunMass, moonMass,
                                    xp, yp, computeMatrix, rotacc, rotgrad);
#ifdef DEBUG_DERIVATIVES
   MessageInterface::ShowMessage("after CalculateFullField, rotgrad = %s\n", rotgrad.ToString().c_str());
#endif
   /*
    MessageInterface::ShowMessage
    ("HarmonicField::Calculate pos= %20.14f %20.14f %20.14f\n",
    tmpState[0],tmpState[1],tmpState[2]);
    MessageInterface::ShowMessage
    ("HarmonicField::Calculate grad= %20.14e %20.14e %20.14e\n",
    rotgrad(0,0),rotgrad(0,1),rotgrad(0,2));
    MessageInterface::ShowMessage
    ("HarmonicField::Calculate grad= %20.14e %20.14e %20.14e\n",
    rotgrad(1,0),rotgrad(1,1),rotgrad(1,2));
    MessageInterface::ShowMessage
    ("HarmonicField::Calculate grad= %20.14e %20.14e %20.14e\n",
    rotgrad(2,0),rotgrad(2,1),rotgrad(2,2));
    */
   
   // Convert back to target CS
   InverseRotate (rotMatrix,rotacc,acc);
   grad = rotMatrix.Transpose() * rotgrad * rotMatrix;
#ifdef DEBUG_DERIVATIVES
   MessageInterface::ShowMessage("at end of Calculate, after rotation, grad = %s\n", grad.ToString().c_str());
#endif
}
Beispiel #9
0
// a single Runge-Kutta step (parameter = step length)
void Solvers::RK4(double step)
{
	int n = this->_rk4->n();

	// matrices for Runge-Kutta values:
	mat k1_v(this->_rk4->dim(), n); // k1, velocity
	mat k1_p(this->_rk4->dim(), n); // k1, position
	mat k2_v(this->_rk4->dim(), n); // k2, velocity (etc.)
	mat k2_p(this->_rk4->dim(), n);
	mat k3_v(this->_rk4->dim(), n);
	mat k3_p(this->_rk4->dim(), n);
	mat k4_v(this->_rk4->dim(), n);
	mat k4_p(this->_rk4->dim(), n);

	// initial position and velocity for each celestial body
	mat orig_v(this->_rk4->dim(), n);
	mat orig_p(this->_rk4->dim(), n);

	#pragma region k1

	// calculate forces/accelerations based on current postions
	this->_rk4->setForces();

	for (int j = 0; j < n; j++) // for each celestial body
	{
		CelestialBody* cb = this->_rk4->body(j);

		if (!cb->fixed) // a fixed celestial body will never move
		{
			// store initial position and velocity
			orig_v.col(j) = *(cb->velocity);
			orig_p.col(j) = *(cb->position);

			// save values
			k1_v.col(j) = step * cb->acc();
			k1_p.col(j) = step * *(cb->velocity);

			// advance to mid-point after k1
			*(cb->velocity) = orig_v.col(j) + 0.5 * k1_v.col(j);
			*(cb->position) = orig_p.col(j) + 0.5 * k1_p.col(j);
		}
	}

	#pragma endregion

	#pragma region k2

	// calculate forces/accelerations based on current postions
	this->_rk4->setForces();

	for (int j = 0; j < n; j++) // for each celestial body
	{
		CelestialBody* cb = this->_rk4->body(j);

		if (!cb->fixed) // a fixed celestial body will never move
		{
			// save values
			k2_v.col(j) = step * cb->acc();
			k2_p.col(j) = step * *(cb->velocity);

			// switch to new mid-point using k2 instead
			*(cb->velocity) = orig_v.col(j) + 0.5 * k2_v.col(j);
			*(cb->position) = orig_p.col(j) + 0.5 * k2_p.col(j);
		}
	}

	#pragma endregion

	#pragma region k3

	// calculate forces/accelerations based on current postions
	this->_rk4->setForces();

	for (int j = 0; j < n; j++) // for each celestial body
	{
		CelestialBody* cb = this->_rk4->body(j);

		if (!cb->fixed) // a fixed celestial body will never move
		{
		// save values
			k3_v.col(j) = step * cb->acc();
			k3_p.col(j) = step * *(cb->velocity);

			// switch to end-point
			*(cb->velocity) = orig_v.col(j) + k3_v.col(j);
			*(cb->position) = orig_p.col(j) + k3_p.col(j);
		}
	}

	#pragma endregion

	#pragma region k4

	// calculate forces/accelerations based on current postions
	this->_rk4->setForces();

	for (int j = 0; j < n; j++) // for each celestial body
	{
		CelestialBody* cb = this->_rk4->body(j);

		if (!cb->fixed) // a fixed celestial body will never move
		{
			// save values
			k4_v.col(j) = step * cb->acc();
			k4_p.col(j) = step * *(cb->velocity);

			// finally, update position and velocity
			*(cb->velocity) = orig_v.col(j) + (1.0 / 6.0)*(k1_v.col(j) + 2.0 * k2_v.col(j) + 2.0 * k3_v.col(j) + k4_v.col(j));
			*(cb->position) = orig_p.col(j) + (1.0 / 6.0)*(k1_p.col(j) + 2.0 * k2_p.col(j) + 2.0 * k3_p.col(j) + k4_p.col(j));
		}
	}

	#pragma endregion
}
Beispiel #10
0
//------------------------------------------------------------------------------
void BarycenterPanel::SaveData()
{
   canClose = true;

   // Save color if changed
   if (theColorPanel->HasColorChanged())
   {
      // Copy cloned object to actual object
      theBarycenter->Copy(theClonedBarycenter);
   }
   
   if (mIsBuiltIn) return;
   
   try
   {
      Integer count = bodySelectedListBox->GetCount();
  
      if (count == 0)
      {
         MessageInterface::PopupMessage(Gmat::ERROR_,
                 "At least one body must be selected!");
         canClose = false;
         return;
      }
      
      theClonedBarycenter->TakeAction("ClearBodies");
      
      // get Earth pointer as J2000Body
      CelestialBody *j2000body =
         (CelestialBody*)theGuiInterpreter->GetConfiguredObject("Earth");
      CelestialBody *body;
      std::string bodyName;
      
      for (Integer i = 0; i < count; i++)
      {
         bodyName = bodySelectedListBox->GetString(i).c_str();
         theClonedBarycenter->SetStringParameter("BodyNames", bodyName, i);
         
         body = (CelestialBody*)theGuiInterpreter->GetConfiguredObject(bodyName);
         
         // set J2000Body for the body
         if (body->GetJ2000Body() == NULL)
            body->SetJ2000Body(j2000body);
         
         theClonedBarycenter->SetRefObject(body, Gmat::SPACE_POINT, bodyName);
         
         #if DEBUG_BARYCENTER_PANEL
         MessageInterface::ShowMessage
            ("BarycenterPanel::SaveData() body[%d]=%d, name=%s, J2000Body=%d\n",
             i, body, bodyName.c_str(), j2000body);
         #endif
      }
      
      // Copy cloned object to actual object
      theBarycenter->Copy(theClonedBarycenter);
      EnableUpdate(false);
   }
   catch (BaseException &e)
   {
      MessageInterface::ShowMessage
         ("BarycenterPanel:SaveData() error occurred!\n%s\n",
            e.GetFullMessage().c_str());
   }
}
Beispiel #11
0
//------------------------------------------------------------------------------
//int RunTest(TestOutput &out)
//------------------------------------------------------------------------------
int RunTest(TestOutput &out)
{

   Real realVal;
   Real expResult;
   
   // for SolarSystem, internal CoordinateSystem
   SolarSystem *ssPtr = new SolarSystem("MySolarSystem");
   
   // set J2000Body for Earth
   CelestialBody *earthPtr = ssPtr->GetBody("Earth");
   std::string j2000BodyName = "Earth";
   CelestialBody *j2000Body = earthPtr;
   earthPtr->SetJ2000BodyName(j2000BodyName);
   earthPtr->SetJ2000Body(j2000Body);
   
   // for CoordinateSystem - EarthMJ2000Eq
   CoordinateSystem *csPtr = new CoordinateSystem("CoordinateSystem", "EarthMJ2000Eq");
   AxisSystem *mj2000EqAxis = new MJ2000EqAxes("MJ2000Eq");
   csPtr->SetRefObject(mj2000EqAxis, Gmat::AXIS_SYSTEM, mj2000EqAxis->GetName());
   csPtr->SetSolarSystem(ssPtr);
   csPtr->SetStringParameter("Origin", "Earth");
   csPtr->SetStringParameter("J2000Body", "Earth");
   csPtr->SetRefObject(earthPtr, Gmat::SPACE_POINT, "Earth");
   csPtr->Initialize();
   
   // for CoordinateSystem - EarthMJ2000Ec
   CoordinateSystem *eccsPtr = new CoordinateSystem("CoordinateSystem", "EarthMJ2000Ec");
   AxisSystem *ecAxis = new MJ2000EcAxes("MJ2000Ec");
   eccsPtr->SetRefObject(ecAxis, Gmat::AXIS_SYSTEM, ecAxis->GetName());
   eccsPtr->SetSolarSystem(ssPtr);
   eccsPtr->SetStringParameter("Origin", "Earth");
   eccsPtr->SetStringParameter("J2000Body", "Earth");
   eccsPtr->SetRefObject(earthPtr, Gmat::SPACE_POINT, "Earth");
   eccsPtr->Initialize();
   
   // set SLP file to SolarSystem
   std::string slpFileName = "C:\\projects\\gmat\\files\\planetary_ephem\\slp\\mn2000.pc";
   SlpFile *theSlpFile = new SlpFile(slpFileName);
   ssPtr->SetSource(Gmat::SLP);
   ssPtr->SetSourceFile(theSlpFile);
   
   // for Spacecraft
   Spacecraft *scPtr = new Spacecraft("MySpacecraft");
   scPtr->SetRefObject(csPtr, Gmat::COORDINATE_SYSTEM);
   
   //---------------------------------------------------------------------------
   out.Put("======================================== test BplaneParameters\n");
   //---------------------------------------------------------------------------
   
   out.Put("=================================== Test with default spacecraft orbit");
   out.Put("========== state = ", scPtr->GetCartesianState().ToString());
   
   out.Put("============================== test BdotT()");
   BdotT *btParam = new BdotT();
   btParam->SetSolarSystem(ssPtr);
   btParam->SetInternalCoordSystem(csPtr);
   btParam->SetRefObjectName(Gmat::COORDINATE_SYSTEM, "EarthMJ2000Eq");
   btParam->SetRefObject(csPtr, Gmat::COORDINATE_SYSTEM, "EarthMJ2000Eq");
   btParam->SetRefObjectName(Gmat::SPACECRAFT, "MySpacecraft");
   btParam->SetRefObject(scPtr, Gmat::SPACECRAFT, "MySpacecraft");
   btParam->Initialize();
   
   out.Put("num RefObjects = ", btParam->GetNumRefObjects());
   out.Put("----- test btParam->EvaluateReal()");
   out.Put("----- Should get an exception due to non-hyperbolic orbit");
   realVal = btParam->EvaluateReal();
   
   out.Put("============================== test BdotR()");
   BdotR *brParam = new BdotR();
   brParam->SetSolarSystem(ssPtr);
   brParam->SetInternalCoordSystem(csPtr);
   brParam->SetRefObjectName(Gmat::COORDINATE_SYSTEM, "EarthMJ2000Eq");
   brParam->SetRefObject(csPtr, Gmat::COORDINATE_SYSTEM, "EarthMJ2000Eq");
   brParam->SetRefObjectName(Gmat::SPACECRAFT, "MySpacecraft");
   brParam->SetRefObject(scPtr, Gmat::SPACECRAFT, "MySpacecraft");
   brParam->Initialize();
   
   out.Put("num RefObjects = ", brParam->GetNumRefObjects());
   out.Put("----- test brParam->EvaluateReal()");
   out.Put("----- Should get an exception due to non-hyperbolic orbit");
   realVal = brParam->EvaluateReal();
   out.Put("");

   out.Put("=================================== Test in EarthMJ2000Ec");
   
   BdotT *btecParam = new BdotT();
   btecParam->SetSolarSystem(ssPtr);
   btecParam->SetInternalCoordSystem(csPtr);
   btecParam->SetRefObjectName(Gmat::COORDINATE_SYSTEM, "EarthMJ2000Ec");
   btecParam->SetRefObject(eccsPtr, Gmat::COORDINATE_SYSTEM, "EarthMJ2000Ec");
   btecParam->SetRefObjectName(Gmat::SPACECRAFT, "MySpacecraft");
   btecParam->SetRefObject(scPtr, Gmat::SPACECRAFT, "MySpacecraft");
   
   out.Put("----- test btParam->EvaluateReal()");
   out.Put("----- Should get an exception due to non-hyperbolic orbit");
   realVal = btecParam->EvaluateReal();
   out.Put("");
   
   BdotR *brecParam = new BdotR();
   brecParam->SetSolarSystem(ssPtr);
   brecParam->SetInternalCoordSystem(csPtr);
   brecParam->SetRefObjectName(Gmat::COORDINATE_SYSTEM, "EarthMJ2000Ec");
   brecParam->SetRefObject(eccsPtr, Gmat::COORDINATE_SYSTEM, "EarthMJ2000Ec");
   brecParam->SetRefObjectName(Gmat::SPACECRAFT, "MySpacecraft");
   brecParam->SetRefObject(scPtr, Gmat::SPACECRAFT, "MySpacecraft");
   
   out.Put("----- test brParam->EvaluateReal()");
   out.Put("----- Should get an exception due to non-hyperbolic orbit");
   realVal = brecParam->EvaluateReal();
   out.Put("");
   
   /*
   ***************************************************************************
   * From Steve Hughes(2005/06/16)
   % Position and velocity in EarthMJ2000Eq
   % (Epoch does not matter so you can choose your own)
   rv = [233410.6846140172000   83651.0868276347170  -168884.42195943173]';
   vv = [-0.4038280708568842      2.0665425988121107  0.4654706868112324]';

   *%  Bplane Coordinates for EarthMJ2000Eq system*
   Sat.EarthMJ2000Eq.BdotT =   365738.686341826
   Sat.EarthMJ2000Eq.BdotR =   276107.260600374
   
   *%  Bplane Coordinates for EarthMJ2000Ec system*
   Sat.EarthMJ2000Ec.BdotT =   381942.623061352
   Sat.EarthMJ2000Ec.BdotR =   253218.95413318
   ***************************************************************************
   */
   
   // Now set spacecraft state to hyperbolic orbit
   Real state[6];
 
   state[0] =  233410.6846140172000;
   state[1] =   83651.0868276347170;
   state[2] = -168884.42195943173;
   state[3] = -0.4038280708568842;
   state[4] =  2.0665425988121107;
   state[5] =  0.4654706868112324;
   scPtr->SetState("Cartesian", state);
   Rvector6 stateVec(state);
   
   out.Put("=================================== Test with hyperbolic orbit");
   out.Put("========== state = ", scPtr->GetCartesianState().ToString());
   
   // Now test in EartMJ2000Eq
   
   out.Put("=================================== Test in EarthMJ2000Eq");
   btParam->SetRefObjectName(Gmat::COORDINATE_SYSTEM, "EarthMJ2000Eq");
   btParam->SetRefObject(csPtr, Gmat::COORDINATE_SYSTEM, "EarthMJ2000Eq");
   
   expResult = 365738.686341826;
   out.Put("----- test btParam->EvaluateReal() Should return ", expResult);
   realVal = btParam->EvaluateReal();
   out.Validate(realVal, expResult);
   
   expResult = 276107.260600374;
   out.Put("----- test brParam->EvaluateReal() Should return ", expResult);
   realVal = brParam->EvaluateReal();
   out.Validate(realVal, expResult);
   
   // Now test in EartMJ2000Ec
   
   out.Put("=================================== Test in EarthMJ2000Ec");
      
   realVal = btecParam->EvaluateReal();
   
   out.Put("----- test btecParam->EvaluateReal() Should return ", expResult);
   expResult = 381942.623061352;
   out.Validate(realVal, expResult);
   
   expResult = 253218.95413318;
   out.Put("----- test brecParam->EvaluateReal() Should return ", expResult);
   realVal = brecParam->EvaluateReal();
   out.Validate(realVal, expResult);
   
   //---------------------------------------------
   // clean up
   //---------------------------------------------
   delete btParam;
   delete brParam;
   delete btecParam;
   delete brecParam;
   delete scPtr;
   delete ssPtr;
   delete csPtr;
   //delete theSlpFile; //problem deleting!!
}
Beispiel #12
0
int main (int argc, char * argv[]) {
  GravitySystem gs;
  CelestialBody * sun = new CelestialBody(100, 1);
  sun->setName("Sun");
  sun->setPosition(Vector3(0,0,0));
  sun->setVelocity(Vector3(0,0,0));
  CelestialBody * jupiter = new CelestialBody(1, 2);
  jupiter->setName("Jupiter");
  jupiter->setPosition(Vector3(100, 0, 0));
  jupiter->setVelocity(Vector3(1,5,0));
  gs.addCelestialBody(sun);
  gs.addCelestialBody(jupiter);
  cout<<"The system has " << gs.getCelestialBodies().size() << " bodies." <<endl;
  assert(gs.getCelestialBodies().size()==2);
  CelestialBody * body = gs.getCelestialBodyById(1);
  assert (body->getId()==1);
  assert (body->getName() == string("Sun"));
  cout<<"The first body is the "<<body->getName() <<"."<<endl;
  return 0;
}
Beispiel #13
0
//------------------------------------------------------------------------------
// void OnHorizonReferenceComboBoxChange()
//------------------------------------------------------------------------------
void GroundStationPanel::OnHorizonReferenceComboBoxChange(wxCommandEvent &event)
{
   std::string horizon       = horizonReferenceComboBox->GetValue().c_str();
   std::string inputString;
   Real        location1, location2, location3;
   if (horizon != currentHorizonReference)
   {
      std::string bodyName = centralBodyComboBox->GetValue().c_str();
      // get a pointer to the celestial body
      CelestialBody *body = ss->GetBody(bodyName);
      if (!body)
      {
         std::string errmsg = "Cannot find body ";
         errmsg += bodyName + " needed for GroundStation panel update.\n";
         throw GmatBaseException(errmsg);
      }
      Real meanRadius = body->GetRealParameter(body->GetParameterID("EquatorialRadius"));
      Real flattening = body->GetRealParameter(body->GetParameterID("Flattening"));
      // Convert location values to the appropriate values
      // Location 1 (Latitude)
      inputString = location1TextCtrl->GetValue();
      CheckReal(location1, inputString, localGroundStation->GetStringParameter(BodyFixedPoint::LOCATION_LABEL_1), "Real Number");

      // Location 2 (Longitude)
      inputString = location2TextCtrl->GetValue();
      if (currentStateType != "Cartesian")
         CheckReal(location2, inputString, localGroundStation->GetStringParameter(BodyFixedPoint::LOCATION_LABEL_2), "Real Number >= 0.0", false, true, true, true);
      else
         CheckReal(location2, inputString, localGroundStation->GetStringParameter(BodyFixedPoint::LOCATION_LABEL_2), "Real Number");

      // Location 3 (Altitude)
      inputString = location3TextCtrl->GetValue();
      CheckReal(location3, inputString, localGroundStation->GetStringParameter(BodyFixedPoint::LOCATION_LABEL_3), "Real Number");

      Rvector3 locInCurrent(location1, location2, location3);
      if (currentStateType == "Spherical") // latitude and longitude need to be passed in as radians
      {
         locInCurrent[0] *= GmatMathConstants::RAD_PER_DEG;
         locInCurrent[1] *= GmatMathConstants::RAD_PER_DEG;
      }
      //MessageInterface::ShowMessage(" ... Spherical to new horizon ... loc = %12.10f  %12.10f  %12.10f\n",
      //      locInCurrent[0], locInCurrent[1], locInCurrent[2]); // *************************
      Rvector3 locInNew = BodyFixedStateConverterUtil::Convert(locInCurrent, currentStateType,
                          currentHorizonReference, currentStateType, horizon,
                          flattening, meanRadius);
      //MessageInterface::ShowMessage(" ... result =  %12.10f  %12.10f  %12.10f\n",
      //      locInNew[0], locInNew[1], locInNew[2]); // *************************
      location1 = locInNew[0];
      location2 = locInNew[1];
      location3 = locInNew[2];
      if (currentStateType == "Spherical") // need to display DEGREES for latitude and longitude
      {
         location1 *= GmatMathConstants::DEG_PER_RAD;
         location2 *= GmatMathConstants::DEG_PER_RAD;
      }
      localGroundStation->SetStringParameter(BodyFixedPoint::HORIZON_REFERENCE, horizon);
      localGroundStation->SetRealParameter(BodyFixedPoint::LOCATION_1, location1);
      localGroundStation->SetRealParameter(BodyFixedPoint::LOCATION_2, location2);
      localGroundStation->SetRealParameter(BodyFixedPoint::LOCATION_3, location3);
      location1TextCtrl->SetValue(ToWxString(location1));
      location2TextCtrl->SetValue(ToWxString(location2));
      location3TextCtrl->SetValue(ToWxString(location3));
      currentHorizonReference = horizon;
   }
   UpdateControls();
   EnableUpdate(true);
}