]> git.mxchange.org Git - flightgear.git/commitdiff
Syncing with the very latest JSBSim development code.
authorcurt <curt>
Fri, 5 Oct 2001 20:19:59 +0000 (20:19 +0000)
committercurt <curt>
Fri, 5 Oct 2001 20:19:59 +0000 (20:19 +0000)
84 files changed:
src/FDM/JSBSim/FGAerodynamics.cpp
src/FDM/JSBSim/FGAerodynamics.h
src/FDM/JSBSim/FGAircraft.cpp
src/FDM/JSBSim/FGAircraft.h
src/FDM/JSBSim/FGAtmosphere.cpp
src/FDM/JSBSim/FGAtmosphere.h
src/FDM/JSBSim/FGAuxiliary.cpp
src/FDM/JSBSim/FGAuxiliary.h
src/FDM/JSBSim/FGCoefficient.cpp
src/FDM/JSBSim/FGCoefficient.h
src/FDM/JSBSim/FGConfigFile.cpp
src/FDM/JSBSim/FGConfigFile.h
src/FDM/JSBSim/FGDefs.h
src/FDM/JSBSim/FGEngine.cpp
src/FDM/JSBSim/FGEngine.h
src/FDM/JSBSim/FGFCS.cpp
src/FDM/JSBSim/FGFCS.h
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/FGFDMExec.h
src/FDM/JSBSim/FGFactorGroup.cpp
src/FDM/JSBSim/FGFactorGroup.h
src/FDM/JSBSim/FGForce.cpp
src/FDM/JSBSim/FGForce.h
src/FDM/JSBSim/FGGroundReactions.cpp
src/FDM/JSBSim/FGGroundReactions.h
src/FDM/JSBSim/FGInertial.cpp
src/FDM/JSBSim/FGInertial.h
src/FDM/JSBSim/FGInitialCondition.cpp
src/FDM/JSBSim/FGInitialCondition.h
src/FDM/JSBSim/FGLGear.cpp
src/FDM/JSBSim/FGLGear.h
src/FDM/JSBSim/FGMassBalance.cpp
src/FDM/JSBSim/FGMassBalance.h
src/FDM/JSBSim/FGModel.cpp
src/FDM/JSBSim/FGModel.h
src/FDM/JSBSim/FGNozzle.cpp
src/FDM/JSBSim/FGNozzle.h
src/FDM/JSBSim/FGOutput.cpp
src/FDM/JSBSim/FGOutput.h
src/FDM/JSBSim/FGPiston.cpp
src/FDM/JSBSim/FGPiston.h
src/FDM/JSBSim/FGPosition.cpp
src/FDM/JSBSim/FGPosition.h
src/FDM/JSBSim/FGPropeller.cpp
src/FDM/JSBSim/FGPropeller.h
src/FDM/JSBSim/FGPropulsion.cpp
src/FDM/JSBSim/FGPropulsion.h
src/FDM/JSBSim/FGRocket.cpp
src/FDM/JSBSim/FGRotation.cpp
src/FDM/JSBSim/FGRotation.h
src/FDM/JSBSim/FGRotor.cpp
src/FDM/JSBSim/FGState.cpp
src/FDM/JSBSim/FGState.h
src/FDM/JSBSim/FGTable.cpp
src/FDM/JSBSim/FGTable.h
src/FDM/JSBSim/FGTank.cpp
src/FDM/JSBSim/FGTank.h
src/FDM/JSBSim/FGThruster.cpp
src/FDM/JSBSim/FGThruster.h
src/FDM/JSBSim/FGTranslation.cpp
src/FDM/JSBSim/FGTranslation.h
src/FDM/JSBSim/FGTrim.cpp
src/FDM/JSBSim/FGTrim.h
src/FDM/JSBSim/FGTrimAxis.cpp
src/FDM/JSBSim/FGTrimAxis.h
src/FDM/JSBSim/FGTurboJet.cpp
src/FDM/JSBSim/FGTurboProp.cpp
src/FDM/JSBSim/FGTurboShaft.cpp
src/FDM/JSBSim/FGUtility.cpp
src/FDM/JSBSim/FGUtility.h
src/FDM/JSBSim/FGfdmSocket.cpp
src/FDM/JSBSim/FGfdmSocket.h
src/FDM/JSBSim/JSBSim.cpp
src/FDM/JSBSim/Makefile.am
src/FDM/JSBSim/filtersjb/FGDeadBand.cpp
src/FDM/JSBSim/filtersjb/FGFCSComponent.cpp
src/FDM/JSBSim/filtersjb/FGFCSComponent.h
src/FDM/JSBSim/filtersjb/FGFilter.cpp
src/FDM/JSBSim/filtersjb/FGFilter.h
src/FDM/JSBSim/filtersjb/FGFlaps.cpp
src/FDM/JSBSim/filtersjb/FGGain.cpp
src/FDM/JSBSim/filtersjb/FGGradient.cpp
src/FDM/JSBSim/filtersjb/FGSummer.cpp
src/FDM/JSBSim/filtersjb/FGSwitch.cpp

index 2239c150252c68108f57730783caac5ebb1718d6..e373f95ad5505bffd5060d5e3857d4382bc3e392 100644 (file)
@@ -43,8 +43,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_AERODYNAMICS;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -109,16 +107,14 @@ bool FGAerodynamics::Run(void)
 
     vForces = State->GetTs2b(alpha, beta)*vFs;
 
-    // see http://home.earthlink.net/~apeden/jsbsim_moments_due_to_forces.txt
-    // for details on this
-
-    vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX) - MassBalance->GetXYZcg(eX))/12.0;
-    vDXYZcg(eY) =  (Aircraft->GetXYZrp(eY) - MassBalance->GetXYZcg(eY))/12.0;
-    vDXYZcg(eZ) = -(Aircraft->GetXYZrp(eZ) - MassBalance->GetXYZcg(eZ))/12.0;
+    vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX) 
+                      - MassBalance->GetXYZcg(eX))*INCHTOFT;
+    vDXYZcg(eY) =  (Aircraft->GetXYZrp(eY) 
+                      - MassBalance->GetXYZcg(eY))*INCHTOFT;
+    vDXYZcg(eZ) = -(Aircraft->GetXYZrp(eZ) 
+                      - MassBalance->GetXYZcg(eZ))*INCHTOFT;
 
-    vMoments(eL) = vForces(eZ)*vDXYZcg(eY) - vForces(eY)*vDXYZcg(eZ);
-    vMoments(eM) = vForces(eX)*vDXYZcg(eZ) - vForces(eZ)*vDXYZcg(eX);
-    vMoments(eN) = vForces(eY)*vDXYZcg(eX) - vForces(eX)*vDXYZcg(eY);
+    vMoments = vDXYZcg*vForces; // M = r X F
 
     for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
       for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
index 65cffbd7a5e2711fa8c3a53c608f602a36446b3a..fc87b529d7689fd87039e7fe62be3ebe769924c6 100644 (file)
@@ -111,15 +111,17 @@ public:
 
   /** Gets the total aerodynamic force vector.
       @return a force vector reference. */
-  FGColumnVector& GetForces(void) {return vForces;}
+  FGColumnVector3& GetForces(void) {return vForces;}
+  inline float GetForces(int n) {return vForces(n);}
 
   /** Gets the total aerodynamic moment vector.
       @return a moment vector reference. */
-  FGColumnVector& GetMoments(void) {return vMoments;}
+  FGColumnVector3& GetMoments(void) {return vMoments;}
+  inline float GetMoments(int n) {return vMoments(n);}
 
-  inline FGColumnVector GetvLastFs(void) { return vLastFs; }
+  inline FGColumnVector3& GetvLastFs(void) { return vLastFs; }
   inline float GetvLastFs(int axis) { return vLastFs(axis); }
-  inline FGColumnVector GetvFs(void) { return vFs; }
+  inline FGColumnVector3& GetvFs(void) { return vFs; }
   inline float GetvFs(int axis) { return vFs(axis); }
   float GetLoD(void);
 
@@ -140,11 +142,11 @@ private:
   AxisIndex AxisIdx;
   typedef vector<FGCoefficient*> CoeffArray;
   CoeffArray* Coeff;
-  FGColumnVector vFs;
-  FGColumnVector vForces;
-  FGColumnVector vMoments;
-  FGColumnVector vLastFs;
-  FGColumnVector vDXYZcg;
+  FGColumnVector3 vFs;
+  FGColumnVector3 vForces;
+  FGColumnVector3 vMoments;
+  FGColumnVector3 vLastFs;
+  FGColumnVector3 vDXYZcg;
 
   void Debug(void);
 };
