47 #include "FGFDMExec.h"
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 "input_output/FGScript.h"
64 #include "input_output/FGXMLFileRead.h"
65 #include "initialization/FGInitialCondition.h"
93 IncrementThenHolding =
false;
94 TimeStepsUntilHold = -1;
100 AircraftPath =
"aircraft";
101 EnginePath =
"engine";
102 SystemsPath =
"systems";
105 char* num = getenv(
"JSBSIM_DEBUG");
106 if (num) debug_lvl = atoi(num);
112 FDMctr = std::make_shared<unsigned int>();
125 Root = root->GetNode();
127 FGPropertyNode* instanceRoot = Root->GetNode(
"fdm/jsbsim", IdFDM,
true);
128 instance = std::make_shared<FGPropertyManager>(instanceRoot);
131 char* num = getenv(
"JSBSIM_DISPERSE");
133 if (atoi(num) != 0) disperse = 1;
137 std::cerr <<
"Could not process JSBSIM_DISPERSIONS environment variable: Assumed NO dispersions." << endl;
145 catch (
const string& msg) {
146 cerr << endl <<
"Caught error: " << msg << endl;
150 cout << endl <<
"Caught error: " << e.what() << endl;
159 typedef int (
FGFDMExec::*iPMF)(void)
const;
162 instance->Tie(
"simulation/disperse",
this, &FGFDMExec::GetDisperse);
163 instance->Tie(
"simulation/randomseed",
this, (iPMF)&FGFDMExec::SRand, &FGFDMExec::SRand);
164 instance->Tie(
"simulation/terminate", (
int *)&Terminate);
165 instance->Tie(
"simulation/pause", (
int *)&holding);
169 instance->Tie(
"simulation/frame", (
int *)&Frame);
170 instance->Tie(
"simulation/trim-completed", (
int *)&trim_completed);
173 Constructing =
false;
183 }
catch (
const string& msg ) {
184 cout <<
"Caught error: " << msg << endl;
187 if (!FDMctr) (*FDMctr)--;
213 bool FGFDMExec::Allocate(
void)
217 Models.resize(eNumStandardModels);
223 Models[eInertial] = std::make_shared<FGInertial>(
this);
228 Models[ePropagate] = std::make_shared<FGPropagate>(
this);
229 Models[eInput] = std::make_shared<FGInput>(
this);
230 Models[eAtmosphere] = std::make_shared<FGStandardAtmosphere>(
this);
231 Models[eWinds] = std::make_shared<FGWinds>(
this);
232 Models[eSystems] = std::make_shared<FGFCS>(
this);
233 Models[eMassBalance] = std::make_shared<FGMassBalance>(
this);
234 Models[eAuxiliary] = std::make_shared<FGAuxiliary>(
this);
235 Models[ePropulsion] = std::make_shared<FGPropulsion>(
this);
236 Models[eAerodynamics] = std::make_shared<FGAerodynamics> (
this);
237 Models[eGroundReactions] = std::make_shared<FGGroundReactions>(
this);
238 Models[eExternalReactions] = std::make_shared<FGExternalReactions>(
this);
239 Models[eBuoyantForces] = std::make_shared<FGBuoyantForces>(
this);
240 Models[eAircraft] = std::make_shared<FGAircraft>(
this);
241 Models[eAccelerations] = std::make_shared<FGAccelerations>(
this);
242 Models[eOutput] = std::make_shared<FGOutput>(
this);
245 Propagate =
static_cast<FGPropagate*
>(Models[ePropagate].get());
246 Inertial =
static_cast<FGInertial*
>(Models[eInertial].get());
247 Input =
static_cast<FGInput*
>(Models[eInput].get());
248 Atmosphere =
static_cast<FGAtmosphere*
>(Models[eAtmosphere].get());
249 Winds =
static_cast<FGWinds*
>(Models[eWinds].get());
250 FCS =
static_cast<FGFCS*
>(Models[eSystems].get());
251 MassBalance =
static_cast<FGMassBalance*
>(Models[eMassBalance].get());
252 Auxiliary =
static_cast<FGAuxiliary*
>(Models[eAuxiliary].get());
253 Propulsion =
static_cast<FGPropulsion*
>(Models[ePropulsion].get());
254 Aerodynamics =
static_cast<FGAerodynamics*
>(Models[eAerodynamics].get());
255 GroundReactions =
static_cast<FGGroundReactions*
>(Models[eGroundReactions].get());
257 BuoyantForces =
static_cast<FGBuoyantForces*
>(Models[eBuoyantForces].get());
258 Aircraft =
static_cast<FGAircraft*
>(Models[eAircraft].get());
259 Accelerations =
static_cast<FGAccelerations*
>(Models[eAccelerations].get());
260 Output =
static_cast<FGOutput*
>(Models[eOutput].get());
263 LoadPlanetConstants();
268 IC = std::make_shared<FGInitialCondition>(
this);
269 IC->bind(instance.get());
280 return static_pointer_cast<FGPropagate>(Models[ePropagate]);
287 return static_pointer_cast<FGInertial>(Models[eInertial]);
294 return static_pointer_cast<FGInput>(Models[eInput]);
299 std::shared_ptr<FGAtmosphere> FGFDMExec::GetAtmosphere(
void)
const
301 return static_pointer_cast<FGAtmosphere>(Models[eAtmosphere]);
308 return static_pointer_cast<FGWinds>(Models[eWinds]);
315 return static_pointer_cast<FGFCS>(Models[eSystems]);
322 return static_pointer_cast<FGMassBalance>(Models[eMassBalance]);
329 return static_pointer_cast<FGAuxiliary>(Models[eAuxiliary]);
336 return static_pointer_cast<FGPropulsion>(Models[ePropulsion]);
343 return static_pointer_cast<FGAerodynamics>(Models[eAerodynamics]);
350 return static_pointer_cast<FGGroundReactions>(Models[eGroundReactions]);
357 return static_pointer_cast<FGExternalReactions>(Models[eExternalReactions]);
364 return static_pointer_cast<FGBuoyantForces>(Models[eBuoyantForces]);
371 return static_pointer_cast<FGAircraft>(Models[eAircraft]);
378 return static_pointer_cast<FGAccelerations>(Models[eAccelerations]);
385 return static_pointer_cast<FGOutput>(Models[eOutput]);
390 void FGFDMExec::InitializeModels(
void)
392 for (
unsigned int i = 0; i < Models.size(); i++) {
394 if (i == eInput || i == eOutput)
continue;
397 Models[i]->InitModel();
403 bool FGFDMExec::DeAllocate(
void)
419 for (
auto &ChildFDM: ChildFDMList) {
420 ChildFDM->AssignState(Propagate);
429 for (
unsigned int i = 0; i < Models.size(); i++) {
431 Models[i]->Run(holding);
434 if (Terminate) success =
false;
441 void FGFDMExec::LoadInputs(
unsigned int idx)
445 Propagate->in.vPQRidot = Accelerations->
GetPQRidot();
446 Propagate->in.vUVWidot = Accelerations->
GetUVWidot();
447 Propagate->in.DeltaT = dT;
452 Inertial->in.Position = Propagate->GetLocation();
456 Atmosphere->in.GeodLatitudeDeg = Propagate->GetGeodLatitudeDeg();
457 Atmosphere->in.LongitudeDeg = Propagate->GetLongitudeDeg();
461 Winds->in.DistanceAGL = Propagate->GetDistanceAGL();
462 Winds->in.Tl2b = Propagate->
GetTl2b();
463 Winds->in.Tw2b = Auxiliary->
GetTw2b();
464 Winds->in.V = Auxiliary->
GetVt();
465 Winds->in.totalDeltaT = dT * Winds->
GetRate();
468 Auxiliary->in.Pressure = Atmosphere->
GetPressure();
469 Auxiliary->in.Density = Atmosphere->
GetDensity();
473 Auxiliary->in.DistanceAGL = Propagate->GetDistanceAGL();
474 Auxiliary->in.Mass = MassBalance->GetMass();
475 Auxiliary->in.Tl2b = Propagate->
GetTl2b();
476 Auxiliary->in.Tb2l = Propagate->
GetTb2l();
477 Auxiliary->in.vPQR = Propagate->
GetPQR();
478 Auxiliary->in.vPQRi = Propagate->
GetPQRi();
479 Auxiliary->in.vPQRidot = Accelerations->
GetPQRidot();
480 Auxiliary->in.vUVW = Propagate->
GetUVW();
481 Auxiliary->in.vUVWdot = Accelerations->
GetUVWdot();
482 Auxiliary->in.vVel = Propagate->
GetVel();
483 Auxiliary->in.vBodyAccel = Accelerations->
GetBodyAccel();
484 Auxiliary->in.ToEyePt = MassBalance->
StructuralToBody(Aircraft->GetXYZep());
485 Auxiliary->in.VRPBody = MassBalance->
StructuralToBody(Aircraft->GetXYZvrp());
487 Auxiliary->in.vFw = Aerodynamics->
GetvFw();
488 Auxiliary->in.vLocation = Propagate->GetLocation();
489 Auxiliary->in.CosTht = Propagate->
GetCosEuler(eTht);
490 Auxiliary->in.SinTht = Propagate->
GetSinEuler(eTht);
491 Auxiliary->in.CosPhi = Propagate->
GetCosEuler(ePhi);
492 Auxiliary->in.SinPhi = Propagate->
GetSinEuler(ePhi);
494 Auxiliary->in.TurbPQR = Winds->GetTurbPQR();
500 Propulsion->in.Pressure = Atmosphere->
GetPressure();
504 Propulsion->in.Density = Atmosphere->
GetDensity();
508 Propulsion->in.Vt = Auxiliary->
GetVt();
509 Propulsion->in.qbar = Auxiliary->Getqbar();
510 Propulsion->in.TAT_c = Auxiliary->GetTAT_C();
511 Propulsion->in.AeroUVW = Auxiliary->GetAeroUVW();
512 Propulsion->in.AeroPQR = Auxiliary->GetAeroPQR();
513 Propulsion->in.alpha = Auxiliary->Getalpha();
514 Propulsion->in.beta = Auxiliary->Getbeta();
515 Propulsion->in.TotalDeltaT = dT * Propulsion->
GetRate();
522 Propulsion->in.H_agl = Propagate->GetDistanceAGL();
523 Propulsion->in.PQRi = Propagate->
GetPQRi();
527 Aerodynamics->in.Alpha = Auxiliary->Getalpha();
528 Aerodynamics->in.Beta = Auxiliary->Getbeta();
529 Aerodynamics->in.Qbar = Auxiliary->Getqbar();
530 Aerodynamics->in.Vt = Auxiliary->
GetVt();
531 Aerodynamics->in.Tb2w = Auxiliary->
GetTb2w();
532 Aerodynamics->in.Tw2b = Auxiliary->
GetTw2b();
535 case eGroundReactions:
537 GroundReactions->in.Vground = Auxiliary->
GetVground();
541 GroundReactions->in.BrakePos = FCS->GetBrakePos();
542 GroundReactions->in.FCSGearPos = FCS->
GetGearPos();
543 GroundReactions->in.EmptyWeight = MassBalance->GetEmptyWeight();
544 GroundReactions->in.Tb2l = Propagate->
GetTb2l();
545 GroundReactions->in.Tec2l = Propagate->
GetTec2l();
546 GroundReactions->in.Tec2b = Propagate->
GetTec2b();
547 GroundReactions->in.PQR = Propagate->
GetPQR();
548 GroundReactions->in.UVW = Propagate->
GetUVW();
549 GroundReactions->in.DistanceAGL = Propagate->GetDistanceAGL();
551 GroundReactions->in.TotalDeltaT = dT * GroundReactions->
GetRate();
552 GroundReactions->in.WOW = GroundReactions->GetWOW();
553 GroundReactions->in.Location = Propagate->GetLocation();
554 GroundReactions->in.vXYZcg = MassBalance->
GetXYZcg();
556 case eExternalReactions:
560 BuoyantForces->in.Density = Atmosphere->
GetDensity();
561 BuoyantForces->in.Pressure = Atmosphere->
GetPressure();
563 BuoyantForces->in.gravity = Inertial->GetGravity().
Magnitude();
567 MassBalance->in.GasMass = BuoyantForces->
GetGasMass();
569 MassBalance->in.TanksWeight = Propulsion->GetTanksWeight();
570 MassBalance->in.TanksMoment = Propulsion->GetTanksMoment();
571 MassBalance->in.TankInertia = Propulsion->CalculateTankInertias();
572 MassBalance->in.WOW = GroundReactions->GetWOW();
575 Aircraft->in.AeroForce = Aerodynamics->
GetForces();
576 Aircraft->in.PropForce = Propulsion->GetForces();
577 Aircraft->in.GroundForce = GroundReactions->GetForces();
578 Aircraft->in.ExternalForce = ExternalReactions->
GetForces();
579 Aircraft->in.BuoyantForce = BuoyantForces->
GetForces();
580 Aircraft->in.AeroMoment = Aerodynamics->
GetMoments();
581 Aircraft->in.PropMoment = Propulsion->GetMoments();
582 Aircraft->in.GroundMoment = GroundReactions->GetMoments();
583 Aircraft->in.ExternalMoment = ExternalReactions->
GetMoments();
584 Aircraft->in.BuoyantMoment = BuoyantForces->
GetMoments();
587 Accelerations->in.
J = MassBalance->
GetJ();
593 Accelerations->in.
Moment = Aircraft->GetMoments();
594 Accelerations->in.
GroundMoment = GroundReactions->GetMoments();
595 Accelerations->in.
Force = Aircraft->GetForces();
596 Accelerations->in.
GroundForce = GroundReactions->GetForces();
597 Accelerations->in.
vGravAccel = Inertial->GetGravity();
602 Accelerations->in.
DeltaT = dT;
603 Accelerations->in.
Mass = MassBalance->GetMass();
604 Accelerations->in.
MultipliersList = GroundReactions->GetMultipliersList();
615 void FGFDMExec::LoadPlanetConstants(
void)
617 Propagate->in.vOmegaPlanet = Inertial->GetOmegaPlanet();
618 Accelerations->in.
vOmegaPlanet = Inertial->GetOmegaPlanet();
619 Propagate->in.SemiMajor = Inertial->GetSemimajor();
620 Propagate->in.SemiMinor = Inertial->GetSemiminor();
621 Propagate->in.GM = Inertial->GetGM();
622 Auxiliary->in.StandardGravity = Inertial->GetStandardGravity();
623 Auxiliary->in.StdDaySLsoundspeed = Atmosphere->StdDaySLsoundspeed;
628 void FGFDMExec::LoadModelConstants(
void)
631 Aerodynamics->in.Wingarea = Aircraft->
GetWingArea();
632 Aerodynamics->in.Wingchord = Aircraft->
Getcbar();
633 Aerodynamics->in.Wingincidence = Aircraft->GetWingIncidence();
634 Aerodynamics->in.Wingspan = Aircraft->
GetWingSpan();
636 Auxiliary->in.Wingchord = Aircraft->
Getcbar();
637 GroundReactions->in.vXYZcg = MassBalance->
GetXYZcg();
648 Models[eInput]->InitModel();
649 Models[eOutput]->InitModel();
652 Propagate->InitializeDerivatives();
656 MassBalance->GetMassPropertiesReport(0);
659 <<
"End of vehicle configuration loading." << endl
660 <<
"-------------------------------------------------------------------------------"
661 <<
reset << std::setprecision(6) << endl;
664 for (
unsigned int n=0; n < Propulsion->
GetNumEngines(); ++n) {
665 if (IC->IsEngineRunning(n)) {
668 }
catch (
const string& str) {
682 Propagate->SetInitialState(FGIC);
691 if (Constructing)
return;
700 Script->ResetEvents();
704 if (!(mode & DONT_EXECUTE_RUN_IC))
715 Propagate->in.vPQRidot = Accelerations->
GetPQRidot();
716 Propagate->in.vUVWidot = Accelerations->
GetUVWidot();
725 vector <string> FDMList;
728 for (
auto &ChildFDM: ChildFDMList)
729 FDMList.push_back(ChildFDM->exec->GetAircraft()->GetAircraftName());
737 const SGPath& initfile)
739 Script = std::make_shared<FGScript>(
this);
740 return Script->LoadScript(GetFullPath(script), deltaT, initfile);
747 SGPath PlanetFileName;
749 if(useAircraftPath && PlanetPath.isRelative()) {
750 PlanetFileName = AircraftPath/PlanetPath.utf8Str();
752 PlanetFileName = PlanetPath;
756 Element* document = XMLFileRead.LoadXMLDocument(PlanetFileName);
761 s <<
"File: " << PlanetFileName <<
" could not be read.";
762 cerr << s.str() << endl;
766 if (document->
GetName() !=
"planet") {
768 s <<
"File: " << PlanetFileName <<
" is not a planet file.";
769 cerr << s.str() << endl;
776 cerr << endl <<
"Planet element has problems in file " << PlanetFileName << endl;
785 bool result = Models[eInertial]->Load(element);
789 LoadPlanetConstants();
795 if (atm_element && atm_element->
HasAttribute(
"model")) {
797 if (model ==
"MSIS") {
799 instance->Unbind(Models[eAtmosphere]);
800 Models[eAtmosphere] = std::make_shared<FGMSIS>(
this);
801 Atmosphere =
static_cast<FGAtmosphere*
>(Models[eAtmosphere].get());
804 LoadInputs(eAtmosphere);
805 Atmosphere->InitModel();
806 result = Atmosphere->Load(atm_element);
808 cerr << endl <<
"Incorrect definition of <atmosphere>." << endl;
822 const SGPath& SystemsPath,
const string& model,
825 FGFDMExec::AircraftPath = GetFullPath(AircraftPath);
826 FGFDMExec::EnginePath = GetFullPath(EnginePath);
827 FGFDMExec::SystemsPath = GetFullPath(SystemsPath);
836 SGPath aircraftCfgFileName;
841 if( AircraftPath.isNull() || EnginePath.isNull() || SystemsPath.isNull()) {
842 cerr <<
"Error: attempted to load aircraft with undefined "
843 <<
"aircraft, engine, and system paths" << endl;
847 FullAircraftPath = AircraftPath;
848 if (addModelToPath) FullAircraftPath.append(model);
849 aircraftCfgFileName = FullAircraftPath/(model +
".xml");
856 int saved_debug_lvl = debug_lvl;
858 Element *document = XMLFileRead.LoadXMLDocument(aircraftCfgFileName);
861 if (IsChild) debug_lvl = 0;
863 ReadPrologue(document);
865 if (IsChild) debug_lvl = saved_debug_lvl;
870 result = ReadFileHeader(element);
872 cerr << endl <<
"Aircraft fileheader element has problems in file " << aircraftCfgFileName << endl;
877 if (IsChild) debug_lvl = 0;
884 cerr << endl <<
"Planet element has problems in file " << aircraftCfgFileName << endl;
892 result = Models[eAircraft]->Load(element);
894 cerr << endl <<
"Aircraft metrics element has problems in file " << aircraftCfgFileName << endl;
898 cerr << endl <<
"No metrics element was found in the aircraft config file." << endl;
905 result = Models[eMassBalance]->Load(element);
907 cerr << endl <<
"Aircraft mass_balance element has problems in file " << aircraftCfgFileName << endl;
911 cerr << endl <<
"No mass_balance element was found in the aircraft config file." << endl;
916 element = document->
FindElement(
"ground_reactions");
918 result = Models[eGroundReactions]->Load(element);
921 <<
"Aircraft ground_reactions element has problems in file "
922 << aircraftCfgFileName << endl;
926 cerr << endl <<
"No ground_reactions element was found in the aircraft config file." << endl;
931 element = document->
FindElement(
"external_reactions");
933 result = Models[eExternalReactions]->Load(element);
935 cerr << endl <<
"Aircraft external_reactions element has problems in file " << aircraftCfgFileName << endl;
943 result = Models[eBuoyantForces]->Load(element);
945 cerr << endl <<
"Aircraft buoyant_forces element has problems in file " << aircraftCfgFileName << endl;
953 result = Propulsion->
Load(element);
955 cerr << endl <<
"Aircraft propulsion element has problems in file " << aircraftCfgFileName << endl;
965 result = Models[eSystems]->Load(element);
967 cerr << endl <<
"Aircraft system element has problems in file " << aircraftCfgFileName << endl;
976 result = Models[eSystems]->Load(element);
978 cerr << endl <<
"Aircraft autopilot element has problems in file " << aircraftCfgFileName << endl;
986 result = Models[eSystems]->Load(element);
988 cerr << endl <<
"Aircraft flight_control element has problems in file " << aircraftCfgFileName << endl;
996 result = Models[eAerodynamics]->Load(element);
998 cerr << endl <<
"Aircraft aerodynamics element has problems in file " << aircraftCfgFileName << endl;
1002 cerr << endl <<
"No expected aerodynamics element was found in the aircraft config file." << endl;
1008 if (!Input->
Load(element))
1018 if (!Output->
Load(element))
1027 result = ReadChild(element);
1029 cerr << endl <<
"Aircraft child element has problems in file " << aircraftCfgFileName << endl;
1036 LoadModelConstants();
1040 if (IsChild) debug_lvl = saved_debug_lvl;
1044 <<
" JSBSim failed to open the configuration file: " << aircraftCfgFileName
1048 for (
unsigned int i=0; i< Models.size(); i++) LoadInputs(i);
1053 masterPCS.
node = Root;
1062 string FGFDMExec::GetPropulsionTankReport()
const
1064 return Propulsion->GetPropulsionTankReport();
1071 auto pcsNew = std::make_unique<struct PropertyCatalogStructure>();
1073 for (
int i=0; i<pcs->
node->nChildren(); i++) {
1075 pcsNew->base_string = pcs->
base_string +
"/" + pcs->
node->getChild(i)->getNameString();
1076 int node_idx = pcs->
node->getChild(i)->getIndex();
1077 if (node_idx != 0) {
1078 pcsNew->base_string = CreateIndexedPropertyName(pcsNew->base_string, node_idx);
1080 if (pcs->
node->getChild(i)->nChildren() == 0) {
1081 if (pcsNew->base_string.substr(0,12) ==
string(
"/fdm/jsbsim/")) {
1082 pcsNew->base_string = pcsNew->base_string.erase(0,12);
1084 if (pcs->
node->getChild(i)->getAttribute(SGPropertyNode::READ)) access=
"R";
1085 if (pcs->
node->getChild(i)->getAttribute(SGPropertyNode::WRITE)) access+=
"W";
1086 PropertyCatalog.push_back(pcsNew->base_string+
" ("+access+
")");
1099 for (
auto &catalogElm: PropertyCatalog) {
1100 if (catalogElm.find(in) != string::npos) results += catalogElm + end_of_line;
1102 if (results.empty())
return "No matches found"+end_of_line;
1108 void FGFDMExec::PrintPropertyCatalog(
void)
1112 << modelName <<
reset << endl << endl;
1113 for (
auto &catalogElm: PropertyCatalog)
1114 cout <<
" " << catalogElm << endl;
1119 void FGFDMExec::PrintSimulationConfiguration(
void)
const
1121 cout << endl <<
"Simulation Configuration" << endl <<
"------------------------" << endl;
1122 cout << MassBalance->GetName() << endl;
1123 cout << GroundReactions->GetName() << endl;
1124 cout << Aerodynamics->GetName() << endl;
1125 cout << Propulsion->GetName() << endl;
1130 bool FGFDMExec::ReadFileHeader(Element* el)
1134 if (debug_lvl == 0)
return result;
1137 cout << endl <<
highint <<
fgblue <<
"Reading child model: " << IdFDM <<
reset << endl << endl;
1140 if (el->FindElement(
"description"))
1141 cout <<
" Description: " << el->FindElement(
"description")->GetDataLine() << endl;
1142 if (el->FindElement(
"author"))
1143 cout <<
" Model Author: " << el->FindElement(
"author")->GetDataLine() << endl;
1144 if (el->FindElement(
"filecreationdate"))
1145 cout <<
" Creation Date: " << el->FindElement(
"filecreationdate")->GetDataLine() << endl;
1146 if (el->FindElement(
"version"))
1147 cout <<
" Version: " << el->FindElement(
"version")->GetDataLine() << endl;
1154 bool FGFDMExec::ReadPrologue(Element* el)
1158 if (!el)
return false;
1160 string AircraftName = el->GetAttributeValue(
"name");
1161 Aircraft->SetAircraftName(AircraftName);
1163 if (debug_lvl & 1) cout <<
underon <<
"Reading Aircraft Configuration File"
1166 CFGVersion = el->GetAttributeValue(
"version");
1167 Release = el->GetAttributeValue(
"release");
1170 cout <<
" Version: " <<
highint << CFGVersion
1172 if (CFGVersion != needed_cfg_version) {
1173 cerr << endl <<
fgred <<
"YOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT."
1174 " RESULTS WILL BE UNPREDICTABLE !!" << endl;
1175 cerr <<
"Current version needed is: " << needed_cfg_version << endl;
1176 cerr <<
" You have version: " << CFGVersion << endl <<
fgdef << endl;
1180 if (Release ==
"ALPHA" && (debug_lvl & 1)) {
1181 cout << endl << endl
1182 <<
highint <<
"This aircraft model is an " <<
fgred << Release
1184 <<
"This aircraft model may not even properly load, and probably"
1185 <<
" will not fly as expected." << endl << endl
1186 <<
fgred <<
highint <<
"Use this model for development purposes ONLY!!!"
1188 }
else if (Release ==
"BETA" && (debug_lvl & 1)) {
1189 cout << endl << endl
1190 <<
highint <<
"This aircraft model is a " <<
fgred << Release
1192 <<
"This aircraft model probably will not fly as expected." << endl << endl
1193 <<
fgblue <<
highint <<
"Use this model for development purposes ONLY!!!"
1195 }
else if (Release ==
"PRODUCTION" && (debug_lvl & 1)) {
1196 cout << endl << endl
1197 <<
highint <<
"This aircraft model is a " <<
fgblue << Release
1199 }
else if (debug_lvl & 1) {
1200 cout << endl << endl
1201 <<
highint <<
"This aircraft model is an " <<
fgred << Release
1203 <<
"This aircraft model may not even properly load, and probably"
1204 <<
" will not fly as expected." << endl << endl
1205 <<
fgred <<
highint <<
"Use this model for development purposes ONLY!!!"
1214 bool FGFDMExec::ReadChild(Element* el)
1224 auto child = std::make_shared<childData>();
1226 auto pm = std::make_unique<FGPropertyManager>(Root);
1227 child->exec = std::make_unique<FGFDMExec>(pm.get(), FDMctr);
1228 child->exec->SetChild(
true);
1230 string childAircraft = el->GetAttributeValue(
"name");
1231 string sMated = el->GetAttributeValue(
"mated");
1232 if (sMated ==
"false") child->mated =
false;
1233 string sInternal = el->GetAttributeValue(
"internal");
1234 if (sInternal ==
"true") child->internal =
true;
1236 child->exec->SetAircraftPath( AircraftPath );
1237 child->exec->SetEnginePath( EnginePath );
1238 child->exec->SetSystemsPath( SystemsPath );
1239 child->exec->LoadModel(childAircraft);
1241 Element* location = el->FindElement(
"location");
1243 child->Loc = location->FindElementTripletConvertTo(
"IN");
1245 const string s(
" No location was found for this child object!");
1247 << s <<
reset << endl;
1248 throw BaseException(s);
1251 Element* orientation = el->FindElement(
"orient");
1253 child->Orient = orientation->FindElementTripletConvertTo(
"RAD");
1254 }
else if (debug_lvl > 0) {
1255 cerr << endl <<
highint <<
" No orientation was found for this child object! Assuming 0,0,0." <<
reset << endl;
1258 ChildFDMList.push_back(child);
1267 Trim = std::make_shared<FGTrim>(
this,tNone);
1276 if( IncrementThenHolding ) {
1278 if (TimeStepsUntilHold == 0) {
1285 IncrementThenHolding =
false;
1286 TimeStepsUntilHold--;
1288 }
else if ( TimeStepsUntilHold > 0 ) {
1290 TimeStepsUntilHold--;
1299 if (Constructing)
return;
1301 if (mode < 0 || mode > JSBSim::tNone)
1302 throw(
"Illegal trimming mode!");
1304 FGTrim trim(
this, (JSBSim::TrimMode)mode);
1305 bool success = trim.DoTrim();
1318 void FGFDMExec::SRand(
int sr)
1321 RandomGenerator->seed(RandomSeed);
1343 void FGFDMExec::Debug(
int from)
1345 if (debug_lvl <= 0)
return;
1347 if (debug_lvl & 1 && IdFDM == 0) {
1350 <<
"JSBSim Flight Dynamics Model v" << JSBSim_version << endl;
1351 cout <<
" [JSBSim-ML v" << needed_cfg_version <<
"]\n\n";
1352 cout <<
"JSBSim startup beginning ...\n\n";
1353 if (disperse == 1) cout <<
"Dispersions are ON." << endl << endl;
1354 }
else if (from == 3) {
1355 cout <<
"\n\nJSBSim startup complete\n\n";
1358 if (debug_lvl & 2 ) {
1359 if (from == 0) cout <<
"Instantiated: FGFDMExec" << endl;
1360 if (from == 1) cout <<
"Destroyed: FGFDMExec" << endl;
1362 if (debug_lvl & 4 ) {
1364 cout <<
"================== Frame: " << Frame <<
" Time: "
1365 << sim_time <<
" dt: " << dT << endl;
1368 if (debug_lvl & 8 ) {
1370 if (debug_lvl & 16) {
1372 if (debug_lvl & 64) {
Element * FindElement(const std::string &el="")
Searches for a specified element.
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.
const std::string & GetName(void) const
Retrieves the element name.
Handles the calculation of accelerations.
const FGColumnVector3 & GetPQRidot(void) const
Retrieves the axis angular acceleration vector 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 & GetUVWidot(void) const
Retrieves the body axis acceleration in the ECI frame.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
Encapsulates the aerodynamic calculations.
const FGColumnVector3 & GetvFw(void) const
Retrieves the aerodynamic forces in the wind axes.
const FGColumnVector3 & GetMoments(void) const
Gets the total aerodynamic moment vector about the CG.
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.
const std::string & GetAircraftName(void) const
Gets the aircraft name.
double GetWingArea(void) const
Gets the wing area.
const FGColumnVector3 & GetXYZrp(void) const
Gets the the aero reference point (RP) coordinates.
double GetWingSpan(void) const
Gets the wing span.
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.
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.
const FGMatrix33 & GetTb2w(void) const
Calculates and returns the body-to-wind axis transformation matrix.
double GetVt(void) const
Gets the magnitude of total vehicle velocity including wind effects in feet per second.
const FGMatrix33 & GetTw2b(void) const
Calculates and returns the wind-to-body axis transformation matrix.
Encapsulates the Buoyant forces calculations.
const FGMatrix33 & GetGasMassInertia(void)
Gets the total moments of inertia for the gas mass in the body frame.
const FGColumnVector3 & GetMoments(void) const
Gets the total Buoyancy moment vector.
const FGColumnVector3 & GetForces(void) const
Gets the total Buoyant force vector.
double GetGasMass(void) const
Gets the total gas mass.
const FGColumnVector3 & GetGasMassMoment(void)
Gets the total moment from the gas mass.
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.
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.
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 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
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.
const FGMatrix33 & GetJinv(void) const
Returns the inverse of the inertia matrix expressed in the body frame.
FGColumnVector3 StructuralToBody(const FGColumnVector3 &r) const
Conversion from the structural frame to 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=SGPath())
Load the output directives and adds a new output instance to the Output Manager list.
Models the EOM and integration/propagation of state.
const FGColumnVector3 & GetUVW(void) const
Retrieves the body frame vehicle velocity vector.
const FGColumnVector3 & GetVel(void) const
Retrieves the velocity vector.
const FGMatrix33 & GetTec2i(void) const
Retrieves the ECEF-to-ECI transformation matrix.
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.
const FGMatrix33 & GetTec2l(void) const
Retrieves the ECEF-to-local transformation matrix.
double GetSinEuler(int idx) const
Retrieves the sine of a vehicle Euler angle component.
double GetAltitudeASL(void) const
Returns the current altitude above sea level.
const FGMatrix33 & GetTb2l(void) const
Retrieves the body-to-local transformation matrix.
const FGMatrix33 & GetTb2i(void) const
Retrieves the body-to-ECI transformation matrix.
const FGColumnVector3 & GetInertialPosition(void) const
Retrieves the inertial position vector.
const FGColumnVector3 & GetPQRi(void) const
Retrieves the body angular rates vector, relative to the ECI (inertial) frame.
const FGMatrix33 & GetTec2b(void) const
Retrieves the ECEF-to-body transformation matrix.
const FGMatrix33 & GetTl2b(void) const
Retrieves the local-to-body transformation matrix.
double GetCosEuler(int idx) const
Retrieves the cosine of a vehicle Euler angle component.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
Class wrapper for property handling.
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.
FGPropertyNode_ptr node
The node for the property.
std::string base_string
Name of the property.