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); }
//------------------------------------------------------------------------------ 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 ); }
// 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); } } }
// 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(); } } }
//------------------------------------------------------------------------------ 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; }
//------------------------------------------------------------------------------ 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 }
// 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 }
//------------------------------------------------------------------------------ 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()); } }
//------------------------------------------------------------------------------ //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!! }
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; }
//------------------------------------------------------------------------------ // 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); }