]> git.mxchange.org Git - flightgear.git/commitdiff
Code cleanups, code updates and fix at least on (possible) devide-by-zero
authorErik Hofman <erik@ehofman.com>
Mon, 23 May 2016 09:38:05 +0000 (11:38 +0200)
committerRoland Haeder <roland@mxchange.org>
Thu, 22 Sep 2016 21:27:35 +0000 (23:27 +0200)
22 files changed:
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/JSBSim.cxx
src/FDM/JSBSim/input_output/FGOutputTextFile.cpp
src/FDM/JSBSim/input_output/FGPropertyManager.h
src/FDM/JSBSim/input_output/FGfdmSocket.h
src/FDM/JSBSim/math/FGTable.cpp
src/FDM/JSBSim/models/FGAccelerations.cpp
src/FDM/JSBSim/models/FGAccelerations.h
src/FDM/JSBSim/models/FGAerodynamics.cpp
src/FDM/JSBSim/models/FGAuxiliary.cpp
src/FDM/JSBSim/models/FGFCS.cpp
src/FDM/JSBSim/models/FGFCS.h
src/FDM/JSBSim/models/FGGroundReactions.cpp
src/FDM/JSBSim/models/FGGroundReactions.h
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/FGLGear.h
src/FDM/JSBSim/models/FGPropagate.cpp
src/FDM/JSBSim/models/FGPropulsion.cpp
src/FDM/JSBSim/models/FGPropulsion.h
src/FDM/JSBSim/models/flight_control/FGWaypoint.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/models/flight_control/FGWaypoint.h [changed mode: 0644->0755]
src/FDM/JSBSim/models/propulsion/FGTank.cpp

index 8829b6787518cc1203de47efaf61b6b2b2715bad..8552a519cd89e29aa25ccb9ff8a2dc8c49de8730 100644 (file)
@@ -72,7 +72,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.189 2016/04/16 12:24:39 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.191 2016/05/16 18:19:57 bcoconni Exp $");
 IDENT(IdHdr,ID_FDMEXEC);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -446,7 +446,6 @@ void FGFDMExec::LoadInputs(unsigned int idx)
     GroundReactions->in.VcalibratedKts  = Auxiliary->GetVcalibratedKTS();
     GroundReactions->in.Temperature     = Atmosphere->GetTemperature();
     GroundReactions->in.TakeoffThrottle = (FCS->GetThrottlePos().size() > 0) ? (FCS->GetThrottlePos(0) > 0.90) : false;
-    GroundReactions->in.SteerPosDeg     = FCS->GetSteerPosDeg();
     GroundReactions->in.BrakePos        = FCS->GetBrakePos();
     GroundReactions->in.FCSGearPos      = FCS->GetGearPos();
     GroundReactions->in.EmptyWeight     = MassBalance->GetEmptyWeight();
@@ -561,6 +560,7 @@ bool FGFDMExec::RunIC(void)
   Models[eOutput]->InitModel();
 
   Run();
