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"
94 IncrementThenHolding =
false;
95 TimeStepsUntilHold = -1;
101 AircraftPath =
"aircraft";
102 EnginePath =
"engine";
103 SystemsPath =
"systems";
105 if (
const char* num = getenv(
"JSBSIM_DEBUG"); num !=
nullptr)
106 debug_lvl = strtol(num,
nullptr, 0);
111 FDMctr = std::make_shared<unsigned int>();
124 Root = root->GetNode();
126 SGPropertyNode* instanceRoot = Root->getNode(
"fdm/jsbsim", IdFDM,
true);
127 instance = std::make_shared<FGPropertyManager>(instanceRoot);
129 if (
const char* num = getenv(
"JSBSIM_DISPERSE");
130 num !=
nullptr && strtol(num,
nullptr, 0) != 0)
140 catch (
const string& msg) {
141 cerr << endl <<
"Caught error: " << msg << endl;
145 cout << endl <<
"Caught error: " << e.what() << endl;
157 instance->Tie(
"simulation/disperse",
this, &FGFDMExec::GetDisperse);
158 instance->Tie(
"simulation/randomseed",
this, &FGFDMExec::SRand, &FGFDMExec::SRand);
159 instance->Tie(
"simulation/terminate", &Terminate);
160 instance->Tie(
"simulation/pause", &holding);
164 instance->Tie(
"simulation/frame",
reinterpret_cast<int*
>(&Frame));
165 instance->Tie(
"simulation/trim-completed", &trim_completed);
168 Constructing =
false;
178 }
catch (
const string& msg ) {
179 cout <<
"Caught error: " << msg << endl;
182 if (!FDMctr) (*FDMctr)--;
208bool FGFDMExec::Allocate(
void)
212 Models.resize(eNumStandardModels);
218 Models[eInertial] = std::make_shared<FGInertial>(
this);
223 Models[ePropagate] = std::make_shared<FGPropagate>(
this);
224 Models[eInput] = std::make_shared<FGInput>(
this);
225 Models[eAtmosphere] = std::make_shared<FGStandardAtmosphere>(
this);
226 Models[eWinds] = std::make_shared<FGWinds>(
this);
227 Models[eSystems] = std::make_shared<FGFCS>(
this);
228 Models[eMassBalance] = std::make_shared<FGMassBalance>(
this);
229 Models[eAuxiliary] = std::make_shared<FGAuxiliary>(
this);
230 Models[ePropulsion] = std::make_shared<FGPropulsion>(
this);
231 Models[eAerodynamics] = std::make_shared<FGAerodynamics> (
this);
232 Models[eGroundReactions] = std::make_shared<FGGroundReactions>(
this);
233 Models[eExternalReactions] = std::make_shared<FGExternalReactions>(
this);
234 Models[eBuoyantForces] = std::make_shared<FGBuoyantForces>(
this);
235 Models[eAircraft] = std::make_shared<FGAircraft>(
this);
236 Models[eAccelerations] = std::make_shared<FGAccelerations>(
this);
237 Models[eOutput] = std::make_shared<FGOutput>(
this);
240 Propagate =
static_cast<FGPropagate*
>(Models[ePropagate].get());
241 Inertial =
static_cast<FGInertial*
>(Models[eInertial].get());
242 Input =
static_cast<FGInput*
>(Models[eInput].get());
243 Atmosphere =
static_cast<FGAtmosphere*
>(Models[eAtmosphere].get());
244 Winds =
static_cast<FGWinds*
>(Models[eWinds].get());
245 FCS =
static_cast<FGFCS*
>(Models[eSystems].get());
246 MassBalance =
static_cast<FGMassBalance*
>(Models[eMassBalance].get());
247 Auxiliary =
static_cast<FGAuxiliary*
>(Models[eAuxiliary].get());
248 Propulsion =
static_cast<FGPropulsion*
>(Models[ePropulsion].get());
249 Aerodynamics =
static_cast<FGAerodynamics*
>(Models[eAerodynamics].get());
250 GroundReactions =
static_cast<FGGroundReactions*
>(Models[eGroundReactions].get());
252 BuoyantForces =
static_cast<FGBuoyantForces*
>(Models[eBuoyantForces].get());
253 Aircraft =
static_cast<FGAircraft*
>(Models[eAircraft].get());
254 Accelerations =
static_cast<FGAccelerations*
>(Models[eAccelerations].get());
255 Output =
static_cast<FGOutput*
>(Models[eOutput].get());
258 LoadPlanetConstants();
263 IC = std::make_shared<FGInitialCondition>(
this);
264 IC->bind(instance.get());
275 return static_pointer_cast<FGPropagate>(Models[ePropagate]);
282 return static_pointer_cast<FGInertial>(Models[eInertial]);
289 return static_pointer_cast<FGInput>(Models[eInput]);
294std::shared_ptr<FGAtmosphere> FGFDMExec::GetAtmosphere(
void)
const
296 return static_pointer_cast<FGAtmosphere>(Models[eAtmosphere]);
303 return static_pointer_cast<FGWinds>(Models[eWinds]);
310 return static_pointer_cast<FGFCS>(Models[eSystems]);
317 return static_pointer_cast<FGMassBalance>(Models[eMassBalance]);
324 return static_pointer_cast<FGAuxiliary>(Models[eAuxiliary]);
331 return static_pointer_cast<FGPropulsion>(Models[ePropulsion]);
338 return static_pointer_cast<FGAerodynamics>(Models[eAerodynamics]);
345 return static_pointer_cast<FGGroundReactions>(Models[eGroundReactions]);
352 return static_pointer_cast<FGExternalReactions>(Models[eExternalReactions]);
359 return static_pointer_cast<FGBuoyantForces>(Models[eBuoyantForces]);
366 return static_pointer_cast<FGAircraft>(Models[eAircraft]);
373 return static_pointer_cast<FGAccelerations>(Models[eAccelerations]);
380 return static_pointer_cast<FGOutput>(Models[eOutput]);
385void FGFDMExec::InitializeModels(
void)
387 for (
unsigned int i = 0; i < Models.size(); i++) {
389 if (i == eInput || i == eOutput)
continue;
392 Models[i]->InitModel();
398bool FGFDMExec::DeAllocate(
void)
414 for (
auto &ChildFDM: ChildFDMList) {
415 ChildFDM->AssignState(Propagate);
424 for (
unsigned int i = 0; i < Models.size(); i++) {
426 Models[i]->Run(holding);
429 if (Terminate) success =
false;
436void FGFDMExec::LoadInputs(
unsigned int idx)
440 Propagate->in.vPQRidot = Accelerations->
GetPQRidot();
441 Propagate->in.vUVWidot = Accelerations->
GetUVWidot();
442 Propagate->in.DeltaT = dT;
447 Inertial->in.Position = Propagate->GetLocation();
451 Atmosphere->in.GeodLatitudeDeg = Propagate->GetGeodLatitudeDeg();
452 Atmosphere->in.LongitudeDeg = Propagate->GetLongitudeDeg();
456 Winds->in.DistanceAGL = Propagate->GetDistanceAGL();
457 Winds->in.Tl2b = Propagate->
GetTl2b();
458 Winds->in.Tw2b = Auxiliary->
GetTw2b();
459 Winds->in.V = Auxiliary->
GetVt();
460 Winds->in.totalDeltaT = dT * Winds->
GetRate();
463 Auxiliary->in.Pressure = Atmosphere->
GetPressure();
464 Auxiliary->in.Density = Atmosphere->
GetDensity();
468 Auxiliary->in.DistanceAGL = Propagate->GetDistanceAGL();
469 Auxiliary->in.Mass = MassBalance->GetMass();
470 Auxiliary->in.Tl2b = Propagate->
GetTl2b();
471 Auxiliary->in.Tb2l = Propagate->
GetTb2l();
472 Auxiliary->in.vPQR = Propagate->
GetPQR();
473 Auxiliary->in.vPQRi = Propagate->
GetPQRi();
474 Auxiliary->in.vPQRidot = Accelerations->
GetPQRidot();
475 Auxiliary->in.vUVW = Propagate->
GetUVW();
476 Auxiliary->in.vUVWdot = Accelerations->
GetUVWdot();
477 Auxiliary->in.vVel = Propagate->
GetVel();
478 Auxiliary->in.vBodyAccel = Accelerations->
GetBodyAccel();
479 Auxiliary->in.ToEyePt = MassBalance->
StructuralToBody(Aircraft->GetXYZep());
480 Auxiliary->in.VRPBody = MassBalance->
StructuralToBody(Aircraft->GetXYZvrp());
482 Auxiliary->in.vFw = Aerodynamics->
GetvFw();
483 Auxiliary->in.vLocation = Propagate->GetLocation();
484 Auxiliary->in.CosTht = Propagate->
GetCosEuler(eTht);
485 Auxiliary->in.SinTht = Propagate->
GetSinEuler(eTht);
486 Auxiliary->in.CosPhi = Propagate->
GetCosEuler(ePhi);
487 Auxiliary->in.SinPhi = Propagate->
GetSinEuler(ePhi);
489 Auxiliary->in.TurbPQR = Winds->GetTurbPQR();
495 Propulsion->in.Pressure = Atmosphere->
GetPressure();
499 Propulsion->in.Density = Atmosphere->
GetDensity();
503 Propulsion->in.Vt = Auxiliary->
GetVt();
504 Propulsion->in.qbar = Auxiliary->Getqbar();
505 Propulsion->in.TAT_c = Auxiliary->GetTAT_C();
506 Propulsion->in.AeroUVW = Auxiliary->GetAeroUVW();
507 Propulsion->in.AeroPQR = Auxiliary->GetAeroPQR();
508 Propulsion->in.alpha = Auxiliary->Getalpha();
509 Propulsion->in.beta = Auxiliary->Getbeta();
510 Propulsion->in.TotalDeltaT = dT * Propulsion->
GetRate();
517 Propulsion->in.H_agl = Propagate->GetDistanceAGL();
518 Propulsion->in.PQRi = Propagate->
GetPQRi();
522 Aerodynamics->in.Alpha = Auxiliary->Getalpha();
523 Aerodynamics->in.Beta = Auxiliary->Getbeta();
524 Aerodynamics->in.Qbar = Auxiliary->Getqbar();
525 Aerodynamics->in.Vt = Auxiliary->
GetVt();
526 Aerodynamics->in.Tb2w = Auxiliary->
GetTb2w();
527 Aerodynamics->in.Tw2b = Auxiliary->
GetTw2b();
530 case eGroundReactions:
532 GroundReactions->in.Vground = Auxiliary->
GetVground();
536 GroundReactions->in.BrakePos = FCS->GetBrakePos();
537 GroundReactions->in.FCSGearPos = FCS->
GetGearPos();
538 GroundReactions->in.EmptyWeight = MassBalance->GetEmptyWeight();
539 GroundReactions->in.Tb2l = Propagate->
GetTb2l();
540 GroundReactions->in.Tec2l = Propagate->
GetTec2l();
541 GroundReactions->in.Tec2b = Propagate->
GetTec2b();
542 GroundReactions->in.PQR = Propagate->
GetPQR();
543 GroundReactions->in.UVW = Propagate->
GetUVW();
544 GroundReactions->in.DistanceAGL = Propagate->GetDistanceAGL();
546 GroundReactions->in.TotalDeltaT = dT * GroundReactions->
GetRate();
547 GroundReactions->in.WOW = GroundReactions->GetWOW();
548 GroundReactions->in.Location = Propagate->GetLocation();
549 GroundReactions->in.vXYZcg = MassBalance->
GetXYZcg();
551 case eExternalReactions:
555 BuoyantForces->in.Density = Atmosphere->
GetDensity();
556 BuoyantForces->in.Pressure = Atmosphere->
GetPressure();
558 BuoyantForces->in.gravity = Inertial->GetGravity().
Magnitude();
562 MassBalance->in.GasMass = BuoyantForces->
GetGasMass();
564 MassBalance->in.TanksWeight = Propulsion->GetTanksWeight();
565 MassBalance->in.TanksMoment = Propulsion->GetTanksMoment();
566 MassBalance->in.TankInertia = Propulsion->CalculateTankInertias();
567 MassBalance->in.WOW = GroundReactions->GetWOW();
570 Aircraft->in.AeroForce = Aerodynamics->
GetForces();
571 Aircraft->in.PropForce = Propulsion->GetForces();
572 Aircraft->in.GroundForce = GroundReactions->GetForces();
573 Aircraft->in.ExternalForce = ExternalReactions->
GetForces();
574 Aircraft->in.BuoyantForce = BuoyantForces->
GetForces();
575 Aircraft->in.AeroMoment = Aerodynamics->
GetMoments();
576 Aircraft->in.PropMoment = Propulsion->GetMoments();
577 Aircraft->in.GroundMoment = GroundReactions->GetMoments();
578 Aircraft->in.ExternalMoment = ExternalReactions->
GetMoments();
579 Aircraft->in.BuoyantMoment = BuoyantForces->
GetMoments();
582 Accelerations->in.
J = MassBalance->
GetJ();
588 Accelerations->in.
Moment = Aircraft->GetMoments();
589 Accelerations->in.
GroundMoment = GroundReactions->GetMoments();
590 Accelerations->in.
Force = Aircraft->GetForces();
591 Accelerations->in.
GroundForce = GroundReactions->GetForces();
592 Accelerations->in.
vGravAccel = Inertial->GetGravity();
597 Accelerations->in.
DeltaT = dT;
598 Accelerations->in.
Mass = MassBalance->GetMass();
599 Accelerations->in.
MultipliersList = GroundReactions->GetMultipliersList();
610void FGFDMExec::LoadPlanetConstants(
void)
612 Propagate->in.vOmegaPlanet = Inertial->GetOmegaPlanet();
613 Accelerations->in.
vOmegaPlanet = Inertial->GetOmegaPlanet();
614 Propagate->in.SemiMajor = Inertial->GetSemimajor();
615 Propagate->in.SemiMinor = Inertial->GetSemiminor();
616 Propagate->in.GM = Inertial->GetGM();
617 Auxiliary->in.StandardGravity = Inertial->GetStandardGravity();
618 Auxiliary->in.StdDaySLsoundspeed = Atmosphere->StdDaySLsoundspeed;
623void FGFDMExec::LoadModelConstants(
void)
626 Aerodynamics->in.Wingarea = Aircraft->
GetWingArea();
627 Aerodynamics->in.Wingchord = Aircraft->
Getcbar();
628 Aerodynamics->in.Wingincidence = Aircraft->GetWingIncidence();
629 Aerodynamics->in.Wingspan = Aircraft->
GetWingSpan();
631 Auxiliary->in.Wingchord = Aircraft->
Getcbar();
632 GroundReactions->in.vXYZcg = MassBalance->
GetXYZcg();
643 Models[eInput]->InitModel();
644 Models[eOutput]->InitModel();
647 Propagate->InitializeDerivatives();
651 MassBalance->GetMassPropertiesReport(0);
654 <<
"End of vehicle configuration loading." << endl
655 <<
"-------------------------------------------------------------------------------"
656 <<
reset << std::setprecision(6) << endl;
659 for (
unsigned int n=0; n < Propulsion->
GetNumEngines(); ++n) {
660 if (IC->IsEngineRunning(n)) {
663 }
catch (
const string& str) {
677 Propagate->SetInitialState(FGIC);
679 Auxiliary->SetInitialState(FGIC);
687 if (Constructing)
return;
696 Script->ResetEvents();
700 if (!(mode & DONT_EXECUTE_RUN_IC))
711 Propagate->in.vPQRidot = Accelerations->
GetPQRidot();
712 Propagate->in.vUVWidot = Accelerations->
GetUVWidot();
721 vector <string> FDMList;
724 for (
auto &ChildFDM: ChildFDMList)
725 FDMList.push_back(ChildFDM->exec->GetAircraft()->GetAircraftName());
733 const SGPath& initfile)
735 Script = std::make_shared<FGScript>(
this);
736 return Script->LoadScript(GetFullPath(script), deltaT, initfile);
743 SGPath PlanetFileName;
745 if(useAircraftPath && PlanetPath.isRelative()) {
746 PlanetFileName = AircraftPath/PlanetPath.utf8Str();
748 PlanetFileName = PlanetPath;
752 Element* document = XMLFileRead.LoadXMLDocument(PlanetFileName);
757 s <<
"File: " << PlanetFileName <<
" could not be read.";
758 cerr << s.str() << endl;
762 if (document->
GetName() !=
"planet") {
764 s <<
"File: " << PlanetFileName <<
" is not a planet file.";
765 cerr << s.str() << endl;
772 cerr << endl <<
"Planet element has problems in file " << PlanetFileName << endl;
781 bool result = Models[eInertial]->Load(element);
785 LoadPlanetConstants();
791 if (atm_element && atm_element->
HasAttribute(
"model")) {
793 if (model ==
"MSIS") {
795 instance->Unbind(Models[eAtmosphere]);
796 Models[eAtmosphere] = std::make_shared<FGMSIS>(
this);
797 Atmosphere =
static_cast<FGAtmosphere*
>(Models[eAtmosphere].get());
800 LoadInputs(eAtmosphere);
801 Atmosphere->InitModel();
802 result = Atmosphere->Load(atm_element);
804 cerr << endl <<
"Incorrect definition of <atmosphere>." << endl;
818 const SGPath& SystemsPath,
const string& model,
821 FGFDMExec::AircraftPath = GetFullPath(AircraftPath);
822 FGFDMExec::EnginePath = GetFullPath(EnginePath);
823 FGFDMExec::SystemsPath = GetFullPath(SystemsPath);
832 SGPath aircraftCfgFileName;
837 if( AircraftPath.isNull() || EnginePath.isNull() || SystemsPath.isNull()) {
838 cerr <<
"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);
868 cerr << endl <<
"Aircraft fileheader element has problems in file " << aircraftCfgFileName << endl;
873 if (IsChild) debug_lvl = 0;
880 cerr << endl <<
"Planet element has problems in file " << aircraftCfgFileName << endl;
888 result = Models[eAircraft]->Load(element);
890 cerr << endl <<
"Aircraft metrics element has problems in file " << aircraftCfgFileName << endl;
894 cerr << endl <<
"No metrics element was found in the aircraft config file." << endl;
901 result = Models[eMassBalance]->Load(element);
903 cerr << endl <<
"Aircraft mass_balance element has problems in file " << aircraftCfgFileName << endl;
907 cerr << endl <<
"No mass_balance element was found in the aircraft config file." << endl;
912 element = document->
FindElement(
"ground_reactions");
914 result = Models[eGroundReactions]->Load(element);
917 <<
"Aircraft ground_reactions element has problems in file "
918 << aircraftCfgFileName << endl;
922 cerr << endl <<
"No ground_reactions element was found in the aircraft config file." << endl;
927 element = document->
FindElement(
"external_reactions");
929 result = Models[eExternalReactions]->Load(element);
931 cerr << endl <<
"Aircraft external_reactions element has problems in file " << aircraftCfgFileName << endl;
939 result = Models[eBuoyantForces]->Load(element);
941 cerr << endl <<
"Aircraft buoyant_forces element has problems in file " << aircraftCfgFileName << endl;
949 result = Propulsion->
Load(element);
951 cerr << endl <<
"Aircraft propulsion element has problems in file " << aircraftCfgFileName << endl;
961 result = Models[eSystems]->Load(element);
963 cerr << endl <<
"Aircraft system element has problems in file " << aircraftCfgFileName << endl;
972 result = Models[eSystems]->Load(element);
974 cerr << endl <<
"Aircraft autopilot element has problems in file " << aircraftCfgFileName << endl;
982 result = Models[eSystems]->Load(element);
984 cerr << endl <<
"Aircraft flight_control element has problems in file " << aircraftCfgFileName << endl;
992 result = Models[eAerodynamics]->Load(element);
994 cerr << endl <<
"Aircraft aerodynamics element has problems in file " << aircraftCfgFileName << endl;
998 cerr << endl <<
"No expected aerodynamics element was found in the aircraft config file." << endl;
1004 if (!Input->
Load(element))
1014 if (!Output->
Load(element))
1023 result = ReadChild(element);
1025 cerr << endl <<
"Aircraft child element has problems in file " << aircraftCfgFileName << endl;
1032 LoadModelConstants();
1036 if (IsChild) debug_lvl = saved_debug_lvl;
1040 <<
" JSBSim failed to open the configuration file: " << aircraftCfgFileName
1044 for (
unsigned int i=0; i< Models.size(); i++) LoadInputs(i);
1049 masterPCS.
node = Root;
1058string FGFDMExec::GetPropulsionTankReport()
const
1060 return Propulsion->GetPropulsionTankReport();
1067 auto pcsNew = std::make_unique<struct PropertyCatalogStructure>();
1069 const string root_name = GetFullyQualifiedName(root_node) +
"/";
1070 const size_t root_name_length = root_name.length();
1072 for (
int i=0; i<pcs->
node->nChildren(); i++) {
1074 pcsNew->base_string = pcs->
base_string +
"/" + pcs->
node->getChild(i)->getNameString();
1075 int node_idx = pcs->
node->getChild(i)->getIndex();
1076 if (node_idx != 0) {
1077 pcsNew->base_string = CreateIndexedPropertyName(pcsNew->base_string, node_idx);
1079 if (pcs->
node->getChild(i)->nChildren() == 0) {
1080 if (pcsNew->base_string.substr(0, root_name_length) == root_name) {
1081 pcsNew->base_string = pcsNew->base_string.erase(0, root_name_length);
1083 if (pcs->
node->getChild(i)->getAttribute(SGPropertyNode::READ)) access=
"R";
1084 if (pcs->
node->getChild(i)->getAttribute(SGPropertyNode::WRITE)) access+=
"W";
1085 PropertyCatalog.push_back(pcsNew->base_string+
" ("+access+
")");
1087 pcsNew->node = pcs->
node->getChild(i);
1098 for (
auto &catalogElm: PropertyCatalog) {
1099 if (catalogElm.find(in) != string::npos) results += catalogElm + end_of_line;
1101 if (results.empty())
return "No matches found"+end_of_line;
1107void FGFDMExec::PrintPropertyCatalog(
void)
1111 << modelName <<
reset << endl << endl;
1112 for (
auto &catalogElm: PropertyCatalog)
1113 cout <<
" " << catalogElm << endl;
1118void FGFDMExec::PrintSimulationConfiguration(
void)
const
1120 cout << endl <<
"Simulation Configuration" << endl <<
"------------------------" << endl;
1121 cout << MassBalance->GetName() << endl;
1122 cout << GroundReactions->GetName() << endl;
1123 cout << Aerodynamics->GetName() << endl;
1124 cout << Propulsion->GetName() << endl;
1129bool FGFDMExec::ReadFileHeader(Element* el)
1133 if (debug_lvl == 0)
return result;
1136 cout << endl <<
highint <<
fgblue <<
"Reading child model: " << IdFDM <<
reset << endl << endl;
1139 if (el->FindElement(
"description"))
1140 cout <<
" Description: " << el->FindElement(
"description")->GetDataLine() << endl;
1141 if (el->FindElement(
"author"))
1142 cout <<
" Model Author: " << el->FindElement(
"author")->GetDataLine() << endl;
1143 if (el->FindElement(
"filecreationdate"))
1144 cout <<
" Creation Date: " << el->FindElement(
"filecreationdate")->GetDataLine() << endl;
1145 if (el->FindElement(
"version"))
1146 cout <<
" Version: " << el->FindElement(
"version")->GetDataLine() << endl;
1153bool FGFDMExec::ReadPrologue(Element* el)
1157 if (!el)
return false;
1159 string AircraftName = el->GetAttributeValue(
"name");
1160 Aircraft->SetAircraftName(AircraftName);
1162 if (debug_lvl & 1) cout <<
underon <<
"Reading Aircraft Configuration File"
1165 CFGVersion = el->GetAttributeValue(
"version");
1166 Release = el->GetAttributeValue(
"release");
1169 cout <<
" Version: " <<
highint << CFGVersion
1171 if (CFGVersion != needed_cfg_version) {
1172 cerr << endl <<
fgred <<
"YOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT."
1173 " RESULTS WILL BE UNPREDICTABLE !!" << endl;
1174 cerr <<
"Current version needed is: " << needed_cfg_version << endl;
1175 cerr <<
" You have version: " << CFGVersion << endl <<
fgdef << endl;
1179 if (Release ==
"ALPHA" && (debug_lvl & 1)) {
1180 cout << endl << endl
1181 <<
highint <<
"This aircraft model is an " <<
fgred << Release
1183 <<
"This aircraft model may not even properly load, and probably"
1184 <<
" will not fly as expected." << endl << endl
1185 <<
fgred <<
highint <<
"Use this model for development purposes ONLY!!!"
1187 }
else if (Release ==
"BETA" && (debug_lvl & 1)) {
1188 cout << endl << endl
1189 <<
highint <<
"This aircraft model is a " <<
fgred << Release
1191 <<
"This aircraft model probably will not fly as expected." << endl << endl
1192 <<
fgblue <<
highint <<
"Use this model for development purposes ONLY!!!"
1194 }
else if (Release ==
"PRODUCTION" && (debug_lvl & 1)) {
1195 cout << endl << endl
1196 <<
highint <<
"This aircraft model is a " <<
fgblue << Release
1198 }
else if (debug_lvl & 1) {
1199 cout << endl << endl
1200 <<
highint <<
"This aircraft model is an " <<
fgred << Release
1202 <<
"This aircraft model may not even properly load, and probably"
1203 <<
" will not fly as expected." << endl << endl
1204 <<
fgred <<
highint <<
"Use this model for development purposes ONLY!!!"
1213bool FGFDMExec::ReadChild(Element* el)
1223 auto child = std::make_shared<childData>();
1225 auto pm = std::make_unique<FGPropertyManager>(Root);
1226 child->exec = std::make_unique<FGFDMExec>(pm.get(), FDMctr);
1227 child->exec->SetChild(
true);
1229 string childAircraft = el->GetAttributeValue(
"name");
1230 string sMated = el->GetAttributeValue(
"mated");
1231 if (sMated ==
"false") child->mated =
false;
1232 string sInternal = el->GetAttributeValue(
"internal");
1233 if (sInternal ==
"true") child->internal =
true;
1235 child->exec->SetAircraftPath( AircraftPath );
1236 child->exec->SetEnginePath( EnginePath );
1237 child->exec->SetSystemsPath( SystemsPath );
1238 child->exec->LoadModel(childAircraft);
1240 Element* location = el->FindElement(
"location");
1242 child->Loc = location->FindElementTripletConvertTo(
"IN");
1244 const string s(
" No location was found for this child object!");
1246 << s <<
reset << endl;
1247 throw BaseException(s);
1250 Element* orientation = el->FindElement(
"orient");
1252 child->Orient = orientation->FindElementTripletConvertTo(
"RAD");
1253 }
else if (debug_lvl > 0) {
1254 cerr << endl <<
highint <<
" No orientation was found for this child object! Assuming 0,0,0." <<
reset << endl;
1257 ChildFDMList.push_back(child);
1266 Trim = std::make_shared<FGTrim>(
this,tNone);
1275 if( IncrementThenHolding ) {
1277 if (TimeStepsUntilHold == 0) {
1284 IncrementThenHolding =
false;
1285 TimeStepsUntilHold--;
1287 }
else if ( TimeStepsUntilHold > 0 ) {
1289 TimeStepsUntilHold--;
1298 if (Constructing)
return;
1300 if (mode < 0 || mode > JSBSim::tNone)
1301 throw(
"Illegal trimming mode!");
1303 FGTrim trim(
this, (JSBSim::TrimMode)mode);
1304 bool success = trim.DoTrim();
1327void FGFDMExec::SRand(
int sr)
1330 RandomGenerator->seed(RandomSeed);
1352void FGFDMExec::Debug(
int from)
1354 if (debug_lvl <= 0)
return;
1356 if (debug_lvl & 1 && IdFDM == 0) {
1359 <<
"JSBSim Flight Dynamics Model v" << JSBSim_version << endl;
1360 cout <<
" [JSBSim-ML v" << needed_cfg_version <<
"]\n\n";
1361 cout <<
"JSBSim startup beginning ...\n\n";
1362 if (disperse == 1) cout <<
"Dispersions are ON." << endl << endl;
1363 }
else if (from == 3) {
1364 cout <<
"\n\nJSBSim startup complete\n\n";
1367 if (debug_lvl & 2 ) {
1368 if (from == 0) cout <<
"Instantiated: FGFDMExec" << endl;
1369 if (from == 1) cout <<
"Destroyed: FGFDMExec" << endl;
1371 if (debug_lvl & 4 ) {
1373 cout <<
"================== Frame: " << Frame <<
" Time: "
1374 << sim_time <<
" dt: " << dT << endl;
1377 if (debug_lvl & 8 ) {
1379 if (debug_lvl & 16) {
1381 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.
std::string ReadFrom(void) const
Return a string that contains a description of the location where the current XML element was read fr...
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 normint[6]
normal intensity text
static char fgred[6]
red text
static char fgblue[6]
blue text
static char underon[5]
underlines text
static char fgdef[6]
default text
static char reset[5]
resets text properties
static char underoff[6]
underline off
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)
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.
SGPropertyNode_ptr node
The node for the property.
std::string base_string
Name of the property.