1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Module: FGPropulsion.cpp
6 Purpose: Encapsulates the set of engines, tanks, and thrusters associated
9 ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
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
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
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.
25 Further information about the GNU General Public License can also be found on
26 the world wide web at http://www.gnu.org.
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 The Propulsion class is the container for the entire propulsion system, which is
31 comprised of engines, tanks, and "thrusters" (the device that transforms the
32 engine power into a force that acts on the aircraft, such as a nozzle or
33 propeller). Once the Propulsion class gets the config file, it reads in
34 information which is specific to a type of engine. Then:
36 1) The appropriate engine type instance is created
37 2) A thruster object is instantiated, and is linked to the engine
38 3) At least one tank object is created, and is linked to an engine.
40 At Run time each engines Calculate() method is called to return the excess power
41 generated during that iteration. The drag from the previous iteration is sub-
42 tracted to give the excess power available for thrust this pass. That quantity
43 is passed to the thrusters associated with a particular engine - perhaps with a
44 scaling mechanism (gearing?) to allow the engine to give its associated thrust-
45 ers specific distributed portions of the excess power.
48 --------------------------------------------------------------------------------
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
55 #include "FGPropulsion.h"
56 #include "FGPropertyManager.h"
59 static const char *IdSrc = "$Id$";
60 static const char *IdHdr = ID_PROPULSION;
62 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
66 FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
68 Name = "FGPropulsion";
69 numSelectedFuelTanks = numSelectedOxiTanks = 0;
70 numTanks = numEngines = numThrusters = 0;
71 numOxiTanks = numFuelTanks = 0;
77 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79 FGPropulsion::~FGPropulsion()
81 for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i];
87 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 bool FGPropulsion::Run(void)
91 double PowerAvailable;
95 vMoments.InitMatrix();
97 if (!FGModel::Run()) {
98 for (unsigned int i=0; i<numEngines; i++) {
99 Thrusters[i]->SetdeltaT(dt*rate);
100 PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
101 Thrusters[i]->Calculate(PowerAvailable);
102 vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
103 vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
111 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 bool FGPropulsion::GetSteadyState(void)
115 double PowerAvailable;
116 double currentThrust = 0, lastThrust=-1;
118 int steady_count,j=0;
121 vForces.InitMatrix();
122 vMoments.InitMatrix();
124 if (!FGModel::Run()) {
125 for (unsigned int i=0; i<numEngines; i++) {
126 Engines[i]->SetTrimMode(true);
127 Thrusters[i]->SetdeltaT(dt*rate);
130 while (!steady && j < 6000) {
131 PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
132 lastThrust = currentThrust;
133 currentThrust = Thrusters[i]->Calculate(PowerAvailable);
134 if(fabs(lastThrust-currentThrust) < 0.0001) {
136 if(steady_count > 120) { steady=true; }
142 vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
143 vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
144 Engines[i]->SetTrimMode(false);
153 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
155 bool FGPropulsion::ICEngineStart(void)
157 double PowerAvailable;
161 vForces.InitMatrix();
162 vMoments.InitMatrix();
164 for (unsigned int i=0; i<numEngines; i++) {
165 Engines[i]->SetTrimMode(true);
166 Thrusters[i]->SetdeltaT(dt*rate);
168 while (!Engines[i]->GetRunning() && j < 2000) {
169 PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
170 Thrusters[i]->Calculate(PowerAvailable);
173 vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
174 vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
175 Engines[i]->SetTrimMode(false);
180 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 bool FGPropulsion::Load(FGConfigFile* AC_cfg)
184 string token, fullpath;
185 string engineFileName, engType;
186 string thrusterFileName, thrType;
188 string enginePath = FDMExec->GetEnginePath();
189 double xLoc, yLoc, zLoc, Pitch, Yaw;
190 double P_Factor = 0, Sense = 0.0;
192 bool ThrottleAdded = false;
195 fullpath = enginePath + "/";
197 fullpath = enginePath + ";";
200 AC_cfg->GetNextConfigLine();
202 while ((token = AC_cfg->GetValue()) != string("/PROPULSION")) {
204 if (token == "AC_ENGINE") { // ============ READING ENGINES
206 engineFileName = AC_cfg->GetValue("FILE");
208 if (debug_lvl > 0) cout << "\n Reading engine from file: " << fullpath
209 + engineFileName + ".xml"<< endl;
210 FGConfigFile Eng_cfg(fullpath + engineFileName + ".xml");
212 if (Eng_cfg.IsOpen()) {
213 Eng_cfg.GetNextConfigLine();
214 engType = Eng_cfg.GetValue();
217 ThrottleAdded = true;
219 if (engType == "FG_ROCKET") {
220 Engines.push_back(new FGRocket(FDMExec, &Eng_cfg));
221 } else if (engType == "FG_PISTON") {
222 Engines.push_back(new FGPiston(FDMExec, &Eng_cfg));
223 } else if (engType == "FG_TURBOJET") {
224 Engines.push_back(new FGTurboJet(FDMExec, &Eng_cfg));
225 } else if (engType == "FG_TURBOSHAFT") {
226 Engines.push_back(new FGTurboShaft(FDMExec, &Eng_cfg));
227 } else if (engType == "FG_TURBOPROP") {
228 Engines.push_back(new FGTurboProp(FDMExec, &Eng_cfg));
230 cerr << fgred << " Unrecognized engine type: " << underon << engType
231 << underoff << " found in config file." << fgdef << endl;
235 AC_cfg->GetNextConfigLine();
236 while ((token = AC_cfg->GetValue()) != string("/AC_ENGINE")) {
238 if (token == "XLOC") { *AC_cfg >> xLoc; }
239 else if (token == "YLOC") { *AC_cfg >> yLoc; }
240 else if (token == "ZLOC") { *AC_cfg >> zLoc; }
241 else if (token == "PITCH") { *AC_cfg >> Pitch;}
242 else if (token == "YAW") { *AC_cfg >> Yaw;}
243 else if (token == "FEED") {
245 Engines[numEngines]->AddFeedTank(Feed);
246 if (debug_lvl > 0) cout << " Feed tank: " << Feed << endl;
247 } else cerr << "Unknown identifier: " << token << " in engine file: "
248 << engineFileName << endl;
252 cout << " X = " << xLoc << endl;
253 cout << " Y = " << yLoc << endl;
254 cout << " Z = " << zLoc << endl;
255 cout << " Pitch = " << Pitch << endl;
256 cout << " Yaw = " << Yaw << endl;
259 Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
260 Engines[numEngines]->SetEngineNumber(numEngines);
265 cerr << fgred << "\n Could not read engine config file: " << underon <<
266 fullpath + engineFileName + ".xml" << underoff << fgdef << endl;
270 } else if (token == "AC_TANK") { // ============== READING TANKS
272 if (debug_lvl > 0) cout << "\n Reading tank definition" << endl;
273 Tanks.push_back(new FGTank(AC_cfg));
274 switch(Tanks[numTanks]->GetType()) {
276 numSelectedFuelTanks++;
279 case FGTank::ttOXIDIZER:
280 numSelectedOxiTanks++;
287 } else if (token == "AC_THRUSTER") { // ========== READING THRUSTERS
289 thrusterFileName = AC_cfg->GetValue("FILE");
291 if (debug_lvl > 0) cout << "\n Reading thruster from file: " <<
292 fullpath + thrusterFileName + ".xml" << endl;
293 FGConfigFile Thruster_cfg(fullpath + thrusterFileName + ".xml");
295 if (Thruster_cfg.IsOpen()) {
296 Thruster_cfg.GetNextConfigLine();
297 thrType = Thruster_cfg.GetValue();
299 if (thrType == "FG_PROPELLER") {
300 Thrusters.push_back(new FGPropeller(FDMExec, &Thruster_cfg));
301 } else if (thrType == "FG_NOZZLE") {
302 Thrusters.push_back(new FGNozzle(FDMExec, &Thruster_cfg));
305 AC_cfg->GetNextConfigLine();
306 while ((token = AC_cfg->GetValue()) != string("/AC_THRUSTER")) {
308 if (token == "XLOC") *AC_cfg >> xLoc;
309 else if (token == "YLOC") *AC_cfg >> yLoc;
310 else if (token == "ZLOC") *AC_cfg >> zLoc;
311 else if (token == "PITCH") *AC_cfg >> Pitch;
312 else if (token == "YAW") *AC_cfg >> Yaw;
313 else if (token == "P_FACTOR") *AC_cfg >> P_Factor;
314 else if (token == "SENSE") *AC_cfg >> Sense;
315 else cerr << "Unknown identifier: " << token << " in engine file: "
316 << engineFileName << endl;
319 Thrusters[numThrusters]->SetLocation(xLoc, yLoc, zLoc);
320 Thrusters[numThrusters]->SetAnglesToBody(0, Pitch, Yaw);
321 if (thrType == "FG_PROPELLER" && P_Factor > 0.001) {
322 ((FGPropeller*)Thrusters[numThrusters])->SetPFactor(P_Factor);
323 if (debug_lvl > 0) cout << " P-Factor: " << P_Factor << endl;
324 ((FGPropeller*)Thrusters[numThrusters])->SetSense(fabs(Sense)/Sense);
325 if (debug_lvl > 0) cout << " Sense: " << Sense << endl;
327 Thrusters[numThrusters]->SetdeltaT(dt*rate);
328 Thrusters[numThrusters]->SetThrusterNumber(numThrusters);
332 cerr << "Could not read thruster config file: " << fullpath
333 + thrusterFileName + ".xml" << endl;
338 AC_cfg->GetNextConfigLine();
341 if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle
346 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348 string FGPropulsion::GetPropulsionStrings(void)
350 string PropulsionStrings = "";
351 bool firstime = true;
354 for (unsigned int i=0;i<Engines.size();i++) {
355 if (firstime) firstime = false;
356 else PropulsionStrings += ", ";
358 sprintf(buffer, "%d", i);
360 switch(Engines[i]->GetType()) {
361 case FGEngine::etPiston:
362 PropulsionStrings += (Engines[i]->GetName() + "_PwrAvail[" + buffer + "]");
364 case FGEngine::etRocket:
365 PropulsionStrings += (Engines[i]->GetName() + "_ChamberPress[" + buffer + "]");
367 case FGEngine::etTurboJet:
368 case FGEngine::etTurboProp:
369 case FGEngine::etTurboShaft:
372 PropulsionStrings += "INVALID ENGINE TYPE";
376 PropulsionStrings += ", ";
378 FGPropeller* Propeller = (FGPropeller*)Thrusters[i];
379 switch(Thrusters[i]->GetType()) {
380 case FGThruster::ttNozzle:
381 PropulsionStrings += (Thrusters[i]->GetName() + "_Thrust[" + buffer + "]");
383 case FGThruster::ttRotor:
385 case FGThruster::ttPropeller:
386 PropulsionStrings += (Thrusters[i]->GetName() + "_Torque[" + buffer + "], ");
387 PropulsionStrings += (Thrusters[i]->GetName() + "_PFactor_Roll[" + buffer + "], ");
388 PropulsionStrings += (Thrusters[i]->GetName() + "_PFactor_Pitch[" + buffer + "], ");
389 PropulsionStrings += (Thrusters[i]->GetName() + "_PFactor_Yaw[" + buffer + "], ");
390 PropulsionStrings += (Thrusters[i]->GetName() + "_Thrust[" + buffer + "], ");
391 if (Propeller->IsVPitch())
392 PropulsionStrings += (Thrusters[i]->GetName() + "_Pitch[" + buffer + "], ");
393 PropulsionStrings += (Thrusters[i]->GetName() + "_RPM[" + buffer + "]");
396 PropulsionStrings += "INVALID THRUSTER TYPE";
401 return PropulsionStrings;
404 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
406 string FGPropulsion::GetPropulsionValues(void)
409 string PropulsionValues = "";
410 bool firstime = true;
412 for (unsigned int i=0;i<Engines.size();i++) {
413 if (firstime) firstime = false;
414 else PropulsionValues += ", ";
416 switch(Engines[i]->GetType()) {
417 case FGEngine::etPiston:
418 PropulsionValues += (string(gcvt(((FGPiston*)Engines[i])->GetPowerAvailable(), 10, buff)));
420 case FGEngine::etRocket:
421 PropulsionValues += (string(gcvt(((FGRocket*)Engines[i])->GetChamberPressure(), 10, buff)));
423 case FGEngine::etTurboJet:
424 case FGEngine::etTurboProp:
425 case FGEngine::etTurboShaft:
429 PropulsionValues += ", ";
431 switch(Thrusters[i]->GetType()) {
432 case FGThruster::ttNozzle:
433 PropulsionValues += (string(gcvt(((FGNozzle*)Thrusters[i])->GetThrust(), 10, buff)));
435 case FGThruster::ttRotor:
437 case FGThruster::ttPropeller:
438 FGPropeller* Propeller = (FGPropeller*)Thrusters[i];
439 FGColumnVector3 vPFactor = Propeller->GetPFactor();
440 PropulsionValues += string(gcvt(Propeller->GetTorque(), 10, buff)) + ", ";
441 PropulsionValues += string(gcvt(vPFactor(eRoll), 10, buff)) + ", ";
442 PropulsionValues += string(gcvt(vPFactor(ePitch), 10, buff)) + ", ";
443 PropulsionValues += string(gcvt(vPFactor(eYaw), 10, buff)) + ", ";
444 PropulsionValues += string(gcvt(Propeller->GetThrust(), 10, buff)) + ", ";
445 if (Propeller->IsVPitch())
446 PropulsionValues += string(gcvt(Propeller->GetPitch(), 10, buff)) + ", ";
447 PropulsionValues += string(gcvt(Propeller->GetRPM(), 10, buff));
452 return PropulsionValues;
455 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457 FGColumnVector3& FGPropulsion::GetTanksCG(void)
459 iTank = Tanks.begin();
460 vXYZtank.InitMatrix();
461 while (iTank < Tanks.end()) {
462 vXYZtank(eX) += (*iTank)->GetX()*(*iTank)->GetContents();
463 vXYZtank(eY) += (*iTank)->GetY()*(*iTank)->GetContents();
464 vXYZtank(eZ) += (*iTank)->GetZ()*(*iTank)->GetContents();
470 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472 double FGPropulsion::GetTanksWeight(void)
476 iTank = Tanks.begin();
477 while (iTank < Tanks.end()) {
478 Tw += (*iTank)->GetContents();
484 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
486 double FGPropulsion::GetTanksIxx(const FGColumnVector3& vXYZcg)
489 iTank = Tanks.begin();
490 while (iTank < Tanks.end()) {
491 I += ((*iTank)->GetX() - vXYZcg(eX))*((*iTank)->GetX() - vXYZcg(eX)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
497 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 double FGPropulsion::GetTanksIyy(const FGColumnVector3& vXYZcg)
502 iTank = Tanks.begin();
503 while (iTank < Tanks.end()) {
504 I += ((*iTank)->GetY() - vXYZcg(eY))*((*iTank)->GetY() - vXYZcg(eY)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
510 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
512 double FGPropulsion::GetTanksIzz(const FGColumnVector3& vXYZcg)
515 iTank = Tanks.begin();
516 while (iTank < Tanks.end()) {
517 I += ((*iTank)->GetZ() - vXYZcg(eZ))*((*iTank)->GetZ() - vXYZcg(eZ)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
523 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
525 double FGPropulsion::GetTanksIxz(const FGColumnVector3& vXYZcg)
528 iTank = Tanks.begin();
529 while (iTank < Tanks.end()) {
530 I += ((*iTank)->GetX() - vXYZcg(eX))*((*iTank)->GetZ() - vXYZcg(eZ)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
536 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
538 double FGPropulsion::GetTanksIxy(const FGColumnVector3& vXYZcg)
541 iTank = Tanks.begin();
542 while (iTank != Tanks.end()) {
543 I += ((*iTank)->GetX() - vXYZcg(eX))*((*iTank)->GetY() - vXYZcg(eY)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
549 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
551 void FGPropulsion::bind(void){
552 /* PropertyManager->Tie("propulsion/num-engines", this,
553 &FGPropulsion::GetNumEngines);
554 PropertyManager->Tie("propulsion/num-tanks", this,
555 &FGPropulsion::GetNumTanks); */
556 PropertyManager->Tie("propulsion/num-sel-fuel-tanks", this,
557 &FGPropulsion::GetnumSelectedFuelTanks);
558 PropertyManager->Tie("propulsion/num-sel-ox-tanks", this,
559 &FGPropulsion::GetnumSelectedOxiTanks);
560 PropertyManager->Tie("forces/fbx-prop-lbs", this,1,
561 &FGPropulsion::GetForces);
562 PropertyManager->Tie("forces/fby-prop-lbs", this,2,
563 &FGPropulsion::GetForces);
564 PropertyManager->Tie("forces/fbz-prop-lbs", this,3,
565 &FGPropulsion::GetForces);
566 PropertyManager->Tie("moments/l-prop-lbsft", this,1,
567 &FGPropulsion::GetMoments);
568 PropertyManager->Tie("moments/m-prop-lbsft", this,2,
569 &FGPropulsion::GetMoments);
570 PropertyManager->Tie("moments/n-prop-lbsft", this,3,
571 &FGPropulsion::GetMoments);
572 //PropertyManager->Tie("propulsion/tanks-weight-lbs", this,
573 // &FGPropulsion::GetTanksWeight);
576 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 void FGPropulsion::unbind(void){
579 /* PropertyManager->Untie("propulsion/num-engines");
580 PropertyManager->Untie("propulsion/num-tanks"); */
581 PropertyManager->Untie("propulsion/num-sel-fuel-tanks");
582 PropertyManager->Untie("propulsion/num-sel-ox-tanks");
583 PropertyManager->Untie("forces/fbx-prop-lbs");
584 PropertyManager->Untie("forces/fby-prop-lbs");
585 PropertyManager->Untie("forces/fbz-prop-lbs");
586 PropertyManager->Untie("moments/l-prop-lbsft");
587 PropertyManager->Untie("moments/m-prop-lbsft");
588 PropertyManager->Untie("moments/n-prop-lbsft");
589 //PropertyManager->Untie("propulsion/tanks-weight-lbs");
592 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 // The bitmasked value choices are as follows:
594 // unset: In this case (the default) JSBSim would only print
595 // out the normally expected messages, essentially echoing
596 // the config files as they are read. If the environment
597 // variable is not set, debug_lvl is set to 1 internally
598 // 0: This requests JSBSim not to output any messages
600 // 1: This value explicity requests the normal JSBSim
602 // 2: This value asks for a message to be printed out when
603 // a class is instantiated
604 // 4: When this value is set, a message is displayed when a
605 // FGModel object executes its Run() method
606 // 8: When this value is set, various runtime state variables
607 // are printed out periodically
608 // 16: When set various parameters are sanity checked and
609 // a message is printed out when they go out of bounds
611 void FGPropulsion::Debug(int from)
613 if (debug_lvl <= 0) return;
615 if (debug_lvl & 1) { // Standard console startup message output
616 if (from == 0) { // Constructor
620 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
621 if (from == 0) cout << "Instantiated: FGPropulsion" << endl;
622 if (from == 1) cout << "Destroyed: FGPropulsion" << endl;
624 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
626 if (debug_lvl & 8 ) { // Runtime state variables
628 if (debug_lvl & 16) { // Sanity checking
630 if (debug_lvl & 64) {
631 if (from == 0) { // Constructor
632 cout << IdSrc << endl;
633 cout << IdHdr << endl;