]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/FGFDMExec.cpp
Updates from JSBSim, including new turbine engine model from David Culp
[flightgear.git] / src / FDM / JSBSim / FGFDMExec.cpp
index 72badc4a55a99b85dc7d29cd963e47187ea68c74..ee6386705eab9641124d7dcfd75005a6f8af0548 100644 (file)
@@ -73,6 +73,8 @@ INCLUDES
 #include "FGInitialCondition.h"
 #include "FGPropertyManager.h"
 
+namespace JSBSim {
+
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FDMEXEC;
 
@@ -87,6 +89,22 @@ FGPropertyManager* FGFDMExec::master=0;
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+void checkTied ( FGPropertyManager *node )
+{
+  int N = node->nChildren();
+  string name;
+
+  for (int i=0; i<N; i++) {
+    if (node->getChild(i)->nChildren() ) {
+      checkTied( (FGPropertyManager*)node->getChild(i) );
+    } else if ( node->getChild(i)->isTied() ) {
+      name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
+      cerr << name << " is tied" << endl;
+    } 
+  }
+}        
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Constructor
 
 FGFDMExec::FGFDMExec(FGPropertyManager* root)
@@ -109,6 +127,8 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
   Position        = 0;
   Auxiliary       = 0;
   Output          = 0;
+  IC              = 0;
+  Trim            = 0;
 
   terminate = false;
   frozen = false;
@@ -117,7 +137,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
 
   IdFDM = FDMctr;
   FDMctr++;
-  
+
   try {
     char* num = getenv("JSBSIM_DEBUG");
     if (!num) debug_lvl = 1;
@@ -130,7 +150,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
   else            master = root;
 
   instance = master->GetNode("/fdm/jsbsim",IdFDM,true);
-  instance->SetDouble("zero",0);  
+
   
   Debug(0);
   
@@ -150,13 +170,14 @@ FGFDMExec::~FGFDMExec()
 {
   try {
     DeAllocate();
+    checkTied( instance );
   } catch ( string msg ) {
     cout << "Caught error: " << msg << endl;
   }    
-
+  
   for (unsigned int i=1; i<SlaveFDMList.size(); i++) delete SlaveFDMList[i]->exec;
   SlaveFDMList.clear();
+  
   Debug(1);
 }
 
@@ -227,10 +248,13 @@ bool FGFDMExec::Allocate(void)
     Error+=4096;}
 
   if (Error > 0) result = false;
-
+  
+  IC = new FGInitialCondition(this); 
+  
   // Schedule a model. The second arg (the integer) is the pass number. For
   // instance, the atmosphere model gets executed every fifth pass it is called
   // by the executive. Everything else here gets executed each pass.
+  // IC and Trim objects are NOT scheduled.
 
   Schedule(Atmosphere,      1);
   Schedule(FCS,             1);
@@ -253,23 +277,26 @@ bool FGFDMExec::Allocate(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGFDMExec::DeAllocate(void) {
-
-  if ( Atmosphere != 0 )     delete Atmosphere;
-  if ( FCS != 0 )            delete FCS;
-  if ( Propulsion != 0)      delete Propulsion;
-  if ( MassBalance != 0)     delete MassBalance;
-  if ( Aerodynamics != 0)    delete Aerodynamics;
-  if ( Inertial != 0)        delete Inertial;
-  if ( GroundReactions != 0) delete GroundReactions;
-  if ( Aircraft != 0 )       delete Aircraft;
-  if ( Translation != 0 )    delete Translation;
-  if ( Rotation != 0 )       delete Rotation;
-  if ( Position != 0 )       delete Position;
-  if ( Auxiliary != 0 )      delete Auxiliary;
-  if ( Output != 0 )         delete Output;
-  if ( State != 0 )          delete State;
-
+bool FGFDMExec::DeAllocate(void)
+{
+  delete Atmosphere;
+  delete FCS;
+  delete Propulsion;
+  delete MassBalance;
+  delete Aerodynamics;
+  delete Inertial;
+  delete GroundReactions;
+  delete Aircraft;
+  delete Translation;
+  delete Rotation;
+  delete Position;
+  delete Auxiliary;
+  delete Output;
+  delete State;
+  
+  delete IC;
+  delete Trim;
+    
   FirstModel  = 0L;
   Error       = 0;
 
@@ -332,14 +359,14 @@ bool FGFDMExec::Run(void)
 
   Debug(2);
 
-  for (unsigned int i=0; i<SlaveFDMList.size(); i++) {
-    // TransferState(i);
-    // Run(i)
+  for (unsigned int i=1; i<SlaveFDMList.size(); i++) {
+//    SlaveFDMList[i]->exec->State->Initialize(); // Transfer state to the slave FDM
+//    SlaveFDMList[i]->exec->Run();
   }
 
-  while (!model_iterator->Run()) {
+  while (model_iterator != 0L) {
+    model_iterator->Run();
     model_iterator = model_iterator->NextModel;
-    if (model_iterator == 0L) break;
   }
 
   frame = Frame++;
@@ -349,23 +376,14 @@ bool FGFDMExec::Run(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGFDMExec::RunIC(FGInitialCondition *fgic)
+bool FGFDMExec::RunIC(void)
 {
   State->Suspend();
-  State->Initialize(fgic);
+  State->Initialize(IC);
   Run();
   State->Resume();
-  return true;
-}
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFDMExec::TransferState(int idxFDM)
-{
-  SlaveFDMList[idxFDM]->exec->GetRotation()->SetEuler(Rotation->GetEuler());
-  SlaveFDMList[idxFDM]->exec->GetRotation()->SetAeroPQR(Rotation->GetAeroPQR());
-  SlaveFDMList[idxFDM]->exec->GetTranslation()->SetAeroUVW(Translation->GetAeroUVW());
-  SlaveFDMList[idxFDM]->exec->GetRotation()->SetEuler(Rotation->GetEuler());
+  return true;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -385,15 +403,28 @@ vector <string> FGFDMExec::EnumerateFDMs(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGFDMExec::LoadModel(string APath, string EPath, string model)
+bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model)
+{
+  FGFDMExec::AircraftPath = AircraftPath;
+  FGFDMExec::EnginePath = EnginePath;
+
+  return LoadModel(model);
+}  
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGFDMExec::LoadModel(string model)
 {
   bool result = true;
   string token;
   string aircraftCfgFileName;
 
-  AircraftPath = APath;
-  EnginePath   = EPath;
-
+  if( AircraftPath.empty() || EnginePath.empty() ) {
+    cerr << "Error: attempted to load aircraft with undefined ";
+    cerr << "aircraft and engine paths" << endl;
+    return false;
+  }
+    
 # ifndef macintosh
   aircraftCfgFileName = AircraftPath + "/" + model + "/" + model + ".xml";
 # else
@@ -402,7 +433,9 @@ bool FGFDMExec::LoadModel(string APath, string EPath, string model)
 
   FGConfigFile AC_cfg(aircraftCfgFileName);
   if (!AC_cfg.IsOpen()) return false;
-
+  
+  modelName = model;
+  
   if (modelLoaded) {
     DeAllocate();
     Allocate();
@@ -431,6 +464,9 @@ bool FGFDMExec::LoadModel(string APath, string EPath, string model)
     } else if (token == "FLIGHT_CONTROL") {
       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Flight Control" << fgdef << endl;
       if (!ReadFlightControls(&AC_cfg)) result = false;
+    } else if (token == "AUTOPILOT") {
+      if (debug_lvl > 0) cout << fgcyan << "\n  Reading Autopilot" << fgdef << endl;
+      if (!ReadFlightControls(&AC_cfg)) result = false;
     } else if (token == "OUTPUT") {
       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Output directives" << fgdef << endl;
       if (!ReadOutput(&AC_cfg)) result = false;
@@ -493,6 +529,7 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
   // reset debug level to prior setting
 
   int saved_debug_lvl = debug_lvl;
+  string token;
 
   SlaveFDMList.push_back(new slaveData);
   SlaveFDMList.back()->exec = new FGFDMExec();
@@ -500,9 +537,33 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
 
   string AircraftName = AC_cfg->GetValue("FILE");
 
-  debug_lvl = 0;
-  SlaveFDMList.back()->exec->LoadModel("aircraft", "engine", AircraftName);
-  debug_lvl = saved_debug_lvl;
+  debug_lvl = 0;                 // turn off debug output for slave vehicle
+  
+  SlaveFDMList.back()->exec->SetAircraftPath( AircraftPath );
+  SlaveFDMList.back()->exec->SetEnginePath( EnginePath );
+  SlaveFDMList.back()->exec->LoadModel(AircraftName);
+  debug_lvl = saved_debug_lvl;   // turn debug output back on for master vehicle
+
+  AC_cfg->GetNextConfigLine();
+  while ((token = AC_cfg->GetValue()) != string("/SLAVE")) {
+    *AC_cfg >> token;
+    if      (token == "XLOC")  { *AC_cfg >> SlaveFDMList.back()->x;    }
+    else if (token == "YLOC")  { *AC_cfg >> SlaveFDMList.back()->y;    }
+    else if (token == "ZLOC")  { *AC_cfg >> SlaveFDMList.back()->z;    }
+    else if (token == "PITCH") { *AC_cfg >> SlaveFDMList.back()->pitch;}
+    else if (token == "YAW")   { *AC_cfg >> SlaveFDMList.back()->yaw;  }
+    else if (token == "ROLL")  { *AC_cfg >> SlaveFDMList.back()->roll;  }
+    else cerr << "Unknown identifier: " << token << " in slave vehicle definition" << endl;
+  }
+
+  if (debug_lvl > 0)  {
+    cout << "      X = " << SlaveFDMList.back()->x << endl;
+    cout << "      Y = " << SlaveFDMList.back()->y << endl;
+    cout << "      Z = " << SlaveFDMList.back()->z << endl;
+    cout << "      Pitch = " << SlaveFDMList.back()->pitch << endl;
+    cout << "      Yaw = " << SlaveFDMList.back()->yaw << endl;
+    cout << "      Roll = " << SlaveFDMList.back()->roll << endl;
+  }
 
   return true;
 }
@@ -579,6 +640,14 @@ FGPropertyManager* FGFDMExec::GetPropertyManager(void) {
   return instance;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGTrim* FGFDMExec::GetTrim(void) { 
+  delete Trim;
+  Trim = new FGTrim(this,tNone);
+  return Trim;
+}
+  
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //    The bitmasked value choices are as follows:
 //    unset: In this case (the default) JSBSim would only print
@@ -602,7 +671,7 @@ void FGFDMExec::Debug(int from)
 {
   if (debug_lvl <= 0) return;
 
-  if (debug_lvl & 1) { // Standard console startup message output
+  if (debug_lvl & 1 && IdFDM == 0) { // Standard console startup message output
     if (from == 0) { // Constructor
       cout << "\n\n     " << highint << underon << "JSBSim Flight Dynamics Model v"
                                      << JSBSim_version << underoff << normint << endl;
@@ -633,4 +702,5 @@ void FGFDMExec::Debug(int from)
     }
   }
 }
+}