JSBSim Flight Dynamics Model  1.2.0 (05 Nov 2023)
An Open Source Flight Dynamics and Control Software Library in C++
FGFDMExec.cpp
1 
2 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 
4  Module: FGFDMExec.cpp
5  Author: Jon S. Berndt
6  Date started: 11/17/98
7  Purpose: Schedules and runs the model routines.
8 
9  ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
10 
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU Lesser General Public License as published by the Free
13  Software Foundation; either version 2 of the License, or (at your option) any
14  later version.
15 
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19  details.
20 
21  You should have received a copy of the GNU Lesser General Public License along
22  with this program; if not, write to the Free Software Foundation, Inc., 59
23  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25  Further information about the GNU Lesser General Public License can also be
26  found on the world wide web at http://www.gnu.org.
27 
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 
31 This class wraps up the simulation scheduling routines.
32 
33 HISTORY
34 --------------------------------------------------------------------------------
35 11/17/98 JSB Created
36 
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 COMMENTS, REFERENCES, and NOTES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 INCLUDES
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44 
45 #include <iomanip>
46 
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"
66 
67 using namespace std;
68 
69 namespace JSBSim {
70 
71 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 CLASS IMPLEMENTATION
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
74 
75 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 // Constructor
77 
78 FGFDMExec::FGFDMExec(FGPropertyManager* root, std::shared_ptr<unsigned int> fdmctr)
79  : RandomSeed(0), RandomGenerator(make_shared<RandomNumberGenerator>(RandomSeed)),
80  FDMctr(fdmctr)
81 {
82  Frame = 0;
83  disperse = 0;
84 
85  RootDir = "";
86 
87  modelLoaded = false;
88  IsChild = false;
89  holding = false;
90  Terminate = false;
91  HoldDown = false;
92 
93  IncrementThenHolding = false; // increment then hold is off by default
94  TimeStepsUntilHold = -1;
95 
96  sim_time = 0.0;
97  dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
98  // run in standalone mode with no initialization file.
99 
100  AircraftPath = "aircraft";
101  EnginePath = "engine";
102  SystemsPath = "systems";
103 
104  try {
105  char* num = getenv("JSBSIM_DEBUG");
106  if (num) debug_lvl = atoi(num); // set debug level
107  } catch (...) { // if error set to 1
108  debug_lvl = 1;
109  }
110 
111  if (!FDMctr) {
112  FDMctr = std::make_shared<unsigned int>(); // Create and initialize the child FDM counter
113  *FDMctr = 0;
114  }
115 
116  // Store this FDM's ID
117  IdFDM = *FDMctr; // The main (parent) JSBSim instance is always the "zeroth"
118 
119  // Prepare FDMctr for the next child FDM id
120  (*FDMctr)++; // instance. "child" instances are loaded last.
121 
122  if (root == nullptr) // Then this is the root FDM
123  Root = new FGPropertyNode();
124  else
125  Root = root->GetNode();
126 
127  FGPropertyNode* instanceRoot = Root->GetNode("fdm/jsbsim", IdFDM, true);
128  instance = std::make_shared<FGPropertyManager>(instanceRoot);
129 
130  try {
131  char* num = getenv("JSBSIM_DISPERSE");
132  if (num) {
133  if (atoi(num) != 0) disperse = 1; // set dispersions on
134  }
135  } catch (...) { // if error set to false
136  disperse = 0;
137  std::cerr << "Could not process JSBSIM_DISPERSIONS environment variable: Assumed NO dispersions." << endl;
138  }
139 
140  Debug(0);
141  // this is to catch errors in binding member functions to the property tree.
142  try {
143  Allocate();
144  }
145  catch (const string& msg) {
146  cerr << endl << "Caught error: " << msg << endl;
147  throw;
148  }
149  catch (const BaseException& e) {
150  cout << endl << "Caught error: " << e.what() << endl;
151  throw;
152  }
153 
154  trim_status = false;
155  ta_mode = 99;
156  trim_completed = 0;
157 
158  Constructing = true;
159  typedef int (FGFDMExec::*iPMF)(void) const;
160  instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim);
161  instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions);
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);
166  instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime);
167  instance->Tie("simulation/dt", this, &FGFDMExec::GetDeltaT);
168  instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel);
169  instance->Tie("simulation/frame", (int *)&Frame);
170  instance->Tie("simulation/trim-completed", (int *)&trim_completed);
171  instance->Tie("forces/hold-down", this, &FGFDMExec::GetHoldDown, &FGFDMExec::SetHoldDown);
172 
173  Constructing = false;
174 }
175 
176 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 
179 {
180  try {
181  Unbind();
182  DeAllocate();
183  } catch (const string& msg ) {
184  cout << "Caught error: " << msg << endl;
185  }
186 
187  if (!FDMctr) (*FDMctr)--;
188 
189  Debug(1);
190 }
191 
192 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193 
194 double FGFDMExec::Setsim_time(double cur_time) {
195  sim_time = cur_time;
196  Inertial->SetTime(sim_time);
197  return sim_time;
198 }
199 
200 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 
202 double FGFDMExec::IncrTime(void) {
203  if (!holding && !IntegrationSuspended()) {
204  sim_time += dT;
205  Inertial->SetTime(sim_time);
206  Frame++;
207  }
208  return sim_time;
209 }
210 
211 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212 
213 bool FGFDMExec::Allocate(void)
214 {
215  bool result=true;
216 
217  Models.resize(eNumStandardModels);
218 
219  // First build the inertial model since some other models are relying on
220  // the inertial model and the ground callback to build themselves.
221  // Note that this does not affect the order in which the models will be
222  // executed later.
223  Models[eInertial] = std::make_shared<FGInertial>(this);
224 
225  // See the eModels enum specification in the header file. The order of the
226  // enums specifies the order of execution. The Models[] vector is the primary
227  // storage array for the list of models.
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);
243 
244  // Assign the Model shortcuts for internal executive use only.
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());
256  ExternalReactions = static_cast<FGExternalReactions*>(Models[eExternalReactions].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());
261 
262  // Initialize planet (environment) constants
263  LoadPlanetConstants();
264 
265  // Initialize models
266  InitializeModels();
267 
268  IC = std::make_shared<FGInitialCondition>(this);
269  IC->bind(instance.get());
270 
271  modelLoaded = false;
272 
273  return result;
274 }
275 
276 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277 
278 std::shared_ptr<FGPropagate> FGFDMExec::GetPropagate(void) const
279 {
280  return static_pointer_cast<FGPropagate>(Models[ePropagate]);
281 }
282 
283 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 
285 std::shared_ptr<FGInertial> FGFDMExec::GetInertial(void) const
286 {
287  return static_pointer_cast<FGInertial>(Models[eInertial]);
288 }
289 
290 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 
292 std::shared_ptr<FGInput> FGFDMExec::GetInput(void) const
293 {
294  return static_pointer_cast<FGInput>(Models[eInput]);
295 }
296 
297 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 
299 std::shared_ptr<FGAtmosphere> FGFDMExec::GetAtmosphere(void) const
300 {
301  return static_pointer_cast<FGAtmosphere>(Models[eAtmosphere]);
302 }
303 
304 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 
306 std::shared_ptr<FGWinds> FGFDMExec::GetWinds(void) const
307 {
308  return static_pointer_cast<FGWinds>(Models[eWinds]);
309 }
310 
311 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312 
313 std::shared_ptr<FGFCS> FGFDMExec::GetFCS(void) const
314 {
315  return static_pointer_cast<FGFCS>(Models[eSystems]);
316 }
317 
318 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 
320 std::shared_ptr<FGMassBalance> FGFDMExec::GetMassBalance(void) const
321 {
322  return static_pointer_cast<FGMassBalance>(Models[eMassBalance]);
323 }
324 
325 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326 
327 std::shared_ptr<FGAuxiliary> FGFDMExec::GetAuxiliary(void) const
328 {
329  return static_pointer_cast<FGAuxiliary>(Models[eAuxiliary]);
330 }
331 
332 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333 
334 std::shared_ptr<FGPropulsion> FGFDMExec::GetPropulsion(void) const
335 {
336  return static_pointer_cast<FGPropulsion>(Models[ePropulsion]);
337 }
338 
339 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 
341 std::shared_ptr<FGAerodynamics> FGFDMExec::GetAerodynamics(void) const
342 {
343  return static_pointer_cast<FGAerodynamics>(Models[eAerodynamics]);
344 }
345 
346 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 
348 std::shared_ptr<FGGroundReactions> FGFDMExec::GetGroundReactions(void) const
349 {
350  return static_pointer_cast<FGGroundReactions>(Models[eGroundReactions]);
351 }
352 
353 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354 
355 std::shared_ptr<FGExternalReactions> FGFDMExec::GetExternalReactions(void) const
356 {
357  return static_pointer_cast<FGExternalReactions>(Models[eExternalReactions]);
358 }
359 
360 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361 
362 std::shared_ptr<FGBuoyantForces> FGFDMExec::GetBuoyantForces(void) const
363 {
364  return static_pointer_cast<FGBuoyantForces>(Models[eBuoyantForces]);
365 }
366 
367 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368 
369 std::shared_ptr<FGAircraft> FGFDMExec::GetAircraft(void) const
370 {
371  return static_pointer_cast<FGAircraft>(Models[eAircraft]);
372 }
373 
374 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375 
376 std::shared_ptr<FGAccelerations> FGFDMExec::GetAccelerations(void) const
377 {
378  return static_pointer_cast<FGAccelerations>(Models[eAccelerations]);
379 }
380 
381 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382 
383 std::shared_ptr<FGOutput> FGFDMExec::GetOutput(void) const
384 {
385  return static_pointer_cast<FGOutput>(Models[eOutput]);
386 }
387 
388 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 
390 void FGFDMExec::InitializeModels(void)
391 {
392  for (unsigned int i = 0; i < Models.size(); i++) {
393  // The Input/Output models must not be initialized prior to IC loading
394  if (i == eInput || i == eOutput) continue;
395 
396  LoadInputs(i);
397  Models[i]->InitModel();
398  }
399 }
400 
401 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402 
403 bool FGFDMExec::DeAllocate(void)
404 {
405 
406  Models.clear();
407  modelLoaded = false;
408  return modelLoaded;
409 }
410 
411 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 
413 bool FGFDMExec::Run(void)
414 {
415  bool success=true;
416 
417  Debug(2);
418 
419  for (auto &ChildFDM: ChildFDMList) {
420  ChildFDM->AssignState(Propagate); // Transfer state to the child FDM
421  ChildFDM->Run();
422  }
423 
424  IncrTime();
425 
426  // returns true if success, false if complete
427  if (Script && !IntegrationSuspended()) success = Script->RunScript();
428 
429  for (unsigned int i = 0; i < Models.size(); i++) {
430  LoadInputs(i);
431  Models[i]->Run(holding);
432  }
433 
434  if (Terminate) success = false;
435 
436  return success;
437 }
438 
439 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 
441 void FGFDMExec::LoadInputs(unsigned int idx)
442 {
443  switch(idx) {
444  case ePropagate:
445  Propagate->in.vPQRidot = Accelerations->GetPQRidot();
446  Propagate->in.vUVWidot = Accelerations->GetUVWidot();
447  Propagate->in.DeltaT = dT;
448  break;
449  case eInput:
450  break;
451  case eInertial:
452  Inertial->in.Position = Propagate->GetLocation();
453  break;
454  case eAtmosphere:
455  Atmosphere->in.altitudeASL = Propagate->GetAltitudeASL();
456  Atmosphere->in.GeodLatitudeDeg = Propagate->GetGeodLatitudeDeg();
457  Atmosphere->in.LongitudeDeg = Propagate->GetLongitudeDeg();
458  break;
459  case eWinds:
460  Winds->in.AltitudeASL = Propagate->GetAltitudeASL();
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();
466  break;
467  case eAuxiliary:
468  Auxiliary->in.Pressure = Atmosphere->GetPressure();
469  Auxiliary->in.Density = Atmosphere->GetDensity();
470  Auxiliary->in.Temperature = Atmosphere->GetTemperature();
471  Auxiliary->in.SoundSpeed = Atmosphere->GetSoundSpeed();
472  Auxiliary->in.KinematicViscosity = Atmosphere->GetKinematicViscosity();
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());
486  Auxiliary->in.RPBody = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
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);
493  Auxiliary->in.TotalWindNED = Winds->GetTotalWindNED();
494  Auxiliary->in.TurbPQR = Winds->GetTurbPQR();
495  break;
496  case eSystems:
497  // Dynamic inputs come into the components that FCS manages through properties
498  break;
499  case ePropulsion:
500  Propulsion->in.Pressure = Atmosphere->GetPressure();
501  Propulsion->in.PressureRatio = Atmosphere->GetPressureRatio();
502  Propulsion->in.Temperature = Atmosphere->GetTemperature();
503  Propulsion->in.DensityRatio = Atmosphere->GetDensityRatio();
504  Propulsion->in.Density = Atmosphere->GetDensity();
505  Propulsion->in.Soundspeed = Atmosphere->GetSoundSpeed();
506  Propulsion->in.TotalPressure = Auxiliary->GetTotalPressure();
507  Propulsion->in.Vc = Auxiliary->GetVcalibratedKTS();
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();
516  Propulsion->in.ThrottlePos = FCS->GetThrottlePos();
517  Propulsion->in.MixturePos = FCS->GetMixturePos();
518  Propulsion->in.ThrottleCmd = FCS->GetThrottleCmd();
519  Propulsion->in.MixtureCmd = FCS->GetMixtureCmd();
520  Propulsion->in.PropAdvance = FCS->GetPropAdvance();
521  Propulsion->in.PropFeather = FCS->GetPropFeather();
522  Propulsion->in.H_agl = Propagate->GetDistanceAGL();
523  Propulsion->in.PQRi = Propagate->GetPQRi();
524 
525  break;
526  case eAerodynamics:
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();
533  Aerodynamics->in.RPBody = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
534  break;
535  case eGroundReactions:
536  // There are no external inputs to this model.
537  GroundReactions->in.Vground = Auxiliary->GetVground();
538  GroundReactions->in.VcalibratedKts = Auxiliary->GetVcalibratedKTS();
539  GroundReactions->in.Temperature = Atmosphere->GetTemperature();
540  GroundReactions->in.TakeoffThrottle = (FCS->GetThrottlePos().size() > 0) ? (FCS->GetThrottlePos(0) > 0.90) : false;
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();
550  GroundReactions->in.DistanceASL = Propagate->GetAltitudeASL();
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();
555  break;
556  case eExternalReactions:
557  // There are no external inputs to this model.
558  break;
559  case eBuoyantForces:
560  BuoyantForces->in.Density = Atmosphere->GetDensity();
561  BuoyantForces->in.Pressure = Atmosphere->GetPressure();
562  BuoyantForces->in.Temperature = Atmosphere->GetTemperature();
563  BuoyantForces->in.gravity = Inertial->GetGravity().Magnitude();
564  break;
565  case eMassBalance:
566  MassBalance->in.GasInertia = BuoyantForces->GetGasMassInertia();
567  MassBalance->in.GasMass = BuoyantForces->GetGasMass();
568  MassBalance->in.GasMoment = BuoyantForces->GetGasMassMoment();
569  MassBalance->in.TanksWeight = Propulsion->GetTanksWeight();
570  MassBalance->in.TanksMoment = Propulsion->GetTanksMoment();
571  MassBalance->in.TankInertia = Propulsion->CalculateTankInertias();
572  MassBalance->in.WOW = GroundReactions->GetWOW();
573  break;
574  case eAircraft:
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();
585  break;
586  case eAccelerations:
587  Accelerations->in.J = MassBalance->GetJ();
588  Accelerations->in.Jinv = MassBalance->GetJinv();
589  Accelerations->in.Ti2b = Propagate->GetTi2b();
590  Accelerations->in.Tb2i = Propagate->GetTb2i();
591  Accelerations->in.Tec2b = Propagate->GetTec2b();
592  Accelerations->in.Tec2i = Propagate->GetTec2i();
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();
598  Accelerations->in.vPQRi = Propagate->GetPQRi();
599  Accelerations->in.vPQR = Propagate->GetPQR();
600  Accelerations->in.vUVW = Propagate->GetUVW();
601  Accelerations->in.vInertialPosition = Propagate->GetInertialPosition();
602  Accelerations->in.DeltaT = dT;
603  Accelerations->in.Mass = MassBalance->GetMass();
604  Accelerations->in.MultipliersList = GroundReactions->GetMultipliersList();
605  Accelerations->in.TerrainVelocity = Propagate->GetTerrainVelocity();
606  Accelerations->in.TerrainAngularVel = Propagate->GetTerrainAngularVelocity();
607  break;
608  default:
609  break;
610  }
611 }
612 
613 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614 
615 void FGFDMExec::LoadPlanetConstants(void)
616 {
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;
624 }
625 
626 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
627 
628 void FGFDMExec::LoadModelConstants(void)
629 {
630  Winds->in.wingspan = Aircraft->GetWingSpan();
631  Aerodynamics->in.Wingarea = Aircraft->GetWingArea();
632  Aerodynamics->in.Wingchord = Aircraft->Getcbar();
633  Aerodynamics->in.Wingincidence = Aircraft->GetWingIncidence();
634  Aerodynamics->in.Wingspan = Aircraft->GetWingSpan();
635  Auxiliary->in.Wingspan = Aircraft->GetWingSpan();
636  Auxiliary->in.Wingchord = Aircraft->Getcbar();
637  GroundReactions->in.vXYZcg = MassBalance->GetXYZcg();
638 }
639 
640 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641 // This call will cause the sim time to reset to 0.0
642 
644 {
645  SuspendIntegration(); // saves the integration rate, dt, then sets it to 0.0.
646  Initialize(IC.get());
647 
648  Models[eInput]->InitModel();
649  Models[eOutput]->InitModel();
650 
651  Run();
652  Propagate->InitializeDerivatives();
653  ResumeIntegration(); // Restores the integration rate to what it was.
654 
655  if (debug_lvl > 0) {
656  MassBalance->GetMassPropertiesReport(0);
657 
658  cout << endl << fgblue << highint
659  << "End of vehicle configuration loading." << endl
660  << "-------------------------------------------------------------------------------"
661  << reset << std::setprecision(6) << endl;
662  }
663 
664  for (unsigned int n=0; n < Propulsion->GetNumEngines(); ++n) {
665  if (IC->IsEngineRunning(n)) {
666  try {
667  Propulsion->InitRunning(n);
668  } catch (const string& str) {
669  cerr << str << endl;
670  return false;
671  }
672  }
673  }
674 
675  return true;
676 }
677 
678 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 
681 {
682  Propagate->SetInitialState(FGIC);
683  Winds->SetWindNED(FGIC->GetWindNEDFpsIC());
684  Run();
685 }
686 
687 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688 
690 {
691  if (Constructing) return;
692 
693  // mode flags
694 
695  if (mode & START_NEW_OUTPUT) Output->SetStartNewOutput();
696 
697  InitializeModels();
698 
699  if (Script)
700  Script->ResetEvents();
701  else
702  Setsim_time(0.0);
703 
704  if (!(mode & DONT_EXECUTE_RUN_IC))
705  RunIC();
706 }
707 
708 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709 
711 {
712  HoldDown = hd;
713  Accelerations->SetHoldDown(hd);
714  if (hd) {
715  Propagate->in.vPQRidot = Accelerations->GetPQRidot();
716  Propagate->in.vUVWidot = Accelerations->GetUVWidot();
717  }
718  Propagate->SetHoldDown(hd);
719 }
720 
721 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722 
723 vector <string> FGFDMExec::EnumerateFDMs(void)
724 {
725  vector <string> FDMList;
726  FDMList.push_back(Aircraft->GetAircraftName());
727 
728  for (auto &ChildFDM: ChildFDMList)
729  FDMList.push_back(ChildFDM->exec->GetAircraft()->GetAircraftName());
730 
731  return FDMList;
732 }
733 
734 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735 
736 bool FGFDMExec::LoadScript(const SGPath& script, double deltaT,
737  const SGPath& initfile)
738 {
739  Script = std::make_shared<FGScript>(this);
740  return Script->LoadScript(GetFullPath(script), deltaT, initfile);
741 }
742 
743 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
744 
745 bool FGFDMExec::LoadPlanet(const SGPath& PlanetPath, bool useAircraftPath)
746 {
747  SGPath PlanetFileName;
748 
749  if(useAircraftPath && PlanetPath.isRelative()) {
750  PlanetFileName = AircraftPath/PlanetPath.utf8Str();
751  } else {
752  PlanetFileName = PlanetPath;
753  }
754 
755  FGXMLFileRead XMLFileRead;
756  Element* document = XMLFileRead.LoadXMLDocument(PlanetFileName);
757 
758  // Make sure that the document is valid
759  if (!document) {
760  stringstream s;
761  s << "File: " << PlanetFileName << " could not be read.";
762  cerr << s.str() << endl;
763  throw BaseException(s.str());
764  }
765 
766  if (document->GetName() != "planet") {
767  stringstream s;
768  s << "File: " << PlanetFileName << " is not a planet file.";
769  cerr << s.str() << endl;
770  throw BaseException(s.str());
771  }
772 
773  bool result = LoadPlanet(document);
774 
775  if (!result)
776  cerr << endl << "Planet element has problems in file " << PlanetFileName << endl;
777 
778  return result;
779 }
780 
781 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782 
783 bool FGFDMExec::LoadPlanet(Element* element)
784 {
785  bool result = Models[eInertial]->Load(element);
786 
787  if (result) {
788  // Reload the planet constants and re-initialize the models.
789  LoadPlanetConstants();
790  IC->InitializeIC();
791  InitializeModels();
792 
793  // Process the atmosphere element. This element is OPTIONAL.
794  Element* atm_element = element->FindElement("atmosphere");
795  if (atm_element && atm_element->HasAttribute("model")) {
796  string model = atm_element->GetAttributeValue("model");
797  if (model == "MSIS") {
798  // Replace the existing atmosphere model
799  instance->Unbind(Models[eAtmosphere]);
800  Models[eAtmosphere] = std::make_shared<FGMSIS>(this);
801  Atmosphere = static_cast<FGAtmosphere*>(Models[eAtmosphere].get());
802 
803  // Model initialization sequence
804  LoadInputs(eAtmosphere);
805  Atmosphere->InitModel();
806  result = Atmosphere->Load(atm_element);
807  if (!result) {
808  cerr << endl << "Incorrect definition of <atmosphere>." << endl;
809  return result;
810  }
811  InitializeModels();
812  }
813  }
814  }
815 
816  return result;
817 }
818 
819 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820 
821 bool FGFDMExec::LoadModel(const SGPath& AircraftPath, const SGPath& EnginePath,
822  const SGPath& SystemsPath, const string& model,
823  bool addModelToPath)
824 {
825  FGFDMExec::AircraftPath = GetFullPath(AircraftPath);
826  FGFDMExec::EnginePath = GetFullPath(EnginePath);
827  FGFDMExec::SystemsPath = GetFullPath(SystemsPath);
828 
829  return LoadModel(model, addModelToPath);
830 }
831 
832 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
833 
834 bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
835 {
836  SGPath aircraftCfgFileName;
837  bool result = false; // initialize result to false, indicating input file not yet read
838 
839  modelName = model; // Set the class modelName attribute
840 
841  if( AircraftPath.isNull() || EnginePath.isNull() || SystemsPath.isNull()) {
842  cerr << "Error: attempted to load aircraft with undefined "
843  << "aircraft, engine, and system paths" << endl;
844  return false;
845  }
846 
847  FullAircraftPath = AircraftPath;
848  if (addModelToPath) FullAircraftPath.append(model);
849  aircraftCfgFileName = FullAircraftPath/(model + ".xml");
850 
851  if (modelLoaded) {
852  DeAllocate();
853  Allocate();
854  }
855 
856  int saved_debug_lvl = debug_lvl;
857  FGXMLFileRead XMLFileRead;
858  Element *document = XMLFileRead.LoadXMLDocument(aircraftCfgFileName); // "document" is a class member
859 
860  if (document) {
861  if (IsChild) debug_lvl = 0;
862 
863  ReadPrologue(document);
864 
865  if (IsChild) debug_lvl = saved_debug_lvl;
866 
867  // Process the fileheader element in the aircraft config file. This element is OPTIONAL.
868  Element* element = document->FindElement("fileheader");
869  if (element) {
870  result = ReadFileHeader(element);
871  if (!result) {
872  cerr << endl << "Aircraft fileheader element has problems in file " << aircraftCfgFileName << endl;
873  return result;
874  }
875  }
876 
877  if (IsChild) debug_lvl = 0;
878 
879  // Process the planet element. This element is OPTIONAL.
880  element = document->FindElement("planet");
881  if (element) {
882  result = LoadPlanet(element);
883  if (!result) {
884  cerr << endl << "Planet element has problems in file " << aircraftCfgFileName << endl;
885  return result;
886  }
887  }
888 
889  // Process the metrics element. This element is REQUIRED.
890  element = document->FindElement("metrics");
891  if (element) {
892  result = Models[eAircraft]->Load(element);
893  if (!result) {
894  cerr << endl << "Aircraft metrics element has problems in file " << aircraftCfgFileName << endl;
895  return result;
896  }
897  } else {
898  cerr << endl << "No metrics element was found in the aircraft config file." << endl;
899  return false;
900  }
901 
902  // Process the mass_balance element. This element is REQUIRED.
903  element = document->FindElement("mass_balance");
904  if (element) {
905  result = Models[eMassBalance]->Load(element);
906  if (!result) {
907  cerr << endl << "Aircraft mass_balance element has problems in file " << aircraftCfgFileName << endl;
908  return result;
909  }
910  } else {
911  cerr << endl << "No mass_balance element was found in the aircraft config file." << endl;
912  return false;
913  }
914 
915  // Process the ground_reactions element. This element is REQUIRED.
916  element = document->FindElement("ground_reactions");
917  if (element) {
918  result = Models[eGroundReactions]->Load(element);
919  if (!result) {
920  cerr << endl << element->ReadFrom()
921  << "Aircraft ground_reactions element has problems in file "
922  << aircraftCfgFileName << endl;
923  return result;
924  }
925  } else {
926  cerr << endl << "No ground_reactions element was found in the aircraft config file." << endl;
927  return false;
928  }
929 
930  // Process the external_reactions element. This element is OPTIONAL.
931  element = document->FindElement("external_reactions");
932  if (element) {
933  result = Models[eExternalReactions]->Load(element);
934  if (!result) {
935  cerr << endl << "Aircraft external_reactions element has problems in file " << aircraftCfgFileName << endl;
936  return result;
937  }
938  }
939 
940  // Process the buoyant_forces element. This element is OPTIONAL.
941  element = document->FindElement("buoyant_forces");
942  if (element) {
943  result = Models[eBuoyantForces]->Load(element);
944  if (!result) {
945  cerr << endl << "Aircraft buoyant_forces element has problems in file " << aircraftCfgFileName << endl;
946  return result;
947  }
948  }
949 
950  // Process the propulsion element. This element is OPTIONAL.
951  element = document->FindElement("propulsion");
952  if (element) {
953  result = Propulsion->Load(element);
954  if (!result) {
955  cerr << endl << "Aircraft propulsion element has problems in file " << aircraftCfgFileName << endl;
956  return result;
957  }
958  for (unsigned int i=0; i < Propulsion->GetNumEngines(); i++)
959  FCS->AddThrottle();
960  }
961 
962  // Process the system element[s]. This element is OPTIONAL, and there may be more than one.
963  element = document->FindElement("system");
964  while (element) {
965  result = Models[eSystems]->Load(element);
966  if (!result) {
967  cerr << endl << "Aircraft system element has problems in file " << aircraftCfgFileName << endl;
968  return result;
969  }
970  element = document->FindNextElement("system");
971  }
972 
973  // Process the autopilot element. This element is OPTIONAL.
974  element = document->FindElement("autopilot");
975  if (element) {
976  result = Models[eSystems]->Load(element);
977  if (!result) {
978  cerr << endl << "Aircraft autopilot element has problems in file " << aircraftCfgFileName << endl;
979  return result;
980  }
981  }
982 
983  // Process the flight_control element. This element is OPTIONAL.
984  element = document->FindElement("flight_control");
985  if (element) {
986  result = Models[eSystems]->Load(element);
987  if (!result) {
988  cerr << endl << "Aircraft flight_control element has problems in file " << aircraftCfgFileName << endl;
989  return result;
990  }
991  }
992 
993  // Process the aerodynamics element. This element is OPTIONAL, but almost always expected.
994  element = document->FindElement("aerodynamics");
995  if (element) {
996  result = Models[eAerodynamics]->Load(element);
997  if (!result) {
998  cerr << endl << "Aircraft aerodynamics element has problems in file " << aircraftCfgFileName << endl;
999  return result;
1000  }
1001  } else {
1002  cerr << endl << "No expected aerodynamics element was found in the aircraft config file." << endl;
1003  }
1004 
1005  // Process the input element. This element is OPTIONAL, and there may be more than one.
1006  element = document->FindElement("input");
1007  while (element) {
1008  if (!Input->Load(element))
1009  return false;
1010 
1011  element = document->FindNextElement("input");
1012  }
1013 
1014  // Process the output element[s]. This element is OPTIONAL, and there may be
1015  // more than one.
1016  element = document->FindElement("output");
1017  while (element) {
1018  if (!Output->Load(element))
1019  return false;
1020 
1021  element = document->FindNextElement("output");
1022  }
1023 
1024  // Lastly, process the child element. This element is OPTIONAL - and NOT YET SUPPORTED.
1025  element = document->FindElement("child");
1026  if (element) {
1027  result = ReadChild(element);
1028  if (!result) {
1029  cerr << endl << "Aircraft child element has problems in file " << aircraftCfgFileName << endl;
1030  return result;
1031  }
1032  }
1033 
1034  // Since all vehicle characteristics have been loaded, place the values in the Inputs
1035  // structure for the FGModel-derived classes.
1036  LoadModelConstants();
1037 
1038  modelLoaded = true;
1039 
1040  if (IsChild) debug_lvl = saved_debug_lvl;
1041 
1042  } else {
1043  cerr << fgred
1044  << " JSBSim failed to open the configuration file: " << aircraftCfgFileName
1045  << fgdef << endl;
1046  }
1047 
1048  for (unsigned int i=0; i< Models.size(); i++) LoadInputs(i);
1049 
1050  if (result) {
1051  struct PropertyCatalogStructure masterPCS;
1052  masterPCS.base_string = "";
1053  masterPCS.node = Root;
1054  BuildPropertyCatalog(&masterPCS);
1055  }
1056 
1057  return result;
1058 }
1059 
1060 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1061 
1062 string FGFDMExec::GetPropulsionTankReport() const
1063 {
1064  return Propulsion->GetPropulsionTankReport();
1065 }
1066 
1067 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1068 
1070 {
1071  auto pcsNew = std::make_unique<struct PropertyCatalogStructure>();
1072 
1073  for (int i=0; i<pcs->node->nChildren(); i++) {
1074  string access="";
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);
1079  }
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);
1083  }
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+")");
1087  } else {
1088  pcsNew->node = (FGPropertyNode*)pcs->node->getChild(i);
1089  BuildPropertyCatalog(pcsNew.get());
1090  }
1091  }
1092 }
1093 
1094 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095 
1096 string FGFDMExec::QueryPropertyCatalog(const string& in, const string& end_of_line)
1097 {
1098  string results;
1099  for (auto &catalogElm: PropertyCatalog) {
1100  if (catalogElm.find(in) != string::npos) results += catalogElm + end_of_line;
1101  }
1102  if (results.empty()) return "No matches found"+end_of_line;
1103  return results;
1104 }
1105 
1106 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1107 
1108 void FGFDMExec::PrintPropertyCatalog(void)
1109 {
1110  cout << endl;
1111  cout << " " << fgblue << highint << underon << "Property Catalog for "
1112  << modelName << reset << endl << endl;
1113  for (auto &catalogElm: PropertyCatalog)
1114  cout << " " << catalogElm << endl;
1115 }
1116 
1117 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118 
1119 void FGFDMExec::PrintSimulationConfiguration(void) const
1120 {
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;
1126 }
1127 
1128 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1129 
1130 bool FGFDMExec::ReadFileHeader(Element* el)
1131 {
1132  bool result = true; // true for success
1133 
1134  if (debug_lvl == 0) return result;
1135 
1136  if (IsChild) {
1137  cout << endl <<highint << fgblue << "Reading child model: " << IdFDM << reset << endl << endl;
1138  }
1139 
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;
1148 
1149  return result;
1150 }
1151 
1152 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1153 
1154 bool FGFDMExec::ReadPrologue(Element* el) // el for ReadPrologue is the document element
1155 {
1156  bool result = true; // true for success
1157 
1158  if (!el) return false;
1159 
1160  string AircraftName = el->GetAttributeValue("name");
1161  Aircraft->SetAircraftName(AircraftName);
1162 
1163  if (debug_lvl & 1) cout << underon << "Reading Aircraft Configuration File"
1164  << underoff << ": " << highint << AircraftName << normint << endl;
1165 
1166  CFGVersion = el->GetAttributeValue("version");
1167  Release = el->GetAttributeValue("release");
1168 
1169  if (debug_lvl & 1)
1170  cout << " Version: " << highint << CFGVersion
1171  << normint << endl;
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;
1177  return false;
1178  }
1179 
1180  if (Release == "ALPHA" && (debug_lvl & 1)) {
1181  cout << endl << endl
1182  << highint << "This aircraft model is an " << fgred << Release
1183  << reset << highint << " release!!!" << endl << endl << reset
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!!!"
1187  << normint << reset << endl << endl;
1188  } else if (Release == "BETA" && (debug_lvl & 1)) {
1189  cout << endl << endl
1190  << highint << "This aircraft model is a " << fgred << Release
1191  << reset << highint << " release!!!" << endl << endl << reset
1192  << "This aircraft model probably will not fly as expected." << endl << endl
1193  << fgblue << highint << "Use this model for development purposes ONLY!!!"
1194  << normint << reset << endl << endl;
1195  } else if (Release == "PRODUCTION" && (debug_lvl & 1)) {
1196  cout << endl << endl
1197  << highint << "This aircraft model is a " << fgblue << Release
1198  << reset << highint << " release." << endl << endl << reset;
1199  } else if (debug_lvl & 1) {
1200  cout << endl << endl
1201  << highint << "This aircraft model is an " << fgred << Release
1202  << reset << highint << " release!!!" << endl << endl << reset
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!!!"
1206  << normint << reset << endl << endl;
1207  }
1208 
1209  return result;
1210 }
1211 
1212 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1213 
1214 bool FGFDMExec::ReadChild(Element* el)
1215 {
1216  // Add a new childData object to the child FDM list
1217  // Populate that childData element with a new FDMExec object
1218  // Set the IsChild flag for that FDMExec object
1219  // Get the aircraft name
1220  // set debug level to print out no additional data for child objects
1221  // Load the model given the aircraft name
1222  // reset debug level to prior setting
1223 
1224  auto child = std::make_shared<childData>();
1225 
1226  auto pm = std::make_unique<FGPropertyManager>(Root);
1227  child->exec = std::make_unique<FGFDMExec>(pm.get(), FDMctr);
1228  child->exec->SetChild(true);
1229 
1230  string childAircraft = el->GetAttributeValue("name");
1231  string sMated = el->GetAttributeValue("mated");
1232  if (sMated == "false") child->mated = false; // child objects are mated by default.
1233  string sInternal = el->GetAttributeValue("internal");
1234  if (sInternal == "true") child->internal = true; // child objects are external by default.
1235 
1236  child->exec->SetAircraftPath( AircraftPath );
1237  child->exec->SetEnginePath( EnginePath );
1238  child->exec->SetSystemsPath( SystemsPath );
1239  child->exec->LoadModel(childAircraft);
1240 
1241  Element* location = el->FindElement("location");
1242  if (location) {
1243  child->Loc = location->FindElementTripletConvertTo("IN");
1244  } else {
1245  const string s(" No location was found for this child object!");
1246  cerr << el->ReadFrom() << endl << highint << fgred
1247  << s << reset << endl;
1248  throw BaseException(s);
1249  }
1250 
1251  Element* orientation = el->FindElement("orient");
1252  if (orientation) {
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;
1256  }
1257 
1258  ChildFDMList.push_back(child);
1259 
1260  return true;
1261 }
1262 
1263 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264 
1265 std::shared_ptr<FGTrim> FGFDMExec::GetTrim(void)
1266 {
1267  Trim = std::make_shared<FGTrim>(this,tNone);
1268  return Trim;
1269 }
1270 
1271 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272 
1274 {
1275  // Only check if increment then hold is on
1276  if( IncrementThenHolding ) {
1277 
1278  if (TimeStepsUntilHold == 0) {
1279 
1280  // Should hold simulation if TimeStepsUntilHold has reached zero
1281  holding = true;
1282 
1283  // Still need to decrement TimeStepsUntilHold as value of -1
1284  // indicates that incremental then hold is turned off
1285  IncrementThenHolding = false;
1286  TimeStepsUntilHold--;
1287 
1288  } else if ( TimeStepsUntilHold > 0 ) {
1289  // Keep decrementing until 0 is reached
1290  TimeStepsUntilHold--;
1291  }
1292  }
1293 }
1294 
1295 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296 
1297 void FGFDMExec::DoTrim(int mode)
1298 {
1299  if (Constructing) return;
1300 
1301  if (mode < 0 || mode > JSBSim::tNone)
1302  throw("Illegal trimming mode!");
1303 
1304  FGTrim trim(this, (JSBSim::TrimMode)mode);
1305  bool success = trim.DoTrim();
1306 
1307  if (debug_lvl > 0)
1308  trim.Report();
1309 
1310  if (!success)
1311  throw TrimFailureException("Trim Failed");
1312 
1313  trim_completed = 1;
1314 }
1315 
1316 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1317 
1318 void FGFDMExec::SRand(int sr)
1319 {
1320  RandomSeed = sr;
1321  RandomGenerator->seed(RandomSeed);
1322 }
1323 
1324 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1325 // The bitmasked value choices are as follows:
1326 // unset: In this case (the default) JSBSim would only print
1327 // out the normally expected messages, essentially echoing
1328 // the config files as they are read. If the environment
1329 // variable is not set, debug_lvl is set to 1 internally
1330 // 0: This requests JSBSim not to output any messages
1331 // whatsoever.
1332 // 1: This value explicity requests the normal JSBSim
1333 // startup messages
1334 // 2: This value asks for a message to be printed out when
1335 // a class is instantiated
1336 // 4: When this value is set, a message is displayed when a
1337 // FGModel object executes its Run() method
1338 // 8: When this value is set, various runtime state variables
1339 // are printed out periodically
1340 // 16: When set various parameters are sanity checked and
1341 // a message is printed out when they go out of bounds
1342 
1343 void FGFDMExec::Debug(int from)
1344 {
1345  if (debug_lvl <= 0) return;
1346 
1347  if (debug_lvl & 1 && IdFDM == 0) { // Standard console startup message output
1348  if (from == 0) { // Constructor
1349  cout << "\n\n "
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";
1356  }
1357  }
1358  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
1359  if (from == 0) cout << "Instantiated: FGFDMExec" << endl;
1360  if (from == 1) cout << "Destroyed: FGFDMExec" << endl;
1361  }
1362  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
1363  if (from == 2) {
1364  cout << "================== Frame: " << Frame << " Time: "
1365  << sim_time << " dt: " << dT << endl;
1366  }
1367  }
1368  if (debug_lvl & 8 ) { // Runtime state variables
1369  }
1370  if (debug_lvl & 16) { // Sanity checking
1371  }
1372  if (debug_lvl & 64) {
1373  if (from == 0) { // Constructor
1374  }
1375  }
1376 }
1377 }
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.
Definition: FGXMLElement.h:155
const std::string & GetName(void) const
Retrieves the element name.
Definition: FGXMLElement.h:179
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.
Definition: FGAircraft.h:102
double Getcbar(void) const
Gets the average wing chord.
Definition: FGAircraft.h:138
const std::string & GetAircraftName(void) const
Gets the aircraft name.
Definition: FGAircraft.h:131
double GetWingArea(void) const
Gets the wing area.
Definition: FGAircraft.h:134
const FGColumnVector3 & GetXYZrp(void) const
Gets the the aero reference point (RP) coordinates.
Definition: FGAircraft.h:155
double GetWingSpan(void) const
Gets the wing span.
Definition: FGAircraft.h:136
Models an empty, abstract base atmosphere class.
Definition: FGAtmosphere.h:76
virtual double GetPressureRatio(void) const
Returns the ratio of at-altitude pressure over the sea level value.
Definition: FGAtmosphere.h:153
virtual double GetPressure(void) const
Returns the pressure in psf.
Definition: FGAtmosphere.h:144
virtual double GetKinematicViscosity(void) const
Returns the kinematic viscosity.
Definition: FGAtmosphere.h:202
virtual double GetSoundSpeed(void) const
Returns the speed of sound in ft/sec.
Definition: FGAtmosphere.h:183
virtual double GetDensityRatio(void) const
Returns the ratio of at-altitude density over the sea level value.
Definition: FGAtmosphere.h:176
virtual double GetDensity(void) const
Returns the density in slugs/ft^3.
Definition: FGAtmosphere.h:167
virtual double GetTemperature() const
Returns the actual, modeled temperature at the current altitude in degrees Rankine.
Definition: FGAtmosphere.h:109
Encapsulates various uncategorized scheduled functions.
Definition: FGAuxiliary.h:100
double GetVground(void) const
Gets the ground speed in feet per second.
Definition: FGAuxiliary.h:245
double GetVcalibratedKTS(void) const
Returns Calibrated airspeed in knots.
Definition: FGAuxiliary.h:162
double GetTotalPressure(void) const
Returns the total pressure.
Definition: FGAuxiliary.h:176
const FGMatrix33 & GetTb2w(void) const
Calculates and returns the body-to-wind axis transformation matrix.
Definition: FGAuxiliary.h:230
double GetVt(void) const
Gets the magnitude of total vehicle velocity including wind effects in feet per second.
Definition: FGAuxiliary.h:239
const FGMatrix33 & GetTw2b(void) const
Calculates and returns the wind-to-body axis transformation matrix.
Definition: FGAuxiliary.h:225
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.
Definition: FGFCS.h:189
double GetMixtureCmd(int engine) const
Gets the mixture command.
Definition: FGFCS.h:249
double GetThrottleCmd(int engine) const
Gets the throttle command.
Definition: FGFCS.cpp:352
double GetGearPos(void) const
Gets the gear position (0 up, 1 down), defaults to down.
Definition: FGFCS.h:334
bool GetPropFeather(int engine) const
Gets the prop feather position.
Definition: FGFCS.h:354
double GetPropAdvance(int engine) const
Gets the prop pitch position.
Definition: FGFCS.h:347
double GetMixturePos(int engine) const
Gets the mixture position.
Definition: FGFCS.h:328
double GetThrottlePos(int engine) const
Gets the throttle position.
Definition: FGFCS.cpp:370
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:184
bool GetHoldDown(void) const
Gets the value of the property forces/hold-down.
Definition: FGFDMExec.h:611
std::shared_ptr< FGWinds > GetWinds(void) const
Returns the FGWinds pointer.
Definition: FGFDMExec.cpp:306
void SetDebugLevel(int level)
Sets the debug level.
Definition: FGFDMExec.h:504
std::shared_ptr< FGBuoyantForces > GetBuoyantForces(void) const
Returns the FGBuoyantForces pointer.
Definition: FGFDMExec.cpp:362
bool LoadScript(const SGPath &Script, double deltaT=0.0, const SGPath &initfile=SGPath())
Load a script.
Definition: FGFDMExec.cpp:736
std::shared_ptr< FGAircraft > GetAircraft(void) const
Returns the FGAircraft pointer.
Definition: FGFDMExec.cpp:369
std::shared_ptr< FGFCS > GetFCS(void) const
Returns the FGFCS pointer.
Definition: FGFDMExec.cpp:313
int GetDebugLevel(void) const
Retrieves the current debug level setting.
Definition: FGFDMExec.h:596
std::shared_ptr< FGOutput > GetOutput(void) const
Returns the FGOutput pointer.
Definition: FGFDMExec.cpp:383
static const int START_NEW_OUTPUT
Mode flags for ResetToInitialConditions.
Definition: FGFDMExec.h:493
std::string QueryPropertyCatalog(const std::string &check, const std::string &end_of_line="\n")
Retrieves property or properties matching the supplied string.
Definition: FGFDMExec.cpp:1096
void BuildPropertyCatalog(struct PropertyCatalogStructure *pcs)
Builds a catalog of properties.
Definition: FGFDMExec.cpp:1069
double GetDeltaT(void) const
Returns the simulation delta T.
Definition: FGFDMExec.h:547
double Setsim_time(double cur_time)
Sets the current sim time.
Definition: FGFDMExec.cpp:194
std::vector< std::string > EnumerateFDMs(void)
Returns a vector of strings representing the names of all loaded models (future)
Definition: FGFDMExec.cpp:723
void DoTrim(int mode)
Executes trimming in the selected mode.
Definition: FGFDMExec.cpp:1297
std::shared_ptr< FGPropagate > GetPropagate(void) const
Returns the FGPropagate pointer.
Definition: FGFDMExec.cpp:278
std::shared_ptr< FGAerodynamics > GetAerodynamics(void) const
Returns the FGAerodynamics pointer.
Definition: FGFDMExec.cpp:341
double IncrTime(void)
Increments the simulation time if not in Holding mode.
Definition: FGFDMExec.cpp:202
std::shared_ptr< FGExternalReactions > GetExternalReactions(void) const
Returns the FGExternalReactions pointer.
Definition: FGFDMExec.cpp:355
void CheckIncrementalHold(void)
Checks if required to hold afer increment.
Definition: FGFDMExec.cpp:1273
bool LoadPlanet(const SGPath &PlanetPath, bool useAircraftPath=true)
Loads the planet.
Definition: FGFDMExec.cpp:745
bool Run(void)
This function executes each scheduled model in succession.
Definition: FGFDMExec.cpp:413
std::shared_ptr< FGGroundReactions > GetGroundReactions(void) const
Returns the FGGroundReactions pointer.
Definition: FGFDMExec.cpp:348
std::shared_ptr< FGMassBalance > GetMassBalance(void) const
Returns the FGAircraft pointer.
Definition: FGFDMExec.cpp:320
std::shared_ptr< FGTrim > GetTrim(void)
Returns a pointer to the FGTrim object.
Definition: FGFDMExec.cpp:1265
std::shared_ptr< FGPropulsion > GetPropulsion(void) const
Returns the FGPropulsion pointer.
Definition: FGFDMExec.cpp:334
bool LoadModel(const SGPath &AircraftPath, const SGPath &EnginePath, const SGPath &SystemsPath, const std::string &model, bool addModelToPath=true)
Loads an aircraft model.
Definition: FGFDMExec.cpp:821
~FGFDMExec()
Default destructor.
Definition: FGFDMExec.cpp:178
void ResetToInitialConditions(int mode)
Resets the initial conditions object and prepares the simulation to run again.
Definition: FGFDMExec.cpp:689
bool IntegrationSuspended(void) const
Returns the simulation suspension state.
Definition: FGFDMExec.h:557
void Unbind(void)
Unbind all tied JSBSim properties.
Definition: FGFDMExec.h:243
double GetSimTime(void) const
Returns the cumulative simulation time in seconds.
Definition: FGFDMExec.h:544
void SuspendIntegration(void)
Suspends the simulation and sets the delta T to zero.
Definition: FGFDMExec.h:550
std::shared_ptr< FGInertial > GetInertial(void) const
Returns the FGInertial pointer.
Definition: FGFDMExec.cpp:285
void Initialize(const FGInitialCondition *FGIC)
Initializes the simulation with initial conditions.
Definition: FGFDMExec.cpp:680
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
Definition: FGFDMExec.cpp:710
std::shared_ptr< FGAuxiliary > GetAuxiliary(void) const
Returns the FGAuxiliary pointer.
Definition: FGFDMExec.cpp:327
std::shared_ptr< FGAccelerations > GetAccelerations(void) const
Returns the FGAccelerations pointer.
Definition: FGFDMExec.cpp:376
bool RunIC(void)
Initializes the sim from the initial condition object and executes each scheduled model without integ...
Definition: FGFDMExec.cpp:643
void ResumeIntegration(void)
Resumes the simulation by resetting delta T to the correct value.
Definition: FGFDMExec.h:553
std::shared_ptr< FGInput > GetInput(void) const
Returns the FGInput pointer.
Definition: FGFDMExec.cpp:292
Manages ground reactions modeling.
Models inertial forces (e.g.
Definition: FGInertial.h:65
void SetTime(double time)
Set the simulation time.
Definition: FGInertial.h:140
Initializes the simulation run.
FGColumnVector3 GetWindNEDFpsIC(void) const
Gets the initial wind velocity in the NED local frame.
Handles simulation input.
Definition: FGInput.h:85
bool Load(Element *el) override
Load the input directives and adds a new input instance to the Input Manager list.
Definition: FGInput.cpp:76
static char normint[6]
normal intensity text
Definition: FGJSBBase.h:155
static char fgred[6]
red text
Definition: FGJSBBase.h:167
static char fgblue[6]
blue text
Definition: FGJSBBase.h:163
static char underon[5]
underlines text
Definition: FGJSBBase.h:159
static char fgdef[6]
default text
Definition: FGJSBBase.h:171
static char reset[5]
resets text properties
Definition: FGJSBBase.h:157
static char underoff[6]
underline off
Definition: FGJSBBase.h:161
static char highint[5]
highlights text
Definition: FGJSBBase.h:151
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.
Definition: FGModel.h:93
Handles simulation output.
Definition: FGOutput.h:126
void SetStartNewOutput(void)
Reset the output prior to a restart of the simulation.
Definition: FGOutput.cpp:117
bool Load(Element *el, const SGPath &dir=SGPath())
Load the output directives and adds a new output instance to the Output Manager list.
Definition: FGOutput.cpp:238
Models the EOM and integration/propagation of state.
Definition: FGPropagate.h:95
const FGColumnVector3 & GetUVW(void) const
Retrieves the body frame vehicle velocity vector.
Definition: FGPropagate.h:197
const FGColumnVector3 & GetVel(void) const
Retrieves the velocity vector.
Definition: FGPropagate.h:185
const FGMatrix33 & GetTec2i(void) const
Retrieves the ECEF-to-ECI transformation matrix.
Definition: FGPropagate.h:494
const FGMatrix33 & GetTi2b(void) const
Retrieves the ECI-to-body transformation matrix.
Definition: FGPropagate.h:485
const FGColumnVector3 & GetPQR(void) const
Retrieves the body angular rates vector, relative to the ECEF frame.
Definition: FGPropagate.h:211
const FGMatrix33 & GetTec2l(void) const
Retrieves the ECEF-to-local transformation matrix.
Definition: FGPropagate.h:505
double GetSinEuler(int idx) const
Retrieves the sine of a vehicle Euler angle component.
Definition: FGPropagate.h:411
double GetAltitudeASL(void) const
Returns the current altitude above sea level.
const FGMatrix33 & GetTb2l(void) const
Retrieves the body-to-local transformation matrix.
Definition: FGPropagate.h:473
const FGMatrix33 & GetTb2i(void) const
Retrieves the body-to-ECI transformation matrix.
Definition: FGPropagate.h:489
const FGColumnVector3 & GetInertialPosition(void) const
Retrieves the inertial position vector.
Definition: FGPropagate.h:313
const FGColumnVector3 & GetPQRi(void) const
Retrieves the body angular rates vector, relative to the ECI (inertial) frame.
Definition: FGPropagate.h:225
const FGMatrix33 & GetTec2b(void) const
Retrieves the ECEF-to-body transformation matrix.
Definition: FGPropagate.h:477
const FGMatrix33 & GetTl2b(void) const
Retrieves the local-to-body transformation matrix.
Definition: FGPropagate.h:467
double GetCosEuler(int idx) const
Retrieves the cosine of a vehicle Euler angle component.
Definition: FGPropagate.h:399
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
Class wrapper for property handling.
Propulsion management class.
Definition: FGPropulsion.h:99
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.
Definition: FGPropulsion.h:126
void InitRunning(int n)
Sets up the engines as running.
The trimming routine for JSBSim.
Definition: FGTrim.h:126
Models atmospheric disturbances: winds, gusts, turbulence, downbursts, etc.
Definition: FGWinds.h:166
virtual const FGColumnVector3 & GetTotalWindNED(void) const
Retrieves the total wind components in NED frame.
Definition: FGWinds.h:187
virtual void SetWindNED(double wN, double wE, double wD)
Sets the wind components in NED frame.
Definition: FGWinds.h:195
Random number generator.
Definition: FGJSBBase.h:75
FGColumnVector3 TerrainVelocity
Terrain velocities with respect to the local frame (expressed in the ECEF frame).
FGColumnVector3 GroundMoment
Moments generated by the ground normal reactions expressed in the body frame. Does not account for fr...
FGColumnVector3 vUVW
Velocities of the body with respect to the local frame (expressed in the body frame).
FGMatrix33 Tb2i
Transformation matrix from the Body to the ECI frame.
FGMatrix33 J
The body inertia matrix expressed in the body frame.
FGColumnVector3 vPQRi
Angular velocities of the body with respect to the ECI frame (expressed in the body frame).
FGColumnVector3 Moment
Total moments applied to the body except friction and gravity (expressed in the body frame)
FGMatrix33 Jinv
The inverse of the inertia matrix J.
FGColumnVector3 vOmegaPlanet
Earth rotating vector (expressed in the ECI frame).
FGColumnVector3 vInertialPosition
Body position (X,Y,Z) measured in the ECI frame.
FGColumnVector3 vPQR
Angular velocities of the body with respect to the local frame (expressed in the body frame).
FGColumnVector3 vGravAccel
Gravity intensity vector (expressed in the ECEF frame).
FGMatrix33 Tec2i
Transformation matrix from the ECEF to the ECI frame.
std::vector< LagrangeMultiplier * > * MultipliersList
List of Lagrange multipliers set by FGLGear for friction forces calculations.
FGMatrix33 Tec2b
Transformation matrix from the ECEF to the Body frame.
FGColumnVector3 GroundForce
Forces generated by the ground normal reactions expressed in the body frame. Does not account for fri...
FGColumnVector3 TerrainAngularVel
Terrain angular velocities with respect to the local frame (expressed in the ECEF frame).
FGColumnVector3 Force
Total forces applied to the body except friction and gravity (expressed in the body frame)
FGMatrix33 Ti2b
Transformation matrix from the ECI to the Body frame.
FGPropertyNode_ptr node
The node for the property.
Definition: FGFDMExec.h:510
std::string base_string
Name of the property.
Definition: FGFDMExec.h:508