]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGFDMExec.cpp
Member variable initialization fixes from Cameron Moore
[flightgear.git] / src / FDM / JSBSim / FGFDMExec.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGFDMExec.cpp
4  Author:       Jon S. Berndt
5  Date started: 11/17/98
6  Purpose:      Schedules and runs the model routines.
7
8  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  details.
19
20  You should have received a copy of the GNU General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA  02111-1307, USA.
23
24  Further information about the GNU General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 FUNCTIONAL DESCRIPTION
28 --------------------------------------------------------------------------------
29
30 This class wraps up the simulation scheduling routines.
31
32 HISTORY
33 --------------------------------------------------------------------------------
34 11/17/98   JSB   Created
35
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 COMMENTS, REFERENCES,  and NOTES
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 INCLUDES
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
43
44 #ifdef FGFS
45 #  include <simgear/compiler.h>
46 #  include STL_IOSTREAM
47 #  include STL_ITERATOR
48 #else
49 #  if defined(sgi) && !defined(__GNUC__)
50 #    include <iostream.h>
51 #  else
52 #    include <iostream>
53 #  endif
54 #  include <iterator>
55 #endif
56
57 #include "FGFDMExec.h"
58 #include "FGState.h"
59 #include "FGAtmosphere.h"
60 #include "FGFCS.h"
61 #include "FGPropulsion.h"
62 #include "FGMassBalance.h"
63 #include "FGGroundReactions.h"
64 #include "FGAerodynamics.h"
65 #include "FGInertial.h"
66 #include "FGAircraft.h"
67 #include "FGTranslation.h"
68 #include "FGRotation.h"
69 #include "FGPosition.h"
70 #include "FGAuxiliary.h"
71 #include "FGOutput.h"
72 #include "FGConfigFile.h"
73 #include "FGInitialCondition.h"
74 #include "FGPropertyManager.h"
75
76 static const char *IdSrc = "$Id$";
77 static const char *IdHdr = ID_FDMEXEC;
78
79 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 GLOBAL DECLARATIONS
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
82
83 unsigned int FGFDMExec::FDMctr = 0;
84 FGPropertyManager* FGFDMExec::master=0;
85
86 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87 CLASS IMPLEMENTATION
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
89
90 // Constructor
91
92 FGFDMExec::FGFDMExec(FGPropertyManager* root)
93 {
94   
95   Frame           = 0;
96   FirstModel      = 0;
97   Error           = 0;
98   State           = 0;
99   Atmosphere      = 0;
100   FCS             = 0;
101   Propulsion      = 0;
102   MassBalance     = 0;
103   Aerodynamics    = 0;
104   Inertial        = 0;
105   GroundReactions = 0;
106   Aircraft        = 0;
107   Translation     = 0;
108   Rotation        = 0;
109   Position        = 0;
110   Auxiliary       = 0;
111   Output          = 0;
112
113   terminate = false;
114   frozen = false;
115   modelLoaded = false;
116   IsSlave = false;
117   
118   cout << "FGFDMExec::FGFDMExec, FDMctr: " << FDMctr << endl;
119   
120   IdFDM = FDMctr;
121   FDMctr++;
122   
123   try {
124     char* num = getenv("JSBSIM_DEBUG");
125     if (!num) debug_lvl = 1;
126     else debug_lvl = atoi(num); // set debug level
127   } catch (...) {               // if error set to 1
128     debug_lvl = 1;
129   }
130
131   if (root == 0)  master= new FGPropertyManager;
132   else            master = root;
133
134   instance = master->GetNode("/fdm/jsbsim",IdFDM,true);
135   
136   Debug(0);
137   
138   // this is here to catch errors in binding member functions
139   // to the property tree.
140   try {
141     Allocate();
142   } catch ( string msg ) {
143     cout << "Caught error: " << msg << endl;
144     exit(1);
145   }    
146 }
147
148 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149
150 FGFDMExec::~FGFDMExec()
151 {
152   try {
153     DeAllocate();
154   } catch ( string msg ) {
155     cout << "Caught error: " << msg << endl;
156   }    
157
158   for (unsigned int i=1; i<SlaveFDMList.size(); i++) delete SlaveFDMList[i]->exec;
159   SlaveFDMList.clear();
160   cout << "FGFDMExec::~FGFDMExec, FDMctr: " << FDMctr << endl;
161   FDMctr--;
162   Debug(1);
163 }
164
165 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166
167 bool FGFDMExec::Allocate(void)
168 {
169   bool result=true;
170
171   Atmosphere      = new FGAtmosphere(this);
172   FCS             = new FGFCS(this);
173   Propulsion      = new FGPropulsion(this);
174   MassBalance     = new FGMassBalance(this);
175   Aerodynamics    = new FGAerodynamics (this);
176   Inertial        = new FGInertial(this);
177   GroundReactions = new FGGroundReactions(this);
178   Aircraft        = new FGAircraft(this);
179   Translation     = new FGTranslation(this);
180   Rotation        = new FGRotation(this);
181   Position        = new FGPosition(this);
182   Auxiliary       = new FGAuxiliary(this);
183   Output          = new FGOutput(this);
184
185   State        = new FGState(this); // This must be done here, as the FGState
186                                     // class needs valid pointers to the above
187                                     // model classes
188   
189   // Initialize models so they can communicate with each other
190
191   if (!Atmosphere->InitModel()) {
192     cerr << fgred << "Atmosphere model init failed" << fgdef << endl;
193     Error+=1;}
194   if (!FCS->InitModel())        {
195     cerr << fgred << "FCS model init failed" << fgdef << endl;
196     Error+=2;}
197   if (!Propulsion->InitModel()) {
198     cerr << fgred << "FGPropulsion model init failed" << fgdef << endl;
199     Error+=4;}
200   if (!MassBalance->InitModel()) {
201     cerr << fgred << "FGMassBalance model init failed" << fgdef << endl;
202     Error+=8;}
203   if (!Aerodynamics->InitModel()) {
204     cerr << fgred << "FGAerodynamics model init failed" << fgdef << endl;
205     Error+=16;}
206   if (!Inertial->InitModel()) {
207     cerr << fgred << "FGInertial model init failed" << fgdef << endl;
208     Error+=32;}
209   if (!GroundReactions->InitModel())   {
210     cerr << fgred << "Ground Reactions model init failed" << fgdef << endl;
211     Error+=64;}
212   if (!Aircraft->InitModel())   {
213     cerr << fgred << "Aircraft model init failed" << fgdef << endl;
214     Error+=128;}
215   if (!Translation->InitModel()) {
216     cerr << fgred << "Translation model init failed" << fgdef << endl;
217     Error+=256;}
218   if (!Rotation->InitModel())   {
219     cerr << fgred << "Rotation model init failed" << fgdef << endl;
220     Error+=512;}
221   if (!Position->InitModel())   {
222     cerr << fgred << "Position model init failed" << fgdef << endl;
223     Error+=1024;}
224   if (!Auxiliary->InitModel())  {
225     cerr << fgred << "Auxiliary model init failed" << fgdef << endl;
226     Error+=2058;}
227   if (!Output->InitModel())     {
228     cerr << fgred << "Output model init failed" << fgdef << endl;
229     Error+=4096;}
230
231   if (Error > 0) result = false;
232
233   // Schedule a model. The second arg (the integer) is the pass number. For
234   // instance, the atmosphere model gets executed every fifth pass it is called
235   // by the executive. Everything else here gets executed each pass.
236
237   Schedule(Atmosphere,      1);
238   Schedule(FCS,             1);
239   Schedule(Propulsion,      1);
240   Schedule(MassBalance,     1);
241   Schedule(Aerodynamics,    1);
242   Schedule(Inertial,        1);
243   Schedule(GroundReactions, 1);
244   Schedule(Aircraft,        1);
245   Schedule(Rotation,        1);
246   Schedule(Translation,     1);
247   Schedule(Position,        1);
248   Schedule(Auxiliary,       1);
249   Schedule(Output,          1);
250
251   modelLoaded = false;
252
253   return result;
254 }
255
256 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257
258 bool FGFDMExec::DeAllocate(void) {
259
260   if ( Atmosphere != 0 )     delete Atmosphere;
261   if ( FCS != 0 )            delete FCS;
262   if ( Propulsion != 0)      delete Propulsion;
263   if ( MassBalance != 0)     delete MassBalance;
264   if ( Aerodynamics != 0)    delete Aerodynamics;
265   if ( Inertial != 0)        delete Inertial;
266   if ( GroundReactions != 0) delete GroundReactions;
267   if ( Aircraft != 0 )       delete Aircraft;
268   if ( Translation != 0 )    delete Translation;
269   if ( Rotation != 0 )       delete Rotation;
270   if ( Position != 0 )       delete Position;
271   if ( Auxiliary != 0 )      delete Auxiliary;
272   if ( Output != 0 )         delete Output;
273   if ( State != 0 )          delete State;
274
275   FirstModel  = 0L;
276   Error       = 0;
277
278   State           = 0;
279   Atmosphere      = 0;
280   FCS             = 0;
281   Propulsion      = 0;
282   MassBalance     = 0;
283   Aerodynamics    = 0;
284   Inertial        = 0;
285   GroundReactions = 0;
286   Aircraft        = 0;
287   Translation     = 0;
288   Rotation        = 0;
289   Position        = 0;
290   Auxiliary       = 0;
291   Output          = 0;
292
293   modelLoaded = false;
294   return modelLoaded;
295 }
296
297 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298
299 int FGFDMExec::Schedule(FGModel* model, int rate)
300 {
301   FGModel* model_iterator;
302
303   model_iterator = FirstModel;
304
305   if (model_iterator == 0L) {                  // this is the first model
306
307     FirstModel = model;
308     FirstModel->NextModel = 0L;
309     FirstModel->SetRate(rate);
310
311   } else {                                     // subsequent model
312
313     while (model_iterator->NextModel != 0L) {
314       model_iterator = model_iterator->NextModel;
315     }
316     model_iterator->NextModel = model;
317     model_iterator->NextModel->SetRate(rate);
318
319   }
320   
321   return 0;
322 }
323
324 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325
326 bool FGFDMExec::Run(void)
327 {
328   FGModel* model_iterator;
329
330   if (frozen) return true;
331
332   model_iterator = FirstModel;
333   if (model_iterator == 0L) return false;
334
335   Debug(2);
336
337   for (unsigned int i=0; i<SlaveFDMList.size(); i++) {
338     // TransferState(i);
339     // Run(i)
340   }
341
342   while (!model_iterator->Run()) {
343     model_iterator = model_iterator->NextModel;
344     if (model_iterator == 0L) break;
345   }
346
347   frame = Frame++;
348   State->IncrTime();
349   return true;
350 }
351
352 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353
354 bool FGFDMExec::RunIC(FGInitialCondition *fgic)
355 {
356   State->Suspend();
357   State->Initialize(fgic);
358   Run();
359   State->Resume();
360   return true;
361 }
362
363 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364
365 vector <string> FGFDMExec::EnumerateFDMs(void)
366 {
367   vector <string> FDMList;
368
369   FDMList.push_back(Aircraft->GetAircraftName());
370
371   for (unsigned int i=1; i<SlaveFDMList.size(); i++) {
372     FDMList.push_back(SlaveFDMList[i]->exec->GetAircraft()->GetAircraftName());
373   }
374
375   return FDMList;
376 }
377
378 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379
380 bool FGFDMExec::LoadModel(string APath, string EPath, string model)
381 {
382   bool result = true;
383   string token;
384   string aircraftCfgFileName;
385
386   AircraftPath = APath;
387   EnginePath   = EPath;
388
389 # ifndef macintosh
390   aircraftCfgFileName = AircraftPath + "/" + model + "/" + model + ".xml";
391 # else
392   aircraftCfgFileName = AircraftPath + ";" + model + ";" + model + ".xml";
393 # endif
394
395   FGConfigFile AC_cfg(aircraftCfgFileName);
396   if (!AC_cfg.IsOpen()) return false;
397
398   if (modelLoaded) {
399     DeAllocate();
400     Allocate();
401   }
402
403   if (!ReadPrologue(&AC_cfg)) return false;
404
405   while ((AC_cfg.GetNextConfigLine() != string("EOF")) &&
406          (token = AC_cfg.GetValue()) != string("/FDM_CONFIG")) {
407     if (token == "METRICS") {
408       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Metrics" << fgdef << endl;
409       if (!ReadMetrics(&AC_cfg)) result = false;
410     } else if (token == "SLAVE") {
411       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Slave flight vehicle: " << fgdef
412                                         << AC_cfg.GetValue("NAME") << endl;
413       if (!ReadSlave(&AC_cfg)) result = false;
414     } else if (token == "AERODYNAMICS") {
415       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Aerodynamics" << fgdef << endl;
416       if (!ReadAerodynamics(&AC_cfg)) result = false;
417     } else if (token == "UNDERCARRIAGE") {
418       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Landing Gear" << fgdef << endl;
419       if (!ReadUndercarriage(&AC_cfg)) result = false;
420     } else if (token == "PROPULSION") {
421       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Propulsion" << fgdef << endl;
422       if (!ReadPropulsion(&AC_cfg)) result = false;
423     } else if (token == "FLIGHT_CONTROL") {
424       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Flight Control" << fgdef << endl;
425       if (!ReadFlightControls(&AC_cfg)) result = false;
426     } else if (token == "OUTPUT") {
427       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Output directives" << fgdef << endl;
428       if (!ReadOutput(&AC_cfg)) result = false;
429     }
430   }
431
432   if (result) {
433     modelLoaded = true;
434     Debug(3);
435   } else {
436     cerr << fgred
437          << "  FGFDMExec: Failed to load aircraft and/or engine model"
438          << fgdef << endl;
439   }
440
441   return result;
442 }
443
444 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445
446 bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
447 {
448   string token = AC_cfg->GetValue();
449   string scratch;
450   string AircraftName;
451
452   AircraftName = AC_cfg->GetValue("NAME");
453   Aircraft->SetAircraftName(AircraftName);
454
455   if (debug_lvl > 0) cout << underon << "Reading Aircraft Configuration File"
456             << underoff << ": " << highint << AircraftName << normint << endl;
457   scratch = AC_cfg->GetValue("VERSION").c_str();
458
459   CFGVersion = AC_cfg->GetValue("VERSION");
460
461   if (debug_lvl > 0)
462     cout << "                            Version: " << highint << CFGVersion
463                                                     << normint << endl;
464   if (CFGVersion != needed_cfg_version) {
465     cerr << endl << fgred << "YOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT."
466             " RESULTS WILL BE UNPREDICTABLE !!" << endl;
467     cerr << "Current version needed is: " << needed_cfg_version << endl;
468     cerr << "         You have version: " << CFGVersion << endl << fgdef << endl;
469     return false;
470   }
471
472   return true;
473 }
474
475 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
476
477 bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
478 {
479   // Add a new slaveData object to the slave FDM list
480   // Populate that slaveData element with a new FDMExec object
481   // Set the IsSlave flag for that FDMExec object
482   // Get the aircraft name
483   // set debug level to print out no additional data for slave objects
484   // Load the model given the aircraft name
485   // reset debug level to prior setting
486
487   int saved_debug_lvl = debug_lvl;
488
489   SlaveFDMList.push_back(new slaveData);
490   SlaveFDMList.back()->exec = new FGFDMExec();
491   SlaveFDMList.back()->exec->SetSlave();
492
493   string AircraftName = AC_cfg->GetValue("FILE");
494
495   debug_lvl = 0;
496   SlaveFDMList.back()->exec->LoadModel("aircraft", "engine", AircraftName);
497   debug_lvl = saved_debug_lvl;
498
499   return true;
500 }
501
502 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503
504 bool FGFDMExec::ReadPropulsion(FGConfigFile* AC_cfg)
505 {
506   if (!Propulsion->Load(AC_cfg)) {
507     cerr << "  Propulsion not successfully loaded" << endl;
508     return false;
509   }
510   return true;
511 }
512
513 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514
515 bool FGFDMExec::ReadFlightControls(FGConfigFile* AC_cfg)
516 {
517   if (!FCS->Load(AC_cfg)) {
518     cerr << "  Flight Controls not successfully loaded" << endl;
519     return false;
520   }
521   return true;
522 }
523
524 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
525
526 bool FGFDMExec::ReadAerodynamics(FGConfigFile* AC_cfg)
527 {
528   if (!Aerodynamics->Load(AC_cfg)) {
529     cerr << "  Aerodynamics not successfully loaded" << endl;
530     return false;
531   }
532   return true;
533 }
534
535 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536
537 bool FGFDMExec::ReadUndercarriage(FGConfigFile* AC_cfg)
538 {
539   if (!GroundReactions->Load(AC_cfg)) {
540     cerr << "  Ground Reactions not successfully loaded" << endl;
541     return false;
542   }
543   return true;
544 }
545
546 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
547
548 bool FGFDMExec::ReadMetrics(FGConfigFile* AC_cfg)
549 {
550   if (!Aircraft->Load(AC_cfg)) {
551     cerr << "  Aircraft metrics not successfully loaded" << endl;
552     return false;
553   }
554   return true;
555 }
556
557 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
558
559 bool FGFDMExec::ReadOutput(FGConfigFile* AC_cfg)
560 {
561   if (!Output->Load(AC_cfg)) {
562     cerr << "  Output not successfully loaded" << endl;
563     return false;
564   }
565   return true;
566 }
567
568 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569
570 FGPropertyManager* FGFDMExec::GetPropertyManager(void) { 
571   return instance;
572 }
573
574 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575 //    The bitmasked value choices are as follows:
576 //    unset: In this case (the default) JSBSim would only print
577 //       out the normally expected messages, essentially echoing
578 //       the config files as they are read. If the environment
579 //       variable is not set, debug_lvl is set to 1 internally
580 //    0: This requests JSBSim not to output any messages
581 //       whatsoever.
582 //    1: This value explicity requests the normal JSBSim
583 //       startup messages
584 //    2: This value asks for a message to be printed out when
585 //       a class is instantiated
586 //    4: When this value is set, a message is displayed when a
587 //       FGModel object executes its Run() method
588 //    8: When this value is set, various runtime state variables
589 //       are printed out periodically
590 //    16: When set various parameters are sanity checked and
591 //       a message is printed out when they go out of bounds
592
593 void FGFDMExec::Debug(int from)
594 {
595   if (debug_lvl <= 0) return;
596
597   if (debug_lvl & 1) { // Standard console startup message output
598     if (from == 0) { // Constructor
599       cout << "\n\n     " << highint << underon << "JSBSim Flight Dynamics Model v"
600                                      << JSBSim_version << underoff << normint << endl;
601       cout << halfint << "            [cfg file spec v" << needed_cfg_version << "]\n\n";
602       cout << normint << "JSBSim startup beginning ...\n\n";
603     } else if (from == 3) {
604       cout << "\n\nJSBSim startup complete\n\n";
605     }
606   }
607   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
608     if (from == 0) cout << "Instantiated: FGFDMExec" << endl;
609     if (from == 1) cout << "Destroyed:    FGFDMExec" << endl;
610   }
611   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
612     if (from == 2) {
613       cout << "================== Frame: " << Frame << "  Time: "
614            << State->Getsim_time() << endl;
615     }
616   }
617   if (debug_lvl & 8 ) { // Runtime state variables
618   }
619   if (debug_lvl & 16) { // Sanity checking
620   }
621   if (debug_lvl & 64) {
622     if (from == 0) { // Constructor
623       cout << IdSrc << endl;
624       cout << IdHdr << endl;
625     }
626   }
627 }
628