X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FFDM%2FJSBSim%2FFGFDMExec.cpp;h=b61529229c40c3947ff50ab9792c1792907a8bb8;hb=69baf3a9d6adb645325e7bfc0305b09604379d9f;hp=8d29a688f2eb487acfbfc241018e7d9fab7aee03;hpb=e1d5a52a3a535007d4249aeba84fc645158997a7;p=flightgear.git diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index 8d29a688f..b61529229 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -1,3 +1,4 @@ + /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module: FGFDMExec.cpp @@ -63,14 +64,18 @@ INCLUDES #include "models/FGInput.h" #include "models/FGOutput.h" #include "initialization/FGInitialCondition.h" +#include "initialization/FGSimplexTrim.h" +#include "initialization/FGLinearization.h" #include "input_output/FGPropertyManager.h" #include "input_output/FGScript.h" +#include "input_output/FGXMLFileRead.h" +#include "input_output/FGXMLElement.h" using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.114 2011/09/11 11:36:04 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.150 2013/11/24 11:40:55 bcoconni Exp $"; static const char *IdHdr = ID_FDMEXEC; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,10 +87,9 @@ CLASS IMPLEMENTATION FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root), FDMctr(fdmctr) { - Frame = 0; Error = 0; - GroundCallback = 0; + SetGroundCallback(new FGDefaultGroundCallback()); IC = 0; Trim = 0; Script = 0; @@ -97,7 +101,9 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root) 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 @@ -126,11 +132,12 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root) // 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); + FGPropertyNode* instanceRoot = Root->GetNode("/fdm/jsbsim",IdFDM,true); + instance = new FGPropertyManager(instanceRoot); Debug(0); // this is to catch errors in binding member functions to the property tree. try { @@ -145,14 +152,62 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root) Constructing = true; typedef int (FGFDMExec::*iPMF)(void) const; + typedef double (FGFDMExec::*dPMF)(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/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization); 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/dt", this, &FGFDMExec::GetDeltaT); instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel); instance->Tie("simulation/frame", (int *)&Frame, false); + // simplex trim properties + instanceRoot->SetDouble("trim/solver/rtol",0.0001); + instanceRoot->SetDouble("trim/solver/speed",2); + instanceRoot->SetDouble("trim/solver/abstol",0.001); + instanceRoot->SetDouble("trim/solver/iterMax",2000); + instanceRoot->SetInt("trim/solver/debugLevel",0); + instanceRoot->SetDouble("trim/solver/random",0); + instanceRoot->SetBool("trim/solver/showSimplex",false); + instanceRoot->SetBool("trim/solver/showConvergence",false); + instanceRoot->SetBool("trim/solver/pause",false); + instanceRoot->SetBool("trim/solver/variablePropPitch",false); + + instanceRoot->SetDouble("trim/solver/throttleGuess",0.50); + instanceRoot->SetDouble("trim/solver/throttleMin",0.0); + instanceRoot->SetDouble("trim/solver/throttleMax",1.0); + instanceRoot->SetDouble("trim/solver/throttleStep",0.1); + + instanceRoot->SetDouble("trim/solver/aileronGuess",0); + instanceRoot->SetDouble("trim/solver/aileronMin",-1.00); + instanceRoot->SetDouble("trim/solver/aileronMax",1.00); + instanceRoot->SetDouble("trim/solver/aileronStep",0.1); + + instanceRoot->SetDouble("trim/solver/rudderGuess",0); + instanceRoot->SetDouble("trim/solver/rudderMin",-1.00); + instanceRoot->SetDouble("trim/solver/rudderMax",1.00); + instanceRoot->SetDouble("trim/solver/rudderStep",0.1); + + instanceRoot->SetDouble("trim/solver/elevatorGuess",-0.1); + instanceRoot->SetDouble("trim/solver/elevatorMin",-1.0); + instanceRoot->SetDouble("trim/solver/elevatorMax",1.0); + instanceRoot->SetDouble("trim/solver/elevatorStep",0.1); + + instanceRoot->SetDouble("trim/solver/alphaGuess",0.05); + instanceRoot->SetDouble("trim/solver/alphaMin",-0.1); + instanceRoot->SetDouble("trim/solver/alphaMax",.18); + instanceRoot->SetDouble("trim/solver/alphaStep",0.05); + + instanceRoot->SetDouble("trim/solver/betaGuess",0); + instanceRoot->SetDouble("trim/solver/betaMin",-0.1); + instanceRoot->SetDouble("trim/solver/betaMax",0.1); + instanceRoot->SetDouble("trim/solver/betaStep",0.0001); + Constructing = false; } @@ -163,7 +218,9 @@ FGFDMExec::~FGFDMExec() try { Unbind(); DeAllocate(); - + + delete instance; + if (IdFDM == 0) { // Meaning this is no child FDM if(Root != 0) { if(StandAlone) @@ -209,15 +266,13 @@ bool FGFDMExec::Allocate(void) Models[eSystems] = new FGFCS(this); Models[ePropulsion] = new FGPropulsion(this); Models[eAerodynamics] = new FGAerodynamics (this); - - GroundCallback = new FGGroundCallback(((FGInertial*)Models[eInertial])->GetRefRadius()); - Models[eGroundReactions] = new FGGroundReactions(this); Models[eExternalReactions] = new FGExternalReactions(this); Models[eBuoyantForces] = new FGBuoyantForces(this); Models[eMassBalance] = new FGMassBalance(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]; @@ -234,12 +289,17 @@ bool FGFDMExec::Allocate(void) MassBalance = (FGMassBalance*)Models[eMassBalance]; Aircraft = (FGAircraft*)Models[eAircraft]; Accelerations = (FGAccelerations*)Models[eAccelerations]; + Output = (FGOutput*)Models[eOutput]; // Initialize planet (environment) constants LoadPlanetConstants(); + GetGroundCallback()->SetSeaLevelRadius(Inertial->GetRefRadius()); // Initialize models for (unsigned int i = 0; i < Models.size(); i++) { + // The Output model must not be initialized prior to IC loading + if (i == eOutput) continue; + LoadInputs(i); Models[i]->InitModel(); } @@ -259,15 +319,10 @@ bool FGFDMExec::DeAllocate(void) for (unsigned int i=0; iRun(); } - if (firstPass && !IntegrationSuspended()) { - // Outputs the initial conditions - for (unsigned int i = 0; i < Outputs.size(); i++) - Outputs[i]->Run(holding); - - firstPass = false; - } + IncrTime(); // returns true if success, false if complete if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript(); - IncrTime(); - for (unsigned int i = 0; i < Models.size(); i++) { LoadInputs(i); Models[i]->Run(holding); @@ -369,8 +416,6 @@ void FGFDMExec::LoadInputs(unsigned int idx) Auxiliary->in.RPBody = MassBalance->StructuralToBody(Aircraft->GetXYZrp()); Auxiliary->in.vFw = Aerodynamics->GetvFw(); Auxiliary->in.vLocation = Propagate->GetLocation(); - Auxiliary->in.Latitude = Propagate->GetLatitude(); - Auxiliary->in.Longitude = Propagate->GetLongitude(); Auxiliary->in.CosTht = Propagate->GetCosEuler(eTht); Auxiliary->in.SinTht = Propagate->GetSinEuler(eTht); Auxiliary->in.CosPhi = Propagate->GetCosEuler(ePhi); @@ -411,6 +456,7 @@ void FGFDMExec::LoadInputs(unsigned int idx) Propulsion->in.PropFeather = FCS->GetPropFeather(); Propulsion->in.H_agl = Propagate->GetDistanceAGL(); Propulsion->in.PQR = Propagate->GetPQR(); + break; case eAerodynamics: Aerodynamics->in.Alpha = Auxiliary->Getalpha(); @@ -441,9 +487,7 @@ void FGFDMExec::LoadInputs(unsigned int idx) GroundReactions->in.TotalDeltaT = dT * GroundReactions->GetRate(); GroundReactions->in.WOW = GroundReactions->GetWOW(); GroundReactions->in.Location = Propagate->GetLocation(); - for (int i=0; iGetNumGearUnits(); i++) { - GroundReactions->in.vWhlBodyVec[i] = MassBalance->StructuralToBody(GroundReactions->GetGearUnit(i)->GetLocation()); - } + GroundReactions->in.vXYZcg = MassBalance->GetXYZcg(); break; case eExternalReactions: // There are no external inputs to this model. @@ -473,8 +517,6 @@ void FGFDMExec::LoadInputs(unsigned int idx) Aircraft->in.GroundMoment = GroundReactions->GetMoments(); Aircraft->in.ExternalMoment = ExternalReactions->GetMoments(); Aircraft->in.BuoyantMoment = BuoyantForces->GetMoments(); - Aircraft->in.Weight = MassBalance->GetWeight(); - Aircraft->in.Tl2b = Propagate->GetTl2b(); break; case eAccelerations: Accelerations->in.J = MassBalance->GetJ(); @@ -482,7 +524,7 @@ void FGFDMExec::LoadInputs(unsigned int idx) Accelerations->in.Ti2b = Propagate->GetTi2b(); Accelerations->in.Tb2i = Propagate->GetTb2i(); Accelerations->in.Tec2b = Propagate->GetTec2b(); - Accelerations->in.Tl2b = Propagate->GetTl2b(); + Accelerations->in.Tec2i = Propagate->GetTec2i(); Accelerations->in.qAttitudeECI = Propagate->GetQuaternionECI(); Accelerations->in.Moment = Aircraft->GetMoments(); Accelerations->in.GroundMoment = GroundReactions->GetMoments(); @@ -511,7 +553,6 @@ void FGFDMExec::LoadPlanetConstants(void) { Propagate->in.vOmegaPlanet = Inertial->GetOmegaPlanet(); Accelerations->in.vOmegaPlanet = Inertial->GetOmegaPlanet(); - Propagate->in.RefRadius = Inertial->GetRefRadius(); Propagate->in.SemiMajor = Inertial->GetSemimajor(); Propagate->in.SemiMinor = Inertial->GetSemiminor(); Auxiliary->in.SLGravity = Inertial->SLgravity(); @@ -530,9 +571,7 @@ void FGFDMExec::LoadModelConstants(void) Aerodynamics->in.Wingspan = Aircraft->GetWingSpan(); Auxiliary->in.Wingspan = Aircraft->GetWingSpan(); Auxiliary->in.Wingchord = Aircraft->Getcbar(); - for (int i=0; iGetNumGearUnits(); i++) { - GroundReactions->in.vWhlBodyVec[i] = MassBalance->StructuralToBody(GroundReactions->GetGearUnit(i)->GetLocation()); - } + GroundReactions->in.vXYZcg = MassBalance->GetXYZcg(); LoadPlanetConstants(); } @@ -542,11 +581,18 @@ void FGFDMExec::LoadModelConstants(void) bool FGFDMExec::RunIC(void) { + FGPropulsion* propulsion = (FGPropulsion*)Models[ePropulsion]; + + Models[eOutput]->InitModel(); + SuspendIntegration(); // saves the integration rate, dt, then sets it to 0.0. Initialize(IC); Run(); ResumeIntegration(); // Restores the integration rate to what it was. + for (unsigned int i=0; iGetNumEnginesRunning(); i++) + propulsion->InitRunning(IC->GetEngineRunning(i)); + return true; } @@ -563,9 +609,7 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC) Propagate->InitializeDerivatives(); LoadInputs(eAtmosphere); Atmosphere->Run(false); - Winds->SetWindNED( FGIC->GetWindNFpsIC(), - FGIC->GetWindEFpsIC(), - FGIC->GetWindDFpsIC() ); + Winds->SetWindNED(FGIC->GetWindNEDFpsIC()); Auxiliary->Run(false); } @@ -576,12 +620,8 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC) void FGFDMExec::ResetToInitialConditions(int mode) { - if (mode == 1) { - for (unsigned int i=0; iSetStartNewFile(true); - } - } - + if (mode == 1) Output->SetStartNewOutput(); + ResetToInitialConditions(); } @@ -591,36 +631,17 @@ void FGFDMExec::ResetToInitialConditions(void) { if (Constructing) return; - vector ::iterator it; - for (it = Models.begin(); it != Models.end(); ++it) (*it)->InitModel(); - - RunIC(); - if (Script) Script->ResetEvents(); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -bool FGFDMExec::SetOutputFileName(const string& fname) -{ - if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname); - else return false; - return true; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + for (unsigned int i = 0; i < Models.size(); i++) { + // The Output model will be initialized during the RunIC() execution + if (i == eOutput) continue; -string FGFDMExec::GetOutputFileName(void) -{ - if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName(); - else return string(""); -} + LoadInputs(i); + Models[i]->InitModel(); + } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + RunIC(); -void FGFDMExec::SetGroundCallback(FGGroundCallback* p) -{ - delete GroundCallback; - GroundCallback = p; + if (Script) Script->ResetEvents(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -641,12 +662,12 @@ vector FGFDMExec::EnumerateFDMs(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGFDMExec::LoadScript(const string& script, double deltaT) +bool FGFDMExec::LoadScript(const string& script, double deltaT, const string initfile) { bool result; Script = new FGScript(this); - result = Script->LoadScript(RootDir + script, deltaT); + result = Script->LoadScript(RootDir + script, deltaT, initfile); return result; } @@ -690,8 +711,9 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) } int saved_debug_lvl = debug_lvl; + FGXMLFileRead XMLFileRead; + Element *document = XMLFileRead.LoadXMLDocument(aircraftCfgFileName); // "document" is a class member - document = LoadXMLDocument(aircraftCfgFileName); // "document" is a class member if (document) { if (IsChild) debug_lvl = 0; @@ -837,25 +859,20 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) } // Process the output element[s]. This element is OPTIONAL, and there may be more than one. - unsigned int idx=0; - typedef double (FGOutput::*iOPMF)(void) const; - typedef int (FGFDMExec::*iOPV)(void) const; element = document->FindElement("output"); while (element) { - if (debug_lvl > 0) cout << endl << " Output data set: " << idx << " "; - FGOutput* Output = new FGOutput(this); - Output->InitModel(); - Schedule(Output); - result = Output->Load(element); + string output_file_name = aircraftCfgFileName; + + if (!element->GetAttributeValue("file").empty()) { + output_file_name = RootDir + element->GetAttributeValue("file"); + result = ((FGOutput*)Models[eOutput])->SetDirectivesFile(output_file_name); + } + else + result = ((FGOutput*)Models[eOutput])->Load(element); + if (!result) { - cerr << endl << "Aircraft output element has problems in file " << aircraftCfgFileName << endl; + cerr << endl << "Aircraft output element has problems in file " << output_file_name << endl; return result; - } else { - Outputs.push_back(Output); - string outputProp = CreateIndexedPropertyName("simulation/output",idx); - instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false); - instance->Tie("simulation/force-output", this, (iOPV)0, &FGFDMExec::ForceOutput, false); - idx++; } element = document->FindNextElement("output"); } @@ -879,6 +896,10 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) if (debug_lvl > 0) { LoadInputs(eMassBalance); // Update all input mass properties for the report. Models[eMassBalance]->Run(false); // Update all mass properties for the report. + LoadInputs(ePropulsion); // Update propulsion properties for the report. + Models[ePropulsion]->Run(false); // Update propulsion properties for the report. + LoadInputs(eMassBalance); // Update all (one more time) input mass properties for the report. + Models[eMassBalance]->Run(false); // Update all (one more time) mass properties for the report. ((FGMassBalance*)Models[eMassBalance])->GetMassPropertiesReport(); cout << endl << fgblue << highint @@ -886,7 +907,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) << "-------------------------------------------------------------------------------" << reset << endl; } - + if (IsChild) debug_lvl = saved_debug_lvl; } else { @@ -900,7 +921,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) if (result) { struct PropertyCatalogStructure masterPCS; masterPCS.base_string = ""; - masterPCS.node = (FGPropertyManager*)Root; + masterPCS.node = Root->GetNode(); BuildPropertyCatalog(&masterPCS); } @@ -922,18 +943,21 @@ void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs) int node_idx = 0; for (int i=0; inode->nChildren(); i++) { + string access=""; pcsNew->base_string = pcs->base_string + "/" + pcs->node->getChild(i)->getName(); node_idx = pcs->node->getChild(i)->getIndex(); if (node_idx != 0) { pcsNew->base_string = CreateIndexedPropertyName(pcsNew->base_string, node_idx); } if (pcs->node->getChild(i)->nChildren() == 0) { - if (pcsNew->base_string.substr(0,11) == string("/fdm/jsbsim")) { + if (pcsNew->base_string.substr(0,12) == string("/fdm/jsbsim/")) { pcsNew->base_string = pcsNew->base_string.erase(0,12); } - PropertyCatalog.push_back(pcsNew->base_string); + if (pcs->node->getChild(i)->getAttribute(SGPropertyNode::READ)) access="R"; + if (pcs->node->getChild(i)->getAttribute(SGPropertyNode::WRITE)) access+="W"; + PropertyCatalog.push_back(pcsNew->base_string+" ("+access+")"); } else { - pcsNew->node = (FGPropertyManager*)pcs->node->getChild(i); + pcsNew->node = (FGPropertyNode*)pcs->node->getChild(i); BuildPropertyCatalog(pcsNew); } } @@ -1085,7 +1109,7 @@ bool FGFDMExec::ReadChild(Element* el) cerr << endl << highint << fgred << " No location was found for this child object!" << reset << endl; exit(-1); } - + Element* orientation = el->FindElement("orient"); if (orientation) { child->Orient = orientation->FindElementTripletConvertTo("RAD"); @@ -1116,49 +1140,26 @@ FGTrim* FGFDMExec::GetTrim(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGFDMExec::DisableOutput(void) -{ - for (unsigned i=0; iDisable(); - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFDMExec::EnableOutput(void) +void FGFDMExec::CheckIncrementalHold(void) { - for (unsigned i=0; iEnable(); - } -} + // Only check if increment then hold is on + if( IncrementThenHolding ) { -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFDMExec::ForceOutput(int idx) -{ - if (idx >= (int)0 && idx < (int)Outputs.size()) Outputs[idx]->Print(); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if (TimeStepsUntilHold == 0) { -bool FGFDMExec::SetOutputDirectives(const string& fname) -{ - bool result; + // Should hold simulation if TimeStepsUntilHold has reached zero + holding = true; - FGOutput* Output = new FGOutput(this); - Output->SetDirectivesFile(RootDir + fname); - Output->InitModel(); - Schedule(Output); - result = Output->Load(0); + // Still need to decrement TimeStepsUntilHold as value of -1 + // indicates that incremental then hold is turned off + IncrementThenHolding = false; + TimeStepsUntilHold--; - if (result) { - Outputs.push_back(Output); - typedef double (FGOutput::*iOPMF)(void) const; - string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1); - instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false); + } else if ( TimeStepsUntilHold > 0 ) { + // Keep decrementing until 0 is reached + TimeStepsUntilHold--; + } } - - return result; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1180,6 +1181,42 @@ void FGFDMExec::DoTrim(int mode) sim_time = saved_time; } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFDMExec::DoSimplexTrim(int mode) +{ + double saved_time; + if (Constructing) return; + if (mode < 0 || mode > JSBSim::tNone) { + cerr << endl << "Illegal trimming mode!" << endl << endl; + return; + } + saved_time = sim_time; + FGSimplexTrim trim(this, (JSBSim::TrimMode)mode); + sim_time = saved_time; + Setsim_time(saved_time); + std::cout << "dT: " << dT << std::endl; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFDMExec::DoLinearization(int mode) +{ + double saved_time; + if (Constructing) return; + saved_time = sim_time; + FGLinearization lin(this,mode); + sim_time = saved_time; + Setsim_time(saved_time); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFDMExec::SRand(int sr) +{ + srand(sr); +} + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // The bitmasked value choices are as follows: // unset: In this case (the default) JSBSim would only print @@ -1205,7 +1242,7 @@ void FGFDMExec::Debug(int from) if (debug_lvl & 1 && IdFDM == 0) { // Standard console startup message output if (from == 0) { // Constructor - cout << "\n\n " + cout << "\n\n " << "JSBSim Flight Dynamics Model v" << JSBSim_version << endl; cout << " [JSBSim-ML v" << needed_cfg_version << "]\n\n"; cout << "JSBSim startup beginning ...\n\n";