+  Propagate->InitializeDerivatives();
   ResumeIntegration(); // Restores the integration rate to what it was.
 
   if (debug_lvl > 0) {
@@ -593,7 +593,6 @@ void FGFDMExec::Initialize(FGInitialCondition* FGIC)
   Propagate->SetInitialState(FGIC);
   Winds->SetWindNED(FGIC->GetWindNEDFpsIC());
   Run();
-  Propagate->InitializeDerivatives();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -751,10 +750,11 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     if (element) {
       result = ((FGGroundReactions*)Models[eGroundReactions])->Load(element);
       if (!result) {
-        cerr << endl << "Aircraft ground_reactions element has problems in file " << aircraftCfgFileName << endl;
+        cerr << endl << element->ReadFrom()
+             << "Aircraft ground_reactions element has problems in file "
+             << aircraftCfgFileName << endl;
         return result;
       }
-      ((FGFCS*)Models[eSystems])->AddGear(((FGGroundReactions*)Models[eGroundReactions])->GetNumGearUnits());
     } else {
       cerr << endl << "No ground_reactions element was found in the aircraft config file." << endl;
       return false;
index 0ac6cfb280b3ee63993c361a61a16d7fad7e3b8e..b2b20c5c762799387f9e31db683fd4c7335ab1ac 100644 (file)
@@ -594,8 +594,8 @@ bool FGJSBsim::copy_to_JSBsim()
     FCS->SetDeCmd( globals->get_controls()->get_elevator());
     FCS->SetPitchTrimCmd( globals->get_controls()->get_elevator_trim() );
     FCS->SetDrCmd( -globals->get_controls()->get_rudder() );
-    FCS->SetYawTrimCmd( -globals->get_controls()->get_rudder_trim() );
     FCS->SetDsCmd( globals->get_controls()->get_rudder() );
+    FCS->SetYawTrimCmd( -globals->get_controls()->get_rudder_trim() );
     FCS->SetDfCmd( globals->get_controls()->get_flaps() );
     FCS->SetDsbCmd( globals->get_controls()->get_speedbrake() );
     FCS->SetDspCmd( globals->get_controls()->get_spoilers() );
index c67b4dbf8713cb403c41b1e61b269c9a90730934..569408e46bad4bdfc405924b0a5a53d5e7e734ac 100644 (file)
@@ -64,7 +64,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGOutputTextFile.cpp,v 1.11 2014/02/17 05:02:38 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGOutputTextFile.cpp,v 1.12 2016/05/22 10:28:23 bcoconni Exp $");
 IDENT(IdHdr,ID_OUTPUTTEXTFILE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -158,6 +158,7 @@ bool FGOutputTextFile::OpenFile(void)
     outstream << "F_{Gear x} (lbs)" + delimeter + "F_{Gear y} (lbs)" + delimeter + "F_{Gear z} (lbs)" + delimeter;
     outstream << "F_{Ext x} (lbs)" + delimeter + "F_{Ext y} (lbs)" + delimeter + "F_{Ext z} (lbs)" + delimeter;
     outstream << "F_{Buoyant x} (lbs)" + delimeter + "F_{Buoyant y} (lbs)" + delimeter + "F_{Buoyant z} (lbs)" + delimeter;
+    outstream << "F_{Weight x} (lbs)" + delimeter + "F_{Weight y} (lbs)" + delimeter + "F_{Weight z} (lbs)" + delimeter;
     outstream << "F_{Total x} (lbs)" + delimeter + "F_{Total y} (lbs)" + delimeter + "F_{Total z} (lbs)";
   }
   if (SubSystems & ssMoments) {
@@ -315,20 +316,21 @@ void FGOutputTextFile::Print(void)
     outstream << Aerodynamics->GetLoD() << delimeter;
     outstream << Aerodynamics->GetForces().Dump(delimeter) << delimeter;
     outstream << Propulsion->GetForces().Dump(delimeter) << delimeter;
-    outstream << GroundReactions->GetForces().Dump(delimeter) << delimeter;
+    outstream << Accelerations->GetGroundForces().Dump(delimeter) << delimeter;
     outstream << ExternalReactions->GetForces().Dump(delimeter) << delimeter;
     outstream << BuoyantForces->GetForces().Dump(delimeter) << delimeter;
-    outstream << Aircraft->GetForces().Dump(delimeter);
+    outstream << Accelerations->GetWeight().Dump(delimeter) << delimeter;
+    outstream << Accelerations->GetForces().Dump(delimeter);
   }
   if (SubSystems & ssMoments) {
     outstream << delimeter;
     outstream << Aerodynamics->GetMoments().Dump(delimeter) << delimeter;
     outstream << Aerodynamics->GetMomentsMRC().Dump(delimeter) << delimeter;
     outstream << Propulsion->GetMoments().Dump(delimeter) << delimeter;
-    outstream << GroundReactions->GetMoments().Dump(delimeter) << delimeter;
+    outstream << Accelerations->GetGroundMoments().Dump(delimeter) << delimeter;
     outstream << ExternalReactions->GetMoments().Dump(delimeter) << delimeter;
     outstream << BuoyantForces->GetMoments().Dump(delimeter) << delimeter;
-    outstream << Aircraft->GetMoments().Dump(delimeter);
+    outstream << Accelerations->GetMoments().Dump(delimeter);
   }
   if (SubSystems & ssAtmosphere) {
     outstream << delimeter;
index 774904ce2286e4ce26b17e6fa256b670d0c7c0ca..3850a510cb67734cd9d724512d6f2fdebb6a8530 100644 (file)
@@ -42,7 +42,7 @@ INCLUDES
 #endif
 
 #include <string>
-#include "simgear/props/props.hxx"
+#include "simgear/props/propertyObject.hxx"
 #if !PROPS_STANDALONE
 # include "simgear/math/SGMath.hxx"
 #endif
@@ -53,7 +53,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.29 2014/11/15 11:32:54 bcoconni Exp $"
+#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.30 2016/05/05 15:32:42 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -383,7 +383,7 @@ class FGPropertyManager
     FGPropertyManager(void) { root = new FGPropertyNode; }
 
     /// Constructor
-    FGPropertyManager(FGPropertyNode* _root) : root(_root) {};
+    explicit FGPropertyManager(FGPropertyNode* _root) : root(_root) {};
 
     /// Destructor
     virtual ~FGPropertyManager(void) { Unbind(); }
@@ -687,6 +687,10 @@ class FGPropertyManager
       }
    }
 
+    template <class T> simgear::PropertyObject<T>
+    CreatePropertyObject(const std::string &path)
+    { return simgear::PropertyObject<T>(root->GetNode(path, true)); }
+
   private:
     std::vector<SGPropertyNode_ptr> tied_properties;
     FGPropertyNode_ptr root;
index 53a1dc641167bd446225f1854bd87df7b284f815..65151ccf68ac61848a2605fe095f528449d0c35f 100644 (file)
@@ -65,7 +65,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.23 2015/03/28 15:03:44 bcoconni Exp $"
+#define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.24 2016/04/17 13:13:29 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -114,7 +114,6 @@ public:
 private:
   int sckt;
   int sckt_in;
-  int udpsckt;
   DirectionType Direction;
   ProtocolType Protocol;
   struct sockaddr_in scktName;
index 8b951f86e92b58f71868e7cff98589fd1f9ea210..406d023a7d445d0b341c6a5ab90d2aad9f98878a 100644 (file)
@@ -47,7 +47,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGTable.cpp,v 1.31 2014/01/13 10:46:03 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGTable.cpp,v 1.32 2016/05/22 09:08:05 bcoconni Exp $");
 IDENT(IdHdr,ID_TABLE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -178,6 +178,7 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
       node = PropertyManager->GetNode(property_string);
 
       if (node == 0) {
+        cerr << axisElement->ReadFrom();
         throw("IndependentVar property, " + property_string + " in Table definition is not defined.");
       }
 
index bfb4a6a81c8cf77f11feac3ea842de993429caf4..62fc0e977f51c58561d57b9bb36c54f7557023e0 100644 (file)
@@ -60,7 +60,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGAccelerations.cpp,v 1.28 2016/04/16 12:24:39 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGAccelerations.cpp,v 1.29 2016/05/22 10:28:23 bcoconni Exp $");
 IDENT(IdHdr,ID_ACCELERATIONS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -367,6 +367,9 @@ void FGAccelerations::bind(void)
   PropertyManager->Tie("accelerations/gravity-ft_sec2", this, &FGAccelerations::GetGravAccelMagnitude);
   PropertyManager->Tie("simulation/gravity-model", &gravType);
   PropertyManager->Tie("simulation/gravitational-torque", &gravTorque);
+  PropertyManager->Tie("forces/fbx-weight-lbs", this, eX, (PMF)&FGAccelerations::GetWeight);
+  PropertyManager->Tie("forces/fby-weight-lbs", this, eY, (PMF)&FGAccelerations::GetWeight);
+  PropertyManager->Tie("forces/fbz-weight-lbs", this, eZ, (PMF)&FGAccelerations::GetWeight);
 
   PropertyManager->Tie("forces/fbx-total-lbs", this, eX, (PMF)&FGAccelerations::GetForces);
   PropertyManager->Tie("forces/fby-total-lbs", this, eY, (PMF)&FGAccelerations::GetForces);
index 684e626633d4db4041ebb72f2853607d246fe2ea..85dda88bb975aec6c251df9c76a55763e6be9e3e 100644 (file)
@@ -49,7 +49,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ACCELERATIONS "$Id: FGAccelerations.h,v 1.19 2016/04/16 12:24:39 bcoconni Exp $"
+#define ID_ACCELERATIONS "$Id: FGAccelerations.h,v 1.20 2016/05/22 10:28:23 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -96,7 +96,7 @@ CLASS DOCUMENTATION
          NASA SP-8024, May 1969
 
     @author Jon S. Berndt, Mathias Froehlich, Bertrand Coconnier
-    @version $Id: FGAccelerations.h,v 1.19 2016/04/16 12:24:39 bcoconni Exp $
+    @version $Id: FGAccelerations.h,v 1.20 2016/05/22 10:28:23 bcoconni Exp $
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -266,6 +266,7 @@ public:
       @return The total moments applied on the body.
    */
   double GetMoments(int idx) const { return in.Moment(idx) + vFrictionMoments(idx); }
+  FGColumnVector3 GetMoments(void) const { return in.Moment + vFrictionMoments; }
 
   /** Retrieves the total forces applied on the body.
       Retrieves the total forces applied on the body. This does include the
@@ -279,6 +280,7 @@ public:
       @return The total forces applied on the body.
    */
   double GetForces(int idx) const { return in.Force(idx) + vFrictionForces(idx); }
+  FGColumnVector3 GetForces(void) const { return in.Force + vFrictionForces; }
 
   /** Retrieves the ground moments applied on the body.
       Retrieves the ground moments applied on the body. This does include the
@@ -292,19 +294,35 @@ public:
       @return The ground moments applied on the body.
    */
   double GetGroundMoments(int idx) const { return in.GroundMoment(idx) + vFrictionMoments(idx); }
+  FGColumnVector3 GetGroundMoments(void) const { return in.GroundMoment + vFrictionMoments; }
 
   /** Retrieves the ground forces applied on the body.
       Retrieves the ground forces applied on the body. This does include the
       ground normal reaction and friction forces.
-      The vector for the total moments in the body frame is organized (Fx, Fy
+      The vector for the ground forces in the body frame is organized (Fx, Fy
       , Fz). The vector is 1-based. In other words, GetGroundForces(1) returns
       Fx. Various convenience enumerators are defined in FGJSBBase. The relevant
       enumerators for the forces returned by this call are, eX=1, eY=2, eZ=3.
-      units lbs
+      units lbs.
       @param idx the index of the forces component desired (1-based).
       @return The ground forces applied on the body.
    */
   double GetGroundForces(int idx) const { return in.GroundForce(idx) + vFrictionForces(idx); }
+  FGColumnVector3 GetGroundForces(void) const { return in.GroundForce + vFrictionForces; }
+
+  /** Retrieves the weight applied on the body.
+      Retrieves the weight applied on the body i.e. the force that results from
+      the gravity applied to the body mass.
+      The vector for the weight forces in the body frame is organized (Fx, Fy ,
+      Fz). The vector is 1-based. In other words, GetWeight(1) returns
+      Fx. Various convenience enumerators are defined in FGJSBBase. The relevant
+      enumerators for the forces returned by this call are, eX=1, eY=2, eZ=3.
+      units lbs.
+      @param idx the index of the forces component desired (1-based).
+      @return The ground forces applied on the body.
+  */
+  double GetWeight(int idx) const { return in.Mass * (in.Ti2b * vGravAccel)(idx); }
+  FGColumnVector3 GetWeight(void) const { return in.Mass * in.Ti2b * vGravAccel; }
 
   /** Initializes the FGAccelerations class prior to a new execution.
       Initializes the class prior to a new execution when the input data stored
index e870d0f74e66315257615fca5d6569661c09bffa..e50ecb85167a88912fa6cec2ccb1437d03d64769 100644 (file)
@@ -50,7 +50,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.55 2014/09/03 17:26:28 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.58 2016/05/22 17:02:13 bcoconni Exp $");
 IDENT(IdHdr,ID_AERODYNAMICS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -144,7 +144,7 @@ bool FGAerodynamics::Run(bool Holding)
   if (FGModel::Run(Holding)) return true;
   if (Holding) return false; // if paused don't execute
 
-  unsigned int axis_ctr, ctr;
+  unsigned int axis_ctr;
   const double twovel=2*in.Vt;
 
   RunPreFunctions();
@@ -179,15 +179,23 @@ bool FGAerodynamics::Run(bool Holding)
   vFnative.InitMatrix();
   vFnativeAtCG.InitMatrix();
 
-  for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
-    for (ctr=0; ctr < AeroFunctions[axis_ctr].size(); ctr++) {
-      vFnative(axis_ctr+1) += AeroFunctions[axis_ctr][ctr]->GetValue();
+  for (axis_ctr = 0; axis_ctr < 3; ++axis_ctr) {
+    AeroFunctionArray::iterator f;
+
+    AeroFunctionArray* array = &AeroFunctions[axis_ctr];
+    for (f=array->begin(); f != array->end(); ++f) {
+      // Tell the Functions to cache values, so when the function values are
+      // being requested for output, the functions do not get calculated again
+      // in a context that might have changed, but instead use the values that
+      // have already been calculated for this frame.
+      (*f)->cacheValue(true);
+      vFnative(axis_ctr+1) += (*f)->GetValue();
     }
-  }
 
-  for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
-    for (ctr=0; ctr < AeroFunctionsAtCG[axis_ctr].size(); ctr++) {
-      vFnativeAtCG(axis_ctr+1) += AeroFunctionsAtCG[axis_ctr][ctr]->GetValue();
+    array = &AeroFunctionsAtCG[axis_ctr];
+    for (f=array->begin(); f != array->end(); ++f) {
+      (*f)->cacheValue(true); // Same as above
+      vFnativeAtCG(axis_ctr+1) += (*f)->GetValue();
     }
   }
 
@@ -264,8 +272,14 @@ bool FGAerodynamics::Run(bool Holding)
   vMomentsMRC.InitMatrix();
 
   for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
-    for (ctr = 0; ctr < AeroFunctions[axis_ctr+3].size(); ctr++) {
-      vMomentsMRC(axis_ctr+1) += AeroFunctions[axis_ctr+3][ctr]->GetValue();
+    AeroFunctionArray* array = &AeroFunctions[axis_ctr+3];
+    for (AeroFunctionArray::iterator f=array->begin(); f != array->end(); ++f) {
+      // Tell the Functions to cache values, so when the function values are
+      // being requested for output, the functions do not get calculated again
+      // in a context that might have changed, but instead use the values that
+      // have already been calculated for this frame.
+      (*f)->cacheValue(true);
+      vMomentsMRC(axis_ctr+1) += (*f)->GetValue();
     }
   }
   vMoments = vMomentsMRC + vDXYZcg*vForces; // M = r X F
@@ -283,7 +297,7 @@ bool FGAerodynamics::Run(bool Holding)
 
 bool FGAerodynamics::Load(Element *document)
 {
-  string parameter, axis, scratch;
+  string axis;
   string scratch_unit="";
   Element *temp_element, *axis_element, *function_element;
 
@@ -333,7 +347,7 @@ bool FGAerodynamics::Load(Element *document)
       if (!apply_at_cg) {
       try {
         ca.push_back( new FGFunction(PropertyManager, function_element) );
-      } catch (string const str) {
+      } catch (const string& str) {
         cerr << endl << fgred << "Error loading aerodynamic function in " 
              << current_func_name << ":" << str << " Aborting." << reset << endl;
         return false;
@@ -341,7 +355,7 @@ bool FGAerodynamics::Load(Element *document)
       } else {
         try {
           ca_atCG.push_back( new FGFunction(PropertyManager, function_element) );
-        } catch (string const str) {
+        } catch (const string& str) {
           cerr << endl << fgred << "Error loading aerodynamic function in " 
                << current_func_name << ":" << str << " Aborting." << reset << endl;
           return false;
index 3a51c046dbd88a15b7fd3b2122eff6cc2e43d9db..b4eef4f31c4c97e5f66c924a84b57492ad8b6a68 100644 (file)
@@ -51,7 +51,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGAuxiliary.cpp,v 1.71 2016/01/10 12:12:59 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGAuxiliary.cpp,v 1.72 2016/05/21 11:45:22 bcoconni Exp $");
 IDENT(IdHdr,ID_AUXILIARY);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -160,7 +160,6 @@ bool FGAuxiliary::Run(bool Holding)
   double AeroV2 = vAeroUVW(eV)*vAeroUVW(eV);
   double AeroW2 = vAeroUVW(eW)*vAeroUVW(eW);
   double mUW = AeroU2 + AeroW2;
-  double Vtdot = (vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eV)*in.vUVWdot(eV) + vAeroUVW(eW)*in.vUVWdot(eW))/Vt;
 
   double Vt2 = Vt*Vt;
 
@@ -174,6 +173,7 @@ bool FGAuxiliary::Run(bool Holding)
     //if (vAeroUVW(eU) < 0.0) signU=-1;
 
     if ( mUW >= 0.001 ) {
+      double Vtdot = (vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eV)*in.vUVWdot(eV) + vAeroUVW(eW)*in.vUVWdot(eW))/Vt;
       adot = (vAeroUVW(eU)*in.vUVWdot(eW) - vAeroUVW(eW)*in.vUVWdot(eU))/mUW;
       // bdot = (signU*mUW*in.vUVWdot(eV)
       //        - vAeroUVW(eV)*(vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eW)*in.vUVWdot(eW)))/(Vt2*sqrt(mUW));
index 84bc7c412a62330b26694089913c46afe80d1526..134a88f3d680d1f917c4eecb568d53e8294c68c1 100644 (file)
@@ -70,20 +70,21 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.94 2016/04/03 11:13:19 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.95 2016/05/16 18:19:57 bcoconni Exp $");
 IDENT(IdHdr,ID_FCS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex), ChannelRate(1)
+FGFCS::FGFCS(FGFDMExec* fdm) : FGModel(fdm), ChannelRate(1)
 {
   int i;
   Name = "FGFCS";
   systype = stFCS;
 
-  DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
+  fdmex = fdm;
+  DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = 0;
   PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
   GearCmd = GearPos = 1; // default to gear down
   BrakePos.resize(FGLGear::bgNumBrakeGroups);
@@ -108,7 +109,6 @@ FGFCS::~FGFCS()
   MixturePos.clear();
   PropAdvanceCmd.clear();
   PropAdvance.clear();
-  SteerPosDeg.clear();
   PropFeatherCmd.clear();
   PropFeather.clear();
 
@@ -135,7 +135,7 @@ bool FGFCS::InitModel(void)
   for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = 0.0;
   for (i=0; i<PropFeather.size(); i++) PropFeather[i] = 0.0;
 
-  DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
+  DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = 0;
   PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
   TailhookPos = WingFoldPos = 0.0;
 
@@ -172,12 +172,6 @@ bool FGFCS::Run(bool Holding)
   for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
   for (i=0; i<PropFeather.size(); i++) PropFeather[i] = PropFeatherCmd[i];
 
-  // Set the default steering angle
-  for (i=0; i<SteerPosDeg.size(); i++) {
-    FGLGear* gear = FDMExec->GetGroundReactions()->GetGearUnit(i);
-    SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
-  }
-
   // Execute system channels in order
   for (i=0; i<SystemChannels.size(); i++) {
     if (debug_lvl & 4) cout << "    Executing System Channel: " << SystemChannels[i]->GetName() << endl;
@@ -503,8 +497,6 @@ bool FGFCS::Load(Element* document)
 
   Debug(2);
 
-  if (systype == stFCS) bindModel();
-
   Element* channel_element = document->FindElement("channel");
   
   while (channel_element) {
@@ -688,14 +680,6 @@ void FGFCS::AddThrottle(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGFCS::AddGear(unsigned int NumGear)
-{
-  SteerPosDeg.clear();
-  for (unsigned int i=0; i<NumGear; i++) SteerPosDeg.push_back(0.0);
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 double FGFCS::GetDt(void) const
 {
   return FDMExec->GetDeltaT()*rate;
@@ -754,7 +738,6 @@ void FGFCS::bind(void)
   PropertyManager->Tie("fcs/left-brake-cmd-norm", this, &FGFCS::GetLBrake, &FGFCS::SetLBrake);
   PropertyManager->Tie("fcs/right-brake-cmd-norm", this, &FGFCS::GetRBrake, &FGFCS::SetRBrake);
   PropertyManager->Tie("fcs/center-brake-cmd-norm", this, &FGFCS::GetCBrake, &FGFCS::SetCBrake);
-  PropertyManager->Tie("fcs/steer-cmd-norm", this, &FGFCS::GetDsCmd, &FGFCS::SetDsCmd);
 
   PropertyManager->Tie("gear/tailhook-pos-norm", this, &FGFCS::GetTailhookPos, &FGFCS::SetTailhookPos);
   PropertyManager->Tie("fcs/wing-fold-pos-norm", this, &FGFCS::GetWingFoldPos, &FGFCS::SetWingFoldPos);
@@ -795,21 +778,6 @@ void FGFCS::bindThrottle(unsigned int num)
                                         &FGFCS::SetPropFeather);
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCS::bindModel(void)
-{
-  unsigned int i;
-  string tmp;
-
-  for (i=0; i<SteerPosDeg.size(); i++) {
-    if (FDMExec->GetGroundReactions()->GetGearUnit(i)->GetSteerable()) {
-      tmp = CreateIndexedPropertyName("fcs/steer-pos-deg", i);
-      PropertyManager->Tie( tmp.c_str(), this, i, &FGFCS::GetSteerPosDeg, &FGFCS::SetSteerPosDeg);
-    }
-  }
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //    The bitmasked value choices are as follows:
 //    unset: In this case (the default) JSBSim would only print
index ed291188fbb1555903c20a1bac5013f8f91f009d..fabb7dd1a8892e3dd3fef353dc516880ca229c71 100644 (file)
@@ -44,12 +44,13 @@ INCLUDES
 
 #include "models/FGModel.h"
 #include "models/FGLGear.h"
+#include "models/FGGroundReactions.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FCS "$Id: FGFCS.h,v 1.50 2016/02/27 16:54:15 bcoconni Exp $"
+#define ID_FCS "$Id: FGFCS.h,v 1.53 2016/05/18 08:06:57 ehofman Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -167,7 +168,7 @@ CLASS DOCUMENTATION
     @property gear/tailhook-pos-norm
 
     @author Jon S. Berndt
-    @version $Revision: 1.50 $
+    @version $Revision: 1.53 $
     @see FGActuator
     @see FGDeadBand
     @see FGFCSFunction
@@ -225,8 +226,8 @@ public:
   double GetDrCmd(void) const { return DrCmd; }
 
   /** Gets the steering command.
-      @return steering command in range from -1.0 - 1.0 */
-  double GetDsCmd(void) const { return DsCmd; }
+       @return steering command in range from -1.0 - 1.0 */
+   double GetDsCmd(void) const { return fdmex->GetGroundReactions()->GetDsCmd(); }
 
   /** Gets the flaps command.
       @return flaps command in range from 0 to 1.0 */
@@ -333,12 +334,6 @@ public:
 
   const std::vector<double>& GetMixturePos() const {return MixturePos;}
 
-  /** Gets the steering position.
-      @return steering position in degrees */
-  double GetSteerPosDeg(int gear) const { return SteerPosDeg[gear]; }
-
-  const std::vector<double>& GetSteerPosDeg() const {return SteerPosDeg;}
-
   /** Gets the gear position (0 up, 1 down), defaults to down
       @return gear position (0 up, 1 down) */
   double GetGearPos(void) const { return GearPos; }
@@ -392,8 +387,8 @@ public:
   void SetDrCmd(double cmd) { DrCmd = cmd; }
 
   /** Sets the steering command
-      @param cmd steering command in percent*/
-  void SetDsCmd(double cmd) { DsCmd = cmd; }
+       @param cmd steering command in percent*/
+   void SetDsCmd(double cmd) { fdmex->GetGroundReactions()->SetDsCmd( cmd ); }
 
   /** Sets the flaps command
       @param cmd flaps command in percent*/
@@ -484,10 +479,6 @@ public:
       @param cmd normalized mixture setting (0.0 - 1.0)*/
   void SetMixturePos(int engine, double cmd);
 
-  /** Sets the steering position
-      @param cmd steering position in degrees*/
-  void SetSteerPosDeg(int gear, double pos) { SteerPosDeg[gear] = pos; }
-
   /** Set the gear extend/retract position, defaults to down
       @param gear position 0 up, 1 down       */
    void SetGearPos(double gearpos) { GearPos = gearpos; }
@@ -556,7 +547,6 @@ public:
   std::string FindFullPathName(const std::string& system_filename) const;
 
   void AddThrottle(void);
-  void AddGear(unsigned int NumGear);
   double GetDt(void) const;
 
   FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
@@ -565,7 +555,7 @@ public:
   double GetChannelDeltaT(void) const { return GetDt() * ChannelRate; }
 
 private:
-  double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
+  double DaCmd, DeCmd, DrCmd, DfCmd, DsbCmd, DspCmd;
   double DePos[NForms], DaLPos[NForms], DaRPos[NForms], DrPos[NForms];
   double DfPos[NForms], DsbPos[NForms], DspPos[NForms];
   double PTrimCmd, YTrimCmd, RTrimCmd;
@@ -577,18 +567,17 @@ private:
   std::vector <double> PropAdvance;
   std::vector <bool> PropFeatherCmd;
   std::vector <bool> PropFeather;
-  std::vector <double> SteerPosDeg;
   //double LeftBrake, RightBrake, CenterBrake; // Brake settings
   std::vector <double> BrakePos; // left, center, right - defined by FGLGear:: enum
   double GearCmd,GearPos;
   double TailhookPos, WingFoldPos;
   SystemType systype;
   int ChannelRate;
+  FGFDMExec* fdmex;
 
   typedef std::vector <FGFCSChannel*> Channels;
   Channels SystemChannels;
   void bind(void);
-  void bindModel(void);
   void bindThrottle(unsigned int);
   void Debug(int from);
 };
index 8e9bcb5f37500a21a529ad88e7e9ff26a3d7c850..1e8ae271cbf5935eeffb21e4f75bc39d13b16ae3 100644 (file)
@@ -48,7 +48,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.51 2014/06/09 11:52:07 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.52 2016/05/16 18:19:57 bcoconni Exp $");
 IDENT(IdHdr,ID_GROUNDREACTIONS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -57,7 +57,8 @@ CLASS IMPLEMENTATION
 
 FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) :
    FGModel(fgex),
-   FGSurface(fgex)
+   FGSurface(fgex),
+   DsCmd(0.0)
 {
   Name = "FGGroundReactions";
 
@@ -84,6 +85,7 @@ bool FGGroundReactions::InitModel(void)
 
   vForces.InitMatrix();
   vMoments.InitMatrix();
+  DsCmd = 0.0;
 
   multipliers.clear();
 
@@ -138,6 +140,15 @@ bool FGGroundReactions::GetWOW(void) const
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGGroundReactions::SetDsCmd(double cmd)
+{
+  DsCmd = cmd;
+  for (unsigned int i=0; i<lGear.size(); ++i)
+    lGear[i]->SetSteerCmd(cmd);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 bool FGGroundReactions::Load(Element* document)
 {
   int num=0;
@@ -258,6 +269,8 @@ void FGGroundReactions::bind(void)
 
   PropertyManager->Tie("gear/num-units", this, &FGGroundReactions::GetNumGearUnits);
   PropertyManager->Tie("gear/wow", this, &FGGroundReactions::GetWOW);
+  PropertyManager->Tie("fcs/steer-cmd-norm", this, &FGGroundReactions::GetDsCmd,
+                       &FGGroundReactions::SetDsCmd);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 339b1c5f84f8e84aab7766c598143fe475a4a6a4..fbb89e3a4263d7e75cd7ed72be59916a63af9884 100644 (file)
@@ -45,7 +45,7 @@ INCLUDES
 #include "FGLGear.h"
 #include "math/FGColumnVector3.h"
 
-#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.28 2014/01/16 09:03:04 ehofman Exp $"
+#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.30 2016/05/16 18:19:57 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -109,6 +109,14 @@ public:
       @return a pointer to the FGLGear instance of the gear unit requested */
   FGLGear* GetGearUnit(int gear) const { return lGear[gear]; }
 
+  /** Gets the steering command.
+      @return steering command in range from -1.0 - 1.0 */
+  double GetDsCmd(void) const { return DsCmd; }
+
+  /** Sets the steering command
+      @param cmd steering command in percent*/
+  void SetDsCmd(double cmd);
+
   void RegisterLagrangeMultiplier(LagrangeMultiplier* lmult) { multipliers.push_back(lmult); }
   std::vector <LagrangeMultiplier*>* GetMultipliersList(void) { return &multipliers; }
 
@@ -119,6 +127,7 @@ private:
   FGColumnVector3 vForces;
   FGColumnVector3 vMoments;
   std::vector <LagrangeMultiplier*> multipliers;
+  double DsCmd;
 
   void bind(void);
   void Debug(int from);
index d26ddbcbefd247938591b9ec12bbf8b35956b37e..3d552dddf3d908e5383dc0dcad19f200a1cb8879 100644 (file)
@@ -61,7 +61,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.120 2015/08/16 16:13:31 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.123 2016/05/16 18:19:57 bcoconni Exp $");
 IDENT(IdHdr,ID_LGEAR);
 
 // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
@@ -80,7 +80,8 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs&
   GearNumber(number),
   SteerAngle(0.0),
   Castered(false),
-  StaticFriction(false)
+  StaticFriction(false),
+  eSteerType(stSteer)
 {
   kSpring = bDamp = bDampRebound = dynamicFCoeff = staticFCoeff = rollingFCoeff = maxSteerAngle = 0;
   isRetractable = false;
@@ -154,7 +155,10 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs&
   if (el->FindElement("max_steer"))
     maxSteerAngle = el->FindElementValueAsNumberConvertTo("max_steer", "DEG");
 
-  if (maxSteerAngle == 360) {
+  Element* castered_el = el->FindElement("castered");
+
+  if ((maxSteerAngle == 360 && !castered_el)
+      || (castered_el && castered_el->GetDataAsNumber() != 0.0)) {
     eSteerType = stCaster;
     Castered = true;
   }
@@ -164,23 +168,6 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs&
   else
     eSteerType = stSteer;
 
-  Element* castering = el->FindElement("castered");
-  if (castering) {
-    if (castering->GetDataAsNumber() != 0.0) {
-      eSteerType = stCaster;
-      Castered = true;
-    }
-    else {
-      if (maxSteerAngle == 0.0) {
-        eSteerType = stFixed;
-      }
-      else {
-        eSteerType = stSteer;
-      }
-      Castered = false;
-    }
-  }
-
   GroundReactions = fdmex->GetGroundReactions();
 
   ForceY_Table = 0;
@@ -267,6 +254,7 @@ void FGLGear::ResetToIC(void)
   LandingDistanceTraveled = TakeoffDistanceTraveled = TakeoffDistanceTraveled50ft = 0.0;
   MaximumStrutForce = MaximumStrutTravel = 0.0;
   SinkRate = GroundSpeed = 0.0;
+  SteerAngle = 0.0;
 
   vWhlVelVec.InitMatrix();
 
@@ -460,7 +448,7 @@ void FGLGear::ComputeGroundFrame(void)
 
 void FGLGear::ComputeSlipAngle(void)
 {
-// Check that the speed is non-null otherwise use the current angle
+// Check that the speed is non-null otherwise keep the current angle
   if (vGroundWhlVel.Magnitude(eX,eY) > 1E-3)
     WheelSlip = -atan2(vGroundWhlVel(eY), fabs(vGroundWhlVel(eX)))*radtodeg;
 }
@@ -471,25 +459,10 @@ void FGLGear::ComputeSlipAngle(void)
 
 void FGLGear::ComputeSteeringAngle(void)
 {
-  switch (eSteerType) {
-  case stSteer:
-    SteerAngle = degtorad * in.SteerPosDeg[GearNumber];
-    break;
-  case stFixed:
-    SteerAngle = 0.0;
-    break;
-  case stCaster:
-    if (!Castered)
-      SteerAngle = degtorad * in.SteerPosDeg[GearNumber];
-    else {
-      // Check that the speed is non-null otherwise use the current angle
+  if (Castered) {
+      // Check that the speed is non-null otherwise keep the current angle
       if (vWhlVelVec.Magnitude(eX,eY) > 0.1)
         SteerAngle = atan2(vWhlVelVec(eY), fabs(vWhlVelVec(eX)));
-    }
-    break;
-  default:
-    cerr << "Improper steering type membership detected for this gear." << endl;
-    break;
   }
 }
 
@@ -845,6 +818,14 @@ void FGLGear::bind(void)
     property_name = base_property_name + "/pos-norm";
     PropertyManager->Tie( property_name.c_str(), &GearPos );
   }
+
+  if (eSteerType != stFixed) {
+    // This property allows the FCS to override the steering position angle that
+    // is set by the property fcs/steer-cmd-norm. The prefix fcs/ has been kept
+    // for backward compatibility.
+    string tmp = CreateIndexedPropertyName("fcs/steer-pos-deg", GearNumber);
+    PropertyManager->Tie(tmp.c_str(), this, &FGLGear::GetSteerAngleDeg, &FGLGear::SetSteerAngleDeg);
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index ed0fb862a3cd504cd02f2605b59b585af702becb..30c64195b5403ee62985143ba8c51f69797468c8 100644 (file)
@@ -49,7 +49,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_LGEAR "$Id: FGLGear.h,v 1.64 2014/01/28 09:42:21 ehofman Exp $"
+#define ID_LGEAR "$Id: FGLGear.h,v 1.65 2016/05/16 18:19:57 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -178,7 +178,7 @@ CLASS DOCUMENTATION
         </contact>
 @endcode
     @author Jon S. Berndt
-    @version $Id: FGLGear.h,v 1.64 2014/01/28 09:42:21 ehofman Exp $
+    @version $Id: FGLGear.h,v 1.65 2016/05/16 18:19:57 bcoconni Exp $
     @see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
      NASA-Ames", NASA CR-2497, January 1975
     @see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
@@ -210,7 +210,6 @@ public:
     FGColumnVector3 UVW;
     FGColumnVector3 vXYZcg; // CG coordinates expressed in the structural frame
     FGLocation Location;
-    std::vector <double> SteerPosDeg;
     std::vector <double> BrakePos;
     double FCSGearPos;
     double EmptyWeight;
@@ -275,7 +274,7 @@ public:
       @return true if reporting is turned on */
   bool GetReport(void) const  { return ReportEnable; }
   double GetSteerNorm(void) const { return radtodeg/maxSteerAngle*SteerAngle; }
-  double GetDefaultSteerAngle(double cmd) const { return cmd*maxSteerAngle; }
+  void SetSteerCmd(double cmd) { SetSteerAngleDeg(cmd * maxSteerAngle); }
   double GetstaticFCoeff(void) const { return staticFCoeff; }
 
   int  GetBrakeGroup(void) const   { return (int)eBrakeGrp; }
@@ -315,6 +314,10 @@ public:
   bool IsBogey(void) const             { return (eContactType == ctBOGEY);}
   double GetGearUnitPos(void) const;
   double GetSteerAngleDeg(void) const { return radtodeg*SteerAngle; }
+  void SetSteerAngleDeg(double angle) {
+    if (eSteerType != stFixed && !Castered)
+      SteerAngle = degtorad * angle;
+  }
 
   const struct Inputs& in;
 
index 6b356b6b3368a9ecacc910f0f0a77930f057efa6..57b839feb994359f0794b8cf58143658cc46585d 100644 (file)
@@ -79,7 +79,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGPropagate.cpp,v 1.130 2016/04/16 12:24:39 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGPropagate.cpp,v 1.131 2016/05/01 18:25:57 bcoconni Exp $");
 IDENT(IdHdr,ID_PROPAGATE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -222,16 +222,18 @@ bool FGPropagate::Run(bool Holding)
 
   // Propagate rotational / translational velocity, angular /translational position, respectively.
 
-  Integrate(VState.qAttitudeECI,      VState.vQtrndot,      VState.dqQtrndot,          dt, integrator_rotational_position);
-  Integrate(VState.vPQRi,             in.vPQRidot,          VState.dqPQRidot,          dt, integrator_rotational_rate);
-  Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
-  Integrate(VState.vInertialVelocity, in.vUVWidot,          VState.dqUVWidot,          dt, integrator_translational_rate);
+  if (!FDMExec->IntegrationSuspended()) {
+    Integrate(VState.qAttitudeECI,      VState.vQtrndot,      VState.dqQtrndot,          dt, integrator_rotational_position);
+    Integrate(VState.vPQRi,             in.vPQRidot,          VState.dqPQRidot,          dt, integrator_rotational_rate);
+    Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
+    Integrate(VState.vInertialVelocity, in.vUVWidot,          VState.dqUVWidot,          dt, integrator_translational_rate);
+  }
 
   // CAUTION : the order of the operations below is very important to get transformation
   // matrices that are consistent with the new state of the vehicle
 
   // 1. Update the Earth position angle (EPA)
-  VState.vLocation.IncrementEarthPositionAngle(in.vOmegaPlanet(eZ)*(in.DeltaT*rate));
+  VState.vLocation.IncrementEarthPositionAngle(in.vOmegaPlanet(eZ)*dt);
 
   // 2. Update the Ti2ec and Tec2i transforms from the updated EPA
   Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
index e886e5036dbe299fcbd744b52d4ffe7b01c7fc1f..7d61e22e6c1b1e2b7dafdedf8c1f0d2e1752ffc9 100644 (file)
@@ -65,7 +65,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.85 2016/01/02 17:42:53 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.87 2016/05/05 15:38:09 bcoconni Exp $");
 IDENT(IdHdr,ID_PROPULSION);
 
 extern short debug_lvl;
@@ -84,11 +84,9 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
   numOxiTanks = numFuelTanks = 0;
   ActiveEngine = -1; // -1: ALL, 0: Engine 1, 1: Engine 2 ...
   tankJ.InitMatrix();
-  refuel = dump = false;
   DumpRate = 0.0; 
   RefuelRate = 6000.0;
   FuelFreeze = false;
-  TotalFuelQuantity = 0.0;
   IsBound =
   HavePistonEngine =
   HaveTurbineEngine =
@@ -122,6 +120,9 @@ bool FGPropulsion::InitModel(void)
   vMoments.InitMatrix();
 
   for (unsigned int i=0; i<numTanks; i++) Tanks[i]->ResetToIC();
+  TotalFuelQuantity = 0.0;
+  TotalOxidizerQuantity = 0.0;
+  refuel = dump = false;
 
   for (unsigned int i=0; i<numEngines; i++)
     Engines[i]->ResetToIC();
@@ -151,15 +152,23 @@ bool FGPropulsion::Run(bool Holding)
   }
 
   TotalFuelQuantity = 0.0;
+  TotalOxidizerQuantity = 0.0;
   for (i=0; i<numTanks; i++) {
     Tanks[i]->Calculate( in.TotalDeltaT, in.TAT_c);
-    if (Tanks[i]->GetType() == FGTank::ttFUEL) {
+    switch (Tanks[i]->GetType()) {
+    case FGTank::ttFUEL:
       TotalFuelQuantity += Tanks[i]->GetContents();
+      break;
+    case FGTank::ttOXIDIZER:
+      TotalOxidizerQuantity += Tanks[i]->GetContents();
+      break;
+    default:
+      break;
     }
   }
 
-  if (refuel) DoRefuel( in.TotalDeltaT );
-  if (dump) DumpFuel( in.TotalDeltaT );
+  if (refuel.node() && refuel) DoRefuel( in.TotalDeltaT );
+  if (dump.node() && dump) DumpFuel( in.TotalDeltaT );
 
   RunPostFunctions();
 
@@ -765,17 +774,16 @@ void FGPropulsion::bind(void)
 
   PropertyManager->Tie("propulsion/active_engine", this, (iPMF)&FGPropulsion::GetActiveEngine,
                         &FGPropulsion::SetActiveEngine, true);
-  PropertyManager->Tie("propulsion/total-fuel-lbs", this, &FGPropulsion::GetTotalFuelQuantity);
-  PropertyManager->Tie("propulsion/refuel", this, &FGPropulsion::GetRefuel,
-                        &FGPropulsion::SetRefuel, true);
-  PropertyManager->Tie("propulsion/fuel_dump", this, &FGPropulsion::GetFuelDump,
-                        &FGPropulsion::SetFuelDump, true);
   PropertyManager->Tie("forces/fbx-prop-lbs", this, eX, (PMF)&FGPropulsion::GetForces);
   PropertyManager->Tie("forces/fby-prop-lbs", this, eY, (PMF)&FGPropulsion::GetForces);
   PropertyManager->Tie("forces/fbz-prop-lbs", this, eZ, (PMF)&FGPropulsion::GetForces);
   PropertyManager->Tie("moments/l-prop-lbsft", this, eX, (PMF)&FGPropulsion::GetMoments);
   PropertyManager->Tie("moments/m-prop-lbsft", this, eY, (PMF)&FGPropulsion::GetMoments);
   PropertyManager->Tie("moments/n-prop-lbsft", this, eZ, (PMF)&FGPropulsion::GetMoments);
+  TotalFuelQuantity = PropertyManager->CreatePropertyObject<double>("propulsion/total-fuel-lbs");
+  TotalOxidizerQuantity = PropertyManager->CreatePropertyObject<double>("propulsion/total-oxidizer-lbs");
+  refuel = PropertyManager->CreatePropertyObject<bool>("propulsion/refuel");
+  dump = PropertyManager->CreatePropertyObject<bool>("propulsion/fuel_dump");
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 40d1a1a05c6ad6593176825c75e46b43cb45ee48..0b95dc0b8f451d28bf1600987caa2aa9032e2795 100644 (file)
@@ -41,6 +41,7 @@ INCLUDES
 #include <vector>
 #include <iosfwd>
 
+#include "simgear/props/propertyObject.hxx"
 #include "FGModel.h"
 #include "propulsion/FGEngine.h"
 #include "math/FGMatrix33.h"
@@ -49,7 +50,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.35 2015/01/07 23:22:59 dpculp Exp $"
+#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.36 2016/05/05 15:38:08 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -92,7 +93,7 @@ CLASS DOCUMENTATION
   @endcode
 
     @author Jon S. Berndt
-    @version $Id: FGPropulsion.h,v 1.35 2015/01/07 23:22:59 dpculp Exp $
+    @version $Id: FGPropulsion.h,v 1.36 2016/05/05 15:38:08 bcoconni Exp $
     @see
     FGEngine
     FGTank
@@ -172,10 +173,6 @@ public:
   const FGColumnVector3& GetMoments(void) const {return vMoments;}
   double GetMoments(int n) const {return vMoments(n);}
 
-  bool GetRefuel(void) const {return refuel;}
-  void SetRefuel(bool setting) {refuel = setting;}
-  bool GetFuelDump(void) const {return dump;}
-  void SetFuelDump(bool setting) {dump = setting;}
   double Transfer(int source, int target, double amount);
   void DoRefuel(double time_slice);
   void DumpFuel(double time_slice);
@@ -186,7 +183,6 @@ public:
   std::string FindFullPathName(const std::string& filename) const;
   inline int GetActiveEngine(void) const {return ActiveEngine;}
   inline bool GetFuelFreeze(void) const {return FuelFreeze;}
-  double GetTotalFuelQuantity(void) const {return TotalFuelQuantity;}
 
   void SetMagnetos(int setting);
   void SetStarter(int setting);
@@ -212,10 +208,11 @@ private:
   FGColumnVector3 vTankXYZ;
   FGColumnVector3 vXYZtank_arm;
   FGMatrix33 tankJ;
-  bool refuel;
-  bool dump;
+  simgear::PropertyObject<bool> refuel;
+  simgear::PropertyObject<bool> dump;
   bool FuelFreeze;
-  double TotalFuelQuantity;
+  simgear::PropertyObject<double> TotalFuelQuantity;
+  simgear::PropertyObject<double> TotalOxidizerQuantity;
   double DumpRate;
   double RefuelRate;
   bool IsBound;
old mode 100644 (file)
new mode 100755 (executable)
index 0173ade..a57ceb9
@@ -46,7 +46,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGWaypoint.cpp,v 1.6 2015/09/20 20:53:13 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGWaypoint.cpp,v 1.8 2016/05/05 15:32:42 bcoconni Exp $");
 IDENT(IdHdr,ID_WAYPOINT);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -66,56 +66,80 @@ FGWaypoint::FGWaypoint(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, eleme
   source_longitude_unit = 1.0;
 
   if (element->FindElement("target_latitude") ) {
-    target_latitude_pNode = PropertyManager->GetNode(element->FindElementValue("target_latitude"));
+    target_latitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("target_latitude"));
     if (element->FindElement("target_latitude")->HasAttribute("unit")) {
       if (element->FindElement("target_latitude")->GetAttributeValue("unit") == "DEG") {
         target_latitude_unit = 0.017453293;
       }
     }
-  } else
-    throw("Target latitude is required for waypoint component: "+Name);
+  } else {
+    cerr << element->ReadFrom() << endl
+         << "Target latitude is required for waypoint component: " << Name
+         << endl;
+    throw("Malformed waypoint definition");
+  }
 
   if (element->FindElement("target_longitude") ) {
-    target_longitude_pNode = PropertyManager->GetNode(element->FindElementValue("target_longitude"));
+    target_longitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("target_longitude"));
     if (element->FindElement("target_longitude")->HasAttribute("unit")) {
       if (element->FindElement("target_longitude")->GetAttributeValue("unit") == "DEG") {
         target_longitude_unit = 0.017453293;
       }
     }
-  } else
-    throw("Target longitude is required for waypoint component: "+Name);
+  } else {
+    cerr << element->ReadFrom() << endl
+         << "Target longitude is required for waypoint component: " << Name
+         << endl;
+    throw("Malformed waypoint definition");
+  }
 
   if (element->FindElement("source_latitude") ) {
-    source_latitude_pNode = PropertyManager->GetNode(element->FindElementValue("source_latitude"));
+    source_latitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("source_latitude"));
     if (element->FindElement("source_latitude")->HasAttribute("unit")) {
       if (element->FindElement("source_latitude")->GetAttributeValue("unit") == "DEG") {
         source_latitude_unit = 0.017453293;
       }
     }
-  } else
-    throw("Source latitude is required for waypoint component: "+Name);
+  } else {
+    cerr << element->ReadFrom() << endl
+         << "Source latitude is required for waypoint component: " << Name
+         << endl;
+    throw("Malformed waypoint definition");
+  }
 
   if (element->FindElement("source_longitude") ) {
-    source_longitude_pNode = PropertyManager->GetNode(element->FindElementValue("source_longitude"));
+    source_longitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("source_longitude"));
     if (element->FindElement("source_longitude")->HasAttribute("unit")) {
       if (element->FindElement("source_longitude")->GetAttributeValue("unit") == "DEG") {
         source_longitude_unit = 0.017453293;
       }
     }
-  } else
-    throw("Source longitude is required for waypoint component: "+Name);
+  } else {
+    cerr << element->ReadFrom() << endl
+         << "Source longitude is required for waypoint component: " << Name
+         << endl;
+    throw("Malformed waypoint definition");
+  }
 
   if (element->FindElement("radius"))
     radius = element->FindElementValueAsNumberConvertTo("radius", "FT");
-  else
-    radius = 21144000; // Radius of Earth in feet.
+  else {
+    FGLocation source(source_longitude * source_latitude_unit,
+                      source_latitude * source_longitude_unit, 1.0);
+    radius = source.GetSeaLevelRadius(); // Radius of Earth in feet.
+  }
 
   unit = element->GetAttributeValue("unit");
   if (WaypointType == eHeading) {
     if (!unit.empty()) {
       if      (unit == "DEG") eUnit = eDeg;
       else if (unit == "RAD") eUnit = eRad;
-      else throw("Unknown unit "+unit+" in HEADING waypoint component, "+Name);
+      else {
+        cerr << element->ReadFrom() << endl
+             << "Unknown unit " << unit << " in HEADING waypoint component, "
+             << Name << endl;
+        throw("Malformed waypoint definition");
+      }
     } else {
       eUnit = eRad; // Default is radians if unspecified
     }
@@ -123,7 +147,12 @@ FGWaypoint::FGWaypoint(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, eleme
     if (!unit.empty()) {
       if      (unit == "FT") eUnit = eFeet;
       else if (unit == "M")  eUnit = eMeters;
-      else throw("Unknown unit "+unit+" in DISTANCE waypoint component, "+Name);
+      else {
+        cerr << element->ReadFrom() << endl
+             << "Unknown unit " << unit << " in DISTANCE waypoint component, "
+             << Name << endl;
+        throw("Malformed waypoint definition");
+      }
     } else {
       eUnit = eFeet; // Default is feet if unspecified
     }
@@ -144,30 +173,24 @@ FGWaypoint::~FGWaypoint()
 
 bool FGWaypoint::Run(void )
 {
-  double target_latitude = target_latitude_pNode->getDoubleValue() * target_latitude_unit;
-  double target_longitude = target_longitude_pNode->getDoubleValue() * target_longitude_unit;
-  double source_latitude = source_latitude_pNode->getDoubleValue() * source_latitude_unit;
-  double source_longitude = source_longitude_pNode->getDoubleValue() * source_longitude_unit;
-  FGLocation source(source_longitude, source_latitude, radius);
+  double target_latitude_rad = target_latitude * target_latitude_unit;
+  double target_longitude_rad = target_longitude * target_longitude_unit;
+  FGLocation source(source_longitude * source_latitude_unit,
+                    source_latitude * source_longitude_unit, radius);
 
   if (WaypointType == eHeading) {     // Calculate Heading
-    double heading_to_waypoint_rad = source.GetHeadingTo(target_longitude,
-                                                         target_latitude);
+    double heading_to_waypoint_rad = source.GetHeadingTo(target_longitude_rad,
+                                                         target_latitude_rad);
 
-    double heading_to_waypoint = 0;
-    if (eUnit == eDeg) heading_to_waypoint = heading_to_waypoint_rad * radtodeg;
-    else               heading_to_waypoint = heading_to_waypoint_rad;
-
-    Output = heading_to_waypoint;
+    if (eUnit == eDeg) Output = heading_to_waypoint_rad * radtodeg;
+    else               Output = heading_to_waypoint_rad;
 
   } else {                            // Calculate Distance
-    double wp_distance = source.GetDistanceTo(target_longitude, target_latitude);
+    double wp_distance = source.GetDistanceTo(target_longitude_rad,
+                                              target_latitude_rad);
 
-    if (eUnit == eMeters) {
-      Output = FeetToMeters(wp_distance);
-    } else {
-      Output = wp_distance;
-    }
+    if (eUnit == eMeters) Output = FeetToMeters(wp_distance);
+    else                  Output = wp_distance;
   }
 
   Clip();
old mode 100644 (file)
new mode 100755 (executable)
index 999e973..be76852
@@ -38,13 +38,14 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include <string>
+#include "simgear/props/propertyObject.hxx"
 #include "FGFCSComponent.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_WAYPOINT "$Id: FGWaypoint.h,v 1.3 2015/09/20 20:53:13 bcoconni Exp $"
+#define ID_WAYPOINT "$Id: FGWaypoint.h,v 1.4 2016/04/17 13:19:39 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -92,7 +93,7 @@ CLASS DOCUMENTATION
     @endcode
 
     @author Jon S. Berndt
-    @version $Id: FGWaypoint.h,v 1.3 2015/09/20 20:53:13 bcoconni Exp $
+    @version $Id: FGWaypoint.h,v 1.4 2016/04/17 13:19:39 bcoconni Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -108,10 +109,10 @@ public:
   bool Run(void);
 
 private:
-  FGPropertyNode_ptr target_latitude_pNode;
-  FGPropertyNode_ptr target_longitude_pNode;
-  FGPropertyNode_ptr source_latitude_pNode;
-  FGPropertyNode_ptr source_longitude_pNode;
+  simgear::PropertyObject<double> target_latitude;
+  simgear::PropertyObject<double> target_longitude;
+  simgear::PropertyObject<double> source_latitude;
+  simgear::PropertyObject<double> source_longitude;
   double target_latitude_unit;
   double target_longitude_unit;
   double source_latitude_unit;
index d2c73f3a53171a827c314298b27e36af8b2394ad..e4e8348e88eb0a3faf8d18b2c449ed8f91c9ae9f 100644 (file)
@@ -48,7 +48,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGTank.cpp,v 1.44 2015/12/02 04:23:26 dpculp Exp $");
+IDENT(IdSrc,"$Id: FGTank.cpp,v 1.45 2016/05/05 17:23:10 bcoconni Exp $");
 IDENT(IdHdr,ID_TANK);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -84,7 +84,8 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
 
   element = el->FindElement("location");
   if (element)  vXYZ = element->FindElementTripletConvertTo("IN");
-  else          cerr << "No location found for this tank." << endl;
+  else          cerr << el->ReadFrom() << "No location found for this tank."
+                     << endl;
 
   vXYZ_drain = vXYZ; // Set initial drain location to initial tank CG
 
@@ -116,13 +117,15 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
   SetPriority( InitialPriority );     // this will also set the Selected flag
 
   if (Capacity == 0) {
-    cerr << "Tank capacity must not be zero. Reset to 0.00001 lbs!" << endl;
+    cerr << el->ReadFrom()
+         << "Tank capacity must not be zero. Reset to 0.00001 lbs!" << endl;
     Capacity = 0.00001;
     Contents = 0.0;
   }
   if (Contents > Capacity) {
-    cerr << "Tank content (" << Contents << " lbs) is greater than tank capacity ("
-         << Capacity << " lbs) for tank " << tank_number
+    cerr << el->ReadFrom() << "Tank content (" << Contents
+         << " lbs) is greater than tank capacity (" << Capacity
+         << " lbs) for tank " << tank_number
          << "! Did you accidentally swap contents and capacity?" << endl;
     throw("tank definition error");
   }
@@ -169,7 +172,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
         throw("For tank "+to_string(TankNumber)+" and when grain_config is specified an izz must be specified when the FUNCTION grain type is specified.");
       }
     }
-    else                               cerr << "Unknown propellant grain type specified" << endl;
+    else
+      cerr << el->ReadFrom() << "Unknown propellant grain type specified"
+           << endl;
 
     if (element_Grain->FindElement("length"))
       Length = element_Grain->FindElementValueAsNumberConvertTo("length", "IN");
@@ -181,7 +186,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
     switch (grainType) {
       case gtCYLINDRICAL:
         if (Radius <= InnerRadius) {
-          cerr << "The bore diameter should be smaller than the total grain diameter!" << endl;
+          cerr << element_Grain->ReadFrom()
+               << "The bore diameter should be smaller than the total grain diameter!"
+               << endl;
           exit(-1);
         }
         Volume = M_PI * Length * (Radius*Radius - InnerRadius*InnerRadius); // cubic inches
@@ -193,10 +200,12 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
         Volume = 1;  // Volume is irrelevant for the FUNCTION type, but it can't be zero!
         break;
       case gtUNKNOWN:
-        cerr << "Unknown grain type found in this rocket engine definition." << endl;
+        cerr << el->ReadFrom()
+             << "Unknown grain type found in this rocket engine definition."
+             << endl;
         exit(-1);
     }
-    Density = (Contents*lbtoslug)/Volume; // slugs/in^3
+    Density = (Capacity*lbtoslug)/Volume; // slugs/in^3
   }
 
   CalculateInertias();