48#include "models/atmosphere/FGStandardAtmosphere.h"
49#include "models/atmosphere/FGMSIS.h"
50#include "models/atmosphere/FGWinds.h"
51#include "models/FGFCS.h"
52#include "models/FGPropulsion.h"
53#include "models/FGMassBalance.h"
54#include "models/FGExternalReactions.h"
55#include "models/FGBuoyantForces.h"
56#include "models/FGAerodynamics.h"
57#include "models/FGInertial.h"
58#include "models/FGAircraft.h"
59#include "models/FGAccelerations.h"
60#include "models/FGAuxiliary.h"
61#include "models/FGInput.h"
62#include "initialization/FGTrim.h"
63#include "initialization/FGLinearization.h"
64#include "input_output/FGScript.h"
65#include "input_output/FGXMLFileRead.h"
66#include "initialization/FGInitialCondition.h"
67#include "input_output/FGLog.h"
95 IncrementThenHolding =
false;
96 TimeStepsUntilHold = -1;
102 AircraftPath =
"aircraft";
103 EnginePath =
"engine";
104 SystemsPath =
"systems";
106 if (
const char* num = getenv(
"JSBSIM_DEBUG"); num !=
nullptr)
107 debug_lvl = strtol(num,
nullptr, 0);
110 FDMctr = std::make_shared<unsigned int>();
123 Root = root->GetNode();
125 SGPropertyNode* instanceRoot = Root->getNode(
"fdm/jsbsim", IdFDM,
true);
126 instance = std::make_shared<FGPropertyManager>(instanceRoot);
128 if (
const char* num = getenv(
"JSBSIM_DISPERSE");
129 num !=
nullptr && strtol(num,
nullptr, 0) != 0)
140 err << endl <<
"Caught error: " << e.what() << endl;
152 instance->Tie(
"simulation/disperse",
this, &FGFDMExec::GetDisperse);
153 instance->Tie(
"simulation/randomseed",
this, &FGFDMExec::SRand, &FGFDMExec::SRand);
154 instance->Tie(
"simulation/terminate", &Terminate);
155 instance->Tie(
"simulation/pause", &holding);
159 instance->Tie(
"simulation/frame",
reinterpret_cast<int*
>(&Frame));
160 instance->Tie(
"simulation/trim-completed", &trim_completed);
163 Constructing =
false;
173 }
catch (
const string& msg ) {
175 log <<
"Caught error: " << msg << endl;
178 if (!FDMctr) (*FDMctr)--;
204bool FGFDMExec::Allocate(
void)
208 Models.resize(eNumStandardModels);
214 Models[eInertial] = std::make_shared<FGInertial>(
this);
219 Models[ePropagate] = std::make_shared<FGPropagate>(
this);
220 Models[eInput] = std::make_shared<FGInput>(
this);
221 Models[eAtmosphere] = std::make_shared<FGStandardAtmosphere>(
this);
222 Models[eWinds] = std::make_shared<FGWinds>(
this);
223 Models[eSystems] = std::make_shared<FGFCS>(
this);
224 Models[eMassBalance] = std::make_shared<FGMassBalance>(
this);
225 Models[eAuxiliary] = std::make_shared<FGAuxiliary>(
this);
226 Models[ePropulsion] = std::make_shared<FGPropulsion>(
this);
227 Models[eAerodynamics] = std::make_shared<FGAerodynamics> (
this);
228 Models[eGroundReactions] = std::make_shared<FGGroundReactions>(
this);
229 Models[eExternalReactions] = std::make_shared<FGExternalReactions>(
this);
230 Models[eBuoyantForces] = std::make_shared<FGBuoyantForces>(
this);
231 Models[eAircraft] = std::make_shared<FGAircraft>(
this);
232 Models[eAccelerations] = std::make_shared<FGAccelerations>(
this);
233 Models[eOutput] = std::make_shared<FGOutput>(
this);
236 Propagate =
static_cast<FGPropagate*
>(Models[ePropagate].get());
237 Inertial =
static_cast<FGInertial*
>(Models[eInertial].get());
238 Input =
static_cast<FGInput*
>(Models[eInput].get());
239 Atmosphere =
static_cast<FGAtmosphere*
>(Models[eAtmosphere].get());
240 Winds =
static_cast<FGWinds*
>(Models[eWinds].get());
241 FCS =
static_cast<FGFCS*
>(Models[eSystems].get());
242 MassBalance =
static_cast<FGMassBalance*
>(Models[eMassBalance].get());
243 Auxiliary =
static_cast<FGAuxiliary*
>(Models[eAuxiliary].get());
244 Propulsion =
static_cast<FGPropulsion*
>(Models[ePropulsion].get());
245 Aerodynamics =
static_cast<FGAerodynamics*
>(Models[eAerodynamics].get());
246 GroundReactions =
static_cast<FGGroundReactions*
>(Models[eGroundReactions].get());
248 BuoyantForces =
static_cast<FGBuoyantForces*
>(Models[eBuoyantForces].get());
249 Aircraft =
static_cast<FGAircraft*
>(Models[eAircraft].get());
250 Accelerations =
static_cast<FGAccelerations*
>(Models[eAccelerations].get());
251 Output =
static_cast<FGOutput*
>(Models[eOutput].get());
254 LoadPlanetConstants();
259 IC = std::make_shared<FGInitialCondition>(
this);
260 IC->bind(instance.get());
271 return static_pointer_cast<FGPropagate>(Models[ePropagate]);
278 return static_pointer_cast<FGInertial>(Models[eInertial]);
285 return static_pointer_cast<FGInput>(Models[eInput]);
290std::shared_ptr<FGAtmosphere> FGFDMExec::GetAtmosphere(
void)
const
292 return static_pointer_cast<FGAtmosphere>(Models[eAtmosphere]);
299 return static_pointer_cast<FGWinds>(Models[eWinds]);
306 return static_pointer_cast<FGFCS>(Models[eSystems]);
313 return static_pointer_cast<FGMassBalance>(Models[eMassBalance]);
320 return static_pointer_cast<FGAuxiliary>(Models[eAuxiliary]);
327 return static_pointer_cast<FGPropulsion>(Models[ePropulsion]);
334 return static_pointer_cast<FGAerodynamics>(Models[eAerodynamics]);
341 return static_pointer_cast<FGGroundReactions>(Models[eGroundReactions]);
348 return static_pointer_cast<FGExternalReactions>(Models[eExternalReactions]);
355 return static_pointer_cast<FGBuoyantForces>(Models[eBuoyantForces]);
362 return static_pointer_cast<FGAircraft>(Models[eAircraft]);
369 return static_pointer_cast<FGAccelerations>(Models[eAccelerations]);
376 return static_pointer_cast<FGOutput>(Models[eOutput]);
381void FGFDMExec::InitializeModels(
void)
383 for (
unsigned int i = 0; i < Models.size(); i++) {
385 if (i == eInput || i == eOutput)
continue;
388 Models[i]->InitModel();
394bool FGFDMExec::DeAllocate(
void)
410 for (
auto &ChildFDM: ChildFDMList) {
411 ChildFDM->AssignState(Propagate);
420 for (
unsigned int i = 0; i < Models.size(); i++) {
422 Models[i]->Run(holding);
425 if (Terminate) success =
false;
432void FGFDMExec::LoadInputs(
unsigned int idx)
436 Propagate->in.vPQRidot = Accelerations->
GetPQRidot();
437 Propagate->in.vUVWidot = Accelerations->
GetUVWidot();
438 Propagate->in.DeltaT = dT;
443 Inertial->in.Position = Propagate->GetLocation();
447 Atmosphere->in.GeodLatitudeDeg = Propagate->GetGeodLatitudeDeg();
448 Atmosphere->in.LongitudeDeg = Propagate->GetLongitudeDeg();
452 Winds->in.DistanceAGL = Propagate->GetDistanceAGL();
453 Winds->in.Tl2b = Propagate->
GetTl2b();
454 Winds->in.Tw2b = Auxiliary->
GetTw2b();
455 Winds->in.V = Auxiliary->
GetVt();
456 Winds->in.totalDeltaT = dT * Winds->
GetRate();
459 Auxiliary->in.Pressure = Atmosphere->
GetPressure();
460 Auxiliary->in.Density = Atmosphere->
GetDensity();
464 Auxiliary->in.DistanceAGL = Propagate->GetDistanceAGL();
465 Auxiliary->in.Mass = MassBalance->GetMass();
466 Auxiliary->in.Tl2b = Propagate->
GetTl2b();
467 Auxiliary->in.Tb2l = Propagate->
GetTb2l();
468 Auxiliary->in.vPQR = Propagate->
GetPQR();
469 Auxiliary->in.vPQRi = Propagate->
GetPQRi();
470 Auxiliary->in.vPQRidot = Accelerations->
GetPQRidot();
471 Auxiliary->in.vUVW = Propagate->
GetUVW();
472 Auxiliary->in.vUVWdot = Accelerations->
GetUVWdot();
473 Auxiliary->in.vVel = Propagate->
GetVel();
474 Auxiliary->in.vBodyAccel = Accelerations->
GetBodyAccel();
475 Auxiliary->in.ToEyePt = MassBalance->
StructuralToBody(Aircraft->GetXYZep());
476 Auxiliary->in.VRPBody = MassBalance->
StructuralToBody(Aircraft->GetXYZvrp());
478 Auxiliary->in.vFw = Aerodynamics->
GetvFw();
479 Auxiliary->in.vLocation = Propagate->GetLocation();
480 Auxiliary->in.CosTht = Propagate->
GetCosEuler(eTht);
481 Auxiliary->in.SinTht = Propagate->
GetSinEuler(eTht);
482 Auxiliary->in.CosPhi = Propagate->
GetCosEuler(ePhi);
483 Auxiliary->in.SinPhi = Propagate->
GetSinEuler(ePhi);
485 Auxiliary->in.TurbPQR = Winds->GetTurbPQR();
491 Propulsion->in.Pressure = Atmosphere->
GetPressure();
495 Propulsion->in.Density = Atmosphere->
GetDensity();
499 Propulsion->in.Vt = Auxiliary->
GetVt();
500 Propulsion->in.qbar = Auxiliary->Getqbar();
501 Propulsion->in.TAT_c = Auxiliary->GetTAT_C();
502 Propulsion->in.AeroUVW = Auxiliary->GetAeroUVW();
503 Propulsion->in.AeroPQR = Auxiliary->GetAeroPQR();
504 Propulsion->in.alpha = Auxiliary->Getalpha();
505 Propulsion->in.beta = Auxiliary->Getbeta();
506 Propulsion->in.TotalDeltaT = dT * Propulsion->
GetRate();
513 Propulsion->in.H_agl = Propagate->GetDistanceAGL();
514 Propulsion->in.PQRi = Propagate->
GetPQRi();
518 Aerodynamics->in.Alpha = Auxiliary->Getalpha();
519 Aerodynamics->in.Beta = Auxiliary->Getbeta();
520 Aerodynamics->in.Qbar = Auxiliary->Getqbar();
521 Aerodynamics->in.Vt = Auxiliary->
GetVt();
522 Aerodynamics->in.Tb2w = Auxiliary->
GetTb2w();
523 Aerodynamics->in.Tw2b = Auxiliary->
GetTw2b();
526 case eGroundReactions:
528 GroundReactions->in.Vground = Auxiliary->
GetVground();
532 GroundReactions->in.BrakePos = FCS->GetBrakePos();
533 GroundReactions->in.FCSGearPos = FCS->
GetGearPos();
534 GroundReactions->in.EmptyWeight = MassBalance->GetEmptyWeight();
535 GroundReactions->in.Tb2l = Propagate->
GetTb2l();
536 GroundReactions->in.Tec2l = Propagate->
GetTec2l();
537 GroundReactions->in.Tec2b = Propagate->
GetTec2b();
538 GroundReactions->in.PQR = Propagate->
GetPQR();
539 GroundReactions->in.UVW = Propagate->
GetUVW();
540 GroundReactions->in.DistanceAGL = Propagate->GetDistanceAGL();
542 GroundReactions->in.TotalDeltaT = dT * GroundReactions->
GetRate();
543 GroundReactions->in.WOW = GroundReactions->GetWOW();
544 GroundReactions->in.Location = Propagate->GetLocation();
545 GroundReactions->in.vXYZcg = MassBalance->
GetXYZcg();
547 case eExternalReactions:
551 BuoyantForces->in.Density = Atmosphere->
GetDensity();
552 BuoyantForces->in.Pressure = Atmosphere->
GetPressure();
554 BuoyantForces->in.gravity = Inertial->GetGravity().
Magnitude();
558 MassBalance->in.GasMass = BuoyantForces->
GetGasMass();
560 MassBalance->in.TanksWeight = Propulsion->GetTanksWeight();
561 MassBalance->in.TanksMoment = Propulsion->GetTanksMoment();
562 MassBalance->in.TankInertia = Propulsion->CalculateTankInertias();
563 MassBalance->in.WOW = GroundReactions->GetWOW();
566 Aircraft->in.AeroForce = Aerodynamics->
GetForces();
567 Aircraft->in.PropForce = Propulsion->GetForces();
568 Aircraft->in.GroundForce = GroundReactions->GetForces();
569 Aircraft->in.ExternalForce = ExternalReactions->
GetForces();
570 Aircraft->in.BuoyantForce = BuoyantForces->
GetForces();
571 Aircraft->in.AeroMoment = Aerodynamics->
GetMoments();
572 Aircraft->in.PropMoment = Propulsion->GetMoments();
573 Aircraft->in.GroundMoment = GroundReactions->GetMoments();
574 Aircraft->in.ExternalMoment = ExternalReactions->
GetMoments();
575 Aircraft->in.BuoyantMoment = BuoyantForces->
GetMoments();
578 Accelerations->in.
J = MassBalance->
GetJ();
584 Accelerations->in.
Moment = Aircraft->GetMoments();
585 Accelerations->in.
GroundMoment = GroundReactions->GetMoments();
586 Accelerations->in.
Force = Aircraft->GetForces();
587 Accelerations->in.
GroundForce = GroundReactions->GetForces();
588 Accelerations->in.
vGravAccel = Inertial->GetGravity();
593 Accelerations->in.
DeltaT = dT;
594 Accelerations->in.
Mass = MassBalance->GetMass();
595 Accelerations->in.
MultipliersList = GroundReactions->GetMultipliersList();
606void FGFDMExec::LoadPlanetConstants(
void)
608 Propagate->in.vOmegaPlanet = Inertial->GetOmegaPlanet();
609 Accelerations->in.
vOmegaPlanet = Inertial->GetOmegaPlanet();
610 Propagate->in.SemiMajor = Inertial->GetSemimajor();
611 Propagate->in.SemiMinor = Inertial->GetSemiminor();
612 Propagate->in.GM = Inertial->GetGM();
613 Auxiliary->in.StandardGravity = Inertial->GetStandardGravity();
614 Auxiliary->in.StdDaySLsoundspeed = Atmosphere->StdDaySLsoundspeed;
619void FGFDMExec::LoadModelConstants(
void)
622 Aerodynamics->in.Wingarea = Aircraft->
GetWingArea();
623 Aerodynamics->in.Wingchord = Aircraft->
Getcbar();
624 Aerodynamics->in.Wingincidence = Aircraft->GetWingIncidence();
625 Aerodynamics->in.Wingspan = Aircraft->
GetWingSpan();
627 Auxiliary->in.Wingchord = Aircraft->
Getcbar();
628 GroundReactions->in.vXYZcg = MassBalance->
GetXYZcg();
639 Models[eInput]->InitModel();
640 Models[eOutput]->InitModel();
643 Propagate->InitializeDerivatives();
647 MassBalance->GetMassPropertiesReport(0);
650 log << endl << LogFormat::BLUE << LogFormat::BOLD
651 <<
"End of vehicle configuration loading." << endl
652 <<
"-------------------------------------------------------------------------------"
653 << LogFormat::RESET << std::setprecision(6) << endl;
656 for (
unsigned int n=0; n < Propulsion->
GetNumEngines(); ++n) {
657 if (IC->IsEngineRunning(n)) {
660 }
catch (
const string& str) {
675 Propagate->SetInitialState(FGIC);
677 Auxiliary->SetInitialState(FGIC);
685 if (Constructing)
return;
694 Script->ResetEvents();
698 if (!(mode & DONT_EXECUTE_RUN_IC))
709 Propagate->in.vPQRidot = Accelerations->
GetPQRidot();
710 Propagate->in.vUVWidot = Accelerations->
GetUVWidot();
719 vector <string> FDMList;
722 for (
auto &ChildFDM: ChildFDMList)
723 FDMList.push_back(ChildFDM->exec->GetAircraft()->GetAircraftName());
731 const SGPath& initfile)
733 Script = std::make_shared<FGScript>(
this);
734 return Script->LoadScript(GetFullPath(script), deltaT, initfile);
741 SGPath PlanetFileName;
743 if(useAircraftPath && PlanetPath.isRelative()) {
744 PlanetFileName = AircraftPath/PlanetPath.utf8Str();
746 PlanetFileName = PlanetPath;
750 Element* document = XMLFileRead.LoadXMLDocument(PlanetFileName);
755 err <<
"File: " << PlanetFileName <<
" could not be read." << endl;
759 if (document->
GetName() !=
"planet") {
761 err <<
"File: " << PlanetFileName <<
" is not a planet file." << endl;
769 log << endl <<
"Planet element has problems in file " << PlanetFileName << endl;
779 bool result = Models[eInertial]->Load(element);
783 LoadPlanetConstants();
789 if (atm_element && atm_element->
HasAttribute(
"model")) {
791 if (model ==
"MSIS") {
793 instance->Unbind(Models[eAtmosphere]);
794 Models[eAtmosphere] = std::make_shared<FGMSIS>(
this);
795 Atmosphere =
static_cast<FGAtmosphere*
>(Models[eAtmosphere].get());
798 LoadInputs(eAtmosphere);
799 Atmosphere->InitModel();
800 result = Atmosphere->Load(atm_element);
803 log << endl <<
"Incorrect definition of <atmosphere>." << endl;
817 const SGPath& SystemsPath,
const string& model,
820 FGFDMExec::AircraftPath = GetFullPath(AircraftPath);
821 FGFDMExec::EnginePath = GetFullPath(EnginePath);
822 FGFDMExec::SystemsPath = GetFullPath(SystemsPath);
831 SGPath aircraftCfgFileName;
836 if( AircraftPath.isNull() || EnginePath.isNull() || SystemsPath.isNull()) {
838 log <<
"Error: attempted to load aircraft with undefined "
839 <<
"aircraft, engine, and system paths" << endl;
843 FullAircraftPath = AircraftPath;
844 if (addModelToPath) FullAircraftPath.append(model);
845 aircraftCfgFileName = FullAircraftPath/(model +
".xml");
852 int saved_debug_lvl = debug_lvl;
854 Element *document = XMLFileRead.LoadXMLDocument(aircraftCfgFileName);
857 if (IsChild) debug_lvl = 0;
859 ReadPrologue(document);
861 if (IsChild) debug_lvl = saved_debug_lvl;
866 result = ReadFileHeader(element);
869 log << endl <<
"Aircraft fileheader element has problems in file " << aircraftCfgFileName << endl;
874 if (IsChild) debug_lvl = 0;
882 log << endl <<
"Planet element has problems in file " << aircraftCfgFileName << endl;
890 result = Models[eAircraft]->Load(element);
893 log << endl <<
"Aircraft metrics element has problems in file " << aircraftCfgFileName << endl;
898 log << endl <<
"No metrics element was found in the aircraft config file." << endl;
905 result = Models[eMassBalance]->Load(element);
908 log << endl <<
"Aircraft mass_balance element has problems in file " << aircraftCfgFileName << endl;
913 log << endl <<
"No mass_balance element was found in the aircraft config file." << endl;
918 element = document->
FindElement(
"ground_reactions");
920 result = Models[eGroundReactions]->Load(element);
924 <<
"Aircraft ground_reactions element has problems in file "
925 << aircraftCfgFileName << endl;
930 log << endl <<
"No ground_reactions element was found in the aircraft config file." << endl;
935 element = document->
FindElement(
"external_reactions");
937 result = Models[eExternalReactions]->Load(element);
940 log << endl <<
"Aircraft external_reactions element has problems in file " << aircraftCfgFileName << endl;
948 result = Models[eBuoyantForces]->Load(element);
951 log << endl <<
"Aircraft buoyant_forces element has problems in file " << aircraftCfgFileName << endl;
959 result = Propulsion->
Load(element);
962 log << endl <<
"Aircraft propulsion element has problems in file " << aircraftCfgFileName << endl;
972 result = Models[eSystems]->Load(element);
975 log << endl <<
"Aircraft system element has problems in file " << aircraftCfgFileName << endl;
984 result = Models[eSystems]->Load(element);
987 log << endl <<
"Aircraft autopilot element has problems in file " << aircraftCfgFileName << endl;
995 result = Models[eSystems]->Load(element);
998 log << endl <<
"Aircraft flight_control element has problems in file " << aircraftCfgFileName << endl;
1006 result = Models[eAerodynamics]->Load(element);
1009 log << endl <<
"Aircraft aerodynamics element has problems in file " << aircraftCfgFileName << endl;
1014 log << endl <<
"No expected aerodynamics element was found in the aircraft config file." << endl;
1020 if (!Input->
Load(element))
1030 if (!Output->
Load(element))
1039 result = ReadChild(element);
1042 log << endl <<
"Aircraft child element has problems in file " << aircraftCfgFileName << endl;
1049 LoadModelConstants();
1053 if (IsChild) debug_lvl = saved_debug_lvl;
1057 log << LogFormat::RED
1058 <<
" JSBSim failed to open the configuration file: " << aircraftCfgFileName
1059 << LogFormat::DEFAULT << endl;
1062 for (
unsigned int i=0; i< Models.size(); i++) LoadInputs(i);
1067 masterPCS.
node = Root;
1076string FGFDMExec::GetPropulsionTankReport()
const
1078 return Propulsion->GetPropulsionTankReport();
1085 auto pcsNew = std::make_unique<struct PropertyCatalogStructure>();
1087 const string root_name = GetFullyQualifiedName(root_node) +
"/";
1088 const size_t root_name_length = root_name.length();
1090 for (
int i=0; i<pcs->
node->nChildren(); i++) {
1092 pcsNew->base_string = pcs->
base_string +
"/" + pcs->
node->getChild(i)->getNameString();
1093 int node_idx = pcs->
node->getChild(i)->getIndex();
1094 if (node_idx != 0) {
1095 pcsNew->base_string = CreateIndexedPropertyName(pcsNew->base_string, node_idx);
1097 if (pcs->
node->getChild(i)->nChildren() == 0) {
1098 if (pcsNew->base_string.substr(0, root_name_length) == root_name) {
1099 pcsNew->base_string = pcsNew->base_string.erase(0, root_name_length);
1101 if (pcs->
node->getChild(i)->getAttribute(SGPropertyNode::READ)) access=
"R";
1102 if (pcs->
node->getChild(i)->getAttribute(SGPropertyNode::WRITE)) access+=
"W";
1103 PropertyCatalog.push_back(pcsNew->base_string+
" ("+access+
")");
1105 pcsNew->node = pcs->
node->getChild(i);
1116 for (
auto &catalogElm: PropertyCatalog) {
1117 if (catalogElm.find(in) != string::npos) results += catalogElm + end_of_line;
1119 if (results.empty())
return "No matches found"+end_of_line;
1125void FGFDMExec::PrintPropertyCatalog(
void)
1129 <<
" " << LogFormat::BLUE <<
highint << LogFormat::UNDERLINE_ON
1130 <<
"Property Catalog for " << modelName << LogFormat::RESET << endl << endl;
1131 for (
auto &catalogElm: PropertyCatalog)
1132 out <<
" " << catalogElm << endl;
1137void FGFDMExec::PrintSimulationConfiguration(
void)
const
1139 FGLogging log(LogLevel::INFO);
1140 log << endl <<
"Simulation Configuration" << endl <<
"------------------------" << endl;
1141 log << MassBalance->GetName() << endl;
1142 log << GroundReactions->GetName() << endl;
1143 log << Aerodynamics->GetName() << endl;
1144 log << Propulsion->GetName() << endl;
1149bool FGFDMExec::ReadFileHeader(Element* el)
1151 if (debug_lvl == 0)
return true;
1153 FGLogging log(LogLevel::DEBUG);
1156 log << endl << LogFormat::BOLD << LogFormat::BLUE <<
"Reading child model: "
1157 << IdFDM << LogFormat::RESET << endl << endl;
1160 if (el->FindElement(
"description"))
1161 log <<
" Description: " << el->FindElement(
"description")->GetDataLine() << endl;
1162 if (el->FindElement(
"author"))
1163 log <<
" Model Author: " << el->FindElement(
"author")->GetDataLine() << endl;
1164 if (el->FindElement(
"filecreationdate"))
1165 log <<
" Creation Date: " << el->FindElement(
"filecreationdate")->GetDataLine() << endl;
1166 if (el->FindElement(
"version"))
1167 log <<
" Version: " << el->FindElement(
"version")->GetDataLine() << endl;
1174bool FGFDMExec::ReadPrologue(Element* el)
1178 if (!el)
return false;
1180 string AircraftName = el->GetAttributeValue(
"name");
1181 Aircraft->SetAircraftName(AircraftName);
1183 if (debug_lvl & 1) {
1184 FGLogging log(LogLevel::INFO);
1185 log << LogFormat::UNDERLINE_ON <<
"Reading Aircraft Configuration File"
1186 << LogFormat::UNDERLINE_OFF <<
": " << LogFormat::BOLD << AircraftName
1187 << LogFormat::NORMAL << endl;
1190 CFGVersion = el->GetAttributeValue(
"version");
1191 Release = el->GetAttributeValue(
"release");
1193 if (debug_lvl & 1) {
1194 FGLogging log(LogLevel::INFO);
1196 << LogFormat::BOLD << CFGVersion << LogFormat::NORMAL << endl;
1198 if (CFGVersion != needed_cfg_version) {
1199 FGLogging log(LogLevel::ERROR);
1200 log << endl << LogFormat::RED <<
"YOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT."
1201 " RESULTS WILL BE UNPREDICTABLE !!" << endl;
1202 log <<
"Current version needed is: " << needed_cfg_version << endl;
1203 log <<
" You have version: " << CFGVersion << endl << LogFormat::DEFAULT << endl;
1207 if (Release ==
"ALPHA" && (debug_lvl & 1)) {
1208 FGLogging log(LogLevel::DEBUG);
1210 << LogFormat::BOLD <<
"This aircraft model is an " << LogFormat::RED << Release
1211 << LogFormat::RESET << LogFormat::BOLD <<
" release!!!" << endl << endl << LogFormat::RESET
1212 <<
"This aircraft model may not even properly load, and probably"
1213 <<
" will not fly as expected." << endl << endl
1214 << LogFormat::RED << LogFormat::BOLD <<
"Use this model for development purposes ONLY!!!"
1215 << LogFormat::NORMAL << LogFormat::RESET << endl << endl;
1216 }
else if (Release ==
"BETA" && (debug_lvl & 1)) {
1217 FGLogging log(LogLevel::DEBUG);
1219 << LogFormat::BOLD <<
"This aircraft model is a " << LogFormat::RED << Release
1220 << LogFormat::RESET << LogFormat::BOLD <<
" release!!!" << endl << endl << LogFormat::RESET
1221 <<
"This aircraft model probably will not fly as expected." << endl << endl
1222 << LogFormat::BLUE << LogFormat::BOLD <<
"Use this model for development purposes ONLY!!!"
1223 << LogFormat::NORMAL << LogFormat::RESET << endl << endl;
1224 }
else if (Release ==
"PRODUCTION" && (debug_lvl & 1)) {
1225 FGLogging log(LogLevel::DEBUG);
1227 << LogFormat::BOLD <<
"This aircraft model is a " << LogFormat::BLUE << Release
1228 << LogFormat::RESET << LogFormat::BOLD <<
" release." << endl << endl << LogFormat::RESET;
1229 }
else if (debug_lvl & 1) {
1230 FGLogging log(LogLevel::DEBUG);
1232 << LogFormat::BOLD <<
"This aircraft model is an " << LogFormat::RED << Release
1233 << LogFormat::RESET << LogFormat::BOLD <<
" release!!!" << endl << endl << LogFormat::RESET
1234 <<
"This aircraft model may not even properly load, and probably"
1235 <<
" will not fly as expected." << endl << endl
1236 << LogFormat::RED << LogFormat::BOLD <<
"Use this model for development purposes ONLY!!!"
1237 << LogFormat::NORMAL << LogFormat::RESET << endl << endl;
1245bool FGFDMExec::ReadChild(Element* el)
1255 auto child = std::make_shared<childData>();
1257 auto pm = std::make_unique<FGPropertyManager>(Root);
1258 child->exec = std::make_unique<FGFDMExec>(pm.get(), FDMctr);
1259 child->exec->SetChild(
true);
1261 string childAircraft = el->GetAttributeValue(
"name");
1262 string sMated = el->GetAttributeValue(
"mated");
1263 if (sMated ==
"false") child->mated =
false;
1264 string sInternal = el->GetAttributeValue(
"internal");
1265 if (sInternal ==
"true") child->internal =
true;
1267 child->exec->SetAircraftPath( AircraftPath );
1268 child->exec->SetEnginePath( EnginePath );
1269 child->exec->SetSystemsPath( SystemsPath );
1270 child->exec->LoadModel(childAircraft);
1272 Element* location = el->FindElement(
"location");
1274 child->Loc = location->FindElementTripletConvertTo(
"IN");
1276 XMLLogException err(el);
1277 err <<
"No location was found for this child object!" << endl;
1281 Element* orientation = el->FindElement(
"orient");
1283 child->Orient = orientation->FindElementTripletConvertTo(
"RAD");
1284 }
else if (debug_lvl > 0) {
1285 FGLogging log(LogLevel::WARN);
1286 log << endl << LogFormat::BOLD
1287 <<
" No orientation was found for this child object! Assuming 0,0,0."
1288 << LogFormat::RESET << endl;
1291 ChildFDMList.push_back(child);
1300 Trim = std::make_shared<FGTrim>(
this,tNone);
1309 if( IncrementThenHolding ) {
1311 if (TimeStepsUntilHold == 0) {
1318 IncrementThenHolding =
false;
1319 TimeStepsUntilHold--;
1321 }
else if ( TimeStepsUntilHold > 0 ) {
1323 TimeStepsUntilHold--;
1332 if (Constructing)
return;
1334 if (mode < 0 || mode > JSBSim::tNone)
1337 FGTrim trim(
this, (JSBSim::TrimMode)mode);
1338 bool success = trim.DoTrim();
1361void FGFDMExec::SRand(
int sr)
1364 RandomGenerator->seed(RandomSeed);
1386void FGFDMExec::Debug(
int from)
1388 if (debug_lvl <= 0)
return;
1390 FGLogging log(LogLevel::DEBUG);
1392 if (debug_lvl & 1 && IdFDM == 0) {
1395 <<
"JSBSim Flight Dynamics Model v" << JSBSim_version << endl;
1396 log <<
" [JSBSim-ML v" << needed_cfg_version <<
"]\n\n";
1397 log <<
"JSBSim startup beginning ...\n\n";
1398 if (disperse == 1) log <<
"Dispersions are ON." << endl << endl;
1399 }
else if (from == 3) {
1400 log <<
"\n\nJSBSim startup complete\n\n";
1403 if (debug_lvl & 2 ) {
1404 if (from == 0) log <<
"Instantiated: FGFDMExec" << endl;
1405 if (from == 1) log <<
"Destroyed: FGFDMExec" << endl;
1407 if (debug_lvl & 4 ) {
1409 log <<
"================== Frame: " << Frame <<
" Time: " << fixed
1410 << sim_time <<
" dt: " << dT << endl;
1413 if (debug_lvl & 8 ) {
1415 if (debug_lvl & 16) {
1417 if (debug_lvl & 64) {
Element * FindElement(const std::string &el="")
Searches for a specified element.
const std::string & GetName(void) const
Retrieves the element name.
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
bool HasAttribute(const std::string &key)
Determines if an element has the supplied attribute.
Handles the calculation of accelerations.
const FGColumnVector3 & GetUVWidot(void) const
Retrieves the body axis acceleration in the ECI frame.
const FGColumnVector3 & GetUVWdot(void) const
Retrieves the body axis acceleration.
const FGColumnVector3 & GetBodyAccel(void) const
Retrieves the acceleration resulting from the applied forces.
const FGColumnVector3 & GetPQRidot(void) const
Retrieves the axis angular acceleration vector in the ECI frame.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
Encapsulates the aerodynamic calculations.
const FGColumnVector3 & GetMoments(void) const
Gets the total aerodynamic moment vector about the CG.
const FGColumnVector3 & GetvFw(void) const
Retrieves the aerodynamic forces in the wind axes.
const FGColumnVector3 & GetForces(void) const
Gets the total aerodynamic force vector.
Encapsulates an Aircraft and its systems.
double Getcbar(void) const
Gets the average wing chord.
double GetWingArea(void) const
Gets the wing area.
double GetWingSpan(void) const
Gets the wing span.
const std::string & GetAircraftName(void) const
Gets the aircraft name.
const FGColumnVector3 & GetXYZrp(void) const
Gets the the aero reference point (RP) coordinates.
Models an empty, abstract base atmosphere class.
virtual double GetPressureRatio(void) const
Returns the ratio of at-altitude pressure over the sea level value.
virtual double GetPressure(void) const
Returns the pressure in psf.
virtual double GetKinematicViscosity(void) const
Returns the kinematic viscosity.
virtual double GetSoundSpeed(void) const
Returns the speed of sound in ft/sec.
virtual double GetDensityRatio(void) const
Returns the ratio of at-altitude density over the sea level value.
virtual double GetDensity(void) const
Returns the density in slugs/ft^3.
virtual double GetTemperature() const
Returns the actual, modeled temperature at the current altitude in degrees Rankine.
Encapsulates various uncategorized scheduled functions.
const FGMatrix33 & GetTb2w(void) const
Calculates and returns the body-to-wind axis transformation matrix.
const FGMatrix33 & GetTw2b(void) const
Calculates and returns the wind-to-body axis transformation matrix.
double GetVground(void) const
Gets the ground speed in feet per second.
double GetVcalibratedKTS(void) const
Returns Calibrated airspeed in knots.
double GetTotalPressure(void) const
Returns the total pressure.
double GetVt(void) const
Gets the magnitude of total vehicle velocity including wind effects in feet per second.
Encapsulates the Buoyant forces calculations.
const FGColumnVector3 & GetMoments(void) const
Gets the total Buoyancy moment vector.
const FGMatrix33 & GetGasMassInertia(void)
Gets the total moments of inertia for the gas mass in the body frame.
double GetGasMass(void) const
Gets the total gas mass.
const FGColumnVector3 & GetGasMassMoment(void)
Gets the total moment from the gas mass.
const FGColumnVector3 & GetForces(void) const
Gets the total Buoyant force vector.
double Magnitude(void) const
Length of the vector.
Manages the external and/or arbitrary forces and moments.
const FGColumnVector3 & GetMoments(void) const
Retrieves the total moment resulting from the forces defined in the external reactions.
const FGColumnVector3 & GetForces(void) const
Retrieves the total forces defined in the external reactions.
Encapsulates the Flight Control System (FCS) functionality.
double GetMixtureCmd(int engine) const
Gets the mixture command.
double GetThrottleCmd(int engine) const
Gets the throttle command.
double GetGearPos(void) const
Gets the gear position (0 up, 1 down), defaults to down.
bool GetPropFeather(int engine) const
Gets the prop feather position.
double GetPropAdvance(int engine) const
Gets the prop pitch position.
double GetMixturePos(int engine) const
Gets the mixture position.
double GetThrottlePos(int engine) const
Gets the throttle position.
Encapsulates the JSBSim simulation executive.
bool GetHoldDown(void) const
Gets the value of the property forces/hold-down.
void DoLinearization(int)
Executes linearization with state-space output You must trim first to get an accurate state-space mod...
std::shared_ptr< FGWinds > GetWinds(void) const
Returns the FGWinds pointer.
void SetDebugLevel(int level)
Sets the debug level.
std::shared_ptr< FGBuoyantForces > GetBuoyantForces(void) const
Returns the FGBuoyantForces pointer.
bool LoadScript(const SGPath &Script, double deltaT=0.0, const SGPath &initfile=SGPath())
Load a script.
std::shared_ptr< FGAircraft > GetAircraft(void) const
Returns the FGAircraft pointer.
std::shared_ptr< FGFCS > GetFCS(void) const
Returns the FGFCS pointer.
int GetDebugLevel(void) const
Retrieves the current debug level setting.
std::shared_ptr< FGOutput > GetOutput(void) const
Returns the FGOutput pointer.
static const int START_NEW_OUTPUT
Mode flags for ResetToInitialConditions.
std::string QueryPropertyCatalog(const std::string &check, const std::string &end_of_line="\n")
Retrieves property or properties matching the supplied string.
void BuildPropertyCatalog(struct PropertyCatalogStructure *pcs)
Builds a catalog of properties.
FGFDMExec(FGPropertyManager *root=nullptr, std::shared_ptr< unsigned int > fdmctr=nullptr)
Default constructor.
double GetDeltaT(void) const
Returns the simulation delta T.
double Setsim_time(double cur_time)
Sets the current sim time.
std::vector< std::string > EnumerateFDMs(void)
Returns a vector of strings representing the names of all loaded models (future)
void DoTrim(int mode)
Executes trimming in the selected mode.
std::shared_ptr< FGPropagate > GetPropagate(void) const
Returns the FGPropagate pointer.
std::shared_ptr< FGAerodynamics > GetAerodynamics(void) const
Returns the FGAerodynamics pointer.
double IncrTime(void)
Increments the simulation time if not in Holding mode.
std::shared_ptr< FGExternalReactions > GetExternalReactions(void) const
Returns the FGExternalReactions pointer.
void CheckIncrementalHold(void)
Checks if required to hold afer increment.
bool LoadPlanet(const SGPath &PlanetPath, bool useAircraftPath=true)
Loads the planet.
bool Run(void)
This function executes each scheduled model in succession.
std::shared_ptr< FGGroundReactions > GetGroundReactions(void) const
Returns the FGGroundReactions pointer.
std::shared_ptr< FGMassBalance > GetMassBalance(void) const
Returns the FGAircraft pointer.
std::shared_ptr< FGTrim > GetTrim(void)
Returns a pointer to the FGTrim object.
std::shared_ptr< FGPropulsion > GetPropulsion(void) const
Returns the FGPropulsion pointer.
bool LoadModel(const SGPath &AircraftPath, const SGPath &EnginePath, const SGPath &SystemsPath, const std::string &model, bool addModelToPath=true)
Loads an aircraft model.
~FGFDMExec()
Default destructor.
void ResetToInitialConditions(int mode)
Resets the initial conditions object and prepares the simulation to run again.
bool IntegrationSuspended(void) const
Returns the simulation suspension state.
void Unbind(void)
Unbind all tied JSBSim properties.
double GetSimTime(void) const
Returns the cumulative simulation time in seconds.
void Setdt(double delta_t)
Sets the integration time step for the simulation executive.
void SuspendIntegration(void)
Suspends the simulation and sets the delta T to zero.
std::shared_ptr< FGInertial > GetInertial(void) const
Returns the FGInertial pointer.
void Initialize(const FGInitialCondition *FGIC)
Initializes the simulation with initial conditions.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
std::shared_ptr< FGAuxiliary > GetAuxiliary(void) const
Returns the FGAuxiliary pointer.
std::shared_ptr< FGAccelerations > GetAccelerations(void) const
Returns the FGAccelerations pointer.
bool RunIC(void)
Initializes the sim from the initial condition object and executes each scheduled model without integ...
void ResumeIntegration(void)
Resumes the simulation by resetting delta T to the correct value.
std::shared_ptr< FGInput > GetInput(void) const
Returns the FGInput pointer.
Manages ground reactions modeling.
Models inertial forces (e.g.
void SetTime(double time)
Set the simulation time.
Initializes the simulation run.
FGColumnVector3 GetWindNEDFpsIC(void) const
Gets the initial wind velocity in the NED local frame.
static char highint[5]
highlights text
Class used to create linear models from FGFDMExec instances.
void WriteScicoslab() const
Write Scicoslab source file with the state space model to a file in the current working directory.
Models weight, balance and moment of inertia information.
const FGColumnVector3 & GetXYZcg(void) const
Returns the coordinates of the center of gravity expressed in the structural frame.
FGColumnVector3 StructuralToBody(const FGColumnVector3 &r) const
Conversion from the structural frame to the body frame.
const FGMatrix33 & GetJinv(void) const
Returns the inverse of the inertia matrix expressed in the body frame.
const FGMatrix33 & GetJ(void) const
Returns the inertia matrix expressed in the body frame.
unsigned int GetRate(void) const
Get the output rate for the model in frames.
Handles simulation output.
void SetStartNewOutput(void)
Reset the output prior to a restart of the simulation.
bool Load(Element *el, const SGPath &dir)
Load the output directives and adds a new output instance to the Output Manager list.
Models the EOM and integration/propagation of state.
const FGMatrix33 & GetTi2b(void) const
Retrieves the ECI-to-body transformation matrix.
const FGColumnVector3 & GetPQR(void) const
Retrieves the body angular rates vector, relative to the ECEF frame.
double GetSinEuler(int idx) const
Retrieves the sine of a vehicle Euler angle component.
const FGMatrix33 & GetTec2i(void) const
Retrieves the ECEF-to-ECI transformation matrix.
const FGMatrix33 & GetTec2l(void) const
Retrieves the ECEF-to-local transformation matrix.
double GetAltitudeASL(void) const
Returns the current altitude above sea level.
const FGMatrix33 & GetTb2i(void) const
Retrieves the body-to-ECI transformation matrix.
const FGColumnVector3 & GetPQRi(void) const
Retrieves the body angular rates vector, relative to the ECI (inertial) frame.
const FGColumnVector3 & GetUVW(void) const
Retrieves the body frame vehicle velocity vector.
const FGMatrix33 & GetTl2b(void) const
Retrieves the local-to-body transformation matrix.
const FGColumnVector3 & GetVel(void) const
Retrieves the velocity vector.
double GetCosEuler(int idx) const
Retrieves the cosine of a vehicle Euler angle component.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
const FGMatrix33 & GetTec2b(void) const
Retrieves the ECEF-to-body transformation matrix.
const FGMatrix33 & GetTb2l(void) const
Retrieves the body-to-local transformation matrix.
const FGColumnVector3 & GetInertialPosition(void) const
Retrieves the inertial position vector.
Propulsion management class.
bool Load(Element *el) override
Loads the propulsion system (engine[s] and tank[s]).
size_t GetNumEngines(void) const
Retrieves the number of engines defined for the aircraft.
void InitRunning(int n)
Sets up the engines as running.
The trimming routine for JSBSim.
Models atmospheric disturbances: winds, gusts, turbulence, downbursts, etc.
virtual const FGColumnVector3 & GetTotalWindNED(void) const
Retrieves the total wind components in NED frame.
virtual void SetWindNED(double wN, double wE, double wD)
Sets the wind components in NED frame.
A node in a property tree.
Main namespace for the JSBSim Flight Dynamics Model.
SGPropertyNode_ptr node
The node for the property.
std::string base_string
Name of the property.