]> git.mxchange.org Git - flightgear.git/blobdiff - JSBsim/FGAircraft.cpp
Added initial support for native SGI compilers.
[flightgear.git] / JSBsim / FGAircraft.cpp
index d45a379851b68f9b97180749e7a4f1841acaab37..3a0ad8ae8c919d06a135b3ab7d96d6a16a2c6450 100644 (file)
@@ -2,7 +2,7 @@
 
  Module:       FGAircraft.cpp
  Author:       Jon S. Berndt
- Date started: 12/12/98
+ Date started: 12/12/98                                   
  Purpose:      Encapsulates an aircraft
  Called by:    FGFDMExec
 
 
 FUNCTIONAL DESCRIPTION
 --------------------------------------------------------------------------------
-Models the aircraft reactions and forces.
-
-ARGUMENTS
---------------------------------------------------------------------------------
-
+Models the aircraft reactions and forces. This class is instantiated by the
+FGFDMExec class and scheduled as an FDM entry. LoadAircraft() is supplied with a
+name of a valid, registered aircraft, and the data file is parsed.
 
 HISTORY
 --------------------------------------------------------------------------------
@@ -133,34 +131,50 @@ stability derivatives for the aircraft.
 ********************************************************************************
 INCLUDES
 *******************************************************************************/
-#include "FGAircraft.h"
-
-#include <stdlib.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <math.h>
+
+#ifdef FGFS
+#  include <Include/compiler.h>
+#  ifdef FG_HAVE_STD_INCLUDES
+#    include <cmath>
+#  else
+#    include <math.h>
+#  endif
+#else
+#  include <cmath>
+#endif
+
+#include "FGAircraft.h"
+#include "FGTranslation.h"
+#include "FGRotation.h"
+#include "FGAtmosphere.h"
+#include "FGState.h"
+#include "FGFDMExec.h"
+#include "FGFCS.h"
+#include "FGPosition.h"
+#include "FGAuxiliary.h"
+#include "FGOutput.h"
 
 /*******************************************************************************
 ************************************ CODE **************************************
 *******************************************************************************/
 
-
-FGAircraft::FGAircraft(void) : FGModel()
+FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
 {
   int i;
 
-  strcpy(Name,"FGAircraft");
+  Name = "FGAircraft";
 
-  for (i=0;i<6;i++) Axis[i] = (char*)malloc(7);
   for (i=0;i<6;i++) coeff_ctr[i] = 0;
 
-  strcpy(Axis[LiftCoeff],"CLIFT");
-  strcpy(Axis[DragCoeff],"CDRAG");
-  strcpy(Axis[SideCoeff],"CSIDE");
-  strcpy(Axis[RollCoeff],"CROLL");
-  strcpy(Axis[PitchCoeff],"CPITCH");
-  strcpy(Axis[YawCoeff],"CYAW");
+  Axis[LiftCoeff]  = "CLIFT";
+  Axis[DragCoeff]  = "CDRAG";
+  Axis[SideCoeff]  = "CSIDE";
+  Axis[RollCoeff]  = "CROLL";
+  Axis[PitchCoeff] = "CPITCH";
+  Axis[YawCoeff]   = "CYAW";
 }
 
 
@@ -169,65 +183,65 @@ FGAircraft::~FGAircraft(void)
 }
 
 