index bc73c5c97970ee19d0d6c52fc55fb5b0165380a7..6daa3d42578e9e60fc4334ca0141b09982d6b98d 100644 (file)
@@ -43,59 +43,6 @@ HISTORY
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 COMMENTS, REFERENCES,  and NOTES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
-      Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
-      School, January 1994
-[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
-      JSC 12960, July 1977
-[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
-      NASA-Ames", NASA CR-2497, January 1975
-[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
-      Wiley & Sons, 1979 ISBN 0-471-03032-5
-[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
-      1982 ISBN 0-471-08936-2
-The aerodynamic coefficients used in this model are:
-Longitudinal
-  CL0 - Reference lift at zero alpha
-  CD0 - Reference drag at zero alpha
-  CDM - Drag due to Mach
-  CLa - Lift curve slope (w.r.t. alpha)
-  CDa - Drag curve slope (w.r.t. alpha)
-  CLq - Lift due to pitch rate
-  CLM - Lift due to Mach
-  CLadt - Lift due to alpha rate
-  Cmadt - Pitching Moment due to alpha rate
-  Cm0 - Reference Pitching moment at zero alpha
-  Cma - Pitching moment slope (w.r.t. alpha)
-  Cmq - Pitch damping (pitch moment due to pitch rate)
-  CmM - Pitch Moment due to Mach
-Lateral
-  Cyb - Side force due to sideslip
-  Cyr - Side force due to yaw rate
-  Clb - Dihedral effect (roll moment due to sideslip)
-  Clp - Roll damping (roll moment due to roll rate)
-  Clr - Roll moment due to yaw rate
-  Cnb - Weathercocking stability (yaw moment due to sideslip)
-  Cnp - Rudder adverse yaw (yaw moment due to roll rate)
-  Cnr - Yaw damping (yaw moment due to yaw rate)
-Control
-  CLDe - Lift due to elevator
-  CDDe - Drag due to elevator
-  CyDr - Side force due to rudder
-  CyDa - Side force due to aileron
-  CmDe - Pitch moment due to elevator
-  ClDa - Roll moment due to aileron
-  ClDr - Roll moment due to rudder
-  CnDr - Yaw moment due to rudder
-  CnDa - Yaw moment due to aileron
  
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 INCLUDES
@@ -114,12 +61,17 @@ INCLUDES
 #    include <math.h>
 #  endif
 #else
-#  include <cmath>
+#  if defined (sgi) && !defined(__GNUC__)
+#    include <math.h>
+#  else
+#    include <cmath>
+#  endif
 #endif
 
 #include "FGAircraft.h"
 #include "FGMassBalance.h"
 #include "FGInertial.h"
+#include "FGGroundReactions.h"
 #include "FGAerodynamics.h"
 #include "FGTranslation.h"
 #include "FGRotation.h"
@@ -142,20 +94,6 @@ GLOBAL DATA
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_AIRCRAFT;
 
-extern char highint[5];
-extern char halfint[5];
-extern char normint[6];
-extern char reset[5];
-extern char underon[5];
-extern char underoff[6];
-extern char fgblue[6];
-extern char fgcyan[6];
-extern char fgred[6];
-extern char fggreen[6];
-extern char fgdef[6];
-
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -165,15 +103,15 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
     vForces(3),
     vXYZrp(3),
     vXYZep(3),
-    vEuler(3),
     vDXYZcg(3),
-    vAeroBodyForces(3)
+    vBodyAccel(3)
 {
   Name = "FGAircraft";
-
   GearUp = false;
-
   alphaclmin = alphaclmax = 0;
+  HTailArea = VTailArea = HTailArm = VTailArm = 0.0;
+  lbarh = lbarv = vbarh = vbarv = 0.0;
+  WingIncidence=0;
 
   if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
 }
@@ -217,7 +155,7 @@ bool FGAircraft::Load(FGConfigFile* AC_cfg)
       ReadOutput(AC_cfg);
     }
   }
-
+  
   return true;
 }
 
@@ -226,16 +164,19 @@ bool FGAircraft::Load(FGConfigFile* AC_cfg)
 bool FGAircraft::Run(void)
 {
   if (!FGModel::Run()) {                 // if false then execute this Run()
-    GetState();
-
     vForces.InitMatrix();
-    vMoments.InitMatrix();
-
-    FMProp();
-    FMAero();
-    FMMass();
-    FMGear();
+    vForces += Aerodynamics->GetForces();
+    vForces += Inertial->GetForces();
+    vForces += Propulsion->GetForces();
+    vForces += GroundReactions->GetForces();
 
+    vMoments.InitMatrix();
+    vMoments += Aerodynamics->GetMoments();
+    vMoments += Propulsion->GetMoments();
+    vMoments += GroundReactions->GetMoments();
+    
+    vBodyAccel = vForces/MassBalance->GetMass();
+    
     return false;
   } else {                               // skip Run() execution this time
     return true;
@@ -244,62 +185,12 @@ bool FGAircraft::Run(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGAircraft::FMAero(void)
-{
-    vForces += Aerodynamics->GetForces();
-    vMoments += Aerodynamics->GetMoments();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAircraft::FMGear(void)
-{
-  if ( !GearUp ) {
-    vector <FGLGear>::iterator iGear = lGear.begin();
-    while (iGear != lGear.end()) {
-      vForces  += iGear->Force();
-      vMoments += iGear->Moment();
-      iGear++;
-    }
-  } else {
-    // Crash Routine
-  }
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAircraft::FMMass(void)
-{
-  vForces += Inertial->GetForces();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAircraft::FMProp(void)
-{
-  vForces += Propulsion->GetForces();
-  vMoments += Propulsion->GetMoments();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAircraft::GetState(void)
-{
-  dt = State->Getdt();
-
-  alpha = Translation->Getalpha();
-  beta = Translation->Getbeta();
-  vEuler = Rotation->GetEuler();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
 {
   string token = "";
   string parameter;
   float EW, bixx, biyy, bizz, bixz, biyz;
-  FGColumnVector vbaseXYZcg(3);
+  FGColumnVector3 vbaseXYZcg(3);
 
   AC_cfg->GetNextConfigLine();
 
@@ -311,9 +202,24 @@ void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
     } else if (parameter == "AC_WINGSPAN") {
       *AC_cfg >> WingSpan;
       if (debug_lvl > 0) cout << "    WingSpan: " << WingSpan  << endl;
+    } else if (parameter == "AC_WINGINCIDENCE") {
+      *AC_cfg >> WingIncidence;
+      if (debug_lvl > 0) cout << "    Chord: " << cbar << endl;
     } else if (parameter == "AC_CHORD") {
       *AC_cfg >> cbar;
       if (debug_lvl > 0) cout << "    Chord: " << cbar << endl;
+    } else if (parameter == "AC_HTAILAREA") {
+      *AC_cfg >> HTailArea;
+      if (debug_lvl > 0) cout << "    H. Tail Area: " << HTailArea << endl;
+    } else if (parameter == "AC_HTAILARM") {
+      *AC_cfg >> HTailArm;
+      if (debug_lvl > 0) cout << "    H. Tail Arm: " << HTailArm << endl;
+    } else if (parameter == "AC_VTAILAREA") {
+      *AC_cfg >> VTailArea;
+      if (debug_lvl > 0) cout << "    V. Tail Area: " << VTailArea << endl;
+    } else if (parameter == "AC_VTAILARM") {
+      *AC_cfg >> VTailArm;
+      if (debug_lvl > 0) cout << "    V. Tail Arm: " << VTailArm << endl;
     } else if (parameter == "AC_IXX") {
       *AC_cfg >> bixx;
       if (debug_lvl > 0) cout << "    baseIxx: " << bixx << endl;
@@ -355,11 +261,23 @@ void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
              << endl;
     }
   }
+  
+  // calculate some derived parameters
+  if (cbar != 0.0) {
+    lbarh = HTailArm/cbar;
+    lbarv = VTailArm/cbar;
+    if (WingArea != 0.0) {
+      vbarh = HTailArm*HTailArea / (cbar*WingArea);
+      vbarv = VTailArm*VTailArea / (cbar*WingArea);
+    }
+  }     
+
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg) {
+void FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg)
+{
   if (!Propulsion->Load(AC_cfg)) {
     cerr << "Propulsion not successfully loaded" << endl;
   }
@@ -367,7 +285,8 @@ void FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg) {
+void FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg)
+{
   if (!FCS->Load(AC_cfg)) {
     cerr << "Flight Controls not successfully loaded" << endl;
   }
@@ -380,24 +299,21 @@ void FGAircraft::ReadAerodynamics(FGConfigFile* AC_cfg)
   if (!Aerodynamics->Load(AC_cfg)) {
     cerr << "Aerodynamics not successfully loaded" << endl;
   }
-
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg) {
-  string token;
-
-  AC_cfg->GetNextConfigLine();
-
-  while ((token = AC_cfg->GetValue()) != "/UNDERCARRIAGE") {
-    lGear.push_back(FGLGear(AC_cfg, FDMExec));
+void FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg)
+{
+  if (!GroundReactions->Load(AC_cfg)) {
+    cerr << "Ground Reactions not successfully loaded" << endl;
   }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGAircraft::ReadOutput(FGConfigFile* AC_cfg) {
+void FGAircraft::ReadOutput(FGConfigFile* AC_cfg)
+{
   string token, parameter;
   int OutRate = 0;
   int subsystems = 0;
@@ -473,7 +389,8 @@ void FGAircraft::ReadOutput(FGConfigFile* AC_cfg) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg) {
+void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
+{
   string token = AC_cfg->GetValue();
   string scratch;
   AircraftName = AC_cfg->GetValue("NAME");
@@ -496,46 +413,6 @@ void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGAircraft::GetGroundReactionStrings(void) {
-  string GroundReactionStrings = "";
-  bool firstime = true;
-
-  for (unsigned int i=0;i<lGear.size();i++) {
-    if (!firstime) GroundReactionStrings += ", ";
-    GroundReactionStrings += (lGear[i].GetName() + "_WOW, ");
-    GroundReactionStrings += (lGear[i].GetName() + "_compressLength, ");
-    GroundReactionStrings += (lGear[i].GetName() + "_compressSpeed, ");
-    GroundReactionStrings += (lGear[i].GetName() + "_Force");
-
-    firstime = false;
-  }
-
-  return GroundReactionStrings;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-string FGAircraft::GetGroundReactionValues(void) {
-  char buff[20];
-  string GroundReactionValues = "";
-
-  bool firstime = true;
-
-  for (unsigned int i=0;i<lGear.size();i++) {
-    if (!firstime) GroundReactionValues += ", ";
-    GroundReactionValues += string( lGear[i].GetWOW()?"1":"0" ) + ", ";
-    GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(),    5, buff)) + ", ");
-    GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(),    6, buff)) + ", ");
-    GroundReactionValues += (string(gcvt(lGear[i].GetCompForce(), 10, buff)));
-
-    firstime = false;
-  }
-
-  return GroundReactionValues;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void FGAircraft::Debug(void)
 {
     //TODO: Add your source code here
index 48bfbdc1868e05213e9409ed0385b59a78f56ed1..ae306b0072e74588f16432505f4d21a753f1847b 100644 (file)
@@ -55,7 +55,9 @@ INCLUDES
 #include "FGModel.h"
 #include "FGPropulsion.h"
 #include "FGConfigFile.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 #include "FGLGear.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -70,9 +72,48 @@ FORWARD DECLARATIONS
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Longitudinal
+  CL0 - Reference lift at zero alpha
+  CD0 - Reference drag at zero alpha
+  CDM - Drag due to Mach
+  CLa - Lift curve slope (w.r.t. alpha)
+  CDa - Drag curve slope (w.r.t. alpha)
+  CLq - Lift due to pitch rate
+  CLM - Lift due to Mach
+  CLadt - Lift due to alpha rate
+  Cmadt - Pitching Moment due to alpha rate
+  Cm0 - Reference Pitching moment at zero alpha
+  Cma - Pitching moment slope (w.r.t. alpha)
+  Cmq - Pitch damping (pitch moment due to pitch rate)
+  CmM - Pitch Moment due to Mach
+Lateral
+  Cyb - Side force due to sideslip
+  Cyr - Side force due to yaw rate
+  Clb - Dihedral effect (roll moment due to sideslip)
+  Clp - Roll damping (roll moment due to roll rate)
+  Clr - Roll moment due to yaw rate
+  Cnb - Weathercocking stability (yaw moment due to sideslip)
+  Cnp - Rudder adverse yaw (yaw moment due to roll rate)
+  Cnr - Yaw damping (yaw moment due to yaw rate)
+Control
+  CLDe - Lift due to elevator
+  CDDe - Drag due to elevator
+  CyDr - Side force due to rudder
+  CyDa - Side force due to aileron
+  CmDe - Pitch moment due to elevator
+  ClDa - Roll moment due to aileron
+  ClDr - Roll moment due to rudder
+  CnDr - Yaw moment due to rudder
+  CnDa - Yaw moment due to aileron
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DOCUMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
@@ -107,11 +148,6 @@ CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 class FGAircraft : public FGModel {
-  enum {eL=1, eM, eN};
-  enum {eX=1, eY, eZ};
-  enum {eP=1, eQ, eR};
-  enum {ePhi=1, eTht, ePsi};
-
 public:
   /** Constructor
       @param Executive a pointer to the parent executive object */
@@ -151,12 +187,20 @@ public:
   inline float GetWingSpan(void) { return WingSpan; }
   /// Gets the average wing chord
   inline float Getcbar(void) { return cbar; }
-  inline FGColumnVector GetMoments(void) { return vMoments; }
-  inline FGColumnVector GetForces(void) { return vForces; }
-  inline FGColumnVector GetAeroBodyForces(void) { return vAeroBodyForces; }
-  inline float GetAeroBodyForces(int axis) { return vAeroBodyForces(axis); }
-  inline FGColumnVector GetXYZrp(void) { return vXYZrp; }
-  inline FGColumnVector GetXYZep(void) { return vXYZep; }
+  inline float GetWingIncidence(void) { return WingIncidence; }
+  inline float GetHTailArea(void) { return HTailArea; }
+  inline float GetHTailArm(void)  { return HTailArm; }
+  inline float GetVTailArea(void) { return VTailArea; }
+  inline float GetVTailArm(void)  { return VTailArm; }
+  inline float Getlbarh(void) { return lbarh; } // HTailArm / cbar
+  inline float Getlbarv(void) { return lbarv; } // VTailArm / cbar
+  inline float Getvbarh(void) { return vbarh; } // H. Tail Volume
+  inline float Getvbarv(void) { return vbarv; } // V. Tail Volume
+  inline FGColumnVector3& GetMoments(void) { return vMoments; }
+  inline FGColumnVector3& GetForces(void) { return vForces; }
+  inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
+  inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
+  inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
   inline float GetXYZrp(int idx) { return vXYZrp(idx); }
   inline float GetXYZep(int idx) { return vXYZep(idx); }
   inline float GetAlphaCLMax(void) { return alphaclmax; }
@@ -168,9 +212,6 @@ public:
   inline void SetAlphaCLMax(float tt) { alphaclmax=tt; }
   inline void SetAlphaCLMin(float tt) { alphaclmin=tt; }
 
-  string GetGroundReactionStrings(void);
-  string GetGroundReactionValues(void);
-
   /// Subsystem types for specifying which will be output in the FDM data logging
   enum  SubSystems {
     /** Subsystem: Simulation (= 1)          */ ssSimulation      = 1,
@@ -189,22 +230,17 @@ public:
   } subsystems;
 
 private:
-  void GetState(void);
-  void FMAero(void);
-  void FMGear(void);
-  void FMMass(void);
-  void FMProp(void);
-  FGColumnVector vMoments;
-  FGColumnVector vForces;
-  FGColumnVector vXYZrp;
-  FGColumnVector vXYZep;
-  FGColumnVector vEuler;
-  FGColumnVector vDXYZcg;
-  FGColumnVector vAeroBodyForces;
-  float alpha, beta;
-  float WingArea, WingSpan, cbar;
+  FGColumnVector3 vMoments;
+  FGColumnVector3 vForces;
+  FGColumnVector3 vXYZrp;
+  FGColumnVector3 vXYZep;
+  FGColumnVector3 vEuler;
+  FGColumnVector3 vDXYZcg;
+  FGColumnVector3 vBodyAccel;
+  float WingArea, WingSpan, cbar, WingIncidence;
+  float HTailArea, VTailArea, HTailArm, VTailArm;
+  float lbarh,lbarv,vbarh,vbarv;
   float alphaclmax,alphaclmin;
-  float dt;
   string CFGVersion;
   string AircraftName;
 
index 770e6a5c3d16a84686af846048eb3f15f537b69d..085f95b694c9880bc67d270a8becc97062efaaae 100644 (file)
@@ -57,13 +57,13 @@ INCLUDES
 #include "FGAuxiliary.h"
 #include "FGOutput.h"
 #include "FGDefs.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_ATMOSPHERE;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -73,12 +73,26 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
                                                vWindNED(3)
 {
   Name = "FGAtmosphere";
+  lastIndex=0;
   h = 0;
+  htab[0]=0;
+  htab[1]=36089.239;
+  htab[2]=65616.798;
+  htab[3]=104986.878;
+  htab[4]=154199.475;
+  htab[5]=170603.675;
+  htab[6]=200131.234;
+  htab[7]=259186.352; //ft.
+
   Calculate(h);
   SLtemperature = temperature;
   SLpressure    = pressure;
   SLdensity     = density;
   SLsoundspeed  = sqrt(SHRATIO*Reng*temperature);
+  rSLtemperature = 1.0/temperature;
+  rSLpressure    = 1.0/pressure;
+  rSLdensity     = 1.0/density;
+  rSLsoundspeed  = 1.0/SLsoundspeed;
   useExternal=false;
 
   if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
@@ -95,13 +109,10 @@ FGAtmosphere::~FGAtmosphere()
 
 bool FGAtmosphere::Run(void)
 {
-  //cout << "In FGAtmosphere::Run(void)" << endl;
   if (!FGModel::Run()) {                 // if false then execute this Run()
     //do temp, pressure, and density first
     if (!useExternal) {
-      //cout << "Atmosphere: Using internal model, altitude= ";
       h = Position->Geth();
-
       Calculate(h);
     } else {
       density = exDensity;
@@ -114,7 +125,7 @@ bool FGAtmosphere::Run(void)
     if (psiw < 0) psiw += 2*M_PI;
 
     soundspeed = sqrt(SHRATIO*Reng*temperature);
-    //cout << "Atmosphere: soundspeed: " << soundspeed << endl;
+
     State->Seta(soundspeed);
 
   } else {                               // skip Run() execution this time
@@ -128,84 +139,90 @@ void FGAtmosphere::Calculate(float altitude)
 {
   //see reference [1]
 
-  float slope,reftemp,refpress,refdens;
-  int i=0;
-  float htab[]={0,36089,82020,154198,173882,259183,295272,344484}; //ft.
+  float slope,reftemp,refpress;
+  int i=0; bool lookup = false;
   // cout << "Atmosphere:  h=" << altitude << " rho= " << density << endl;
-  if (altitude <= htab[0]) {
-    altitude=0;
-  } else if (altitude >= htab[7]){
-    i = 7;
-    altitude = htab[7];
-  } else {
-    while (htab[i+1] < altitude) {
-      i++;
-    }
-  }
+  i=lastIndex;
+  if(altitude < htab[lastIndex]) {
+    if (altitude <= 0) { 
+      i=0; altitude=0;
+    } else {
+       i=lastIndex-1;
+       while (htab[i] > altitude) { i--; }
+    }   
+  } else if (altitude > htab[lastIndex+1]){
+    if (altitude >= htab[7]){
+      i = 7; altitude = htab[7];
+    } else {
+      i=lastIndex+1;
+      while(htab[i+1] < altitude) { i++; } 
+    }  
+  } 
 
   switch(i) {
   case 0:     // sea level
-    slope     = -0.0035662; // R/ft.
-    reftemp   = 518.688;    // R
-    refpress  = 2116.17;    // psf
-    refdens   = 0.0023765;  // slugs/cubic ft.
+    slope     = -0.00356616; // R/ft.
+    reftemp   = 518.67;    // R
+    refpress  = 2116.22;    // psf
+    //refdens   = 0.00237767;  // slugs/cubic ft.
     break;
   case 1:     // 36089 ft.
     slope     = 0;
-    reftemp   = 389.988;
-    refpress  = 474.1;
-    refdens   = 0.0007078;
-    break;
-  case 2:     // 82020 ft.
-    slope     = 0.00164594;
-    reftemp   = 389.988;
-    refpress  = 52.7838;
-    refdens   = 7.8849E-5;
+    reftemp   = 389.97;
+    refpress  = 472.452;
+    //refdens   = 0.000706032;
     break;
-  case 3:     // 154198 ft.
-    slope     = 0;
-    reftemp   = 508.788;
-    refpress  = 2.62274;
-    refdens   = 3.01379E-6;
+  case 2:     // 65616 ft.
+    slope     = 0.00054864;
+    reftemp   = 389.97;
+    refpress  = 114.636;
+    //refdens   = 0.000171306;
     break;
-  case 4:     // 173882 ft.
-    slope     = -0.00246891;
-    reftemp   = 508.788;
-    refpress  = 1.28428;
-    refdens   = 1.47035e-06;
+  case 3:     // 104986 ft.
+    slope     = 0.00153619;
+    reftemp   = 411.57;
+    refpress  = 8.36364;
+    //refdens   = 1.18422e-05;
     break;
-  case 5:     // 259183 ft.
+  case 4:     // 154199 ft.
     slope     = 0;
-    reftemp   = 298.188;
-    refpress  = 0.0222008;
-    refdens   = 4.33396e-08;
+    reftemp   = 487.17;
+    refpress  = 0.334882;
+    //refdens   = 4.00585e-7;
+    break;
+  case 5:     // 170603 ft.
+    slope     = -0.00109728;
+    reftemp   = 487.17;
+    refpress  = 0.683084;
+    //refdens   = 8.17102e-7;
     break;
-  case 6:     // 295272 ft.
-    slope     = 0.00219459;
-    reftemp   = 298.188;
-    refpress  = 0.00215742;
-    refdens   = 4.21368e-09;
+  case 6:     // 200131 ft.
+    slope     = -0.00219456;
+    reftemp   = 454.17;
+    refpress  = 0.00684986;
+    //refdens   = 8.77702e-9;
     break;
-  case 7:     // 344484 ft.
+  case 7:     // 259186 ft.
     slope     = 0;
-    reftemp   = 406.188;
-    refpress  = 0.000153755;
-    refdens   = 2.20384e-10;
+    reftemp   = 325.17;
+    refpress  = 0.000122276;
+    //refdens   = 2.19541e-10;
     break;
   }
-
   if (slope == 0) {
     temperature = reftemp;
     pressure = refpress*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
-    density = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
+    //density = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
+    density = pressure/(Reng*temperature);
   } else {
     temperature = reftemp+slope*(altitude-htab[i]);
     pressure = refpress*pow(temperature/reftemp,-GRAVITY/(slope*Reng));
-    density = refdens*pow(temperature/reftemp,-(GRAVITY/(slope*Reng)+1));
+    //density = refdens*pow(temperature/reftemp,-(GRAVITY/(slope*Reng)+1));
+    density = pressure/(Reng*temperature);
   }
-
+  lastIndex=i;
   //cout << "Atmosphere:  h=" << altitude << " rho= " << density << endl;
-
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 1a1bd1aa23362514eba9f00788b8514615fc2e39..6b61ce0b5c3bab5707de38b01e9b73f63dbc7e0b 100644 (file)
@@ -43,69 +43,116 @@ INCLUDES
 *******************************************************************************/
 
 #include "FGModel.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #define ID_ATMOSPHERE "$Id$"
 
-/*******************************************************************************
-COMMENTS, REFERENCES,  and NOTES
-********************************************************************************
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 [1]   Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
       1989, ISBN 0-07-001641-0
-*******************************************************************************
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Models the standard atmosphere.
+    @author Tony Peden, Jon Berndt
+    @version $Id$
+*/
+
+/******************************************************************************
 CLASS DECLARATION
 *******************************************************************************/
 
 class FGAtmosphere : public FGModel {
 public:
 
+  /// Constructor
   FGAtmosphere(FGFDMExec*);
+  /// Destructor
   ~FGAtmosphere();
+  /** Runs the Atmosphere model; called by the Executive
+      @return false if no error */
   bool Run(void);
 
+  /// Returns the temperature in degrees Rankine.
   inline float GetTemperature(void) {return temperature;}
-  inline float GetDensity(void)    {return density;}     // use only after Run() has been called
+  /** Returns the density in slugs/ft^3.
+      <i>This function may <b>only</b> be used if Run() is called first.</i> */
+  inline float GetDensity(void)    {return density;}
+  /// Returns the pressure in psf.
   inline float GetPressure(void)   {return pressure;}
+  /// Returns the speed of sound in ft/sec.
   inline float GetSoundSpeed(void) {return soundspeed;}
 
-  inline float GetTemperatureSL(void) { return SLtemperature; }  //Rankine, altitude in feet
-  inline float GetDensitySL(void)     { return SLdensity; }      //slugs/ft^3
-  inline float GetPressureSL(void)    { return SLpressure; }     //lbs/ft^2
-  inline float GetSoundSpeedSL(void)  { return SLsoundspeed; }   //ft/s
-
-  inline float GetTemperatureRatio(void)  { return temperature/SLtemperature; }
-  inline float GetDensityRatio(void)     { return density/SLdensity; }
-  inline float GetPressureRatio(void)     { return pressure/SLpressure; }
-  inline float GetSoundSpeedRatio(void)   { return soundspeed/SLsoundspeed; }
-
+  /// Returns the sea level temperature in degrees Rankine.
+  inline float GetTemperatureSL(void) { return SLtemperature; }
+  /// Returns the sea level density in slugs/ft^3
+  inline float GetDensitySL(void)     { return SLdensity; }
+  /// Returns the sea level pressure in psf.
+  inline float GetPressureSL(void)    { return SLpressure; }
+  /// Returns the sea level speed of sound in ft/sec.
+  inline float GetSoundSpeedSL(void)  { return SLsoundspeed; }
+
+  /// Returns the ratio of at-altitude temperature over the sea level value.
+  inline float GetTemperatureRatio(void)  { return temperature*rSLtemperature; }
+  /// Returns the ratio of at-altitude density over the sea level value.
+  inline float GetDensityRatio(void)     { return density*rSLdensity; }
+  /// Returns the ratio of at-altitude pressure over the sea level value.
+  inline float GetPressureRatio(void)     { return pressure*rSLpressure; }
+  /// Returns the ratio of at-altitude sound speed over the sea level value.
+  inline float GetSoundSpeedRatio(void)   { return soundspeed*rSLsoundspeed; }
+
+  /// Tells the simulator to use an externally calculated atmosphere model.
   inline void UseExternal(void)          { useExternal=true;  }
+  /// Tells the simulator to use the internal atmosphere model.
   inline void UseInternal(void)          { useExternal=false; } //this is the default
+  /// Gets the boolean that tells if the external atmosphere model is being used.
   bool External(void) { return useExternal; }
 
+  /// Provides the external atmosphere model with an interface to set the temperature.
   inline void SetExTemperature(float t)  { exTemperature=t; }
+  /// Provides the external atmosphere model with an interface to set the density.
   inline void SetExDensity(float d)      { exDensity=d; }
+  /// Provides the external atmosphere model with an interface to set the pressure.
   inline void SetExPressure(float p)     { exPressure=p; }
 
+  /// Sets the wind components in NED frame.
   inline void SetWindNED(float wN, float wE, float wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
 
-  inline FGColumnVector GetWindNED(void) { return vWindNED; }
+  /// Retrieves the wind components in NED frame.
+  inline FGColumnVector3& GetWindNED(void) { return vWindNED; }
   
+  /** Retrieves the wind direction. The direction is defined as north=0 and
+      increases counterclockwise. The wind heading is returned in radians.*/
   inline float GetWindPsi(void) { return psiw; }
   
-protected:
-
 private:
   float rho;
 
+  int lastIndex;
   float h;
+  float htab[8];
   float SLtemperature,SLdensity,SLpressure,SLsoundspeed;
+  float rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
   float temperature,density,pressure,soundspeed;
   bool useExternal;
   float exTemperature,exDensity,exPressure;
   
-  FGColumnVector vWindNED;
+  FGColumnVector3 vWindNED;
   float psiw;
 
   void Calculate(float altitude);
index c8ddc8a3a2ddae52da3a3f903da522b7c10c89d6..3131e47999d130fe67eec7cf99944ba5355597e9 100644 (file)
@@ -50,13 +50,14 @@ INCLUDES
 #include "FGAircraft.h"
 #include "FGPosition.h"
 #include "FGOutput.h"
-#include "FGMatrix.h"
+#include "FGInertial.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_AUXILIARY;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -109,12 +110,50 @@ bool FGAuxiliary::Run()
     vcas = sqrt(7*psl/rhosl*(A-1));
     veas = sqrt(2*qbar/rhosl);
 
-    // vPilotAccel = Translation->GetUVWdot() + Aircraft->GetXYZep() * Rotation->GetPQRdot();
-    
+    // Pilot sensed accelerations are calculated here. This is used
+    // for the coordinated turn ball instrument. Motion base platforms sometimes
+    // use the derivative of pilot sensed accelerations as the driving parameter,
+    // rather than straight accelerations.
+    //
+    // The theory behind pilot-sensed calculations is presented:
+    //
+    // For purposes of discussion and calculation, assume for a minute that the
+    // pilot is in space and motionless in inertial space. She will feel
+    // no accelerations. If the aircraft begins to accelerate along any axis or
+    // axes (without rotating), the pilot will sense those accelerations. If
+    // any rotational moment is applied, the pilot will sense an acceleration
+    // due to that motion in the amount:
+    //
+    // [wdot X R]  +  [w X (w X R)]
+    //   Term I          Term II
+    //
+    // where:
+    //
+    // wdot = omegadot, the rotational acceleration rate vector
+    // w    = omega, the rotational rate vector
+    // R    = the vector from the aircraft CG to the pilot eyepoint
+    //
+    // The sum total of these two terms plus the acceleration of the aircraft
+    // body axis gives the acceleration the pilot senses in inertial space.
+    // In the presence of a large body such as a planet, a gravity field also
+    // provides an accelerating attraction. This acceleration can be transformed
+    // from the reference frame of the planet so as to be expressed in the frame
+    // of reference of the aircraft. This gravity field accelerating attraction
+    // is felt by the pilot as a force on her tushie as she sits in her aircraft
+    // on the runway awaiting takeoff clearance.
+    //
+    // In JSBSim the acceleration of the body frame in inertial space is given
+    // by the F = ma relation. If the vForces vector is divided by the aircraft
+    // mass, the acceleration vector is calculated. The term wdot is equivalent
+    // to the JSBSim vPQRdot vector, and the w parameter is equivalent to vPQR.
+    // The radius R is calculated below in the vector vToEyePt.
+        
     vToEyePt = Aircraft->GetXYZep() - MassBalance->GetXYZcg();
-    vPilotAccel = Translation->GetUVWdot()
-                    + Rotation->GetPQRdot() * vToEyePt
-                    + Rotation->GetPQR() * (Rotation->GetPQR() * vToEyePt);
+
+    vPilotAccel = Aircraft->GetBodyAccel()
+                  + Rotation->GetPQRdot() * vToEyePt
+                  + Rotation->GetPQR() * (Rotation->GetPQR() * vToEyePt)
+                  + Inertial->GetGravity();
 
     earthPosAngle += State->Getdt()*OMEGA_EARTH;
     return false;
@@ -133,7 +172,7 @@ float FGAuxiliary::GetHeadWind(void)
   psi = Rotation->Getpsi();
   vw = Atmosphere->GetWindNED().Magnitude();
 
-  return -vw*cos(psiw - psi);
+  return vw*cos(psiw - psi);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index e52dc15b7b025ce047660f570f778aef4cf518b8..d8f1dec49301657da8c1f6899c919ad9c1f9acc3 100644 (file)
@@ -40,7 +40,9 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGModel.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -88,9 +90,9 @@ public:
   inline float GetVequivalentFPS(void) { return veas; }
   inline float GetVequivalentKTS(void) { return veas*FPSTOKTS; }
   
-  inline FGColumnVector GetPilotAccel(void) { return vPilotAccel; }
+  inline FGColumnVector3& GetPilotAccel(void) { return vPilotAccel; }
   inline float GetPilotAccel(int idx) { return vPilotAccel(idx); }
-  inline FGColumnVector GetNpilot(void) { return vPilotAccel*INVGRAVITY; }
+  inline FGColumnVector3 GetNpilot(void) { return vPilotAccel*INVGRAVITY; }
   inline float GetNpilot(int idx) { return (vPilotAccel*INVGRAVITY)(idx); }
 
   inline float GetEarthPositionAngle(void) { return earthPosAngle; }
@@ -111,8 +113,8 @@ private:
   // (apeden@earthlink.net) or you can add it your self using the
   // isentropic flow equations
 
-  FGColumnVector vPilotAccel;
-  FGColumnVector vToEyePt;
+  FGColumnVector3 vPilotAccel;
+  FGColumnVector3 vToEyePt;
   
   float earthPosAngle;
 
index e1c0dc5b71a5028ef817241be1ede7f2b998d1c6..4d36094ddc59d52e66ef918947d5b88442ca2d28 100644 (file)
@@ -44,12 +44,17 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include "FGDefs.h"
 #include "FGCoefficient.h"
 #include "FGState.h"
 #include "FGFDMExec.h"
 
 #ifndef FGFS
-#  include <iomanip>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <iomanip.h>
+#  else
+#    include <iomanip>
+#  endif
 #else
 #  include STL_IOMANIP
 #endif
@@ -57,20 +62,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_COEFFICIENT;
 
-extern char highint[5];
-extern char halfint[5];
-extern char normint[6];
-extern char reset[5];
-extern char underon[5];
-extern char underoff[6];
-extern char fgblue[6];
-extern char fgcyan[6];
-extern char fgred[6];
-extern char fggreen[6];
-extern char fgdef[6];
-
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -286,10 +277,11 @@ void FGCoefficient::DisplayCoeffFactors(void)
 string FGCoefficient::GetCoefficientValues(void) {
   char buffer[10];
   string value;
-  //value = ", ";
-  snprintf(buffer,10,"%9.6f",SD);
-  value += string(buffer);
+
+  sprintf(buffer,"%9.6f",SD);
+  value = string(buffer);
   return value;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
index 80487135a6ff8ab1d0ebf5930d2165ed50ff962d..5396be219075bd07da8a30ba410f8105c2523ec3 100644 (file)
@@ -47,6 +47,7 @@ INCLUDES
 #include "FGConfigFile.h"
 #include "FGDefs.h"
 #include "FGTable.h"
+#include "FGJSBBase.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -95,11 +96,11 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGCoefficient
+class FGCoefficient : public FGJSBBase
 {
 public:
   FGCoefficient(FGFDMExec*);
-  ~FGCoefficient();
+  virtual ~FGCoefficient();
   
   virtual bool Load(FGConfigFile* AC_cfg);
   
index 4676353addbb97744c2920bb6192de34d09e284b..3585cc2ea4a7a3daae45b25a69b74897c60740fc 100644 (file)
@@ -24,8 +24,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_CONFIGFILE;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 017498970b3c2336a09fa192d3335822d8ef4483..7eb77d69ce8c0e3ba1fe4a46d489728150fca7a8 100644 (file)
@@ -54,20 +54,26 @@ INCLUDES
      SG_USING_STD(cout);
 #  endif
 #else
-#  include <fstream>
-#  include <iostream>
 #  include <string>
-   using std::string;
-   using std::ostream;
-   using std::istream;
-   using std::ifstream;
-   using std::ios;
-   using std::cerr;
-   using std::endl;
-   using std::cout;
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <fstream.h>
+#    include <iostream.h>
+#  else
+#    include <fstream>
+#    include <iostream>
+     using std::ostream;
+     using std::istream;
+     using std::ifstream;
+     using std::ios;
+     using std::cerr;
+     using std::endl;
+     using std::cout;
+#  endif
+    using std::string;
 #endif
 
 #include "FGDefs.h"
+#include "FGJSBBase.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -98,7 +104,7 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGConfigFile
+class FGConfigFile : public FGJSBBase
 {
 public:
   /** Constructor
index 2b1ec119c4ff88f26bb0a86d19a84d79510cf9ac..44398ffac3d4d65a8a2ecee7299722c274b72b7b 100644 (file)
@@ -34,17 +34,11 @@ SENTRY
 #ifndef FGDEFS_H
 #define FGDEFS_H
 
-#define MAX_ENGINES     10
-#define MAX_TANKS       30
 #define GRAVITY         32.174
 #define INVGRAVITY      0.031081
 #define EARTHRAD        20925650.00       // feet, equatorial
 #define EARTHRADSQRD    437882827922500.0
 #define ONESECOND       4.848136811E-6
-#define ECCENT          0.996647186
-#define ECCENTSQRD      0.99330561
-#define INVECCENTSQRD   1.0067395
-#define INVECCENTSQRDM1 0.0067395
 #define Reng            1716             //Specific Gas Constant,ft^2/(sec^2*R)
 #define SHRATIO         1.4              //Specific Heat Ratio
 #define RADTODEG        57.29578
@@ -54,7 +48,7 @@ SENTRY
 #define INCHTOFT        0.08333333
 #define OMEGA_EARTH .00007272205217  
 #define NEEDED_CFG_VERSION "1.40"
-#define JSBSIM_VERSION  "0.8.6"
+#define JSBSIM_VERSION  "0.8.7"
 
 #define HPTOFTLBSSEC 550
 #define METERS_TO_FEET 3.2808
@@ -99,13 +93,23 @@ enum eParam {
   FG_FLAPS_CMD,
   FG_THROTTLE_CMD,
   FG_THROTTLE_POS,
+  FG_MIXTURE_CMD,\r
+  FG_MIXTURE_POS,\r
   FG_ACTIVE_ENGINE,
   FG_HOVERB,
   FG_PITCH_TRIM_CMD,
   FG_LEFT_BRAKE_CMD,
   FG_CENTER_BRAKE_CMD,
   FG_RIGHT_BRAKE_CMD,
-  FG_SET_LOGGING
+  FG_SET_LOGGING,
+  FG_ALPHAH,
+  FG_ALPHAW,
+  FG_LBARH,     //normalized horizontal tail arm
+  FG_LBARV,     //normalized vertical tail arm
+  FG_HTAILAREA,
+  FG_VTAILAREA,
+  FG_VBARH,    //horizontal tail volume 
+  FG_VBARV     //vertical tail volume 
 };
 
 enum eAction {
index 47ff6da78c5ef714bd0d91fcc7e5cb4e79be58fb..fe0aca43b4f50aad149af8fa625d96868fec80ec 100644 (file)
@@ -46,7 +46,11 @@ INCLUDES
 #    include <fstream.h>
 #  endif
 #else
-#  include <fstream>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <fstream.h>
+#  else
+#    include <fstream>
+#  endif
 #endif
 
 #include "FGEngine.h"
@@ -55,8 +59,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_ENGINE;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -75,6 +77,7 @@ FGEngine::FGEngine(FGFDMExec* exec) {
   Auxiliary   = FDMExec->GetAuxiliary();
   Output      = FDMExec->GetOutput();
 
+  Mixture = 1.0;               // FIXME: get actual value\r
   Thrust = PctPower = 0.0;
   Starved = Flameout = false;
   Running = true;
index 12bfc7eafe08992aa189c4fe031dd7e7337e5728..28f7602f1afacd553e0352aa4b8f6c84bc230857 100644 (file)
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- Header:       FGEngine.h
- Author:       Jon S. Berndt
- Date started: 01/21/99
-
- ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
-
- This program is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free Software
- Foundation; either version 2 of the License, or (at your option) any later
- version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- Place - Suite 330, Boston, MA  02111-1307, USA.
-
- Further information about the GNU General Public License can also be found on
- the world wide web at http://www.gnu.org.
-
-FUNCTIONAL DESCRIPTION
---------------------------------------------------------------------------------
-
-Based on Flightgear code, which is based on LaRCSim. This class simulates
-a generic engine.
-
-HISTORY
---------------------------------------------------------------------------------
-01/21/99   JSB   Created
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-SENTRY
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#ifndef FGENGINE_H
-#define FGENGINE_H
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-INCLUDES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#ifdef FGFS
-#  include <simgear/compiler.h>
-#  include STL_STRING
-   SG_USING_STD(string);
-#  ifdef SG_HAVE_STD_INCLUDES
-#    include <vector>
-#  else
-#    include <vector.h>
-#  endif
-#else
-#  include <vector>
-#  include <string>
-#endif
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-DEFINITIONS
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#define ID_ENGINE "$Id$"
-
-using std::string;
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FORWARD DECLARATIONS
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-class FGFDMExec;
-class FGState;
-class FGAtmosphere;
-class FGFCS;
-class FGAircraft;
-class FGTranslation;
-class FGRotation;
-class FGPropulsion;
-class FGPosition;
-class FGAuxiliary;
-class FGOutput;
-
-using std::vector;
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DOCUMENTATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-/** Base class for all engines.
-    This base class contains methods and members common to all engines, such as
-    logic to drain fuel from the appropriate tank, etc.
-    @author Jon S. Berndt
-    @version $Id$ 
-*/
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DECLARATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-class FGEngine {
-public:
-  FGEngine(FGFDMExec* exec);
-  virtual ~FGEngine();
-
-  enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet, etTurboShaft};
-
-  virtual float  GetThrottleMin(void) { return MinThrottle; }
-  virtual float  GetThrottleMax(void) { return MaxThrottle; }
-  float  GetThrottle(void) { return Throttle; }
-  float  GetThrust(void) { return Thrust; }
-  bool   GetStarved(void) { return Starved; }
-  bool   GetFlameout(void) { return Flameout; }
-  bool   GetRunning(void) { return Running; }
-  int    GetType(void) { return Type; }
-  string GetName(void) { return Name; }
-
-  void SetStarved(bool tt) {Starved = tt;}
-  void SetStarved(void)    {Starved = true;}
-
-  void SetRunning(bool bb) { Running=bb; }
-  void SetName(string name) {Name = name;}
-  void AddFeedTank(int tkID);
-
-  /** Calculates the thrust of the engine, and other engine functions.
-      @param PowerRequired this is the power required to run the thrusting device
-             such as a propeller. This resisting effect must be provided to the 
-             engine model.
-      @return Thrust in pounds */
-  virtual float Calculate(float PowerRequired) {return 0.0;};
-
-  /** Reduces the fuel in the active tanks by the amount required.
-      This function should be called from within the
-      derived class' Calculate() function before any other calculations are
-      done. This base class method removes fuel from the fuel tanks as
-      appropriate, and sets the starved flag if necessary. */
-  void ConsumeFuel(void);
-
-  /** The fuel need is calculated based on power levels and flow rate for that
-      power level. It is also turned from a rate into an actual amount (pounds)
-      by multiplying it by the delta T and the rate.
-      @return Total fuel requirement for this engine in pounds. */
-  float CalcFuelNeed(void);
-
-  /** The oxidizer need is calculated based on power levels and flow rate for that
-      power level. It is also turned from a rate into an actual amount (pounds)
-      by multiplying it by the delta T and the rate.
-      @return Total oxidizer requirement for this engine in pounds. */
-  float CalcOxidizerNeed(void);
-
-  /// Sets engine placement information
-  void SetPlacement(float x, float y, float z, float pitch, float yaw);
-
-  virtual float GetPowerAvailable(void) {return 0.0;};
-
-  bool GetTrimMode(void) {return TrimMode;}
-  void SetTrimMode(bool state) {TrimMode = state;}
-
-protected:
-  string Name;
-  EngineType Type;
-  float X, Y, Z;
-  float EnginePitch;
-  float EngineYaw;
-  float SLFuelFlowMax;
-  float SLOxiFlowMax;
-  float MaxThrottle;
-  float MinThrottle;
-
-  float Thrust;
-  float Throttle;
-  float FuelNeed, OxidizerNeed;
-  bool  Starved;
-  bool  Flameout;
-  bool  Running;
-  float PctPower;
-  int   EngineNumber;
-  bool  TrimMode;
-
-  FGFDMExec*      FDMExec;
-  FGState*        State;
-  FGAtmosphere*   Atmosphere;
-  FGFCS*          FCS;
-  FGPropulsion*   Propulsion;
-  FGAircraft*     Aircraft;
-  FGTranslation*  Translation;
-  FGRotation*     Rotation;
-  FGPosition*     Position;
-  FGAuxiliary*    Auxiliary;
-  FGOutput*       Output;
-
-  vector <int> SourceTanks;
-  void Debug(void);
-};
-
-#include "FGState.h"
-#include "FGFDMExec.h"
-#include "FGAtmosphere.h"
-#include "FGFCS.h"
-#include "FGAircraft.h"
-#include "FGTranslation.h"
-#include "FGRotation.h"
-#include "FGPropulsion.h"
-#include "FGPosition.h"
-#include "FGAuxiliary.h"
-#include "FGOutput.h"
-#include "FGDefs.h"
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-#endif
-
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+ Header:       FGEngine.h\r
+ Author:       Jon S. Berndt\r
+ Date started: 01/21/99\r
+\r
+ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------\r
+\r
+ This program is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License as published by the Free Software\r
+ Foundation; either version 2 of the License, or (at your option) any later\r
+ version.\r
+\r
+ This program is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\r
+ details.\r
+\r
+ You should have received a copy of the GNU General Public License along with\r
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
+ Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+ Further information about the GNU General Public License can also be found on\r
+ the world wide web at http://www.gnu.org.\r
+\r
+FUNCTIONAL DESCRIPTION\r
+--------------------------------------------------------------------------------\r
+\r
+Based on Flightgear code, which is based on LaRCSim. This class simulates\r
+a generic engine.\r
+\r
+HISTORY\r
+--------------------------------------------------------------------------------\r
+01/21/99   JSB   Created\r
+\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+SENTRY\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#ifndef FGENGINE_H\r
+#define FGENGINE_H\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+INCLUDES\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#ifdef FGFS\r
+#  include <simgear/compiler.h>\r
+#  include STL_STRING\r
+   SG_USING_STD(string);\r
+#  ifdef SG_HAVE_STD_INCLUDES\r
+#    include <vector>\r
+#  else\r
+#    include <vector.h>\r
+#  endif\r
+#else\r
+#  include <vector>\r
+#  include <string>\r
+#endif\r
+\r
+#include "FGJSBBase.h"\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+DEFINITIONS\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#define ID_ENGINE "$Id$"\r
+\r
+using std::string;\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+FORWARD DECLARATIONS\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+class FGFDMExec;\r
+class FGState;\r
+class FGAtmosphere;\r
+class FGFCS;\r
+class FGAircraft;\r
+class FGTranslation;\r
+class FGRotation;\r
+class FGPropulsion;\r
+class FGPosition;\r
+class FGAuxiliary;\r
+class FGOutput;\r
+\r
+using std::vector;\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS DOCUMENTATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/** Base class for all engines.\r
+    This base class contains methods and members common to all engines, such as\r
+    logic to drain fuel from the appropriate tank, etc.\r
+    @author Jon S. Berndt\r
+    @version $Id$ \r
+*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS DECLARATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+class FGEngine : public FGJSBBase\r
+{\r
+public:\r
+  FGEngine(FGFDMExec* exec);\r
+  virtual ~FGEngine();\r
+\r
+  enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet, etTurboShaft};\r
+\r
+  virtual float  GetThrottleMin(void) { return MinThrottle; }\r
+  virtual float  GetThrottleMax(void) { return MaxThrottle; }\r
+  float  GetThrottle(void) { return Throttle; }\r
+  float  GetMixture(void) { return Mixture; }\r
+  float  GetThrust(void) { return Thrust; }\r
+  bool   GetStarved(void) { return Starved; }\r
+  bool   GetFlameout(void) { return Flameout; }\r
+  bool   GetRunning(void) { return Running; }\r
+  int    GetType(void) { return Type; }\r
+  string GetName(void) { return Name; }\r
+\r
+  virtual float getManifoldPressure_inHg () const {\r
+    return ManifoldPressure_inHg;\r
+  }\r
+  virtual float getExhaustGasTemp_degF () const {\r
+    return (ExhaustGasTemp_degK - 273) * (9.0 / 5.0) + 32.0;\r
+  }\r
+  virtual float getCylinderHeadTemp_degF () const {\r
+    return (CylinderHeadTemp_degK - 273) * (9.0 / 5.0) + 32.0;\r
+  }\r
+  virtual float getOilPressure_psi () const {\r
+    return OilPressure_psi;\r
+  }\r
+  virtual float getOilTemp_degF () const {\r
+    return (OilTemp_degK - 273.0) * (9.0 / 5.0) + 32.0;\r
+  }\r
+\r
+  void SetStarved(bool tt) {Starved = tt;}\r
+  void SetStarved(void)    {Starved = true;}\r
+\r
+  void SetRunning(bool bb) { Running=bb; }\r
+  void SetName(string name) {Name = name;}\r
+  void AddFeedTank(int tkID);\r
+\r
+  /** Calculates the thrust of the engine, and other engine functions.\r
+      @param PowerRequired this is the power required to run the thrusting device\r
+             such as a propeller. This resisting effect must be provided to the \r
+             engine model.\r
+      @return Thrust in pounds */\r
+  virtual float Calculate(float PowerRequired) {return 0.0;};\r
+\r
+  /** Reduces the fuel in the active tanks by the amount required.\r
+      This function should be called from within the\r
+      derived class' Calculate() function before any other calculations are\r
+      done. This base class method removes fuel from the fuel tanks as\r
+      appropriate, and sets the starved flag if necessary. */\r
+  void ConsumeFuel(void);\r
+\r
+  /** The fuel need is calculated based on power levels and flow rate for that\r
+      power level. It is also turned from a rate into an actual amount (pounds)\r
+      by multiplying it by the delta T and the rate.\r
+      @return Total fuel requirement for this engine in pounds. */\r
+  float CalcFuelNeed(void);\r
+\r
+  /** The oxidizer need is calculated based on power levels and flow rate for that\r
+      power level. It is also turned from a rate into an actual amount (pounds)\r
+      by multiplying it by the delta T and the rate.\r
+      @return Total oxidizer requirement for this engine in pounds. */\r
+  float CalcOxidizerNeed(void);\r
+\r
+  /// Sets engine placement information\r
+  void SetPlacement(float x, float y, float z, float pitch, float yaw);\r
+\r
+  virtual float GetPowerAvailable(void) {return 0.0;};\r
+\r
+  bool GetTrimMode(void) {return TrimMode;}\r
+  void SetTrimMode(bool state) {TrimMode = state;}\r
+\r
+protected:\r
+  string Name;\r
+  EngineType Type;\r
+  float X, Y, Z;\r
+  float EnginePitch;\r
+  float EngineYaw;\r
+  float SLFuelFlowMax;\r
+  float SLOxiFlowMax;\r
+  float MaxThrottle;\r
+  float MinThrottle;\r
+\r
+  float Thrust;\r
+  float Throttle;\r
+  float Mixture;\r
+  float FuelNeed, OxidizerNeed;\r
+  bool  Starved;\r
+  bool  Flameout;\r
+  bool  Running;\r
+  float PctPower;\r
+  int   EngineNumber;\r
+  bool  TrimMode;\r
+\r
+  float ManifoldPressure_inHg;\r
+  float ExhaustGasTemp_degK;\r
+  float CylinderHeadTemp_degK;\r
+  float OilPressure_psi;\r
+  float OilTemp_degK;\r
+\r
+  FGFDMExec*      FDMExec;\r
+  FGState*        State;\r
+  FGAtmosphere*   Atmosphere;\r
+  FGFCS*          FCS;\r
+  FGPropulsion*   Propulsion;\r
+  FGAircraft*     Aircraft;\r
+  FGTranslation*  Translation;\r
+  FGRotation*     Rotation;\r
+  FGPosition*     Position;\r
+  FGAuxiliary*    Auxiliary;\r
+  FGOutput*       Output;\r
+\r
+  vector <int> SourceTanks;\r
+  void Debug(void);\r
+};\r
+\r
+#include "FGState.h"\r
+#include "FGFDMExec.h"\r
+#include "FGAtmosphere.h"\r
+#include "FGFCS.h"\r
+#include "FGAircraft.h"\r
+#include "FGTranslation.h"\r
+#include "FGRotation.h"\r
+#include "FGPropulsion.h"\r
+#include "FGPosition.h"\r
+#include "FGAuxiliary.h"\r
+#include "FGOutput.h"\r
+#include "FGDefs.h"\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+#endif\r
+\r
index 1be919c3c00d83a72cb4d07c2f741eb7241f034c..230f75436f54f8593243580d2709fde670f809e7 100644 (file)
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- Module:       FGFCS.cpp
- Author:       Jon Berndt
- Date started: 12/12/98
- Purpose:      Model the flight controls
- Called by:    FDMExec
- ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
- This program is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free Software
- Foundation; either version 2 of the License, or (at your option) any later
- version.
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- details.
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- Place - Suite 330, Boston, MA  02111-1307, USA.
- Further information about the GNU General Public License can also be found on
- the world wide web at http://www.gnu.org.
-FUNCTIONAL DESCRIPTION
---------------------------------------------------------------------------------
-This class models the flight controls for a specific airplane
-HISTORY
---------------------------------------------------------------------------------
-12/12/98   JSB   Created
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-INCLUDES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#include "FGDefs.h"
-
-#include "FGFCS.h"
-#include "FGState.h"
-#include "FGFDMExec.h"
-#include "FGAtmosphere.h"
-#include "FGAircraft.h"
-#include "FGTranslation.h"
-#include "FGRotation.h"
-#include "FGPosition.h"
-#include "FGAuxiliary.h"
-#include "FGOutput.h"
-
-#include "filtersjb/FGFilter.h"
-#include "filtersjb/FGDeadBand.h"
-#include "filtersjb/FGGain.h"
-#include "filtersjb/FGGradient.h"
-#include "filtersjb/FGSwitch.h"
-#include "filtersjb/FGSummer.h"
-#include "filtersjb/FGFlaps.h"
-
-static const char *IdSrc = "$Id$";
-static const char *IdHdr = ID_FCS;
-
-extern short debug_lvl;
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS IMPLEMENTATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
-{
-  Name = "FGFCS";
-
-  DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = PTrimCmd = 0.0;
-  DaPos = DePos = DrPos = DfPos = DsbPos = DspPos = 0.0;
-  LeftBrake = RightBrake = CenterBrake = 0.0;
-
-  if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-FGFCS::~FGFCS()
-{
-  ThrottleCmd.clear();
-  ThrottlePos.clear();
-
-  unsigned int i;
-
-  for(i=0;i<Components.size();i++) delete Components[i];
-  if (debug_lvl & 2) cout << "Destroyed:    FGFCS" << endl;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-bool FGFCS::Run(void)
-{
-  unsigned int i;
-
-  if (!FGModel::Run()) {
-    for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
-    for (i=0; i<Components.size(); i++)  Components[i]->Run();
-  } else {
-  }
-
-  return false;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCS::SetThrottleCmd(int engineNum, float setting)
-{
-  unsigned int ctr;
-
-  if (engineNum < 0) {
-    for (ctr=0;ctr<ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting;
-  } else {
-    ThrottleCmd[engineNum] = setting;
-  }
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCS::SetThrottlePos(int engineNum, float setting)
-{
-  unsigned int ctr;
-
-  if (engineNum < 0) {
-    for (ctr=0;ctr<=ThrottleCmd.size();ctr++) ThrottlePos[ctr] = ThrottleCmd[ctr];
-  } else {
-    ThrottlePos[engineNum] = setting;
-  }
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-bool FGFCS::Load(FGConfigFile* AC_cfg)
-{
-  string token;
-
-  Name = AC_cfg->GetValue("NAME");
-  if (debug_lvl > 0) cout << "    Control System Name: " << Name << endl;
-  AC_cfg->GetNextConfigLine();
-  while ((token = AC_cfg->GetValue()) != "/FLIGHT_CONTROL") {
-    if (token == "COMPONENT") {
-      token = AC_cfg->GetValue("TYPE");
-      if (debug_lvl > 0) cout << "    Loading Component \""
-                              << AC_cfg->GetValue("NAME")
-                                               << "\" of type: " << token << endl;
-      if ((token == "LAG_FILTER") ||
-          (token == "LEAD_LAG_FILTER") ||
-          (token == "SECOND_ORDER_FILTER") ||
-          (token == "WASHOUT_FILTER") ||
-          (token == "INTEGRATOR") ) {
-        Components.push_back(new FGFilter(this, AC_cfg));
-      } else if ((token == "PURE_GAIN") ||
-                 (token == "SCHEDULED_GAIN") ||
-                 (token == "AEROSURFACE_SCALE") ) {
-
-        Components.push_back(new FGGain(this, AC_cfg));
-
-      } else if (token == "SUMMER") {
-        Components.push_back(new FGSummer(this, AC_cfg));
-      } else if (token == "DEADBAND") {
-        Components.push_back(new FGDeadBand(this, AC_cfg));
-      } else if (token == "GRADIENT") {
-        Components.push_back(new FGGradient(this, AC_cfg));
-      } else if (token == "SWITCH") {
-        Components.push_back(new FGSwitch(this, AC_cfg));
-      } else if (token == "FLAPS") {
-        Components.push_back(new FGFlaps(this, AC_cfg));
-      } else {
-        cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl;
-        return false;
-      }
-      AC_cfg->GetNextConfigLine();
-    }
-  }
-  return true;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-float FGFCS::GetComponentOutput(eParam idx) {
-  return Components[idx]->GetOutput();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-string FGFCS::GetComponentName(int idx) {
-  return Components[idx]->GetName();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-float FGFCS::GetBrake(FGLGear::BrakeGroup bg) {
-  switch (bg) {
-  case FGLGear::bgLeft:
-    return LeftBrake;
-  case FGLGear::bgRight:
-    return RightBrake;
-  case FGLGear::bgCenter:
-    return CenterBrake;
-  default:
-    cerr << "GetBrake asked to return a bogus brake value" << endl;
-  }
-  return 0.0;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-string FGFCS::GetComponentStrings(void)
-{
-  unsigned int comp;
-
-  string CompStrings = "";
-  bool firstime = true;
-
-  for (comp = 0; comp < Components.size(); comp++) {
-    if (firstime) firstime = false;
-    else          CompStrings += ", ";
-
-    CompStrings += Components[comp]->GetName();
-  }
-
-  return CompStrings;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-string FGFCS::GetComponentValues(void)
-{
-  unsigned int comp;
-
-  string CompValues = "";
-  char buffer[10];
-  bool firstime = true;
-
-  for (comp = 0; comp < Components.size(); comp++) {
-    if (firstime) firstime = false;
-    else          CompValues += ", ";
-
-    sprintf(buffer, "%9.6f", Components[comp]->GetOutput());
-    CompValues += string(buffer);
-  }
-
-  return CompValues;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCS::AddThrottle(void)
-{
-  ThrottleCmd.push_back(0.0);
-  ThrottlePos.push_back(0.0);
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCS::Debug(void)
-{
-    //TODO: Add your source code here
-}
-
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
\r
+ Module:       FGFCS.cpp\r
+ Author:       Jon Berndt\r
+ Date started: 12/12/98\r
+ Purpose:      Model the flight controls\r
+ Called by:    FDMExec\r
\r
+ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------\r
\r
+ This program is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License as published by the Free Software\r
+ Foundation; either version 2 of the License, or (at your option) any later\r
+ version.\r
\r
+ This program is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\r
+ details.\r
\r
+ You should have received a copy of the GNU General Public License along with\r
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
+ Place - Suite 330, Boston, MA  02111-1307, USA.\r
\r
+ Further information about the GNU General Public License can also be found on\r
+ the world wide web at http://www.gnu.org.\r
\r
+FUNCTIONAL DESCRIPTION\r
+--------------------------------------------------------------------------------\r
+This class models the flight controls for a specific airplane\r
\r
+HISTORY\r
+--------------------------------------------------------------------------------\r
+12/12/98   JSB   Created\r
\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+INCLUDES\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#include "FGDefs.h"\r
+\r
+#include "FGFCS.h"\r
+#include "FGState.h"\r
+#include "FGFDMExec.h"\r
+#include "FGAtmosphere.h"\r
+#include "FGAircraft.h"\r
+#include "FGTranslation.h"\r
+#include "FGRotation.h"\r
+#include "FGPosition.h"\r
+#include "FGAuxiliary.h"\r
+#include "FGOutput.h"\r
+\r
+#include "filtersjb/FGFilter.h"\r
+#include "filtersjb/FGDeadBand.h"\r
+#include "filtersjb/FGGain.h"\r
+#include "filtersjb/FGGradient.h"\r
+#include "filtersjb/FGSwitch.h"\r
+#include "filtersjb/FGSummer.h"\r
+#include "filtersjb/FGFlaps.h"\r
+\r
+static const char *IdSrc = "$Id$";\r
+static const char *IdHdr = ID_FCS;\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS IMPLEMENTATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)\r
+{\r
+  Name = "FGFCS";\r
+\r
+  DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = PTrimCmd = 0.0;\r
+  DaPos = DePos = DrPos = DfPos = DsbPos = DspPos = 0.0;\r
+  LeftBrake = RightBrake = CenterBrake = 0.0;\r
+\r
+  if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+FGFCS::~FGFCS()\r
+{\r
+  ThrottleCmd.clear();\r
+  ThrottlePos.clear();\r
+  MixtureCmd.clear();\r
+  MixturePos.clear();\r
+\r
+  unsigned int i;\r
+\r
+  for(i=0;i<Components.size();i++) delete Components[i];\r
+  if (debug_lvl & 2) cout << "Destroyed:    FGFCS" << endl;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+bool FGFCS::Run(void)\r
+{\r
+  unsigned int i;\r
+\r
+  if (!FGModel::Run()) {\r
+    for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];\r
+    for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];\r
+    for (i=0; i<Components.size(); i++)  Components[i]->Run();\r
+  } else {\r
+  }\r
+\r
+  return false;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+void FGFCS::SetThrottleCmd(int engineNum, float setting)\r
+{\r
+  unsigned int ctr;\r
+\r
+  if ((int)ThrottleCmd.size() > engineNum) {\r
+    if (engineNum < 0) {\r
+      for (ctr=0;ctr<=ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting;\r
+    } else {\r
+      ThrottleCmd[engineNum] = setting;\r
+    }\r
+  } else {\r
+    cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()\r
+         << " engines exist, but attempted throttle command is for engine "\r
+         << engineNum << endl;\r
+  }\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+void FGFCS::SetThrottlePos(int engineNum, float setting)\r
+{\r
+  unsigned int ctr;\r
+\r
+  if ((int)ThrottlePos.size() > engineNum) {\r
+    if (engineNum < 0) {\r
+      for (ctr=0;ctr<=ThrottlePos.size();ctr++) ThrottlePos[ctr] = setting;\r
+    } else {\r
+      ThrottlePos[engineNum] = setting;\r
+    }\r
+  } else {\r
+    cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()\r
+         << " engines exist, but attempted throttle position setting is for engine "\r
+         << engineNum << endl;\r
+  }\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+float FGFCS::GetThrottleCmd(int engineNum)\r
+{\r
+  if ((int)ThrottleCmd.size() > engineNum) {\r
+    if (engineNum < 0) {\r
+       cerr << "Cannot get throttle value for ALL engines" << endl;\r
+    } else {\r
+      return ThrottleCmd[engineNum];\r
+    }\r
+  } else {\r
+    cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()\r
+         << " engines exist, but throttle setting for engine " << engineNum\r
+              << " is selected" << endl;\r
+  }\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+float FGFCS::GetThrottlePos(int engineNum)\r
+{\r
+  if ((int)ThrottlePos.size() > engineNum) {\r
+    if (engineNum < 0) {\r
+       cerr << "Cannot get throttle value for ALL engines" << endl;\r
+    } else {\r
+      return ThrottlePos[engineNum];\r
+    }\r
+  } else {\r
+    cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()\r
+         << " engines exist, but attempted throttle position setting is for engine "\r
+         << engineNum << endl;\r
+  }\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+void FGFCS::SetMixtureCmd(int engineNum, float setting)\r
+{\r
+  unsigned int ctr;\r
+\r
+  if (engineNum < 0) {\r
+    for (ctr=0;ctr<MixtureCmd.size();ctr++) MixtureCmd[ctr] = setting;\r
+  } else {\r
+    MixtureCmd[engineNum] = setting;\r
+  }\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+void FGFCS::SetMixturePos(int engineNum, float setting)\r
+{\r
+  unsigned int ctr;\r
+\r
+  if (engineNum < 0) {\r
+    for (ctr=0;ctr<=MixtureCmd.size();ctr++) MixturePos[ctr] = MixtureCmd[ctr];\r
+  } else {\r
+    MixturePos[engineNum] = setting;\r
+  }\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+bool FGFCS::Load(FGConfigFile* AC_cfg)\r
+{\r
+  string token;\r
+\r
+  Name = Name + ":" + AC_cfg->GetValue("NAME");\r
+  if (debug_lvl > 0) cout << "    Control System Name: " << Name << endl;\r
+  AC_cfg->GetNextConfigLine();\r
+  while ((token = AC_cfg->GetValue()) != "/FLIGHT_CONTROL") {\r
+    if (token == "COMPONENT") {\r
+      token = AC_cfg->GetValue("TYPE");\r
+      if (debug_lvl > 0) cout << "    Loading Component \""\r
+                              << AC_cfg->GetValue("NAME")\r
+                                               << "\" of type: " << token << endl;\r
+      if ((token == "LAG_FILTER") ||\r
+          (token == "LEAD_LAG_FILTER") ||\r
+          (token == "SECOND_ORDER_FILTER") ||\r
+          (token == "WASHOUT_FILTER") ||\r
+          (token == "INTEGRATOR") ) {\r
+        Components.push_back(new FGFilter(this, AC_cfg));\r
+      } else if ((token == "PURE_GAIN") ||\r
+                 (token == "SCHEDULED_GAIN") ||\r
+                 (token == "AEROSURFACE_SCALE") ) {\r
+\r
+        Components.push_back(new FGGain(this, AC_cfg));\r
+\r
+      } else if (token == "SUMMER") {\r
+        Components.push_back(new FGSummer(this, AC_cfg));\r
+      } else if (token == "DEADBAND") {\r
+        Components.push_back(new FGDeadBand(this, AC_cfg));\r
+      } else if (token == "GRADIENT") {\r
+        Components.push_back(new FGGradient(this, AC_cfg));\r
+      } else if (token == "SWITCH") {\r
+        Components.push_back(new FGSwitch(this, AC_cfg));\r
+      } else if (token == "FLAPS") {\r
+        Components.push_back(new FGFlaps(this, AC_cfg));\r
+      } else {\r
+        cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl;\r
+        return false;\r
+      }\r
+      AC_cfg->GetNextConfigLine();\r
+    }\r
+  }\r
+  return true;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+float FGFCS::GetComponentOutput(eParam idx) {\r
+  return Components[idx]->GetOutput();\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+string FGFCS::GetComponentName(int idx) {\r
+  return Components[idx]->GetName();\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+float FGFCS::GetBrake(FGLGear::BrakeGroup bg) {\r
+  switch (bg) {\r
+  case FGLGear::bgLeft:\r
+    return LeftBrake;\r
+  case FGLGear::bgRight:\r
+    return RightBrake;\r
+  case FGLGear::bgCenter:\r
+    return CenterBrake;\r
+  default:\r
+    cerr << "GetBrake asked to return a bogus brake value" << endl;\r
+  }\r
+  return 0.0;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+string FGFCS::GetComponentStrings(void)\r
+{\r
+  unsigned int comp;\r
+\r
+  string CompStrings = "";\r
+  bool firstime = true;\r
+\r
+  for (comp = 0; comp < Components.size(); comp++) {\r
+    if (firstime) firstime = false;\r
+    else          CompStrings += ", ";\r
+\r
+    CompStrings += Components[comp]->GetName();\r
+  }\r
+\r
+  return CompStrings;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+string FGFCS::GetComponentValues(void)\r
+{\r
+  unsigned int comp;\r
+\r
+  string CompValues = "";\r
+  char buffer[10];\r
+  bool firstime = true;\r
+\r
+  for (comp = 0; comp < Components.size(); comp++) {\r
+    if (firstime) firstime = false;\r
+    else          CompValues += ", ";\r
+\r
+    sprintf(buffer, "%9.6f", Components[comp]->GetOutput());\r
+    CompValues += string(buffer);\r
+  }\r
+\r
+  return CompValues;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+void FGFCS::AddThrottle(void)\r
+{\r
+  ThrottleCmd.push_back(0.0);\r
+  ThrottlePos.push_back(0.0);\r
+  MixtureCmd.push_back(0.0);   // assume throttle and mixture are coupled\r
+  MixturePos.push_back(0.0);\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+void FGFCS::Debug(void)\r
+{\r
+    //TODO: Add your source code here\r
+}\r
+\r
index dfaa660326b2bda0b5aec729818aa569af0c031a..f2e84eb48228e1203eb86a783d9ade98d24b5a1e 100644 (file)
@@ -196,8 +196,13 @@ public:
   /** Gets the throttle command.
       @param engine engine ID number
       @return throttle command in percent ( 0 - 100) for the given engine */
-  inline float GetThrottleCmd(int engine) { return ThrottleCmd[engine]; }
-
+  float GetThrottleCmd(int engine);\r
+\r
+  /** Gets the mixture command.\r
+      @param engine engine ID number\r
+      @return mixture command in percent ( 0 - 100) for the given engine */\r
+  inline float GetMixtureCmd(int engine) { return MixtureCmd[engine]; }\r
+\r
   /** Gets the pitch trim command.
       @return pitch trim command in radians */
   inline float GetPitchTrimCmd(void) { return PTrimCmd; }
@@ -232,7 +237,12 @@ public:
   /** Gets the throttle position.
       @param engine engine ID number
       @return throttle position for the given engine in percent ( 0 - 100)*/
-  inline float GetThrottlePos(int engine) { return ThrottlePos[engine]; }
+  float GetThrottlePos(int engine);\r
+\r
+  /** Gets the mixture position.\r
+      @param engine engine ID number\r
+      @return mixture position for the given engine in percent ( 0 - 100)*/\r
+  inline float GetMixturePos(int engine) { return MixturePos[engine]; }\r
   //@}
 
   /** Retrieves the State object pointer.
@@ -290,6 +300,11 @@ public:
       @param engine engine ID number
       @param cmd throttle command in percent (0 - 100)*/
   void SetThrottleCmd(int engine, float cmd);
+\r
+  /** Sets the mixture command for the specified engine\r
+      @param engine engine ID number\r
+      @param cmd mixture command in percent (0 - 100)*/\r
+  void SetMixtureCmd(int engine, float cmd);\r
   //@}
 
   /// @name Aerosurface position setting
@@ -322,6 +337,11 @@ public:
       @param engine engine ID number
       @param cmd throttle setting in percent (0 - 100)*/
   void SetThrottlePos(int engine, float cmd);
+\r
+  /** Sets the actual mixture setting for the specified engine\r
+      @param engine engine ID number\r
+      @param cmd mixture setting in percent (0 - 100)*/\r
+  void SetMixturePos(int engine, float cmd);\r
   //@}
 
   /// @name Landing Gear brakes
@@ -360,6 +380,8 @@ private:
   float PTrimCmd;
   vector <float> ThrottleCmd;
   vector <float> ThrottlePos;
+  vector <float> MixtureCmd;\r
+  vector <float> MixturePos;\r
   float LeftBrake, RightBrake, CenterBrake; // Brake settings
 
   vector <FGFCSComponent*> Components;
index ed10e6986e958f6a090e0456c3b5d4559672481e..30a274675b1d728a7f456aec3238df00dd2ef82d 100644 (file)
@@ -48,8 +48,13 @@ INCLUDES
 #  include STL_IOSTREAM
 #  include STL_ITERATOR
 #else
-#  include <iostream>
-#  include <ctime>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <iostream.h>
+#    include <time.h>
+#  else
+#    include <iostream>
+#    include <ctime>
+#  endif
 #  include <iterator>
 #endif
 
@@ -59,6 +64,7 @@ INCLUDES
 #include "FGFCS.h"
 #include "FGPropulsion.h"
 #include "FGMassBalance.h"
+#include "FGGroundReactions.h"
 #include "FGAerodynamics.h"
 #include "FGInertial.h"
 #include "FGAircraft.h"
@@ -72,18 +78,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FDMEXEC;
 
-char highint[5]  = {27, '[', '1', 'm', '\0'      };
-char halfint[5]  = {27, '[', '2', 'm', '\0'      };
-char normint[6]  = {27, '[', '2', '2', 'm', '\0' };
-char reset[5]    = {27, '[', '0', 'm', '\0'      };
-char underon[5]  = {27, '[', '4', 'm', '\0'      };
-char underoff[6] = {27, '[', '2', '4', 'm', '\0' };
-char fgblue[6]   = {27, '[', '3', '4', 'm', '\0' };
-char fgcyan[6]   = {27, '[', '3', '6', 'm', '\0' };
-char fgred[6]    = {27, '[', '3', '1', 'm', '\0' };
-char fggreen[6]  = {27, '[', '3', '2', 'm', '\0' };
-char fgdef[6]    = {27, '[', '3', '9', 'm', '\0' };
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 GLOBAL DECLARATIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -116,22 +110,23 @@ CLASS IMPLEMENTATION
 
 FGFDMExec::FGFDMExec(void)
 {
-  Frame        = 0;
-  FirstModel   = 0;
-  Error        = 0;
-  State        = 0;
-  Atmosphere   = 0;
-  FCS          = 0;
-  Propulsion   = 0;
-  MassBalance  = 0;
-  Aerodynamics = 0;
-  Inertial     = 0;
-  Aircraft     = 0;
-  Translation  = 0;
-  Rotation     = 0;
-  Position     = 0;
-  Auxiliary    = 0;
-  Output       = 0;
+  Frame           = 0;
+  FirstModel      = 0;
+  Error           = 0;
+  State           = 0;
+  Atmosphere      = 0;
+  FCS             = 0;
+  Propulsion      = 0;
+  MassBalance     = 0;
+  Aerodynamics    = 0;
+  Inertial        = 0;
+  GroundReactions = 0;
+  Aircraft        = 0;
+  Translation     = 0;
+  Rotation        = 0;
+  Position        = 0;
+  Auxiliary       = 0;
+  Output          = 0;
 
   terminate = false;
   frozen = false;
@@ -171,23 +166,24 @@ bool FGFDMExec::Allocate(void) {
 
   bool result=true;
 
-  Atmosphere   = new FGAtmosphere(this);
-  FCS          = new FGFCS(this);
-  Propulsion   = new FGPropulsion(this);
-  MassBalance  = new FGMassBalance(this);
-  Aerodynamics = new FGAerodynamics (this);
-  Inertial     = new FGInertial(this);
-  Aircraft     = new FGAircraft(this);
-  Translation  = new FGTranslation(this);
-  Rotation     = new FGRotation(this);
-  Position     = new FGPosition(this);
-  Auxiliary    = new FGAuxiliary(this);
-  Output       = new FGOutput(this);
+  Atmosphere      = new FGAtmosphere(this);
+  FCS             = new FGFCS(this);
+  Propulsion      = new FGPropulsion(this);
+  MassBalance     = new FGMassBalance(this);
+  Aerodynamics    = new FGAerodynamics (this);
+  Inertial        = new FGInertial(this);
+  GroundReactions = new FGGroundReactions(this);
+  Aircraft        = new FGAircraft(this);
+  Translation     = new FGTranslation(this);
+  Rotation        = new FGRotation(this);
+  Position        = new FGPosition(this);
+  Auxiliary       = new FGAuxiliary(this);
+  Output          = new FGOutput(this);
 
   State        = new FGState(this); // This must be done here, as the FGState
                                     // class needs valid pointers to the above
-  // model classes
-
+                                    // model classes
+  
   // Initialize models so they can communicate with each other
 
   if (!Atmosphere->InitModel()) {
@@ -208,24 +204,27 @@ bool FGFDMExec::Allocate(void) {
   if (!Inertial->InitModel()) {
     cerr << fgred << "FGInertial model init failed" << fgdef << endl;
     Error+=32;}
+  if (!GroundReactions->InitModel())   {
+    cerr << fgred << "Ground Reactions model init failed" << fgdef << endl;
+    Error+=64;}
   if (!Aircraft->InitModel())   {
     cerr << fgred << "Aircraft model init failed" << fgdef << endl;
-    Error+=64;}
+    Error+=128;}
   if (!Translation->InitModel()){
     cerr << fgred << "Translation model init failed" << fgdef << endl;
-    Error+=128;}
+    Error+=256;}
   if (!Rotation->InitModel())   {
     cerr << fgred << "Rotation model init failed" << fgdef << endl;
-    Error+=256;}
+    Error+=512;}
   if (!Position->InitModel())   {
     cerr << fgred << "Position model init failed" << fgdef << endl;
-    Error+=512;}
+    Error+=1024;}
   if (!Auxiliary->InitModel())  {
     cerr << fgred << "Auxiliary model init failed" << fgdef << endl;
-    Error+=1024;}
+    Error+=2058;}
   if (!Output->InitModel())     {
     cerr << fgred << "Output model init failed" << fgdef << endl;
-    Error+=2048;}
+    Error+=4096;}
 
   if (Error > 0) result = false;
 
@@ -233,18 +232,19 @@ bool FGFDMExec::Allocate(void) {
   // instance, the atmosphere model gets executed every fifth pass it is called
   // by the executive. Everything else here gets executed each pass.
 
-  Schedule(Atmosphere,   1);
-  Schedule(FCS,          1);
-  Schedule(Propulsion,   1);
-  Schedule(MassBalance,  1);
-  Schedule(Aerodynamics, 1);
-  Schedule(Inertial,     1);
-  Schedule(Aircraft,     1);
-  Schedule(Rotation,     1);
-  Schedule(Translation,  1);
-  Schedule(Position,     1);
-  Schedule(Auxiliary,    1);
-  Schedule(Output,       1);
+  Schedule(Atmosphere,      1);
+  Schedule(FCS,             1);
+  Schedule(Propulsion,      1);
+  Schedule(MassBalance,     1);
+  Schedule(Aerodynamics,    1);
+  Schedule(Inertial,        1);
+  Schedule(GroundReactions, 1);
+  Schedule(Aircraft,        1);
+  Schedule(Rotation,        1);
+  Schedule(Translation,     1);
+  Schedule(Position,        1);
+  Schedule(Auxiliary,       1);
+  Schedule(Output,          1);
 
   modelLoaded = false;
 
@@ -255,36 +255,38 @@ 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 ( 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;
+  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;
 
   FirstModel  = 0L;
   Error       = 0;
 
-  State        = 0;
-  Atmosphere   = 0;
-  FCS          = 0;
-  Propulsion   = 0;
-  MassBalance  = 0;
-  Aerodynamics = 0;
-  Inertial     = 0;
-  Aircraft     = 0;
-  Translation  = 0;
-  Rotation     = 0;
-  Position     = 0;
-  Auxiliary    = 0;
-  Output       = 0;
+  State           = 0;
+  Atmosphere      = 0;
+  FCS             = 0;
+  Propulsion      = 0;
+  MassBalance     = 0;
+  Aerodynamics    = 0;
+  Inertial        = 0;
+  GroundReactions = 0;
+  Aircraft        = 0;
+  Translation     = 0;
+  Rotation        = 0;
+  Position        = 0;
+  Auxiliary       = 0;
+  Output          = 0;
 
   modelLoaded = false;
   return modelLoaded;
@@ -576,7 +578,7 @@ bool FGFDMExec::LoadScript(string script)
          exit(-1);
   }
   if ( ! State->Reset("aircraft", aircraft, initialize))
-                 State->Initialize(2000,0,0,0,0,0,0.5,0.5,40000);
+                 State->Initialize(2000,0,0,0,0,0,0.5,0.5,40000,0,0,0);
 
   return true;
 }
index b5a3ee7cf7023d38d28c6ae7c18c44cf3be97cff..c817a6d6b0db0ab3bc36e69d2753d9135d6890e2 100644 (file)
@@ -42,6 +42,7 @@ INCLUDES
 
 #include "FGModel.h"
 #include "FGInitialCondition.h"
+#include "FGJSBBase.h"
 #include <vector>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -61,6 +62,7 @@ class FGPropulsion;
 class FGMassBalance;
 class FGAerodynamics;
 class FGInertial;
+class FGGroundReactions;
 class FGAircraft;
 class FGTranslation;
 class FGRotation;
@@ -194,7 +196,7 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGFDMExec
+class FGFDMExec : public FGJSBBase
 {
 public:
   /// Default constructor
@@ -275,6 +277,8 @@ public:
   inline FGAerodynamics* GetAerodynamics(void){return Aerodynamics;}
   /// Returns the FGInertial pointer.
   inline FGInertial* GetInertial(void)        {return Inertial;}
+  /// Returns the FGGroundReactions pointer.
+  inline FGGroundReactions* GetGroundReactions(void) {return GroundReactions;}
   /// Returns the FGAircraft pointer.
   inline FGAircraft* GetAircraft(void)        {return Aircraft;}
   /// Returns the FGTranslation pointer.
@@ -312,19 +316,20 @@ private:
   float  EndTime;
   vector <struct condition> Conditions;
 
-  FGState*        State;
-  FGAtmosphere*   Atmosphere;
-  FGFCS*          FCS;
-  FGPropulsion*   Propulsion;
-  FGMassBalance*  MassBalance;
-  FGAerodynamics* Aerodynamics;
-  FGInertial*     Inertial;
-  FGAircraft*     Aircraft;
-  FGTranslation*  Translation;
-  FGRotation*     Rotation;
-  FGPosition*     Position;
-  FGAuxiliary*    Auxiliary;
-  FGOutput*       Output;
+  FGState*           State;
+  FGAtmosphere*      Atmosphere;
+  FGFCS*             FCS;
+  FGPropulsion*      Propulsion;
+  FGMassBalance*     MassBalance;
+  FGAerodynamics*    Aerodynamics;
+  FGInertial*        Inertial;
+  FGGroundReactions* GroundReactions;
+  FGAircraft*        Aircraft;
+  FGTranslation*     Translation;
+  FGRotation*        Rotation;
+  FGPosition*        Position;
+  FGAuxiliary*       Auxiliary;
+  FGOutput*          Output;
 
   bool Allocate(void);
   bool DeAllocate(void);
index c6cfdc49924bb06cdcc1655bf8384f412ab749bf..bbc4c177bffebc8039838f813f64a42ca1267b01 100644 (file)
@@ -45,19 +45,22 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include "FGDefs.h"
 #include "FGCoefficient.h"
 #include "FGFactorGroup.h"
 #include "FGState.h"
 #include "FGFDMExec.h"
 
 #ifndef FGFS
-#  include <iomanip>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <iomanip.h>
+#  else
+#    include <iomanip>
+#  endif
 #else
 #  include STL_IOMANIP
 #endif
 
-extern short debug_lvl;
-
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FACTORGROUP;
 
@@ -128,41 +131,6 @@ float FGFactorGroup::TotalValue(void) {
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-string FGFactorGroup::GetCoefficientStrings(void) {
-  int i;
-  string CoeffStrings;
-  
-  CoeffStrings += name;
-  CoeffStrings += ", ";
-  CoeffStrings += FGCoefficient::Getname();
-  for(i=0;i<sum.size();i++) {
-    CoeffStrings += ", ";
-    CoeffStrings += sum[i]->Getname();
-  }
-  return CoeffStrings;    
-}
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-string FGFactorGroup::GetCoefficientValues(void) {
-    int i;
-    char buffer[10];
-    string values;
-    
-    snprintf(buffer,10,"%9.6f",SDtotal);
-    values += string(buffer);
-    values += ", ";
-    snprintf(buffer,10,"%9.6f",FGCoefficient::GetSD() );
-    values += string(buffer);
-    values += ", ";
-    for(i=0;i<sum.size();i++) {
-       values += sum[i]->GetCoefficientValues();
-    }
-    return values;
-}       
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
 void FGFactorGroup::Debug(void)
 {
   cout << "FGCoefficient::GetSD(): " << FGCoefficient::GetSD() << endl;
index 38a08c0784e849df55f8f7c160da446876e0e9c2..e524cd200be7d9828e69bb0499556c755a20492e 100644 (file)
@@ -100,8 +100,8 @@ class FGFactorGroup: public FGCoefficient {
     
     bool Load(FGConfigFile *AC_cfg);
     float TotalValue(void);
-    string GetCoefficientStrings(void);
-    string GetCoefficientValues(void);
+    //string GetCoefficientStrings(void);
+    //string GetCoefficientValues(void);
     inline float GetSD(void) { return SDtotal; }
     inline float GetFactorSD(void) { return FGCoefficient::GetSD(); }
     
index aa762ac9320b07a0b51addc54231983a7b620ae3..9c2945f1b5c8fe6ffd8073479373ef9ecf027372 100644 (file)
@@ -43,15 +43,15 @@ and the cg.
 #include "FGFDMExec.h"
 #include "FGAircraft.h"
 #include "FGTranslation.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 #include "FGDefs.h"
 #include "FGForce.h"
 
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FORCE;
 
-extern short debug_lvl;
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 FGForce::FGForce(FGFDMExec *FDMExec) :
@@ -82,7 +82,7 @@ FGForce::~FGForce()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGColumnVector FGForce::GetBodyForces(void) {
+FGColumnVector3& FGForce::GetBodyForces(void) {
 
   vFb=Transform()*(vFn.multElementWise(vSense));
 
@@ -99,7 +99,7 @@ FGColumnVector FGForce::GetBodyForces(void) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGMatrix FGForce::Transform(void) {
+FGMatrix33 FGForce::Transform(void) {
   switch(ttype) {
   case tWindBody:
     return fdmex->GetState()->GetTs2b(fdmex->GetTranslation()->Getalpha(),fdmex->GetTranslation()->Getbeta());
index 5046496c7b4e9f8274a842121afa6458358f954d..58c48af4179efa94b58004495b1543732b90878a 100644 (file)
@@ -60,18 +60,169 @@ INCLUDES
 #define ID_FORCE "$Id$"
 
 #include "FGFDMExec.h"
-#include "FGMatrix.h"
+#include "FGJSBBase.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DECLARATION
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGForce {
+/** Utility class that aids in the conversion of forces between coordinate systems
+    and calculation of moments.
+<br><h3>Resolution of Applied Forces into Moments and Body Axes Components</h3>
+<br><p>
+All forces acting on the aircraft that cannot be considered a change in weight
+need to be resolved into body axis components so that the aircraft acceleration
+vectors, both translational and rotational, can be computed. Furthermore, the
+moments produced by each force that does not act at a location corresponding to
+the center of gravity also need to be computed. Unfortunately, the math required
+to do this can be a bit messy and errors are easily introduced so the class
+FGForce was created to provide these services in a consistent and reusable
+manner.<br><br></p>
+
+<h4>Basic usage</h4>
+
+<p>FGForce requires that its users supply it with the location of the applied
+force vector in JSBSim structural coordinates, the sense of each axis in that
+coordinate system relative to the body system, the orientation of the vector
+also relative to body coordinates and, of course, the force vector itself. With
+this information it will compute both the body axis force components and the
+resulting moments. Any moments inherently produced by the native system can be
+supplied as well and they will be summed with those computed.</p>
+
+<p>A good example for demonstrating the use of this class are the aerodynamic
+forces: lift, drag, and side force and the aerodynamic moments about the pitch,
+roll and yaw axes. These "native" forces and moments are computed and stored
+in the FGColumnVector objects vFs and vMoments. Their native coordinate system
+is often referred to as the wind system and is defined as a right-handed system
+having its x-axis aligned with the relative velocity vector and pointing towards
+the rear of the aircraft , the y-axis extending out the right wing, and the
+z-axis directed upwards. This is different than body axes; they are defined such
+that the x-axis is lies on the aircraft's roll axis and positive forward, the
+y-axis is positive out the right wing, and the z-axis is positive downwards. In
+this instance, JSBSim already provides the needed transform and FGForce can make
+use of it by calling SetTransformType() once an object is created:</p>
+
+<p><tt>FGForce fgf(FDMExec);</tt><br>
+<tt>fgf.SetTransformType(tWindBody);</tt><br><br>
+
+This call need only be made once for each object. The available transforms are
+defined in the enumerated type TransformType and are tWindBody, tLocalBody,
+tCustom, and tNone. The local-to-body transform, like the wind-to-body, also
+makes use of that already available in JSBSim. tNone sets FGForce to do no
+angular transform at all, and tCustom allows for modeling force vectors at
+arbitrary angles relative to the body system such as that produced by propulsion
+systems. Setting up and using a custom transform is covered in more detail below.
+Continuing with the example, the point of application of the aerodynamic forces,
+the aerodynamic reference point in JSBSim, also needs to be set:</p>
+<p><tt>
+fgf.SetLocation(x, y, z)</tt></p>
+
+<p>where x, y, and z are in JSBSim structural coordinates.</p>
+
+<p>Initialization is complete and the FGForce object is ready to do its job. As
+stated above, the lift, drag, and side force are computed and stored in the
+vector vFs and need to be passed to FGForce:</p>
+
+<p><tt>fgf.SetNativeForces(vFs);</tt> </p>
+
+<p>The same applies to the aerodynamic pitching, rolling and yawing moments:</p>
+
+<p><tt>fgf.SetNativeMoments(vMoments);</tt></p>
+
+<p>Note that storing the native forces and moments outside of this class is not
+strictly necessary, overloaded SetNativeForces() and SetNativeMoments() methods
+which each accept three floats (rather than a vector) are provided and can be
+repeatedly called without incurring undue overhead. The body axes force vector
+can now be retrieved by calling:</p>
+
+<p><tt>vFb=fgf.GetBodyForces();</tt></p>
+
+<p>This method is where the bulk of the work gets done so calling it more than
+once for the same set of native forces and moments should probably be avoided.
+Note that the moment calculations are done here as well so they should not be
+retrieved after calling the GetBodyForces() method:</p>
+
+<p><tt>vM=fgf.GetMoments();</tt> </p>
+
+<p>As an aside, the native moments are not needed to perform the computations
+correctly so, if the FGForce object is not being used to store them then an
+alternate approach is to avoid the SetNativeMoments call and perform the sum</p>
+
+<p><tt>vMoments+=fgf.GetMoments();</tt> <br><br>
+
+after the forces have been retrieved. </p>
+
+<h4>Use of the Custom Transform Type</h4>
+
+<p>In cases where the native force vector is not aligned with the body, wind, or
+local coordinate systems a custom transform type is provided. A vectorable engine
+nozzle will be used to demonstrate its usage. Initialization is much the same:</p>
+
+<p><tt>FGForce fgf(FDMExec);</tt> <br>
+<tt>fgf.SetTransformType(tCustom);</tt> <br>
+<tt>fgf.SetLocation(x,y,z);</tt> </p>
+
+<p>Except that here the tCustom transform type is specified and the location of
+the thrust vector is used rather than the aerodynamic reference point. Thrust is
+typically considered to be positive when directed aft while the body x-axis is
+positive forward and, if the native system is right handed, the z-axis will be
+reversed as well. These differences in sense need to be specified using by the
+call: </p>
+
+<p><tt>fgf.SetSense(-1,1,-1);</tt></p>
+
+<p>The angles are specified by calling the method: </p>
+
+<p><tt>fgf.SetAnglesToBody(pitch, roll, yaw);</tt> </p>
+
+<p>in which the transform matrix is computed. Note that these angles should be
+taken relative to the body system and not the local as the names might suggest.
+For an aircraft with vectorable thrust, this method will need to be called
+every time the nozzle angle changes, a fixed engine/nozzle installation, on the
+other hand, will require it to be be called only once.</p>
+
+<p>Retrieval of the computed forces and moments is done as detailed above.</p>
+<br>
+<blockquote>
+    <p><i>CAVEAT: If the custom system is used to compute
+    the wind-to-body transform, then the sign of the sideslip
+    angle must be reversed when calling SetAnglesToBody().
+    This is true because sideslip angle does not follow the right
+    hand rule. Using the custom transform type this way
+    should not be necessary, as it is already provided as a built
+    in type (and the sign differences are correctly accounted for).</i>
+    <br></p>
+</blockquote>
+
+<h4>Use as a Base Type</h4>
 
-public:
+<p>For use as a base type, the native force and moment vector data members are
+defined as protected. In this case the SetNativeForces() and SetNativeMoments()
+methods need not be used and, instead, the assignments to vFn, the force vector,
+and vMn, the moments, can be made directly. Otherwise, the usage is similar.<br>
+<br><br></p>
+
+    @author Tony Peden
+    @version $Id$
+*/
 
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGForce : public FGJSBBase
+{
+public:
+  /// Constructor
   FGForce(FGFDMExec *FDMExec);
+  /// Destructor
   ~FGForce();
 
   enum TransformType { tNone, tWindBody, tLocalBody, tCustom } ttype;
@@ -81,22 +232,22 @@ public:
     vFn(2)=Fny;
     vFn(3)=Fnz;
   }
-  inline void SetNativeForces(FGColumnVector vv) { vFn = vv; };
+  inline void SetNativeForces(FGColumnVector3 vv) { vFn = vv; };
 
   inline void SetNativeMoments(float Ln,float Mn, float Nn) {
     vMn(1)=Ln;
     vMn(2)=Mn;
     vMn(3)=Nn;
   }
-  inline void SetNativeMoments(FGColumnVector vv) { vMn = vv; }
+  inline void SetNativeMoments(FGColumnVector3 vv) { vMn = vv; }
 
-  inline FGColumnVector GetNativeForces(void) { return vFn; }
-  inline FGColumnVector GetNativeMoments(void) { return vMn; }
+  inline FGColumnVector3& GetNativeForces(void) { return vFn; }
+  inline FGColumnVector3& GetNativeMoments(void) { return vMn; }
 
 
-  FGColumnVector GetBodyForces(void);
+  FGColumnVector3& GetBodyForces(void);
 
-  inline FGColumnVector GetMoments(void) { return vM; }
+  inline FGColumnVector3& GetMoments(void) { return vM; }
 
   //point of application, JSBsim structural coords
   //(inches, x +back, y +right, z +up)
@@ -105,8 +256,8 @@ public:
     vXYZn(2) = y;
     vXYZn(3) = z;
   }
-  inline void SetLocation(FGColumnVector vv) { vXYZn = vv; }
-  FGColumnVector GetLocation(void) { return vXYZn; }
+  inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; }
+  FGColumnVector3& GetLocation(void) { return vXYZn; }
 
   //these angles are relative to body axes, not earth!!!!!
   //I'm using these because pitch, roll, and yaw are easy to visualize,
@@ -116,32 +267,32 @@ public:
   //They are in radians.
 
   void SetAnglesToBody(float broll, float bpitch, float byaw);
-  inline void  SetAnglesToBody(FGColumnVector vv) { SetAnglesToBody(vv(1), vv(2), vv(3));}
+  inline void  SetAnglesToBody(FGColumnVector3 vv) { SetAnglesToBody(vv(1), vv(2), vv(3));}
 
   inline void SetSense(float x, float y, float z) { vSense(1)=x, vSense(2)=y, vSense(3)=z; }
-  inline void SetSense(FGColumnVector vv) { vSense=vv; }
+  inline void SetSense(FGColumnVector3 vv) { vSense=vv; }
 
-  inline FGColumnVector GetSense(void) { return vSense; }
+  inline FGColumnVector3& GetSense(void) { return vSense; }
 
   inline void SetTransformType(TransformType ii) { ttype=ii; }
   inline TransformType GetTransformType(void) { return ttype; }
 
-  FGMatrix Transform(void);
+  FGMatrix33 Transform(void);
 
 protected:
-  FGColumnVector vFn;
-  FGColumnVector vMn;
+  FGColumnVector3 vFn;
+  FGColumnVector3 vMn;
   FGFDMExec *fdmex;
-  void Debug(void);
+  virtual void Debug(void);
 
 private:
-  FGColumnVector vFb;
-  FGColumnVector vM;
-  FGColumnVector vXYZn;
-  FGColumnVector vDXYZ;
-  FGColumnVector vSense;
+  FGColumnVector3 vFb;
+  FGColumnVector3 vM;
+  FGColumnVector3 vXYZn;
+  FGColumnVector3 vDXYZ;
+  FGColumnVector3 vSense;
 
-  FGMatrix mT;
+  FGMatrix33 mT;
 };
 
 #endif
index 0d310fd9d98232153c97d3fc6f8ef6b798202615..06983a02cf71e7867afac4fe0aba65a155f1c0bb 100644 (file)
@@ -40,23 +40,98 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_GROUNDREACTIONS;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
-FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex)
+FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex),
+                                                        vForces(3),
+                                                        vMoments(3),
+                                                        vMaxStaticGrip(3),
+                                                        vMaxMomentResist(3)
 {
-  if (debug_lvl & 2) cout << "Instantiated: FGGroundReactions" << endl;
+  Name = "FGGroundReactions";
+
+  GearUp = false;
+  if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGGroundReactions:: Run(void) {
+bool FGGroundReactions::Run(void)
+{
+  float steerAngle = 0.0;
+  float xForces = 0.0, yForces = 0.0;
 
   if (!FGModel::Run()) {
+    vForces.InitMatrix();
+    vMoments.InitMatrix();
+
+    // Only execute gear force code below 300 feet
+    if ( !GearUp && Position->GetDistanceAGL() < 300.0 ) {
+      vector <FGLGear>::iterator iGear = lGear.begin();
+      // Sum forces and moments for all gear, here.
+      // Some optimizations may be made here - or rather in the gear code itself.
+      // The gear ::Run() method is called several times - once for each gear.
+      // Perhaps there is some commonality for things which only need to be
+      // calculated once.
+      while (iGear != lGear.end()) {
+        vForces  += iGear->Force();
+        vMoments += iGear->Moment();
+        iGear++;
+      }
+
+      // Only execute this code when the aircraft ground speed is very, very small.
+      if (fabs(Translation->GetUVW(eX)) < 0.1 &&
+          fabs(Translation->GetUVW(eZ)) < 0.1)
+      {
+        // Initialize the comparison matrices.
+        vMaxStaticGrip.InitMatrix();
+        vMaxMomentResist.InitMatrix();
+        iGear = lGear.begin();
+        // For each gear that is touching the ground (which had better be all of them!)
+        // calculate the X and Y direction maximum "gripping" power. Also, keep track
+        // of the number of gear that have weight on wheels. This is probably unnecessary.
+        while (iGear != lGear.end()) {
+          // calculate maximum gripping power for each gear here based on brake
+          // and steering settings
+          // also calculate total number of wheels with WOW set true?
+          if (iGear->GetWOW()) {
+            steerAngle = iGear->GetSteerAngle();
+            vMaxStaticGrip(eX) += (iGear->GetBrakeFCoeff()*cos(steerAngle) - 
+                 iGear->GetstaticFCoeff()*sin(steerAngle))*iGear->GetCompForce();
+            vMaxStaticGrip(eY) += iGear->GetBrakeFCoeff()*sin(steerAngle) + 
+                  iGear->GetstaticFCoeff()*cos(steerAngle)*iGear->GetCompForce();
+            vMaxStaticGrip(eZ)  = 0.0;
+//            vMaxMomentResist += 1;
+          }
+          iGear++;
+        }
+
+        // Calculate the X and Y direction non-gear forces to counteract if needed.
+        xForces =  -1.0 * ( Aerodynamics->GetForces(eX)
+                          + Propulsion->GetForces(eX)
+                          + Inertial->GetForces(eX));
+
+        yForces =  -1.0 * ( Aerodynamics->GetForces(eY)
+                          + Propulsion->GetForces(eY)
+                          + Inertial->GetForces(eY));
+
+        // These if statement comparisons probably need some validation and work
+        if (fabs(xForces) < fabs(vMaxStaticGrip(eX))) { // forces exceed gear power
+          vForces(eX) = xForces;
+        }
+
+        if (fabs(yForces) < fabs(vMaxStaticGrip(eY))) { // forces exceed gear power
+          vForces(eY) = yForces;
+        }
+
+        vMoments(eZ) = -(Aerodynamics->GetMoments(eZ) + Propulsion->GetMoments(eZ));
+      }
+    } else {
+      // Crash Routine
+    }
 
     return false;
   } else {
@@ -68,11 +143,61 @@ bool FGGroundReactions:: Run(void) {
 
 bool FGGroundReactions::Load(FGConfigFile* AC_cfg)
 {
+  string token;
+
+  AC_cfg->GetNextConfigLine();
+
+  while ((token = AC_cfg->GetValue()) != "/UNDERCARRIAGE") {
+    lGear.push_back(FGLGear(AC_cfg, FDMExec));
+  }
+
   return true;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+string FGGroundReactions::GetGroundReactionStrings(void)
+{
+  string GroundReactionStrings = "";
+  bool firstime = true;
+
+  for (unsigned int i=0;i<lGear.size();i++) {
+    if (!firstime) GroundReactionStrings += ", ";
+    GroundReactionStrings += (lGear[i].GetName() + "_WOW, ");
+    GroundReactionStrings += (lGear[i].GetName() + "_compressLength, ");
+    GroundReactionStrings += (lGear[i].GetName() + "_compressSpeed, ");
+    GroundReactionStrings += (lGear[i].GetName() + "_Force");
+
+    firstime = false;
+  }
+
+  return GroundReactionStrings;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+string FGGroundReactions::GetGroundReactionValues(void)
+{
+  char buff[20];
+  string GroundReactionValues = "";
+
+  bool firstime = true;
+
+  for (unsigned int i=0;i<lGear.size();i++) {
+    if (!firstime) GroundReactionValues += ", ";
+    GroundReactionValues += string( lGear[i].GetWOW()?"1":"0" ) + ", ";
+    GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(),    5, buff)) + ", ");
+    GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(),    6, buff)) + ", ");
+    GroundReactionValues += (string(gcvt(lGear[i].GetCompForce(), 10, buff)));
+
+    firstime = false;
+  }
+
+  return GroundReactionValues;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGGroundReactions::Debug(void)
 {
     //TODO: Add your source code here
index a0b4caf0e2034d30838087e4f99bddfdb6086a3e..e24d1727732320fbd32303891963836feac4dcb8 100644 (file)
@@ -55,6 +55,9 @@ INCLUDES
 
 #include "FGModel.h"
 #include "FGConfigFile.h"
+#include "FGLGear.h"
+#include "FGInertial.h"
+#include "FGMatrix33.h"
 
 #define ID_GROUNDREACTIONS "$Id$"
 
@@ -62,16 +65,27 @@ INCLUDES
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGGroundReactions : public FGModel {
-
+class FGGroundReactions : public FGModel
+{
 public:
   FGGroundReactions(FGFDMExec*);
-  ~FGGroundReactions();
+  ~FGGroundReactions() {};
 
   bool Run(void);
   bool Load(FGConfigFile* AC_cfg);
+  FGColumnVector3& GetForces(void) {return vForces;}
+  FGColumnVector3& GetMoments(void) {return vMoments;}
+  string GetGroundReactionStrings(void);
+  string GetGroundReactionValues(void);
 
 private:
+  vector <FGLGear> lGear;
+  bool GearUp;
+  FGColumnVector3 vForces;
+  FGColumnVector3 vMoments;
+  FGColumnVector3 vMaxStaticGrip;
+  FGColumnVector3 vMaxMomentResist;
+
   void Debug(void);
 };
 
index db9ffe46ece93d04a0085fc43dee447ceb27443d..a224c35919f320583c99154c151e526d3f6d00d1 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_INERTIAL;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -52,7 +50,8 @@ CLASS IMPLEMENTATION
 FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex),
     vForces(3),
     vOmegaLocal(3),
-    vRadius(3)
+    vRadius(3),
+    vGravity(3)
 {
   Name = "FGInertial";
 
@@ -81,9 +80,9 @@ bool FGInertial::Run(void)
     sphi = sin(Rotation->GetEuler(ePhi));
     cphi = cos(Rotation->GetEuler(ePhi));
 
-    vForces(eX) = -GRAVITY*stht;
-    vForces(eY) =  GRAVITY*sphi*ctht;
-    vForces(eZ) =  GRAVITY*cphi*ctht;
+    vGravity(eX) = vForces(eX) = -GRAVITY*stht;
+    vGravity(eY) = vForces(eY) =  GRAVITY*sphi*ctht;
+    vGravity(eZ) = vForces(eZ) =  GRAVITY*cphi*ctht;
     
     // The following equation for vOmegaLocal terms shows the angular velocity
     // calculation _for_the_local_frame_ given the earth's rotation (first set)
index a4cf900744cb9cb4bc6dc043e5be97502af693eb..f5be24d221e7239bb273ff93160155584e035ab5 100644 (file)
@@ -55,7 +55,9 @@ INCLUDES
 
 #include "FGModel.h"
 #include "FGConfigFile.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 #define ID_INERTIAL "$Id$"
 
@@ -71,14 +73,17 @@ public:
   ~FGInertial(void);
 
   bool Run(void);
-  FGColumnVector GetForces(void) {return vForces;}
+  FGColumnVector3& GetForces(void) {return vForces;}
+  FGColumnVector3& GetGravity(void) {return vGravity;}
+  float GetForces(int n) {return vForces(n);}
   bool LoadInertial(FGConfigFile* AC_cfg);
 
 private:
   void Debug(void);
-  FGColumnVector vOmegaLocal;
-  FGColumnVector vForces;
-  FGColumnVector vRadius;
+  FGColumnVector3 vOmegaLocal;
+  FGColumnVector3 vForces;
+  FGColumnVector3 vRadius;
+  FGColumnVector3 vGravity;
 };
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 2982bc970f67315a390e3f9ded8a1f14dbdba571..3b53a74b9c77f19c9f62d501bbc864c8b797cd0e 100644 (file)
@@ -54,12 +54,11 @@ INCLUDES
 #include "FGAuxiliary.h"
 #include "FGOutput.h"
 #include "FGDefs.h"
+#include "FGConfigFile.h"
 
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_INITIALCONDITION;
 
-extern short debug_lvl;
-
 //******************************************************************************
 
 FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec){
@@ -71,12 +70,17 @@ FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec){
   altitude=hdot=0;
   latitude=longitude=0;
   u=v=w=0;
-  vw=vw=ww=0;
+  uw=vw=ww=0;
   vnorth=veast=vdown=0;
+  wnorth=weast=wdown=0;
+  whead=wcross=0;
+  wdir=wmag=0;
   lastSpeedSet=setvt;
+  lastWindSet=setwned;
   sea_level_radius = EARTHRAD;
   radius_to_vehicle = EARTHRAD;
   terrain_altitude = 0;
+  
 
   salpha=sbeta=stheta=sphi=spsi=sgamma=0;
   calpha=cbeta=ctheta=cphi=cpsi=cgamma=1;
@@ -130,27 +134,19 @@ void FGInitialCondition::SetVequivalentKtsIC(float tt) {
 //******************************************************************************
 
 void FGInitialCondition::SetVgroundFpsIC(float tt) {
-  //float ua,va,wa;
+  float ua,va,wa;
   float vxz;
 
-  //cout << "FGInitialCondition::SetVgroundFpsIC" << endl;
   vg=tt;
   lastSpeedSet=setvg;
   vnorth = vg*cos(psi); veast = vg*sin(psi); vdown = 0;
   calcUVWfromNED();
-  //cout << "\tu,v,w: " << u << ", " << v << ", " << w << endl;
-  calcWindUVW();
-  //cout << "\tuw,vw,ww: " << uw << ", " << vw << ", " << ww << endl;
-  u = -uw; v = -vw; w = -ww;
-  //ua = u - uw; va = v - vw; wa = w - ww;
-  //cout << "\tua,va,wa: " << ua << ", " << va << ", " << wa << endl;
-  vt = sqrt( u*u + v*v + w*w );
+  ua = u + uw; va = v + vw; wa = w + ww;
+  vt = sqrt( ua*ua + va*va + wa*wa );
   alpha = beta = 0;
   vxz = sqrt( u*u + w*w );
   if( w != 0 ) alpha = atan2( w, u );
   if( vxz != 0 ) beta = atan2( v, vxz );
-  //cout << "\tvt,alpha,beta: " << vt << ", " << alpha*RADTODEG << ", "
-  //          << beta*RADTODEG << endl;
   mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
   vc=calcVcas(mach);
   ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
@@ -216,7 +212,6 @@ void FGInitialCondition::SetAlphaRadIC(float tt) {
 void FGInitialCondition::SetPitchAngleRadIC(float tt) {
   theta=tt;
   stheta=sin(theta); ctheta=cos(theta);
-  calcWindUVW();
   getAlpha();
 }
 
@@ -226,6 +221,7 @@ void FGInitialCondition::SetBetaRadIC(float tt) {
   beta=tt;
   sbeta=sin(beta); cbeta=cos(beta);
   getTheta();
+  
 }
 
 //******************************************************************************
@@ -274,7 +270,7 @@ float FGInitialCondition::GetUBodyFpsIC(void) {
     if(lastSpeedSet == setvg )
       return u;
     else
-      return vt*calpha*cbeta;
+      return vt*calpha*cbeta - uw;
 }
 
 //******************************************************************************
@@ -282,8 +278,9 @@ float FGInitialCondition::GetUBodyFpsIC(void) {
 float FGInitialCondition::GetVBodyFpsIC(void) {
     if( lastSpeedSet == setvg )
       return v;
-    else
-      return vt*sbeta;
+    else {
+      return vt*sbeta - vw;
+    }  
 }
 
 //******************************************************************************
@@ -291,26 +288,87 @@ float FGInitialCondition::GetVBodyFpsIC(void) {
 float FGInitialCondition::GetWBodyFpsIC(void) {
     if( lastSpeedSet == setvg )
       return w;
-    else {
-      return vt*salpha*cbeta;
-   }
+    else 
+      return vt*salpha*cbeta -ww;
 }
 
 //******************************************************************************
 
 void FGInitialCondition::SetWindNEDFpsIC(float wN, float wE, float wD ) {
   wnorth = wN; weast = wE; wdown = wD;
+  lastWindSet = setwned;
+  calcWindUVW();
   if(lastSpeedSet == setvg)
     SetVgroundFpsIC(vg);
+}
+
+//******************************************************************************
+
+// positive from left
+void FGInitialCondition::SetHeadWindKtsIC(float head){ 
+    whead=head*KTSTOFPS;
+    lastWindSet=setwhc; 
+    calcWindUVW();
+    if(lastSpeedSet == setvg)
+      SetVgroundFpsIC(vg);
+
+} 
+
+//******************************************************************************
+
+void FGInitialCondition::SetCrossWindKtsIC(float cross){ 
+    wcross=cross*KTSTOFPS; 
+    lastWindSet=setwhc; 
+    calcWindUVW();
+    if(lastSpeedSet == setvg)
+      SetVgroundFpsIC(vg);
+
+} 
+
+//******************************************************************************
+
+void FGInitialCondition::SetWindDownKtsIC(float wD) { 
+    wdown=wD; 
+    calcWindUVW();
+    if(lastSpeedSet == setvg)
+      SetVgroundFpsIC(vg);
+} 
+
+//******************************************************************************
+
+void FGInitialCondition::SetWindMagKtsIC(float mag) {
+  wmag=mag*KTSTOFPS;
+  lastWindSet=setwmd;
+  calcWindUVW();    
+  if(lastSpeedSet == setvg)
+      SetVgroundFpsIC(vg);
+}
 
+//******************************************************************************
 
+void FGInitialCondition::SetWindDirDegIC(float dir) {
+  wdir=dir*DEGTORAD;
+  lastWindSet=setwmd;
+  calcWindUVW();    
+  if(lastSpeedSet == setvg)
+      SetVgroundFpsIC(vg);
 }
 
+
 //******************************************************************************
 
 void FGInitialCondition::calcWindUVW(void) {
-  if(lastSpeedSet == setvg ) {
-
+    
+    switch(lastWindSet) {
+      case setwmd:
+        wnorth=wmag*cos(wdir);
+        weast=wmag*sin(wdir);
+      break;
+      case setwhc:
+        wnorth=whead*cos(psi) + wcross*cos(psi+M_PI/2);
+        weast=whead*sin(psi) + wcross*sin(psi+M_PI/2);
+      break;
+    }    
     uw=wnorth*ctheta*cpsi +
        weast*ctheta*spsi -
        wdown*stheta;
@@ -320,6 +378,8 @@ void FGInitialCondition::calcWindUVW(void) {
     ww=wnorth*(cphi*stheta*cpsi + sphi*spsi) +
        weast*(cphi*stheta*spsi - sphi*cpsi) +
        wdown*cphi*ctheta;
+            
+   
     /* cout << "FGInitialCondition::calcWindUVW: wnorth, weast, wdown "
          << wnorth << ", " << weast << ", " << wdown << endl;
     cout << "FGInitialCondition::calcWindUVW: theta, phi, psi "
@@ -327,9 +387,6 @@ void FGInitialCondition::calcWindUVW(void) {
     cout << "FGInitialCondition::calcWindUVW: uw, vw, ww "
           << uw << ", " << vw << ", " << ww << endl;   */
 
-  } else {
-    uw=vw=ww=0;
-  }
 }
 
 //******************************************************************************
@@ -338,7 +395,6 @@ void FGInitialCondition::SetAltitudeFtIC(float tt) {
   altitude=tt;
   fdmex->GetPosition()->Seth(altitude);
   fdmex->GetAtmosphere()->Run();
-
   //lets try to make sure the user gets what they intended
 
   switch(lastSpeedSet) {
@@ -380,8 +436,6 @@ void FGInitialCondition::SetSeaLevelRadiusFtIC(double tt) {
 
 void FGInitialCondition::SetTerrainAltitudeFtIC(double tt) {
   terrain_altitude=tt;
-  fdmex->GetPosition()->SetDistanceAGL(altitude-terrain_altitude);
-  fdmex->GetPosition()->SetRunwayRadius(sea_level_radius + terrain_altitude);
 }
 
 //******************************************************************************
@@ -458,6 +512,7 @@ bool FGInitialCondition::getAlpha(void) {
       calpha=cos(alpha);
     }
   }
+  calcWindUVW();
   return result;
 }
 
@@ -476,6 +531,7 @@ bool FGInitialCondition::getTheta(void) {
       ctheta=cos(theta);
     }
   }
+  calcWindUVW();
   return result;
 }
 
@@ -590,49 +646,50 @@ bool FGInitialCondition::findInterval(float x,float guess) {
 
 //******************************************************************************
 
-bool FGInitialCondition::solve(float *y,float x) {
+bool FGInitialCondition::solve(float *y,float x)
+{
   float x1,x2,x3,f1,f2,f3,d,d0;
   float eps=1E-5;
   float const relax =0.9;
   int i;
   bool success=false;
 
-   //initializations
+  //initializations
   d=1;
 
-    x1=xlo;x3=xhi;
-    f1=(this->*sfunc)(x1)-x;
-    f3=(this->*sfunc)(x3)-x;
-    d0=fabs(x3-x1);
-
-    //iterations
-    i=0;
-    while ((fabs(d) > eps) && (i < 100)) {
-      d=(x3-x1)/d0;
-      x2=x1-d*d0*f1/(f3-f1);
-
-      f2=(this->*sfunc)(x2)-x;
-      //cout << "solve x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl;
-      //cout << "                " << f1 << "," << f2 << "," << f3 << endl;
-
-      if(fabs(f2) <= 0.001) {
-        x1=x3=x2;
-      } else if(f1*f2 <= 0.0) {
-        x3=x2;
-        f3=f2;
-        f1=relax*f1;
-      } else if(f2*f3 <= 0) {
-        x1=x2;
-        f1=f2;
-        f3=relax*f3;
-      }
-      //cout << i << endl;
-      i++;
-    }//end while
-    if(i < 100) {
-      success=true;
-      *y=x2;
+  x1=xlo;x3=xhi;
+  f1=(this->*sfunc)(x1)-x;
+  f3=(this->*sfunc)(x3)-x;
+  d0=fabs(x3-x1);
+
+  //iterations
+  i=0;
+  while ((fabs(d) > eps) && (i < 100)) {
+    d=(x3-x1)/d0;
+    x2=x1-d*d0*f1/(f3-f1);
+
+    f2=(this->*sfunc)(x2)-x;
+    //cout << "solve x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl;
+    //cout << "                " << f1 << "," << f2 << "," << f3 << endl;
+
+    if(fabs(f2) <= 0.001) {
+      x1=x3=x2;
+    } else if(f1*f2 <= 0.0) {
+      x3=x2;
+      f3=f2;
+      f1=relax*f1;
+    } else if(f2*f3 <= 0) {
+      x1=x2;
+      f1=f2;
+      f3=relax*f3;
     }
+    //cout << i << endl;
+    i++;
+  }//end while
+  if(i < 100) {
+    success=true;
+    *y=x2;
+  }
 
   //cout << "Success= " << success << " Vcas: " << vcas*jsbFPSTOKTS << " Mach: " << x2 << endl;
   return success;
@@ -640,8 +697,69 @@ bool FGInitialCondition::solve(float *y,float x) {
 
 //******************************************************************************
 
-void FGInitialCondition::Debug(void)
+float FGInitialCondition::GetWindDirDegIC(void) {
+  if(weast != 0.0) 
+    return atan2(weast,wnorth)*RADTODEG;
+  else if(wnorth > 0) 
+    return 0.0;
+  else
+    return 180.0;
+}        
+
+//******************************************************************************
+
+bool FGInitialCondition::Load(string path, string acname, string fname)
 {
-    //TODO: Add your source code here
-}
+  string resetDef;
+  string token="";
+
+  float temp;
+
+# ifndef macintosh
+  resetDef = path + "/" + acname + "/" + fname + ".xml";
+# else
+  resetDef = path + ";" + acname + ";" + fname + ".xml";
+# endif
+
+  cout << resetDef << endl;
+  FGConfigFile resetfile(resetDef);
+  if (!resetfile.IsOpen()) return false;
+
+  resetfile.GetNextConfigLine();
+  token = resetfile.GetValue();
+  if (token != "initialize") {
+    cerr << "The reset file " << resetDef
+         << " does not appear to be a reset file" << endl;
+    return false;
+  }
+  
+  resetfile.GetNextConfigLine();
+  resetfile >> token;
+  while (token != "/initialize" && token != "EOF") {
+    if (token == "UBODY" ) { resetfile >> temp; SetUBodyFpsIC(temp); } 
+    if (token == "VBODY" ) { resetfile >> temp; SetVBodyFpsIC(temp); } 
+    if (token == "WBODY" ) { resetfile >> temp; SetWBodyFpsIC(temp); }  
+    if (token == "LATITUDE" ) { resetfile >> temp; SetLatitudeDegIC(temp); }
+    if (token == "LONGITUDE" ) { resetfile >> temp; SetLongitudeDegIC(temp); }
+    if (token == "PHI" ) { resetfile >> temp; SetRollAngleDegIC(temp); }
+    if (token == "THETA" ) { resetfile >> temp; SetPitchAngleDegIC(temp); }
+    if (token == "PSI" ) { resetfile >> temp; SetTrueHeadingDegIC(temp); }
+    if (token == "ALPHA" ) { resetfile >> temp; SetAlphaDegIC(temp); }
+    if (token == "BETA" ) { resetfile >> temp; SetBetaDegIC(temp); }
+    if (token == "GAMMA" ) { resetfile >> temp; SetFlightPathAngleDegIC(temp); }
+    if (token == "ROC" ) { resetfile >> temp; SetClimbRateFpmIC(temp); }
+    if (token == "ALTITUDE" ) { resetfile >> temp; SetAltitudeFtIC(temp); }
+    if (token == "WINDDIR" ) { resetfile >> temp; SetWindDirDegIC(temp); }
+    if (token == "VWIND" ) { resetfile >> temp; SetWindMagKtsIC(temp); }
+    if (token == "HWIND" ) { resetfile >> temp; SetHeadWindKtsIC(temp); }
+    if (token == "XWIND" ) { resetfile >> temp; SetCrossWindKtsIC(temp); }
+    if (token == "VC" ) { resetfile >> temp; SetVcalibratedKtsIC(temp); }
+    if (token == "MACH" ) { resetfile >> temp; SetMachIC(temp); }
+    if (token == "VGROUND" ) { resetfile >> temp; SetVgroundKtsIC(temp); }
+    resetfile >> token;
+  }
 
+  fdmex->RunIC(this);
+  
+  return true;
+}  
index cee99ad8ce135e73fc6e2956c15a12db793dd978..5481148ffc41b98a8055c88f9645ef9eb907192e 100644 (file)
  Further information about the GNU General Public License can also be found on
  the world wide web at http://www.gnu.org.
  
  HISTORY
 --------------------------------------------------------------------------------
 7/1/99   TP   Created
  
 FUNCTIONAL DESCRIPTION
 --------------------------------------------------------------------------------
  
@@ -50,22 +48,43 @@ INCLUDES
 *******************************************************************************/
 
 #include "FGFDMExec.h"
+#include "FGJSBBase.h"
 #include "FGAtmosphere.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
-#define ID_INITIALCONDITION "$Id$"
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-/*******************************************************************************
-CLASS DECLARATION
-*******************************************************************************/
+#define ID_INITIALCONDITION "$Id$"
+#define jsbFPSTOKTS 0.5924838
+#define jsbKTSTOFPS 1.6878099
 
 typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
+typedef enum { setwned, setwmd, setwhc } windset; 
 
-#define jsbFPSTOKTS 0.5924838
-#define jsbKTSTOFPS 1.6878099
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Takes a set of initial conditions and provide a kinematically consistent set
+    of body axis velocity components, euler angles, and altitude.  This class
+    does not attempt to trim the model i.e. the sim will most likely start in a
+    very dynamic state (unless, of course, you have chosen your IC's wisely)
+    even after setting it up with this class.
 
+   USAGE NOTES
 
-/* USAGE NOTES
    With a valid object of FGFDMExec and an aircraft model loaded
    FGInitialCondition fgic=new FGInitialCondition(FDMExec);
    fgic->SetVcalibratedKtsIC()
@@ -82,6 +101,7 @@ typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
    FDMExec->RunIC(fgic)
    
    Speed:
+   
         Since vc, ve, vt, and mach all represent speed, the remaining
         three are recalculated each time one of them is set (using the
         current altitude).  The most recent speed set is remembered so 
@@ -91,10 +111,12 @@ typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
         most recent speed set.
    
    Alpha,Gamma, and Theta:
-     This class assumes that it will be used to set up the sim for a
+   
+   This class assumes that it will be used to set up the sim for a
         steady, zero pitch rate condition. Since any two of those angles 
    specifies the third gamma (flight path angle) is favored when setting
    alpha and theta and alpha is favored when setting gamma. i.e.
+   
        set alpha : recalculate theta using gamma as currently set
                  set theta : recalculate alpha using gamma as currently set
                  set gamma : recalculate theta using alpha as currently set
@@ -104,12 +126,20 @@ typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
         
         Setting climb rate is, for the purpose of this discussion, 
         considered equivalent to setting gamma.
+   @author Anthony K. Peden
+   @version $Id$
 */
-class FGInitialCondition {
-public:
 
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGInitialCondition : public FGJSBBase
+{
+public:
+  /// Constructor
   FGInitialCondition(FGFDMExec *fdmex);
+  /// Destructor
   ~FGInitialCondition();
 
   void SetVcalibratedKtsIC(float tt);
@@ -171,7 +201,17 @@ public:
   void SetVnorthFpsIC(float tt);
   void SetVeastFpsIC(float tt);
   void SetVdownFpsIC(float tt);
+  
   void SetWindNEDFpsIC(float wN, float wE, float wD);
+  void SetWindMagKtsIC(float mag);
+  void SetWindDirDegIC(float dir);
+  void SetHeadWindKtsIC(float head);
+  void SetCrossWindKtsIC(float cross);// positive from left
+  void SetWindDownKtsIC(float wD);                                          
+  
   void SetClimbRateFpsIC(float tt);
   inline float GetVgroundFpsIC(void) { return vg; }
   inline float GetVtrueFpsIC(void) { return vt; }
@@ -181,6 +221,8 @@ public:
   inline float GetWindNFpsIC(void) { return wnorth; }
   inline float GetWindEFpsIC(void) { return weast; }
   inline float GetWindDFpsIC(void) { return wdown; }
+  inline float GetWindFpsIC(void)  { return sqrt(wnorth*wnorth + weast*weast); }
+  float GetWindDirDegIC(void); 
   inline float GetClimbRateFpsIC(void) { return hdot; }
   float GetUBodyFpsIC(void);
   float GetVBodyFpsIC(void);
@@ -206,6 +248,9 @@ public:
   inline float GetPsiRadIC(void)   { return psi; }
 
   inline speedset GetSpeedSet(void) { return lastSpeedSet; }
+  inline windset GetWindSet(void) { return lastWindSet; }
+  
+  bool Load(string path, string acname, string fname);
 
 private:
   float vt,vc,ve,vg;
@@ -216,6 +261,7 @@ private:
   float uw,vw,ww;
   float vnorth,veast,vdown;
   float wnorth,weast,wdown;
+  float whead, wcross, wdir, wmag;
   double sea_level_radius;
   double terrain_altitude;
   double radius_to_vehicle;
@@ -230,6 +276,7 @@ private:
   fp sfunc;
 
   speedset lastSpeedSet;
+  windset lastWindSet;
 
   FGFDMExec *fdmex;
 
@@ -245,7 +292,6 @@ private:
 
   bool findInterval(float x,float guess);
   bool solve(float *y, float x);
-  void Debug(void);
 };
 
 #endif
index 6be481e9dde5610b4122af82a8df738734d5d4f2..fc418fe5aacb6f00a08e43801c40fbd10f2a8a60 100644 (file)
@@ -53,8 +53,6 @@ GLOBAL DATA
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_LGEAR;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -62,6 +60,9 @@ CLASS IMPLEMENTATION
 FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : vXYZ(3),
                                                            vMoment(3),
                                                            vWhlBodyVec(3),
+                                                           vForce(3),
+                                                           vLocalForce(3),
+                                                           vWhlVelVec(3),
                                                            Exec(fdmex)
 {
   string tmp;
@@ -181,17 +182,13 @@ FGLGear::~FGLGear()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGColumnVector FGLGear::Force(void)
+FGColumnVector3& FGLGear::Force(void)
 {
-  float SteerGain, SteerAngle, BrakeFCoeff;
+  float SteerGain;
   float SinWheel, CosWheel, SideWhlVel, RollingWhlVel;
   float RudderPedal, RollingForce, SideForce, FCoeff;
   float WheelSlip;
 
-  FGColumnVector vForce(3);
-  FGColumnVector vLocalForce(3);
-  FGColumnVector vWhlVelVec(3);     // Velocity of this wheel (Local)
-
   vWhlBodyVec     = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
   vWhlBodyVec(eX) = -vWhlBodyVec(eX);
   vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
@@ -225,6 +222,7 @@ FGColumnVector FGLGear::Force(void)
 // wheel velocity.
 
     vWhlVelVec      =  State->GetTb2l() * (Rotation->GetPQR() * vWhlBodyVec);
+
     vWhlVelVec     +=  Position->GetVel();
 
     compressSpeed   =  vWhlVelVec(eZ);
@@ -247,30 +245,30 @@ FGColumnVector FGLGear::Force(void)
 
     switch (eBrakeGrp) {
     case bgLeft:
-      SteerGain = -maxSteerAngle;
+      SteerGain = -0.10;
       BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
                                             staticFCoeff*FCS->GetBrake(bgLeft);
       break;
     case bgRight:
-      SteerGain = -maxSteerAngle;
+      SteerGain = -0.10;
       BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
                                            staticFCoeff*FCS->GetBrake(bgRight);
       break;
     case bgCenter:
-      SteerGain = -maxSteerAngle;
+      SteerGain = -0.10;
       BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
                                            staticFCoeff*FCS->GetBrake(bgCenter);
       break;
     case bgNose:
-      SteerGain = maxSteerAngle;
+      SteerGain = 0.10;
       BrakeFCoeff = rollingFCoeff;
       break;
     case bgTail:
-      SteerGain = -maxSteerAngle;
+      SteerGain = -0.10;
       BrakeFCoeff = rollingFCoeff;
       break;
     case bgNone:
-      SteerGain = -maxSteerAngle;
+      SteerGain = -0.10;
       BrakeFCoeff = rollingFCoeff;
       break;
     default:
@@ -280,7 +278,7 @@ FGColumnVector FGLGear::Force(void)
 
     switch (eSteerType) {
     case stSteer:
-      SteerAngle = SteerGain*FCS->GetDrCmd();
+      SteerAngle = SteerGain*FCS->GetDrPos();
       break;
     case stFixed:
       SteerAngle = 0.0;
@@ -298,8 +296,8 @@ FGColumnVector FGLGear::Force(void)
 // For now, steering angle is assumed to happen in the Local Z axis,
 // not the strut axis as it should be.  Will fix this later.
 
-    SinWheel      = sin(Rotation->Getpsi() + SteerAngle*DEGTORAD);
-    CosWheel      = cos(Rotation->Getpsi() + SteerAngle*DEGTORAD);
+    SinWheel      = sin(Rotation->Getpsi() + SteerAngle);
+    CosWheel      = cos(Rotation->Getpsi() + SteerAngle);
     RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
     SideWhlVel    = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
 
index 046853d5fb4718240d8267735416d7d32f411d77..b6c7ab0ed40d95ed9d8ecc8f296a8c2de4229207 100644 (file)
@@ -44,8 +44,11 @@ INCLUDES
 
 #include <string>
 #include "FGConfigFile.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 #include "FGFDMExec.h"
+#include "FGJSBBase.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -172,7 +175,7 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGLGear
+class FGLGear : public FGJSBBase
 {
 public:
   /// Brake grouping enumerators
@@ -191,15 +194,15 @@ public:
 
 
   /// The Force vector for this gear
-  FGColumnVector Force(void);
+  FGColumnVector3& Force(void);
   /// The Moment vector for this gear
-  FGColumnVector Moment(void) {return vMoment;}
+  FGColumnVector3& Moment(void) {return vMoment;}
 
   /// Gets the location of the gear in Body axes
-  FGColumnVector GetBodyLocation(void) { return vWhlBodyVec; }
+  FGColumnVector3& GetBodyLocation(void) { return vWhlBodyVec; }
   float GetBodyLocation(int idx) { return vWhlBodyVec(idx); }
 
-  FGColumnVector GetLocalGear(void) { return vLocalGear; }
+  FGColumnVector3& GetLocalGear(void) { return vLocalGear; }
   float GetLocalGear(int idx) { return vLocalGear(idx); }
 
   /// Gets the name of the gear
@@ -212,6 +215,7 @@ public:
   inline float  GetCompVel(void)   {return compressSpeed; }
   /// Gets the gear compression force in pounds
   inline float  GetCompForce(void) {return Force()(3);    }
+  inline float  GetBrakeFCoeff(void) {return BrakeFCoeff;}
   
   /// Sets the brake value in percent (0 - 100)
   inline void SetBrake(double bp) {brakePct = bp;}
@@ -222,19 +226,25 @@ public:
   /** Get the console touchdown reporting feature
       @return true if reporting is turned on */
   inline bool GetReport(void)    { return ReportEnable; }
+  inline float GetSteerAngle(void) { return SteerAngle;}
+  inline float GetstaticFCoeff(void) { return staticFCoeff;}
 
 private:
-  enum {eX=1, eY, eZ};
-  FGColumnVector vXYZ;
-  FGColumnVector vMoment;
-  FGColumnVector vWhlBodyVec;
-  FGColumnVector vLocalGear;
+  FGColumnVector3 vXYZ;
+  FGColumnVector3 vMoment;
+  FGColumnVector3 vWhlBodyVec;
+  FGColumnVector3 vLocalGear;
+  FGColumnVector3 vForce;
+  FGColumnVector3 vLocalForce;
+  FGColumnVector3 vWhlVelVec;     // Velocity of this wheel (Local)
+  float SteerAngle;
   float kSpring;
   float bDamp;
   float compressLength;
   float compressSpeed;
   float staticFCoeff, dynamicFCoeff, rollingFCoeff;
   float brakePct;
+  float BrakeFCoeff;
   float maxCompLen;
   double SinkRate;
   double GroundSpeed;
index b670b2176a9bc8bf7e7bb5d12b7440510249e413..da8124d629970fd18aceac068857f79ecc7c48d0 100644 (file)
@@ -43,8 +43,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_MASSBALANCE;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 8dc53da8407340e39de390271ef5e31f064b6898..06c63cbd8722700386afdb1ba326a8dae5e917f5 100644 (file)
@@ -67,7 +67,7 @@ public:
   inline float GetIzz(void) {return Izz;}
   inline float GetIxz(void) {return Ixz;}
   inline float GetIyz(void) {return Iyz;}
-  inline FGColumnVector& GetXYZcg(void) {return vXYZcg;}
+  inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
   inline float GetXYZcg(int axis) {return vXYZcg(axis);}
 
   inline void SetEmptyWeight(float EW) { EmptyWeight = EW;}
@@ -76,7 +76,7 @@ public:
   inline void SetBaseIzz(float bizz)   { baseIzz = bizz;}
   inline void SetBaseIxz(float bixz)   { baseIxz = bixz;}
   inline void SetBaseIyz(float biyz)   { baseIyz = biyz;}
-  inline void SetBaseCG(const FGColumnVector& CG) {vbaseXYZcg = CG;}
+  inline void SetBaseCG(const FGColumnVector3& CG) {vbaseXYZcg = CG;}
 
 private:
   float Weight;
@@ -92,9 +92,9 @@ private:
   float baseIzz;
   float baseIxz;
   float baseIyz;
-  FGColumnVector vXYZcg;
-  FGColumnVector vXYZtank;
-  FGColumnVector vbaseXYZcg;
+  FGColumnVector3 vXYZcg;
+  FGColumnVector3 vXYZtank;
+  FGColumnVector3 vbaseXYZcg;
   void Debug(void);
 };
 
index 7006b1d0bb2711893d2d1cf266ad71697a3f9aad..c7f2d4de3c43fe1ab3eba6354429aac5c441b6eb 100644 (file)
@@ -47,6 +47,7 @@ INCLUDES
 #include "FGMassBalance.h"
 #include "FGAerodynamics.h"
 #include "FGInertial.h"
+#include "FGGroundReactions.h"
 #include "FGAircraft.h"
 #include "FGTranslation.h"
 #include "FGRotation.h"
@@ -61,8 +62,6 @@ static const char *IdHdr = ID_MODEL;
 GLOBAL DECLARATIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -72,19 +71,20 @@ FGModel::FGModel(FGFDMExec* fdmex)
   FDMExec     = fdmex;
   NextModel   = 0L;
 
-  State        = 0;
-  Atmosphere   = 0;
-  FCS          = 0;
-  Propulsion   = 0;
-  MassBalance  = 0;
-  Aerodynamics = 0;
-  Inertial     = 0;
-  Aircraft     = 0;
-  Translation  = 0;
-  Rotation     = 0;
-  Position     = 0;
-  Auxiliary    = 0;
-  Output       = 0;
+  State           = 0;
+  Atmosphere      = 0;
+  FCS             = 0;
+  Propulsion      = 0;
+  MassBalance     = 0;
+  Aerodynamics    = 0;
+  Inertial        = 0;
+  GroundReactions = 0;
+  Aircraft        = 0;
+  Translation     = 0;
+  Rotation        = 0;
+  Position        = 0;
+  Auxiliary       = 0;
+  Output          = 0;
 
   exe_ctr     = 1;
 
@@ -102,19 +102,20 @@ FGModel::~FGModel()
 
 bool FGModel::InitModel(void)
 {
-  State        = FDMExec->GetState();
-  Atmosphere   = FDMExec->GetAtmosphere();
-  FCS          = FDMExec->GetFCS();
-  Propulsion   = FDMExec->GetPropulsion();
-  MassBalance  = FDMExec->GetMassBalance();
-  Aerodynamics = FDMExec->GetAerodynamics();
-  Inertial     = FDMExec->GetInertial();
-  Aircraft     = FDMExec->GetAircraft();
-  Translation  = FDMExec->GetTranslation();
-  Rotation     = FDMExec->GetRotation();
-  Position     = FDMExec->GetPosition();
-  Auxiliary    = FDMExec->GetAuxiliary();
-  Output       = FDMExec->GetOutput();
+  State           = FDMExec->GetState();
+  Atmosphere      = FDMExec->GetAtmosphere();
+  FCS             = FDMExec->GetFCS();
+  Propulsion      = FDMExec->GetPropulsion();
+  MassBalance     = FDMExec->GetMassBalance();
+  Aerodynamics    = FDMExec->GetAerodynamics();
+  Inertial        = FDMExec->GetInertial();
+  GroundReactions = FDMExec->GetGroundReactions();
+  Aircraft        = FDMExec->GetAircraft();
+  Translation     = FDMExec->GetTranslation();
+  Rotation        = FDMExec->GetRotation();
+  Position        = FDMExec->GetPosition();
+  Auxiliary       = FDMExec->GetAuxiliary();
+  Output          = FDMExec->GetOutput();
 
   if (!State ||
       !Atmosphere ||
@@ -123,6 +124,7 @@ bool FGModel::InitModel(void)
       !MassBalance ||
       !Aerodynamics ||
       !Inertial ||
+      !GroundReactions ||
       !Aircraft ||
       !Translation ||
       !Rotation ||
@@ -149,8 +151,3 @@ bool FGModel::Run()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGModel::Debug(void)
-{
-    //TODO: Add your source code here
-}
-
index e81a5a932a67990055cf10758aa52eab02e0252e..3ba25c1c4f2881ac563ea75ccf986dbeb5fee3de 100644 (file)
@@ -39,6 +39,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGDefs.h"
+#include "FGJSBBase.h"
 
 #ifdef FGFS
 #  include <simgear/compiler.h>
@@ -48,7 +49,11 @@ INCLUDES
 #    include <iostream.h>
 #  endif
 #else
-#  include <iostream>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <iostream.h>
+#  else
+#    include <iostream>
+#  endif
 #endif
 
 #include <string>
@@ -73,6 +78,7 @@ class FGPropulsion;
 class FGMassBalance;
 class FGAerodynamics;
 class FGInertial;
+class FGGroundReactions;
 class FGAircraft;
 class FGTranslation;
 class FGRotation;
@@ -97,7 +103,7 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGModel
+class FGModel : public FGJSBBase
 {
 public:
 
@@ -123,31 +129,24 @@ public:
   virtual int  GetRate(void)   {return rate;}
 
 protected:
-  enum {eU=1, eV, eW};
-  enum {eNorth=1, eEast, eDown};
-  enum {eP=1, eQ, eR};
-  enum {eL=1, eM, eN};
-  enum {eX=1, eY, eZ};
-  enum {ePhi=1, eTht, ePsi};
-
   int exe_ctr;
   int rate;
 
-  FGFDMExec*      FDMExec;
-  FGState*        State;
-  FGAtmosphere*   Atmosphere;
-  FGFCS*          FCS;
-  FGPropulsion*   Propulsion;
-  FGMassBalance*  MassBalance;
-  FGAerodynamics* Aerodynamics;
-  FGInertial*     Inertial;
-  FGAircraft*     Aircraft;
-  FGTranslation*  Translation;
-  FGRotation*     Rotation;
-  FGPosition*     Position;
-  FGAuxiliary*    Auxiliary;
-  FGOutput*       Output;
-  virtual void Debug(void);
+  FGFDMExec*         FDMExec;
+  FGState*           State;
+  FGAtmosphere*      Atmosphere;
+  FGFCS*             FCS;
+  FGPropulsion*      Propulsion;
+  FGMassBalance*     MassBalance;
+  FGAerodynamics*    Aerodynamics;
+  FGInertial*        Inertial;
+  FGGroundReactions* GroundReactions;
+  FGAircraft*        Aircraft;
+  FGTranslation*     Translation;
+  FGRotation*        Rotation;
+  FGPosition*        Position;
+  FGAuxiliary*       Auxiliary;
+  FGOutput*          Output;
 };
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index f4346b531943b9d1459ef7133a0a13b95235ef26..b571e6ff3695603c8d45626c18a22bdf52db9049 100644 (file)
@@ -47,8 +47,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_NOZZLE;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index d8737e0596d8ac53bab1e08d1bc78d042ed7a77e..7a97261a663edaf656e3b156d0eda722c170c764 100644 (file)
@@ -46,11 +46,6 @@ DEFINITIONS
 
 #define ID_NOZZLE "$Id$";
 
-#ifndef M_PI
-#  include <simgear/constants.h>
-#  define M_PI SG_PI
-#endif
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index af3b8ad221ac05871c677e44df4d985c7c953a20..b5fd9e57a1aaea5c02a075d02fa051d1e87cfb96 100644 (file)
@@ -44,6 +44,7 @@ INCLUDES
 #include "FGAtmosphere.h"
 #include "FGFCS.h"
 #include "FGAerodynamics.h"
+#include "FGGroundReactions.h"
 #include "FGAircraft.h"
 #include "FGMassBalance.h"
 #include "FGTranslation.h"
@@ -54,8 +55,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_OUTPUT;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -94,11 +93,7 @@ bool FGOutput::Run(void)
       if (Type == otSocket) {
         SocketOutput();
       } else if (Type == otCSV) {
-        if (Filename != "COUT" && Filename != "cout" && Filename.size() > 0) {
-          DelimitedOutput(Filename);
-        } else {
-          DelimitedOutput();
-        }
+        DelimitedOutput(Filename);
       } else if (Type == otTerminal) {
         // Not done yet
       } else if (Type == otNone) {
@@ -133,320 +128,171 @@ void FGOutput::SetType(string type)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGOutput::DelimitedOutput(void)
+void FGOutput::DelimitedOutput(string fname)
 {
+# if defined(sgi) && !defined(__GNUC__)
+  ostream_withassign outstream;
+# else
+  _IO_ostream_withassign outstream;
+# endif
+
+  if (fname == "COUT" || fname == "cout") {
+    outstream = cout;
+  } else {
+    datafile.open(fname.c_str());
+    outstream = datafile;
+  }
+
   if (dFirstPass) {
-    cout << "Time";
+    outstream << "Time";
     if (SubSystems & FGAircraft::ssSimulation) {
       // Nothing here, yet
     }
     if (SubSystems & FGAircraft::ssAerosurfaces) {
-      cout << ", ";
-      cout << "Throttle, ";
-      cout << "Aileron Cmd, ";
-      cout << "Elevator Cmd, ";
-      cout << "Rudder Cmd, ";
-      cout << "Aileron Pos, ";
-      cout << "Elevator Pos, ";
-      cout << "Rudder Pos";
+      outstream << ", ";
+      outstream << "Throttle, ";
+      outstream << "Aileron Cmd, ";
+      outstream << "Elevator Cmd, ";
+      outstream << "Rudder Cmd, ";
+      outstream << "Aileron Pos, ";
+      outstream << "Elevator Pos, ";
+      outstream << "Rudder Pos";
     }
     if (SubSystems & FGAircraft::ssRates) {
-      cout << ", ";
-      cout << "P, Q, R";
+      outstream << ", ";
+      outstream << "P, Q, R";
     }
     if (SubSystems & FGAircraft::ssVelocities) {
-      cout << ", ";
-      cout << "QBar, ";
-      cout << "Vtotal, ";
-      cout << "UBody, VBody, WBody, ";
-      cout << "UAero, VAero, WAero, ";
-      cout << "Vn, Ve, Vd";
+      outstream << ", ";
+      outstream << "QBar, ";
+      outstream << "Vtotal, ";
+      outstream << "UBody, VBody, WBody, ";
+      outstream << "UAero, VAero, WAero, ";
+      outstream << "Vn, Ve, Vd";
     }
     if (SubSystems & FGAircraft::ssForces) {
-      cout << ", ";
-      cout << "Drag, Side, Lift, ";
-      cout << "L/D, ";
-      cout << "Xforce, Yforce, Zforce";
+      outstream << ", ";
+      outstream << "Drag, Side, Lift, ";
+      outstream << "L/D, ";
+      outstream << "Xforce, Yforce, Zforce";
     }
     if (SubSystems & FGAircraft::ssMoments) {
-      cout << ", ";
-      cout << "L, M, N";
+      outstream << ", ";
+      outstream << "L, M, N";
     }
     if (SubSystems & FGAircraft::ssAtmosphere) {
-      cout << ", ";
-      cout << "Rho";
+      outstream << ", ";
+      outstream << "Rho";
     }
     if (SubSystems & FGAircraft::ssMassProps) {
-      cout << ", ";
-      cout << "Ixx, ";
-      cout << "Iyy, ";
-      cout << "Izz, ";
-      cout << "Ixz, ";
-      cout << "Mass, ";
-      cout << "Xcg, Ycg, Zcg";
+      outstream << ", ";
+      outstream << "Ixx, ";
+      outstream << "Iyy, ";
+      outstream << "Izz, ";
+      outstream << "Ixz, ";
+      outstream << "Mass, ";
+      outstream << "Xcg, Ycg, Zcg";
     }
     if (SubSystems & FGAircraft::ssPosition) {
-      cout << ", ";
-      cout << "Altitude, ";
-      cout << "Phi, Tht, Psi, ";
-      cout << "Alpha, ";
-      cout << "Latitude, ";
-      cout << "Longitude, ";
-      cout << "Distance AGL, ";
-      cout << "Runway Radius";
+      outstream << ", ";
+      outstream << "Altitude, ";
+      outstream << "Phi, Tht, Psi, ";
+      outstream << "Alpha, ";
+      outstream << "Latitude, ";
+      outstream << "Longitude, ";
+      outstream << "Distance AGL, ";
+      outstream << "Runway Radius";
     }
     if (SubSystems & FGAircraft::ssCoefficients) {
-      cout << ", ";
-      cout << Aerodynamics->GetCoefficientStrings();
+      outstream << ", ";
+      outstream << Aerodynamics->GetCoefficientStrings();
     }
     if (SubSystems & FGAircraft::ssGroundReactions) {
-      cout << ", ";
-      cout << Aircraft->GetGroundReactionStrings();
+      outstream << ", ";
+      outstream << GroundReactions->GetGroundReactionStrings();
     }
     if (SubSystems & FGAircraft::ssPropulsion) {
-      cout << ", ";
-      cout << Propulsion->GetPropulsionStrings();
+      outstream << ", ";
+      outstream << Propulsion->GetPropulsionStrings();
     }
 
-    cout << endl;
+    outstream << endl;
     dFirstPass = false;
   }
 
-  cout << State->Getsim_time();
+  outstream << State->Getsim_time();
   if (SubSystems & FGAircraft::ssSimulation) {
   }
   if (SubSystems & FGAircraft::ssAerosurfaces) {
-    cout << ", ";
-    cout << FCS->GetThrottlePos(0) << ", ";
-    cout << FCS->GetDaCmd() << ", ";
-    cout << FCS->GetDeCmd() << ", ";
-    cout << FCS->GetDrCmd() << ", ";
-    cout << FCS->GetDaPos() << ", ";
-    cout << FCS->GetDePos() << ", ";
-    cout << FCS->GetDrPos();
+    outstream << ", ";
+    outstream << FCS->GetThrottlePos(0) << ", ";
+    outstream << FCS->GetDaCmd() << ", ";
+    outstream << FCS->GetDeCmd() << ", ";
+    outstream << FCS->GetDrCmd() << ", ";
+    outstream << FCS->GetDaPos() << ", ";
+    outstream << FCS->GetDePos() << ", ";
+    outstream << FCS->GetDrPos();
   }
   if (SubSystems & FGAircraft::ssRates) {
-    cout << ", ";
-    cout << Rotation->GetPQR();
+    outstream << ", ";
+    outstream << Rotation->GetPQR();
   }
   if (SubSystems & FGAircraft::ssVelocities) {
-    cout << ", ";
-    cout << Translation->Getqbar() << ", ";
-    cout << Translation->GetVt() << ", ";
-    cout << Translation->GetUVW() << ", ";
-    cout << Translation->GetvAero() << ", ";
-    cout << Position->GetVel();
+    outstream << ", ";
+    outstream << Translation->Getqbar() << ", ";
+    outstream << Translation->GetVt() << ", ";
+    outstream << Translation->GetUVW() << ", ";
+    outstream << Translation->GetvAero() << ", ";
+    outstream << Position->GetVel();
   }
   if (SubSystems & FGAircraft::ssForces) {
-    cout << ", ";
-    cout << Aerodynamics->GetvFs() << ", ";
-    cout << Aerodynamics->GetLoD() << ", ";
-    cout << Aircraft->GetForces();
+    outstream << ", ";
+    outstream << Aerodynamics->GetvFs() << ", ";
+    outstream << Aerodynamics->GetLoD() << ", ";
+    outstream << Aircraft->GetForces();
   }
   if (SubSystems & FGAircraft::ssMoments) {
-    cout << ", ";
-    cout << Aircraft->GetMoments();
+    outstream << ", ";
+    outstream << Aircraft->GetMoments();
   }
   if (SubSystems & FGAircraft::ssAtmosphere) {
-    cout << ", ";
-    cout << Atmosphere->GetDensity();
+    outstream << ", ";
+    outstream << Atmosphere->GetDensity();
   }
   if (SubSystems & FGAircraft::ssMassProps) {
-    cout << ", ";
-    cout << MassBalance->GetIxx() << ", ";
-    cout << MassBalance->GetIyy() << ", ";
-    cout << MassBalance->GetIzz() << ", ";
-    cout << MassBalance->GetIxz() << ", ";
-    cout << MassBalance->GetMass() << ", ";
-    cout << MassBalance->GetXYZcg();
+    outstream << ", ";
+    outstream << MassBalance->GetIxx() << ", ";
+    outstream << MassBalance->GetIyy() << ", ";
+    outstream << MassBalance->GetIzz() << ", ";
+    outstream << MassBalance->GetIxz() << ", ";
+    outstream << MassBalance->GetMass() << ", ";
+    outstream << MassBalance->GetXYZcg();
   }
   if (SubSystems & FGAircraft::ssPosition) {
-    cout << ", ";
-    cout << Position->Geth() << ", ";
-    cout << Rotation->GetEuler() << ", ";
-    cout << Translation->Getalpha() << ", ";
-    cout << Position->GetLatitude() << ", ";
-    cout << Position->GetLongitude() << ", ";
-    cout << Position->GetDistanceAGL() << ", ";
-    cout << Position->GetRunwayRadius();
+    outstream << ", ";
+    outstream << Position->Geth() << ", ";
+    outstream << Rotation->GetEuler() << ", ";
+    outstream << Translation->Getalpha() << ", ";
+    outstream << Position->GetLatitude() << ", ";
+    outstream << Position->GetLongitude() << ", ";
+    outstream << Position->GetDistanceAGL() << ", ";
+    outstream << Position->GetRunwayRadius();
   }
   if (SubSystems & FGAircraft::ssCoefficients) {
-    cout << ", ";
-    cout << Aerodynamics->GetCoefficientValues();
+    outstream << ", ";
+    outstream << Aerodynamics->GetCoefficientValues();
   }
   if (SubSystems & FGAircraft::ssGroundReactions) {
-    cout << ", ";
-    cout << Aircraft->GetGroundReactionValues();
+    outstream << ", ";
+    outstream << GroundReactions->GetGroundReactionValues();
   }
   if (SubSystems & FGAircraft::ssPropulsion) {
-    cout << ", ";
-    cout << Propulsion->GetPropulsionValues();
+    outstream << ", ";
+    outstream << Propulsion->GetPropulsionValues();
   }
 
-  cout << endl;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGOutput::DelimitedOutput(string fname)
-{
-  if (sFirstPass) {
-    datafile.open(fname.c_str());
-    datafile << "Time";
-    if (SubSystems & FGAircraft::ssSimulation) {
-      // Nothing here, yet
-    }
-    if (SubSystems & FGAircraft::ssAerosurfaces) {
-      datafile << ", ";
-      datafile << "Throttle, ";
-      datafile << "Aileron Cmd, ";
-      datafile << "Elevator Cmd, ";
-      datafile << "Rudder Cmd, ";
-      datafile << "Aileron Pos, ";
-      datafile << "Elevator Pos, ";
-      datafile << "Rudder Pos";
-    }
-    if (SubSystems & FGAircraft::ssRates) {
-      datafile << ", ";
-      datafile << "P, Q, R";
-    }
-    if (SubSystems & FGAircraft::ssVelocities) {
-      datafile << ", ";
-      datafile << "QBar, ";
-      datafile << "Vtotal, ";
-      datafile << "UBody, VBody, WBody, ";
-      datafile << "UAero, VAero, WAero, ";
-      datafile << "Vn, Ve, Vd";
-    }
-    if (SubSystems & FGAircraft::ssForces) {
-      datafile << ", ";
-      datafile << "Drag, Side, Lift, ";
-      datafile << "L/D, ";
-      datafile << "Xforce, Yforce, Zforce";
-    }
-    if (SubSystems & FGAircraft::ssMoments) {
-      datafile << ", ";
-      datafile << "L, M, N";
-    }
-    if (SubSystems & FGAircraft::ssAtmosphere) {
-      datafile << ", ";
-      datafile << "Rho";
-    }
-    if (SubSystems & FGAircraft::ssMassProps) {
-      datafile << ", ";
-      datafile << "Ixx, ";
-      datafile << "Iyy, ";
-      datafile << "Izz, ";
-      datafile << "Ixz, ";
-      datafile << "Mass, ";
-      datafile << "Xcg, Ycg, Zcg";
-    }
-    if (SubSystems & FGAircraft::ssPosition) {
-      datafile << ", ";
-      datafile << "Altitude, ";
-      datafile << "Phi, Tht, Psi, ";
-      datafile << "Alpha, ";
-      datafile << "Latitude, ";
-      datafile << "Longitude, ";
-      datafile << "Distance AGL, ";
-      datafile << "Runway Radius";
-    }
-    if (SubSystems & FGAircraft::ssCoefficients) {
-      datafile << ", ";
-      datafile << Aerodynamics->GetCoefficientStrings();
-    }
-    if (SubSystems & FGAircraft::ssGroundReactions) {
-      datafile << ", ";
-      datafile << Aircraft->GetGroundReactionStrings();
-    }
-    if (SubSystems & FGAircraft::ssFCS) {
-      datafile << ", ";
-      datafile << FCS->GetComponentStrings();
-    }
-    if (SubSystems & FGAircraft::ssPropulsion) {
-      datafile << ", ";
-      datafile << Propulsion->GetPropulsionStrings();
-    }
-    datafile << endl;
-    sFirstPass = false;
-  }
-
-  datafile << State->Getsim_time();
-  if (SubSystems & FGAircraft::ssSimulation) {
-  }
-  if (SubSystems & FGAircraft::ssAerosurfaces) {
-    datafile << ", ";
-    datafile << FCS->GetThrottlePos(0) << ", ";
-    datafile << FCS->GetDaCmd() << ", ";
-    datafile << FCS->GetDeCmd() << ", ";
-    datafile << FCS->GetDrCmd() << ", ";
-    datafile << FCS->GetDaPos() << ", ";
-    datafile << FCS->GetDePos() << ", ";
-    datafile << FCS->GetDrPos();
-  }
-  if (SubSystems & FGAircraft::ssRates) {
-    datafile << ", ";
-    datafile << Rotation->GetPQR();
-  }
-  if (SubSystems & FGAircraft::ssVelocities) {
-    datafile << ", ";
-    datafile << Translation->Getqbar() << ", ";
-    datafile << Translation->GetVt() << ", ";
-    datafile << Translation->GetUVW() << ", ";
-    datafile << Translation->GetvAero() << ", ";
-    datafile << Position->GetVel();
-  }
-  if (SubSystems & FGAircraft::ssForces) {
-    datafile << ", ";
-    datafile << Aerodynamics->GetvFs() << ", ";
-    datafile << Aerodynamics->GetLoD() << ", ";
-    datafile << Aircraft->GetForces();
-  }
-  if (SubSystems & FGAircraft::ssMoments) {
-    datafile << ", ";
-    datafile << Aircraft->GetMoments();
-  }
-  if (SubSystems & FGAircraft::ssAtmosphere) {
-    datafile << ", ";
-    datafile << Atmosphere->GetDensity();
-  }
-  if (SubSystems & FGAircraft::ssMassProps) {
-    datafile << ", ";
-    datafile << MassBalance->GetIxx() << ", ";
-    datafile << MassBalance->GetIyy() << ", ";
-    datafile << MassBalance->GetIzz() << ", ";
-    datafile << MassBalance->GetIxz() << ", ";
-    datafile << MassBalance->GetMass() << ", ";
-    datafile << MassBalance->GetXYZcg();
-  }
-  if (SubSystems & FGAircraft::ssPosition) {
-    datafile << ", ";
-    datafile << Position->Geth() << ", ";
-    datafile << Rotation->GetEuler() << ", ";
-    datafile << Translation->Getalpha() << ", ";
-    datafile << Position->GetLatitude() << ", ";
-    datafile << Position->GetLongitude() << ", ";
-    datafile << Position->GetDistanceAGL() << ", ";
-    datafile << Position->GetRunwayRadius();
-  }
-  if (SubSystems & FGAircraft::ssCoefficients) {
-    datafile << ", ";
-    datafile << Aerodynamics->GetCoefficientValues();
-  }
-  if (SubSystems & FGAircraft::ssGroundReactions) {
-    datafile << ", ";
-    datafile << Aircraft->GetGroundReactionValues();
-  }
-  if (SubSystems & FGAircraft::ssFCS) {
-    datafile << ", ";
-    datafile << FCS->GetComponentValues();
-  }
-  if (SubSystems & FGAircraft::ssPropulsion) {
-    datafile << ", ";
-    datafile << Propulsion->GetPropulsionValues();
-  }
-  datafile << endl;
-  datafile.flush();
+  outstream << endl;
+  outstream.flush();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 6638a89bbe81a721caabc4580fee7aff17d44e06..669cf521809bcd1f3caf67d6aba4e0bf004686e8 100644 (file)
@@ -45,8 +45,13 @@ INCLUDES
 #  include STL_IOSTREAM
 #  include STL_FSTREAM
 #else
-#  include <iostream>
-#  include <fstream>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <iostream.h>
+#    include <fstream.h>
+#  else
+#    include <iostream>
+#    include <fstream>
+#  endif
 #endif
 
 #include "FGfdmSocket.h"
@@ -65,7 +70,6 @@ public:
 
   bool Run(void);
 
-  void DelimitedOutput(void);
   void DelimitedOutput(string);
   void SocketOutput(void);
   void SocketStatusOutput(string);
@@ -76,8 +80,6 @@ public:
   inline void Disable(void) { enabled = false; }
   inline bool Toggle(void) {enabled = !enabled; return enabled;}
 
-protected:
-
 private:
   bool sFirstPass, dFirstPass, enabled;
   int SubSystems;
index 805200f18025037ef561f4ea51f3a6fd60a3635e..cb398ab3c4d8cbe23e2a96b789ae5ca1c942365f 100644 (file)
@@ -40,17 +40,32 @@ INCLUDES
 
 #include "FGDefs.h"
 #include "FGPiston.h"
+#include "FGPropulsion.h"
 
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_PISTON;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg) : FGEngine(exec)
+FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg)
+  : FGEngine(exec),
+    MinManifoldPressure_inHg(6.5),
+    MaxManifoldPressure_inHg(28.5),
+    Displacement(360),
+    MaxHP(200),
+    Cycles(2),
+    IdleRPM(900),
+    // Set constants
+    CONVERT_CUBIC_INCHES_TO_METERS_CUBED(1.638706e-5),
+    R_air(287.3),
+    rho_fuel(800),                 // estimate
+    calorific_value_fuel(47.3e6),
+    Cp_air(1005),
+    Cp_fuel(1700),
+    running(true),             // FIXME: FGEngine already has 'Running'
+    cranking(false)
 {
   string token;
 
@@ -58,29 +73,39 @@ FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg) : FGEngine(exec)
   Eng_cfg->GetNextConfigLine();
   while (Eng_cfg->GetValue() != "/FG_PISTON") {
     *Eng_cfg >> token;
-    if      (token == "BRAKEHORSEPOWER") *Eng_cfg >> BrakeHorsePower;
-    else if (token == "MAXTHROTTLE")     *Eng_cfg >> MaxThrottle;
-    else if (token == "MINTHROTTLE")     *Eng_cfg >> MinThrottle;
-    else if (token == "SLFUELFLOWMAX")   *Eng_cfg >> SLFuelFlowMax;
-    else if (token == "SPEEDSLOPE")      *Eng_cfg >> SpeedSlope;
-    else if (token == "SPEEDINTERCEPT")  *Eng_cfg >> SpeedIntercept;
-    else if (token == "ALTITUDESLOPE")   *Eng_cfg >> AltitudeSlope;
+    if      (token == "MINMP") *Eng_cfg >> MinManifoldPressure_inHg;
+    else if (token == "MAXMP") *Eng_cfg >> MaxManifoldPressure_inHg;
+    else if (token == "DISPLACEMENT") *Eng_cfg >> Displacement;
+    else if (token == "MAXHP") *Eng_cfg >> MaxHP;
+    else if (token == "CYCLES") *Eng_cfg >> Cycles;
+    else if (token == "IDLERPM") *Eng_cfg >> IdleRPM;
+    else if (token == "MAXTHROTTLE") *Eng_cfg >> MaxThrottle;
+    else if (token == "MINTHROTTLE") *Eng_cfg >> MinThrottle;
+    else if (token == "SLFUELFLOWMAX") *Eng_cfg >> SLFuelFlowMax;
     else cerr << "Unhandled token in Engine config file: " << token << endl;
   }
 
   if (debug_lvl > 0) {
     cout << "\n    Engine Name: " << Name << endl;
-    cout << "      BrakeHorsePower = " << BrakeHorsePower << endl;
-    cout << "      MaxThrottle = " << MaxThrottle << endl;
-    cout << "      MinThrottle = " << MinThrottle << endl;
-    cout << "      SLFuelFlowMax = " << SLFuelFlowMax << endl;
-    cout << "      SpeedSlope = " << SpeedSlope << endl;
-    cout << "      SpeedIntercept = " << SpeedIntercept << endl;
-    cout << "      AltitudeSlope = " << AltitudeSlope << endl;
+    cout << "      MinManifoldPressure: " << MinManifoldPressure_inHg << endl;
+    cout << "      MaxManifoldPressure: " << MaxManifoldPressure_inHg << endl;
+    cout << "      Displacement: " << Displacement << endl;
+    cout << "      MaxHP: " << MaxHP << endl;
+    cout << "      Cycles: " << Cycles << endl;
+    cout << "      IdleRPM: " << IdleRPM << endl;
+    cout << "      MaxThrottle: " << MaxThrottle << endl;
+    cout << "      MinThrottle: " << MinThrottle << endl;
+    cout << "      SLFuelFlowMax: " << SLFuelFlowMax << endl;
   }
 
   Type = etPiston;
-  EngineNumber = 0;
+  EngineNumber = 0;    // FIXME: this should be the actual number
+  OilTemp_degK = 298;  // FIXME: should be initialized in FGEngine
+
+  dt = State->Getdt();
+
+  // Initialisation
+  volumetric_efficiency = 0.8;  // Actually f(speed, load) but this will get us running
 
   if (debug_lvl & 2) cout << "Instantiated: FGPiston" << endl;
 }
@@ -98,24 +123,362 @@ float FGPiston::Calculate(float PowerRequired)
 {
   float h,EngineMaxPower;
 
+        // FIXME: calculate from actual fuel flow
   ConsumeFuel();
 
   Throttle = FCS->GetThrottlePos(EngineNumber);
+  Mixture = FCS->GetMixturePos(EngineNumber);
 
-  h = Position->Geth();
+  //
+  // Input values.
+  //
+        // convert from lbs/ft2 to Pa
+  p_amb = Atmosphere->GetPressure() * 48;
+  p_amb_sea_level = Atmosphere->GetPressureSL() * 48;
+        // convert from Rankine to Kelvin
+  T_amb = Atmosphere->GetTemperature() * (5.0 / 9.0);
+  RPM = Propulsion->GetThruster(EngineNumber)->GetRPM();
+  if (RPM < IdleRPM)    // kludge
+    RPM = IdleRPM;
+  IAS = Auxiliary->GetVcalibratedKTS();
 
-  if (h < 0) h = 0;
+  if (Mixture >= 0.5) {
+    doEngineStartup();
+    doManifoldPressure();
+    doAirFlow();
+    doFuelFlow();
+    doEnginePower();
+    doEGT();
+    doCHT();
+    doOilTemperature();
+    doOilPressure();
+  } else {
+    HP = 0;
+  }
 
-  EngineMaxPower = (1 + AltitudeSlope*h)*BrakeHorsePower;
-  PowerAvailable = Throttle*EngineMaxPower*HPTOFTLBSSEC - PowerRequired;
-  
+  PowerAvailable = (HP * HPTOFTLBSSEC) - PowerRequired;
   return PowerAvailable;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Look up the power/mixture correlation.
+ *
+ * FIXME: this should use JSBSim's interpolation support.
+ */
+
+static float Power_Mixture_Correlation(float thi_actual)
+{
+  float AFR_actual = 14.7 / thi_actual;
+  const int NUM_ELEMENTS = 13;
+  float AFR[NUM_ELEMENTS] = 
+    {(14.7/1.6), 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, (14.7/0.6)};
+  float mixPerPow[NUM_ELEMENTS] = 
+    {78, 86, 93.5, 98, 100, 99, 96.4, 92.5, 88, 83, 78.5, 74, 58};
+  float mixPerPow_actual = 0.0f;
+  float factor;
+  float dydx;
+
+  int i;
+  int j = NUM_ELEMENTS;
+
+  for (i=0;i<j;i++) {
+    if (i == (j-1)) {
+      dydx = (mixPerPow[i] - mixPerPow[i-1]) / (AFR[i] - AFR[i-1]);
+      mixPerPow_actual = mixPerPow[i] + dydx * (AFR_actual - AFR[i]);
+      return mixPerPow_actual;
+    }
+    if ((i == 0) && (AFR_actual < AFR[i])) {
+      dydx = (mixPerPow[i] - mixPerPow[i-1]) / (AFR[i] - AFR[i-1]);
+      mixPerPow_actual = mixPerPow[i] + dydx * (AFR_actual - AFR[i]);
+      return mixPerPow_actual;
+    }
+    if (AFR_actual == AFR[i]) {
+      mixPerPow_actual = mixPerPow[i];
+      return mixPerPow_actual;
+    }
+    if ((AFR_actual > AFR[i]) && (AFR_actual < AFR[i + 1])) {
+      factor = (AFR_actual - AFR[i]) / (AFR[i+1] - AFR[i]);
+      mixPerPow_actual = (factor * (mixPerPow[i+1] - mixPerPow[i])) + mixPerPow[i];
+      return mixPerPow_actual;
+    }
+  }
+
+  cerr << "ERROR: error in FGNewEngine::Power_Mixture_Correlation\n";
+  return mixPerPow_actual;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Look up the combustion efficiency.
+ *
+ *
+ * FIXME: this should use JSBSim's interpolation support.
+ */
+
+static float Lookup_Combustion_Efficiency(float thi_actual)
+{
+  const int NUM_ELEMENTS = 11;
+  float thi[NUM_ELEMENTS] = {0.0, 0.9, 1.0, 1.05, 1.1, 1.15, 1.2, 1.3, 1.4, 1.5, 1.6};  //array of equivalence ratio values
+  float neta_comb[NUM_ELEMENTS] = {0.98, 0.98, 0.97, 0.95, 0.9, 0.85, 0.79, 0.7, 0.63, 0.57, 0.525};  //corresponding array of combustion efficiency values
+  //combustion efficiency values from Heywood, "Internal Combustion Engine Fundamentals", ISBN 0-07-100499-8
+  float neta_comb_actual = 0.0f;
+  float factor;
+
+  int i;
+  int j = NUM_ELEMENTS;  //This must be equal to the number of elements in the lookup table arrays
+
+  for (i=0;i<j;i++) {
+    if(i == (j-1)) {
+      // Assume linear extrapolation of the slope between the last two points beyond the last point
+      float dydx = (neta_comb[i] - neta_comb[i-1]) / (thi[i] - thi[i-1]);
+      neta_comb_actual = neta_comb[i] + dydx * (thi_actual - thi[i]);
+      return neta_comb_actual;
+    }
+    if(thi_actual == thi[i]) {
+      neta_comb_actual = neta_comb[i];
+      return neta_comb_actual;
+    }
+    if((thi_actual > thi[i]) && (thi_actual < thi[i + 1])) {
+      //do linear interpolation between the two points
+      factor = (thi_actual - thi[i]) / (thi[i+1] - thi[i]);
+      neta_comb_actual = (factor * (neta_comb[i+1] - neta_comb[i])) + neta_comb[i];
+      return neta_comb_actual;
+    }
+  }
+
+  //if we get here something has gone badly wrong
+  cerr << "ERROR: error in FGNewEngine::Lookup_Combustion_Efficiency\n";
+  return neta_comb_actual;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Start or stop the engine.
+ */
+
+void FGPiston::doEngineStartup(void)
+{
+  // TODO: check magnetos, spark, starter, etc. and decide whether
+  // engine is running
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+/**
+ * Calculate the nominal manifold pressure in inches hg
+ *
+ * This function calculates nominal manifold pressure directly
+ * from the throttle position, and does not adjust it for the
+ * difference between the pressure at sea level and the pressure
+ * at the current altitude (that adjustment takes place in
+ * {@link #doEnginePower}).
+ *
+ * TODO: changes in MP should not be instantaneous -- introduce
+ * a lag between throttle changes and MP changes, to allow pressure
+ * to build up or disperse.
+ *
+ * Inputs: MinManifoldPressure_inHg, MaxManifoldPressure_inHg, Throttle
+ *
+ * Outputs: ManifoldPressure_inHg
+ */
+
+void FGPiston::doManifoldPressure(void)
+{
+  ManifoldPressure_inHg = MinManifoldPressure_inHg +
+    (Throttle * (MaxManifoldPressure_inHg - MinManifoldPressure_inHg));
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Calculate the air flow through the engine.
+ *
+ * Inputs: p_amb, R_air, T_amb, ManifoldPressure_inHg, Displacement,
+ *   RPM, volumetric_efficiency
+ *
+ * Outputs: rho_air, m_dot_air
+ */
+
+void FGPiston::doAirFlow(void)
+{
+  rho_air = p_amb / (R_air * T_amb);
+  float rho_air_manifold = rho_air * ManifoldPressure_inHg / 29.6;
+  float displacement_SI = Displacement * CONVERT_CUBIC_INCHES_TO_METERS_CUBED;
+  float swept_volume = (displacement_SI * (RPM/60)) / 2;
+  float v_dot_air = swept_volume * volumetric_efficiency;
+  m_dot_air = v_dot_air * rho_air_manifold;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Calculate the fuel flow into the engine.
+ *
+ * Inputs: Mixture, thi_sea_level, p_amb_sea_level, p_amb, m_dot_air
+ *
+ * Outputs: equivalence_ratio, m_dot_fuel
+ */
+
+void FGPiston::doFuelFlow(void)
+{
+  float thi_sea_level = 1.3 * Mixture;
+  equivalence_ratio = thi_sea_level * p_amb_sea_level / p_amb;
+  m_dot_fuel = m_dot_air / 14.7 * equivalence_ratio;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Calculate the power produced by the engine.
+ *
+ * <p>Currently, the JSBSim propellor model does not allow the
+ * engine to produce enough RPMs to get up to a high horsepower.
+ * When tested with sufficient RPM, it has no trouble reaching
+ * 200HP.</p>
+ *
+ * Inputs: ManifoldPressure_inHg, p_amb, p_amb_sea_level, RPM, T_amb, 
+ *   equivalence_ratio, Cycles, MaxHP
+ *
+ * Outputs: Percentage_Power, HP
+ */
+
+void FGPiston::doEnginePower(void)
+{
+  float True_ManifoldPressure_inHg = ManifoldPressure_inHg * p_amb / p_amb_sea_level;
+  float ManXRPM = True_ManifoldPressure_inHg * RPM;
+        // FIXME: this needs to be generalized
+  Percentage_Power = (6e-9 * ManXRPM * ManXRPM) + (8e-4 * ManXRPM) - 1.0;
+  float T_amb_degF = (T_amb * 1.8) - 459.67;
+  float T_amb_sea_lev_degF = (288 * 1.8) - 459.67; 
+  Percentage_Power =
+    Percentage_Power + ((T_amb_sea_lev_degF - T_amb_degF) * 7 /120);
+  float Percentage_of_best_power_mixture_power =
+    Power_Mixture_Correlation(equivalence_ratio);
+  Percentage_Power =
+    Percentage_Power * Percentage_of_best_power_mixture_power / 100.0;
+  if (Percentage_Power < 0.0)
+    Percentage_Power = 0.0;
+  else if (Percentage_Power > 100.0)
+    Percentage_Power = 100.0;
+  HP = Percentage_Power * MaxHP / 100.0;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Calculate the exhaust gas temperature.
+ *
+ * Inputs: equivalence_ratio, m_dot_fuel, calorific_value_fuel, 
+ *   Cp_air, m_dot_air, Cp_fuel, m_dot_fuel, T_amb, Percentage_Power
+ *
+ * Outputs: combustion_efficiency, ExhaustGasTemp_degK
+ */
+
+void FGPiston::doEGT(void)
+{
+  combustion_efficiency = Lookup_Combustion_Efficiency(equivalence_ratio);
+  float enthalpy_exhaust = m_dot_fuel * calorific_value_fuel * 
+    combustion_efficiency * 0.33;
+  float heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel);
+  float delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust;
+  ExhaustGasTemp_degK = T_amb + delta_T_exhaust;
+  ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * Percentage_Power / 100.0);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Calculate the cylinder head temperature.
+ *
+ * Inputs: T_amb, IAS, rho_air, m_dot_fuel, calorific_value_fuel,
+ *   combustion_efficiency, RPM
+ *
+ * Outputs: CylinderHeadTemp_degK
+ */
+
+void FGPiston::doCHT(void)
+{
+  float h1 = -95.0;
+  float h2 = -3.95;
+  float h3 = -0.05;
+
+  float arbitary_area = 1.0;
+  float CpCylinderHead = 800.0;
+  float MassCylinderHead = 8.0;
+
+  float temperature_difference = CylinderHeadTemp_degK - T_amb;
+  float v_apparent = IAS * 0.5144444;
+  float v_dot_cooling_air = arbitary_area * v_apparent;
+  float m_dot_cooling_air = v_dot_cooling_air * rho_air;
+  float dqdt_from_combustion = 
+    m_dot_fuel * calorific_value_fuel * combustion_efficiency * 0.33;
+  float dqdt_forced = (h2 * m_dot_cooling_air * temperature_difference) + 
+    (h3 * RPM * temperature_difference);
+  float dqdt_free = h1 * temperature_difference;
+  float dqdt_cylinder_head = dqdt_from_combustion + dqdt_forced + dqdt_free;
+    
+  float HeatCapacityCylinderHead = CpCylinderHead * MassCylinderHead;
+    
+  CylinderHeadTemp_degK = dqdt_cylinder_head / HeatCapacityCylinderHead;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Calculate the oil temperature.
+ *
+ * Inputs: Percentage_Power, running flag.
+ *
+ * Outputs: OilTemp_degK
+ */
+
+void FGPiston::doOilTemperature(void)
+{
+  float idle_percentage_power = 2.3;        // approximately
+  float target_oil_temp;        // Steady state oil temp at the current engine conditions
+  float time_constant;          // The time constant for the differential equation
+
+  if (running) {
+    target_oil_temp = 363;
+    time_constant = 500;        // Time constant for engine-on idling.
+    if (Percentage_Power > idle_percentage_power) {
+      time_constant /= ((Percentage_Power / idle_percentage_power) / 10.0);       // adjust for power 
+    }
+  } else {
+    target_oil_temp = 298;
+    time_constant = 1000;  // Time constant for engine-off; reflects the fact that oil is no longer getting circulated
+  }
+
+  float dOilTempdt = (target_oil_temp - OilTemp_degK) / time_constant;
+
+  OilTemp_degK += (dOilTempdt * dt);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/**
+ * Calculate the oil pressure.
+ *
+ * Inputs: RPM
+ *
+ * Outputs: OilPressure_psi
+ */
+
+void FGPiston::doOilPressure(void)
+{
+  float Oil_Press_Relief_Valve = 60; // FIXME: may vary by engine
+  float Oil_Press_RPM_Max = 1800;    // FIXME: may vary by engine
+  float Design_Oil_Temp = 85;        // FIXME: may vary by engine
+                                    // FIXME: WRONG!!! (85 degK???)
+  float Oil_Viscosity_Index = 0.25;
+
+  OilPressure_psi = (Oil_Press_Relief_Valve / Oil_Press_RPM_Max) * RPM;
+
+  if (OilPressure_psi >= Oil_Press_Relief_Valve) {
+    OilPressure_psi = Oil_Press_Relief_Valve;
+  }
+
+  OilPressure_psi += (Design_Oil_Temp - OilTemp_degK) * Oil_Viscosity_Index;
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGPiston::Debug(void)
 {
-    //TODO: Add your source code here
+  //TODO: Add your source code here
 }
 
index a71197c3b0dbd0081d533ee3009779ebd01c32e4..62cfdebeb986acfe5a134c5dbdf05bd02f1adae7 100644 (file)
@@ -26,6 +26,7 @@
 HISTORY
 --------------------------------------------------------------------------------
 09/12/2000  JSB  Created
+10/01/2001  DPM  Modified to use equations from Dave Luff's piston model.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 COMMENTS, REFERENCES,  and NOTES
@@ -45,8 +46,31 @@ INCLUDES
 #include "FGEngine.h"
 #include "FGConfigFile.h"
 
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
 #define ID_PISTON "$Id$";
 
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES,  and NOTES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Models Dave Luff's engine model as ported into JSBSim by David Megginson.
+    @author Jon S. Berndt (Engine framework code and framework-related mods)
+    @author Dave Luff (engine operational code)
+    @author David Megginson (porting and additional code)
+    @version $Id$
+  */
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -54,7 +78,9 @@ CLASS DECLARATION
 class FGPiston : public FGEngine
 {
 public:
+  /// Constructor
   FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg);
+  /// Destructor
   ~FGPiston();
 
   float Calculate(float PowerRequired);
@@ -66,9 +92,68 @@ private:
   float SpeedIntercept;
   float AltitudeSlope;
   float PowerAvailable;
+
+  // timestep
+  float dt;
+
+  // engine state
+  bool running;
+  bool cranking;
+
+  void doEngineStartup(void);
+  void doManifoldPressure(void);
+  void doAirFlow(void);
+  void doFuelFlow(void);
+  void doEnginePower(void);
+  void doEGT(void);
+  void doCHT(void);
+  void doOilPressure(void);
+  void doOilTemperature(void);
+
+  //
+  // constants
+  //
+  const float CONVERT_CUBIC_INCHES_TO_METERS_CUBED;
+
+  const float R_air;
+  const float rho_fuel;    // kg/m^3
+  const float calorific_value_fuel;  // W/Kg (approximate)
+  const float Cp_air;      // J/KgK
+  const float Cp_fuel;     // J/KgK
+
+  //
+  // Configuration
+  //
+  float MinManifoldPressure_inHg; // Inches Hg
+  float MaxManifoldPressure_inHg; // Inches Hg
+  float Displacement;             // cubic inches
+  float MaxHP;                    // horsepower
+  float Cycles;                   // cycles/power stroke
+  float IdleRPM;                  // revolutions per minute
+
+  //
+  // Inputs (in addition to those in FGEngine).
+  //
+  float p_amb;              // Pascals
+  float p_amb_sea_level;    // Pascals
+  float T_amb;              // degrees Kelvin
+  float RPM;                // revolutions per minute
+  float IAS;                // knots
+
+  //
+  // Outputs (in addition to those in FGEngine).
+  //
+  float rho_air;
+  float volumetric_efficiency;
+  float m_dot_air;
+  float equivalence_ratio;
+  float m_dot_fuel;
+  float Percentage_Power;
+  float HP;
+  float combustion_efficiency;
+
   void Debug(void);
 };
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 #endif
-
index 29576930aa89cf73a69c7eb179799e7915ecc60f..6e0b008bf1663f2cb59b09654b3353bb6261c528 100644 (file)
@@ -63,8 +63,13 @@ INCLUDES
 #    include <iomanip.h>
 #  endif
 #else
-#  include <cmath>
-#  include <iomanip>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <math.h>
+#    include <iomanip.h>
+#  else
+#    include <cmath>
+#    include <iomanip>
+#  endif
 #endif
 
 #include "FGPosition.h"
@@ -82,8 +87,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_POSITION;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index ca93d258a2441e02b0050b4d7a74cabb3d25687d..ca455cacd72d2b1594e89dba71ab0fcdf1874f50 100644 (file)
@@ -39,7 +39,9 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGModel.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -81,8 +83,8 @@ public:
       @return false if no error */
   bool Run(void);
   
-  inline FGColumnVector GetVel(void) { return vVel; }
-  inline FGColumnVector GetVelDot(void) { return vVelDot; }
+  inline FGColumnVector3& GetVel(void) { return vVel; }
+  inline FGColumnVector3& GetVelDot(void) { return vVelDot; }
   inline double GetVn(void)  { return vVel(eX); }
   inline double GetVe(void)  { return vVel(eY); }
   inline double GetVd(void)  { return vVel(eZ); }
@@ -97,12 +99,12 @@ public:
   inline double GetRunwayRadius(void) { return RunwayRadius; }
   inline double GetDistanceAGL(void)  { return DistanceAGL; }
   inline double GetRadius(void) { return Radius; }
-  inline FGColumnVector GetRunwayNormal(void) { return vRunwayNormal; }
+  inline FGColumnVector3& GetRunwayNormal(void) { return vRunwayNormal; }
   
   inline double GetGamma(void) { return gamma; }
   inline void SetGamma(float tt) { gamma = tt; }
   inline double GetHOverB(void) { return hoverb; }
-  void SetvVel(const FGColumnVector& v) { vVel = v; }
+  void SetvVel(const FGColumnVector3& v) { vVel = v; }
   void SetLatitude(float tt) { Latitude = tt; }
   void SetLongitude(double tt) { Longitude = tt; }
   void Seth(double tt);
@@ -114,9 +116,9 @@ public:
   }
   
 private:  
-  FGColumnVector vVel;
-  FGColumnVector vVelDot;
-  FGColumnVector vRunwayNormal;
+  FGColumnVector3 vVel;
+  FGColumnVector3 vVelDot;
+  FGColumnVector3 vRunwayNormal;
   
   double Vee, invMass, invRadius;
   double Radius, h;
index b37f66bdefad722818ca4c85bce8db687048a8c3..36b7e0e930c87269bab1e772246b9154774ec58c 100644 (file)
@@ -40,8 +40,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_PROPELLER;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 34dc2e9005cf747ad29ee38ed97a2c6e9fde7d70..cd014c76fa47d034683ba8fd8fec0c183f5600a6 100644 (file)
@@ -48,11 +48,6 @@ DEFINITIONS
 
 #define ID_PROPELLER "$Id$"
 
-#ifndef M_PI
-#  include <simgear/constants.h>
-#  define M_PI SG_PI
-#endif
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 2a2ef8cb4d1b8b6ae5a1b6df811949f25d92296d..2434228e1b97a74113798ccc6fd25a6a1d437562 100644 (file)
@@ -57,8 +57,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_PROPULSION;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -70,8 +68,8 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
   numSelectedFuelTanks = numSelectedOxiTanks = 0;
   numTanks = numEngines = numThrusters = 0;
   numOxiTanks = numFuelTanks = 0;
-  Forces  = new FGColumnVector(3);
-  Moments = new FGColumnVector(3);
+  Forces  = new FGColumnVector3(3);
+  Moments = new FGColumnVector3(3);
 
   if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
 }
@@ -394,7 +392,7 @@ string FGPropulsion::GetPropulsionValues(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGColumnVector& FGPropulsion::GetTanksCG(void)
+FGColumnVector3& FGPropulsion::GetTanksCG(void)
 {
   iTank = Tanks.begin();
   vXYZtank.InitMatrix();
@@ -423,7 +421,7 @@ float FGPropulsion::GetTanksWeight(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-float FGPropulsion::GetTanksIxx(const FGColumnVector& vXYZcg)
+float FGPropulsion::GetTanksIxx(const FGColumnVector3& vXYZcg)
 {
   float I = 0.0;
   iTank = Tanks.begin();
@@ -436,7 +434,7 @@ float FGPropulsion::GetTanksIxx(const FGColumnVector& vXYZcg)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-float FGPropulsion::GetTanksIyy(const FGColumnVector& vXYZcg)
+float FGPropulsion::GetTanksIyy(const FGColumnVector3& vXYZcg)
 {
   float I = 0.0;
   iTank = Tanks.begin();
@@ -449,7 +447,7 @@ float FGPropulsion::GetTanksIyy(const FGColumnVector& vXYZcg)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-float FGPropulsion::GetTanksIzz(const FGColumnVector& vXYZcg)
+float FGPropulsion::GetTanksIzz(const FGColumnVector3& vXYZcg)
 {
   float I = 0.0;
   iTank = Tanks.begin();
@@ -462,7 +460,7 @@ float FGPropulsion::GetTanksIzz(const FGColumnVector& vXYZcg)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-float FGPropulsion::GetTanksIxz(const FGColumnVector& vXYZcg)
+float FGPropulsion::GetTanksIxz(const FGColumnVector3& vXYZcg)
 {
   float I = 0.0;
   iTank = Tanks.begin();
@@ -475,7 +473,7 @@ float FGPropulsion::GetTanksIxz(const FGColumnVector& vXYZcg)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-float FGPropulsion::GetTanksIxy(const FGColumnVector& vXYZcg)
+float FGPropulsion::GetTanksIxy(const FGColumnVector3& vXYZcg)
 {
   float I = 0.0;
   iTank = Tanks.begin();
index 56e38c9980389e379d27fa3ff73ba93a904f593c..cc3d37115f46358120922d0df66853c6d2e3221e 100644 (file)
@@ -163,17 +163,19 @@ public:
   string GetPropulsionStrings(void);
   string GetPropulsionValues(void);
 
-  inline FGColumnVector& GetForces(void)  {return *Forces; }
-  inline FGColumnVector& GetMoments(void) {return *Moments;}
+  inline FGColumnVector3& GetForces(void)  {return *Forces; }
+  inline float GetForces(int n) { return (*Forces)(n);}
+  inline FGColumnVector3& GetMoments(void) {return *Moments;}
+  inline float GetMoments(int n) {return (*Moments)(n);}
   
-  FGColumnVector& GetTanksCG(void);
+  FGColumnVector3& GetTanksCG(void);
   float GetTanksWeight(void);
 
-  float GetTanksIxx(const FGColumnVector& vXYZcg);
-  float GetTanksIyy(const FGColumnVector& vXYZcg);
-  float GetTanksIzz(const FGColumnVector& vXYZcg);
-  float GetTanksIxz(const FGColumnVector& vXYZcg);
-  float GetTanksIxy(const FGColumnVector& vXYZcg);
+  float GetTanksIxx(const FGColumnVector3& vXYZcg);
+  float GetTanksIyy(const FGColumnVector3& vXYZcg);
+  float GetTanksIzz(const FGColumnVector3& vXYZcg);
+  float GetTanksIxz(const FGColumnVector3& vXYZcg);
+  float GetTanksIxy(const FGColumnVector3& vXYZcg);
 
 private:
   vector <FGEngine*>   Engines;
@@ -188,9 +190,9 @@ private:
   unsigned int numTanks;
   unsigned int numThrusters;
   float dt;
-  FGColumnVector *Forces;
-  FGColumnVector *Moments;
-  FGColumnVector vXYZtank;
+  FGColumnVector3 *Forces;
+  FGColumnVector3 *Moments;
+  FGColumnVector3 vXYZtank;
   void Debug(void);
 };
 
index 0b0a0c30fbb04d491bf6c069d7d358b040090fdc..da96b0cef4ecbe5eae2f6734154942be52c5c1a1 100644 (file)
@@ -44,8 +44,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_ROCKET;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 0a3df1f64de7089ad984b505ca54ef96f1ff5c9f..dd928d555d6f63e271dfe6a24345d014389255a0 100644 (file)
@@ -70,8 +70,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_ROTATION;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 3f64a254656dc28543a51c7aa687e9c3bb2d5de5..410f7296e14e1ccb9b07d143145a403c266f4f92 100644 (file)
@@ -60,16 +60,17 @@ INCLUDES
 #  include <simgear/compiler.h>
 #  include <math.h>
 #else
-#  include <cmath>
-#endif
-
-#ifndef M_PI
-#  include <simgear/constants.h>
-#  define M_PI SG_PI
+#  if defined (sgi) && !defined(__GNUC__)
+#    include <math.h>
+#  else
+#    include <cmath>
+#  endif
 #endif
 
 #include "FGModel.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 #define ID_ROTATION "$Id$"
 
@@ -85,16 +86,16 @@ public:
 
   bool Run(void);
 
-  inline FGColumnVector GetPQR(void) {return vPQR;}
+  inline FGColumnVector3& GetPQR(void) {return vPQR;}
   inline float GetPQR(int axis) {return vPQR(axis);}
-  inline FGColumnVector GetPQRdot(void) {return vPQRdot;}
+  inline FGColumnVector3& GetPQRdot(void) {return vPQRdot;}
   inline float GetPQRdot(int idx) {return vPQRdot(idx);}
-  inline FGColumnVector GetEuler(void) {return vEuler;}
+  inline FGColumnVector3& GetEuler(void) {return vEuler;}
   inline float GetEuler(int axis) {return vEuler(axis);}
-  inline FGColumnVector GetEulerRates(void) { return vEulerRates; }
+  inline FGColumnVector3& GetEulerRates(void) { return vEulerRates; }
   inline float GetEulerRates(int axis) { return vEulerRates(axis); }
-  inline void SetPQR(FGColumnVector tt) {vPQR = tt;}
-  inline void SetEuler(FGColumnVector tt) {vEuler = tt;}
+  inline void SetPQR(FGColumnVector3 tt) {vPQR = tt;}
+  inline void SetEuler(FGColumnVector3 tt) {vEuler = tt;}
   
   inline float Getphi(void) {return vEuler(1);}
   inline float Gettht(void) {return vEuler(2);}
@@ -109,12 +110,12 @@ public:
   inline float GetSinpsi(void) {return sPsi;}
 
 private:
-  FGColumnVector vPQR;
-  FGColumnVector vPQRdot;
-  FGColumnVector vMoments;
-  FGColumnVector vEuler;
-  FGColumnVector vEulerRates;
-  FGColumnVector vlastPQRdot;
+  FGColumnVector3 vPQR;
+  FGColumnVector3 vPQRdot;
+  FGColumnVector3 vMoments;
+  FGColumnVector3 vEuler;
+  FGColumnVector3 vEulerRates;
+  FGColumnVector3 vlastPQRdot;
   
   float cTht,sTht;
   float cPhi,sPhi;
index 3bfd7e5d009a0ff705ad93873422cf2025bb1e1d..a80f04ad30c475b6b754071f1d449fb6a28d7e1d 100644 (file)
@@ -40,8 +40,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_ROTOR;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index d97dfb439cabc98b893d099ab6733e93fffcc5d1..3e023aa6276ddb32a4f2ff25ea6f86c94ac80658 100644 (file)
@@ -40,12 +40,11 @@ INCLUDES
 #  include <simgear/compiler.h>
 #  include <math.h>
 #else
-#  include <cmath>
-#endif
-
-#ifndef M_PI 
-#  include <simgear/constants.h>
-#  define M_PI SG_PI
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <math.h>
+#  else
+#    include <cmath>
+#  endif
 #endif
 
 #include "FGState.h"
@@ -53,8 +52,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_STATE;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 MACROS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -79,7 +76,10 @@ FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
     vlastQdot(4),
     vQdot(4),
     vTmp(4),
-    vEuler(3)
+    vEuler(3),
+    vUVW(3),
+    vLocalVelNED(3),
+    vLocalEuler(3)
 {
   FDMExec = fdex;
 
@@ -137,6 +137,14 @@ FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
   RegisterVariable(FG_LEFT_BRAKE_CMD, " left_brake_cmd " );
   RegisterVariable(FG_RIGHT_BRAKE_CMD," right_brake_cmd ");
   RegisterVariable(FG_CENTER_BRAKE_CMD," center_brake_cmd ");
+  RegisterVariable(FG_ALPHAH,          " h-tail alpha " );
+  RegisterVariable(FG_ALPHAW,          " wing alpha " );
+  RegisterVariable(FG_LBARH,           " h-tail arm " );
+  RegisterVariable(FG_LBARV,           " v-tail arm " );
+  RegisterVariable(FG_HTAILAREA,       " h-tail area " );
+  RegisterVariable(FG_VTAILAREA,       " v-tail area " );
+  RegisterVariable(FG_VBARH,           " h-tail volume " );
+  RegisterVariable(FG_VBARV,           " v-tail volume " );
   RegisterVariable(FG_SET_LOGGING,    " data_logging "   );
 
   if (debug_lvl & 2) cout << "Instantiated: FGState" << endl;
@@ -165,8 +173,22 @@ float FGState::GetParameter(eParam val_idx) {
     return Aircraft->GetWingSpan();
   case FG_CBAR:
     return Aircraft->Getcbar();
+  case FG_LBARH:
+    return Aircraft->Getlbarh();
+  case FG_LBARV:
+    return Aircraft->Getvbarh();
+  case FG_HTAILAREA:
+    return Aircraft->GetHTailArea();
+  case FG_VTAILAREA:
+    return Aircraft->GetVTailArea();
+  case FG_VBARH:
+    return Aircraft->Getvbarh();
+  case FG_VBARV:
+    return Aircraft->Getvbarv();
   case FG_ALPHA:
     return Translation->Getalpha();
+  case FG_ALPHAW:
+    return  Translation->Getalpha() + Aircraft->GetWingIncidence();
   case FG_ALPHADOT:
     return Translation->Getadot();
   case FG_BETA:
@@ -336,44 +358,63 @@ void FGState::SetParameter(eParam val_idx, float val) {
 // Reset: Assume all angles READ FROM FILE IN DEGREES !!
 //
 
-bool FGState::Reset(string path, string acname, string fname) {
+bool FGState::Reset(string path, string acname, string fname)
+{
   string resetDef;
+  string token="";
+
   float U, V, W;
   float phi, tht, psi;
   float latitude, longitude, h;
+  float wdir, wmag, wnorth, weast;
 
+# ifndef macintosh
   resetDef = path + "/" + acname + "/" + fname + ".xml";
-
-#if defined ( sgi ) && !defined( __GNUC__ )
-  ifstream resetfile(resetDef.c_str(), ios::in );
-#else
-  ifstream resetfile(resetDef.c_str(), ios::in | ios::binary );
-#endif
-
-  if (resetfile) {
-    resetfile >> U;
-    resetfile >> V;
-    resetfile >> W;
-    resetfile >> latitude;
-    resetfile >> longitude;
-    resetfile >> phi;
-    resetfile >> tht;
-    resetfile >> psi;
-    resetfile >> h;
-    resetfile.close();
-
-    Position->SetLatitude(latitude*DEGTORAD);
-    Position->SetLongitude(longitude*DEGTORAD);
-    Position->Seth(h);
-
-    Initialize(U, V, W, phi*DEGTORAD, tht*DEGTORAD, psi*DEGTORAD,
-               latitude*DEGTORAD, longitude*DEGTORAD, h);
-
-    return true;
-  } else {
-    cerr << "Unable to load reset file " << fname << endl;
+# else
+  resetDef = path + ";" + acname + ";" + fname + ".xml";
+# endif
+
+  FGConfigFile resetfile(resetDef);
+  if (!resetfile.IsOpen()) return false;
+
+  resetfile.GetNextConfigLine();
+  token = resetfile.GetValue();
+  if (token != "initialize") {
+    cerr << "The reset file " << resetDef
+         << " does not appear to be a reset file" << endl;
     return false;
   }
+  
+  resetfile.GetNextConfigLine();
+  resetfile >> token;
+  while (token != "/initialize" && token != "EOF") {
+    if (token == "UBODY") resetfile >> U;
+    if (token == "VBODY") resetfile >> V;
+    if (token == "WBODY") resetfile >> W;
+    if (token == "LATITUDE") resetfile >> latitude;
+    if (token == "LONGITUDE") resetfile >> longitude;
+    if (token == "PHI") resetfile >> phi;
+    if (token == "THETA") resetfile >> tht;
+    if (token == "PSI") resetfile >> psi;
+    if (token == "ALTITUDE") resetfile >> h;
+    if (token == "WINDDIR") resetfile >> wdir;
+    if (token == "VWIND") resetfile >> wmag;
+
+    resetfile >> token;
+  }
+  
+  
+  Position->SetLatitude(latitude*DEGTORAD);
+  Position->SetLongitude(longitude*DEGTORAD);
+  Position->Seth(h);
+
+  wnorth = wmag*KTSTOFPS*cos(wdir*DEGTORAD);
+  weast = wmag*KTSTOFPS*sin(wdir*DEGTORAD);
+  
+  Initialize(U, V, W, phi*DEGTORAD, tht*DEGTORAD, psi*DEGTORAD,
+               latitude*DEGTORAD, longitude*DEGTORAD, h, wnorth, weast, 0.0);
+
+  return true;
 }
 
 //***************************************************************************
@@ -383,34 +424,40 @@ bool FGState::Reset(string path, string acname, string fname) {
 
 void FGState::Initialize(float U, float V, float W,
                          float phi, float tht, float psi,
-                         float Latitude, float Longitude, float H) {
-  FGColumnVector vUVW(3);
-  FGColumnVector vLocalVelNED(3);
-  FGColumnVector vLocalEuler(3);
+                         float Latitude, float Longitude, float H,
+                         float wnorth, float weast, float wdown)
+{
   float alpha, beta;
   float qbar, Vt;
+  FGColumnVector3 vAero;
 
   Position->SetLatitude(Latitude);
   Position->SetLongitude(Longitude);
   Position->Seth(H);
 
   Atmosphere->Run();
+  
+  vLocalEuler << phi << tht << psi;
+  Rotation->SetEuler(vLocalEuler);
 
-  if (W != 0.0)
-    alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
+  InitMatrices(phi, tht, psi);
+  
+  vUVW << U << V << W;
+  Translation->SetUVW(vUVW);
+  
+  Atmosphere->SetWindNED(wnorth, weast, wdown);
+  
+  vAero = vUVW + mTl2b*Atmosphere->GetWindNED();
+  
+  if (vAero(eW) != 0.0)
+    alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
   else
     alpha = 0.0;
-  if (V != 0.0)
-    beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
+  if (vAero(eV) != 0.0)
+    beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV), (fabs(vAero(eU))/vAero(eU))*sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
   else
     beta = 0.0;
 
-  vUVW << U << V << W;
-  Translation->SetUVW(vUVW);
-
-  vLocalEuler << phi << tht << psi;
-  Rotation->SetEuler(vLocalEuler);
-
   Translation->SetAB(alpha, beta);
 
   Vt = sqrt(U*U + V*V + W*W);
@@ -421,8 +468,6 @@ void FGState::Initialize(float U, float V, float W,
   qbar = 0.5*(U*U + V*V + W*W)*Atmosphere->GetDensity();
   Translation->Setqbar(qbar);
 
-  InitMatrices(phi, tht, psi);
-
   vLocalVelNED = mTb2l*vUVW;
   Position->SetvVel(vLocalVelNED);
 }
@@ -434,7 +479,8 @@ void FGState::Initialize(FGInitialCondition *FGIC) {
   float tht,psi,phi;
   float U, V, W, h;
   float latitude, longitude;
-
+  float wnorth,weast, wdown;
+  
   latitude = FGIC->GetLatitudeRadIC();
   longitude = FGIC->GetLongitudeRadIC();
   h = FGIC->GetAltitudeFtIC();
@@ -444,13 +490,16 @@ void FGState::Initialize(FGInitialCondition *FGIC) {
   tht = FGIC->GetThetaRadIC();
   phi = FGIC->GetPhiRadIC();
   psi = FGIC->GetPsiRadIC();
-
-  Initialize(U, V, W, phi, tht, psi, latitude, longitude, h);
+  wnorth = FGIC->GetWindNFpsIC();
+  weast = FGIC->GetWindEFpsIC();
+  wdown = FGIC->GetWindDFpsIC();
   
   Position->SetSeaLevelRadius( FGIC->GetSeaLevelRadiusFtIC() );
   Position->SetRunwayRadius( FGIC->GetSeaLevelRadiusFtIC() + 
                                              FGIC->GetTerrainAltitudeFtIC() );
 
+  // need to fix the wind speed args, here.  
+  Initialize(U, V, W, phi, tht, psi, latitude, longitude, h, wnorth, weast, wdown);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -546,7 +595,7 @@ void FGState::CalcMatrices(void) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGState::IntegrateQuat(FGColumnVector vPQR, int rate) {
+void FGState::IntegrateQuat(FGColumnVector3 vPQR, int rate) {
   vQdot(1) = -0.5*(vQtrn(2)*vPQR(eP) + vQtrn(3)*vPQR(eQ) + vQtrn(4)*vPQR(eR));
   vQdot(2) =  0.5*(vQtrn(1)*vPQR(eP) + vQtrn(3)*vPQR(eR) - vQtrn(4)*vPQR(eQ));
   vQdot(3) =  0.5*(vQtrn(1)*vPQR(eQ) + vQtrn(4)*vPQR(eP) - vQtrn(2)*vPQR(eR));
@@ -560,7 +609,7 @@ void FGState::IntegrateQuat(FGColumnVector vPQR, int rate) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGColumnVector FGState::CalcEuler(void) {
+FGColumnVector3& FGState::CalcEuler(void) {
   if (mTl2b(3,3) == 0.0) mTl2b(3,3) = 0.0000001;
   if (mTl2b(1,1) == 0.0) mTl2b(1,1) = 0.0000001;
 
@@ -575,7 +624,8 @@ FGColumnVector FGState::CalcEuler(void) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGMatrix FGState::GetTs2b(float alpha, float beta) {
+FGMatrix33& FGState::GetTs2b(float alpha, float beta)
+{
   float ca, cb, sa, sb;
 
   ca = cos(alpha);
@@ -596,6 +646,76 @@ FGMatrix FGState::GetTs2b(float alpha, float beta) {
   return mTs2b;
 }
 
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGState::ReportState(void) {
+  char out[80], flap[10], gear[10];
+  
+  cout << endl << "  JSBSim State" << endl;
+  snprintf(out,80,"    Weight: %7.0f lbs.  CG: %5.1f, %5.1f, %5.1f inches\n",
+                   FDMExec->GetMassBalance()->GetWeight(),
+                   FDMExec->GetMassBalance()->GetXYZcg(1),
+                   FDMExec->GetMassBalance()->GetXYZcg(2),
+                   FDMExec->GetMassBalance()->GetXYZcg(3));
+  cout << out;             
+  if( FCS->GetDfPos() <= 0.01)
+    snprintf(flap,10,"Up");
+  else
+    snprintf(flap,10,"%2.0f",FCS->GetDfPos());
+  if(Aircraft->GetGearUp() == true)
+    snprintf(gear,10,"Up");
+  else
+    snprintf(gear,10,"Down");
+  snprintf(out,80, "    Flaps: %3s  Gear: %4s\n",flap,gear);
+  cout << out;
+  snprintf(out,80, "    Speed: %4.0f KCAS  Mach: %5.2f\n",
+                    FDMExec->GetAuxiliary()->GetVcalibratedKTS(),
+                    GetParameter(FG_MACH) );
+  cout << out;
+  snprintf(out,80, "    Altitude: %7.0f ft.  AGL Altitude: %7.0f ft.\n",
+                    Position->Geth(),
+                    Position->GetDistanceAGL() );
+  cout << out;
+  snprintf(out,80, "    Angle of Attack: %6.2f deg  Pitch Angle: %6.2f deg\n",
+                    GetParameter(FG_ALPHA)*RADTODEG,
+                    Rotation->Gettht()*RADTODEG );
+  cout << out;
+  snprintf(out,80, "    Flight Path Angle: %6.2f deg  Climb Rate: %5.0f ft/min\n",
+                    Position->GetGamma()*RADTODEG,
+                    Position->Gethdot()*60 );
+  cout << out;                  
+  snprintf(out,80, "    Normal Load Factor: %4.2f g's  Pitch Rate: %5.2f deg/s\n",
+                    Aerodynamics->GetNlf(),
+                    GetParameter(FG_PITCHRATE)*RADTODEG );
+  cout << out;
+  snprintf(out,80, "    Heading: %3.0f deg true  Sideslip: %5.2f deg\n",
+                    Rotation->Getpsi()*RADTODEG,
+                    GetParameter(FG_BETA)*RADTODEG );                  
+  cout << out;
+  snprintf(out,80, "    Bank Angle: %5.2f deg\n",
+                    Rotation->Getphi()*RADTODEG );
+  cout << out;
+  snprintf(out,80, "    Elevator: %5.2f deg  Left Aileron: %5.2f deg  Rudder: %5.2f deg\n",
+                    GetParameter(FG_ELEVATOR_POS)*RADTODEG,
+                    GetParameter(FG_AILERON_POS)*RADTODEG,
+                    GetParameter(FG_RUDDER_POS)*RADTODEG );
+  cout << out;                  
+  snprintf(out,80, "    Throttle: %5.2f%c\n",
+                    FCS->GetThrottlePos(0),'%' );
+  cout << out;
+  
+  snprintf(out,80, "    Wind Components: %5.2f kts head wind, %5.2f kts cross wind\n",
+                    FDMExec->GetAuxiliary()->GetHeadWind()*jsbFPSTOKTS,
+                    FDMExec->GetAuxiliary()->GetCrossWind()*jsbFPSTOKTS );
+  cout << out; 
+  
+  snprintf(out,80, "    Ground Speed: %4.0f knots , Ground Track: %3.0f deg true\n",
+                    Position->GetVground()*jsbFPSTOKTS,
+                    Position->GetGroundTrack()*RADTODEG );
+  cout << out;                                   
+
+} 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGState::Debug(void)
index e494d280986cfd256727ee30ef4d0ca508e21569..a2e70450dd3ceaaaf356f222663ea626dfb9052e 100644 (file)
@@ -26,9 +26,6 @@
 FUNCTIONAL DESCRIPTION
 --------------------------------------------------------------------------------
  
-Based on Flightgear code, which is based on LaRCSim. This class wraps all
-global state variables (such as velocity, position, orientation, etc.).
 HISTORY
 --------------------------------------------------------------------------------
 11/17/98   JSB   Created
@@ -52,14 +49,21 @@ INCLUDES
 #    include <fstream.h>
 #  endif
 #else
-#  include <fstream>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <fstream.h>
+#  else
+#    include <fstream>
+#  endif
 #endif
 
 #include <string>
 #include <map>
 #include "FGDefs.h"
+#include "FGJSBBase.h"
 #include "FGInitialCondition.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -77,6 +81,7 @@ class FGRotation;
 class FGAtmosphere;
 class FGOutput;
 class FGPosition;
+class FGFDMExec;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
@@ -86,77 +91,235 @@ COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
 CLASS DOCUMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+/** Encapsulates the calculation of aircraft state.
+    @author Jon S. Berndt
+    @version $Id$
+*/
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGFDMExec;
-
-class FGState {
+class FGState : public FGJSBBase
+{
 public:
+  /** Constructor
+      @param Executive a pointer to the parent executive object */
   FGState(FGFDMExec*);
+  /// Destructor
   ~FGState();
 
-  enum {ePhi=1, eTht, ePsi};
-  enum {eP=1, eQ, eR};
-  enum {eU=1, eV, eW};
-  enum {eDrag=1, eSide, eLift};
-
-  bool Reset(string, string, string);
-  void Initialize(float, float, float, float, float, float, float, float, float);
+  /** Specifies the Reset file to use.
+      The reset file normally resides in the same directory as an aircraft config file.
+      it includes the following information:
+      <ul>
+      <li>U, the body X-Axis velocity</li>
+      <li>V, the body Y-Axis velocity</li>
+      <li>W, the body Z-Axis velocity</li>
+      <li>Latitude measured in radians from the equator, negative values are south.</li>
+      <li>Longitude, measured in radians from the Greenwich meridian, negative values are west.</li>
+      <li>Phi, the roll angle in radians.</li>
+      <li>Theta, the pitch attitude in radians.</li>
+      <li>Psi, the heading angle in radians.</li>
+      <li>H, the altitude in feet</li>
+      <li>Wind Direction, the direction the wind is coming <u>from</u>.</li>
+      <li>Wind magnitude, the wind speed in fps.</li>
+      </ul>
+      @param path the path string leading to the specific aircraft file, i.e. "aircraft".
+      @param aircraft the name of the aircraft, i.e. "c172".
+      @param filename the name of the reset file without an extension, i.e. "reset00".
+      @return true if successful, false if the file could not be opened.
+      */
+  bool Reset(string path, string aircraft, string filename);
+
+  /** Initializes the simulation state based on the passed-in parameters.
+      @param U the body X-Axis velocity in fps.
+      @param V the body Y-Axis velocity in fps.
+      @param W the body Z-Axis velocity in fps.
+      @param lat latitude measured in radians from the equator, negative values are south.
+      @param lon longitude, measured in radians from the Greenwich meridian, negative values are west.
+      @param phi the roll angle in radians.
+      @param tht the pitch angle in radians.
+      @param psi the heading angle in radians measured clockwise from north.
+      @param h altitude in feet.
+      @param wnorth north velocity in feet per second
+      @param weast eastward velocity in feet per second
+      @param wdown downward velocity in feet per second
+      */
+  void Initialize(float U,
+                  float V,
+                  float W,
+                  float lat,
+                  float lon,
+                  float phi,
+                  float tht,
+                  float psi,
+                  float h,
+                  float wnorth,
+                  float weast,
+                  float wdown);
+
+  /** Initializes the simulation state based on parameters from an Initial Conditions object.
+      @param FGIC pointer to an initial conditions object.
+      @see FGInitialConditions.
+      */
   void Initialize(FGInitialCondition *FGIC);
-  bool StoreData(string);
 
+  /** Stores state data in the supplied file name.
+      @param filename the file to store the data in.
+      @return true if successful.
+      */
+  bool StoreData(string filename);
+
+  /// returns the speed of sound in feet per second.
   inline float Geta(void) { return a; }
 
+  /// Returns the simulation time in seconds.
   inline float Getsim_time(void) { return sim_time; }
+  /// Returns the simulation delta T.
   inline float Getdt(void) { return dt; }
 
+  /// Suspends the simulation and sets the delta T to zero.
   inline void Suspend(void) {saved_dt = dt; dt = 0.0;}
+  /// Resumes the simulation by resetting delta T to the correct value.
   inline void Resume(void)  {dt = saved_dt;}
 
+  /** Retrieves a parameter.
+      The parameters that can be retrieved are enumerated in FGDefs.h.
+      @param val_idx one of the enumerated JSBSim parameters.
+      @return the value of the parameter.
+      */
   float GetParameter(eParam val_idx);
+
+  /** Retrieves a parameter.
+      The parameters that can be retrieved are enumerated in FGDefs.h.
+      @param val_string a string representing one of the enumerated JSBSim parameters,
+             i.e. "FG_QBAR".
+      @return the value of the parameter.
+      */
   float GetParameter(string val_string);
-  eParam GetParameterIndex(string val_string);
 
-  inline void Seta(float tt) { a = tt; }
+  /** Retrieves the JSBSim parameter enumerated item given the text string.
+      @param val_string the parameter string, i.e. "FG_QBAR".
+      @return the JSBSim parameter index (an enumerated type) for the supplied string.
+      */
+  eParam GetParameterIndex(string val_string);
 
-  inline float Setsim_time(float tt) {
-    sim_time = tt;
+  /** Sets the speed of sound.
+      @param speed the speed of sound in feet per second.
+      */
+  inline void Seta(float speed) { a = speed; }
+
+  /** Sets the current sim time.
+      @param cur_time the current time
+      @return the current time.
+      */
+  inline float Setsim_time(float cur_time) {
+    sim_time = cur_time;
     return sim_time;
   }
-  inline void  Setdt(float tt) { dt = tt; }
-
-  void SetParameter(eParam, float);
-
+  
+  /** Sets the integration time step for the simulation executive.
+      @param delta_t the time step in seconds.
+      */
+  inline void  Setdt(float delta_t) { dt = delta_t; }
+
+  /** Sets the JSBSim parameter to the supplied value.
+      @param prm the JSBSim parameter to set, i.e. FG_RUDDER_POS.
+      @param val the value to give the parameter.
+      */
+  void SetParameter(eParam prm, float val);
+
+  /** Increments the simulation time.
+      @return the new simulation time.
+      */
   inline float IncrTime(void) {
     sim_time+=dt;
     return sim_time;
   }
+
+  /** Initializes the transformation matrices.
+      @param phi the roll angle in radians.
+      @param tht the pitch angle in radians.
+      @param psi the heading angle in radians
+      */
   void InitMatrices(float phi, float tht, float psi);
+
+  /** Calculates the local-to-body and body-to-local conversion matrices.
+      */
   void CalcMatrices(void);
-  void IntegrateQuat(FGColumnVector vPQR, int rate);
-  FGColumnVector CalcEuler(void);
-  FGMatrix GetTs2b(float alpha, float beta);
-  FGMatrix GetTl2b(void) { return mTl2b; }
-  float GetTl2b(int i, int j) { return mTl2b(i,j);}
-  FGMatrix GetTb2l(void) { return mTb2l; }
+
+  /** Integrates the quaternion.
+      Given the supplied rotational rate vector and integration rate, the quaternion
+      is integrated. The quaternion is later used to update the transformation
+      matrices.
+      @param vPQR the body rotational rate column vector.
+      @param rate the integration rate in seconds.
+      */
+  void IntegrateQuat(FGColumnVector3 vPQR, int rate);
+
+  /** Calculates Euler angles from the local-to-body matrix.
+      @return a reference to the vEuler column vector.
+      */
+  FGColumnVector3& CalcEuler(void);
+
+  /** Calculates and returns the stability-to-body axis transformation matrix.
+      @param alpha angle of attack in radians.
+      @param beta angle of sideslip in radians.
+      @return a reference to the stability-to-body transformation matrix.
+      */
+  FGMatrix33& GetTs2b(float alpha, float beta);
+
+  /** Retrieves the local-to-body transformation matrix.
+      @return a reference to the local-to-body transformation matrix.
+      */
+  FGMatrix33& GetTl2b(void) { return mTl2b; }
+
+  /** Retrieves a specific local-to-body matrix element.
+      @param r matrix row index.
+      @param c matrix column index.
+      @return the matrix element described by the row and column supplied.
+      */
+  float GetTl2b(int r, int c) { return mTl2b(r,c);}
+
+  /** Retrieves the body-to-local transformation matrix.
+      @return a reference to the body-to-local matrix.
+      */
+  FGMatrix33& GetTb2l(void) { return mTb2l; }
+
+  /** Retrieves a specific body-to-local matrix element.
+      @param r matrix row index.
+      @param c matrix column index.
+      @return the matrix element described by the row and column supplied.
+      */
   float GetTb2l(int i, int j) { return mTb2l(i,j);}
+  
+  /** Prints a summary of simulator state (speed, altitude, 
+      configuration, etc.)
+  */
+  void ReportState(void);
+
+
   typedef map<eParam, string> ParamMap;
   ParamMap paramdef;
 
 private:
-
   float a;                          // speed of sound
   float sim_time, dt;
   float saved_dt;
 
   FGFDMExec* FDMExec;
-  FGMatrix mTb2l;
-  FGMatrix mTl2b;
-  FGMatrix mTs2b;
-  FGColumnVector vQtrn;
-  FGColumnVector vlastQdot;
+  FGMatrix33 mTb2l;
+  FGMatrix33 mTl2b;
+  FGMatrix33 mTs2b;
+  FGColumnVector4 vQtrn;
+  FGColumnVector4 vlastQdot;
+  FGColumnVector3 vUVW;
+  FGColumnVector3 vLocalVelNED;
+  FGColumnVector3 vLocalEuler;
+  FGColumnVector4 vQdot;
+  FGColumnVector4 vTmp;
+  FGColumnVector3 vEuler;
 
   FGAircraft* Aircraft;
   FGPosition* Position;
@@ -171,10 +334,6 @@ private:
   CoeffMap coeffdef;
   void Debug(void);
   int ActiveEngine;
-
-  FGColumnVector vQdot;
-  FGColumnVector vTmp;
-  FGColumnVector vEuler;
 };
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 0ef6f324248332c3ef85f930d19a43ddd0278c21..e53fa2a67e8d1b42275c7b26c5610521180a2809 100644 (file)
@@ -47,8 +47,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TABLE;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -96,8 +94,8 @@ float** FGTable::Allocate(void)
 
 FGTable::~FGTable()
 {
-  for (int r=0; r<=nRows; r++) if (Data[r]) delete Data[r];
-  if (Data) delete Data;
+  for (int r=0; r<=nRows; r++) if (Data[r]) delete[] Data[r];
+  if (Data) delete[] Data;
   if (debug_lvl & 2) cout << "Destroyed:    FGTable" << endl;
 }
 
index da4f33bf364a41cc19d255f9ab0328f028676dff..aa9258ee8be2749d281f2a6231b5e05585b683b0 100644 (file)
@@ -39,6 +39,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGConfigFile.h"
+#include "FGJSBBase.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -71,8 +72,8 @@ CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
-class FGTable {
-
+class FGTable : public FGJSBBase
+{
 public:
   ~FGTable();
   FGTable(int nRows);
index 6efda682146efc58e9115b9b33496da3b7d9b8c4..3cfbb0da1508ec6f106248e62727abab67973c38 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TANK;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index d70933ce99481c24ea8e10f3c4473e7484dea8ea..17bcfd0b4335710e89998769c1a680ed323e76c1 100644 (file)
@@ -45,6 +45,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGConfigFile.h"
+#include "FGJSBBase.h"
 
 #ifdef FGFS
 #  include <simgear/compiler.h>
@@ -58,9 +59,11 @@ INCLUDES
 #else
 # include <string>
   using std::string;
-  using std::cerr;
-  using std::endl;
-  using std::cout;
+# if !defined(sgi) || defined(__GNUC__)
+   using std::cerr;
+   using std::endl;
+   using std::cout;
+# endif
 #endif
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -73,7 +76,7 @@ DEFINES
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGTank
+class FGTank : public FGJSBBase
 {
 public:
   FGTank(FGConfigFile*);
index 758c144947f59ebdfc7f93b2f2b13a56a2bbf5a5..108889403f61e70619e3ed256a563a9630632317 100644 (file)
@@ -40,8 +40,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_THRUSTER;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 50043c3a327046b265e6a79e4908d8658e52923c..c49b62c3b6f3194fb49fde1cf66354ac3b277c5a 100644 (file)
@@ -47,6 +47,19 @@ INCLUDES
 
 #define ID_THRUSTER "$Id$"
 
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Base class for specific thrusting devices such as propellers, nozzles, etc.
+    @author Jon Berndt
+    @version $Id$
+    */
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -54,7 +67,9 @@ CLASS DECLARATION
 class FGThruster : public FGForce {
 
 public:
+  /// Constructor
   FGThruster(FGFDMExec *FDMExec);
+  /// Destructor
   virtual ~FGThruster();
 
   enum eType {ttNozzle, ttRotor, ttPropeller};
@@ -74,7 +89,7 @@ protected:
   float Thrust;
   float PowerRequired;
   float deltaT;
-  void Debug(void);
+  virtual void Debug(void);
 };
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 65274d9fccc6685baf0ae6b2a5174e32905d753d..2e7cfca2b8f524775bf5cb7d2052827bcf4ccfac 100644 (file)
@@ -72,8 +72,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TRANSLATION;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -83,9 +81,6 @@ FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
     vUVW(3),
     vUVWdot(3),
     vNcg(3),
-    vPQR(3),
-    vForces(3),
-    vEuler(3),
     vlastUVWdot(3),
     mVel(3,3),
     vAero(3)
@@ -96,7 +91,6 @@ FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
   Mach = 0.0;
   alpha = beta = 0.0;
   adot = bdot = 0.0;
-  rho = 0.002378;
 
   if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
 }
@@ -110,12 +104,12 @@ FGTranslation::~FGTranslation()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGTranslation::Run(void) {
+bool FGTranslation::Run(void)
+{
+  float Tc = 0.5*State->Getdt()*rate;
 
   if (!FGModel::Run()) {
 
-    GetState();
-
     mVel(1,1) =  0.0;
     mVel(1,2) = -vUVW(eW);
     mVel(1,3) =  vUVW(eV);
@@ -126,37 +120,40 @@ bool FGTranslation::Run(void) {
     mVel(3,2) =  vUVW(eU);
     mVel(3,3) =  0.0;
 
-    vUVWdot = mVel*vPQR + vForces/Mass;
+    vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetForces()/MassBalance->GetMass();
 
     vNcg = vUVWdot*INVGRAVITY;
 
-    vUVW += 0.5*dt*rate*(vlastUVWdot + vUVWdot);
+    vUVW += Tc * (vlastUVWdot + vUVWdot);
     vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
 
     Vt = vAero.Magnitude();
-
-    if (vAero(eW) != 0.0)
-      alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
-    if (vAero(eV) != 0.0)
-      beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV),
-             sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
-
-    // stolen, quite shamelessly, from LaRCsim
-    float mUW = (vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW));
-    float signU=1;
-    if (vAero(eU) != 0.0)
-      signU = vAero(eU)/fabs(vAero(eU));
-
-    if ( (mUW == 0.0) || (Vt == 0.0) ) {
-      adot = 0.0;
-      bdot = 0.0;
+    if ( Vt > 1) {
+      if (vAero(eW) != 0.0)
+        alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
+      if (vAero(eV) != 0.0)
+        beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV),
+               sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
+
+      // stolen, quite shamelessly, from LaRCsim
+      float mUW = (vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW));
+      float signU=1;
+      if (vAero(eU) != 0.0)
+        signU = vAero(eU)/fabs(vAero(eU));
+
+      if ( (mUW == 0.0) || (Vt == 0.0) ) {
+        adot = 0.0;
+        bdot = 0.0;
+      } else {
+        adot = (vAero(eU)*vAero(eW) - vAero(eW)*vUVWdot(eU))/mUW;
+        bdot = (signU*mUW*vUVWdot(eV) - vAero(eV)*(vAero(eU)*vUVWdot(eU)
+                + vAero(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
+      }
     } else {
-      adot = (vAero(eU)*vAero(eW) - vAero(eW)*vUVWdot(eU))/mUW;
-      bdot = (signU*mUW*vUVWdot(eV) - vAero(eV)*(vAero(eU)*vUVWdot(eU)
-              + vAero(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
+      alpha = beta = adot = bdot = 0;
     }
 
-    qbar = 0.5*rho*Vt*Vt;
+    qbar = 0.5*Atmosphere->GetDensity()*Vt*Vt;
     Mach = Vt / State->Geta();
 
     vlastUVWdot = vUVWdot;
@@ -171,20 +168,6 @@ bool FGTranslation::Run(void) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGTranslation::GetState(void) {
-  dt = State->Getdt();
-
-  vPQR = Rotation->GetPQR();
-  vForces = Aircraft->GetForces();
-
-  Mass = MassBalance->GetMass();
-  rho = Atmosphere->GetDensity();
-
-  vEuler = Rotation->GetEuler();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void FGTranslation::Debug(void)
 {
   if (debug_lvl & 16) { // Sanity check variables
index 1729a9d85eb66126b9daef0fabdcbc509e1260b9..43c69b6ffe44185a7a33dcc01175ff8478e8bf0e 100644 (file)
@@ -64,11 +64,17 @@ INCLUDES
 #    include <math.h>
 #  endif
 #else
-#  include <cmath>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <math.h>
+#  else
+#    include <cmath>
+#  endif
 #endif
 
 #include "FGModel.h"
-#include "FGMatrix.h"
+#include "FGMatrix33.h"
+#include "FGColumnVector3.h"
+#include "FGColumnVector4.h"
 
 #define ID_TRANSLATION "$Id$"
 
@@ -81,14 +87,14 @@ public:
   FGTranslation(FGFDMExec*);
   ~FGTranslation();
 
-  inline FGColumnVector GetUVW   (void)    { return vUVW; }
-  inline float          GetUVW   (int idx) { return vUVW(idx); }
-  inline FGColumnVector GetUVWdot(void)    { return vUVWdot; }
-  inline float          GetUVWdot(int idx) { return vUVWdot(idx); }
-  inline FGColumnVector GetNcg   (void)    { return vNcg; }
-  inline float          GetNcg   (int idx) { return vNcg(idx); }
-  inline FGColumnVector GetvAero (void)    { return vAero; }
-  inline float          GetvAero (int idx) { return vAero(idx); }
+  inline FGColumnVector3& GetUVW   (void)    { return vUVW; }
+  inline float            GetUVW   (int idx) { return vUVW(idx); }
+  inline FGColumnVector3& GetUVWdot(void)    { return vUVWdot; }
+  inline float            GetUVWdot(int idx) { return vUVWdot(idx); }
+  inline FGColumnVector3& GetNcg   (void)    { return vNcg; }
+  inline float            GetNcg   (int idx) { return vNcg(idx); }
+  inline FGColumnVector3& GetvAero (void)    { return vAero; }
+  inline float            GetvAero (int idx) { return vAero(idx); }
 
   inline float Getalpha(void) { return alpha; }
   inline float Getbeta (void) { return beta; }
@@ -98,7 +104,7 @@ public:
   inline float Getadot (void) { return adot; }
   inline float Getbdot (void) { return bdot; }
 
-  void SetUVW(FGColumnVector tt) { vUVW = tt; }
+  void SetUVW(FGColumnVector3 tt) { vUVW = tt; }
 
   inline void Setalpha(float tt) { alpha = tt; }
   inline void Setbeta (float tt) { beta  = tt; }
@@ -112,26 +118,19 @@ public:
   
   bool Run(void);
 
-protected:
-
 private:
-  FGColumnVector vUVW;
-  FGColumnVector vUVWdot;
-  FGColumnVector vNcg;
-  FGColumnVector vPQR;
-  FGColumnVector vForces;
-  FGColumnVector vEuler;
-  FGColumnVector vlastUVWdot;
-  FGMatrix       mVel;
-  FGColumnVector vAero;
+  FGColumnVector3 vUVW;
+  FGColumnVector3 vUVWdot;
+  FGColumnVector3 vNcg;
+  FGColumnVector3 vlastUVWdot;
+  FGMatrix33       mVel;
+  FGColumnVector3 vAero;
 
   float Vt, qbar, Mach;
-  float Mass, dt;
+  float dt;
   float alpha, beta;
   float adot,bdot;
-  float rho;
 
-  void GetState(void);
   void Debug(void);
 };
 
index 72087c48c477f7108524efea13b79cad65b98667..55ed69a0d9edf42223549e1afecefedf2371c74c 100644 (file)
@@ -60,8 +60,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TRIM;
 
-extern short debug_lvl;
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
index de1b02cf0201a79ee733a1d90b4c29e0fffa6d0f..5603bed11996586379550fe61c0635876ca60c60 100644 (file)
@@ -49,6 +49,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFDMExec.h"
+#include "FGJSBBase.h"
 #include "FGRotation.h"
 #include "FGAtmosphere.h"
 #include "FGState.h"
@@ -69,12 +70,12 @@ DEFINITIONS
 
 #define ID_TRIM "$Id$"
 
+typedef enum { tLongitudinal, tFull, tGround, tCustom, tNone } TrimMode;
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-typedef enum { tLongitudinal, tFull, tGround, tCustom, tNone } TrimMode;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -135,7 +136,8 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGTrim {
+class FGTrim : public FGJSBBase
+{
 private:
 
   vector<FGTrimAxis*> TrimAxes;
index 51ccb932dd6d184a9d92c25458f4fc04cf2ad7f5..d580a756dbab9b08ee0f388f7097df0a05b5bc8c 100644 (file)
@@ -45,8 +45,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TRIMAXIS;
 
-extern short debug_lvl;
-
 /*****************************************************************************/
 
 FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
index 969e89cda8b7e6c154c6575418a254cfe77403c7..face0e94e4e0a0b219f6e285214d5936142757c7 100644 (file)
@@ -41,6 +41,7 @@ INCLUDES
 #include <string>
 
 #include "FGFDMExec.h"
+#include "FGJSBBase.h"
 #include "FGRotation.h"
 #include "FGAtmosphere.h"
 #include "FGState.h"
@@ -72,7 +73,8 @@ enum State { tUdot,tVdot,tWdot,tQdot,tPdot,tRdot,tHmgt };
 enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL,
                tTheta, tPhi, tGamma, tPitchTrim, tRollTrim, tYawTrim, tHeading };
 
-class FGTrimAxis {
+class FGTrimAxis : public FGJSBBase
+{
 public:
   FGTrimAxis(FGFDMExec* fdmex, FGInitialCondition *ic, State st,
              Control ctrl );
index 93c383dda4f7e9f29da8f85cde55f56db70ac70a..bfc5e7580e55ca34e8cc2e39da6d3fc3be4d259b 100644 (file)
@@ -43,8 +43,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TURBOJET;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index fa0e8f2fa5fa1c53c58c290ff94453f46e4b9d1d..c84d63371ca9482683243dcc9b18b67ededc97a8 100644 (file)
@@ -43,8 +43,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TURBOPROP;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 86030771e8422e96d56513ab959485bf6e547352..9c5531b51023455641e27193e809e033f1293408 100644 (file)
@@ -43,8 +43,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_TURBOSHAFT;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index c32abed4efd84ae80aebf653505affb2a8ca361c..9866eac9f38fcefb8f8cf0391ca6fa9440f2a630 100644 (file)
@@ -50,7 +50,11 @@ INCLUDES
 #    include <math.h>
 #  endif
 #else
-#  include <cmath>
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <math.h>
+#  else
+#    include <cmath>
+#  endif
 #endif
 
 #include "FGUtility.h"
@@ -60,8 +64,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_UTILITY;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 824f87dde0951acbe4983e6ce62591129b76f1dd..061fa90c9c20b8ee373ec0fe2b473539e37fe93d 100644 (file)
@@ -38,6 +38,8 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include "FGJSBBase.h"
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -51,7 +53,7 @@ CLASS DECLARATION
 class FGFDMExec;
 class FGState;
 
-class FGUtility
+class FGUtility : public FGJSBBase
 {
 public:
   FGUtility(void);
index 105187102a87098b9dde7219af0a050d5fb08d47..48915055c200e917cc91d7bfa85b50b9d8ef9da7 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FDMSOCKET;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -52,7 +50,7 @@ FGfdmSocket::FGfdmSocket(string address, int port)
 {
   size = 0;
 
-  #if defined(__BORLANDC__) || defined(_MSC_VER)
+#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
     WSADATA wsaData;
     int PASCAL FAR wsaReturnCode;
     wsaReturnCode = WSAStartup(MAKEWORD(1,1), &wsaData);
index f2009d46f78058513616bbfd76ff0c2514f3019d..ccf36a15be0a724eca47f6face6562935fa3414d 100644 (file)
@@ -54,16 +54,22 @@ INCLUDES
      SG_USING_STD(endl);
 #  endif
 #else
-#  include <iostream>
-#  include <fstream>
 #  include <string>
-   using std::cout;
-   using std::endl;
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <iostream.h>
+#    include <fstream.h>
+#  else
+#    include <iostream>
+#    include <fstream>
+     using std::cout;
+     using std::endl;
+#  endif
 #endif
 
 #include <sys/types.h>
+#include "FGJSBBase.h"
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
+#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
   #include <winsock.h>
 #else
   #include <sys/socket.h>
@@ -84,7 +90,8 @@ CLASS DECLARATION
 
 using std::string;
 
-class FGfdmSocket {
+class FGfdmSocket : public FGJSBBase
+{
 public:
   FGfdmSocket(string, int);
   ~FGfdmSocket();
index 3760784cec4dbe588598cd76c2fdc1b71853c7a7..366d394b1bc3911dc187628d6834d937c805dc19 100644 (file)
@@ -60,60 +60,13 @@ INCLUDES
 #    include <time.h>
 #  endif
 #else
-#include <iostream>
-#include <ctime>
-#endif
-
-#if __BORLANDC__ > 0x540
-#include <condefs.h>
-USEUNIT("FGUtility.cpp");
-USEUNIT("FGAircraft.cpp");
-USEUNIT("FGAtmosphere.cpp");
-USEUNIT("FGAuxiliary.cpp");
-USEUNIT("FGCoefficient.cpp");
-USEUNIT("FGConfigFile.cpp");
-USEUNIT("FGEngine.cpp");
-USEUNIT("FGFCS.cpp");
-USEUNIT("FGFDMExec.cpp");
-USEUNIT("FGfdmSocket.cpp");
-USEUNIT("FGForce.cpp");
-USEUNIT("FGGroundReactions.cpp");
-USEUNIT("FGInertial.cpp");
-USEUNIT("FGInitialCondition.cpp");
-USEUNIT("FGLGear.cpp");
-USEUNIT("FGMassBalance.cpp");
-USEUNIT("FGMatrix.cpp");
-USEUNIT("FGModel.cpp");
-USEUNIT("FGNozzle.cpp");
-USEUNIT("FGOutput.cpp");
-USEUNIT("FGPiston.cpp");
-USEUNIT("FGPosition.cpp");
-USEUNIT("FGJSBBase.cpp");
-USEUNIT("FGPropulsion.cpp");
-USEUNIT("FGRocket.cpp");
-USEUNIT("FGRotation.cpp");
-USEUNIT("FGRotor.cpp");
-USEUNIT("FGState.cpp");
-USEUNIT("FGTable.cpp");
-USEUNIT("FGTank.cpp");
-USEUNIT("FGThruster.cpp");
-USEUNIT("FGTranslation.cpp");
-USEUNIT("FGTrim.cpp");
-USEUNIT("FGTrimAxis.cpp");
-USEUNIT("FGTurboJet.cpp");
-USEUNIT("FGTurboProp.cpp");
-USEUNIT("FGTurboShaft.cpp");
-USEUNIT("FGAerodynamics.cpp");
-USEUNIT("filtersjb\FGSwitch.cpp");
-USEUNIT("filtersjb\FGFCSComponent.cpp");
-USEUNIT("filtersjb\FGFilter.cpp");
-USEUNIT("filtersjb\FGFlaps.cpp");
-USEUNIT("filtersjb\FGGain.cpp");
-USEUNIT("filtersjb\FGGradient.cpp");
-USEUNIT("filtersjb\FGSummer.cpp");
-USEUNIT("filtersjb\FGDeadBand.cpp");
-USEUNIT("FGPropeller.cpp");
-//---------------------------------------------------------------------------
+#  if defined(sgi) && !defined(__GNUC__)
+#    include <iostream.h>
+#    include <time.h>
+#  else
+#    include <iostream>
+#    include <ctime>
+#  endif
 #endif
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -187,13 +140,16 @@ int main(int argc, char** argv)
       exit(-1);
     }
   } else {
-    result = FDMExec->LoadModel("aircraft", "engine", string(argv[1]));
+    // result = FDMExec->LoadModel("aircraft", "engine", string(argv[1]));
+    FGInitialCondition IC(FDMExec);
+    result = IC.Load("aircraft","engine",string(argv[1]));
+
     if (!result) {
        cerr << "Aircraft file " << argv[1] << " was not found" << endl;
            exit(-1);
     }
     if ( ! FDMExec->GetState()->Reset("aircraft", string(argv[1]), string(argv[2])))
-                   FDMExec->GetState()->Initialize(2000,0,0,0,0,0,0.5,0.5,40000);
+                   FDMExec->GetState()->Initialize(2000,0,0,0,0,0,0.5,0.5,40000, 0, 0, 0);
   }
 
   while (FDMExec->Run()) {}
index 6f547a3b3dedd1ee368603c5e2f261dfacceb376..323190afd7cc26ae9a01ed785979d4b2e6ce8ae0 100644 (file)
@@ -17,17 +17,22 @@ libJSBSim_a_SOURCES = \
        FGAtmosphere.cpp FGAtmosphere.h \
        FGAuxiliary.cpp FGAuxiliary.h \
        FGCoefficient.cpp FGCoefficient.h \
+        FGColumnVector3.cpp FGColumnVector3.h \
+        FGColumnVector4.cpp FGColumnVector4.h \
        FGConfigFile.cpp FGConfigFile.h \
        FGDefs.h \
        FGFCS.cpp FGFCS.h \
        FGFDMExec.cpp FGFDMExec.h \
        FGFactorGroup.cpp FGFactorGroup.h \
        FGForce.cpp FGForce.h \
+        FGGroundReactions.cpp FGGroundReactions.h \
         FGInertial.cpp FGInertial.h \
        FGInitialCondition.cpp FGInitialCondition.h \
+        FGJSBBase.cpp FGJSBBase.h \
        FGLGear.cpp FGLGear.h \
         FGMassBalance.cpp FGMassBalance.h \
        FGMatrix.cpp FGMatrix.h \
+        FGMatrix33.cpp FGMatrix33.h \
        FGModel.cpp FGModel.h \
        FGNozzle.cpp FGNozzle.h \
        FGOutput.cpp FGOutput.h \
index da45f22669606c255049ef2c7e8127db6b2c1b3d..45210296cf0a51a9d18bafb3a78f8cff580873f8 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_DEADBAND;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 6e94d530ee80b16482d9b60b58d6852fe6d09162..b4b1e3e45a1588481ca325ba21422a21e7cb6ebb 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FCSCOMPONENT;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 1cece8d456ed6df1753245720fc62130f7390156..6eba5cf184da9f877596724bd8375e73302f8e5e 100644 (file)
@@ -43,6 +43,7 @@ INCLUDES
 
 #include <string>
 #include "../FGDefs.h"
+#include "../FGJSBBase.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -89,7 +90,7 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGFCSComponent
+class FGFCSComponent : public FGJSBBase
 {
 public:
   /// Constructor
@@ -115,7 +116,7 @@ protected:
   eParam OutputIdx;
   float Output;
   bool IsOutput;
-  void Debug(void);
+  virtual void Debug(void);
 };
 
 #include "../FGFCS.h"
index 2c2cabbea0b51feb75a79ea3b84e5e93d0b9893c..44dc815770354cd03689b296ab8b8c61efafc175 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FILTER;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -113,6 +111,12 @@ FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
       cc = (2.00*C3 - dt*C2) / denom;
       break;
     case eOrder2:
+      denom = 4.0*C3 + 2.0*C5*dt + C6*dt*dt;
+      ca = 4.0*C1 + 2.0*C2*dt + C3*dt*dt / denom;
+      cb = 2.0*C3*dt*dt - 8.0*C1 / denom;
+      cc = 4.0*C1 - 2.0*C2*dt + C3*dt*dt / denom;
+      cd = 2.0*C6*dt*dt - 8.0*C4 / denom;
+      ce = 4.0*C3 - 2.0*C5*dt + C6*dt*dt / denom;
       break;
     case eWashout:
       denom = 2.00 + dt*C1;
@@ -122,6 +126,9 @@ FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
     case eIntegrator:
       ca = dt*C1 / 2.00;
       break;
+    case eUnknown:
+      cerr << "Unknown filter type" << endl;
+    break;
   }
 
   if (debug_lvl > 0) {
@@ -162,12 +169,13 @@ bool FGFilter::Run(void)
     switch (FilterType) {
       case eLag:
         Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
-//        Output = Input * ca + PreviousOutput1 * cb;
         break;
       case eLeadLag:
         Output = Input * ca + PreviousInput1 * cb + PreviousOutput1 * cc;
         break;
       case eOrder2:
+        Output = Input * ca + PreviousInput1 * cb + PreviousInput2 * cc
+                                 - PreviousOutput1 * cd - PreviousOutput2 * ce;
         break;
       case eWashout:
         Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
index 12eb347b716074212692b5375cb76270ad01d851..2fa35b67146c118c8c72a2d1075b15335afe4149 100644 (file)
@@ -103,6 +103,7 @@ private:
   float cb;
   float cc;
   float cd;
+  float ce;
   float C1;
   float C2;
   float C3;
@@ -118,3 +119,4 @@ private:
 };
 
 #endif
+
index ba743ee066a68458c880e54bee6851cde8a24ff7..5b746ae78c51258587966b6285a7d2846446daa3 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_FLAPS;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 48505338b659cd9b39ecda8771ad885756369b03..acb6401c92fe58e809a459bb4fba197fb724e790 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_GAIN;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index fd7cdbbfdb9c684bb2278ba76d1004aef83e7260..af22700fa7ee35de9ddb2be01b72d79a34bde414 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_GRADIENT;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 431a6bacf77ffd0d645b4b2a9d281009572af633..3e9064f949cee3d88d56cc4209fe745befabcc77 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_SUMMER;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
index 2b29a72aa5b67edc89175e0aad98e0c5222382ac..8c369f58dfb2cec87426c4134cc5101c76753f2e 100644 (file)
@@ -42,8 +42,6 @@ INCLUDES
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_SWITCH;
 
-extern short debug_lvl;
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/