]> git.mxchange.org Git - flightgear.git/commitdiff
Update to the latest version of JSBSim
authorehofman <ehofman>
Sun, 16 Aug 2009 19:36:55 +0000 (19:36 +0000)
committerTim Moore <timoore@redhat.com>
Sun, 23 Aug 2009 19:43:08 +0000 (21:43 +0200)
15 files changed:
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/FGJSBBase.cpp
src/FDM/JSBSim/FGJSBBase.h
src/FDM/JSBSim/JSBSim.cxx
src/FDM/JSBSim/initialization/FGInitialCondition.cpp
src/FDM/JSBSim/initialization/FGInitialCondition.h
src/FDM/JSBSim/input_output/FGPropertyManager.h
src/FDM/JSBSim/models/FGFCS.cpp
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/FGMassBalance.cpp
src/FDM/JSBSim/models/FGMassBalance.h
src/FDM/JSBSim/models/FGOutput.cpp
src/FDM/JSBSim/models/FGOutput.h
src/FDM/JSBSim/models/FGPropagate.h
src/FDM/JSBSim/models/propulsion/FGPropeller.cpp

index 7f50d05904d246db50716c48296dae619097ad68..da1b9deb0bd5a3ed52be6b1219cc24ca9efe32e2 100644 (file)
@@ -650,16 +650,23 @@ bool FGFDMExec::LoadModel(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;
     element = document->FindElement("output");
     while (element) {
+      if (debug_lvl > 0) cout << endl << "  Output data set: " << idx << "  ";
       FGOutput* Output = new FGOutput(this);
       Output->InitModel();
       Schedule(Output, 1);
       result = Output->Load(element);
-      Outputs.push_back(Output);
       if (!result) {
         cerr << endl << "Aircraft output element has problems in file " << aircraftCfgFileName << endl;
         return result;
+      } else {
+        Outputs.push_back(Output);
+        string outputProp = CreateIndexedPropertyName("simulation/output",idx);
+        instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
+        idx++;
       }
       element = document->FindNextElement("output");
     }
@@ -931,6 +938,10 @@ bool FGFDMExec::SetOutputDirectives(string fname)
   result = Output->Load(0);
   Outputs.push_back(Output);
 
+  typedef int (FGOutput::*iOPMF)(void) const;
+  string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
+  instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
+
   return result;
 }
 
index 228fa8639237769cb0f677c5511a7caf004fa563..d0af549b842e3ffb05d16cbeb99876345421db94 100644 (file)
@@ -38,6 +38,7 @@ INCLUDES
 #define BASE
 
 #include "FGJSBBase.h"