-bool FGAircraft::LoadAircraft(char* fname)
+bool FGAircraft::LoadAircraft(string aircraft_path, string engine_path, 
+                             string fname)
 {
-  char path[250];
-  char fullpath[275];
-  char filename[275];
-  char aircraftDef[2100];
-  char tag[220];
+  string path;
+  string fullpath;
+  string filename;
+  string aircraftDef;
+  string tag;
   DIR* dir;
   DIR* coeffdir;
-  struct dirent* dirEntry = 0L;
-  struct dirent* coeffdirEntry = 0L;
+  struct dirent* dirEntry;
+  struct dirent* coeffdirEntry;
   struct stat st;
   struct stat st2;
   ifstream coeffInFile;
 
-  char scratch[250];
-
-  sprintf(aircraftDef, "/h/curt/projects/FlightGear/Simulator/FDM/JSBsim/aircraft/%s/%s.dat", fname, fname);
-  ifstream aircraftfile(aircraftDef);
+  aircraftDef = aircraft_path + "/" + fname + "/" + fname + ".dat";
+  ifstream aircraftfile(aircraftDef.c_str());
 
   if (aircraftfile) {
-    aircraftfile >> AircraftName;
-    aircraftfile >> WingArea;
-    aircraftfile >> WingSpan;
-    aircraftfile >> cbar;
-    aircraftfile >> Ixx;
-    aircraftfile >> Iyy;
-    aircraftfile >> Izz;
-    aircraftfile >> Ixz;
-    aircraftfile >> Weight;
-    m = Weight / 32.174;
+    aircraftfile >> AircraftName;   // String with no embedded spaces
+    aircraftfile >> WingArea;       // square feet
+    aircraftfile >> WingSpan;       // feet
+    aircraftfile >> cbar;           // feet
+    aircraftfile >> Ixx;            // slug ft^2
+    aircraftfile >> Iyy;            // "
+    aircraftfile >> Izz;            // "
+    aircraftfile >> Ixz;            // "
+    aircraftfile >> EmptyWeight;    // pounds
+    EmptyMass = EmptyWeight / GRAVITY;
     aircraftfile >> tag;
 
     numTanks = numEngines = 0;
     numSelectedOxiTanks = numSelectedFuelTanks = 0;
 
-    while (strstr(tag,"EOF") == 0) {
-      if (strstr(tag,"CGLOC")) {
-        aircraftfile >> Xcg;
-        aircraftfile >> Ycg;
-        aircraftfile >> Zcg;
-      } else if (strstr(tag,"EYEPOINTLOC")) {
-        aircraftfile >> Xep;
-        aircraftfile >> Yep;
-        aircraftfile >> Zep;
-      } else if (strstr(tag,"TANK")) {
+    while ( !(tag == "EOF") ) {
+      if (tag == "CGLOC") {
+        aircraftfile >> Xcg;        // inches
+        aircraftfile >> Ycg;        // inches
+        aircraftfile >> Zcg;        // inches
+      } else if (tag == "EYEPOINTLOC") {
+        aircraftfile >> Xep;        // inches
+        aircraftfile >> Yep;        // inches
+        aircraftfile >> Zep;        // inches
+      } else if (tag == "TANK") {
         Tank[numTanks] = new FGTank(aircraftfile);
         switch(Tank[numTanks]->GetType()) {
-        case 0:
-          numSelectedOxiTanks++;
-          break;
-        case 1:
+        case FGTank::ttFUEL:
           numSelectedFuelTanks++;
           break;
+        case FGTank::ttOXIDIZER:
+          numSelectedOxiTanks++;
+          break;
         }
         numTanks++;
-      } else if (strstr(tag,"ENGINE")) {
+      } else if (tag == "ENGINE") {
         aircraftfile >> tag;
-        Engine[numEngines] = new FGEngine(tag);
+        Engine[numEngines] = new FGEngine(FDMExec, engine_path, tag, 
+                                         numEngines);
         numEngines++;
       }
       aircraftfile >> tag;
@@ -253,22 +267,22 @@ bool FGAircraft::LoadAircraft(char* fname)
     //       track of the number of coefficients registered for each of the
     //       previously mentioned axis.
 
-    sprintf(path,"/h/curt/projects/FlightGear/Simulator/FDM/JSBsim/aircraft/%s/",AircraftName);
-    if ( dir = opendir(path) ) {
+    path = aircraft_path + "/" + AircraftName + "/";
+    if (dir = opendir(path.c_str())) {
 
       while (dirEntry = readdir(dir)) {
-        sprintf(fullpath,"%s%s",path,dirEntry->d_name);
-        stat(fullpath,&st);
+        fullpath = path + dirEntry->d_name;
+        stat(fullpath.c_str(),&st);
         if ((st.st_mode & S_IFMT) == S_IFDIR) {
           for (int axis_ctr=0; axis_ctr < 6; axis_ctr++) {
-            if (strstr(dirEntry->d_name,Axis[axis_ctr])) {
-              if (coeffdir = opendir(fullpath)) {
+            if (dirEntry->d_name == Axis[axis_ctr]) {
+              if (coeffdir = opendir(fullpath.c_str())) {
                 while (coeffdirEntry = readdir(coeffdir)) {
                   if (coeffdirEntry->d_name[0] != '.') {
-                    sprintf(filename,"%s%s/%s",path,Axis[axis_ctr],coeffdirEntry->d_name);
-                    stat(filename,&st2);
+                    filename = path + Axis[axis_ctr] + "/" + coeffdirEntry->d_name;
+                    stat(filename.c_str(),&st2);
                     if (st2.st_size > 6) {
-                      Coeff[axis_ctr][coeff_ctr[axis_ctr]] = new FGCoefficient(filename);
+                      Coeff[axis_ctr][coeff_ctr[axis_ctr]] = new FGCoefficient(FDMExec, filename);
                       coeff_ctr[axis_ctr]++;
                     }
                   }
@@ -298,6 +312,8 @@ bool FGAircraft::Run(void)
 
     for (int i = 0; i < 3; i++)  Forces[i] = Moments[i] = 0.0;
 
+    MassChange();
+
     FProp(); FAero(); FGear(); FMass();
     MProp(); MAero(); MGear(); MMass();
 
@@ -308,6 +324,64 @@ bool FGAircraft::Run(void)
 }
 
 
+void FGAircraft::MassChange()
+{
+  // UPDATE TANK CONTENTS
+  //
+  // For each engine, cycle through the tanks and draw an equal amount of
+  // fuel (or oxidizer) from each active tank. The needed amount of fuel is
+  // determined by the engine in the FGEngine class. If more fuel is needed
+  // than is available in the tank, then that amount is considered a shortage,
+  // and will be drawn from the next tank. If the engine cannot be fed what it
+  // needs, it will be considered to be starved, and will shut down.
+
+  float Oshortage, Fshortage;
+
+  for (int e=0; e<numEngines; e++) {
+    Fshortage = Oshortage = 0.0;
+    for (int t=0; t<numTanks; t++) {
+      switch(Engine[e]->GetType()) {
+      case FGEngine::etRocket:
+
+        switch(Tank[t]->GetType()) {
+        case FGTank::ttFUEL:
+          if (Tank[t]->GetSelected()) {
+            Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
+                                   numSelectedFuelTanks)*(dt*rate) + Fshortage);
+          }
+          break;
+        case FGTank::ttOXIDIZER:
+          if (Tank[t]->GetSelected()) {
+            Oshortage = Tank[t]->Reduce((Engine[e]->CalcOxidizerNeed()/
+                                    numSelectedOxiTanks)*(dt*rate) + Oshortage);
+          }
+          break;
+        }
+        break;
+
+      case FGEngine::etPiston:
+      case FGEngine::etTurboJet:
+      case FGEngine::etTurboProp:
+
+        if (Tank[t]->GetSelected()) {
+          Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
+                                   numSelectedFuelTanks)*(dt*rate) + Fshortage);
+        }
+        break;
+      }
+    }
+    if ((Fshortage <= 0.0) || (Oshortage <= 0.0)) Engine[e]->SetStarved();
+    else Engine[e]->SetStarved(false);
+  }
+
+  Weight = EmptyWeight;
+  for (int t=0; t<numTanks; t++)
+    Weight += Tank[t]->GetContents();
+
+  Mass = Weight / GRAVITY;
+}
+
+
 void FGAircraft::FAero(void)
 {
   float F[3];
@@ -334,59 +408,17 @@ void FGAircraft::FGear(void)
 
 void FGAircraft::FMass(void)
 {
-  Forces[0] += -g*sin(tht) * m;
-  Forces[1] +=  g*sin(phi)*cos(tht) * m;
-  Forces[2] +=  g*cos(phi)*cos(tht) * m;
+  Forces[0] += -GRAVITY*sin(tht) * Mass;
+  Forces[1] +=  GRAVITY*sin(phi)*cos(tht) * Mass;
+  Forces[2] +=  GRAVITY*cos(phi)*cos(tht) * Mass;
 }
 
 
 void FGAircraft::FProp(void)
 {
-  float Oshortage, Fshortage;
-
   for (int i=0;i<numEngines;i++) {
     Forces[0] += Engine[i]->CalcThrust();
   }
-
-  //
-  // UPDATE TANK CONTENTS
-  //
-  // For each engine, cycle through the tanks and draw an equal amount of
-  // fuel (or oxidizer) from each active tank. The needed amount of fuel is
-  // determined by the engine in the FGEngine class. If more fuel is needed
-  // than is available in the tank, then that amount is considered a shortage,
-  // and will be drawn from the next tank. If the engine cannot be fed what it
-  // needs, it will be considered to be starved, and will shut down.
-
-  for (int e=0; e<numEngines; e++) {
-    Fshortage = Oshortage = 0.0;
-    for (int t=0; t<numTanks; t++) {
-      switch(Engine[e]->GetType()) {
-      case 0: // Rocket
-        switch(Tank[t]->GetType()) {
-        case 0: // Fuel
-          if (Tank[t]->GetSelected()) {
-            Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/numSelectedFuelTanks)*(dt*rate) + Fshortage);
-          }
-          break;
-        case 1: // Oxidizer
-          if (Tank[t]->GetSelected()) {
-            Oshortage = Tank[t]->Reduce((Engine[e]->CalcOxidizerNeed()/numSelectedOxiTanks)*(dt*rate) + Oshortage);
-          }
-          break;
-        }
-        break;
-      default: // piston, turbojet, turbofan, etc.
-        if (Tank[t]->GetSelected()) {
-          Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/numSelectedFuelTanks)*(dt*rate) + Fshortage);
-        }
-        break;
-      }
-    }
-    if ((Fshortage < 0.0) || (Oshortage < 0.0)) Engine[e]->SetStarved();
-    else Engine[e]->SetStarved(false);
-  }
-
 }
 
 
@@ -418,33 +450,17 @@ void FGAircraft::MProp(void)
 
 void FGAircraft::GetState(void)
 {
-  Ixx = State->GetIxx();
-  Iyy = State->GetIyy();
-  Izz = State->GetIzz();
-  Ixz = State->GetIxz();
-  alpha = State->Getalpha();
-  beta = State->Getbeta();
-  m   = State->Getm();
-  phi = State->Getphi();
-  tht = State->Gettht();
-  psi = State->Getpsi();
-  g = State->Getg();
   dt = State->Getdt();
+
+  alpha = Translation->Getalpha();
+  beta = Translation->Getbeta();
+  phi = Rotation->Getphi();
+  tht = Rotation->Gettht();
+  psi = Rotation->Getpsi();
 }
 
 
 void FGAircraft::PutState(void)
 {
-  State->SetIxx(Ixx);
-  State->SetIyy(Iyy);
-  State->SetIzz(Izz);
-  State->SetIxz(Ixz);
-  State->SetFx(Forces[0]);
-  State->SetFy(Forces[1]);
-  State->SetFz(Forces[2]);
-  State->SetL(Moments[0]);
-  State->SetM(Moments[1]);
-  State->SetN(Moments[2]);
-  State->Setm(m);
 }