//------------------------------------------------------------------------------ PropSetup *GetFirstPropagator(GmatCommand *cmd) { static PropSetup *retval = NULL; GmatCommand *current = cmd; #ifdef DEBUG_ODE_SEARCH extraMsg = "Commands checked:\n"; #endif while (current != NULL) { #ifdef DEBUG_ODE_SEARCH extraMsg += " '" + current->GetTypeName() + "'\n"; #endif if (current->GetTypeName() == "Propagate") { try { // Set all of the internal connections // current->TakeAction("PrepareToPropagate"); current->Execute(); } catch (BaseException &ex) { lastMsg = ex.GetFullMessage(); } #ifdef DEBUG_ODE_SEARCH extraMsg += " Checking in this command\n"; #endif GmatBase *obj = current->GetRefObject(Gmat::PROP_SETUP, "", 0); #ifdef DEBUG_ODE_SEARCH if (obj != NULL) extraMsg += " Found an object of type PROPSETUP\n"; else extraMsg += " Propagate command returns NULL PROPSETUP\n"; #endif if (obj->IsOfType("PropSetup")) { retval = (PropSetup*)(obj); break; } } current = current->GetNext(); } return retval; }
//------------------------------------------------------------------------------ bool Target::Execute() { #ifdef DEBUG_TARGET_EXEC MessageInterface::ShowMessage (wxT("Target::Execute() entered, theSolver=<%p>'%s'\n"), (GmatBase*)theSolver, theSolver->GetName().c_str()); MessageInterface::ShowMessage (wxT("maxIter=%d\n"), theSolver->GetIntegerParameter(theSolver->GetParameterID(wxT("MaximumIterations")))); MessageInterface::ShowMessage (wxT("currentFunction=<%p>'%s'\n"), currentFunction, currentFunction ? ((GmatBase*)currentFunction)->GetName().c_str() : wxT("NULL")); #endif // If targeting inside a function, we need to reinitialize since the local solver is // cloned in Initialize(). All objects including solvers are initialized in // assignment command which happens after Target::Initialize(). (LOJ: 2009.03.17) if (currentFunction != NULL && !targeterInFunctionInitialized) { Initialize(); targeterInFunctionInitialized = true; } bool retval = true; // Drive through the state machine. Solver::SolverState state = theSolver->GetState(); #ifdef DEBUG_TARGET_COMMANDS MessageInterface::ShowMessage(wxT("TargetExecute(%c%c%c%d)\n"), (commandExecuting?wxT('Y'):wxT('N')), (commandComplete?wxT('Y'):wxT('N')), (branchExecuting?wxT('Y'):wxT('N')), state); MessageInterface::ShowMessage(wxT(" targeterConverged=%d\n"), targeterConverged); #endif // Attempt to reset if recalled if (commandComplete) { commandComplete = false; commandExecuting = false; specialState = Solver::INITIALIZING; } if (!commandExecuting) { #ifdef DEBUG_TARGET_COMMANDS MessageInterface::ShowMessage( wxT("Entered Targeter while command is not executing\n")); #endif FreeLoopData(); StoreLoopData(); retval = SolverBranchCommand::Execute(); #ifdef DEBUG_TARGETER MessageInterface::ShowMessage(wxT("Resetting the Differential Corrector\n")); #endif theSolver->TakeAction(wxT("Reset")); state = theSolver->GetState(); } if (branchExecuting) { retval = ExecuteBranch(); if (!branchExecuting) { if ((state == Solver::FINISHED) || (specialState == Solver::FINISHED)) { PenDownSubscribers(); LightenSubscribers(1); commandComplete = true; } else { PenUpSubscribers(); } } } else { GmatCommand *currentCmd; publisher->SetRunState(Gmat::SOLVING); switch (startMode) { case RUN_INITIAL_GUESS: #ifdef DEBUG_START_MODE MessageInterface::ShowMessage( wxT("Running as RUN_INITIAL_GUESS, specialState = %d, currentState = %d\n"), specialState, theSolver->GetState()); #endif switch (specialState) { case Solver::INITIALIZING: // Finalize initialization of the targeter data currentCmd = branch[0]; targeterConverged = false; while (currentCmd != this) { wxString type = currentCmd->GetTypeName(); if ((type == wxT("Target")) || (type == wxT("Vary")) || (type == wxT("Achieve"))) currentCmd->Execute(); currentCmd = currentCmd->GetNext(); } StoreLoopData(); specialState = Solver::NOMINAL; break; case Solver::NOMINAL: // Execute the nominal sequence if (!commandComplete) { branchExecuting = true; ResetLoopData(); } specialState = Solver::RUNSPECIAL; break; case Solver::RUNSPECIAL: // Run once more to publish the data from the converged state if (!commandComplete) { ResetLoopData(); branchExecuting = true; publisher->SetRunState(Gmat::SOLVEDPASS); } theSolver->Finalize(); specialState = Solver::FINISHED; // Final clean-up targeterConverged = true; break; case Solver::FINISHED: specialState = Solver::INITIALIZING; break; default: break; } break; case RUN_SOLUTION: #ifdef DEBUG_START_MODE MessageInterface::ShowMessage( wxT("Running as RUN_SOLUTION, state = %d\n"), state); #endif throw SolverException( wxT("Run Solution is not yet implemented for the Target ") wxT("command\n")); break; case RUN_AND_SOLVE: default: #ifdef DEBUG_START_MODE MessageInterface::ShowMessage( wxT("Running as RUN_AND_SOLVE or default, state = %d\n"), state); #endif switch (state) { case Solver::INITIALIZING: // Finalize initialization of the targeter data currentCmd = branch[0]; targeterConverged = false; while (currentCmd != this) { wxString type = currentCmd->GetTypeName(); if ((type == wxT("Target")) || (type == wxT("Vary")) || (type == wxT("Achieve"))) { currentCmd->Execute(); if ((type == wxT("Vary")) && (targeterRunOnce)) currentCmd->TakeAction(wxT("SolverReset")); } currentCmd = currentCmd->GetNext(); } StoreLoopData(); GetActiveSubscribers(); SetSubscriberBreakpoint(); break; case Solver::NOMINAL: // Execute the nominal sequence if (!commandComplete) { branchExecuting = true; ApplySubscriberBreakpoint(); PenDownSubscribers(); LightenSubscribers(1); ResetLoopData(); } break; case Solver::CHECKINGRUN: // Check for convergence; this is done in the targeter state // machine, so this case is a NoOp for the Target command break; case Solver::PERTURBING: branchExecuting = true; ApplySubscriberBreakpoint(); PenDownSubscribers(); LightenSubscribers(4); ResetLoopData(); break; case Solver::CALCULATING: // Calculate the next set of variables to use; this is // performed in the targeter -- nothing to be done here break; case Solver::FINISHED: // Final clean-up targeterConverged = true; targeterRunOnce = true; // Run once more to publish the data from the converged state if (!commandComplete) { ResetLoopData(); branchExecuting = true; ApplySubscriberBreakpoint(); PenDownSubscribers(); LightenSubscribers(1); publisher->SetRunState(Gmat::SOLVEDPASS); } break; case Solver::ITERATING: // Intentional fall-through default: throw CommandException( wxT("Invalid state in the Targeter state machine")); } break; } } if (!branchExecuting) { theSolver->AdvanceState(); if (theSolver->GetState() == Solver::FINISHED) { publisher->FlushBuffers(); targeterConverged = true; } } // Pass spacecraft data to the targeter for reporting in debug mode if (targeterInDebugMode) { wxString dbgData = wxT(""); for (ObjectArray::iterator i = localStore.begin(); i < localStore.end(); ++i) { dbgData += (*i)->GetGeneratingString() + wxT("\n---\n"); } theSolver->SetDebugString(dbgData); } BuildCommandSummary(true); #ifdef DEBUG_TARGET_EXEC MessageInterface::ShowMessage (wxT("Target::Execute() returning %d, theSolver=<%p>'%s'\n"), retval, theSolver, theSolver->GetName().c_str()); #endif return retval; }
//------------------------------------------------------------------------------ // bool GmatFunction::Execute(ObjectInitializer *objInit, bool reinitialize) //------------------------------------------------------------------------------ bool GmatFunction::Execute(ObjectInitializer *objInit, bool reinitialize) { if (!fcs) return false; if (!objInit) return false; #ifdef DEBUG_TRACE static Integer callCount = 0; callCount++; clock_t t1 = clock(); ShowTrace(callCount, t1, wxT("GmatFunction::Execute() entered")); #endif #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("======================================================================\n") wxT("GmatFunction::Execute() entered for '%s'\n internalCS is <%p>, ") wxT("reinitialize = %d\n"), functionName.c_str(), internalCoordSys, reinitialize); #endif GmatCommand *current = fcs; GmatCommand *last = NULL; // We want to initialize local objects with new object map, // so do it everytime (loj: 2008.09.26) // This causes to slow down function execution, so initialize if necessary if (reinitialize) objectsInitialized = false; // Reinitialize CoordinateSystem to fix bug 1599 (LOJ: 2009.11.05) // Reinitialize Parameters to fix bug 1519 (LOJ: 2009.09.16) if (objectsInitialized) { if (!objInit->InitializeObjects(true, Gmat::COORDINATE_SYSTEM)) throw FunctionException (wxT("Failed to re-initialize Parameters in the \"") + functionName + wxT("\"")); if (!objInit->InitializeObjects(true, Gmat::PARAMETER)) throw FunctionException (wxT("Failed to re-initialize Parameters in the \"") + functionName + wxT("\"")); } // Go through each command in the sequence and execute. // Once it gets to a real command, initialize local and automatic objects. while (current) { // Call to IsNextAFunction is necessary for branch commands in particular #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("......Function executing <%p><%s> [%s]\n"), current, current->GetTypeName().c_str(), current->GetGeneratingString(Gmat::NO_COMMENTS).c_str()); MessageInterface::ShowMessage(wxT(" objectsInitialized=%d\n"), objectsInitialized); #endif last = current; if (!objectsInitialized) { // Since we don't know where actual mission sequence starts, just check // for command that is not NoOp, Create, Global, and GMAT with equation. // Can we have simple command indicating beginning of the sequence, // such as BeginSequence? (loj: 2008.06.19) // @todo: Now we have BeginMissionSequence, but not all functions have it, // so check it first otherwise do in the old way. (loj: 2010.07.16) Function *func = current->GetCurrentFunction(); bool isEquation = false; wxString cmdType = current->GetTypeName(); if (func && cmdType == wxT("GMAT")) if (((Assignment*)current)->GetMathTree() != NULL) isEquation = true; if (cmdType != wxT("NoOp") && cmdType != wxT("Create") && cmdType != wxT("Global")) { bool beginInit = true; if (cmdType == wxT("GMAT") && !isEquation) beginInit = false; if (cmdType == wxT("BeginMissionSequence") || cmdType == wxT("BeginScript")) beginInit = true; if (beginInit) { objectsInitialized = true; validator->HandleCcsdsEphemerisFile(objectStore, true); #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("============================ Initializing LocalObjects at current\n") wxT("%s\n"), current->GetGeneratingString(Gmat::NO_COMMENTS).c_str()); #endif InitializeLocalObjects(objInit, current, true); } } } // Now execute the function sequence try { #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("Now calling <%p>[%s]->Execute()\n"), current->GetTypeName().c_str(), current->GetGeneratingString(Gmat::NO_COMMENTS).c_str()); #endif if (!(current->Execute())) return false; } catch (BaseException &e) { // If it is user interrupt, rethrow (loj: 2008.10.16) // How can we tell if it is thrown by Stop command? // For now just find the phrase wxT("interrupted by Stop command") wxString msg = e.GetFullMessage(); if (msg.find(wxT("interrupted by Stop command")) != msg.npos) { #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("*** Interrupted by Stop commaned, so re-throwing...\n")); #endif throw; } if (e.IsFatal()) { #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("*** The exception is fatal, so re-throwing...\n")); #endif // Add command line to error message (LOJ: 2010.04.13) throw FunctionException (wxT("In ") + current->GetGeneratingString(Gmat::NO_COMMENTS) + wxT(", ") + e.GetFullMessage()); //throw; } // Let's try initialzing local objects here again (2008.10.14) try { #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("============================ Reinitializing LocalObjects at current\n") wxT("%s\n"), current->GetGeneratingString(Gmat::NO_COMMENTS).c_str()); #endif InitializeLocalObjects(objInit, current, false); #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("......Function re-executing <%p><%s> [%s]\n"), current, current->GetTypeName().c_str(), current->GetGeneratingString(Gmat::NO_COMMENTS).c_str()); #endif if (!(current->Execute())) return false; } catch (HardwareException &he) { // Ignore for hardware exception since spacecraft is associated with Thruster // but Thruster binds with Tank later in the fcs } catch (BaseException &be) { throw FunctionException (wxT("During initialization of local objects before \"") + current->GetGeneratingString(Gmat::NO_COMMENTS) + wxT("\", ") + e.GetFullMessage()); } } // If current command is BranchCommand and still executing, continue to next // command in the branch (LOJ: 2009.03.24) if (current->IsOfType(wxT("BranchCommand")) && current->IsExecuting()) { #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("In Function '%s', still executing current command is <%p><%s>\n"), functionName.c_str(), current, current ? current->GetTypeName().c_str() : wxT("NULL")); #endif continue; } current = current->GetNext(); #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("In Function '%s', the next command is <%p><%s>\n"), functionName.c_str(), current, current ? current->GetTypeName().c_str() : wxT("NULL")); #endif } // Set ObjectMap from the last command to Validator in order to create // valid output wrappers (loj: 2008.11.12) validator->SetObjectMap(last->GetObjectMap()); #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT(" Now about to create %d output wrapper(s) to set results, objectsInitialized=%d\n"), outputNames.size(), objectsInitialized); #endif // create output wrappers and put into map GmatBase *obj; wrappersToDelete.clear(); for (unsigned int jj = 0; jj < outputNames.size(); jj++) { if (!(obj = FindObject(outputNames.at(jj)))) { wxString errMsg = wxT("Function: Output \"") + outputNames.at(jj); errMsg += wxT(" not found for function \"") + functionName + wxT("\""); throw FunctionException(errMsg); } wxString outName = outputNames.at(jj); ElementWrapper *outWrapper = validator->CreateElementWrapper(outName, false, false); #ifdef DEBUG_MORE_MEMORY MessageInterface::ShowMessage (wxT("+++ GmatFunction::Execute() *outWrapper = validator->") wxT("CreateElementWrapper(%s), <%p> '%s'\n"), outName.c_str(), outWrapper, outWrapper->GetDescription().c_str()); #endif outWrapper->SetRefObject(obj); // nested CallFunction crashes if old outWrappers are deleted here. (loj: 2008.11.24) // so collect here and delete when FunctionRunner completes. wrappersToDelete.push_back(outWrapper); // Set new outWrapper outputArgMap[outName] = outWrapper; #ifdef DEBUG_FUNCTION_EXEC // --------------------------------------------------- debug --- MessageInterface::ShowMessage(wxT("GmatFunction: Output wrapper created for %s\n"), (outputNames.at(jj)).c_str()); #endif // -------------------------------------------------------------- end debug --- } #ifdef DEBUG_FUNCTION_EXEC MessageInterface::ShowMessage (wxT("GmatFunction::Execute() exiting true for '%s'\n"), functionName.c_str()); #endif #ifdef DEBUG_TRACE ShowTrace(callCount, t1, wxT("GmatFunction::Execute() exiting"), true); #endif return true; }