//------------------------------------------------------------------------------ // void DecrementMass() //------------------------------------------------------------------------------ void ImpulsiveBurn::DecrementMass() { #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (wxT("ImpulsiveBurn::DecrementMass() <%p>'%s' entered. There are %d tank(s)\n"), this, instanceName.c_str(), tankMap.size()); #endif totalTankMass = spacecraft->GetRealParameter(wxT("TotalMass")); #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (wxT(" Now decrementing mass\n before maneuver totalTankMass = %f\n"), totalTankMass); #endif Real dv = sqrt( deltaV[0]*deltaV[0] + deltaV[1]*deltaV[1] + deltaV[2]*deltaV[2]); deltaTankMass = totalTankMass * (exp(-dv * 1000/(isp * gravityAccel)) - 1.0); #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (wxT(" after maneuver deltaTankMass = %f\n"), deltaTankMass); #endif totalTankMass = totalTankMass + deltaTankMass; #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (wxT(" after maneuver totalTankMass = %f\n"), totalTankMass); #endif // Update tank mass if (!tankMap.empty()) { for (ObjectMap::iterator tankPos = tankMap.begin(); tankPos != tankMap.end(); ++tankPos) { GmatBase *currTank = tankPos->second; #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (wxT(" Decrementing tank mass for <%p>'%s'\n"), currTank, (tankPos->first).c_str()); #endif Integer paramID = currTank->GetParameterID(wxT("FuelMass")); Real oldTankMass = currTank->GetRealParameter(paramID); Real currTankMass = oldTankMass + deltaTankMass; #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (wxT(" it was %f, it is now %f\n"), oldTankMass, currTankMass); #endif //@todo What should we do if decremented tank mass is below zero? currTank->SetRealParameter(paramID, currTankMass); } } #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (wxT("ImpulsiveBurn::DecrementMass() <%p>'%s' returning\n"), this, GetName().c_str()); #endif }
//------------------------------------------------------------------------------ // void DecrementMass() //------------------------------------------------------------------------------ void ImpulsiveBurn::DecrementMass(bool backwards) { #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage ("ImpulsiveBurn::DecrementMass() <%p>'%s' entered. There are %d tank(s)\n", this, instanceName.c_str(), tankMap.size()); #endif totalTankMass = spacecraft->GetRealParameter("TotalMass"); #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (" Now decrementing mass\n before maneuver totalTankMass = %f\n", totalTankMass); #endif Real dv = sqrt( deltaV[0]*deltaV[0] + deltaV[1]*deltaV[1] + deltaV[2]*deltaV[2]); if (!backwards) deltaTankMass = totalTankMass * (exp(-dv * 1000/(isp * gravityAccel)) - 1.0); else deltaTankMass = totalTankMass * (exp(dv * 1000/(isp * gravityAccel)) - 1.0); #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (" after maneuver deltaTankMass = %f\n", deltaTankMass); #endif totalTankMass = totalTankMass + deltaTankMass; #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (" after maneuver totalTankMass = %f\n", totalTankMass); #endif // Update tank mass if (!tankMap.empty()) { if (tankMap.size() > 1) throw BurnException("The ImpulsiveBorn object " + instanceName + " is configured to draw mass from multiple tanks, but only one " "tank is supported in the current implementation."); // This code is set up to draw from multiple tanks, but the amount drawn // is not calculated to draw proportionally. Instead, it reduces each // tank by deltaTankMass. We need to check this code before enabling // mass reduction from multiple tanks in a single impulsive burn. for (ObjectMap::iterator tankPos = tankMap.begin(); tankPos != tankMap.end(); ++tankPos) { GmatBase *currTank = tankPos->second; #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (" Decrementing tank mass for <%p>'%s'\n", currTank, (tankPos->first).c_str()); #endif Integer paramID = currTank->GetParameterID("FuelMass"); Real oldTankMass = currTank->GetRealParameter(paramID); Real currTankMass = oldTankMass + deltaTankMass; #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage (" it was %f, it is now %f\n", oldTankMass, currTankMass); #endif //@todo What should we do if decremented tank mass is below zero? currTank->SetRealParameter(paramID, currTankMass); } } else throw BurnException("Impulsive Burn " + instanceName + " is set to decrement mass from a tank named " + tankNames[0] + ", but the Spacecraft " + spacecraft->GetName() + " does not have the selected fuel tank."); #ifdef DEBUG_IMPBURN_DECMASS MessageInterface::ShowMessage ("ImpulsiveBurn::DecrementMass() <%p>'%s' returning\n", this, GetName().c_str()); #endif }
//------------------------------------------------------------------------------ // bool Initialize() //------------------------------------------------------------------------------ bool GmatFunction::Initialize() { #ifdef DEBUG_TRACE static Integer callCount = 0; callCount++; clock_t t1 = clock(); ShowTrace(callCount, t1, wxT("GmatFunction::Initialize() entered")); #endif #ifdef DEBUG_FUNCTION_INIT MessageInterface::ShowMessage (wxT("======================================================================\n") wxT("GmatFunction::Initialize() entered for function '%s'\n"), functionName.c_str()); MessageInterface::ShowMessage(wxT(" and FCS is %s set.\n"), (fcs? wxT("correctly") : wxT("NOT"))); MessageInterface::ShowMessage(wxT(" Pointer for FCS is %p\n"), fcs); MessageInterface::ShowMessage(wxT(" First command in fcs is %s\n"), (fcs->GetTypeName()).c_str()); MessageInterface::ShowMessage(wxT(" internalCS is %p\n"), internalCoordSys); #endif if (!fcs) return false; Function::Initialize(); // Initialize the Validator - I think I need to do this each time - or do I? validator->SetFunction(this); validator->SetSolarSystem(solarSys); std::map<wxString, GmatBase *>::iterator omi; // add automatic objects such as sat.X to the FOS (well, actually, clones of them) for (omi = automaticObjectMap.begin(); omi != automaticObjectMap.end(); ++omi) { wxString autoObjName = omi->first; // if name not found, clone it and add to map (loj: 2008.12.15) if (objectStore->find(autoObjName) == objectStore->end()) { GmatBase *autoObj = (omi->second)->Clone(); #ifdef DEBUG_MEMORY MemoryTracker::Instance()->Add (autoObj, autoObjName, wxT("GmatFunction::Initialize()"), wxT("autoObj = (omi->second)->Clone()")); #endif #ifdef DEBUG_FUNCTION_INIT try { MessageInterface::ShowMessage (wxT(" autoObj->EvaluateReal() = %f\n"), autoObj->GetRealParameter(wxT("Value"))); } catch (BaseException &e) { MessageInterface::ShowMessage(e.GetFullMessage()); } #endif autoObj->SetIsLocal(true); objectStore->insert(std::make_pair(autoObjName, autoObj)); } } // first, send all the commands the object store, solar system, etc GmatCommand *current = fcs; while (current) { #ifdef DEBUG_FUNCTION_INIT if (!current) MessageInterface::ShowMessage(wxT("Current is NULL!!!\n")); else MessageInterface::ShowMessage(wxT(" =====> Current command is %s <%s>\n"), (current->GetTypeName()).c_str(), current->GetGeneratingString(Gmat::NO_COMMENTS).c_str()); #endif current->SetObjectMap(objectStore); current->SetGlobalObjectMap(globalObjectStore); current->SetSolarSystem(solarSys); current->SetInternalCoordSystem(internalCoordSys); current->SetTransientForces(forces); #ifdef DEBUG_FUNCTION_INIT MessageInterface::ShowMessage (wxT(" Now about to set object map of type %s to Validator\n"), (current->GetTypeName()).c_str()); #endif // (Re)set object map on Validator (necessary because objects may have been added to the // Local Object Store or Global Object Store during initialization of previous commands) validatorStore.clear(); for (omi = objectStore->begin(); omi != objectStore->end(); ++omi) validatorStore.insert(std::make_pair(omi->first, omi->second)); for (omi = globalObjectStore->begin(); omi != globalObjectStore->end(); ++omi) validatorStore.insert(std::make_pair(omi->first, omi->second)); validator->SetObjectMap(&validatorStore); #ifdef DEBUG_FUNCTION_INIT MessageInterface::ShowMessage (wxT(" Now about to call Validator->ValidateCommand() of type %s\n"), current->GetTypeName().c_str()); #endif // Let's try to ValidateCommand here, this will validate the command // and create wrappers also if (!validator->ValidateCommand(current, false, 2)) { // get error message (loj: 2008.06.04) StringArray errList = validator->GetErrorList(); wxString msg; // Check for empty errList (loj: 2009.03.17) if (errList.empty()) msg = wxT("Error occurred"); else msg = errList[0]; throw FunctionException(msg + wxT(" in the function \"") + functionPath + wxT("\"")); } #ifdef DEBUG_FUNCTION_INIT MessageInterface::ShowMessage (wxT(" Now about to initialize command of type %s\n"), current->GetTypeName().c_str()); #endif // catch exception and add function name to message (loj: 2008.09.23) try { if (!(current->Initialize())) { #ifdef DEBUG_FUNCTION_INIT MessageInterface::ShowMessage (wxT("Exiting GmatFunction::Initialize for function '%s' with false\n"), functionName.c_str()); #endif return false; } } catch (BaseException &e) { throw FunctionException(wxT("Cannot continue due to ") + e.GetFullMessage() + wxT(" in the function \"") + functionPath + wxT("\"")); } // Check to see if the command needs a server startup (loj: 2008.07.25) if (current->NeedsServerStartup()) if (validator->StartMatlabServer(current) == false) throw FunctionException(wxT("Unable to start the server needed by the ") + (current->GetTypeName()) + wxT(" command")); current = current->GetNext(); } // Get automatic global object list and check if they are used in the function // command sequence so that when any global object is declared in the main script // but not used in the function, they can be ignored during function local object // initialization. (LOJ: 2009.12.18) BuildUnusedGlobalObjectList(); fcsFinalized = false; #ifdef DEBUG_FUNCTION_INIT MessageInterface::ShowMessage (wxT("GmatFunction::Initialize() exiting for function '%s' with true\n"), functionName.c_str()); #endif #ifdef DEBUG_TRACE ShowTrace(callCount, t1, wxT("GmatFunction::Initialize() exiting"), true); #endif return true; }