FGFDMExec::~FGFDMExec() { try { Unbind(); DeAllocate(); delete instance; if (IdFDM == 0) { // Meaning this is no child FDM if(Root != 0) { if(StandAlone) delete Root; Root = 0; } if(FDMctr != 0) { delete FDMctr; FDMctr = 0; } } } catch ( string msg ) { cout << "Caught error: " << msg << endl; } for (unsigned int i=1; i<ChildFDMList.size(); i++) delete ChildFDMList[i]->exec; ChildFDMList.clear(); PropertyCatalog.clear(); SetGroundCallback(0); if (FDMctr > 0) (*FDMctr)--; Debug(1); }
FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root), FDMctr(fdmctr) { Frame = 0; Error = 0; SetGroundCallback(new FGDefaultGroundCallback()); IC = 0; Trim = 0; Script = 0; RootDir = ""; modelLoaded = false; IsChild = false; holding = false; Terminate = false; StandAlone = false; firstPass = true; IncrementThenHolding = false; // increment then hold is off by default TimeStepsUntilHold = -1; sim_time = 0.0; dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is // run in standalone mode with no initialization file. AircraftPath = "aircraft"; EnginePath = "engine"; SystemsPath = "systems"; try { char* num = getenv("JSBSIM_DEBUG"); if (num) debug_lvl = atoi(num); // set debug level } catch (...) { // if error set to 1 debug_lvl = 1; } if (Root == 0) { // Then this is the root FDM Root = new FGPropertyManager; // Create the property manager StandAlone = true; } if (FDMctr == 0) { FDMctr = new unsigned int; // Create and initialize the child FDM counter (*FDMctr) = 0; } // Store this FDM's ID IdFDM = (*FDMctr); // The main (parent) JSBSim instance is always the "zeroth" // Prepare FDMctr for the next child FDM id (*FDMctr)++; // instance. "child" instances are loaded last. instance = Root->GetNode("/fdm/jsbsim",IdFDM,true); Debug(0); // this is to catch errors in binding member functions to the property tree. try { Allocate(); } catch ( string msg ) { cout << "Caught error: " << msg << endl; exit(1); } trim_status = false; ta_mode = 99; Constructing = true; typedef int (FGFDMExec::*iPMF)(void) const; // typedef unsigned int (FGFDMExec::*uiPMF)(void) const; // instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis, false); instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim, false); instance->Tie("simulation/do_simplex_trim", this, (iPMF)0, &FGFDMExec::DoSimplexTrim); instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions, false); instance->Tie("simulation/randomseed", this, (iPMF)0, &FGFDMExec::SRand, false); instance->Tie("simulation/terminate", (int *)&Terminate); instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime); instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel); instance->Tie("simulation/frame", (int *)&Frame, false); Constructing = false; }
bool FGFDMExec::Allocate(void) { bool result=true; Models.resize(eNumStandardModels); // First build the inertial model since some other models are relying on // the inertial model and the ground callback to build themselves. // Note that this does not affect the order in which the models will be // executed later. Models[eInertial] = new FGInertial(this); SetGroundCallback(new FGDefaultGroundCallback(static_cast<FGInertial*>(Models[eInertial])->GetRefRadius())); // See the eModels enum specification in the header file. The order of the // enums specifies the order of execution. The Models[] vector is the primary // storage array for the list of models. Models[ePropagate] = new FGPropagate(this); Models[eInput] = new FGInput(this); Models[eAtmosphere] = new FGStandardAtmosphere(this); Models[eWinds] = new FGWinds(this); Models[eSystems] = new FGFCS(this); Models[eMassBalance] = new FGMassBalance(this); Models[eAuxiliary] = new FGAuxiliary(this); Models[ePropulsion] = new FGPropulsion(this); Models[eAerodynamics] = new FGAerodynamics (this); Models[eGroundReactions] = new FGGroundReactions(this); Models[eExternalReactions] = new FGExternalReactions(this); Models[eBuoyantForces] = new FGBuoyantForces(this); Models[eAircraft] = new FGAircraft(this); Models[eAccelerations] = new FGAccelerations(this); Models[eOutput] = new FGOutput(this); // Assign the Model shortcuts for internal executive use only. Propagate = (FGPropagate*)Models[ePropagate]; Inertial = (FGInertial*)Models[eInertial]; Atmosphere = (FGAtmosphere*)Models[eAtmosphere]; Winds = (FGWinds*)Models[eWinds]; FCS = (FGFCS*)Models[eSystems]; MassBalance = (FGMassBalance*)Models[eMassBalance]; Auxiliary = (FGAuxiliary*)Models[eAuxiliary]; Propulsion = (FGPropulsion*)Models[ePropulsion]; Aerodynamics = (FGAerodynamics*)Models[eAerodynamics]; GroundReactions = (FGGroundReactions*)Models[eGroundReactions]; ExternalReactions = (FGExternalReactions*)Models[eExternalReactions]; BuoyantForces = (FGBuoyantForces*)Models[eBuoyantForces]; Aircraft = (FGAircraft*)Models[eAircraft]; Accelerations = (FGAccelerations*)Models[eAccelerations]; Output = (FGOutput*)Models[eOutput]; // Initialize planet (environment) constants LoadPlanetConstants(); // Initialize models for (unsigned int i = 0; i < Models.size(); i++) { // The Input/Output models must not be initialized prior to IC loading if (i == eInput || i == eOutput) continue; LoadInputs(i); Models[i]->InitModel(); } IC = new FGInitialCondition(this); IC->bind(instance); modelLoaded = false; return result; }