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