]> git.mxchange.org Git - flightgear.git/commitdiff
One step ahead of JSBSim CVS.
authorErik Hofman <erik@ehofman.com>
Mon, 11 Apr 2011 08:06:57 +0000 (10:06 +0200)
committerErik Hofman <erik@ehofman.com>
Mon, 11 Apr 2011 08:06:57 +0000 (10:06 +0200)
61 files changed:
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/FGFDMExec.h
src/FDM/JSBSim/initialization/FGInitialCondition.cpp
src/FDM/JSBSim/initialization/FGTrim.cpp
src/FDM/JSBSim/initialization/FGTrim.h
src/FDM/JSBSim/input_output/FGPropertyManager.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/input_output/FGPropertyManager.h
src/FDM/JSBSim/input_output/FGScript.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/input_output/FGScript.h
src/FDM/JSBSim/input_output/FGXMLElement.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/math/FGCondition.cpp
src/FDM/JSBSim/math/FGCondition.h
src/FDM/JSBSim/math/FGFunction.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/math/FGParameter.h [changed mode: 0644->0755]
src/FDM/JSBSim/math/FGPropertyValue.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/math/FGPropertyValue.h [changed mode: 0644->0755]
src/FDM/JSBSim/math/FGRealValue.h
src/FDM/JSBSim/math/FGTable.h
src/FDM/JSBSim/models/FGAerodynamics.cpp
src/FDM/JSBSim/models/FGAerodynamics.h
src/FDM/JSBSim/models/FGAtmosphere.cpp
src/FDM/JSBSim/models/FGAuxiliary.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/models/FGBuoyantForces.cpp
src/FDM/JSBSim/models/FGFCS.cpp
src/FDM/JSBSim/models/FGFCS.h
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/FGModel.cpp
src/FDM/JSBSim/models/FGOutput.cpp
src/FDM/JSBSim/models/FGOutput.h
src/FDM/JSBSim/models/FGPropagate.cpp
src/FDM/JSBSim/models/FGPropagate.h
src/FDM/JSBSim/models/FGPropulsion.cpp
src/FDM/JSBSim/models/flight_control/FGActuator.cpp
src/FDM/JSBSim/models/flight_control/FGDeadBand.cpp
src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
src/FDM/JSBSim/models/flight_control/FGFCSComponent.h
src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp
src/FDM/JSBSim/models/flight_control/FGFilter.cpp
src/FDM/JSBSim/models/flight_control/FGGain.cpp
src/FDM/JSBSim/models/flight_control/FGKinemat.cpp
src/FDM/JSBSim/models/flight_control/FGPID.cpp
src/FDM/JSBSim/models/flight_control/FGSensor.cpp
src/FDM/JSBSim/models/flight_control/FGSwitch.cpp
src/FDM/JSBSim/models/flight_control/FGSwitch.h
src/FDM/JSBSim/models/propulsion/FGElectric.cpp
src/FDM/JSBSim/models/propulsion/FGElectric.h
src/FDM/JSBSim/models/propulsion/FGEngine.cpp
src/FDM/JSBSim/models/propulsion/FGEngine.h
src/FDM/JSBSim/models/propulsion/FGForce.cpp
src/FDM/JSBSim/models/propulsion/FGPiston.cpp
src/FDM/JSBSim/models/propulsion/FGPiston.h
src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
src/FDM/JSBSim/models/propulsion/FGPropeller.h
src/FDM/JSBSim/models/propulsion/FGRocket.cpp
src/FDM/JSBSim/models/propulsion/FGRotor.cpp
src/FDM/JSBSim/models/propulsion/FGRotor.h
src/FDM/JSBSim/models/propulsion/FGThruster.cpp
src/FDM/JSBSim/models/propulsion/FGThruster.h
src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/models/propulsion/FGTurboProp.h [changed mode: 0644->0755]

index ade4209cdf5a26fa07a7673964c13b66bcb8006f..a3b08a49ec5deaf6afdf01e392f4cfdcf5ac3f75 100644 (file)
@@ -71,7 +71,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.84 2011/01/16 16:26:14 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.91 2011/04/05 20:20:21 andgi Exp $";
 static const char *IdHdr = ID_FDMEXEC;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -116,6 +116,10 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
   dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
                   // run in standalone mode with no initialization file.
 
+  AircraftPath = "aircraft";
+  EnginePath = "engine";
+  SystemsPath = "systems";
+
   try {
     char* num = getenv("JSBSIM_DEBUG");
     if (num) debug_lvl = atoi(num); // set debug level
@@ -154,12 +158,13 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
 
   Constructing = true;
   typedef int (FGFDMExec::*iPMF)(void) const;
-//  instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis);
-  instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim);
-  instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions);
+//  instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis, false);
+  instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim, false);
+  instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions, false);
   instance->Tie("simulation/terminate", (int *)&Terminate);
   instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime);
   instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel);
+  instance->Tie("simulation/frame", (int *)&Frame, false);
 
   Constructing = false;
 }
@@ -350,6 +355,8 @@ bool FGFDMExec::RunIC(void)
 
 void FGFDMExec::Initialize(FGInitialCondition *FGIC)
 {
+  Setsim_time(0.0);
+
   Propagate->SetInitialState( FGIC );
 
   Atmosphere->Run();
@@ -358,6 +365,9 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC)
                           FGIC->GetWindDFpsIC() );
 
   FGColumnVector3 vAeroUVW;
+
+  //ToDo: move this to the Auxiliary class !?
+
   vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
 
   double alpha, beta;
@@ -629,7 +639,9 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
 
     // Process the output element[s]. This element is OPTIONAL, and there may be more than one.
     unsigned int idx=0;
-    typedef int (FGOutput::*iOPMF)(void) const;
+    typedef double (FGOutput::*iOPMF)(void) const;
+    typedef int (FGFDMExec::*iOPV)(void) const;
+    typedef void (FGFDMExec::*vOPI)(int) const;
     element = document->FindElement("output");
     while (element) {
       if (debug_lvl > 0) cout << endl << "  Output data set: " << idx << "  ";
@@ -643,7 +655,8 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
       } else {
         Outputs.push_back(Output);
         string outputProp = CreateIndexedPropertyName("simulation/output",idx);
-        instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
+        instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
+        instance->Tie("simulation/force-output", this, (iOPV)0, &FGFDMExec::ForceOutput, false);
         idx++;
       }
       element = document->FindNextElement("output");
@@ -679,15 +692,6 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
          << fgdef << endl;
   }
 
-  // Late bind previously undefined FCS inputs.
-  try {
-    FCS->LateBind();
-  } catch (string prop) {
-    cerr << endl << fgred << "  Could not late bind property " << prop 
-         << ". Aborting." << reset << endl;
-    result = false;
-  }
-
   if (result) {
     struct PropertyCatalogStructure masterPCS;
     masterPCS.base_string = "";
@@ -918,6 +922,13 @@ void FGFDMExec::EnableOutput(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGFDMExec::ForceOutput(int idx)
+{
+  if (idx >= 0 && idx < Outputs.size()) Outputs[idx]->Print();
+}
+       
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 bool FGFDMExec::SetOutputDirectives(const string& fname)
 {
   bool result;
@@ -930,9 +941,9 @@ bool FGFDMExec::SetOutputDirectives(const string& fname)
 
   if (result) {
     Outputs.push_back(Output);
-    typedef int (FGOutput::*iOPMF)(void) const;
+    typedef double (FGOutput::*iOPMF)(void) const;
     string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
-    instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
+    instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
   }
 
   return result;
index b982654e7aa613158ec47548c21fbb0b5ac18d76..5f103fe159cc2f7e4ad4de2412245713042b2cc7 100644 (file)
@@ -44,11 +44,9 @@ INCLUDES
 #include <vector>
 #include <string>
 
-//#include "models/FGModel.h"
 #include "models/FGOutput.h"
 #include "models/FGInput.h"
 #include "initialization/FGTrim.h"
-#include "initialization/FGInitialCondition.h"
 #include "FGJSBBase.h"
 #include "input_output/FGPropertyManager.h"
 #include "input_output/FGGroundCallback.h"
@@ -60,7 +58,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.56 2010/11/18 20:37:10 jberndt Exp $"
+#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.63 2011/02/19 16:44:41 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -183,7 +181,7 @@ CLASS DOCUMENTATION
                                 property actually maps toa function call of DoTrim().
 
     @author Jon S. Berndt
-    @version $Revision: 1.56 $
+    @version $Revision: 1.63 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -286,8 +284,11 @@ public:
 
   /** Loads a script
       @param Script the full path name and file name for the script to be loaded.
+      @param deltaT The simulation integration step size, if given.  If no value is supplied
+                    then 0.0 is used and the value is expected to be supplied in
+                    the script file itself.
       @return true if successfully loadsd; false otherwise. */
-  bool LoadScript(const string& Script, double deltaT);
+  bool LoadScript(const string& Script, double deltaT=0.0);
 
   /** Sets the path to the engine config file directories.
       @param path path to the directory under which engine config
@@ -401,6 +402,9 @@ public:
     */
   bool SetOutputDirectives(const string& fname);
 
+  /** Forces the specified output object to print its items once */
+  void ForceOutput(int idx=0);
+
   /** Sets (or overrides) the output filename
       @param fname the name of the file to output data to
       @return true if successful, false if there is no output specified for the flight model */
@@ -514,7 +518,7 @@ public:
       @param rootDir the string containing the root directory. */
   void SetRootDir(const string& rootDir) {RootDir = rootDir;}
 
-  /** Retrieves teh Root Directory.
+  /** Retrieves the Root Directory.
       @return the string representing the root (base) JSBSim directory. */
   const string& GetRootDir(void) const {return RootDir;}
 
index f9bbc5415e76ad2ada6a91b070a45a7c237632b5..0dbcf88ce978c39df8fb44afdbb72faeb0cec23b 100644 (file)
@@ -61,7 +61,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.56 2011/01/23 12:13:44 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.59 2011/04/03 13:18:51 bcoconni Exp $";
 static const char *IdHdr = ID_INITIALCONDITION;
 
 //******************************************************************************
@@ -700,6 +700,8 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
     case setve:
       SetVtrueFpsIC(ve0 * sqrt(rho/rhoSL));
       break;
+    default: // Make the compiler stop complaining about missing enums
+      break;
   }
 
   position.SetRadius(alt + sea_level_radius);
@@ -998,6 +1000,18 @@ bool FGInitialCondition::Load_v1(void)
     SetTargetNlfIC(document->FindElementValueAsNumber("targetNlf"));
   }
 
+  // Refer to Stevens and Lewis, 1.5-14a, pg. 49.
+  // This is the rotation rate of the "Local" frame, expressed in the local frame.
+  double radInv = 1.0 / position.GetRadius();
+  FGColumnVector3 vOmegaLocal = FGColumnVector3(
+   radInv*vUVW_NED(eEast),
+  -radInv*vUVW_NED(eNorth),
+  -radInv*vUVW_NED(eEast)*position.GetTanLatitude() );
+
+  p = vOmegaLocal(eP);
+  q = vOmegaLocal(eR);
+  r = vOmegaLocal(eQ);
+
   return result;
 }
 
