]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGPropulsion.cpp
Fix stall widths for the "auxilliary" (reverse flow) stalls so they
[flightgear.git] / src / FDM / JSBSim / FGPropulsion.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGPropulsion.cpp
4  Author:       Jon S. Berndt
5  Date started: 08/20/00
6  Purpose:      Encapsulates the set of engines and tanks associated
7                with this aircraft
8
9  ------------- Copyright (C) 2000  Jon S. Berndt (jsb@hal-pc.org) -------------
10
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU General Public License as published by the Free Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  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 General Public License for more
19  details.
20
21  You should have received a copy of the GNU General Public License along with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA  02111-1307, USA.
24
25  Further information about the GNU General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 The Propulsion class is the container for the entire propulsion system, which is
31 comprised of engines and tanks. Once the Propulsion class gets the config file,
32 it reads in information which is specific to a type of engine. Then:
33
34 1) The appropriate engine type instance is created
35 2) At least one tank object is created, and is linked to an engine.
36
37 At Run time each engines Calculate() method is called.
38
39 HISTORY
40 --------------------------------------------------------------------------------
41 08/20/00   JSB   Created
42
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44 INCLUDES
45 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
46
47 #include "FGPropulsion.h"
48 #include "FGRocket.h"
49 #include "FGTurbine.h"
50 #include "FGPiston.h"
51 #include "FGElectric.h"
52 #include "FGPropertyManager.h"
53 #include <sstream>
54
55 namespace JSBSim {
56
57 static const char *IdSrc = "$Id$";
58 static const char *IdHdr = ID_PROPULSION;
59
60 extern short debug_lvl;
61
62
63 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 CLASS IMPLEMENTATION
65 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
66
67 FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
68 {
69   Name = "FGPropulsion";
70
71   numSelectedFuelTanks = numSelectedOxiTanks = 0;
72   numTanks = numEngines = 0;
73   numOxiTanks = numFuelTanks = 0;
74   ActiveEngine = -1; // -1: ALL, 0: Engine 1, 1: Engine 2 ...
75   tankJ.InitMatrix();
76   refuel = false;
77   fuel_freeze = false;
78
79   bind();
80
81   Debug(0);
82 }
83
84 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85
86 FGPropulsion::~FGPropulsion()
87 {
88   for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i];
89   Engines.clear();
90   unbind();
91   Debug(1);
92 }
93
94 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
95
96 bool FGPropulsion::Run(void)
97 {
98   unsigned int i;
99
100   if (FGModel::Run()) return true;
101
102   double dt = State->Getdt();
103
104   vForces.InitMatrix();
105   vMoments.InitMatrix();
106
107   for (i=0; i<numEngines; i++) {
108     Engines[i]->Calculate();
109     vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
110     vMoments += Engines[i]->GetMoments();     // sum body frame moments
111   }
112
113   for (i=0; i<numTanks; i++) {
114     Tanks[i]->Calculate( dt * rate );
115   }
116
117   if (refuel) DoRefuel( dt * rate );
118   
119   return false;
120 }
121
122 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123
124 bool FGPropulsion::GetSteadyState(void)
125 {
126   double currentThrust = 0, lastThrust=-1;
127   int steady_count,j=0;
128   bool steady=false;
129
130   vForces.InitMatrix();
131   vMoments.InitMatrix();
132
133   if (!FGModel::Run()) {
134     for (unsigned int i=0; i<numEngines; i++) {
135       Engines[i]->SetTrimMode(true);
136       steady=false;
137       steady_count=0;
138       while (!steady && j < 6000) {
139         Engines[i]->Calculate();
140         lastThrust = currentThrust;
141         currentThrust = Engines[i]->GetThrust();
142         if (fabs(lastThrust-currentThrust) < 0.0001) {
143           steady_count++;
144           if (steady_count > 120) { steady=true; }
145         } else {
146           steady_count=0;
147         }
148         j++;
149       }
150       vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
151       vMoments += Engines[i]->GetMoments();     // sum body frame moments
152       Engines[i]->SetTrimMode(false);
153     }
154
155     return false;
156   } else {
157     return true;
158   }
159 }
160
161 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
162
163 bool FGPropulsion::ICEngineStart(void)
164 {
165   int j;
166
167   vForces.InitMatrix();
168   vMoments.InitMatrix();
169
170   for (unsigned int i=0; i<numEngines; i++) {
171     Engines[i]->SetTrimMode(true);
172     j=0;
173     while (!Engines[i]->GetRunning() && j < 2000) {
174       Engines[i]->Calculate();
175       j++;
176     }
177     vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
178     vMoments += Engines[i]->GetMoments();     // sum body frame moments
179     Engines[i]->SetTrimMode(false);
180   }
181   return true;
182 }
183
184 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185
186 bool FGPropulsion::Load(FGConfigFile* AC_cfg)
187 {
188   string token, fullpath, localpath;
189   string engineFileName, engType;
190   string parameter;
191   string enginePath = FDMExec->GetEnginePath();
192   string aircraftPath = FDMExec->GetAircraftPath();
193   double xLoc, yLoc, zLoc, Pitch, Yaw;
194   int Feed;
195   bool ThrottleAdded = false;
196   FGConfigFile* Cfg_ptr = 0;
197
198 # ifndef macintosh
199       fullpath = enginePath + "/";
200       localpath = aircraftPath + "/Engines/";
201 # else
202       fullpath = enginePath + ";";
203       localpath = aircraftPath +  ";Engines;";
204 # endif
205
206   AC_cfg->GetNextConfigLine();
207
208   while ((token = AC_cfg->GetValue()) != string("/PROPULSION")) {
209
210     if (token == "AC_ENGINE") {                   // ============ READING ENGINES
211
212       engineFileName = AC_cfg->GetValue("FILE");
213
214       // Look in the Aircraft/Engines directory first
215       Cfg_ptr = 0;
216       FGConfigFile Local_cfg(localpath + engineFileName + ".xml");
217       FGConfigFile Eng_cfg(fullpath + engineFileName + ".xml");
218       if (Local_cfg.IsOpen()) {
219         Cfg_ptr = &Local_cfg;
220         if (debug_lvl > 0) cout << "\n    Reading engine from file: " << localpath
221                                                 + engineFileName + ".xml"<< endl;
222       } else {
223         if (Eng_cfg.IsOpen()) {
224           Cfg_ptr = &Eng_cfg;
225           if (debug_lvl > 0) cout << "\n    Reading engine from file: " << fullpath
226                                                 + engineFileName + ".xml"<< endl;
227         }
228       }
229
230       if (Cfg_ptr) {
231         Cfg_ptr->GetNextConfigLine();
232         engType = Cfg_ptr->GetValue();
233
234         FCS->AddThrottle();
235         ThrottleAdded = true;
236
237         if (engType == "FG_ROCKET") {
238           Engines.push_back(new FGRocket(FDMExec, Cfg_ptr, numEngines));
239         } else if (engType == "FG_PISTON") {
240           Engines.push_back(new FGPiston(FDMExec, Cfg_ptr, numEngines));
241         } else if (engType == "FG_TURBINE") {
242           Engines.push_back(new FGTurbine(FDMExec, Cfg_ptr, numEngines));
243         } else if (engType == "FG_SIMTURBINE") {
244           cerr << endl;
245           cerr << "The FG_SIMTURBINE engine type has been renamed to FG_TURBINE." << endl;
246           cerr << "To fix this problem, simply replace the FG_SIMTURBINE name " << endl;
247           cerr << "in your engine file to FG_TURBINE." << endl;
248           cerr << endl;
249           Engines.push_back(new FGTurbine(FDMExec, Cfg_ptr, numEngines));
250         } else if (engType == "FG_ELECTRIC") {
251           Engines.push_back(new FGElectric(FDMExec, Cfg_ptr, numEngines));
252         } else {
253           cerr << fgred << "    Unrecognized engine type: " << underon << engType
254                     << underoff << " found in config file." << fgdef << endl;
255           return false;
256         }
257
258         Engines.back()->SetEngineFileName(engineFileName);
259
260         AC_cfg->GetNextConfigLine();
261         while ((token = AC_cfg->GetValue()) != string("/AC_ENGINE")) {
262           *AC_cfg >> token;
263           if      (token == "XLOC")  { *AC_cfg >> xLoc; }
264           else if (token == "YLOC")  { *AC_cfg >> yLoc; }
265           else if (token == "ZLOC")  { *AC_cfg >> zLoc; }
266           else if (token == "PITCH") { *AC_cfg >> Pitch;}
267           else if (token == "YAW")   { *AC_cfg >> Yaw;  }
268           else if (token.find("AC_THRUSTER") != string::npos) {
269             if (debug_lvl > 0) cout << "\n    Reading thruster definition" << endl;
270               Engines.back()->LoadThruster(AC_cfg);
271               AC_cfg->GetNextConfigLine();
272           }
273           else if (token == "FEED")  {
274             *AC_cfg >> Feed;
275             Engines[numEngines]->AddFeedTank(Feed);
276             if (debug_lvl > 0) cout << "      Feed tank: " << Feed << endl;
277           } else cerr << "Unknown identifier: " << token << " in engine file: "
278                                                         << engineFileName << endl;
279         }
280
281         if (debug_lvl > 0)  {
282           cout << "      X = " << xLoc << endl;
283           cout << "      Y = " << yLoc << endl;
284           cout << "      Z = " << zLoc << endl;
285           cout << "      Pitch = " << Pitch << endl;
286           cout << "      Yaw = " << Yaw << endl;
287         }
288
289         Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
290         numEngines++;
291
292       } else {
293
294         cerr << fgred << "\n  Could not read engine config file: " << underon <<
295                     engineFileName + ".xml" << underoff << fgdef << endl;
296         return false;
297       }
298
299     } else if (token == "AC_TANK") {              // ============== READING TANKS
300
301       if (debug_lvl > 0) cout << "\n    Reading tank definition" << endl;
302       Tanks.push_back(new FGTank(AC_cfg, FDMExec));
303       switch(Tanks[numTanks]->GetType()) {
304       case FGTank::ttFUEL:
305         numSelectedFuelTanks++;
306         numFuelTanks++;
307         break;
308       case FGTank::ttOXIDIZER:
309         numSelectedOxiTanks++;
310         numOxiTanks++;
311         break;
312       }
313
314       numTanks++;
315     }
316     AC_cfg->GetNextConfigLine();
317   }
318
319   CalculateTankInertias();
320   if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle
321
322   return true;
323 }
324
325 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326
327 string FGPropulsion::GetPropulsionStrings(string delimeter)
328 {
329   unsigned int i;
330
331   string PropulsionStrings = "";
332   bool firstime = true;
333   stringstream buf;
334
335   for (i=0; i<Engines.size(); i++) {
336     if (firstime)  firstime = false;
337     else           PropulsionStrings += delimeter;
338
339     PropulsionStrings += Engines[i]->GetEngineLabels(delimeter);
340   }
341   for (i=0; i<Tanks.size(); i++) {
342     if (Tanks[i]->GetType() == FGTank::ttFUEL) buf << delimeter << "Fuel Tank " << i;
343     else if (Tanks[i]->GetType() == FGTank::ttOXIDIZER) buf << delimeter << "Oxidizer Tank " << i;
344   }
345
346   return PropulsionStrings;
347 }
348
349 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350
351 string FGPropulsion::GetPropulsionValues(string delimeter)
352 {
353   unsigned int i;
354
355   string PropulsionValues = "";
356   bool firstime = true;
357   stringstream buf;
358
359   for (i=0; i<Engines.size(); i++) {
360     if (firstime)  firstime = false;
361     else           PropulsionValues += delimeter;
362
363     PropulsionValues += Engines[i]->GetEngineValues(delimeter);
364   }
365   for (i=0; i<Tanks.size(); i++) {
366     buf << delimeter;
367     buf << Tanks[i]->GetContents();
368   }
369
370   return PropulsionValues;
371 }
372
373 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374
375 FGColumnVector3& FGPropulsion::GetTanksMoment(void)
376 {
377   iTank = Tanks.begin();
378   vXYZtank_arm.InitMatrix();
379   while (iTank < Tanks.end()) {
380     vXYZtank_arm(eX) += (*iTank)->GetXYZ(eX)*(*iTank)->GetContents();
381     vXYZtank_arm(eY) += (*iTank)->GetXYZ(eY)*(*iTank)->GetContents();
382     vXYZtank_arm(eZ) += (*iTank)->GetXYZ(eZ)*(*iTank)->GetContents();
383     iTank++;
384   }
385   return vXYZtank_arm;
386 }
387
388 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389
390 double FGPropulsion::GetTanksWeight(void)
391 {
392   double Tw = 0.0;
393
394   iTank = Tanks.begin();
395   while (iTank < Tanks.end()) {
396     Tw += (*iTank)->GetContents();
397     iTank++;
398   }
399   return Tw;
400 }
401
402 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403
404 FGMatrix33& FGPropulsion::CalculateTankInertias(void)
405 {
406   unsigned int size;
407
408   size = Tanks.size();
409   if (size == 0) return tankJ;
410
411   tankJ = FGMatrix33();
412
413   for (unsigned int i=0; i<size; i++)
414     tankJ += MassBalance->GetPointmassInertia( lbtoslug * Tanks[i]->GetContents(),
415                                                Tanks[i]->GetXYZ() );
416
417   return tankJ;
418 }
419
420 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421
422 void FGPropulsion::SetMagnetos(int setting)
423 {
424   if (ActiveEngine < 0) {
425     for (unsigned i=0; i<Engines.size(); i++) {
426       ((FGPiston*)Engines[i])->SetMagnetos(setting);
427     }
428   } else {
429     ((FGPiston*)Engines[ActiveEngine])->SetMagnetos(setting);
430   }
431 }
432
433 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434
435 void FGPropulsion::SetStarter(int setting)
436 {
437   if (ActiveEngine < 0) {
438     for (unsigned i=0; i<Engines.size(); i++) {
439       if (setting == 0)
440         Engines[i]->SetStarter(false);
441       else
442         Engines[i]->SetStarter(true);
443     }
444   } else {
445     if (setting == 0)
446       Engines[ActiveEngine]->SetStarter(false);
447     else
448       Engines[ActiveEngine]->SetStarter(true);
449   }
450 }
451
452 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453
454 void FGPropulsion::SetCutoff(int setting)
455 {
456   if (ActiveEngine < 0) {
457     for (unsigned i=0; i<Engines.size(); i++) {
458       if (setting == 0)
459         ((FGTurbine*)Engines[i])->SetCutoff(false);
460       else
461         ((FGTurbine*)Engines[i])->SetCutoff(true);
462     }
463   } else {
464     if (setting == 0)
465       ((FGTurbine*)Engines[ActiveEngine])->SetCutoff(false);
466     else
467       ((FGTurbine*)Engines[ActiveEngine])->SetCutoff(true);
468   }
469 }
470
471 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472
473 void FGPropulsion::SetActiveEngine(int engine)
474 {
475   if (engine >= Engines.size() || engine < 0)
476     ActiveEngine = -1;
477   else
478     ActiveEngine = engine;
479 }
480
481 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482
483 double FGPropulsion::Transfer(int source, int target, double amount)
484 {
485  double shortage, overage;
486
487   if (source == -1) {
488      shortage = 0.0;
489   } else {
490      shortage = Tanks[source]->Drain(amount);
491   }
492   if (target == -1) {
493      overage = 0.0;
494   } else {
495      overage = Tanks[target]->Fill(amount - shortage);
496   }
497   return overage;
498 }
499
500 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501
502 void FGPropulsion::DoRefuel(double time_slice)
503 {
504   double fillrate = 100 * time_slice;   // 100 lbs/sec = 6000 lbs/min
505   int TanksNotFull = 0;
506
507   for (unsigned int i=0; i<numTanks; i++) {
508     if (Tanks[i]->GetPctFull() < 99.99) ++TanksNotFull;
509   }
510
511   if (TanksNotFull) {
512     for (unsigned int i=0; i<numTanks; i++) {
513       if (Tanks[i]->GetPctFull() < 99.99)
514           Transfer(-1, i, fillrate/TanksNotFull);
515     }
516   }
517 }
518
519 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
520
521 void FGPropulsion::SetFuelFreeze(bool f) 
522 {
523   fuel_freeze = f;
524   for (unsigned int i=0; i<numEngines; i++) {
525     Engines[i]->SetFuelFreeze(f);
526   }
527 }  
528  
529 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530
531 void FGPropulsion::bind(void)
532 {
533   typedef double (FGPropulsion::*PMF)(int) const;
534   typedef int (FGPropulsion::*iPMF)(void) const;
535
536   PropertyManager->Tie("propulsion/magneto_cmd", this,
537                        (iPMF)0, &FGPropulsion::SetMagnetos, true);
538   PropertyManager->Tie("propulsion/starter_cmd", this,
539                        (iPMF)0, &FGPropulsion::SetStarter,  true);
540   PropertyManager->Tie("propulsion/cutoff_cmd", this,
541                        (iPMF)0, &FGPropulsion::SetCutoff,   true);
542
543   PropertyManager->Tie("forces/fbx-prop-lbs", this,1,
544                        (PMF)&FGPropulsion::GetForces);
545   PropertyManager->Tie("forces/fby-prop-lbs", this,2,
546                        (PMF)&FGPropulsion::GetForces);
547   PropertyManager->Tie("forces/fbz-prop-lbs", this,3,
548                        (PMF)&FGPropulsion::GetForces);
549   PropertyManager->Tie("moments/l-prop-lbsft", this,1,
550                        (PMF)&FGPropulsion::GetMoments);
551   PropertyManager->Tie("moments/m-prop-lbsft", this,2,
552                        (PMF)&FGPropulsion::GetMoments);
553   PropertyManager->Tie("moments/n-prop-lbsft", this,3,
554                        (PMF)&FGPropulsion::GetMoments);
555
556   PropertyManager->Tie("propulsion/active_engine", this,
557            (iPMF)&FGPropulsion::GetActiveEngine, &FGPropulsion::SetActiveEngine, true);
558 }
559
560 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561
562 void FGPropulsion::unbind(void)
563 {
564   PropertyManager->Untie("propulsion/magneto_cmd");
565   PropertyManager->Untie("propulsion/starter_cmd");
566   PropertyManager->Untie("propulsion/cutoff_cmd");
567   PropertyManager->Untie("propulsion/active_engine");
568   PropertyManager->Untie("forces/fbx-prop-lbs");
569   PropertyManager->Untie("forces/fby-prop-lbs");
570   PropertyManager->Untie("forces/fbz-prop-lbs");
571   PropertyManager->Untie("moments/l-prop-lbsft");
572   PropertyManager->Untie("moments/m-prop-lbsft");
573   PropertyManager->Untie("moments/n-prop-lbsft");
574 }
575
576 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
577 //    The bitmasked value choices are as follows:
578 //    unset: In this case (the default) JSBSim would only print
579 //       out the normally expected messages, essentially echoing
580 //       the config files as they are read. If the environment
581 //       variable is not set, debug_lvl is set to 1 internally
582 //    0: This requests JSBSim not to output any messages
583 //       whatsoever.
584 //    1: This value explicity requests the normal JSBSim
585 //       startup messages
586 //    2: This value asks for a message to be printed out when
587 //       a class is instantiated
588 //    4: When this value is set, a message is displayed when a
589 //       FGModel object executes its Run() method
590 //    8: When this value is set, various runtime state variables
591 //       are printed out periodically
592 //    16: When set various parameters are sanity checked and
593 //       a message is printed out when they go out of bounds
594
595 void FGPropulsion::Debug(int from)
596 {
597   if (debug_lvl <= 0) return;
598
599   if (debug_lvl & 1) { // Standard console startup message output
600     if (from == 0) { // Constructor
601
602     }
603   }
604   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
605     if (from == 0) cout << "Instantiated: FGPropulsion" << endl;
606     if (from == 1) cout << "Destroyed:    FGPropulsion" << endl;
607   }
608   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
609   }
610   if (debug_lvl & 8 ) { // Runtime state variables
611   }
612   if (debug_lvl & 16) { // Sanity checking
613   }
614   if (debug_lvl & 64) {
615     if (from == 0) { // Constructor
616       cout << IdSrc << endl;
617       cout << IdHdr << endl;
618     }
619   }
620 }
621 }