+#include <iostream>
 
 namespace JSBSim {
 
@@ -109,6 +110,10 @@ unsigned int FGJSBBase::messageId = 0;
 
 short FGJSBBase::debug_lvl  = 1;
 
+using std::cerr;
+using std::cout;
+using std::endl;
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGJSBBase::PutMessage(const Message& msg)
@@ -176,10 +181,43 @@ int FGJSBBase::SomeMessages(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
+void FGJSBBase::ProcessMessage(void)
+{
+  if (Messages.empty()) return;
+  localMsg = Messages.front();
+
+  while (Messages.size() > 0) {
+      switch (localMsg.type) {
+      case JSBSim::FGJSBBase::Message::eText:
+        cout << localMsg.messageId << ": " << localMsg.text << endl;
+        break;
+      case JSBSim::FGJSBBase::Message::eBool:
+        cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.bVal << endl;
+        break;
+      case JSBSim::FGJSBBase::Message::eInteger:
+        cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.iVal << endl;
+        break;
+      case JSBSim::FGJSBBase::Message::eDouble:
+        cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.dVal << endl;
+        break;
+      default:
+        cerr << "Unrecognized message type." << endl;
+        break;
+      }
+      Messages.pop();
+      if (Messages.size() > 0) localMsg = Messages.front();
+      else break;
+  }
+
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGJSBBase::Message* FGJSBBase::ProcessNextMessage(void)
 {
   if (Messages.empty()) return NULL;
   localMsg = Messages.front();
+
   Messages.pop();
   return &localMsg;
 }
index 7e56d5f5f5079d1574d12b24c9c96004a78ea9ba..49b0aec9e02282f3c478e510c20e6ddffabfdeb4 100644 (file)
@@ -182,8 +182,12 @@ public:
       @return 1 if some messages */
   int SomeMessages(void);
   /** Reads the message on the queue and removes it from the queue.
-      @return pointer to a Message structure (or NULL if no mesage) */
-  Message* ProcessMessage(void);
+      This function also prints out the message.*/
+  void ProcessMessage(void);
+  /** Reads the next message on the queue and removes it from the queue.
+      This function also prints out the message.
+      @return a pointer to the message, or NULL if there are no messages.*/
+  Message* ProcessNextMessage(void);
   //@}
 
   /** Returns the version number of JSBSim.
index b36c196574f297029eb78015a23680ec17db821e..f5dd9008ed5936afc670746f911befd7839e9f67 100644 (file)
@@ -489,8 +489,8 @@ void FGJSBsim::update( double dt )
     }
 
     FGJSBBase::Message* msg;
-    while (fdmex->SomeMessages()) {
-      msg = fdmex->ProcessMessage();
+    while (msg = fdmex->ProcessNextMessage()) {
+//      msg = fdmex->ProcessNextMessage();
       switch (msg->type) {
       case FGJSBBase::Message::eText:
         if (msg->text == "Crash Detected: Simulation FREEZE.")
index de904e0e133a6797acbe9b77553d00705c1588e8..10b4b7a3e3fe429bb03bf0babed4495f2490eacd 100644 (file)
@@ -865,8 +865,14 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
     SetLongitudeDegIC(document->FindElementValueAsNumberConvertTo("longitude", "DEG"));
   if (document->FindElement("elevation"))
     SetTerrainElevationFtIC(document->FindElementValueAsNumberConvertTo("elevation", "FT"));
+
   if (document->FindElement("altitude")) // This is feet above ground level
     SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitude", "FT"));
+  else if (document->FindElement("altitudeAGL")) // This is feet above ground level
+    SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitudeAGL", "FT"));
+  else if (document->FindElement("altitudeMSL")) // This is feet above sea level
+    SetAltitudeASLFtIC(document->FindElementValueAsNumberConvertTo("altitudeMSL", "FT"));
+
   if (document->FindElement("ubody"))
     SetUBodyFpsIC(document->FindElementValueAsNumberConvertTo("ubody", "FT/SEC"));
   if (document->FindElement("vbody"))
index 330552e7ffb3d7cf93d74e7a537348f56a892d03..86de126a00448a6e7045e1bc88486ab1d9149125 100644 (file)
@@ -140,7 +140,10 @@ CLASS DOCUMENTATION
    - beta (angle, degrees)
    - gamma (angle, degrees)
    - roc (vertical velocity, ft/sec)
+   - elevation (local terrain elevation, ft)
    - altitude (altitude AGL, ft)
+   - altitudeAGL (altitude AGL, ft)
+   - altitudeMSL (altitude MSL, ft)
    - winddir (wind from-angle, degrees)
    - vwind (magnitude wind speed, ft/sec)
    - hwind (headwind speed, knots)
index 8f191fe87fa3cb2b3d174d63c0bb97aacf731b65..52a64217b1b5fc646c5b930e5007a7e23a73034f 100644 (file)
@@ -35,14 +35,9 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
 #include <string>
 #include <iostream>
 #include <simgear/props/props.hxx>
-#include <simgear/math/SGMath.hxx>
 
 #include "FGJSBBase.h"
 
index 22ca19d77ee9892333698f3638762840e41cc615..47213f90074c31b24493ef887785345722b510b1 100644 (file)
@@ -519,7 +519,7 @@ bool FGFCS::Load(Element* el, SystemType systype)
 {
   string name, file, fname="", interface_property_string, parent_name;
   vector <FGFCSComponent*> *Components;
-  Element *component_element, *sensor_element;
+  Element *component_element;
   Element *channel_element;
 
   Components=0;
index dcb140b8aacffc928a539decf7ba33834e173cd3..96d8d2308f28f370730913fb4a7b56d219d1c639 100644 (file)
@@ -652,6 +652,10 @@ void FGLGear::bind(void)
     Exec->GetPropertyManager()->Tie( property_name.c_str(), &compressLength );
     property_name = base_property_name + "/side_friction_coeff";
     Exec->GetPropertyManager()->Tie( property_name.c_str(), &FCoeff );
+
+    property_name = base_property_name + "/static_friction_coeff";
+    Exec->GetPropertyManager()->Tie( property_name.c_str(), &staticFCoeff );
+
   }
 
   if( isRetractable ) {
index eae63733523674de850efd750ec44bc1c52cde52..fd2fad3d5348d967742b82e975ea1cf37acf9876 100644 (file)
@@ -59,6 +59,9 @@ FGMassBalance::FGMassBalance(FGFDMExec* fdmex) : FGModel(fdmex)
   Weight = EmptyWeight = Mass = 0.0;
 
   vbaseXYZcg.InitMatrix(0.0);
+  vXYZcg.InitMatrix(0.0);
+  vLastXYZcg.InitMatrix(0.0);
+  vDeltaXYZcg.InitMatrix(0.0);
   baseJ.InitMatrix();
   mJ.InitMatrix();
   mJinv.InitMatrix();
@@ -85,6 +88,9 @@ bool FGMassBalance::InitModel(void)
 {
   if (!FGModel::InitModel()) return false;
 
+  vLastXYZcg.InitMatrix(0.0);
+  vDeltaXYZcg.InitMatrix(0.0);
+
   return true;
 }
 
@@ -172,6 +178,14 @@ bool FGMassBalance::Run(void)
             + GetPointMassMoment()
             + BuoyantForces->GetGasMassMoment()) / Weight;
 
+  // Track frame-by-frame delta CG, and move the EOM-tracked location
+  // by this amount.
+  if (vLastXYZcg.Magnitude() == 0.0) vLastXYZcg = vXYZcg;
+  vDeltaXYZcg = vXYZcg - vLastXYZcg;
+  vDeltaXYZcgBody = StructuralToBody(vLastXYZcg) - StructuralToBody(vXYZcg);
+  vLastXYZcg = vXYZcg;
+  Propagate->NudgeBodyLocation(vDeltaXYZcgBody);
+
 // Calculate new total moments of inertia
 
   // At first it is the base configuration inertia matrix ...
index 34f6f9cd6bc127c59853993c72f77d033ac9362f..c77400f377e22180cfffde1342a017ec02ce3922 100644 (file)
@@ -107,10 +107,12 @@ public:
   bool InitModel(void);
   bool Run(void);
 
-  inline double GetMass(void) const {return Mass;}
-  inline double GetWeight(void) const {return Weight;}
-  inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
-  inline double GetXYZcg(int axis) const  {return vXYZcg(axis);}
+  double GetMass(void) const {return Mass;}
+  double GetWeight(void) const {return Weight;}
+  FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
+  double GetXYZcg(int axis) const  {return vXYZcg(axis);}
+  FGColumnVector3& GetDeltaXYZcg(void) {return vDeltaXYZcg;}
+  double GetDeltaXYZcg(int axis) const  {return vDeltaXYZcg(axis);}
 
   /** Computes the inertia contribution of a pointmass.
       Computes and returns the inertia matrix of a pointmass of mass
@@ -166,6 +168,9 @@ private:
   FGMatrix33 pmJ;
   FGMatrix33 baseJ;
   FGColumnVector3 vXYZcg;
+  FGColumnVector3 vLastXYZcg;
+  FGColumnVector3 vDeltaXYZcg;
+  FGColumnVector3 vDeltaXYZcgBody;
   FGColumnVector3 vXYZtank;
   FGColumnVector3 vbaseXYZcg;
   FGColumnVector3 vPMxyz;
index f8ef6a0b3bd83b2dda17dc591f808d24627daef1..cb48ab5542f33d342dcae1554323da95a7e29710 100644 (file)
@@ -465,9 +465,11 @@ void FGOutput::DelimitedOutput(string fname)
     outstream << Propulsion->GetPropulsionValues(delimeter);
   }
 
+  outstream.precision(18);
   for (unsigned int i=0;i<OutputProperties.size();i++) {
     outstream << delimeter << OutputProperties[i]->getDoubleValue();
   }
+  outstream.precision(10);
 
   outstream << endl;
   outstream.flush();
@@ -1016,14 +1018,27 @@ bool FGOutput::Load(Element* element)
     property_element = document->FindNextElement("property");
   }
 
-  OutRate = OutRate>1000?1000:(OutRate<0?0:OutRate);
-  rate = (int)(0.5 + 1.0/(State->Getdt()*OutRate));
+  SetRate(OutRate);
 
   Debug(2);
 
   return true;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGOutput::SetRate(int rtHz)
+{
+  rtHz = rtHz>1000?1000:(rtHz<0?0:rtHz);
+  if (rtHz > 0) {
+    rate = (int)(0.5 + 1.0/(State->Getdt()*rtHz));
+    Enable();
+  } else {
+    rate = 1;
+    Disable();
+  }
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //    The bitmasked value choices are as follows:
 //    unset: In this case (the default) JSBSim would only print
index 51fcade3906998f9fcbb68118b95bf65ae49a095..8b3d1403c74c787e3fc7f27467c00072d6e93145 100644 (file)
@@ -150,12 +150,13 @@ public:
   void SetType(string);
   void SetStartNewFile(bool tt) {StartNewFile = tt;}
   void SetSubsystems(int tt) {SubSystems = tt;}
-  inline void Enable(void) { enabled = true; }
-  inline void Disable(void) { enabled = false; }
-  inline bool Toggle(void) {enabled = !enabled; return enabled;}
+  void Enable(void) { enabled = true; }
+  void Disable(void) { enabled = false; }
+  bool Toggle(void) {enabled = !enabled; return enabled;}
   bool Load(Element* el);
   void SetOutputFileName(string fname) {Filename = fname;}
   void SetDirectivesFile(string fname) {DirectivesFile = fname;}
+  void SetRate(int rt);
   string GetOutputFileName(void) const {return Filename;}
 
   /// Subsystem types for specifying which will be output in the FDM data logging
index 63c2b42c38e5258bb607c2f7a486e5c93bad5a47..a4ecd6c912761e5950655f169ad66281d51adfae 100644 (file)
@@ -487,6 +487,11 @@ public:
   void SetInitialState(const FGInitialCondition *);
   void RecomputeLocalTerrainRadius(void);
 
+  void NudgeBodyLocation(FGColumnVector3 deltaLoc) {
+    vDeltaXYZEC = GetTb2ec()*deltaLoc;
+    VState.vLocation -= vDeltaXYZEC;
+  }
+
   void CalculatePQRdot(void);
   void CalculateQuatdot(void);
   void CalculateLocationdot(void);
@@ -504,6 +509,7 @@ private:
   FGColumnVector3 vUVWdot, last_vUVWdot, last2_vUVWdot;
   FGColumnVector3 vLocationDot, last_vLocationDot, last2_vLocationDot;
   FGColumnVector3 vLocation;
+  FGColumnVector3 vDeltaXYZEC;
   FGColumnVector3 vPQRi;   // Inertial frame angular velocity
   FGColumnVector3 vOmega;  // The Earth angular velocity vector
   FGColumnVector3 vOmegaLocal;  // The local frame angular velocity vector
index 3a54175fc9e887c6c7d8d3989b8154e20d441f36..f598468018d0ff43da6da8b13f98857cd426327d 100644 (file)
@@ -199,8 +199,6 @@ double FGPropeller::Calculate(double PowerAvailable)
   vH(eY) = 0.0;
   vH(eZ) = 0.0;
 
-  vH = Transform()*vH; // Transform rotational momentum to rotated frame (if any)
-
   if (omega > 0.0) ExcessTorque = GearRatio * PowerAvailable / omega;
   else             ExcessTorque = GearRatio * PowerAvailable / 1.0;
 
@@ -208,9 +206,9 @@ double FGPropeller::Calculate(double PowerAvailable)
 
   if (RPM < 1.0) RPM = 0; // Engine friction stops rotation arbitrarily at 1 RPM.
 
-  // Transform Torque and momentum prior to this equation, as PQR is used in this
+  // Transform Torque and momentum first, as PQR is used in this
   // equation and cannot be transformed itself.
-  vMn = fdmex->GetPropagate()->GetPQR()*vH + Transform()*vTorque;
+  vMn = fdmex->GetPropagate()->GetPQR()*(Transform()*vH) + Transform()*vTorque;
 
   return Thrust; // return thrust in pounds
 }