@@ -1032,7 +1046,7 @@ bool FGInitialCondition::Load_v2(void)
         if (position_el->FindElement("radius")) {
           position.SetRadius(position_el->FindElementValueAsNumberConvertTo("radius", "FT"));
         } else if (position_el->FindElement("altitudeAGL")) {
-          position.SetRadius(sea_level_radius + terrain_elevation + position_el->FindElementValueAsNumberConvertTo("altitude", "FT"));
+          position.SetRadius(sea_level_radius + terrain_elevation + position_el->FindElementValueAsNumberConvertTo("altitudeAGL", "FT"));
         } else if (position_el->FindElement("altitudeMSL")) {
           position.SetRadius(sea_level_radius + position_el->FindElementValueAsNumberConvertTo("altitudeMSL", "FT"));
         } else {
@@ -1096,7 +1110,7 @@ bool FGInitialCondition::Load_v2(void)
       //
       // Or, using quaternions (note reverse ordering compared to matrix representation):
       //
-      // Q_b/l = Q_e/l * Q_b/i
+      // Q_b/l = Q_i/l * Q_b/i
 
       FGQuaternion QuatI2Body = FGQuaternion(vOrient);
       QuatI2Body.Normalize();
@@ -1196,6 +1210,9 @@ bool FGInitialCondition::Load_v2(void)
   
   FGColumnVector3 vLocalRate;
   Element* attrate_el = document->FindElement("attitude_rate");
+
+  // Refer to Stevens and Lewis, 1.5-14a, pg. 49.
+  // This is the rotation rate of the "Local" frame, expressed in the local frame.
   double radInv = 1.0 / position.GetRadius();
   FGColumnVector3 vOmegaLocal = FGColumnVector3(
    radInv*vUVW_NED(eEast),
@@ -1209,11 +1226,11 @@ bool FGInitialCondition::Load_v2(void)
     FGColumnVector3 vAttRate = attrate_el->FindElementTripletConvertTo("RAD/SEC");
 
     if (frame == "eci") {
-      vLocalRate = Tl2b * (position.GetTi2l() * (vAttRate - vOmegaEarth) - vOmegaLocal);
+      vLocalRate = Tl2b * position.GetTi2l() * (vAttRate - vOmegaEarth);
     } else if (frame == "ecef") {
-      vLocalRate = Tl2b * (position.GetTec2l() * vAttRate - vOmegaLocal);
+      vLocalRate = Tl2b * position.GetTec2l() * vAttRate;
     } else if (frame == "local") {
-      vLocalRate = vAttRate;
+      vLocalRate = vAttRate + vOmegaLocal;
     } else if (!frame.empty()) { // misspelling of frame
       
       cerr << endl << fgred << "  Attitude rate frame type: \"" << frame
@@ -1221,11 +1238,11 @@ bool FGInitialCondition::Load_v2(void)
       result = false;
 
     } else if (frame.empty()) {
-    
+      vLocalRate = vOmegaLocal;
     }
-    
+
   } else { // Body frame attitude rate assumed 0 relative to local.
-      vLocalRate.InitMatrix();
+      vLocalRate = vOmegaLocal;
   }
 
   p = vLocalRate(eP);
index 6b0cd81c05f665e568067d08ed859a6b7c2682bc..cc863c85dc19bd407dda24a631fa35a04f952a73 100644 (file)
@@ -41,19 +41,10 @@ scheme. */
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <cstdlib>
 #include <iomanip>
 #include "FGTrim.h"
-#include "models/FGAtmosphere.h"
-#include "FGInitialCondition.h"
-#include "models/FGAircraft.h"
-#include "models/FGMassBalance.h"
 #include "models/FGGroundReactions.h"
 #include "models/FGInertial.h"
-#include "models/FGAerodynamics.h"
-#include "models/FGPropulsion.h"
-#include "models/propulsion/FGEngine.h"
-#include "math/FGColumnVector3.h"
 
 #if _MSC_VER
 #pragma warning (disable : 4786 4788)
@@ -63,7 +54,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTrim.cpp,v 1.13 2010/04/23 17:23:40 dpculp Exp $";
+static const char *IdSrc = "$Id: FGTrim.cpp,v 1.15 2011/02/19 16:29:29 bcoconni Exp $";
 static const char *IdHdr = ID_TRIM;
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -241,7 +232,7 @@ bool FGTrim::DoTrim(void) {
 
   fdmex->DisableOutput();
 
-  setEngineTrimMode(true);
+  fdmex->SetTrimStatus(true);
 
   fgic->SetPRadpsIC(0.0);
   fgic->SetQRadpsIC(0.0);
@@ -358,7 +349,7 @@ bool FGTrim::DoTrim(void) {
   for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
     fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(true);
   }
-  setEngineTrimMode(false);
+  fdmex->SetTrimStatus(false);
   fdmex->EnableOutput();
   return !trim_failed;
 }
@@ -625,15 +616,6 @@ void FGTrim::setDebug(void) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGTrim::setEngineTrimMode(bool mode) {
-  FGPropulsion* prop = fdmex->GetPropulsion();
-  for (unsigned int i=0; i<prop->GetNumEngines(); i++) {
-    prop->GetEngine(i)->SetTrimMode(mode);
-  }
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void FGTrim::SetMode(TrimMode tt) {
     ClearStates();
     mode=tt;
index 0d6e3092cdd260745df07ada44d3edfa6082bf19..518077f3856f155bfd443b1c9e7a6b5702951507 100644 (file)
@@ -60,7 +60,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_TRIM "$Id: FGTrim.h,v 1.7 2010/04/23 17:23:40 dpculp Exp $"
+#define ID_TRIM "$Id: FGTrim.h,v 1.8 2011/01/24 13:01:55 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -120,7 +120,7 @@ CLASS DOCUMENTATION
     @endcode
     
     @author Tony Peden
-    @version "$Id: FGTrim.h,v 1.7 2010/04/23 17:23:40 dpculp Exp $"
+    @version "$Id: FGTrim.h,v 1.8 2011/01/24 13:01:55 jberndt Exp $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -176,7 +176,6 @@ private:
   void setupTurn(void);
 
   void updateRates(void);
-  void setEngineTrimMode(bool mode);
   void setDebug(void);
 
 public:
old mode 100644 (file)
new mode 100755 (executable)
index c0218ec..6d90792
@@ -49,17 +49,17 @@ COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
 namespace JSBSim {
 
 bool FGPropertyManager::suppress_warning = true;
-std::vector<std::string> FGPropertyManager::tied_properties;
+std::vector<SGPropertyNode_ptr> FGPropertyManager::tied_properties;
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGPropertyManager::Unbind(void)
 {
-    vector<string>::iterator it;
+    vector<SGPropertyNode_ptr>::iterator it;
+
     for (it = tied_properties.begin();it < tied_properties.end();it++)
-    {
-        Untie(*it);
-    }
+        (*it)->untie();
+
     tied_properties.clear();
 }
 
@@ -102,7 +102,6 @@ FGPropertyManager::GetNode (const string &relpath, int index, bool create)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-
 bool FGPropertyManager::HasNode (const string &path)
 {
   // Checking if a node exists shouldn't write a warning if it doesn't exist
@@ -314,11 +313,17 @@ void FGPropertyManager::Untie (const string &name)
 
 void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
 {
-  if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer), useDefault))
+  SGPropertyNode* property = getNode(name.c_str(), true);
+  if (!property) {
+    cerr << "Could not get or create property " << name << endl;
+    return;
+  }
+
+  if (!property->tie(SGRawValuePointer<bool>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else {
-    tied_properties.push_back(name);
-    if (debug_lvl & 0x20) std::cout << name << std::endl;
+    tied_properties.push_back(property);
+    if (debug_lvl & 0x20) cout << name << endl;
   }
 }
 
@@ -327,11 +332,17 @@ void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
 void FGPropertyManager::Tie (const string &name, int *pointer,
                                           bool useDefault )
 {
-  if (!tie(name.c_str(), SGRawValuePointer<int>(pointer), useDefault))
+  SGPropertyNode* property = getNode(name.c_str(), true);
+  if (!property) {
+    cerr << "Could not get or create property " << name << endl;
+    return;
+  }
+
+  if (!property->tie(SGRawValuePointer<int>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else {
-    tied_properties.push_back(name);
-    if (debug_lvl & 0x20) std::cout << name << std::endl;
+    tied_properties.push_back(property);
+    if (debug_lvl & 0x20) cout << name << endl;
   }
 }
 
@@ -340,11 +351,17 @@ void FGPropertyManager::Tie (const string &name, int *pointer,
 void FGPropertyManager::Tie (const string &name, long *pointer,
                                           bool useDefault )
 {
-  if (!tie(name.c_str(), SGRawValuePointer<long>(pointer), useDefault))
+  SGPropertyNode* property = getNode(name.c_str(), true);
+  if (!property) {
+    cerr << "Could not get or create property " << name << endl;
+    return;
+  }
+
+  if (!property->tie(SGRawValuePointer<long>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else {
-    tied_properties.push_back(name);
-    if (debug_lvl & 0x20) std::cout << name << std::endl;
+    tied_properties.push_back(property);
+    if (debug_lvl & 0x20) cout << name << endl;
   }
 }
 
@@ -353,11 +370,17 @@ void FGPropertyManager::Tie (const string &name, long *pointer,
 void FGPropertyManager::Tie (const string &name, float *pointer,
                                           bool useDefault )
 {
-  if (!tie(name.c_str(), SGRawValuePointer<float>(pointer), useDefault))
+  SGPropertyNode* property = getNode(name.c_str(), true);
+  if (!property) {
+    cerr << "Could not get or create property " << name << endl;
+    return;
+  }
+
+  if (!property->tie(SGRawValuePointer<float>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else {
-    tied_properties.push_back(name);
-    if (debug_lvl & 0x20) std::cout << name << std::endl;
+    tied_properties.push_back(property);
+    if (debug_lvl & 0x20) cout << name << endl;
   }
 }
 
@@ -365,11 +388,17 @@ void FGPropertyManager::Tie (const string &name, float *pointer,
 
 void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
 {
-  if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault))
+  SGPropertyNode* property = getNode(name.c_str(), true);
+  if (!property) {
+    cerr << "Could not get or create property " << name << endl;
+    return;
+  }
+
+  if (!property->tie(SGRawValuePointer<double>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else {
-    tied_properties.push_back(name);
-    if (debug_lvl & 0x20) std::cout << name << std::endl;
+    tied_properties.push_back(property);
+    if (debug_lvl & 0x20) cout << name << endl;
   }
 }
 
index a08f896814213dcdf0306ce2edf3b8512549b355..f877bfcddac8f1aa4e395061117bc685e936561e 100644 (file)
@@ -53,7 +53,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.17 2010/07/08 11:36:28 jberndt Exp $"
+#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.20 2011/02/13 00:42:45 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -77,7 +77,7 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
 {
   private:
     static bool suppress_warning;
-    static std::vector<std::string> tied_properties;
+    static std::vector<SGPropertyNode_ptr> tied_properties;
   public:
     /// Constructor
     FGPropertyManager(void) {suppress_warning = false;}
@@ -532,10 +532,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     template <class V> inline void
     Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true)
     {
-      if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
-        std::cout << "Failed to tie property " << name << " to functions" << std::endl;
+      SGPropertyNode* property = getNode(name.c_str(), true);
+      if (!property) {
+        std::cerr << "Could not get or create property " << name << std::endl;
+        return;
+      }
+
+      if (!property->tie(SGRawValueFunctions<V>(getter, setter), useDefault))
+        std::cerr << "Failed to tie property " << name << " to functions" << std::endl;
       else {
-        tied_properties.push_back(name);
+        tied_properties.push_back(property);
         if (debug_lvl & 0x20) std::cout << name << std::endl;
       }
     }
@@ -562,10 +568,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     template <class V> inline void Tie (const std::string &name, int index, V (*getter)(int),
                                 void (*setter)(int, V) = 0, bool useDefault = true)
     {
-      if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
-        std::cout << "Failed to tie property " << name << " to indexed functions" << std::endl;
+      SGPropertyNode* property = getNode(name.c_str(), true);
+      if (!property) {
+        std::cerr << "Could not get or create property " << name << std::endl;
+        return;
+      }
+
+      if (!property->tie(SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
+        std::cerr << "Failed to tie property " << name << " to indexed functions" << std::endl;
       else {
-        tied_properties.push_back(name);
+        tied_properties.push_back(property);
         if (debug_lvl & 0x20) std::cout << name << std::endl;
       }
     }
@@ -594,10 +606,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     Tie (const std::string &name, T * obj, V (T::*getter)() const,
            void (T::*setter)(V) = 0, bool useDefault = true)
     {
-      if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
-        std::cout << "Failed to tie property " << name << " to object methods" << std::endl;
+      SGPropertyNode* property = getNode(name.c_str(), true);
+      if (!property) {
+        std::cerr << "Could not get or create property " << name << std::endl;
+        return;
+      }
+
+      if (!property->tie(SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
+        std::cerr << "Failed to tie property " << name << " to object methods" << std::endl;
       else {
-        tied_properties.push_back(name);
+        tied_properties.push_back(property);
         if (debug_lvl & 0x20) std::cout << name << std::endl;
       }
     }
@@ -625,10 +643,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     Tie (const std::string &name, T * obj, int index, V (T::*getter)(int) const,
                          void (T::*setter)(int, V) = 0, bool useDefault = true)
     {
-      if (!tie(name.c_str(), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
-        std::cout << "Failed to tie property " << name << " to indexed object methods" << std::endl;
+      SGPropertyNode* property = getNode(name.c_str(), true);
+      if (!property) {
+        std::cerr << "Could not get or create property " << name << std::endl;
+        return;
+      }
+
+      if (!property->tie(SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
+        std::cerr << "Failed to tie property " << name << " to indexed object methods" << std::endl;
       else {
-        tied_properties.push_back(name);
+        tied_properties.push_back(property);
         if (debug_lvl & 0x20) std::cout << name << std::endl;
       }
    }
old mode 100644 (file)
new mode 100755 (executable)
index e20e8c1..60d39ed
@@ -54,7 +54,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGScript.cpp,v 1.43 2011/01/16 15:27:34 jberndt Exp $";
+static const char *IdSrc = "$Id: FGScript.cpp,v 1.46 2011/02/18 12:44:16 jberndt Exp $";
 static const char *IdHdr = ID_FGSCRIPT;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -78,12 +78,19 @@ FGScript::FGScript(FGFDMExec* fgex) : FDMExec(fgex)
 
 FGScript::~FGScript()
 {
-  unsigned int i;
+  unsigned int i, j;
 
-  for (i=0; i<local_properties.size(); i++) delete local_properties[i];
+  for (i=0; i<local_properties.size(); i++) {
+    delete local_properties[i]->value;
+    delete local_properties[i];
+  }
   local_properties.clear();
 
-  for (i=0; i<Events.size(); i++) delete Events[i].Condition;
+  for (i=0; i<Events.size(); i++) {
+    delete Events[i].Condition;
+    for (j=0; j<Events[i].Functions.size(); j++)
+      delete Events[i].Functions[j];
+  }
   Events.clear();
 
   Debug(1);
@@ -139,6 +146,8 @@ bool FGScript::LoadScript(string script, double deltaT)
   StartTime = run_element->GetAttributeValueAsNumber("start");
   FDMExec->Setsim_time(StartTime);
   EndTime   = run_element->GetAttributeValueAsNumber("end");
+  // Make sure that the desired time is reached and executed.
+  EndTime += 0.99*FDMExec->GetDeltaT();
 
   if (deltaT == 0.0)
     dt = run_element->GetAttributeValueAsNumber("dt");
@@ -240,11 +249,13 @@ bool FGScript::LoadScript(string script, double deltaT)
         newCondition = new FGCondition(condition_element, PropertyManager);
       } catch(string str) {
         cout << endl << fgred << str << reset << endl << endl;
+        delete newEvent;
         return false;
       }
       newEvent->Condition = newCondition;
     } else {
       cerr << "No condition specified in script event " << newEvent->Name << endl;
+      delete newEvent;
       return false;
     }
 
@@ -258,16 +269,29 @@ bool FGScript::LoadScript(string script, double deltaT)
     // Notify about when this event is triggered?
     if ((notify_element = event_element->FindElement("notify")) != 0) {
       newEvent->Notify = true;
+      // Check here for new <description> tag that gets echoed
+      string notify_description = notify_element->FindElementValue("description");
+      if (!notify_description.empty()) {
+        newEvent->Description = notify_description;
+      }
       notify_property_element = notify_element->FindElement("property");
       while (notify_property_element) {
         notifyPropertyName = notify_property_element->GetDataLine();
         if (PropertyManager->GetNode(notifyPropertyName)) {
           newEvent->NotifyProperties.push_back( PropertyManager->GetNode(notifyPropertyName) );
+          string caption_attribute = notify_property_element->GetAttributeValue("caption");
+          if (caption_attribute.empty()) {
+            newEvent->DisplayString.push_back(notifyPropertyName);
+          } else {
+            newEvent->DisplayString.push_back(caption_attribute);
+          }
         } else {
           cout << endl << fgred << "  Could not find the property named "
                << notifyPropertyName << " in script" << endl << "  \""
                << ScriptName << "\". Execution is aborted. Please recheck "
                << "your input files and scripts." << reset << endl;
+          delete newEvent->Condition;
+          delete newEvent;
           return false;
         }
         notify_property_element = notify_element->FindNextElement("property");
@@ -339,7 +363,7 @@ bool FGScript::RunScript(void)
   double currentTime = FDMExec->GetSimTime();
   double newSetValue = 0;
 
-  if (currentTime > EndTime) return false; //Script done!
+  if (currentTime > EndTime) return false;
 
   // Iterate over all events.
   for (unsigned int ev_ctr=0; ev_ctr < Events.size(); ev_ctr++) {
@@ -426,8 +450,12 @@ bool FGScript::RunScript(void)
       if (Events[ev_ctr].Notify && !Events[ev_ctr].Notified) {
         cout << endl << "  Event " << event_ctr << " (" << Events[ev_ctr].Name << ")"
              << " executed at time: " << currentTime << endl;
+        if (!Events[ev_ctr].Description.empty()) {
+          cout << "    " << Events[ev_ctr].Description << endl;
+        }
         for (j=0; j<Events[ev_ctr].NotifyProperties.size();j++) {
-          cout << "    " << Events[ev_ctr].NotifyProperties[j]->GetRelativeName()
+//          cout << "    " << Events[ev_ctr].NotifyProperties[j]->GetRelativeName()
+          cout << "    " << Events[ev_ctr].DisplayString[j]
                << " = " << Events[ev_ctr].NotifyProperties[j]->getDoubleValue() << endl;
         }
         cout << endl;
index 9f8d3ef8e84984bab04bd7857f64fa9ec717ee6d..1ef0cfaa3e5be1e78678619be5a9796274afcf4e 100644 (file)
@@ -48,7 +48,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FGSCRIPT "$Id: FGScript.h,v 1.18 2010/04/11 13:44:42 jberndt Exp $"
+#define ID_FGSCRIPT "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -157,7 +157,7 @@ CLASS DOCUMENTATION
     comes the &quot;run&quot; section, where the conditions are
     described in &quot;event&quot; clauses.</p>
     @author Jon S. Berndt
-    @version "$Id: FGScript.h,v 1.18 2010/04/11 13:44:42 jberndt Exp $"
+    @version "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -178,7 +178,7 @@ public:
       has been supplied on the command line, it will be override the script-
       specified simulation step size.
       @param script the filename (including path name, if any) for the script.
-      @param deltaT a simulation step size from the command line
+      @param deltaT a simulation step size.
       @return true if successful */
   bool LoadScript(string script, double deltaT);
 
@@ -215,8 +215,10 @@ private:
     double           StartTime;
     double           TimeSpan;
     string           Name;
+    string           Description;
     vector <FGPropertyManager*>  SetParam;
     vector <FGPropertyManager*>  NotifyProperties;
+    vector <string>              DisplayString;
     vector <eAction> Action;
     vector <eType>   Type;
     vector <double>  SetValue;
old mode 100644 (file)
new mode 100755 (executable)
index 832b2c8..383603d
@@ -42,7 +42,7 @@ FORWARD DECLARATIONS
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.31 2010/09/29 02:22:03 jberndt Exp $";
+static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.32 2011/02/13 00:42:45 jberndt Exp $";
 static const char *IdHdr = ID_XMLELEMENT;
 
 bool Element::converterIsInitialized = false;
@@ -64,6 +64,8 @@ Element::Element(const string& nm)
     // Length
     convert["M"]["FT"] = 3.2808399;
     convert["FT"]["M"] = 1.0/convert["M"]["FT"];
+    convert["KM"]["FT"] = 3280.8399;
+    convert["FT"]["KM"] = 1.0/convert["KM"]["FT"];
     convert["FT"]["IN"] = 12.0;
     convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
     convert["IN"]["M"] = convert["IN"]["FT"] * convert["FT"]["M"];
@@ -121,6 +123,8 @@ Element::Element(const string& nm)
     convert["FT/S"]["M/S"] = 1.0/convert["M/S"]["FT/S"];
     convert["M/SEC"]["FT/SEC"] = 3.2808399;
     convert["FT/SEC"]["M/SEC"] = 1.0/convert["M/SEC"]["FT/SEC"];
+    convert["KM/SEC"]["FT/SEC"] = 3280.8399;
+    convert["FT/SEC"]["KM/SEC"] = 1.0/convert["KM/SEC"]["FT/SEC"];
     // Torque
     convert["FT*LBS"]["N*M"] = 1.35581795;
     convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
@@ -153,6 +157,7 @@ Element::Element(const string& nm)
 
     // Length
     convert["M"]["M"] = 1.00;
+    convert["KM"]["KM"] = 1.00;
     convert["FT"]["FT"] = 1.00;
     convert["IN"]["IN"] = 1.00;
     // Area
@@ -195,6 +200,7 @@ Element::Element(const string& nm)
     convert["KTS"]["KTS"] = 1.00;
     convert["M/S"]["M/S"] = 1.0;
     convert["M/SEC"]["M/SEC"] = 1.0;
+    convert["KM/SEC"]["KM/SEC"] = 1.0;
     // Torque
     convert["FT*LBS"]["FT*LBS"] = 1.00;
     convert["N*M"]["N*M"] = 1.00;
index 2a1ffd47f2415b2e574451ba985e3a94fbd921ac..7f7e9057eb99b6e8a87fb8c50f43dd435c1c1cee 100644 (file)
@@ -35,6 +35,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGCondition.h"
+#include "FGPropertyValue.h"
 #include "input_output/FGXMLElement.h"
 #include "input_output/FGPropertyManager.h"
 #include <iostream>
@@ -44,7 +45,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGCondition.cpp,v 1.13 2010/07/14 05:50:40 ehofman Exp $";
+static const char *IdSrc = "$Id: FGCondition.cpp,v 1.14 2011/04/05 20:20:21 andgi Exp $";
 static const char *IdHdr = ID_CONDITION;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -122,12 +123,11 @@ FGCondition::FGCondition(const string& test, FGPropertyManager* PropertyManager)
     exit(-1);
   }
 
-  TestParam1 = PropertyManager->GetNode(property1, false);
-  if (!TestParam1) {
-      cerr << fgred << "  In condition: " << test << ". Unknown property "
-           << property1 << " referenced." << endl
-           << "Creating property.  Check usage." << reset << endl;
-      TestParam1 = PropertyManager->GetNode(property1, true);
+  FGPropertyManager *node = PropertyManager->GetNode(property1, false);
+  if (node) {
+    TestParam1 = new FGPropertyValue(node);
+  } else {
+    TestParam1 = new FGPropertyValue(property1, PropertyManager);
   }
   Comparison = mComparison[conditional];
   if (Comparison == ecUndef) {
@@ -136,12 +136,11 @@ FGCondition::FGCondition(const string& test, FGPropertyManager* PropertyManager)
   if (is_number(property2)) {
     TestValue = atof(property2.c_str());
   } else {
-    TestParam2 = PropertyManager->GetNode(property2, false);
-    if (!TestParam2) {
-        cerr << fgred << "  In condition: " << test << ". Unknown property "
-             << property2 << " referenced." << endl
-             << "Creating property.  Check usage." << reset << endl;
-        TestParam2 = PropertyManager->GetNode(property2, true);
+    node = PropertyManager->GetNode(property2, false);
+    if (node) {
+      TestParam2 = new FGPropertyValue(node);
+    } else {
+      TestParam2 = new FGPropertyValue(property2, PropertyManager);
     }
   }
 }
@@ -267,11 +266,11 @@ void FGCondition::PrintCondition(void )
 
   } else {
     if (TestParam2 != 0L)
-      cout << "    " << TestParam1->GetRelativeName() << " "
+      cout << "    " << TestParam1->GetName() << " "
                         << conditional << " "
-                        << TestParam2->GetRelativeName();
+                        << TestParam2->GetName();
     else
-      cout << "    " << TestParam1->GetRelativeName() << " "
+      cout << "    " << TestParam1->GetName() << " "
                      << conditional << " " << TestValue;
   }
 }
index 2cd75bdfbf2a9761547e42c5a1aefc0c17a07dc8..06632a76da6dc07ad1aa4023c64bc373e5e9122d 100644 (file)
@@ -44,7 +44,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_CONDITION "$Id: FGCondition.h,v 1.5 2009/10/24 22:59:30 jberndt Exp $"
+#define ID_CONDITION "$Id: FGCondition.h,v 1.6 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -53,6 +53,7 @@ FORWARD DECLARATIONS
 namespace JSBSim {
 
 class FGPropertyManager;
+class FGPropertyValue;
 class Element;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -82,7 +83,8 @@ private:
   std::map <std::string, eComparison> mComparison;
   eLogic Logic;
 
-  FGPropertyManager *TestParam1, *TestParam2, *PropertyManager;
+  FGPropertyManager *PropertyManager;
+  FGPropertyValue *TestParam1, *TestParam2;
   double TestValue;
   eComparison Comparison;
   bool isGroup;
old mode 100644 (file)
new mode 100755 (executable)
index 9ad7c7a..c0d2e6a
@@ -43,7 +43,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFunction.cpp,v 1.35 2010/08/28 12:41:56 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFunction.cpp,v 1.36 2011/04/05 20:20:21 andgi Exp $";
 static const char *IdHdr = ID_FUNCTION;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -177,9 +177,10 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr
         newNode = PropertyManager->GetNode(property_name);
         Parameters.push_back(new FGPropertyValue( newNode ));
       } else {
-        cerr << fgcyan << "The property " + property_name + " is initially undefined."
+        cerr << fgcyan << "Warning: The property " + property_name + " is initially undefined."
              << reset << endl;
-        Parameters.push_back(new FGPropertyValue( property_name ));
+        Parameters.push_back(new FGPropertyValue( property_name,
+                                                  PropertyManager ));
       }
     } else if (operation == value_string || operation == v_string) {
       Parameters.push_back(new FGRealValue(element->GetDataAsNumber()));
@@ -252,17 +253,8 @@ double FGFunction::GetValue(void) const
 
   if (cached) return cachedValue;
 
-  try {
-    temp = Parameters[0]->GetValue();
-  } catch (string prop) {
-    if (PropertyManager->HasNode(prop)) {
-      ((FGPropertyValue*)Parameters[0])->SetNode(PropertyManager->GetNode(prop));
-      temp = Parameters[0]->GetValue();
-    } else {
-      throw("Property " + prop + " was not defined anywhere.");
-    }
-  }
-
+  temp = Parameters[0]->GetValue();
+  
   switch (Type) {
   case eTopLevel:
     break;
old mode 100644 (file)
new mode 100755 (executable)
index 85b43b1..c1d66fc
@@ -40,7 +40,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PARAMETER "$Id: FGParameter.h,v 1.5 2009/08/30 03:51:28 jberndt Exp $"
+#define ID_PARAMETER "$Id: FGParameter.h,v 1.6 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -65,6 +65,10 @@ class FGParameter : public FGJSBBase
 public:
   virtual ~FGParameter(void) {};
   virtual double GetValue(void) const = 0;
+  virtual std::string GetName(void) const = 0;
+
+  // SGPropertyNode impersonation.
+  double getDoubleValue(void) const { return GetValue(); }
 
 protected:
 };
old mode 100644 (file)
new mode 100755 (executable)
index 0824a60..7f448da
@@ -6,6 +6,7 @@ Date started: 12/10/2004
 Purpose: Stores property values
 
  ------------- Copyright (C) 2001  Jon S. Berndt (jon@jsbsim.org) -------------
+ ------ Copyright (C) 2010 - 2011  Anders Gidenstam (anders(at)gidenstam.org) -
 
  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free Software
@@ -32,36 +33,53 @@ INCLUDES
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropertyValue.cpp,v 1.6 2010/08/24 10:30:14 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPropertyValue.cpp,v 1.7 2011/04/05 20:20:21 andgi Exp $";
 static const char *IdHdr = ID_PROPERTYVALUE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGPropertyValue::FGPropertyValue(FGPropertyManager* propNode) : PropertyManager(propNode)
+FGPropertyValue::FGPropertyValue(FGPropertyManager* propNode)
+  : PropertyManager(0L), PropertyNode(propNode)
 {
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGPropertyValue::FGPropertyValue(std::string propName) : PropertyManager(0L)
+FGPropertyValue::FGPropertyValue(std::string propName, FGPropertyManager* propertyManager)
+  : PropertyManager(propertyManager), PropertyNode(0L), PropertyName(propName)
 {
-  PropertyName = propName;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 double FGPropertyValue::GetValue(void) const
 {
-  double val;
-  try {
-    val = PropertyManager->getDoubleValue();
-  } catch (...) {
-    throw(PropertyName);
+  FGPropertyManager* node = PropertyNode;
+
+  if (!PropertyNode) {
+    // The node cannot be cached since this is a const method.
+    node = PropertyManager->GetNode(PropertyName);
+    
+    if (!node) {
+      throw(std::string("FGPropertyValue::GetValue() The property " +
+                        PropertyName + " does not exist."));
+    }
   }
 
-  return val;
+  return node->getDoubleValue();
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+std::string FGPropertyValue::GetName(void) const
+{
+  if (PropertyNode) {
+    return PropertyNode->GetName();
+  } else {
+    return PropertyName;
+  }
 }
 
 }
old mode 100644 (file)
new mode 100755 (executable)
index 753df7c..c716cf5
@@ -5,6 +5,7 @@ Author: Jon Berndt
 Date started: December 10 2004
 
  ------------- Copyright (C) 2001  Jon S. Berndt (jon@jsbsim.org) -------------
+ ------ Copyright (C) 2010 - 2011  Anders Gidenstam (anders(at)gidenstam.org) -
 
  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free Software
@@ -41,7 +42,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPERTYVALUE "$Id: FGPropertyValue.h,v 1.8 2010/08/24 10:30:14 jberndt Exp $"
+#define ID_PROPERTYVALUE "$Id: FGPropertyValue.h,v 1.9 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -53,8 +54,8 @@ namespace JSBSim {
 CLASS DOCUMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-  /** Represents a property value
-      @author Jon Berndt
+  /** Represents a property value which can use late binding.
+      @author Jon Berndt, Anders Gidenstam
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -66,14 +67,17 @@ class FGPropertyValue : public FGParameter
 public:
 
   FGPropertyValue(FGPropertyManager* propNode);
-  FGPropertyValue(std::string propName);
+  FGPropertyValue(std::string propName, FGPropertyManager* propertyManager);
   ~FGPropertyValue() {};
 
   double GetValue(void) const;
-  void SetNode(FGPropertyManager* node) {PropertyManager = node;} 
+  void SetNode(FGPropertyManager* node) {PropertyNode = node;} 
+
+  std::string GetName(void) const;
 
 private:
-  FGPropertyManager* PropertyManager;
+  FGPropertyManager* PropertyManager; // Property root used to do late binding.
+  FGPropertyManager* PropertyNode;
   std::string PropertyName;
 };
 
index 277c595c1b2f0a4aa8e0a3794b23c6a1a576d16b..9564eabf7de564829046bb1079d0925af9837e31 100644 (file)
@@ -40,7 +40,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_REALVALUE "$Id: FGRealValue.h,v 1.4 2009/08/30 03:51:28 jberndt Exp $"
+#define ID_REALVALUE "$Id: FGRealValue.h,v 1.5 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -68,6 +68,7 @@ public:
   ~FGRealValue() {};
 
   double GetValue(void) const;
+  std::string GetName(void) const {return "constant";}
 
 private:
   double Value;
index 2f2e271cdf2198318d29c46224c56fe02eda66ba..3d222498174fcdc1818220be051d043a6d216ddd 100644 (file)
@@ -47,7 +47,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_TABLE "$Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $"
+#define ID_TABLE "$Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -233,7 +233,7 @@ combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio
 @endcode
 
 @author Jon S. Berndt
-@version $Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $
+@version $Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -292,6 +292,8 @@ public:
 
   void Print(void);
 
+  std::string GetName(void) const {return Name;}
+
 private:
   enum type {tt1D, tt2D, tt3D} Type;
   enum axis {eRow=0, eColumn, eTable};
index 21583363ba1b83eb12c876923a25e9a6019b499c..0f08c01600d0d99d2e44d5db9d54bd1e4e6fc87a 100644 (file)
@@ -52,7 +52,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.36 2011/01/19 12:41:19 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.37 2011/03/11 13:02:26 jberndt Exp $";
 static const char *IdHdr = ID_AERODYNAMICS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -80,7 +80,7 @@ FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec)
 
   axisType = atNone;
 
-  Coeff = new CoeffArray[6];
+  AeroFunctions = new AeroFunctionArray[6];
 
   impending_stall = stall_hyst = 0.0;
   alphaclmin = alphaclmax = 0.0;
@@ -103,10 +103,10 @@ FGAerodynamics::~FGAerodynamics()
   unsigned int i,j;
 
   for (i=0; i<6; i++)
-    for (j=0; j<Coeff[i].size(); j++)
-      delete Coeff[i][j];
+    for (j=0; j<AeroFunctions[i].size(); j++)
+      delete AeroFunctions[i][j];
 
-  delete[] Coeff;
+  delete[] AeroFunctions;
 
   delete AeroRPShift;
 
@@ -142,7 +142,7 @@ bool FGAerodynamics::Run(void)
   const double alpha=FDMExec->GetAuxiliary()->Getalpha();
   const double twovel=2*FDMExec->GetAuxiliary()->GetVt();
   const double qbar = FDMExec->GetAuxiliary()->Getqbar();
-  const double wingarea = FDMExec->GetAircraft()->GetWingArea();
+  const double wingarea = FDMExec->GetAircraft()->GetWingArea();  // TODO: Make these constants constant!
   const double wingspan = FDMExec->GetAircraft()->GetWingSpan();
   const double wingchord = FDMExec->GetAircraft()->Getcbar();
   const double wingincidence = FDMExec->GetAircraft()->GetWingIncidence();
@@ -177,8 +177,8 @@ bool FGAerodynamics::Run(void)
   vFnative.InitMatrix();
 
   for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
-    for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
-      vFnative(axis_ctr+1) += Coeff[axis_ctr][ctr]->GetValue();
+    for (ctr=0; ctr < AeroFunctions[axis_ctr].size(); ctr++) {
+      vFnative(axis_ctr+1) += AeroFunctions[axis_ctr][ctr]->GetValue();
     }
   }
 
@@ -224,8 +224,8 @@ bool FGAerodynamics::Run(void)
   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++) {
-      vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->GetValue();
+    for (ctr = 0; ctr < AeroFunctions[axis_ctr+3].size(); ctr++) {
+      vMoments(axis_ctr+1) += AeroFunctions[axis_ctr+3][ctr]->GetValue();
     }
   }
 
@@ -349,7 +349,7 @@ bool FGAerodynamics::Load(Element *element)
 
   axis_element = document->FindElement("axis");
   while (axis_element) {
-    CoeffArray ca;
+    AeroFunctionArray ca;
     axis = axis_element->GetAttributeValue("name");
     function_element = axis_element->FindElement("function");
     while (function_element) {
@@ -363,7 +363,7 @@ bool FGAerodynamics::Load(Element *element)
       }
       function_element = axis_element->FindNextElement("function");
     }
-    Coeff[AxisIdx[axis]] = ca;
+    AeroFunctions[AxisIdx[axis]] = ca;
     axis_element = document->FindNextElement("axis");
   }
 
@@ -427,35 +427,35 @@ void FGAerodynamics::DetermineAxisSystem()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGAerodynamics::GetCoefficientStrings(const string& delimeter) const
+string FGAerodynamics::GetAeroFunctionStrings(const string& delimeter) const
 {
-  string CoeffStrings = "";
+  string AeroFunctionStrings = "";
   bool firstime = true;
   unsigned int axis, sd;
 
   for (axis = 0; axis < 6; axis++) {
-    for (sd = 0; sd < Coeff[axis].size(); sd++) {
+    for (sd = 0; sd < AeroFunctions[axis].size(); sd++) {
       if (firstime) {
         firstime = false;
       } else {
-        CoeffStrings += delimeter;
+        AeroFunctionStrings += delimeter;
       }
-      CoeffStrings += Coeff[axis][sd]->GetName();
+      AeroFunctionStrings += AeroFunctions[axis][sd]->GetName();
     }
   }
-  return CoeffStrings;
+  return AeroFunctionStrings;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGAerodynamics::GetCoefficientValues(const string& delimeter) const
+string FGAerodynamics::GetAeroFunctionValues(const string& delimeter) const
 {
   ostringstream buf;
 
   for (unsigned int axis = 0; axis < 6; axis++) {
-    for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
+    for (unsigned int sd = 0; sd < AeroFunctions[axis].size(); sd++) {
       if (buf.tellp() > 0) buf << delimeter;
-      buf << setw(9) << Coeff[axis][sd]->GetValue();
+      buf << setw(9) << AeroFunctions[axis][sd]->GetValue();
     }
   }
 
index a5e2781959da3b3e8ce398c697b8203d53c06ed6..c6638b41161c627c52a799da0dccc9adb501dc5a 100644 (file)
@@ -52,7 +52,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.21 2010/11/18 12:38:06 jberndt Exp $"
+#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -89,7 +89,7 @@ CLASS DOCUMENTATION
          {function contents}
        </function>
        <axis name="{LIFT | DRAG | SIDE | ROLL | PITCH | YAW}">
-         {force coefficient definitions}
+         {force or moment definitions}
        </axis>
        {additional axis definitions}
     </aerodynamics>
@@ -103,13 +103,13 @@ CLASS DOCUMENTATION
     <br>
     2) Axial-Normal coordinate system:
     @code
-       <axis name="{AXIAL | NORMAL}">
+       <axis name="{AXIAL | NORMAL | SIDE}">
     @endcode
     <br>
     Systems may NOT be combined, or a load error will occur.
 
     @author Jon S. Berndt, Tony Peden
-    @version $Revision: 1.21 $
+    @version $Revision: 1.22 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -186,16 +186,16 @@ public:
   void SetAlphaCLMax(double tt) { alphaclmax=tt; }
   void SetAlphaCLMin(double tt) { alphaclmin=tt; }
 
-  /** Gets the strings for the current set of coefficients.
+  /** Gets the strings for the current set of aero functions.
       @param delimeter either a tab or comma string depending on output type
-      @return a string containing the descriptive names for all coefficients */
-  std::string GetCoefficientStrings(const std::string& delimeter) const;
+      @return a string containing the descriptive names for all aero functions */
+  std::string GetAeroFunctionStrings(const std::string& delimeter) const;
 
-  /** Gets the coefficient values.
+  /** Gets the aero function values.
       @param delimeter either a tab or comma string depending on output type
       @return a string containing the numeric values for the current set of
-      coefficients */
-  std::string GetCoefficientValues(const std::string& delimeter) const;
+      aero functions */
+  std::string GetAeroFunctionValues(const std::string& delimeter) const;
 
   /** Calculates and returns the wind-to-body axis transformation matrix.
       @return a reference to the wind-to-body transformation matrix.
@@ -207,15 +207,15 @@ public:
       */
   FGMatrix33& GetTb2w(void);
 
-  std::vector <FGFunction*> * GetCoeff(void) const { return Coeff; }
+  std::vector <FGFunction*> * GetAeroFunctions(void) const { return AeroFunctions; }
 
 private:
   enum eAxisType {atNone, atLiftDrag, atAxialNormal, atBodyXYZ} axisType;
   typedef std::map<std::string,int> AxisIndex;
   AxisIndex AxisIdx;
   FGFunction* AeroRPShift;
-  typedef vector <FGFunction*> CoeffArray;
-  CoeffArray* Coeff;
+  typedef vector <FGFunction*> AeroFunctionArray;
+  AeroFunctionArray* AeroFunctions;
   FGColumnVector3 vFnative;
   FGColumnVector3 vFw;
   FGColumnVector3 vForces;
index f40fabcb5e00c77d85cbc5042bd013eb33ae5233..992e7952ec1ec38e4e2c87895c1065184ba647c7 100644 (file)
@@ -61,7 +61,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.41 2010/11/30 12:19:57 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.42 2011/02/18 12:44:16 jberndt Exp $";
 static const char *IdHdr = ID_ATMOSPHERE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -124,6 +124,7 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
 
 FGAtmosphere::~FGAtmosphere()
 {
+  delete(POE_Table);
   Debug(1);
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index 1dd3e22..36c1e08
@@ -59,7 +59,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.45 2010/11/18 12:38:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.47 2011/03/29 11:49:27 jberndt Exp $";
 static const char *IdHdr = ID_AUXILIARY;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -180,33 +180,30 @@ bool FGAuxiliary::Run()
   vAeroUVW = vUVW - wind;
 
   Vt = vAeroUVW.Magnitude();
+  double Vt2 = Vt*Vt;
+  alpha = beta = adot = bdot = 0;
+  double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
+
   if ( Vt > 1.0 ) {
     if (vAeroUVW(eW) != 0.0)
       alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
     if (vAeroUVW(eV) != 0.0)
-      beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV),
-             sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
+      beta = mUW > 0.0 ? atan2(vAeroUVW(eV), sqrt(mUW)) : 0.0;
 
-    double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
     double signU=1;
     if (vAeroUVW(eU) < 0.0) signU=-1;
 
-    if ( mUW < 1.0 ) {
-      adot = 0.0;
-      bdot = 0.0;
-    } else {
+    if ( mUW >= 1.0 ) {
       adot = (vAeroUVW(eU)*vUVWdot(eW) - vAeroUVW(eW)*vUVWdot(eU))/mUW;
-      bdot = (signU*mUW*vUVWdot(eV) - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU)
-              + vAeroUVW(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
+      bdot = (signU*mUW*vUVWdot(eV)
+             - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU) + vAeroUVW(eW)*vUVWdot(eW)))/(Vt2*sqrt(mUW));
     }
-  } else {
-    alpha = beta = adot = bdot = 0;
   }
 
   Re = Vt * FDMExec->GetAircraft()->Getcbar() / FDMExec->GetAtmosphere()->GetKinematicViscosity();
 
-  qbar = 0.5*density*Vt*Vt;
-  qbarUW = 0.5*density*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
+  qbar = 0.5*density*Vt2;
+  qbarUW = 0.5*density*(mUW);
   qbarUV = 0.5*density*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
   Mach = Vt / soundspeed;
   MachU = vMachUVW(eU) = vAeroUVW(eU) / soundspeed;
@@ -291,6 +288,7 @@ bool FGAuxiliary::Run()
 //
 // A positive headwind is blowing with you, a negative headwind is blowing against you.
 // psi is the direction the wind is blowing *towards*.
+// ToDo: should this simply be in the atmosphere class? Same with Get Crosswind.
 
 double FGAuxiliary::GetHeadWind(void) const
 {
index b3808d70fa71581b348a1f83d8943135670cf3e4..d12777478c1ada31484e00e1cb588b97bb38c17a 100644 (file)
@@ -45,7 +45,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.14 2010/11/18 12:38:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.16 2011/03/23 11:58:29 jberndt Exp $";
 static const char *IdHdr = ID_BUOYANTFORCES;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -213,13 +213,13 @@ string FGBuoyantForces::GetBuoyancyStrings(string delimeter)
   }
 
   for (axis = 0; axis < 6; axis++) {
-    for (sd = 0; sd < Coeff[axis].size(); sd++) {
+    for (sd = 0; sd < AeroFunctions[axis].size(); sd++) {
       if (firstime) {
         firstime = false;
       } else {
         CoeffStrings += delimeter;
       }
-      CoeffStrings += Coeff[axis][sd]->GetName();
+      CoeffStrings += AeroFunctions[axis][sd]->GetName();
     }
   }
 */
@@ -243,13 +243,13 @@ string FGBuoyantForces::GetBuoyancyValues(string delimeter)
   }
 
   for (unsigned int axis = 0; axis < 6; axis++) {
-    for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
+    for (unsigned int sd = 0; sd < AeroFunctions[axis].size(); sd++) {
       if (firstime) {
         firstime = false;
       } else {
         SDValues += delimeter;
       }
-      SDValues += Coeff[axis][sd]->GetValueAsString();
+      SDValues += AeroFunctions[axis][sd]->GetValueAsString();
     }
   }
 */
@@ -260,19 +260,20 @@ string FGBuoyantForces::GetBuoyancyValues(string delimeter)
 
 void FGBuoyantForces::bind(void)
 {
-  typedef double (FGBuoyantForces::*PMF)(int) const;
+  typedef double (FGBuoyantForces::*PGF)(int) const;
+  typedef void   (FGBuoyantForces::*PSF)(int, double);
   PropertyManager->Tie("moments/l-buoyancy-lbsft", this, eL,
-                       (PMF)&FGBuoyantForces::GetMoments);
+                       (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
   PropertyManager->Tie("moments/m-buoyancy-lbsft", this, eM,
-                       (PMF)&FGBuoyantForces::GetMoments);
+                       (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
   PropertyManager->Tie("moments/n-buoyancy-lbsft", this, eN,
-                       (PMF)&FGBuoyantForces::GetMoments);
+                       (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
   PropertyManager->Tie("forces/fbx-buoyancy-lbs", this, eX,
-                       (PMF)&FGBuoyantForces::GetForces);
+                       (PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
   PropertyManager->Tie("forces/fby-buoyancy-lbs", this, eY,
-                       (PMF)&FGBuoyantForces::GetForces);
+                       (PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
   PropertyManager->Tie("forces/fbz-buoyancy-lbs", this, eZ,
-                       (PMF)&FGBuoyantForces::GetForces);
+                       (PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index f0b77007d23cbabd0b344cf67fdde1e14bd4d791..a3b7e91bc5e3ba65bcb1c90e242b29f459b0138c 100644 (file)
@@ -63,7 +63,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFCS.cpp,v 1.72 2010/11/18 12:38:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFCS.cpp,v 1.73 2011/04/05 20:20:21 andgi Exp $";
 static const char *IdHdr = ID_FCS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -182,17 +182,6 @@ bool FGFCS::InitModel(void)
 
   return true;
 }
-  
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCS::LateBind(void)
-{
-  unsigned int i;
-
-  for (i=0; i<Systems.size(); i++) Systems[i]->LateBind();
-  for (i=0; i<APComponents.size(); i++) APComponents[i]->LateBind();
-  for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->LateBind();
-}
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Notes: In this logic the default engine commands are set. This is simply a
index a17509212acbd478337f211b2887e80e91a255bf..6b97297d5ab0f6dba17052aa2f00d4d3dbc8ae27 100644 (file)
@@ -51,7 +51,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FCS "$Id: FGFCS.h,v 1.31 2010/09/22 11:33:40 jberndt Exp $"
+#define ID_FCS "$Id: FGFCS.h,v 1.35 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -168,7 +168,7 @@ CLASS DOCUMENTATION
     @property gear/tailhook-pos-norm
 
     @author Jon S. Berndt
-    @version $Revision: 1.31 $
+    @version $Revision: 1.35 $
     @see FGActuator
     @see FGDeadBand
     @see FGFCSFunction
@@ -540,7 +540,7 @@ public:
 
   FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
 
-  void LateBind(void);
+  bool GetTrimStatus(void) const { return FDMExec->GetTrimStatus(); }
 
 private:
   double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
index 596e495f0c6d1ea0daf5b395a53e482ffc70af4e..4a4c9946f381e4ebd5aadc63f9ee2a10fdcc3441 100644 (file)
@@ -62,7 +62,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-static const char *IdSrc = "$Id: FGLGear.cpp,v 1.79 2010/11/28 13:20:47 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGLGear.cpp,v 1.80 2011/01/24 13:01:56 jberndt Exp $";
 static const char *IdHdr = ID_LGEAR;
 
 // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
@@ -374,13 +374,15 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
     }
   }
 
-  ReportTakeoffOrLanding();
+  if (!fdmex->GetTrimStatus()) {
+    ReportTakeoffOrLanding();
 
-  // Require both WOW and LastWOW to be true before checking crash conditions
-  // to allow the WOW flag to be used in terminating a scripted run.
-  if (WOW && lastWOW) CrashDetect();
+    // Require both WOW and LastWOW to be true before checking crash conditions
+    // to allow the WOW flag to be used in terminating a scripted run.
+    if (WOW && lastWOW) CrashDetect();
 
-  lastWOW = WOW;
+    lastWOW = WOW;
+  }
 
   return FGForce::GetBodyForces();
 }
index 71f6cb3ed3d468e5cadb0bd3b7035ff751e161a6..df7ffbdd017f5c0a01ee33453c626229869cc8b8 100644 (file)
@@ -57,7 +57,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGModel.cpp,v 1.16 2010/11/18 12:38:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGModel.cpp,v 1.17 2011/02/16 12:30:53 jberndt Exp $";
 static const char *IdHdr = ID_MODEL;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -77,7 +77,7 @@ FGModel::FGModel(FGFDMExec* fdmex)
   //must be brought up now.
   PropertyManager = FDMExec->GetPropertyManager();
 
-  exe_ctr     = 1;
+  exe_ctr     = 0;
   rate        = 1;
 
   if (debug_lvl & 2) cout << "              FGModel Base Class" << endl;
@@ -105,7 +105,7 @@ bool FGModel::Run()
 
   if (rate == 1) return false; // Fast exit if nothing to do
 
-  if (exe_ctr >= rate) exe_ctr = 1;
+  if (exe_ctr >= rate) exe_ctr = 0;
 
   if (exe_ctr++ == 1) return false;
   else              return true;
index 3e5c986c6040b96bd8f9b9e8e6949be1fc8236f6..ab70cb2d2de6098afa0957099c56824fc0e6ef49 100644 (file)
@@ -74,7 +74,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGOutput.cpp,v 1.50 2010/11/18 12:38:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGOutput.cpp,v 1.54 2011/03/11 13:02:26 jberndt Exp $";
 static const char *IdHdr = ID_OUTPUT;
 
 // (stolen from FGFS native_fdm.cxx)
@@ -182,21 +182,9 @@ bool FGOutput::Run(void)
 {
   if (FGModel::Run()) return true;
 
-  if (enabled && !FDMExec->IntegrationSuspended()&& !FDMExec->Holding()) {
+  if (enabled && !FDMExec->IntegrationSuspended() && !FDMExec->Holding()) {
     RunPreFunctions();
-    if (Type == otSocket) {
-      SocketOutput();
-    } else if (Type == otFlightGear) {
-      FlightGearSocketOutput();
-    } else if (Type == otCSV || Type == otTab) {
-      DelimitedOutput(Filename);
-    } else if (Type == otTerminal) {
-      // Not done yet
-    } else if (Type == otNone) {
-      // Do nothing
-    } else {
-      // Not a valid type of output
-    }
+    Print();
     RunPostFunctions();
   }
   return false;
@@ -204,6 +192,25 @@ bool FGOutput::Run(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGOutput::Print(void)
+{
+  if (Type == otSocket) {
+    SocketOutput();
+  } else if (Type == otFlightGear) {
+    FlightGearSocketOutput();
+  } else if (Type == otCSV || Type == otTab) {
+    DelimitedOutput(Filename);
+  } else if (Type == otTerminal) {
+    // Not done yet
+  } else if (Type == otNone) {
+    // Do nothing
+  } else {
+    // Not a valid type of output
+  }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGOutput::SetType(const string& type)
 {
   if (type == "CSV") {
@@ -296,6 +303,7 @@ void FGOutput::DelimitedOutput(const string& fname)
       outstream << "UBody" + delimeter + "VBody" + delimeter + "WBody" + delimeter;
       outstream << "Aero V_{X Body} (ft/s)" + delimeter + "Aero V_{Y Body} (ft/s)" + delimeter + "Aero V_{Z Body} (ft/s)" + delimeter;
       outstream << "V_{X_{inertial}} (ft/s)" + delimeter + "V_{Y_{inertial}} (ft/s)" + delimeter + "V_{Z_{inertial}} (ft/s)" + delimeter;
+      outstream << "V_{X_{ecef}} (ft/s)" + delimeter + "V_{Y_{ecef}} (ft/s)" + delimeter + "V_{Z_{ecef}} (ft/s)" + delimeter;
       outstream << "V_{North} (ft/s)" + delimeter + "V_{East} (ft/s)" + delimeter + "V_{Down} (ft/s)";
     }
     if (SubSystems & ssForces) {
@@ -359,8 +367,8 @@ void FGOutput::DelimitedOutput(const string& fname)
       outstream << "Distance AGL (ft)" + delimeter;
       outstream << "Terrain Elevation (ft)";
     }
-    if (SubSystems & ssCoefficients) {
-      scratch = Aerodynamics->GetCoefficientStrings(delimeter);
+    if (SubSystems & ssAeroFunctions) {
+      scratch = Aerodynamics->GetAeroFunctionStrings(delimeter);
       if (scratch.length() != 0) outstream << delimeter << scratch;
     }
     if (SubSystems & ssFCS) {
@@ -415,6 +423,7 @@ void FGOutput::DelimitedOutput(const string& fname)
     outstream << setprecision(12) << Propagate->GetUVW().Dump(delimeter) << delimeter;
     outstream << Auxiliary->GetAeroUVW().Dump(delimeter) << delimeter;
     outstream << Propagate->GetInertialVelocity().Dump(delimeter) << delimeter;
+    outstream << Propagate->GetECEFVelocity().Dump(delimeter) << delimeter;
     outstream << Propagate->GetVel().Dump(delimeter);
     outstream.precision(10);
   }
@@ -475,8 +484,8 @@ void FGOutput::DelimitedOutput(const string& fname)
     outstream << Propagate->GetTerrainElevation();
     outstream.precision(10);
   }
-  if (SubSystems & ssCoefficients) {
-    scratch = Aerodynamics->GetCoefficientValues(delimeter);
+  if (SubSystems & ssAeroFunctions) {
+    scratch = Aerodynamics->GetAeroFunctionValues(delimeter);
     if (scratch.length() != 0) outstream << delimeter << scratch;
   }
   if (SubSystems & ssFCS) {
@@ -826,8 +835,8 @@ void FGOutput::SocketOutput(void)
         socket->Append("Latitude (deg)");
         socket->Append("Longitude (deg)");
     }
-    if (SubSystems & ssCoefficients) {
-      scratch = Aerodynamics->GetCoefficientStrings(",");
+    if (SubSystems & ssAeroFunctions) {
+      scratch = Aerodynamics->GetAeroFunctionStrings(",");
       if (scratch.length() != 0) socket->Append(scratch);
     }
     if (SubSystems & ssFCS) {
@@ -932,8 +941,8 @@ void FGOutput::SocketOutput(void)
     socket->Append(Propagate->GetLocation().GetLatitudeDeg());
     socket->Append(Propagate->GetLocation().GetLongitudeDeg());
   }
-  if (SubSystems & ssCoefficients) {
-    scratch = Aerodynamics->GetCoefficientValues(",");
+  if (SubSystems & ssAeroFunctions) {
+    scratch = Aerodynamics->GetAeroFunctionValues(",");
     if (scratch.length() != 0) socket->Append(scratch);
   }
   if (SubSystems & ssFCS) {
@@ -974,7 +983,7 @@ bool FGOutput::Load(Element* element)
 {
   string parameter="";
   string name="";
-  int OutRate = 0;
+  double OutRate = 0.0;
   unsigned int port;
   Element *property_element;
 
@@ -1003,7 +1012,7 @@ bool FGOutput::Load(Element* element)
     BaseFilename = Filename = name;
   }
   if (!document->GetAttributeValue("rate").empty()) {
-    OutRate = (int)document->GetAttributeValueAsNumber("rate");
+    OutRate = document->GetAttributeValueAsNumber("rate");
   } else {
     OutRate = 1;
   }
@@ -1027,7 +1036,7 @@ bool FGOutput::Load(Element* element)
   if (document->FindElementValue("position") == string("ON"))
     SubSystems += ssPropagate;
   if (document->FindElementValue("coefficients") == string("ON"))
-    SubSystems += ssCoefficients;
+    SubSystems += ssAeroFunctions;
   if (document->FindElementValue("ground_reactions") == string("ON"))
     SubSystems += ssGroundReactions;
   if (document->FindElementValue("fcs") == string("ON"))
@@ -1058,7 +1067,7 @@ bool FGOutput::Load(Element* element)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGOutput::SetRate(int rtHz)
+void FGOutput::SetRate(double rtHz)
 {
   rtHz = rtHz>1000?1000:(rtHz<0?0:rtHz);
   if (rtHz > 0) {
@@ -1128,7 +1137,7 @@ void FGOutput::Debug(int from)
       if (SubSystems & ssMoments)         cout << "    Moments parameters logged" << endl;
       if (SubSystems & ssAtmosphere)      cout << "    Atmosphere parameters logged" << endl;
       if (SubSystems & ssMassProps)       cout << "    Mass parameters logged" << endl;
-      if (SubSystems & ssCoefficients)    cout << "    Coefficient parameters logged" << endl;
+      if (SubSystems & ssAeroFunctions)    cout << "    Coefficient parameters logged" << endl;
       if (SubSystems & ssPropagate)       cout << "    Propagate parameters logged" << endl;
       if (SubSystems & ssGroundReactions) cout << "    Ground parameters logged" << endl;
       if (SubSystems & ssFCS)             cout << "    FCS parameters logged" << endl;
index d03ac5981ac54aff208d950de396ed87ad2f0749..e22dc1319f80f7b40b74fa6d28180a386d553569 100644 (file)
@@ -51,7 +51,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_OUTPUT "$Id: FGOutput.h,v 1.19 2010/10/31 04:48:46 jberndt Exp $"
+#define ID_OUTPUT "$Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -124,7 +124,7 @@ CLASS DOCUMENTATION
     propulsion       ON|OFF
 </pre>
     NOTE that Time is always output with the data.
-    @version $Id: FGOutput.h,v 1.19 2010/10/31 04:48:46 jberndt Exp $
+    @version $Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $
  */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -140,6 +140,7 @@ public:
   bool InitModel(void);
   bool Run(void);
 
+  void Print(void);
   void DelimitedOutput(const std::string&);
   void SocketOutput(void);
   void FlightGearSocketOutput(void);
@@ -153,7 +154,7 @@ public:
   void SetSubsystems(int tt) {SubSystems = tt;}
   void SetOutputFileName(const std::string& fname) {Filename = fname;}
   void SetDirectivesFile(const std::string& fname) {DirectivesFile = fname;}
-  void SetRate(int rt);
+  void SetRate(double rt);
   void Enable(void) { enabled = true; }
   void Disable(void) { enabled = false; }
   bool Toggle(void) {enabled = !enabled; return enabled;}
@@ -171,7 +172,7 @@ public:
     /** Subsystem: Moments (= 32)            */ ssMoments         = 32,
     /** Subsystem: Atmosphere (= 64)         */ ssAtmosphere      = 64,
     /** Subsystem: Mass Properties (= 128)   */ ssMassProps       = 128,
-    /** Subsystem: Coefficients (= 256)      */ ssCoefficients    = 256,
+    /** Subsystem: Coefficients (= 256)      */ ssAeroFunctions    = 256,
     /** Subsystem: Propagate (= 512)         */ ssPropagate       = 512,
     /** Subsystem: Ground Reactions (= 1024) */ ssGroundReactions = 1024,
     /** Subsystem: FCS (= 2048)              */ ssFCS             = 2048,
index 4d1ef44a858a60d532d336d532d30f10673ced8c..ae2174df91557d5c190be4c4f728d41bbbbc5391 100644 (file)
@@ -71,29 +71,35 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.76 2011/01/16 16:10:59 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.85 2011/04/03 19:24:58 jberndt Exp $";
 static const char *IdHdr = ID_PROPAGATE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex),
-LocalTerrainRadius(0), SeaLevelRadius(0), VehicleRadius(0)
+FGPropagate::FGPropagate(FGFDMExec* fdmex)
+  : FGModel(fdmex),
+    LocalTerrainRadius(0),
+    SeaLevelRadius(0),
+    VehicleRadius(0)
 {
   Debug(0);
   Name = "FGPropagate";
   gravType = gtWGS84;
  
-  vPQRdot.InitMatrix();
+  vPQRidot.InitMatrix();
   vQtrndot = FGQuaternion(0,0,0);
-  vUVWdot.InitMatrix();
+  vUVWidot.InitMatrix();
   vInertialVelocity.InitMatrix();
 
-  integrator_rotational_rate = eAdamsBashforth2;
-  integrator_translational_rate = eTrapezoidal;
-  integrator_rotational_position = eAdamsBashforth2;
-  integrator_translational_position = eTrapezoidal;
+  /// These define the indices use to select the various integrators.
+  // eNone = 0, eRectEuler, eTrapezoidal, eAdamsBashforth2, eAdamsBashforth3, eAdamsBashforth4};
+
+  integrator_rotational_rate = eRectEuler;
+  integrator_translational_rate = eAdamsBashforth2;
+  integrator_rotational_position = eRectEuler;
+  integrator_translational_position = eAdamsBashforth3;
 
   VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
   VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
@@ -124,9 +130,9 @@ bool FGPropagate::InitModel(void)
   VState.vLocation.SetEllipse(FDMExec->GetInertial()->GetSemimajor(), FDMExec->GetInertial()->GetSemiminor());
   vOmegaEarth = FGColumnVector3( 0.0, 0.0, FDMExec->GetInertial()->omega() ); // Earth rotation vector
 
-  vPQRdot.InitMatrix();
+  vPQRidot.InitMatrix();
   vQtrndot = FGQuaternion(0,0,0);
-  vUVWdot.InitMatrix();
+  vUVWidot.InitMatrix();
   vInertialVelocity.InitMatrix();
 
   VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
@@ -189,23 +195,13 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
   VehicleRadius = GetRadius();
   double radInv = 1.0/VehicleRadius;
 
-  // Refer to Stevens and Lewis, 1.5-14a, pg. 49.
-  // This is the rotation rate of the "Local" frame, expressed in the local frame.
-
-  FGColumnVector3 vOmegaLocal = FGColumnVector3(
-     radInv*vVel(eEast),
-    -radInv*vVel(eNorth),
-    -radInv*vVel(eEast)*VState.vLocation.GetTanLatitude() );
-
   // Set the angular velocities of the body frame relative to the ECEF frame,
-  // expressed in the body frame. Effectively, this is:
-  //   w_b/e = w_b/l + w_l/e
+  // expressed in the body frame.
   VState.vPQR = FGColumnVector3( FGIC->GetPRadpsIC(),
                                  FGIC->GetQRadpsIC(),
-                                 FGIC->GetRRadpsIC() ) + Tl2b*vOmegaLocal;
+                                 FGIC->GetRRadpsIC() );
 
   VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
-  VState.vPQRi_i = Tb2i * VState.vPQRi;
 
   // Make an initial run and set past values
   InitializeDerivatives();
@@ -245,11 +241,10 @@ bool FGPropagate::Run(void)
   CalculateUVWdot();           // Translational rate derivative
   ResolveFrictionForces(dt);   // Update rate derivatives with friction forces
   CalculateQuatdot();          // Angular orientation derivative
-  CalculateUVW();              // Translational position derivative (velocities are integrated in the inertial frame)
 
   // Propagate rotational / translational velocity, angular /translational position, respectively.
 
-  Integrate(VState.vPQRi_i,           vPQRidot,          VState.dqPQRidot,          dt, integrator_rotational_rate); // ECI  integration
+  Integrate(VState.vPQRi,             vPQRidot,          VState.dqPQRidot,          dt, integrator_rotational_rate);
   Integrate(VState.qAttitudeECI,      vQtrndot,          VState.dqQtrndot,          dt, integrator_rotational_position);
   Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
   Integrate(VState.vInertialVelocity, vUVWidot,          VState.dqUVWidot,          dt, integrator_translational_rate);
@@ -278,12 +273,13 @@ bool FGPropagate::Run(void)
   //    orientation quaternion and vLocation vector.
   UpdateBodyMatrices();
 
+  CalculateUVW();              // Translational position derivative (velocities are integrated in the inertial frame)
+
   // Set auxililary state variables
   RecomputeLocalTerrainRadius();
 
   VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet
 
-  VState.vPQRi = Ti2b * VState.vPQRi_i;
   VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
 
   VState.qAttitudeLocal = Tl2b.GetQuaternion();
@@ -321,8 +317,8 @@ void FGPropagate::CalculatePQRdot(void)
   // moments and the total inertial angular velocity expressed in the body
   // frame.
 
-  vPQRdot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi));
-  vPQRidot = Tb2i * vPQRdot;
+  vPQRidot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi));
+  vPQRdot = vPQRidot - VState.vPQRi * (Ti2b * vOmegaEarth);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -605,7 +601,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
   vUVWdot += invMass * Fc;
   vUVWidot += invMass * Tb2i * Fc;
   vPQRdot += Jinv * Mc;
-  vPQRidot += Tb2i* Jinv * Mc;
+  vPQRidot += Jinv * Mc;
 
   // Save the value of the Lagrange multipliers to accelerate the convergence
   // of the Gauss-Seidel algorithm at next iteration.
@@ -658,8 +654,7 @@ void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) {
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGPropagate::SetInertialRates(FGColumnVector3 vRates) {
-  VState.vPQRi_i = vRates;
-  VState.vPQRi = Ti2b * VState.vPQRi_i;
+  VState.vPQRi = Ti2b * vRates;
   VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
 }
 
@@ -681,7 +676,7 @@ void FGPropagate::InitializeDerivatives(void)
   VState.dqQtrndot.clear();
   for (int i=0; i<4; i++) {
     VState.dqPQRidot.push_front(vPQRidot);
-    VState.dqUVWidot.push_front(vUVWdot);
+    VState.dqUVWidot.push_front(vUVWidot);
     VState.dqInertialVelocity.push_front(VState.vInertialVelocity);
     VState.dqQtrndot.push_front(vQtrndot);
   }
@@ -739,7 +734,6 @@ void FGPropagate::SetVState(const VehicleState& vstate)
   vVel = Tb2l * VState.vUVW;
   VState.vPQR = vstate.vPQR;
   VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
-  VState.vPQRi_i = Tb2i * VState.vPQRi;
   VState.vInertialPosition = vstate.vInertialPosition;
 
   InitializeDerivatives();
index 107b3989b8e6f212ef22cd3c9fba92a93233dc11..26b2ad73e189d47a0416a4ae6c938b7673abc252 100644 (file)
@@ -49,7 +49,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $"
+#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -102,7 +102,7 @@ CLASS DOCUMENTATION
     @endcode
 
     @author Jon S. Berndt, Mathias Froehlich
-    @version $Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $
+    @version $Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -135,11 +135,6 @@ public:
         units rad/sec */
     FGColumnVector3 vPQRi;
 
-    /** The angular velocity vector for the vehicle body frame relative to the
-        ECI frame, expressed in the ECI frame.
-        units rad/sec */
-    FGColumnVector3 vPQRi_i;
-
     /** The current orientation of the vehicle, that is, the orientation of the
         body frame relative to the local, NED frame. */
     FGQuaternion qAttitudeLocal;
@@ -338,6 +333,10 @@ public:
   */
   const FGColumnVector3& GetInertialPosition(void) const { return VState.vInertialPosition; }
 
+  /** Calculates and retrieves the velocity vector relative to the earth centered earth fixed (ECEF) frame.
+  */
+  const FGColumnVector3 GetECEFVelocity(void) const {return Tb2ec * VState.vUVW; }
+
   /** Returns the current altitude above sea level.
       This function returns the altitude above sea level.
       units ft
@@ -581,8 +580,8 @@ public:
   void RecomputeLocalTerrainRadius(void);
 
   void NudgeBodyLocation(FGColumnVector3 deltaLoc) {
-    vDeltaXYZEC = Tb2ec*deltaLoc;
-    VState.vLocation -= vDeltaXYZEC;
+    VState.vInertialPosition -= Tb2i*deltaLoc;
+    VState.vLocation -= Tb2ec*deltaLoc;
   }
 
   struct LagrangeMultiplier {
@@ -602,8 +601,7 @@ private:
   struct VehicleState VState;
 
   FGColumnVector3 vVel;
-  FGColumnVector3 vPQRdot;
-  FGColumnVector3 vPQRidot;
+  FGColumnVector3 vPQRdot, vPQRidot;
   FGColumnVector3 vUVWdot, vUVWidot;
   FGColumnVector3 vInertialVelocity;
   FGColumnVector3 vLocation;
index 05a2da4c415d3bd95dcd60db1695dfcbabd09467..da82acf5103aac6884c20e1e9e7da87428b59565 100644 (file)
@@ -65,7 +65,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.43 2010/11/18 12:38:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.45 2011/02/13 00:42:45 jberndt Exp $";
 static const char *IdHdr = ID_PROPULSION;
 
 extern short debug_lvl;
@@ -194,14 +194,16 @@ bool FGPropulsion::GetSteadyState(void)
   double currentThrust = 0, lastThrust = -1;
   int steady_count = 0, j = 0;
   bool steady = false;
+  bool TrimMode = FDMExec->GetTrimStatus();
 
   vForces.InitMatrix();
   vMoments.InitMatrix();
 
   if (!FGModel::Run()) {
+    FDMExec->SetTrimStatus(true);
+
     for (unsigned int i=0; i<numEngines; i++) {
 //      cout << "  Finding steady state for engine " << i << endl;
-      Engines[i]->SetTrimMode(true);
       steady=false;
       steady_count=0;
       j=0;
@@ -225,9 +227,10 @@ bool FGPropulsion::GetSteadyState(void)
 //      }
       vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
       vMoments += Engines[i]->GetMoments();     // sum body frame moments
-      Engines[i]->SetTrimMode(false);
     }
 
+    FDMExec->SetTrimStatus(TrimMode);
+
     return false;
   } else {
     return true;
@@ -648,13 +651,13 @@ void FGPropulsion::bind(void)
   IsBound = true;
   PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, false);
   if (HaveTurbineEngine) {
-    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  true);
-    PropertyManager->Tie("propulsion/cutoff_cmd", this,  (iPMF)0, &FGPropulsion::SetCutoff,   true);
+    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  false);
+    PropertyManager->Tie("propulsion/cutoff_cmd", this,  (iPMF)0, &FGPropulsion::SetCutoff,   false);
   }
 
   if (HavePistonEngine) {
-    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  true);
-    PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, true);
+    PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  false);
+    PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, false);
   }
 
   PropertyManager->Tie("propulsion/active_engine", this, (iPMF)&FGPropulsion::GetActiveEngine,
index 4c58bebfd56603420861464450465fa87fc6891b..bfbd25920adec52d67bb604ef03a2d9760ac8ba5 100644 (file)
@@ -43,7 +43,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGActuator.cpp,v 1.14 2009/10/24 22:59:30 jberndt Exp $";
+static const char *IdSrc = "$Id: FGActuator.cpp,v 1.17 2011/02/13 00:42:45 jberndt Exp $";
 static const char *IdHdr = ID_ACTUATOR;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -114,10 +114,12 @@ bool FGActuator::Run(void )
                   // the Input will be further processed and the eventual Output
                   // will be overwritten from this perfect value.
 
-  if (lag != 0.0)              Lag();        // models actuator lag
-  if (rate_limit != 0)         RateLimit();  // limit the actuator rate
+  if (!fcs->GetTrimStatus()) {
+    if (lag != 0.0)              Lag();        // models actuator lag
+    if (rate_limit != 0)         RateLimit();  // limit the actuator rate
+  }
   if (deadband_width != 0.0)   Deadband();
-  if (hysteresis_width != 0.0) Hysteresis();
+  if (!fcs->GetTrimStatus() && hysteresis_width != 0.0) Hysteresis();
   if (bias != 0.0)             Bias();       // models a finite bias
 
   if (fail_stuck) Output = PreviousOutput;
@@ -187,6 +189,18 @@ void FGActuator::RateLimit(void)
 
 void FGActuator::Deadband(void)
 {
+  // Note: this function acts cumulatively on the "Output" parameter. So, "Output"
+  // is - for the purposes of this Deadband method - really the input to the
+  // method.
+  double input = Output;
+
+  if (input < -deadband_width/2.0) {
+    Output = (input + deadband_width/2.0);
+  } else if (input > deadband_width/2.0) {
+    Output = (input - deadband_width/2.0);
+  } else {
+    Output = 0.0;
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -232,9 +246,9 @@ void FGActuator::Debug(int from)
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
       if (InputSigns[0] < 0)
-        cout << "      INPUT: -" << InputNodes[0]->getName() << endl;
+        cout << "      INPUT: -" << InputNames[0] << endl;
       else
-        cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+        cout << "      INPUT: " << InputNames[0] << endl;
 
       if (IsOutput) {
         for (unsigned int i=0; i<OutputNodes.size(); i++)
index 0158b63560a36b867b7b6349a7a5501332287278..361afb66a1bf48848f3d4f3536cee60e9189ea5f 100644 (file)
@@ -142,7 +142,7 @@ void FGDeadBand::Debug(int from)
 
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
-      cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+      cout << "      INPUT: " << InputNodes[0]->GetName() << endl;
       if (WidthPropertyNode != 0) {
         cout << "      DEADBAND WIDTH: " << WidthPropertyNode->GetName() << endl;
       } else {
index 6cdf9ab8334ab381cb00c91f759369817637b4bb..4ea969774b6dbaef83a011d1af832abd5b773efd 100644 (file)
@@ -40,6 +40,7 @@ INCLUDES
 #include "FGFCSComponent.h"
 #include "input_output/FGPropertyManager.h"
 #include "input_output/FGXMLElement.h"
+#include "math/FGPropertyValue.h"
 #include <iostream>
 #include <cstdlib>
 
@@ -47,7 +48,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.29 2010/09/07 00:40:03 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.30 2011/04/05 20:20:21 andgi Exp $";
 static const char *IdHdr = ID_FCSCOMPONENT;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -111,8 +112,6 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
 
   Name = element->GetAttributeValue("name");
 
-  FGPropertyManager *tmp=0;
-
   input_element = element->FindElement("input");
   while (input_element) {
     input = input_element->GetDataLine();
@@ -122,14 +121,14 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
     } else {
       InputSigns.push_back( 1.0);
     }
+    FGPropertyManager* node = 0L;
     if (PropertyManager->HasNode(input)) {
-      tmp = PropertyManager->GetNode(input);
+      node = PropertyManager->GetNode(input);
+      InputNodes.push_back(new FGPropertyValue( node ));
     } else {
-      tmp = 0L;
-      // cerr << fgcyan << "In component: " + Name + " property "
-      //      + input + " is initially undefined." << reset << endl;
+      InputNodes.push_back(new FGPropertyValue( input,
+                                                PropertyManager ));
     }
-    InputNodes.push_back( tmp );
     InputNames.push_back( input );
 
     input_element = element->FindNextElement("input");
@@ -238,24 +237,6 @@ void FGFCSComponent::Clip(void)
   }
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCSComponent::LateBind(void)
-{
-  FGPropertyManager* node = 0L;
-
-  for (unsigned int i=0; i<InputNodes.size(); i++) {
-    if (!InputNodes[i]) {
-      if (PropertyManager->HasNode(InputNames[i])) {
-        node = PropertyManager->GetNode(InputNames[i]);
-        InputNodes[i] = node;
-      } else {
-        throw(InputNames[i]);
-      }
-    }
-  }
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //
 // The old way of naming FCS components allowed upper or lower case, spaces, etc.
index 7889cd948a243b05ca40ee82381aef325bc915b9..7ad58de0a00873a44dc1165344f6c47bbf7750b2 100644 (file)
@@ -38,6 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGJSBBase.h"
+#include "math/FGParameter.h"
 #include <string>
 #include <vector>
 
@@ -45,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.17 2010/08/21 22:56:11 jberndt Exp $"
+#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -80,7 +81,7 @@ CLASS DOCUMENTATION
     - FGActuator
 
     @author Jon S. Berndt
-    @version $Id: FGFCSComponent.h,v 1.17 2010/08/21 22:56:11 jberndt Exp $
+    @version $Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $
     @see Documentation for the FGFCS class, and for the configuration file class
 */
 
@@ -98,7 +99,6 @@ public:
 
   virtual bool Run(void);
   virtual void SetOutput(void);
-  void LateBind(void);
   double GetOutput (void) const {return Output;}
   std::string GetName(void) const {return Name;}
   std::string GetType(void) const { return Type; }
@@ -111,7 +111,7 @@ protected:
   std::vector <FGPropertyManager*> OutputNodes;
   FGPropertyManager* ClipMinPropertyNode;
   FGPropertyManager* ClipMaxPropertyNode;
-  std::vector <FGPropertyManager*> InputNodes;
+  std::vector <FGParameter*> InputNodes;
   std::vector <std::string> InputNames;
   std::vector <float> InputSigns;
   std::vector <double> output_array;
index c6a352f3b7d01ed7c35dcb9bc014fbf4dd5588d9..a9143f42ae9d718a71a1ef12ba32a8543648c0a8 100644 (file)
@@ -121,7 +121,7 @@ void FGFCSFunction::Debug(int from)
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
       if (InputNodes.size()>0)
-        cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+        cout << "      INPUT: " << InputNodes[0]->GetName() << endl;
 //    cout << "      Function: " << endl;
       if (IsOutput) {
         for (unsigned int i=0; i<OutputNodes.size(); i++)
index 2aab6e2b80d06844fc11f420d939a914c98db86c..54739e837236b6c08f3d2c56c8eb349367dda039 100644 (file)
@@ -259,7 +259,7 @@ void FGFilter::Debug(int from)
 
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
-      cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+      cout << "      INPUT: " << InputNodes[0]->GetName() << endl;
         switch (FilterType) {
         case eLag:
           if (PropertySign[1] < 0.0) sgn="-";
index e52cd37e6dd830b3974c5f63c728337fb32e3e4d..fac82ab619a879f523b591b1a8062e10d46cbee2 100644 (file)
@@ -209,9 +209,9 @@ void FGGain::Debug(int from)
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
       if (InputSigns[0] < 0)
-        cout << "      INPUT: -" << InputNodes[0]->getName() << endl;
+        cout << "      INPUT: -" << InputNodes[0]->GetName() << endl;
       else
-        cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+        cout << "      INPUT: " << InputNodes[0]->GetName() << endl;
 
       if (GainPropertyNode != 0) {
         cout << "      GAIN: " << GainPropertyNode->GetName() << endl;
index 525fcee377cdbf9a6a2ef124f7ecf0c47ead5a51..4a597f7b479ab51b55537e1f37a68d23aa0aebb4 100644 (file)
@@ -188,7 +188,7 @@ void FGKinemat::Debug(int from)
 
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
-      cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+      cout << "      INPUT: " << InputNodes[0]->GetName() << endl;
       cout << "      DETENTS: " << NumDetents << endl;
       for (int i=0;i<NumDetents;i++) {
         cout << "        " << Detents[i] << " " << TransitionTimes[i] << endl;
index ac265b8ff991275b7cff7e2561a3dc5ce99b44dc..6556ecdb7637dba7abd16189d9dab1705b3970e7 100644 (file)
@@ -189,9 +189,9 @@ void FGPID::Debug(int from)
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
       if (InputSigns[0] < 0)
-        cout << "      INPUT: -" << InputNodes[0]->getName() << endl;
+        cout << "      INPUT: -" << InputNodes[0]->GetName() << endl;
       else
-        cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+        cout << "      INPUT: " << InputNodes[0]->GetName() << endl;
 
       if (IsOutput) {
         for (unsigned int i=0; i<OutputNodes.size(); i++)
index 1f46dc9540a9679da8acb35a3c1b3c072ffde525..60b5f955a0aa8ea6cac1ea632a6eff159c1c5b28 100644 (file)
@@ -293,9 +293,9 @@ void FGSensor::Debug(int from)
     if (from == 0) { // Constructor
       if (InputSigns.size() > 0) {
         if (InputSigns[0] < 0)
-          cout << "      INPUT: -" << InputNodes[0]->getName() << endl;
+          cout << "      INPUT: -" << InputNodes[0]->GetName() << endl;
         else
-          cout << "      INPUT: " << InputNodes[0]->getName() << endl;
+          cout << "      INPUT: " << InputNodes[0]->GetName() << endl;
       }
       if (bits != 0) {
         if (quant_property.empty())
index 4e68ea7ffc2a5cefe08df67ca1cc5a6ef8b9e7bf..cea9f583e3f201d2ca6d103fa5947352109df4cc 100644 (file)
@@ -69,7 +69,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.19 2009/10/24 22:59:30 jberndt Exp $";
+static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.20 2011/04/05 20:20:21 andgi Exp $";
 static const char *IdHdr = ID_SWITCH;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -135,7 +135,13 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
           } else {
             current_test->sign = 1.0;
           }
-          current_test->OutputProp = PropertyManager->GetNode(value);
+          FGPropertyManager *node = PropertyManager->GetNode(value, false);
+          if (node) {
+            current_test->OutputProp = new FGPropertyValue(node);
+          } else {
+            current_test->OutputProp = new FGPropertyValue(value,
+                                                           PropertyManager);
+          }
         }
       }
     }
@@ -151,6 +157,7 @@ FGSwitch::~FGSwitch()
 {
   for (unsigned int i=0; i<tests.size(); i++) {
     for (unsigned int j=0; j<tests[i]->conditions.size(); j++) delete tests[i]->conditions[j];
+    delete tests[i]->OutputProp;
     delete tests[i];
   }
 
index a230aef7e5a2fadc1e5bd7ef35cb823e6c0ba4dc..cca141b0f0d43690646360de786ca5155692f9ec 100644 (file)
@@ -40,12 +40,13 @@ INCLUDES
 #include "FGFCSComponent.h"
 #include "input_output/FGXMLElement.h"
 #include "math/FGCondition.h"
+#include "math/FGPropertyValue.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_SWITCH "$Id: FGSwitch.h,v 1.13 2009/10/02 10:30:09 jberndt Exp $"
+#define ID_SWITCH "$Id: FGSwitch.h,v 1.14 2011/04/05 20:20:21 andgi Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -124,7 +125,7 @@ ap/attitude_hold takes the value 1), the value of the switch component will be
 whatever value fcs/roll-ap-error-summer is.
 
 @author Jon S. Berndt
-@version $Id: FGSwitch.h,v 1.13 2009/10/02 10:30:09 jberndt Exp $
+@version $Id: FGSwitch.h,v 1.14 2011/04/05 20:20:21 andgi Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -156,12 +157,12 @@ private:
     vector <FGCondition*> conditions;
     eLogic Logic;
     double OutputVal;
-    FGPropertyManager *OutputProp;
+    FGPropertyValue *OutputProp;
     float sign;
 
     double GetValue(void) {
       if (OutputProp == 0L) return OutputVal;
-      else                  return OutputProp->getDoubleValue()*sign;
+      else                  return OutputProp->GetValue()*sign;
     }
 
     test(void) { // constructor for the test structure
index 1138d820cceed7fe97b849229c8057af6eb1f8d9..cbcb9220a4decf33e47c3d9ff2ba76d361d26186 100644 (file)
@@ -50,7 +50,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGElectric.cpp,v 1.9 2010/08/21 17:13:48 jberndt Exp $";
+static const char *IdSrc = "$Id: FGElectric.cpp,v 1.10 2011/03/10 01:35:25 dpculp Exp $";
 static const char *IdHdr = ID_ELECTRIC;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -92,12 +92,17 @@ void FGElectric::Calculate(void)
   RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
 
   HP = PowerWatts * Throttle / hptowatts;
+  
+  Thruster->Calculate(HP * hptoftlbssec);
 
-  PowerAvailable = (HP * hptoftlbssec) - Thruster->GetPowerRequired();
+  RunPostFunctions();
+}
 
-  Thruster->Calculate(PowerAvailable);
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-  RunPostFunctions();
+double FGElectric::CalcFuelNeed(void)
+{
+  return 0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -174,10 +179,4 @@ void FGElectric::Debug(int from)
   }
 }
 
-double
-FGElectric::CalcFuelNeed(void)
-{
-  return 0;
-}
-
 } // namespace JSBSim
index 268522956219d2a10302369e58930c184c1cb777..28c703deecaf374de2bb08354e1233d9175db9eb 100644 (file)
@@ -45,7 +45,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ELECTRIC "$Id: FGElectric.h,v 1.9 2010/08/21 18:07:59 jberndt Exp $";
+#define ID_ELECTRIC "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $";
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -65,7 +65,7 @@ CLASS DOCUMENTATION
     there is no battery model available, so this motor does not consume any
     energy.  There is no internal friction.
     @author David Culp
-    @version "$Id: FGElectric.h,v 1.9 2010/08/21 18:07:59 jberndt Exp $"
+    @version "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $"
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -81,7 +81,7 @@ public:
   ~FGElectric();
 
   void Calculate(void);
-  double GetPowerAvailable(void) {return PowerAvailable;}
+  double GetPowerAvailable(void) {return (HP * hptoftlbssec);}
   double getRPM(void) {return RPM;}
   std::string GetEngineLabels(const std::string& delimiter);
   std::string GetEngineValues(const std::string& delimiter);
@@ -91,7 +91,6 @@ private:
   double CalcFuelNeed(void);
 
   double BrakeHorsePower;
-  double PowerAvailable;
 
   // timestep
   double dt;
@@ -101,7 +100,7 @@ private:
 
   double PowerWatts;         // maximum engine power
   double RPM;                // revolutions per minute
-  double HP;
+  double HP;                 // engine output, in horsepower
 
   void Debug(int from);
 };
index e48e274266e6f95becab1050813442bcf8341f15..707d425e4c7433aa72a51a4f71d8f2a0057629e1 100644 (file)
@@ -54,7 +54,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGEngine.cpp,v 1.40 2010/10/15 11:32:41 jberndt Exp $";
+static const char *IdSrc = "$Id: FGEngine.cpp,v 1.42 2011/03/03 12:16:26 jberndt Exp $";
 static const char *IdHdr = ID_ENGINE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -151,6 +151,8 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
   PropertyManager->Tie( property_name.c_str(), Thruster, &FGThruster::GetThrust);
   property_name = base_property_name + "/fuel-flow-rate-pps";
   PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelFlowRate);
+  property_name = base_property_name + "/fuel-used-lbs";
+  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelUsedLbs);
 
   PostLoad(engine_element, PropertyManager, to_string(EngineNumber));
 
@@ -177,11 +179,11 @@ void FGEngine::ResetToIC(void)
   FuelExpended = 0.0;
   Starved = Running = Cranking = false;
   PctPower = 0.0;
-  TrimMode = false;
   FuelFlow_gph = 0.0;
   FuelFlow_pph = 0.0;
   FuelFlowRate = 0.0;
   FuelFreeze = false;
+  FuelUsedLbs = 0.0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -194,7 +196,7 @@ void FGEngine::ResetToIC(void)
 void FGEngine::ConsumeFuel(void)
 {
   if (FuelFreeze) return;
-  if (TrimMode) return;
+  if (FDMExec->GetTrimStatus()) return;
 
   unsigned int i;
   double Fshortage, FuelNeeded;
@@ -240,6 +242,7 @@ void FGEngine::ConsumeFuel(void)
     Tank = Propulsion->GetTank(FeedList[i]);
     Tank->Drain(FuelNeeded); 
   }
+  FuelUsedLbs += FuelToBurn;
 
 }
 
index c25eebfc0a4abdca19e431987e1ebe11bc49cc8a..03b774d94301d4ab91aa884746c317011d2eefde 100644 (file)
@@ -55,7 +55,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ENGINE "$Id: FGEngine.h,v 1.21 2010/08/21 17:13:48 jberndt Exp $"
+#define ID_ENGINE "$Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -118,7 +118,7 @@ CLASS DOCUMENTATION
        documentation for engine and thruster classes.
 </pre>     
     @author Jon S. Berndt
-    @version $Id: FGEngine.h,v 1.21 2010/08/21 17:13:48 jberndt Exp $
+    @version $Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -146,6 +146,7 @@ public:
   virtual double getFuelFlow_gph () const {return FuelFlow_gph;}
   virtual double getFuelFlow_pph () const {return FuelFlow_pph;}
   virtual double GetFuelFlowRate(void) const {return FuelFlowRate;}
+  virtual double GetFuelUsedLbs(void) const {return FuelUsedLbs;}
   virtual bool   GetStarved(void) { return Starved; }
   virtual bool   GetRunning(void) const { return Running; }
   virtual bool   GetCranking(void) { return Cranking; }
@@ -173,9 +174,6 @@ public:
 
   virtual double GetPowerAvailable(void) {return 0.0;};
 
-  virtual bool GetTrimMode(void) {return TrimMode;}
-  virtual void SetTrimMode(bool state) {TrimMode = state;}
-
   virtual FGColumnVector3& GetBodyForces(void);
   virtual FGColumnVector3& GetMoments(void);
 
@@ -219,12 +217,12 @@ protected:
   bool  Starved;
   bool  Running;
   bool  Cranking;
-  bool  TrimMode;
   bool  FuelFreeze;
 
   double FuelFlow_gph;
   double FuelFlow_pph;
   double FuelDensity;
+  double FuelUsedLbs;
 
   FGFDMExec*      FDMExec;
   FGAtmosphere*   Atmosphere;
index 0180d18e404b15f73aec103a04550d1822ce50c2..0bebb1772ab3579e56d902faef47c10e89b2d6ef 100644 (file)
@@ -53,7 +53,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGForce.cpp,v 1.14 2009/10/24 22:59:30 jberndt Exp $";
+static const char *IdSrc = "$Id: FGForce.cpp,v 1.15 2011/02/17 00:20:52 jberndt Exp $";
 static const char *IdHdr = ID_FORCE;
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -62,9 +62,20 @@ FGForce::FGForce(FGFDMExec *FDMExec) :
                  fdmex(FDMExec),
                  ttype(tNone)
 {
-  mT(1,1) = 1; //identity matrix
-  mT(2,2) = 1;
-  mT(3,3) = 1;
+  vFn.InitMatrix();
+  vMn.InitMatrix();
+  vH.InitMatrix();
+  vOrient.InitMatrix();
+  vXYZn.InitMatrix();
+  vActingXYZn.InitMatrix();
+
+  vFb.InitMatrix();
+  vM.InitMatrix();
+  vDXYZ.InitMatrix();
+
+  mT.InitMatrix(1., 0., 0.,
+                0., 1., 0.,
+                0., 0., 1.);
 
   Debug(0);
 }
index 522a0b2fea57b10e41b7345b1fb6833559cae5c4..7726306bfba3ad20c862833100f76f199bd917f2 100644 (file)
@@ -53,7 +53,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPiston.cpp,v 1.54 2010/11/30 12:17:10 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPiston.cpp,v 1.55 2011/03/10 01:35:25 dpculp Exp $";
 static const char *IdHdr = ID_PISTON;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -442,8 +442,7 @@ void FGPiston::Calculate(void)
     ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
   }
 
-  PowerAvailable = (HP * hptoftlbssec) - Thruster->GetPowerRequired();
-  Thruster->Calculate(PowerAvailable);
+  Thruster->Calculate(HP * hptoftlbssec);
 
   RunPostFunctions();
 }
@@ -872,7 +871,7 @@ string FGPiston::GetEngineLabels(const string& delimiter)
 {
   std::ostringstream buf;
 
-  buf << Name << " Power Available (engine " << EngineNumber << " in HP)" << delimiter
+  buf << Name << " Power Available (engine " << EngineNumber << " in ft-lbs/sec)" << delimiter
       << Name << " HP (engine " << EngineNumber << ")" << delimiter
       << Name << " equivalent ratio (engine " << EngineNumber << ")" << delimiter
       << Name << " MAP (engine " << EngineNumber << " in inHg)" << delimiter
@@ -887,7 +886,7 @@ string FGPiston::GetEngineValues(const string& delimiter)
 {
   std::ostringstream buf;
 
-  buf << PowerAvailable << delimiter << HP << delimiter
+  buf << (HP * hptoftlbssec) << delimiter << HP << delimiter
       << equivalence_ratio << delimiter << ManifoldPressure_inHg << delimiter
       << Thruster->GetThrusterValues(EngineNumber, delimiter);
 
index 510c6e6f2c185a15a531221f5abfc645086256cf..a8019e5aa6a79d9f169a4b7f7655081d192fbe99 100644 (file)
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PISTON "$Id: FGPiston.h,v 1.25 2010/11/30 12:17:10 jberndt Exp $";
+#define ID_PISTON "$Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $";
 #define FG_MAX_BOOST_SPEEDS 3
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -182,7 +182,7 @@ CLASS DOCUMENTATION
     @author Dave Luff (engine operational code)
     @author David Megginson (initial porting and additional code)
     @author Ron Jensen (additional engine code)
-    @version $Id: FGPiston.h,v 1.25 2010/11/30 12:17:10 jberndt Exp $
+    @version $Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -201,7 +201,7 @@ public:
   std::string GetEngineValues(const std::string& delimiter);
 
   void Calculate(void);
-  double GetPowerAvailable(void) const {return PowerAvailable;}
+  double GetPowerAvailable(void) const {return (HP * hptoftlbssec);}
   double CalcFuelNeed(void);
 
   void ResetToIC(void);
@@ -227,7 +227,6 @@ private:
   double FMEP;
   double FMEPDynamic;
   double FMEPStatic;
-  double PowerAvailable;
 
   // timestep
   double dt;
index f83f961b8e7aea224b62c5dab8fb1e1cd62ae11e..d5ed3813d3bc29b35198e6bea566b99b91be81f1 100644 (file)
@@ -48,7 +48,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.32 2010/10/21 03:27:40 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.33 2011/03/10 01:35:25 dpculp Exp $";
 static const char *IdHdr = ID_PROPELLER;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -185,23 +185,22 @@ FGPropeller::~FGPropeller()
 // We must be getting the aerodynamic velocity here, NOT the inertial velocity.
 // We need the velocity with respect to the wind.
 //
-// Note that PowerAvailable is the excess power available after the drag of the
-// propeller has been subtracted. At equilibrium, PowerAvailable will be zero -
-// indicating that the propeller will not accelerate or decelerate.
 // Remembering that Torque * omega = Power, we can derive the torque on the
 // propeller and its acceleration to give a new RPM. The current RPM will be
 // used to calculate thrust.
 //
 // Because RPM could be zero, we need to be creative about what RPM is stated as.
 
-double FGPropeller::Calculate(double PowerAvailable)
+double FGPropeller::Calculate(double EnginePower)
 {
-  double omega, alpha, beta;
+  double omega, alpha, beta, PowerAvailable;
 
   double Vel = fdmex->GetAuxiliary()->GetAeroUVW(eU);
   double rho = fdmex->GetAtmosphere()->GetDensity();
   double RPS = RPM/60.0;
 
+  PowerAvailable = EnginePower - GetPowerRequired();
+
   // Calculate helical tip Mach
   double Area = 0.25*Diameter*Diameter*M_PI;
   double Vtip = RPS * Diameter * M_PI;
index ea7953e1eabc8eba4c422104b02b3b63e7d3b932..3e9c3c259058467c09dec2cfb3219c0983a9d6a8 100644 (file)
@@ -45,7 +45,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPELLER "$Id: FGPropeller.h,v 1.16 2010/04/09 12:44:06 jberndt Exp $"
+#define ID_PROPELLER "$Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -141,7 +141,7 @@ CLASS DOCUMENTATION
     <li>Various NACA Technical Notes and Reports</li>
     </ul>
     @author Jon S. Berndt
-    @version $Id: FGPropeller.h,v 1.16 2010/04/09 12:44:06 jberndt Exp $
+    @version $Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $
     @see FGEngine
     @see FGThruster
 */
@@ -247,7 +247,7 @@ public:
       accelerate the prop. It could be negative, dictating that the propeller
       would be slowed.
       @return the thrust in pounds */
-  double Calculate(double PowerAvailable);
+  double Calculate(double EnginePower);
   FGColumnVector3 GetPFactor(void);
   string GetThrusterLabels(int id, string delimeter);
   string GetThrusterValues(int id, string delimeter);
index 3fef49616352fd5bf7b8dd73c62030074b2cd498..f8fb091cb6344653e5fb35cef2e903bad1cdef54 100644 (file)
@@ -49,7 +49,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGRocket.cpp,v 1.22 2010/12/30 13:35:09 jberndt Exp $";
+static const char *IdSrc = "$Id: FGRocket.cpp,v 1.23 2011/01/24 13:01:56 jberndt Exp $";
 static const char *IdHdr = ID_ROCKET;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -202,7 +202,7 @@ void FGRocket::ConsumeFuel(void)
   double Fshortage=0, Oshortage=0, TanksWithFuel=0, TanksWithOxidizer=0;
 
   if (FuelFreeze) return;
-  if (TrimMode) return;
+  if (FDMExec->GetTrimStatus()) return;
 
   // Count how many assigned tanks have fuel for this engine at this time.
   // If there is/are fuel tanks but no oxidizer tanks, this indicates
index 5c69728f293abc8326a5644f2e48a8c9f77c73fc..1ac58405ac759c3a925fcf311beccf143d5ce815 100644 (file)
@@ -34,6 +34,8 @@ HISTORY
 11/15/10  T.Kreitler treated flow solver bug, flow and torque calculations 
                      simplified, tiploss influence removed from flapping angles
 01/10/11  T.Kreitler changed to single rotor model
+03/06/11  T.Kreitler added brake, clutch, and experimental free-wheeling-unit,
+                     reasonable estimate for inflowlag
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 INCLUDES
@@ -56,7 +58,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGRotor.cpp,v 1.11 2011/01/17 22:09:59 jberndt Exp $";
+static const char *IdSrc = "$Id: FGRotor.cpp,v 1.12 2011/03/10 01:35:25 dpculp Exp $";
 static const char *IdHdr = ID_ROTOR;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -109,7 +111,11 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num)
 
   // control
   ControlMap(eMainCtrl),
-  CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0)
+  CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0),
+  BrakeCtrlNorm(0.0), MaxBrakePower(0.0),
+
+  // free-wheeling-unit (FWU)
+  FreeWheelPresent(0), FreeWheelThresh(0.0), FreeWheelTransmission(0.0)
 
 {
   FGColumnVector3 location(0.0, 0.0, 0.0), orientation(0.0, 0.0, 0.0);
@@ -190,6 +196,9 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num)
   // calculation would cause jumps too. 1Hz seems sufficient.
   damp_hagl = Filter(1.0,dt);
 
+  // avoid too abrupt changes in power transmission
+  FreeWheelLag = Filter(200.0,dt);
+
   // enable import-export
   BindModel();
 
@@ -248,7 +257,7 @@ double FGRotor::ConfigValue(Element* el, const string& ename, double default_val
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 // 1. read configuration and try to fill holes, ymmv
-// 2. calculate derived parameters and transforms
+// 2. calculate derived parameters
 void FGRotor::Configure(Element* rotor_element)
 {
 
@@ -279,22 +288,24 @@ void FGRotor::Configure(Element* rotor_element)
 
   estimate = sqr(BladeChord) * sqr(Radius - HingeOffset) * 0.57;
   BladeFlappingMoment = ConfigValueConv(rotor_element, "flappingmoment", estimate, "SLUG*FT2");   
-  BladeFlappingMoment = Constrain(0.001, BladeFlappingMoment, 1e9);
+  BladeFlappingMoment = Constrain(1.0e-6, BladeFlappingMoment, 1e9);
 
   // guess mass from moment of a thin stick, and multiply by the blades cg distance
   estimate = ( 3.0 * BladeFlappingMoment / sqr(Radius) ) * (0.45 * Radius) ;
   BladeMassMoment = ConfigValue(rotor_element, "massmoment", estimate); // unit is slug-ft
   BladeMassMoment = Constrain(0.001, BladeMassMoment, 1e9);
 
-  TipLossB = ConfigValue(rotor_element, "tiplossfactor", 1.0, silent);
-
   estimate = 1.1 * BladeFlappingMoment * BladeNum;
   PolarMoment = ConfigValueConv(rotor_element, "polarmoment", estimate, "SLUG*FT2");
-  PolarMoment = Constrain(0.001, PolarMoment, 1e9);
+  PolarMoment = Constrain(1e-6, PolarMoment, 1e9);
 
-  InflowLag = ConfigValue(rotor_element, "inflowlag", 0.2, yell); // fixme, depends on size
-  InflowLag = Constrain(1e-6, InflowLag, 2.0);
+  // "inflowlag" is treated further down.
 
+  TipLossB = ConfigValue(rotor_element, "tiplossfactor", 1.0, silent);
+
+  estimate = 0.01 * PolarMoment ; // guesses for huey, bo105 20-30hp
+  MaxBrakePower  = ConfigValueConv(rotor_element, "maxbrakepower", estimate, "HP");
+  MaxBrakePower *= hptoftlbssec;
 
   // ground effect
   if (rotor_element->FindElement("cgroundeffect")) {
@@ -309,6 +320,17 @@ void FGRotor::Configure(Element* rotor_element)
   GroundEffectExp = ConfigValue(rotor_element, "groundeffectexp", 0.0);
   GroundEffectShift = ConfigValueConv(rotor_element, "groundeffectshift", 0.0, "FT");
 
+  // handle optional free-wheeling-unit (FWU)
+  FreeWheelPresent = 0;
+  FreeWheelTransmission = 1.0;
+  if (rotor_element->FindElement("freewheelthresh")) {
+    FreeWheelThresh = rotor_element->FindElementValueAsNumber("freewheelthresh");
+    if (FreeWheelThresh > 1.0) {
+      FreeWheelPresent = 1;
+      FreeWheelTransmission = 0.0;
+    }
+  }
+
   // precalc often used powers
   R[0]=1.0; R[1]=Radius;   R[2]=R[1]*R[1]; R[3]=R[2]*R[1]; R[4]=R[3]*R[1];
   B[0]=1.0; B[1]=TipLossB; B[2]=B[1]*B[1]; B[3]=B[2]*B[1]; B[4]=B[3]*B[1];
@@ -317,6 +339,13 @@ void FGRotor::Configure(Element* rotor_element)
   LockNumberByRho = LiftCurveSlope * BladeChord * R[4] / BladeFlappingMoment;
   Solidity = BladeNum * BladeChord / (M_PI * Radius);
 
+  // estimate inflow lag, see /GE49/ eqn(1)
+  double omega_tmp = (NominalRPM/60.0)*2.0*M_PI;
+  estimate = 16.0/(LockNumberByRho*rho * omega_tmp ); // 16/(gamma*Omega)
+  // printf("# Est. InflowLag: %f\n", estimate);
+  InflowLag = ConfigValue(rotor_element, "inflowlag", estimate, yell);
+  InflowLag = Constrain(1.0e-6, InflowLag, 2.0);
+
   return;
 } // Configure
 
@@ -362,7 +391,7 @@ FGColumnVector3 FGRotor::fus_angvel_body2ca( const FGColumnVector3 &pqr)
   av_w_fus(eP)=   av_s_fus(eP)*cos(beta_orient) + av_s_fus(eQ)*sin(beta_orient);
   av_w_fus(eQ)= - av_s_fus(eP)*sin(beta_orient) + av_s_fus(eQ)*cos(beta_orient);
   av_w_fus(eR)=   av_s_fus(eR);
-         
+
   return av_w_fus;
 }
 
@@ -382,7 +411,7 @@ void FGRotor::calc_flow_and_thrust( double theta_0, double Uw, double Ww,
 
   double ct_over_sigma = 0.0;
   double c0, ct_l, ct_t0, ct_t1;
-  double mu2;  
+  double mu2;
 
   mu = Uw/(Omega*Radius); // /SH79/ eqn(24)
   mu2 = sqr(mu);
@@ -390,7 +419,7 @@ void FGRotor::calc_flow_and_thrust( double theta_0, double Uw, double Ww,
   ct_t0 = (1.0/3.0*B[3] + 1.0/2.0 * TipLossB*mu2 - 4.0/(9.0*M_PI) * mu*mu2 ) * theta_0;
   ct_t1 = (1.0/4.0*B[4] + 1.0/4.0 * B[2]*mu2) * BladeTwist;
 
-  ct_l  = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda; // first time  
+  ct_l  = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda; // first time
 
   c0 = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1) * Solidity;
   c0 = c0 / ( 2.0 * sqrt( sqr(mu) + sqr(lambda) ) + 1e-15);
@@ -473,7 +502,7 @@ void FGRotor::calc_flapping_angles(double theta_0, const FGColumnVector3 &pqr_fu
 
 void FGRotor::calc_drag_and_side_forces(double theta_0)
 {
-  double cy_over_sigma  ;
+  double cy_over_sigma;
   double t075 = theta_0 + 0.75 * BladeTwist;
 
   H_drag = Thrust * a_dw;
@@ -494,7 +523,7 @@ void FGRotor::calc_drag_and_side_forces(double theta_0)
 
 // Simplified version of /SH79/ eqn(36). Uses an estimate for blade drag
 // (a new config parameter to come...).
-// From "Bramwell's Helicopter Dynamics" Â­ second edition, eqn(3.43) and (3.44)
+// From "Bramwell's Helicopter Dynamics", second edition, eqn(3.43) and (3.44)
 
 void FGRotor::calc_torque(double theta_0)
 {
@@ -560,7 +589,7 @@ void FGRotor::CalcStatePart1(void)
   FGColumnVector3 vHub_ca, avFus_ca;
 
   double h_agl_ft, filtered_hagl = 0.0;
-  double ge_factor = 1.0;  
+  double ge_factor = 1.0;
 
   // fetch needed values from environment
   Vt = fdmex->GetAuxiliary()->GetVt(); // total vehicle velocity including wind
@@ -637,18 +666,52 @@ void FGRotor::CalcStatePart2(double PowerAvailable)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGRotor::GetPowerRequired(void)
-{
-  CalcStatePart1();
-  PowerRequired = Torque * Omega;
-  return PowerRequired;
+// Simulation of a free-wheeling-unit (FWU). Might need improvements.
+
+void FGRotor::calc_freewheel_state(double p_source, double p_load) {
+
+  // engine is off/detached, release.
+  if (p_source<1e-3) { 
+    FreeWheelTransmission = 0.0;
+    return;
+  }
+
+  // engine is driving the rotor, engage.
+  if (p_source >= p_load) {
+    FreeWheelTransmission = 1.0;
+    return;
+  }
+
+  // releases if engine is detached, but stays calm if
+  // the load changes due to rotor dynamics.
+  if (p_source > 0.0 && p_load/(p_source+0.1) > FreeWheelThresh ) {
+    FreeWheelTransmission = 0.0;
+    return;
+  }
+
+  return;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGRotor::Calculate(double PowerAvailable)
+double FGRotor::Calculate(double EnginePower)
 {
-  CalcStatePart2(PowerAvailable);
+  double FWmult = 1.0;
+  double DeltaPower;
+
+  CalcStatePart1();
+
+  PowerRequired = Torque * Omega + BrakeCtrlNorm * MaxBrakePower;
+
+  if (FreeWheelPresent) {
+    calc_freewheel_state(EnginePower * ClutchCtrlNorm, PowerRequired);
+    FWmult = FreeWheelLag.execute(FreeWheelTransmission);
+  }
+
+  DeltaPower = EnginePower * ClutchCtrlNorm * FWmult - PowerRequired;
+
+  CalcStatePart2(DeltaPower);
+
   return Thrust;
 }
 
@@ -702,7 +765,7 @@ bool FGRotor::BindModel(void)
 
   property_name = base_property_name + "/phi-downwash-rad";
   PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetPhiDW );
-  
+
   switch (ControlMap) {
     case eTailCtrl:
       property_name = base_property_name + "/antitorque-ctrl-rad";
@@ -725,6 +788,11 @@ bool FGRotor::BindModel(void)
       PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetLongitudinalCtrl, &FGRotor::SetLongitudinalCtrl);
   }
 
+  property_name = base_property_name + "/brake-ctrl-norm";
+  PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetBrakeCtrl, &FGRotor::SetBrakeCtrl);
+  property_name = base_property_name + "/free-wheel-transmission";
+  PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetFreeWheelTransmission);
+
   if (ExternalRPM) {
     if (RPMdefinition == -1) {
       property_name = base_property_name + "/x-rpm-dict";
@@ -826,6 +894,7 @@ void FGRotor::Debug(int from)
       cout << "      Tip Loss = " << TipLossB << endl;
       cout << "      Lock Number = " << LockNumberByRho * 0.002356 << " (SL)" << endl;
       cout << "      Solidity = " << Solidity << endl;
+      cout << "      Max Brake Power = " << MaxBrakePower/hptoftlbssec << " HP" << endl;
 
       switch (ControlMap) {
         case eTailCtrl:    ControlMapName = "Tail Rotor";   break;
@@ -834,6 +903,12 @@ void FGRotor::Debug(int from)
       }
       cout << "      Control Mapping = " << ControlMapName << endl;
 
+      if (FreeWheelPresent) {
+        cout << "      Free Wheel Threshold = " << FreeWheelThresh << endl;
+      } else {
+        cout << "      No FWU present" << endl;
+      }
+
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index 9892baa37f734192f16863ed5430babf04c1c795..02fbf92952caabd78118dd7ca2445fb9f37ec558 100644 (file)
@@ -27,6 +27,7 @@ HISTORY
 --------------------------------------------------------------------------------
 01/01/10  T.Kreitler test implementation
 01/10/11  T.Kreitler changed to single rotor model
+03/06/11  T.Kreitler added brake, clutch, and experimental free-wheeling-unit
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 SENTRY
@@ -45,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ROTOR "$Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $"
+#define ID_ROTOR "$Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -76,12 +77,15 @@ CLASS DOCUMENTATION
   <polarmoment unit="{MOMENT}"> {number} </polarmoment>
   <inflowlag> {number} </inflowlag>
   <tiplossfactor> {number} </tiplossfactor>
+  <maxbrakepower unit="{POWER}"> {number} </maxbrakepower>
 
   <controlmap> {MAIN|TAIL|TANDEM} </controlmap>
   <ExternalRPM> {number} </ExternalRPM>
 
   <groundeffectexp> {number} </groundeffectexp>
   <groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift>
+
+  <freewheelthresh> {number} </freewheelthresh>
 </rotor>
 
 //  LENGTH means any of the supported units, same for ANGLE and MOMENT.
@@ -108,10 +112,11 @@ CLASS DOCUMENTATION
     \<massmoment>         - Blade mass moment. Mass of a single blade times the blade's
                              cg-distance from the hub, optional.
     \<polarmoment>        - Moment of inertia for the whole rotor disk, optional.
-    \<inflowlag>          - Rotor inflow time constant, sec. Smaller values yield to
-                              quicker responses to control input (defaults to 0.2).
+    \<inflowlag>          - Rotor inflow time constant, sec. Smaller values yield to quicker
+                              responses (typical values for main rotor: 0.1 - 0.2 s).
     \<tiplossfactor>      - Tip-loss factor. The Blade fraction that produces lift.
                               Value usually ranges between 0.95 - 1.0, optional (B).
+    \<maxbrakepower>      - Rotor brake, 20-30 hp should work for a mid size helicopter.
 
     \<controlmap>         - Defines the control inputs used (see notes).
     \<ExternalRPM>        - Links the rotor to another rotor, or an user controllable property.
@@ -125,6 +130,10 @@ CLASS DOCUMENTATION
                             Omitting or setting to 0.0 disables the effect calculation.
     \<groundeffectshift>  - Further adjustment of ground effect, approx. hub height or slightly above. 
 
+    \<freewheelthresh>    - Ratio of thruster power to engine power. The FWU will release when above
+                              the threshold. The value shouldn't be too close to 1.0, 1.5 seems ok.
+                              0 disables this feature, which is also the default.
+
 </pre>
 
 <h3>Notes:</h3>  
@@ -165,8 +174,6 @@ CLASS DOCUMENTATION
 
   <h4>- Engine issues -</h4>
 
-    Currently the rotor can only be driven with piston and electrical engines. An adaption
-    for the turboprop engine might become available in the future.
     In order to keep the rotor speed constant, use of a RPM-Governor system is 
     encouraged (see examples).
 
@@ -188,11 +195,13 @@ CLASS DOCUMENTATION
     <dt>/AM50/</dt><dd>Amer, Kenneth B.,"Theory of Helicopter Damping in Pitch or Roll and a
               Comparison With Flight Measurements", NACA TN-2136, 1950.</dd>
     <dt>/TA77/</dt><dd>Talbot, Peter D., Corliss, Lloyd D., "A Mathematical Force and Moment
-              Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.</dd>   
+              Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.</dd> 
+    <dt>/GE49/</dt><dd>Gessow, Alfred, Amer, Kenneth B. "An Introduction to the Physical 
+              Aspects of Helicopter Stability", NACA TN-1982, 1949.</dd>  
     </dl>
 
     @author Thomas Kreitler
-    @version $Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $
+    @version $Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $
   */
 
 
@@ -216,14 +225,11 @@ public:
   /// Destructor for FGRotor
   ~FGRotor();
 
-  /** Returns the power required by the rotor. Well, to achieve this the rotor
-      is cycled through the whole machinery, yielding to a new state.
-      (hmm, sort of a huge side effect)
-  */
-  double GetPowerRequired(void);
+  /** Returns the power required by the rotor. */
+  double GetPowerRequired(void)const { return PowerRequired; }
 
   /** Returns the scalar thrust of the rotor, and adjusts the RPM value. */
-  double Calculate(double PowerAvailable);
+  double Calculate(double EnginePower);
 
 
   /// Retrieves the RPMs of the rotor.
@@ -257,6 +263,8 @@ public:
   double GetCT(void) const { return C_T; }
   /// Retrieves the torque
   double GetTorque(void) const { return Torque; }
+  /// Retrieves the state of the free-wheeling-unit (FWU).
+  double GetFreeWheelTransmission(void) const { return FreeWheelTransmission; }
   
   /// Downwash angle - currently only valid for a rotor that spins horizontally
   double GetThetaDW(void) const { return theta_downwash; }
@@ -269,6 +277,8 @@ public:
   double GetLateralCtrl(void) const { return LateralCtrl; }
   /// Retrieves the longitudinal control input in radians.
   double GetLongitudinalCtrl(void) const { return LongitudinalCtrl; }
+  /// Retrieves the normalized brake control input.
+  double GetBrakeCtrl(void) const { return BrakeCtrlNorm; }
 
   /// Sets the collective control input in radians.
   void SetCollectiveCtrl(double c) { CollectiveCtrl = c; }
@@ -276,6 +286,8 @@ public:
   void SetLateralCtrl(double c) { LateralCtrl = c; }
   /// Sets the longitudinal control input in radians.
   void SetLongitudinalCtrl(double c) { LongitudinalCtrl = c; }
+  /// Sets the normalized brake control input.
+  void SetBrakeCtrl(double c) { BrakeCtrlNorm = c; }
 
   // Stubs. Only main rotor RPM is returned
   string GetThrusterLabels(int id, string delimeter);
@@ -303,6 +315,8 @@ private:
   void calc_drag_and_side_forces(double theta_0);
   void calc_torque(double theta_0);
 
+  void calc_freewheel_state(double pwr_in, double pwr_out);
+
   // transformations
   FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr, 
                                    double a_ic = 0.0 , double b_ic = 0.0 );
@@ -380,6 +394,15 @@ private:
   double LateralCtrl;
   double LongitudinalCtrl;
 
+  double BrakeCtrlNorm, MaxBrakePower;
+
+  // free-wheeling-unit (FWU)
+  int    FreeWheelPresent;        // 'installed' or not
+  double FreeWheelThresh;         // when to release
+  Filter FreeWheelLag;
+  double FreeWheelTransmission;   // state, 0: free, 1:locked
+
+
 };
 
 }
index 5af8c1ddd50193ceb8b33b4f3a6542249bec4812..147aad5dabe57b8736da04622a5389c5c57b4a3e 100644 (file)
@@ -45,7 +45,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGThruster.cpp,v 1.13 2010/08/21 22:56:11 jberndt Exp $";
+static const char *IdSrc = "$Id: FGThruster.cpp,v 1.14 2011/03/10 01:35:25 dpculp Exp $";
 static const char *IdHdr = ID_THRUSTER;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -66,6 +66,7 @@ FGThruster::FGThruster(FGFDMExec *FDMExec, Element *el, int num ): FGForce(FDMEx
 
   GearRatio = 1.0;
   ReverserAngle = 0.0;
+  ClutchCtrlNorm = 1.0;
   EngineNum = num;
   PropertyManager = FDMExec->GetPropertyManager();
 
@@ -98,6 +99,13 @@ FGThruster::FGThruster(FGFDMExec *FDMExec, Element *el, int num ): FGForce(FDMEx
                                                           &FGThruster::SetReverserAngle);
   }
 
+  if (el->GetName() == "rotor") // At this time only a rotor can have a clutch.
+  {
+    property_name = base_property_name + "/clutch-ctrl-norm";
+    PropertyManager->Tie( property_name.c_str(), (FGThruster *)this, &FGThruster::GetClutchCtrl,
+                                                          &FGThruster::SetClutchCtrl);
+  }
+
   Debug(0);
 }
 
index 118005f5a408b0498619efcf6c82230cb7197b8d..4ef760e98a2b3450be51092c94433354f4248036 100644 (file)
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_THRUSTER "$Id: FGThruster.h,v 1.15 2009/10/24 22:59:30 jberndt Exp $"
+#define ID_THRUSTER "$Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -74,7 +74,7 @@ CLASS DOCUMENTATION
     1.57 (pi/2) results in no thrust at all.
  
     @author Jon Berndt
-    @version $Id: FGThruster.h,v 1.15 2009/10/24 22:59:30 jberndt Exp $
+    @version $Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $
     */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -105,6 +105,8 @@ public:
   string GetName(void) {return Name;}
   void SetReverserAngle(double angle) {ReverserAngle = angle;}
   double GetReverserAngle(void) const {return ReverserAngle;}
+  double GetClutchCtrl(void) const { return ClutchCtrlNorm; }
+  void SetClutchCtrl(double c) { ClutchCtrlNorm = c; }
   virtual double GetRPM(void) const { return 0.0; };
   double GetGearRatio(void) {return GearRatio; }
   virtual string GetThrusterLabels(int id, string delimeter);
@@ -119,6 +121,7 @@ protected:
   double GearRatio;
   double ThrustCoeff;
   double ReverserAngle;
+  double ClutchCtrlNorm;  
   int EngineNum;
   FGPropertyManager* PropertyManager;
   virtual void Debug(int from);
index 485c01c9421533e2ef9e81891888d37e561fc33d..d7277ba877d972b3733b31c3132e644459f1365b 100644 (file)
@@ -51,7 +51,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.29 2010/08/31 04:01:32 jberndt Exp $";
+static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.31 2011/03/03 12:16:26 jberndt Exp $";
 static const char *IdHdr = ID_TURBINE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -74,6 +74,7 @@ FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number)
   BypassRatio = BleedDemand = 0.0;
   IdleThrustLookup = MilThrustLookup = MaxThrustLookup = InjectionLookup = 0;
   N1_spinup = 1.0; N2_spinup = 3.0; 
+  EPR = 1.0;
 
   ResetToIC();
 
@@ -96,6 +97,9 @@ FGTurbine::~FGTurbine()
 
 void FGTurbine::ResetToIC(void)
 {
+    
+  FGEngine::ResetToIC();
+    
   N1 = N2 = 0.0;
   N2norm = 0.0;
   correctedTSFC = TSFC;
@@ -534,6 +538,8 @@ void FGTurbine::bindmodel()
   PropertyManager->Tie( property_name.c_str(), &Seized);
   property_name = base_property_name + "/stalled";
   PropertyManager->Tie( property_name.c_str(), &Stalled);
+  property_name = base_property_name + "/bleed-factor";
+  PropertyManager->Tie( property_name.c_str(), (FGTurbine*)this, &FGTurbine::GetBleedDemand, &FGTurbine::SetBleedDemand);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
old mode 100644 (file)
new mode 100755 (executable)
index 9813199..acc35cc
@@ -34,6 +34,7 @@ based on parameters given in the engine config file for this class
 HISTORY
 --------------------------------------------------------------------------------
 05/14/2004  Created
+02/08/2011  T. Kreitler, added rotor support
 
 //JVK (mark)
 
@@ -45,6 +46,7 @@ INCLUDES
 #include <sstream>
 #include "FGTurboProp.h"
 #include "FGPropeller.h"
+#include "FGRotor.h"
 #include "models/FGPropulsion.h"
 #include "models/FGAuxiliary.h"
 
@@ -52,7 +54,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.17 2010/08/21 17:13:48 jberndt Exp $";
+static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.19 2011/03/10 01:35:25 dpculp Exp $";
 static const char *IdHdr = ID_TURBOPROP;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -64,8 +66,10 @@ FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number)
     ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL)
 {
   SetDefaults();
+  thrusterType = Thruster->GetType();
 
   Load(exec, el);
+  bindmodel();
   Debug(0);
 }
 
@@ -101,6 +105,7 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
     MaxN2 = el->FindElementValueAsNumber("maxn2");
   if (el->FindElement("betarangeend"))
     BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0;
+  BetaRangeThrottleEnd = Constrain(0.0, BetaRangeThrottleEnd, 0.99999);
   if (el->FindElement("reversemaxpower"))
     ReverseMaxPower = el->FindElementValueAsNumber("reversemaxpower")/100.0;
 
@@ -146,10 +151,10 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
   delay=1;
   N1_factor = MaxN1 - IdleN1;
   N2_factor = MaxN2 - IdleN2;
-  OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
+  OilTemp_degK = Auxiliary->GetTAT_C() + 273.0;
   if (IdleFF==-1) IdleFF = pow(MilThrust, 0.2) * 107.0;  // just an estimate
 
-  cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << "\n";
+  // cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << endl;
 
   return true;
 }
@@ -162,29 +167,29 @@ void FGTurboProp::Calculate(void)
 {
   RunPreFunctions();
 
-  TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
+  TAT = Auxiliary->GetTAT_C();
   dt = FDMExec->GetDeltaT() * Propulsion->GetRate();
 
-  ThrottleCmd = FCS->GetThrottleCmd(EngineNumber);
+  Throttle = FCS->GetThrottlePos(EngineNumber);
 
-  Prop_RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
-  if (Thruster->GetType() == FGThruster::ttPropeller) {
+  RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
+  if (thrusterType == FGThruster::ttPropeller) {
     ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));
     ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
     ((FGPropeller*)Thruster)->SetReverse(Reversed);
     if (Reversed) {
-      ((FGPropeller*)Thruster)->SetReverseCoef(ThrottleCmd);
+      ((FGPropeller*)Thruster)->SetReverseCoef(Throttle);
     } else {
       ((FGPropeller*)Thruster)->SetReverseCoef(0.0);
     }
-  }
 
-  if (Reversed) {
-    if (ThrottleCmd < BetaRangeThrottleEnd) {
-        ThrottleCmd = 0.0;  // idle when in Beta-range
-    } else {
-      // when reversed:
-      ThrottleCmd = (ThrottleCmd-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
+    if (Reversed) {
+      if (Throttle < BetaRangeThrottleEnd) {
+          Throttle = 0.0;  // idle when in Beta-range
+      } else {
+        // when reversed:
+        Throttle = (Throttle-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
+      }
     }
   }
 
@@ -223,36 +228,41 @@ void FGTurboProp::Calculate(void)
     StartTime=-1;
   }
 
-  if (Condition < 1) {
-    if (Ielu_max_torque > 0
-      && -Ielu_max_torque > ((FGPropeller*)(Thruster))->GetTorque()
-      && ThrottleCmd >= OldThrottle ) {
-      ThrottleCmd = OldThrottle - 0.1 * dt; //IELU down
-      Ielu_intervent = true;
-    } else if (Ielu_max_torque > 0 && Ielu_intervent && ThrottleCmd >= OldThrottle) {
-      ThrottleCmd = OldThrottle;
-      ThrottleCmd = OldThrottle + 0.05 * dt; //IELU up
-      Ielu_intervent = true;
+  // limiter intervention wanted?
+  if (Ielu_max_torque > 0.0) {
+    double torque = 0.0;
+    
+    if (thrusterType == FGThruster::ttPropeller) {
+      torque = ((FGPropeller*)(Thruster))->GetTorque();
+    } else if (thrusterType == FGThruster::ttRotor) {
+      torque = ((FGRotor*)(Thruster))->GetTorque();
+    }
+
+    if (Condition < 1) {
+      if ( abs(torque) > Ielu_max_torque && Throttle >= OldThrottle ) {
+        Throttle = OldThrottle - 0.1 * dt; //IELU down
+        Ielu_intervent = true;
+      } else if ( Ielu_intervent && Throttle >= OldThrottle) {
+        Throttle = OldThrottle + 0.05 * dt; //IELU up
+        Ielu_intervent = true;
+      } else {
+        Ielu_intervent = false;
+      }
     } else {
       Ielu_intervent = false;
     }
-  } else {
-    Ielu_intervent = false;
+    OldThrottle = Throttle;
   }
-  OldThrottle = ThrottleCmd;
 
   switch (phase) {
-    case tpOff:    Eng_HP = Off(); break;
-    case tpRun:    Eng_HP = Run(); break;
-    case tpSpinUp: Eng_HP = SpinUp(); break;
-    case tpStart:  Eng_HP = Start(); break;
-    default: Eng_HP = 0;
+    case tpOff:    HP = Off(); break;
+    case tpRun:    HP = Run(); break;
+    case tpSpinUp: HP = SpinUp(); break;
+    case tpStart:  HP = Start(); break;
+    default: HP = 0;
   }
-
-  //printf ("EngHP: %lf / Requi: %lf\n",Eng_HP,Prop_Required_Power);
-  PowerAvailable = (Eng_HP * hptoftlbssec) - Thruster->GetPowerRequired();
-
-  Thruster->Calculate(PowerAvailable);
+  Thruster->Calculate(HP * hptoftlbssec);
 
   RunPostFunctions();
 }
@@ -280,7 +290,7 @@ double FGTurboProp::Off(void)
   ConsumeFuel(); // for possible setting Starved = false when fuel tank
                  // is refilled (fuel crossfeed etc.)
 
-  if (Prop_RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
+  if (RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
   return 0.0;
 }
 
@@ -293,9 +303,9 @@ double FGTurboProp::Run(void)
 
 //---
   double old_N1 = N1;
-  N1 = ExpSeek(&N1, IdleN1 + ThrottleCmd * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
+  N1 = ExpSeek(&N1, IdleN1 + Throttle * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
 
-  EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
+  EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
   EngPower_HP *= EnginePowerVC->GetValue();
   if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
 
@@ -346,7 +356,7 @@ double FGTurboProp::SpinUp(void)
   OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
   NozzlePosition = 1.0;
 
-  EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
+  EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
   EngPower_HP *= EnginePowerVC->GetValue();
   if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
 
@@ -366,13 +376,15 @@ double FGTurboProp::SpinUp(void)
 
 double FGTurboProp::Start(void)
 {
-  double EngPower_HP,eff_coef;
+  double EngPower_HP = 0.0;
+  double eff_coef;
+
   EngStarting = false;
   if ((N1 > 15.0) && !Starved) {       // minimum 15% N2 needed for start
     double old_N1 = N1;
     Cranking = true;                   // provided for sound effects signal
     if (N1 < IdleN1) {
-      EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
+      EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
       EngPower_HP *= EnginePowerVC->GetValue();
       if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
       N1 = ExpSeek(&N1, IdleN1*1.1, Idle_Max_Delay*4, Idle_Max_Delay * 2.4);
@@ -391,7 +403,6 @@ double FGTurboProp::Start(void)
       Starter = false;
       Cranking = false;
       FuelFlow_pph = 0;
-      EngPower_HP=0.0;
     }
   } else {                 // no start if N2 < 15% or Starved
     phase = tpOff;
@@ -449,13 +460,14 @@ void FGTurboProp::SetDefaults(void)
 {
 //  Name = "Not defined";
   N1 = N2 = 0.0;
+  HP = 0.0;
   Type = etTurboprop;
   MilThrust = 10000.0;
   IdleN1 = 30.0;
   IdleN2 = 60.0;
   MaxN1 = 100.0;
   MaxN2 = 100.0;
-  ThrottleCmd = 0.0;
+  Throttle = 0.0;
   InletPosition = 1.0;
   NozzlePosition = 1.0;
   Reversed = false;
@@ -472,6 +484,11 @@ void FGTurboProp::SetDefaults(void)
   Ielu_intervent=false;
 
   Idle_Max_Delay = 1.0;
+
+  Throttle = OldThrottle = 0.0;
+  ITT_Delay = 0.05;
+  ReverseMaxPower = 0.0;
+  BetaRangeThrottleEnd = 0.0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -495,9 +512,9 @@ string FGTurboProp::GetEngineValues(const string& delimiter)
 {
   std::ostringstream buf;
 
-  buf << PowerAvailable << delimiter
-      << N1 << delimiter
+  buf << N1 << delimiter
       << N2 << delimiter
+      << HP << delimiter
       << Thruster->GetThrusterValues(EngineNumber,delimiter);
 
   return buf.str();
@@ -524,10 +541,18 @@ void FGTurboProp::bindmodel()
   base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
   property_name = base_property_name + "/n1";
   PropertyManager->Tie( property_name.c_str(), &N1);
-  property_name = base_property_name + "/n2";
-  PropertyManager->Tie( property_name.c_str(), &N2);
+  // property_name = base_property_name + "/n2";
+  // PropertyManager->Tie( property_name.c_str(), &N2);
   property_name = base_property_name + "/reverser";
   PropertyManager->Tie( property_name.c_str(), &Reversed);
+  property_name = base_property_name + "/power-hp";
+  PropertyManager->Tie( property_name.c_str(), &HP);
+  property_name = base_property_name + "/itt-c";
+  PropertyManager->Tie( property_name.c_str(), &Eng_ITT_degC);
+  property_name = base_property_name + "/engtemp-c";
+  PropertyManager->Tie( property_name.c_str(), &Eng_Temperature);
+  property_name = base_property_name + "/ielu_intervent";
+  PropertyManager->Tie( property_name.c_str(), &Ielu_intervent);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
old mode 100644 (file)
new mode 100755 (executable)
index c73c0b7..1c5f48a
@@ -27,6 +27,7 @@
 HISTORY
 --------------------------------------------------------------------------------
 05/14/2004  Created
+02/08/2011  T. Kreitler, added rotor support
 
 //JVK (mark)
 
@@ -46,7 +47,7 @@ INCLUDES
 #include "input_output/FGXMLElement.h"
 #include "math/FGTable.h"
 
-#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.12 2010/08/21 18:08:37 jberndt Exp $"
+#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.14 2011/03/10 01:35:25 dpculp Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -107,11 +108,10 @@ public:
   void Calculate(void);
   double CalcFuelNeed(void);
 
-  inline double GetPowerAvailable(void) const {return (Eng_HP * hptoftlbssec);}
-  inline double GetPowerAvailable_HP(void) const {return (Eng_HP);}
-  inline double GetPropRPM(void) const {return (Prop_RPM);}
-  inline double GetThrottleCmd(void) const {return (ThrottleCmd);}
-  inline bool GetIeluIntervent(void) const { return Ielu_intervent; }
+  double GetPowerAvailable(void) const { return (HP * hptoftlbssec); }
+  double GetRPM(void) const { return (RPM); }
+  double GetIeluThrottle(void) const { return (Throttle); }
+  bool GetIeluIntervent(void) const { return Ielu_intervent; }
 
   double Seek(double* var, double target, double accel, double decel);
   double ExpSeek(double* var, double target, double accel, double decel);
@@ -165,9 +165,8 @@ private:
   double dt;               ///< Simulator time slice
   double N1_factor;        ///< factor to tie N1 and throttle
   double N2_factor;        ///< factor to tie N2 and throttle
-  double ThrottleCmd;      ///< FCS-supplied throttle position
+  double Throttle;         ///< FCS-supplied throttle position
   double TAT;              ///< total air temperature (deg C)
-  double PowerAvailable;
   bool Stalled;            ///< true if engine is compressor-stalled
   bool Seized;             ///< true if inner spool is seized
   bool Overtemp;           ///< true if EGT exceeds limits
@@ -189,26 +188,27 @@ private:
   double BetaRangeThrottleEnd; // coef (0-1) where is end of beta-range
   double ReverseMaxPower;      // coef (0-1) multiplies max throttle on reverse
 
-  double Idle_Max_Delay;       // time delay for exponencial
+  double Idle_Max_Delay;       // time delay for exponential
   double MaxPower;             // max engine power [HP]
-  double StarterN1;           // rotates of generator maked by starter [%]
+  double StarterN1;            // rotates of generator maked by starter [%]
   double MaxStartingTime;      // maximal time for start [s] (-1 means not used)
-  double Prop_RPM;             // propeller RPM
+  double RPM;                  // shaft RPM
   double Velocity;
   double rho;
   double PSFC;                 // Power specific fuel comsumption [lb/(HP*hr)] at best efficiency
 
-  double Eng_HP;               // current engine power
+  double HP;                   // engine power output
 
-  double StartTime;           // engine strating time [s] (0 when start button pushed)
+  double StartTime;            // engine starting time [s] (0 when start button pushed)
 
-  double  ITT_Delay;          // time delay for exponencial grow of ITT
+  double  ITT_Delay;           // time delay for exponential growth of ITT
   double  Eng_ITT_degC;
   double  Eng_Temperature;     // temperature inside engine
 
   bool EngStarting;            // logicaly output - TRUE if engine is starting
   bool GeneratorPower;
   int Condition;
+  int thrusterType;            // the attached thruster
 
   double Off(void);
   double Run(void);