]> git.mxchange.org Git - flightgear.git/commitdiff
JSBSim sync
authorbcoconni <bcoconni@users.sourceforge.net>
Sat, 15 Nov 2014 10:39:49 +0000 (11:39 +0100)
committerbcoconni <bcoconni@users.sourceforge.net>
Sat, 15 Nov 2014 10:39:49 +0000 (11:39 +0100)
46 files changed:
src/FDM/JSBSim/CMakeLists.txt
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/FGJSBBase.cpp
src/FDM/JSBSim/FGJSBBase.h
src/FDM/JSBSim/input_output/FGModelLoader.cpp [new file with mode: 0644]
src/FDM/JSBSim/input_output/FGModelLoader.h [new file with mode: 0644]
src/FDM/JSBSim/input_output/FGOutputType.cpp
src/FDM/JSBSim/input_output/FGPropertyReader.cpp
src/FDM/JSBSim/input_output/FGPropertyReader.h
src/FDM/JSBSim/input_output/FGScript.cpp
src/FDM/JSBSim/input_output/FGScript.h
src/FDM/JSBSim/input_output/FGXMLElement.cpp
src/FDM/JSBSim/input_output/FGXMLElement.h
src/FDM/JSBSim/input_output/FGXMLParse.cpp
src/FDM/JSBSim/input_output/FGXMLParse.h
src/FDM/JSBSim/math/FGLocation.cpp
src/FDM/JSBSim/math/FGLocation.h
src/FDM/JSBSim/math/FGModelFunctions.cpp
src/FDM/JSBSim/math/FGModelFunctions.h
src/FDM/JSBSim/math/FGRealValue.h
src/FDM/JSBSim/models/FGAerodynamics.cpp
src/FDM/JSBSim/models/FGAerodynamics.h
src/FDM/JSBSim/models/FGBuoyantForces.cpp
src/FDM/JSBSim/models/FGExternalReactions.cpp
src/FDM/JSBSim/models/FGFCS.cpp
src/FDM/JSBSim/models/FGFCS.h
src/FDM/JSBSim/models/FGGasCell.cpp
src/FDM/JSBSim/models/FGGasCell.h
src/FDM/JSBSim/models/FGGroundReactions.cpp
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/FGMassBalance.cpp
src/FDM/JSBSim/models/FGModel.cpp
src/FDM/JSBSim/models/FGModel.h
src/FDM/JSBSim/models/FGOutput.cpp
src/FDM/JSBSim/models/FGPropulsion.cpp
src/FDM/JSBSim/models/FGPropulsion.h
src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
src/FDM/JSBSim/models/flight_control/FGActuator.cpp
src/FDM/JSBSim/models/flight_control/FGActuator.h
src/FDM/JSBSim/models/propulsion/FGElectric.cpp
src/FDM/JSBSim/models/propulsion/FGEngine.cpp
src/FDM/JSBSim/models/propulsion/FGEngine.h
src/FDM/JSBSim/models/propulsion/FGPiston.cpp
src/FDM/JSBSim/models/propulsion/FGRocket.cpp
src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp

index 550d1eca8ccc0e092db8d5b33e5a5668fb87de71..aaa91ec29e7a81c5dda5a2177d35de9d83c49683 100644 (file)
@@ -25,6 +25,7 @@ set(HEADERS
     input_output/FGOutputSocket.h
     input_output/FGOutputTextFile.h
     input_output/FGOutputType.h
+    input_output/FGModelLoader.h
     math/FGParameter.h
     math/LagrangeMultiplier.h
     math/FGColumnVector3.h
@@ -119,6 +120,7 @@ set(SOURCES
     input_output/FGOutputSocket.cpp
     input_output/FGOutputTextFile.cpp
     input_output/FGOutputType.cpp
+    input_output/FGModelLoader.cpp
     math/FGColumnVector3.cpp
     math/FGCondition.cpp
     math/FGFunction.cpp
index 6d07c01e661cb8368a877757dd67af1dd6332f8a..b43cacba18902749d03dcc0e4f52e514d165354f 100644 (file)
@@ -76,7 +76,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.161 2014/05/17 15:35:53 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.163 2014/09/04 10:17:20 bcoconni Exp $");
 IDENT(IdHdr,ID_FDMEXEC);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -879,22 +879,13 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
       }
     }
 
-    // Process the output element[s]. This element is OPTIONAL, and there may be more than one.
+    // Process the output element[s]. This element is OPTIONAL, and there may be
+    // more than one.
     element = document->FindElement("output");
     while (element) {
-      string output_file_name = aircraftCfgFileName;
-
-      if (!element->GetAttributeValue("file").empty()) {
-        output_file_name = RootDir + element->GetAttributeValue("file");
-        result = ((FGOutput*)Models[eOutput])->SetDirectivesFile(output_file_name);
-      }
-      else
-        result = ((FGOutput*)Models[eOutput])->Load(element);
+      if (!static_cast<FGOutput*>(Models[eOutput])->Load(element))
+        return false;
 
-      if (!result) {
-        cerr << endl << "Aircraft output element has problems in file " << output_file_name << endl;
-        return result;
-      }
       element = document->FindNextElement("output");
     }
 
@@ -1246,6 +1237,7 @@ void FGFDMExec::DoLinearization(int mode)
 
 void FGFDMExec::SRand(int sr)
 {
+  gaussian_random_number_phase = 0;
   srand(sr);
 }
 
index b509fd1b8d6ef19672e9a8fc56174a3c64e31a5e..71ce71d6a9efad8c37d265ec0126b5d2eaad5685 100644 (file)
@@ -44,7 +44,7 @@ INCLUDES
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGJSBBase.cpp,v 1.38 2014/01/13 10:45:59 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGJSBBase.cpp,v 1.39 2014/09/03 17:35:04 bcoconni Exp $");
 IDENT(IdHdr,ID_JSBBASE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -112,6 +112,8 @@ std::queue <FGJSBBase::Message> FGJSBBase::Messages;
 FGJSBBase::Message FGJSBBase::localMsg;
 unsigned int FGJSBBase::messageId = 0;
 
+int FGJSBBase::gaussian_random_number_phase = 0;
+
 short FGJSBBase::debug_lvl  = 1;
 
 using std::cerr;
@@ -257,10 +259,9 @@ string FGJSBBase::CreateIndexedPropertyName(const string& Property, int index)
 double FGJSBBase::GaussianRandomNumber(void)
 {
   static double V1, V2, S;
-  static int phase = 0;
   double X;
 
-  if (phase == 0) {
+  if (gaussian_random_number_phase == 0) {
     V1 = V2 = S = X = 0.0;
 
     do {
@@ -276,7 +277,7 @@ double FGJSBBase::GaussianRandomNumber(void)
   } else
     X = V2 * sqrt(-2 * log(S) / S);
 
-  phase = 1 - phase;
+  gaussian_random_number_phase = 1 - gaussian_random_number_phase;
 
   return X;
 }
index 3dd78df9d7bf228626fbd08154fca36f490e7975..c0200d4840bdf01d4ecf5acc416f13ea21ac1715 100644 (file)
@@ -57,7 +57,7 @@ using std::max;
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.39 2014/01/13 10:45:59 ehofman Exp $"
+#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.41 2014/09/03 17:35:04 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -73,7 +73,7 @@ CLASS DOCUMENTATION
 *   This class provides universal constants, utility functions, messaging
 *   functions, and enumerated constants to JSBSim.
     @author Jon S. Berndt
-    @version $Id: FGJSBBase.h,v 1.39 2014/01/13 10:45:59 ehofman Exp $
+    @version $Id: FGJSBBase.h,v 1.41 2014/09/03 17:35:04 bcoconni Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -329,6 +329,8 @@ public:
   
   static double sign(double num) {return num>=0.0?1.0:-1.0;}
 
+  static double GaussianRandomNumber(void);
+
 protected:
   static Message localMsg;
 
@@ -363,7 +365,7 @@ protected:
 
   static std::string CreateIndexedPropertyName(const std::string& Property, int index);
 
-  static double GaussianRandomNumber(void);
+  static int gaussian_random_number_phase;
 
 public:
 /// Moments L, M, N
diff --git a/src/FDM/JSBSim/input_output/FGModelLoader.cpp b/src/FDM/JSBSim/input_output/FGModelLoader.cpp
new file mode 100644 (file)
index 0000000..7c84dc7
--- /dev/null
@@ -0,0 +1,110 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Module:       FGModelLoader.cpp
+ Author:       Bertrand Coconnier
+ Date started: 12/14/13
+ Purpose:      Read and manage XML data for models definition
+
+  ------------- Copyright (C) 2013 Bertrand Coconnier -------------
+
+ 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
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU Lesser General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+This is the place where the XML data is loaded in memory for an access during
+the models initialization.
+
+HISTORY
+--------------------------------------------------------------------------------
+12/14/13   BC    Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include "FGJSBBase.h"
+#include "FGModelLoader.h"
+#include "FGXMLFileRead.h"
+#include "models/FGModel.h"
+
+using namespace std;
+
+namespace JSBSim {
+
+IDENT(IdSrc, "$Id: FGModelLoader.cpp,v 1.1 2014/06/09 11:52:06 bcoconni Exp $");
+IDENT(IdHdr, ID_MODELLOADER);
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS IMPLEMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+Element_ptr FGModelLoader::Open(Element *el)
+{
+  Element_ptr document = el;
+  string fname = el->GetAttributeValue("file");
+
+  if (!fname.empty()) {
+    FGXMLFileRead XMLFileRead;
+    string file;
+
+    try {
+      file = model->FindFullPathName(fname);
+    }
+    catch(string& e) {
+      cerr << endl << el->ReadFrom()
+           << "Could not open file: " << e << endl;
+      return NULL;
+    }
+
+    if (CachedFiles.find(file) != CachedFiles.end())
+      document = CachedFiles[file];
+    else {
+      document = XMLFileRead.LoadXMLDocument(file);
+      if (document == 0L) {
+        cerr << endl << el->ReadFrom()
+             << "Could not open file: " << file << endl;
+        return NULL;
+      }
+      CachedFiles[file] = document;
+    }
+
+    if (document->GetName() != el->GetName()) {
+      document->SetParent(el);
+      el->AddChildElement(document);
+    }
+  }
+
+  return document;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+string CheckFullPathName(const string& path, const string& fname)
+{
+  string name = path + "/" + fname;
+
+  if (name.length() <=4 || name.substr(name.length()-4, 4) != ".xml")
+    name.append(".xml");
+
+  ifstream file(name.c_str());
+  if (!file.is_open())
+    return string();
+
+  return name;
+}
+}
diff --git a/src/FDM/JSBSim/input_output/FGModelLoader.h b/src/FDM/JSBSim/input_output/FGModelLoader.h
new file mode 100644 (file)
index 0000000..4c2b937
--- /dev/null
@@ -0,0 +1,81 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Header:       FGModelLoader.h
+ Author:       Bertrand Coconnier
+ Date started: 12/14/13
+
+ ------------- Copyright (C) 2013 Bertrand Coconnier -------------
+
+ 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
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU Lesser General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+HISTORY
+--------------------------------------------------------------------------------
+12/14/13   BC    Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+SENTRY
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#ifndef FGMODELLOADER_H
+#define FGMODELLOADER_H
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include <string>
+
+#include "FGXMLElement.h"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#define ID_MODELLOADER "$Id: FGModelLoader.h,v 1.1 2014/06/09 11:52:06 bcoconni Exp $"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+class FGModel;
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGModelLoader
+{
+public:
+  FGModelLoader(const FGModel* _model) : model(_model) {}
+  Element_ptr Open(Element *el);
+
+private:
+  const FGModel* model;
+  std::map<std::string, Element_ptr> CachedFiles;
+};
+
+ std::string CheckFullPathName(const std::string& path, const std::string& fname);
+}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+#endif
index 09cbc62b699c68dd2e29cde9c7e7418c154fdc80..362f50b4d6275688d031f0479a31d0c153de27d3 100644 (file)
@@ -46,7 +46,7 @@ INCLUDES
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGOutputType.cpp,v 1.10 2014/01/13 10:46:00 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGOutputType.cpp,v 1.11 2014/09/12 20:10:04 bcoconni Exp $");
 IDENT(IdHdr,ID_OUTPUTTYPE);
 
 using namespace std;
@@ -100,9 +100,6 @@ void FGOutputType::SetIdx(int idx)
 
 bool FGOutputType::Load(Element* element)
 {
-  // Perform base class Load.
-  PreLoad(element, PropertyManager);
-
   if (element->FindElementValue("simulation") == string("ON"))
     SubSystems += ssSimulation;
   if (element->FindElementValue("aerosurfaces") == string("ON"))
@@ -158,9 +155,6 @@ bool FGOutputType::Load(Element* element)
   }
   SetRate(outRate);
 
-  // FIXME : PostLoad should be called in the most derived class ?
-  PostLoad(element, PropertyManager);
-
   return true;
 }
 
index b6c001a53f8f1c666646efb6c485e11a379c7fe5..f2956cdbaad3c2a798ede50c949b2c92fa81a8af 100644 (file)
@@ -45,18 +45,20 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGPropertyReader.cpp,v 1.3 2014/01/13 10:46:00 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGPropertyReader.cpp,v 1.5 2014/06/14 11:58:31 bcoconni Exp $");
 IDENT(IdHdr,ID_PROPERTYREADER);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 bool FGPropertyReader::ResetToIC(void)
 {
-  map<FGPropertyNode_ptr, double>::iterator it = interface_prop_initial_value.begin();
+  map<SGPropertyNode_ptr, double>::iterator it = interface_prop_initial_value.begin();
   for (;it != interface_prop_initial_value.end(); ++it) {
-    FGPropertyNode* node = it->first;
+    SGPropertyNode* node = it->first;
     if (!node->getAttribute(SGPropertyNode::PRESERVE))
       node->setDoubleValue(it->second);
   }
@@ -66,8 +68,7 @@ bool FGPropertyReader::ResetToIC(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGPropertyReader::LoadProperties(Element* el, FGPropertyManager* PM,
-                                     bool override)
+void FGPropertyReader::Load(Element* el, FGPropertyManager* PM, bool override)
 {
   // Interface properties are all stored in the interface properties array.
   string interface_property_string = "";
@@ -83,7 +84,7 @@ void FGPropertyReader::LoadProperties(Element* el, FGPropertyManager* PM,
   }
 
   while (property_element) {
-    FGPropertyNode* node = 0;
+    SGPropertyNode* node = 0;
     double value=0.0;
     if ( ! property_element->GetAttributeValue("value").empty())
       value = property_element->GetAttributeValueAsNumber("value");
@@ -115,12 +116,20 @@ void FGPropertyReader::LoadProperties(Element* el, FGPropertyManager* PM,
        continue;
       }
     } else {
-      interface_properties.push_back(value);
-      PM->Tie(interface_property_string, &interface_properties.back());
-      if (FGJSBBase::debug_lvl > 0)
-        cout << "      " << interface_property_string << " (initial value: " 
-             << value << ")" << endl << endl;
-      node = PM->GetNode(interface_property_string);
+      node = PM->GetNode(interface_property_string, true);
+      if (node) {
+        node->setDoubleValue(value);
+
+        if (FGJSBBase::debug_lvl > 0)
+          cout << "      " << interface_property_string << " (initial value: " 
+               << value << ")" << endl << endl;
+      }
+      else {
+        cerr << "Could not create property " << interface_property_string
+             << endl;
+        property_element = el->FindNextElement("property");
+        continue;
+      }
     }
     interface_prop_initial_value[node] = value;
     if (property_element->GetAttributeValue("persistent") == string("true"))
index c50b363f242e50d925da48f6ff48e5f53094227f..d8539b438f09a1f3c14df0f430cec146727bc8c8 100644 (file)
@@ -38,16 +38,17 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <list>
+#include <vector>
 #include <map>
 
-#include "simgear/structure/SGSharedPtr.hxx"
+#include "simgear/props/props.hxx"
+#include "input_output/FGPropertyManager.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPERTYREADER "$Id: FGPropertyReader.h,v 1.1 2014/01/02 22:37:47 bcoconni Exp $"
+#define ID_PROPERTYREADER "$Id: FGPropertyReader.h,v 1.3 2014/06/14 11:58:31 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -56,8 +57,6 @@ FORWARD DECLARATIONS
 namespace JSBSim {
 
 class Element;
-class FGPropertyManager;
-class FGPropertyNode;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DOCUMENTATION
@@ -70,12 +69,32 @@ CLASS DECLARATION
 class FGPropertyReader
 {
 public:
-  void LoadProperties(Element* el, FGPropertyManager* PropertyManager, bool override);
+  FGPropertyReader() {}; // Needed because the copy constructor is private
+  void Load(Element* el, FGPropertyManager* PropertyManager, bool override);
   bool ResetToIC(void);
 
-protected:
-  std::list<double> interface_properties;
-  std::map<SGSharedPtr<FGPropertyNode>, double> interface_prop_initial_value;
+  class const_iterator
+  {
+  public:
+    const_iterator(void) {}
+    const_iterator(const std::map<SGPropertyNode_ptr, double>::const_iterator &it) : prop_it(it) {}
+    const_iterator& operator++() { ++prop_it; return *this; }
+    bool operator!=(const const_iterator& it) const { return prop_it != it.prop_it; }
+    FGPropertyNode* operator*() {
+      SGPropertyNode* node = prop_it->first;
+      return static_cast<FGPropertyNode*>(node);
+    }
+
+  private:
+    std::map<SGPropertyNode_ptr, double>::const_iterator prop_it;
+  };
+
+  const_iterator begin(void) const { return const_iterator(interface_prop_initial_value.begin()); }
+  const_iterator end(void) const { return const_iterator(interface_prop_initial_value.end()); }
+  bool empty(void) const { return interface_prop_initial_value.empty(); }
+
+private:
+  std::map<SGPropertyNode_ptr, double> interface_prop_initial_value;
 };
 }
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 5a259ba14b9ac836f3ffe7f2b6bc4aa4f36b0c09..12185869c25ddb8e7d62d7616c542da25955dd42 100644 (file)
@@ -46,16 +46,19 @@ INCLUDES
 #include <iomanip>
 
 #include "FGScript.h"
+#include "FGFDMExec.h"
 #include "input_output/FGXMLElement.h"
 #include "input_output/FGXMLFileRead.h"
-#include "initialization/FGTrim.h"
+#include "initialization/FGInitialCondition.h"
 #include "models/FGInput.h"
+#include "math/FGCondition.h"
+#include "math/FGFunction.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGScript.cpp,v 1.57 2014/05/17 15:33:08 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGScript.cpp,v 1.60 2014/06/08 12:50:05 bcoconni Exp $");
 IDENT(IdHdr,ID_FGSCRIPT);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -173,11 +176,11 @@ bool FGScript::LoadScript(string script, double deltaT, const string initfile)
       return false;
     }
 
-    initialize = element->GetAttributeValue("initialize");
     if (initfile.empty()) {
-    if (initialize.empty()) {
-      cerr << "Initialization file must be specified in use element." << endl;
-      return false;
+      initialize = element->GetAttributeValue("initialize");
+      if (initialize.empty()) {
+        cerr << "Initialization file must be specified in use element." << endl;
+        return false;
       }
     } else {
       cout << endl << "The initialization file specified in the script file (" << initialize
@@ -190,6 +193,12 @@ bool FGScript::LoadScript(string script, double deltaT, const string initfile)
     return false;
   }
 
+  FGInitialCondition *IC=FDMExec->GetIC();
+  if ( ! IC->Load( initialize )) {
+    cerr << "Initialization unsuccessful" << endl;
+    exit(-1);
+  }
+
   // Now, read input spec if given.
   if (input_element > 0) {
     FDMExec->GetInput()->Load(input_element);
@@ -208,7 +217,7 @@ bool FGScript::LoadScript(string script, double deltaT, const string initfile)
   // Read local property/value declarations
   int saved_debug_lvl = debug_lvl;
   debug_lvl = 0; // Disable messages
-  LoadProperties(run_element, PropertyManager, true);
+  LocalProperties.Load(run_element, PropertyManager, true);
   debug_lvl = saved_debug_lvl;
 
   // Read "events" from script
@@ -337,12 +346,6 @@ bool FGScript::LoadScript(string script, double deltaT, const string initfile)
 
   Debug(4);
 
-  FGInitialCondition *IC=FDMExec->GetIC();
-  if ( ! IC->Load( initialize )) {
-    cerr << "Initialization unsuccessful" << endl;
-    exit(-1);
-  }
-
   return true;
 }
 
@@ -350,7 +353,7 @@ bool FGScript::LoadScript(string script, double deltaT, const string initfile)
 
 void FGScript::ResetEvents(void)
 {
-  //ResetToIC();
+  //LocalProperties.ResetToIC();
 
   for (unsigned int i=0; i<Events.size(); i++)
     Events[i].reset();
@@ -550,15 +553,15 @@ void FGScript::Debug(int from)
         ceil(1.0/FDMExec->GetDeltaT()) << " Hz)" << endl;
       cout << endl;
 
-      map<FGPropertyNode_ptr, double>::iterator it = interface_prop_initial_value.begin();
-      for (; it != interface_prop_initial_value.end(); ++it) {
-        FGPropertyNode* node = it->first;
+      FGPropertyReader::const_iterator it;
+      for (it = LocalProperties.begin(); it != LocalProperties.end(); ++it) {
+        FGPropertyNode* node = *it;
         cout << "Local property: " << node->GetName()
              << " = " << node->getDoubleValue()
              << endl;
       }
       
-      if (!interface_prop_initial_value.empty()) cout << endl;
+      if (LocalProperties.empty()) cout << endl;
 
       for (unsigned i=0; i<Events.size(); i++) {
         cout << "Event " << i;
index 2b6b438791941fed1a217efd10ed98619e2f0a79..e04ef368e344abf88be76b75c0ec8957b97da4df 100644 (file)
@@ -40,17 +40,15 @@ INCLUDES
 #include <vector>
 #include <map>
 
-#include "FGFDMExec.h"
 #include "FGJSBBase.h"
-#include "math/FGFunction.h"
-#include "math/FGCondition.h"
 #include "FGPropertyReader.h"
+#include "input_output/FGPropertyManager.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FGSCRIPT "$Id: FGScript.h,v 1.28 2014/01/02 22:37:47 bcoconni Exp $"
+#define ID_FGSCRIPT "$Id: FGScript.h,v 1.29 2014/05/29 18:46:44 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -58,6 +56,10 @@ FORWARD DECLARATIONS
 
 namespace JSBSim {
 
+class FGFDMExec;
+class FGCondition;
+class FGFunction;
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DOCUMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -159,14 +161,14 @@ 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.28 2014/01/02 22:37:47 bcoconni Exp $"
+    @version "$Id: FGScript.h,v 1.29 2014/05/29 18:46:44 bcoconni Exp $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGScript : public FGPropertyReader, public FGJSBBase
+class FGScript : public FGJSBBase
 {
 public:
   /// Default constructor
@@ -258,6 +260,8 @@ private:
   double  EndTime;
   std::vector <struct event> Events;
 
+  FGPropertyReader LocalProperties;
+
   FGFDMExec* FDMExec;
   FGPropertyManager* PropertyManager;
   void Debug(int from);
index bae0bf1b05d9afd384af18110846bc2b27566989..dd9bce1cc0826cdf1efc5c612c568747c1992e8f 100644 (file)
@@ -35,6 +35,7 @@ INCLUDES
 
 #include "FGXMLElement.h"
 #include "string_utilities.h"
+#include "FGJSBBase.h"
 
 using namespace std;
 
@@ -44,7 +45,7 @@ FORWARD DECLARATIONS
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGXMLElement.cpp,v 1.48 2014/05/17 15:31:17 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGXMLElement.cpp,v 1.52 2014/06/29 10:13:18 bcoconni Exp $");
 IDENT(IdHdr,ID_XMLELEMENT);
 
 bool Element::converterIsInitialized = false;
@@ -242,9 +243,8 @@ Element::Element(const string& nm)
 
 Element::~Element(void)
 {
-  for (unsigned int i=0; i<children.size(); i++) delete children[i];
-  data_lines.clear();
-  attributes.clear();
+  for (unsigned int i = 0; i < children.size(); ++i)
+    children[i]->SetParent(0);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -257,11 +257,13 @@ string Element::GetAttributeValue(const string& attr)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool Element::HasAttribute(const string& attr)
+bool Element::SetAttributeValue(const std::string& key, const std::string& value)
 {
-  map<string, string>::iterator found = attributes.find(attr);
+  bool ret = HasAttribute(key);
+  if (ret)
+    attributes[key] = value;
 
-  return found != attributes.end();
+  return ret;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -588,7 +590,7 @@ double Element::DisperseValue(Element *e, double val, const std::string supplied
     if (!supplied_units.empty()) disp *= convert[supplied_units][target_units];
     string attType = e->GetAttributeValue("type");
     if (attType == "gaussian" || attType == "gaussiansigned") {
-      double grn = GaussianRandomNumber();
+      double grn = FGJSBBase::GaussianRandomNumber();
     if (attType == "gaussian") {
       value = val + disp*grn;
       } else { // Assume gaussiansigned
@@ -612,35 +614,6 @@ double Element::DisperseValue(Element *e, double val, const std::string supplied
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double Element::GaussianRandomNumber(void)
-{
-  static double V1, V2, S;
-  static int phase = 0;
-  double X;
-
-  if (phase == 0) {
-    V1 = V2 = S = X = 0.0;
-
-    do {
-      double U1 = (double)rand() / RAND_MAX;
-      double U2 = (double)rand() / RAND_MAX;
-
-      V1 = 2 * U1 - 1;
-      V2 = 2 * U2 - 1;
-      S = V1 * V1 + V2 * V2;
-    } while(S >= 1 || S == 0);
-
-    X = V1 * sqrt(-2 * log(S) / S);
-  } else
-    X = V2 * sqrt(-2 * log(S) / S);
-
-  phase = 1 - phase;
-
-  return X;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void Element::Print(unsigned int level)
 {
   unsigned int i, spaces;
@@ -694,4 +667,23 @@ string Element::ReadFrom(void) const
   return message.str();
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void Element::MergeAttributes(Element* el)
+{
+  map<string, string>::iterator it;
+
+  for (it=el->attributes.begin(); it != el->attributes.end(); ++it) {
+    if (attributes.find(it->first) == attributes.end())
+      attributes[it->first] = it->second;
+    else {
+      if (FGJSBBase::debug_lvl > 0)
+        cout << el->ReadFrom() << " Attribute '" << it->first << "' is overridden in file "
+             << GetFileName() << ": line " << GetLineNumber() << endl
+             << " The value '" << attributes[it->first] << "' will be used instead of '"
+             << it->second << "'." << endl;
+    }
+  }
+}
+
 } // end namespace JSBSim
index 9224b1eb87e2551ddb016d1a49f268648beb67ea..22c1f39a8989dec8e4811b198aa9bce71363eb22 100644 (file)
@@ -38,14 +38,14 @@ INCLUDES
 #include <map>
 #include <vector>
 
-#include "FGJSBBase.h"
+#include "simgear/structure/SGSharedPtr.hxx"
 #include "math/FGColumnVector3.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_XMLELEMENT "$Id: FGXMLElement.h,v 1.20 2014/01/13 10:46:02 ehofman Exp $"
+#define ID_XMLELEMENT "$Id: FGXMLElement.h,v 1.24 2014/06/29 10:13:18 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -137,14 +137,17 @@ CLASS DOCUMENTATION
     - GAL = gallon (U.S. liquid) 
 
     @author Jon S. Berndt
-    @version $Id: FGXMLElement.h,v 1.20 2014/01/13 10:46:02 ehofman Exp $
+    @version $Id: FGXMLElement.h,v 1.24 2014/06/29 10:13:18 bcoconni Exp $
 */
 
+class Element;
+typedef SGSharedPtr<Element> Element_ptr;
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class Element {
+class Element : public SGReferenced {
 public:
   /** Constructor
       @param nm the name of this element (if given)
@@ -156,7 +159,7 @@ public:
   /** Determines if an element has the supplied attribute.
       @param key specifies the attribute key to retrieve the value of.
       @return true or false. */
-  bool HasAttribute(const std::string& key);
+  bool HasAttribute(const std::string& key) {return attributes.find(key) != attributes.end();}
 
   /** Retrieves an attribute.
       @param key specifies the attribute key to retrieve the value of.
@@ -164,6 +167,14 @@ public:
               attribute exists. */
   std::string GetAttributeValue(const std::string& key);
 
+  /** Modifies an attribute.
+      @param key specifies the attribute key to modify the value of.
+      @param value new key value (as a string).
+      @return false if it did not find any attribute with the requested key,
+              true otherwise.
+   */
+  bool SetAttributeValue(const std::string& key, const std::string& value);
+
   /** Retrieves an attribute value as a double precision real number.
       @param key specifies the attribute key to retrieve the value of.
       @return the key value (as a number), or the HUGE_VAL if no such
@@ -359,11 +370,20 @@ public:
    */
   std::string ReadFrom(void) const;
 
+  /** Merges the attributes of the current element with another element. The
+   *  attributes from the current element override the element that is passed
+   *  as a parameter. In other words if the two elements have an attribute with
+   *  the same name, the attribute from the current element is kept and the
+   *  corresponding attribute of the other element is ignored.
+   *  @param el element with which the current element will merge its attributes.
+   */
+  void MergeAttributes(Element* el);
+
 private:
   std::string name;
   std::map <std::string, std::string> attributes;
   std::vector <std::string> data_lines;
-  std::vector <Element*> children;
+  std::vector <Element_ptr> children;
   Element *parent;
   unsigned int element_index;
   std::string file_name;
@@ -371,7 +391,6 @@ private:
   typedef std::map <std::string, std::map <std::string, double> > tMapConvert;
   static tMapConvert convert;
   static bool converterIsInitialized;
-  double GaussianRandomNumber(void);
 };
 
 } // namespace JSBSim
index e6b4c87c0493ded74ee6398f47990ccc284250cd..00b30457ff549d595f2b954539af3d2269f819f9 100644 (file)
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGXMLParse.h"
-#include "FGXMLElement.h"
 #include <string>
 #include <iostream>
 #include <cstdlib>
+
+#include "FGJSBBase.h"
+#include "FGXMLParse.h"
+#include "FGXMLElement.h"
 #include "input_output/string_utilities.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGXMLParse.cpp,v 1.14 2014/01/13 10:46:03 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGXMLParse.cpp,v 1.16 2014/06/09 11:52:06 bcoconni Exp $");
 IDENT(IdHdr,ID_XMLPARSE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGXMLParse.h"
-
 using namespace std;
 
 FGXMLParse::FGXMLParse(void)
@@ -59,13 +59,6 @@ FGXMLParse::FGXMLParse(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGXMLParse::~FGXMLParse(void)
-{
-  delete document;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void FGXMLParse::startXML(void)
 {
 }
@@ -74,7 +67,6 @@ void FGXMLParse::startXML(void)
 
 void FGXMLParse::reset(void)
 {
-  delete document;
   first_element_read = false;
   current_element = document = 0L;
 }
index 6367dbb93f73231c1f2ca5a92b1d3be108e1509c..68f61b7a0bf5b521c921dd4b86d25e2ad11e8207 100644 (file)
@@ -35,12 +35,13 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "simgear/xml/easyxml.hxx"
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_XMLPARSE "$Id: FGXMLParse.h,v 1.7 2009/10/24 22:59:30 jberndt Exp $"
+#define ID_XMLPARSE "$Id: FGXMLParse.h,v 1.9 2014/06/09 11:52:06 bcoconni Exp $"
 #define VALID_CHARS """`!@#$%^&*()_+`1234567890-={}[];':,.<>/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -57,7 +58,7 @@ CLASS DOCUMENTATION
 
 /** Encapsulates an XML parser based on the EasyXML parser from the SimGear library.
     @author Jon S. Berndt
-    @version $Id: FGXMLParse.h,v 1.7 2009/10/24 22:59:30 jberndt Exp $
+    @version $Id: FGXMLParse.h,v 1.9 2014/06/09 11:52:06 bcoconni Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -68,7 +69,6 @@ class FGXMLParse : public XMLVisitor
 {
 public:
   FGXMLParse(void);
-  virtual ~FGXMLParse(void);
 
   Element* GetDocument(void) {return document;}
 
@@ -84,7 +84,7 @@ public:
 private:
   bool first_element_read;
   mutable std::string working_string;
-  Element *document;
+  Element_ptr document;
   Element *current_element;
 };
 
index da418394435c4e73f04d3b6e0d59d26d0305c3b6..2094ecd6029ef37bc1206b1ceca54a81f24201b5 100644 (file)
@@ -47,10 +47,8 @@ INCLUDES
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGLocation.cpp,v 1.32 2014/01/13 10:46:03 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGLocation.cpp,v 1.33 2014/08/28 11:46:11 bcoconni Exp $");
 IDENT(IdHdr,ID_LOCATION);
-using std::cerr;
-using std::endl;
 
 // Set up the default ground callback object.
 FGGroundCallback_ptr FGLocation::GroundCallback = NULL;
@@ -62,13 +60,12 @@ CLASS IMPLEMENTATION
 FGLocation::FGLocation(void)
   : mECLoc(1.0, 0.0, 0.0), mCacheValid(false)
 {
-  a = b = a2 = b2 = 0.0;
-  e = e2 = f = 1.0;
-  eps2 = -1.0;
+  e2 = c = 0.0;
+  a = ec = ec2 = 1.0;
   epa = 0.0;
 
   mLon = mLat = mRadius = 0.0;
-  mGeodLat = GeodeticAltitude = initial_longitude = 0.0;
+  mGeodLat = GeodeticAltitude = 0.0;
 
   mTl2ec.InitMatrix();
   mTec2l.InitMatrix();
@@ -83,13 +80,12 @@ FGLocation::FGLocation(void)
 FGLocation::FGLocation(double lon, double lat, double radius)
   : mCacheValid(false)
 {
-  a = b = a2 = b2 = 0.0;
-  e = e2 = f = 1.0;
-  eps2 = -1.0;
+  e2 = c = 0.0;
+  a = ec = ec2 = 1.0;
   epa = 0.0;
 
   mLon = mLat = mRadius = 0.0;
-  mGeodLat = GeodeticAltitude = initial_longitude = 0.0;
+  mGeodLat = GeodeticAltitude = 0.0;
 
   mTl2ec.InitMatrix();
   mTec2l.InitMatrix();
@@ -112,13 +108,12 @@ FGLocation::FGLocation(double lon, double lat, double radius)
 FGLocation::FGLocation(const FGColumnVector3& lv)
   : mECLoc(lv), mCacheValid(false)
 {
-  a = b = a2 = b2 = 0.0;
-  e = e2 = f = 1.0;
-  eps2 = -1.0;
+  e2 = c = 0.0;
+  a = ec = ec2 = 1.0;
   epa = 0.0;
 
   mLon = mLat = mRadius = 0.0;
-  mGeodLat = GeodeticAltitude = initial_longitude = 0.0;
+  mGeodLat = GeodeticAltitude = 0.0;
 
   mTl2ec.InitMatrix();
   mTec2l.InitMatrix();
@@ -134,13 +129,10 @@ FGLocation::FGLocation(const FGLocation& l)
   : mECLoc(l.mECLoc), mCacheValid(l.mCacheValid)
 {
   a = l.a;
-  b = l.b;
-  a2 = l.a2;
-  b2 = l.b2;
   e2 = l.e2;
-  e = l.e;
-  eps2 = l.eps2;
-  f = l.f;
+  c = l.c;
+  ec = l.ec;
+  ec2 = l.ec2;
   epa = l.epa;
 
   /*ag
@@ -162,7 +154,6 @@ FGLocation::FGLocation(const FGLocation& l)
   mTi2l = l.mTi2l;
   mTl2i = l.mTl2i;
 
-  initial_longitude = l.initial_longitude;
   mGeodLat = l.mGeodLat;
   GeodeticAltitude = l.GeodeticAltitude;
 }
@@ -175,13 +166,10 @@ const FGLocation& FGLocation::operator=(const FGLocation& l)
   mCacheValid = l.mCacheValid;
 
   a = l.a;
-  b = l.b;
-  a2 = l.a2;
-  b2 = l.b2;
   e2 = l.e2;
-  e = l.e;
-  eps2 = l.eps2;
-  f = l.f;
+  c = l.c;
+  ec = l.ec;
+  ec2 = l.ec2;
   epa = l.epa;
 
   //ag See comment in constructor above
@@ -198,7 +186,6 @@ const FGLocation& FGLocation::operator=(const FGLocation& l)
   mTi2l = l.mTi2l;
   mTl2i = l.mTl2i;
 
-  initial_longitude = l.initial_longitude;
   mGeodLat = l.mGeodLat;
   GeodeticAltitude = l.GeodeticAltitude;
 
@@ -221,8 +208,6 @@ void FGLocation::SetLongitude(double longitude)
 
   mCacheValid = false;
 
-  // Need to figure out how to set the initial_longitude here
-
   mECLoc(eX) = rtmp*cos(longitude);
   mECLoc(eY) = rtmp*sin(longitude);
 }
@@ -274,7 +259,7 @@ void FGLocation::SetPosition(double lon, double lat, double radius)
   double cosLat = cos(lat);
   double sinLon = sin(lon);
   double cosLon = cos(lon);
-//  initial_longitude = lon;
+
   mECLoc = FGColumnVector3( radius*cosLat*cosLon,
                             radius*cosLat*sinLon,
                             radius*sinLat );
@@ -286,17 +271,13 @@ void FGLocation::SetPositionGeodetic(double lon, double lat, double height)
 {
   mCacheValid = false;
 
-  mGeodLat = lat;
-  mLon = lon;
-  GeodeticAltitude = height;
-
-//  initial_longitude = mLon;
+  double slat = sin(lat);
+  double clat = cos(lat);
+  double RN = a / sqrt(1.0 - e2*slat*slat);
 
-  double RN = a / sqrt(1.0 - e2*sin(mGeodLat)*sin(mGeodLat));
-
-  mECLoc(eX) = (RN + GeodeticAltitude)*cos(mGeodLat)*cos(mLon);
-  mECLoc(eY) = (RN + GeodeticAltitude)*cos(mGeodLat)*sin(mLon);
-  mECLoc(eZ) = ((1 - e2)*RN + GeodeticAltitude)*sin(mGeodLat);
+  mECLoc(eX) = (RN + height)*clat*cos(lon);
+  mECLoc(eY) = (RN + height)*clat*sin(lon);
+  mECLoc(eZ) = ((1 - e2)*RN + height)*slat;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -306,13 +287,10 @@ void FGLocation::SetEllipse(double semimajor, double semiminor)
   mCacheValid = false;
 
   a = semimajor;
-  b = semiminor;
-  a2 = a*a;
-  b2 = b*b;
-  e2 = 1.0 - b2/a2;
-  e = sqrt(e2);
-  eps2 = a2/b2 - 1.0;
-  f = 1.0 - b/a;
+  ec = semiminor/a;
+  ec2 = ec * ec;
+  e2 = 1.0 - ec2;
+  c = a * e2;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -387,51 +365,33 @@ void FGLocation::ComputeDerivedUnconditional(void) const
   mTl2i = mTec2i * mTl2ec;
   mTi2l = mTl2i.Transposed();
 
-  // Calculate the geodetic latitude base on AIAA Journal of Guidance and Control paper,
-  // "Improved Method for Calculating Exact Geodetic Latitude and Altitude", and
-  // "Improved Method for Calculating Exact Geodetic Latitude and Altitude, Revisited",
-  // author: I. Sofair
-
-  if (a != 0.0 && b != 0.0) {
-    double c, p, q, s, t, u, v, w, z, p2, u2, r0;
-    double Ne, P, Q0, Q, signz0, sqrt_q, z_term;
-    p  = fabs(mECLoc(eZ))/eps2;
-    s  = r02/(e2*eps2);
-    p2 = p*p;
-    q  = p2 - b2 + s;
-    if (q>0)
-    {
-      sqrt_q = sqrt(q);
-      u  = p/sqrt_q;
-      u2 = p2/q;
-      v  = b2*u2/q;
-      P  = 27.0*v*s/q;
-      Q0 = sqrt(P+1) + sqrt(P);
-      Q  = pow(Q0, 0.66666666667);
-      t  = (1.0 + Q + 1.0/Q)/6.0;
-      c  = sqrt(u2 - 1 + 2.0*t);
-      w  = (c - u)/2.0;
-      signz0 = mECLoc(eZ)>=0?1.0:-1.0;
-      z_term = sqrt(t*t+v)-u*w-0.5*t-0.25;
-      if (z_term < 0.0) {
-        z = 0.0;
-      } else {
-        z  = signz0*sqrt_q*(w+sqrt(z_term));
-      }
-      Ne = a*sqrt(1+eps2*z*z/b2);
-      double tmp = (eps2+1.0)*(z/Ne);
-      // Ugly hack to work around the round-off errors when the simulation is
-      // started at a latitude of 90deg.
-      if (tmp > 1.0)
-        tmp = 1.0;
-      else if (tmp < -1.0)
-        tmp = -1.0;
-      // End of ugly hack
-      mGeodLat = asin(tmp);
-      r0 = rxy;
-      GeodeticAltitude = r0*cos(mGeodLat) + mECLoc(eZ)*sin(mGeodLat) - a2/Ne;
-    }
-  }
+  // Calculate the geodetic latitude based on "Transformation from Cartesian
+  // to geodetic coordinates accelerated by Halley's method", Fukushima T. (2006)
+  // Journal of Geodesy, Vol. 79, pp. 689-693
+  // Unlike I. Sofair's method which uses a closed form solution, Fukushima's
+  // method is an iterative method whose convergence is so fast that only one
+  // iteration suffices. In addition, Fukushima's method has a much better
+  // numerical stability over Sofair's method at the North and South poles and
+  // it also gives the correct result for a spherical Earth.
+
+  double s0 = fabs(mECLoc(eZ));
+  double zc = ec * s0;
+  double c0 = ec * rxy;
+  double c02 = c0 * c0;
+  double s02 = s0 * s0;
+  double a02 = c02 + s02;
+  double a0 = sqrt(a02);
+  double a03 = a02 * a0;
+  double s1 = zc*a03 + c*s02*s0;
+  double c1 = rxy*a03 - c*c02*c0;
+  double cs0c0 = c*c0*s0;
+  double b0 = 1.5*cs0c0*((rxy*s0-zc*c0)*a0-cs0c0);
+  s1 = s1*a03-b0*s0;
+  double cc = ec*(c1*a03-b0*c0);
+  mGeodLat = sign(mECLoc(eZ))*atan(s1 / cc);
+  double s12 = s1 * s1;
+  double cc2 = cc * cc;
+  GeodeticAltitude = (rxy*cc + s0*s1 - a*sqrt(ec2*s12 + cc2)) / sqrt(s12 + cc2);
 
   // Mark the cached values as valid
   mCacheValid = true;
index cc8a86b21199d4cb8f5306b10c6d8272b29615c0..38a6c76cbe7dd3c3ee8c263ba3988536b4b6b318 100644 (file)
@@ -42,8 +42,6 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <iostream>
-
 #include "FGJSBBase.h"
 #include "FGColumnVector3.h"
 #include "FGMatrix33.h"
@@ -53,7 +51,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_LOCATION "$Id: FGLocation.h,v 1.32 2013/10/19 17:59:51 bcoconni Exp $"
+#define ID_LOCATION "$Id: FGLocation.h,v 1.33 2014/08/28 11:46:12 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -152,7 +150,7 @@ CLASS DOCUMENTATION
     @see W. C. Durham "Aircraft Dynamics & Control", section 2.2
 
     @author Mathias Froehlich
-    @version $Id: FGLocation.h,v 1.32 2013/10/19 17:59:51 bcoconni Exp $
+    @version $Id: FGLocation.h,v 1.33 2014/08/28 11:46:12 bcoconni Exp $
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -632,8 +630,6 @@ private:
   mutable double mGeodLat;
   mutable double GeodeticAltitude;
 
-  double initial_longitude;
-
   /** The cached rotation matrices from and to the associated frames. */
   mutable FGMatrix33 mTl2ec;
   mutable FGMatrix33 mTec2l;
@@ -645,14 +641,11 @@ private:
   double epa;
 
   /* Terms for geodetic latitude calculation. Values are from WGS84 model */
-  double a;    // Earth semimajor axis in feet (6,378,137.0 meters)
-  double b;    // Earth semiminor axis in feet (6,356,752.3142 meters)
-  double a2;
-  double b2;
-  double e;    // Earth eccentricity
+  double a;    // Earth semimajor axis in feet
   double e2;   // Earth eccentricity squared
-  double eps2; //
-  double f;    // Flattening
+  double c;
+  double ec;
+  double ec2;
 
   /** A data validity flag.
       This class implements caching of the derived values like the
index 957bf069712da26dbab3a1430fc84439720f027f..f82ef0cd1b1a53693de2ea752c9a0bf452402218 100644 (file)
@@ -40,6 +40,7 @@ INCLUDES
 #include <iostream>
 #include <sstream>
 #include <string>
+
 #include "FGModelFunctions.h"
 #include "FGFunction.h"
 #include "input_output/FGXMLElement.h"
@@ -48,7 +49,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGModelFunctions.cpp,v 1.12 2014/01/13 10:46:03 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGModelFunctions.cpp,v 1.14 2014/05/30 17:26:42 bcoconni Exp $");
 IDENT(IdHdr,ID_MODELFUNCTIONS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -67,7 +68,7 @@ FGModelFunctions::~FGModelFunctions()
 
 bool FGModelFunctions::InitModel(void)
 {
-  ResetToIC();
+  LocalProperties.ResetToIC();
 
   return true;
 }
@@ -76,7 +77,7 @@ bool FGModelFunctions::InitModel(void)
 
 bool FGModelFunctions::Load(Element* el, FGPropertyManager* PM, string prefix)
 {
-  LoadProperties(el, PM, false);
+  LocalProperties.Load(el, PM, false);
   PreLoad(el, PM, prefix);
 
   return true; // TODO: Need to make this value mean something.
@@ -91,18 +92,10 @@ void FGModelFunctions::PreLoad(Element* el, FGPropertyManager* PM, string prefix
   Element *function = el->FindElement("function");
 
   while (function) {
-    if (function->GetAttributeValue("type") == "pre") {
+    string fType = function->GetAttributeValue("type");
+    if (fType.empty() || fType == "pre")
       PreFunctions.push_back(new FGFunction(PM, function, prefix));
-    } else if (function->GetAttributeValue("type").empty()) { // Assume pre-function
-      string funcname = function->GetAttributeValue("name");
-      if (funcname.find("IdleThrust") == string::npos && // Do not process functions that are
-          funcname.find("MilThrust") == string::npos  && // already pre-defined turbine engine
-          funcname.find("AugThrust") == string::npos  && // functions. These are loaded within
-          funcname.find("Injection") == string::npos )   // the Turbine::Load() method.
-      {
-        PreFunctions.push_back(new FGFunction(PM, function, prefix));
-      }
-    }
+
     function = el->FindNextElement("function");
   }
 }
@@ -152,6 +145,22 @@ void FGModelFunctions::RunPostFunctions(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+FGFunction* FGModelFunctions::GetPreFunction(const std::string& name)
+{
+  FGFunction* result;
+  vector<FGFunction*>::iterator it = PreFunctions.begin();
+
+  for (; it != PreFunctions.end(); ++it) {
+    result = *it;
+    if (result->GetName() == name)
+      return result;
+  }
+
+  return 0;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 string FGModelFunctions::GetFunctionStrings(const string& delimeter) const
 {
   string FunctionStrings = "";
index f67c203fb23567216a30d110d4cdaf314af84d41..7d3d2d6646ef94165010efabb251baa3678e94f9 100644 (file)
@@ -45,7 +45,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_MODELFUNCTIONS "$Id: FGModelFunctions.h,v 1.9 2014/01/02 22:37:48 bcoconni Exp $"
+#define ID_MODELFUNCTIONS "$Id: FGModelFunctions.h,v 1.11 2014/05/30 17:26:42 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -78,7 +78,7 @@ CLASS DOCUMENTATION
 DECLARATION: FGModelFunctions
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGModelFunctions : public FGPropertyReader, public FGJSBBase
+class FGModelFunctions : public FGJSBBase
 {
 public:
   virtual ~FGModelFunctions();
@@ -99,9 +99,16 @@ public:
       functions */
   std::string GetFunctionValues(const std::string& delimeter) const;
 
+  /** Get one of the "pre" function
+      @param name the name of the requested function.
+      @return a pointer to the function (NULL if not found)
+   */
+  FGFunction* GetPreFunction(const std::string& name);
+
 protected:
   std::vector <FGFunction*> PreFunctions;
   std::vector <FGFunction*> PostFunctions;
+  FGPropertyReader LocalProperties;
 
   virtual bool InitModel(void);
 };
index 9564eabf7de564829046bb1079d0925af9837e31..9e7eef8b376741ec98e26c33c6224c21b84eabfe 100644 (file)
@@ -35,12 +35,13 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGParameter.h"
+#include "input_output/string_utilities.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_REALVALUE "$Id: FGRealValue.h,v 1.5 2011/04/05 20:20:21 andgi Exp $"
+#define ID_REALVALUE "$Id: FGRealValue.h,v 1.6 2014/08/28 13:44:27 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -68,7 +69,8 @@ public:
   ~FGRealValue() {};
 
   double GetValue(void) const;
-  std::string GetName(void) const {return "constant";}
+  std::string GetName(void) const
+  { return std::string("constant value ") + to_string(Value); }
 
 private:
   double Value;
index a7aedb19e87e44b68af21ebf73b85ab9f97024f1..e870d0f74e66315257615fca5d6569661c09bffa 100644 (file)
@@ -44,14 +44,13 @@ INCLUDES
 #include "FGFDMExec.h"
 #include "FGAerodynamics.h"
 #include "input_output/FGPropertyManager.h"
-#include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.53 2014/05/17 15:30:35 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.55 2014/09/03 17:26:28 bcoconni Exp $");
 IDENT(IdHdr,ID_AERODYNAMICS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -84,6 +83,7 @@ FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec)
 
   impending_stall = stall_hyst = 0.0;
   alphaclmin = alphaclmax = 0.0;
+  alphaclmin0 = alphaclmax0 = 0.0;
   alphahystmin = alphahystmax = 0.0;
   clsq = lod = 0.0;
   alphaw = 0.0;
@@ -124,7 +124,8 @@ bool FGAerodynamics::InitModel(void)
   if (!FGModel::InitModel()) return false;
 
   impending_stall = stall_hyst = 0.0;
-  alphaclmin = alphaclmax = 0.0;
+  alphaclmin = alphaclmin0;
+  alphaclmax = alphaclmax0;
   alphahystmin = alphahystmax = 0.0;
   clsq = lod = 0.0;
   alphaw = 0.0;
@@ -280,39 +281,29 @@ bool FGAerodynamics::Run(bool Holding)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGAerodynamics::Load(Element *element)
+bool FGAerodynamics::Load(Element *document)
 {
   string parameter, axis, scratch;
   string scratch_unit="";
-  string fname="", file="";
   Element *temp_element, *axis_element, *function_element;
 
-  string separator = "/";
-  FGXMLFileRead XMLFileRead;
-  Element* document;
-
-  fname = element->GetAttributeValue("file");
-  if (!fname.empty()) {
-    file = FDMExec->GetFullAircraftPath() + separator + fname;
-    document = XMLFileRead.LoadXMLDocument(file);
-    if (document == 0L) return false;
-  } else {
-    document = element;
-  }
-
   Name = "Aerodynamics Model: " + document->GetAttributeValue("name");
 
-  FGModel::Load(document); // Perform base class Pre-Load
+  // Perform base class Pre-Load
+  if (!FGModel::Load(document))
+    return false;
 
-  DetermineAxisSystem(document); // Detemine if Lift/Side/Drag, etc. is used.
+  DetermineAxisSystem(document); // Determine if Lift/Side/Drag, etc. is used.
 
   Debug(2);
 
   if ((temp_element = document->FindElement("alphalimits"))) {
     scratch_unit = temp_element->GetAttributeValue("unit");
     if (scratch_unit.empty()) scratch_unit = "RAD";
-    alphaclmin = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
-    alphaclmax = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
+    alphaclmin0 = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
+    alphaclmax0 = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
+    alphaclmin = alphaclmin0;
+    alphaclmax = alphaclmax0;
   }
 
   if ((temp_element = document->FindElement("hysteresis_limits"))) {
index da28d87b9fae589607d5968045ae5038b8efea92..9b7ec1dad1ad130d517d77c2e761e922d53a1f45 100644 (file)
@@ -51,7 +51,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.29 2013/11/24 11:40:55 bcoconni Exp $"
+#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.30 2014/09/03 17:26:28 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -108,7 +108,7 @@ CLASS DOCUMENTATION
     Systems may NOT be combined, or a load error will occur.
 
     @author Jon S. Berndt, Tony Peden
-    @version $Revision: 1.29 $
+    @version $Revision: 1.30 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -245,6 +245,7 @@ private:
   FGColumnVector3 vDXYZcg;
   FGColumnVector3 vDeltaRP;
   double alphaclmax, alphaclmin;
+  double alphaclmax0, alphaclmin0;
   double alphahystmax, alphahystmin;
   double impending_stall, stall_hyst;
   double bi2vel, ci2vel,alphaw;
index 68c945adc003870795b89475740648a8b64a6b6a..c1195b7b5d283eeb1c5b862cf9099c706915ffc8 100644 (file)
@@ -41,14 +41,13 @@ INCLUDES
 #include "FGBuoyantForces.h"
 #include "FGMassBalance.h"
 #include "input_output/FGPropertyManager.h"
-#include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGBuoyantForces.cpp,v 1.26 2014/01/13 10:46:06 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGBuoyantForces.cpp,v 1.27 2014/06/09 11:52:07 bcoconni Exp $");
 IDENT(IdHdr,ID_BUOYANTFORCES);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -117,26 +116,15 @@ bool FGBuoyantForces::Run(bool Holding)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGBuoyantForces::Load(Element *element)
+bool FGBuoyantForces::Load(Element *document)
 {
-  string fname="", file="";
   Element *gas_cell_element;
 
   Debug(2);
 
-  string separator = "/";
-  FGXMLFileRead XMLFileRead;
-  Element* document;
-
-  fname = element->GetAttributeValue("file");
-  if (!fname.empty()) {
-    file = FDMExec->GetFullAircraftPath() + separator + fname;
-    document = XMLFileRead.LoadXMLDocument(file);
-  } else {
-    document = element;
-  }
-
-  FGModel::Load(element); // Perform base class Load
+  // Perform base class Pre-Load
+  if (!FGModel::Load(document))
+    return false;
 
   gas_cell_element = document->FindElement("gas_cell");
   while (gas_cell_element) {
index 6e72838b65d1c366615f1f61ff7ba892883dc3ed..b07da09082a83d65f52416737bdf4fdcb46f4668 100644 (file)
@@ -40,7 +40,6 @@ INCLUDES
 #include <string>
 
 #include "FGExternalReactions.h"
-#include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
 
 using namespace std;
@@ -55,7 +54,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-IDENT(IdSrc,"$Id: FGExternalReactions.cpp,v 1.17 2014/01/13 10:46:07 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGExternalReactions.cpp,v 1.18 2014/06/09 11:52:07 bcoconni Exp $");
 IDENT(IdHdr,ID_EXTERNALREACTIONS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -73,17 +72,9 @@ FGExternalReactions::FGExternalReactions(FGFDMExec* fdmex) : FGModel(fdmex)
 
 bool FGExternalReactions::Load(Element* el)
 {
-  // check if a file attribute was specified
-  string fname = el->GetAttributeValue("file");
-  FGXMLFileRead XMLFileRead;
-
-  if (!fname.empty()) {
-    string file = FDMExec->GetFullAircraftPath() + "/" + fname;
-    el = XMLFileRead.LoadXMLDocument(file);
-    if (el == 0L) return false;
-  }
-
-  FGModel::Load(el); // Call the base class Load() function to load interface properties.
+  // Call the base class Load() function to load interface properties.
+  if (!FGModel::Load(el))
+    return false;
 
   Debug(2);
 
index 2c7d3bedb4211569331d6b3e08a129b7a5d3aef5..486f03e87f4df8b7d6e52049361cecae0fb13b5e 100644 (file)
@@ -45,8 +45,8 @@ INCLUDES
 #include "FGFDMExec.h"
 #include "FGGroundReactions.h"
 #include "input_output/FGPropertyManager.h"
-#include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
+#include "input_output/FGModelLoader.h"
 
 #include "models/flight_control/FGFilter.h"
 #include "models/flight_control/FGDeadBand.h"
@@ -71,7 +71,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.88 2014/05/17 15:27:16 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.90 2014/06/09 11:52:07 bcoconni Exp $");
 IDENT(IdHdr,ID_FCS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -488,40 +488,19 @@ void FGFCS::SetPropFeather(int engineNum, bool setting)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGFCS::Load(Element* el, SystemType systype)
+bool FGFCS::Load(Element* document, SystemType type)
 {
-  string name, file, fname="", interface_property_string, parent_name;
+  string name, parent_name;
   Element *component_element;
   Element *channel_element;
-  FGXMLFileRead XMLFileRead;
-  Element* document;
   
-// ToDo: The handling of name and file attributes could be improved, here,
-//       considering that a name can be in the external file, as well.
+  systype = type;
 
-  name = el->GetAttributeValue("name");
+  // Load interface properties from document
+  if (!FGModel::Load(document))
+    return false;
 
-  if (name.empty() || !el->GetAttributeValue("file").empty()) {
-    fname = el->GetAttributeValue("file");
-    if (systype == stSystem) {
-      file = FindSystemFullPathname(fname);
-    } else { 
-      file = FDMExec->GetFullAircraftPath() + "/" + fname + ".xml";
-    }
-    if (fname.empty()) {
-      cerr << "FCS, Autopilot, or system does not appear to be defined inline nor in a file" << endl;
-      return false;
-    } else {
-      document = XMLFileRead.LoadXMLDocument(file);
-      if (!document) {
-        cerr << "Error loading file " << file << endl;
-        return false;
-      }
-      name = document->GetAttributeValue("name");
-    }
-  } else {
-    document = el;
-  }
+  name = document->GetAttributeValue("name");
 
   Name = "Flight Control Systems Model: " + document->GetAttributeValue("name");
 
@@ -536,16 +515,6 @@ bool FGFCS::Load(Element* el, SystemType systype)
 
   if (document->GetName() == "flight_control") bindModel();
 
-  FGModel::Load(document); // Load interface properties from document
-
-  // After reading interface properties in a file, read properties in the local
-  // flight_control, autopilot, or system element. This allows general-purpose
-  // systems to be defined in a file, with overrides or initial loaded constants
-  // supplied in the relevant element of the aircraft configuration file.
-
-  if (!fname.empty())
-    LoadProperties(el, PropertyManager, true);
-
   channel_element = document->FindElement("channel");
   
   while (channel_element) {
@@ -648,68 +617,16 @@ double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGFCS::FindSystemFullPathname(const string& sysfilename)
-{
-  string fullpath, localpath;
-  string system_filename = sysfilename;
-  string systemPath = FDMExec->GetSystemsPath();
-  string aircraftPath = FDMExec->GetFullAircraftPath() + "/";
-  ifstream system_file;
-
-  fullpath = systemPath + "/";
-  localpath = aircraftPath + "Systems/";
-
-  if (system_filename.length() <=4 || system_filename.substr(system_filename.length()-4, 4) != ".xml") {
-    system_filename.append(".xml");
-  }
-
-  system_file.open(string(aircraftPath + system_filename).c_str());
-  if ( !system_file.is_open()) {
-    system_file.open(string(localpath + system_filename).c_str());
-    if ( !system_file.is_open()) {
-      system_file.open(string(fullpath + system_filename).c_str());
-      if ( !system_file.is_open()) {
-        cerr << " Could not open system file: " << system_filename << " in path "
-             << fullpath << " or " << localpath << endl;
-        return string("");
-      } else {
-        return string(fullpath + system_filename);
-      }
-    } else {
-      return string(localpath + system_filename);
-    }
-  } else {
-    return string(aircraftPath + system_filename);
-  }
-  return string("");
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-ifstream* FGFCS::FindSystemFile(const string& sysfilename)
+string FGFCS::FindFullPathName(const string& sysfilename) const
 {
-  string fullpath, localpath;
-  string system_filename = sysfilename;
-  string systemPath = FDMExec->GetSystemsPath();
-  string aircraftPath = FDMExec->GetFullAircraftPath();
-  ifstream* system_file = new ifstream();
+  string name = FGModel::FindFullPathName(sysfilename);
 
-  fullpath = systemPath + "/";
-  localpath = aircraftPath + "/Systems/";
+  if (systype != stSystem || !name.empty()) return name;
 
-  if (system_filename.substr(system_filename.length()-4, 4) != ".xml") {
-    system_filename.append(".xml");
-  }
+  name = CheckFullPathName(FDMExec->GetFullAircraftPath() + "/Systems", sysfilename);
+  if (!name.empty()) return name;
 
-  system_file->open(string(localpath + system_filename).c_str());
-  if ( !system_file->is_open()) {
-    system_file->open(string(fullpath + system_filename).c_str());
-      if ( !system_file->is_open()) {
-        cerr << " Could not open system file: " << system_filename << " in path "
-             << fullpath << " or " << localpath << endl;
-      }
-  }
-  return system_file;
+  return CheckFullPathName(FDMExec->GetSystemsPath(), sysfilename);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 7a12f8d04db682ba0c7ead381d1a56ca84971c98..f55fc067e6ca471fb549268df91a49d38c14d681 100644 (file)
@@ -50,7 +50,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FCS "$Id: FGFCS.h,v 1.45 2013/11/24 11:40:56 bcoconni Exp $"
+#define ID_FCS "$Id: FGFCS.h,v 1.46 2014/06/09 11:52:07 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -168,7 +168,7 @@ CLASS DOCUMENTATION
     @property gear/tailhook-pos-norm
 
     @author Jon S. Berndt
-    @version $Revision: 1.45 $
+    @version $Revision: 1.46 $
     @see FGActuator
     @see FGDeadBand
     @see FGFCSFunction
@@ -555,8 +555,7 @@ public:
       @return true if succesful */
   bool Load(Element* el, SystemType systype);
 
-  std::ifstream* FindSystemFile(const std::string& system_filename);
-  std::string FindSystemFullPathname(const std::string& system_filename);
+  std::string FindFullPathName(const std::string& system_filename) const;
 
   void AddThrottle(void);
   void AddGear(unsigned int NumGear);
@@ -588,6 +587,7 @@ private:
   std::vector <double> BrakePos; // left, center, right - defined by FGLGear:: enum
   double GearCmd,GearPos;
   double TailhookPos, WingFoldPos;
+  SystemType systype;
 
   typedef std::vector <FGFCSChannel*> Channels;
   Channels SystemChannels;
index 7a5626650c5a952f22ebf470dfe3654b02096ae2..d4134464fcf3043f403e3dd025d776e7570b56be 100644 (file)
@@ -50,7 +50,7 @@ using std::max;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGGasCell.cpp,v 1.20 2014/01/13 10:46:07 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGGasCell.cpp,v 1.21 2014/06/29 10:18:16 bcoconni Exp $");
 IDENT(IdHdr,ID_GASCELL);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -68,7 +68,7 @@ FGGasCell::FGGasCell(FGFDMExec* exec, Element* el, int num, const struct Inputs&
   string token;
   Element* element;
 
-  PropertyManager = exec->GetPropertyManager();
+  FGPropertyManager* PropertyManager = exec->GetPropertyManager();
   MassBalance = exec->GetMassBalance();
 
   gasCellJ = FGMatrix33();
@@ -510,7 +510,7 @@ FGBallonet::FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent,
   string token;
   Element* element;
 
-  PropertyManager = exec->GetPropertyManager();
+  FGPropertyManager* PropertyManager = exec->GetPropertyManager();
   MassBalance = exec->GetMassBalance();
 
   ballonetJ = FGMatrix33();
index df8cde022525d1ee93666ab697624c8d1dcc5088..abffb13fc691f9b0e7c1f1e6a8629f7b402c47c1 100644 (file)
@@ -50,7 +50,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_GASCELL "$Id: FGGasCell.h,v 1.13 2013/04/17 20:24:27 andgi Exp $"
+#define ID_GASCELL "$Id: FGGasCell.h,v 1.15 2014/06/29 10:18:16 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -261,7 +261,6 @@ private:
   FGMatrix33 gasCellJ;      // [slug foot^2]
   FGColumnVector3 gasCellM; // [lbs in]
 
-  FGPropertyManager* PropertyManager;
   FGMassBalance* MassBalance;
   void Debug(int from);
 
@@ -364,7 +363,6 @@ private:
   double ValveOpen;        // 0 <= ValveOpen <= 1 (or higher).
   FGMatrix33 ballonetJ;     // [slug foot^2]
 
-  FGPropertyManager* PropertyManager;
   FGMassBalance* MassBalance;
   void Debug(int from);
 
index 478703842aa117e6a69f1138d874929f7120a9e4..8e9bcb5f37500a21a529ad88e7e9ff26a3d7c850 100644 (file)
@@ -42,14 +42,13 @@ INCLUDES
 #include "FGLGear.h"
 #include "FGAccelerations.h"
 #include "input_output/FGPropertyManager.h"
-#include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.50 2014/05/17 15:25:20 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.51 2014/06/09 11:52:07 bcoconni Exp $");
 IDENT(IdHdr,ID_GROUNDREACTIONS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -139,27 +138,18 @@ bool FGGroundReactions::GetWOW(void) const
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGGroundReactions::Load(Element* elem)
+bool FGGroundReactions::Load(Element* document)
 {
   int num=0;
-  string fname="", file="";
-  string separator = "/";
-  FGXMLFileRead XMLFileRead;
-  Element* document;
-
-  fname = elem->GetAttributeValue("file");
-  if (!fname.empty()) {
-    file = FDMExec->GetFullAircraftPath() + separator + fname;
-    document = XMLFileRead.LoadXMLDocument(file);
-    if (document == 0L) return false;
-  } else {
-    document = elem;
-  }
 
   Name = "Ground Reactions Model: " + document->GetAttributeValue("name");
 
   Debug(2);
 
+  // Perform base class Pre-Load
+  if (!FGModel::Load(document))
+    return false;
+
   unsigned int numContacts = document->GetNumElements("contact");
   lGear.resize(numContacts);
   Element* contact_element = document->FindElement("contact");
@@ -168,8 +158,6 @@ bool FGGroundReactions::Load(Element* elem)
     contact_element = document->FindNextElement("contact");
   }
 
-  FGModel::Load(document); // Perform base class Load
-
   for (unsigned int i=0; i<lGear.size();i++) lGear[i]->bind();
 
   PostLoad(document, PropertyManager);
index 2dbc8b08c5652de2c9400e29d0fd2cf2e103790c..a77d7bfe09a6bc20f6cbe2966322bdac060a9818 100644 (file)
@@ -44,6 +44,7 @@ INCLUDES
 #include <cstring>
 #include <sstream>
 
+#include "math/FGFunction.h"
 #include "FGLGear.h"
 #include "input_output/FGPropertyManager.h"
 #include "models/FGGroundReactions.h"
@@ -62,7 +63,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.116 2014/05/17 15:26:39 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.117 2014/06/08 12:50:05 bcoconni Exp $");
 IDENT(IdHdr,ID_LGEAR);
 
 // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
index 64a15b3db15d44e92bc37cbc65bf85f61bdec233..0181c09ebc48cd2f77da271ff2191c5463394f34 100644 (file)
@@ -45,14 +45,13 @@ INCLUDES
 #include "FGMassBalance.h"
 #include "FGFDMExec.h"
 #include "input_output/FGPropertyManager.h"
-#include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGMassBalance.cpp,v 1.49 2014/05/17 15:17:13 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGMassBalance.cpp,v 1.50 2014/06/09 11:52:07 bcoconni Exp $");
 IDENT(IdHdr,ID_MASSBALANCE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -103,27 +102,16 @@ bool FGMassBalance::InitModel(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGMassBalance::Load(Element* elem)
+bool FGMassBalance::Load(Element* document)
 {
   string element_name = "";
   double bixx, biyy, bizz, bixy, bixz, biyz;
-  string fname="", file="";
-  string separator = "/";
-  FGXMLFileRead XMLFileRead;
-  Element* document;
-
-  fname = elem->GetAttributeValue("file");
-  if (!fname.empty()) {
-    file = FDMExec->GetFullAircraftPath() + separator + fname;
-    document = XMLFileRead.LoadXMLDocument(file);
-    if (document == 0L) return false;
-  } else {
-    document = elem;
-  }
 
   Name = "Mass Properties Model: " + document->GetAttributeValue("name");
 
-  FGModel::Load(document); // Perform base class Load.
+  // Perform base class Pre-Load
+  if (!FGModel::Load(document))
+    return false;
 
   bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
   if (document->FindElement("ixx"))
index d3b6c138725a1f7ace34ca61a835492e131f3922..ba05a71e1bde526f827a1087b0aece493d61575c 100644 (file)
@@ -38,15 +38,15 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <iostream>
 #include "FGModel.h"
 #include "FGFDMExec.h"
+#include "input_output/FGModelLoader.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGModel.cpp,v 1.24 2014/01/13 10:46:07 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGModel.cpp,v 1.25 2014/06/09 11:52:07 bcoconni Exp $");
 IDENT(IdHdr,ID_MODEL);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -101,6 +101,54 @@ bool FGModel::Run(bool Holding)
   else              return true;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+string FGModel::FindFullPathName(const string& fname) const
+{
+  return CheckFullPathName(FDMExec->GetFullAircraftPath(), fname);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGModel::Load(Element* el)
+{
+  FGModelLoader ModelLoader(this);
+  Element* document = ModelLoader.Open(el);
+
+  if (!document) return false;
+
+  if (document->GetName() != el->GetName()) {
+    cerr << el->ReadFrom()
+         << " Read model '" << document->GetName()
+         << "' while expecting model '" << el->GetName() << "'" << endl;
+    return false;
+  }
+
+  bool result = FGModelFunctions::Load(document, PropertyManager);
+
+  if (document != el) {
+    el->MergeAttributes(document);
+
+    // After reading interface properties in a file, read properties in the
+    // local model element. This allows general-purpose models to be defined in
+    // a file, with overrides or initial loaded constants supplied in the
+    // relevant element of the aircraft configuration file.
+
+    LocalProperties.Load(el, PropertyManager, true);
+
+    Element* element = document->FindElement();
+    while (element) {
+      el->AddChildElement(element);
+      element->SetParent(el);
+      element = document->FindNextElement();
+    }
+
+    document = el;
+  }
+
+  return result;
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //    The bitmasked value choices are as follows:
 //    unset: In this case (the default) JSBSim would only print
index 7483dface3e316867ed17e39f4c32e80fd4cf335..86b576b467321cbe7917a7db41aab42f3750edb9 100644 (file)
@@ -38,17 +38,15 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "math/FGFunction.h"
-#include "math/FGModelFunctions.h"
-
 #include <string>
-#include <vector>
+
+#include "math/FGModelFunctions.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_MODEL "$Id: FGModel.h,v 1.20 2011/06/21 04:41:54 jberndt Exp $"
+#define ID_MODEL "$Id: FGModel.h,v 1.22 2014/06/09 11:52:07 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -100,6 +98,7 @@ public:
   FGFDMExec* GetExec(void)     {return FDMExec;}
 
   void SetPropertyManager(FGPropertyManager *fgpm) { PropertyManager=fgpm;}
+  virtual std::string FindFullPathName(const std::string& filename) const;
 
 protected:
   int exe_ctr;
@@ -108,7 +107,7 @@ protected:
   /** Loads this model.
       @param el a pointer to the element
       @return true if model is successfully loaded*/
-  virtual bool Load(Element* el) {return FGModelFunctions::Load(el, PropertyManager);}
+  virtual bool Load(Element* el);
 
   virtual void Debug(int from);
 
index 668011d36acf1808b9de687e6648f6b84fd870fe..46a482d3d012c2c833226eb16415cf4afda68924 100644 (file)
@@ -46,12 +46,13 @@ INCLUDES
 #include "input_output/FGOutputFG.h"
 #include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
+#include "input_output/FGModelLoader.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGOutput.cpp,v 1.77 2014/01/13 10:46:07 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGOutput.cpp,v 1.80 2014/09/12 20:10:05 bcoconni Exp $");
 IDENT(IdHdr,ID_OUTPUT);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -64,7 +65,7 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
 
   Name = "FGOutput";
 
-  fdmex->GetPropertyManager()->Tie("simulation/force-output", this, (iOPV)0, &FGOutput::ForceOutput, false);
+  PropertyManager->Tie("simulation/force-output", this, (iOPV)0, &FGOutput::ForceOutput, false);
 
   Debug(0);
 }
@@ -255,12 +256,22 @@ bool FGOutput::Load(int subSystems, std::string protocol, std::string type,
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGOutput::Load(Element* document)
+bool FGOutput::Load(Element* el)
 {
-  if (!document) return false;
+  // Unlike the other FGModel classes, properties listed in the <output> section
+  // are not intended to create new properties. For that reason, FGOutput
+  // cannot load its XML directives with FGModel::Load().
+  // Instead FGModelLoader::Open() and FGModel::PreLoad() must be explicitely
+  // called.
+  FGModelLoader ModelLoader(this);
+  Element* element = ModelLoader.Open(el);
+
+  if (!element) return false;
+
+  FGModel::PreLoad(element, PropertyManager);
 
   unsigned int idx = OutputTypes.size();
-  string type = document->GetAttributeValue("type");
+  string type = element->GetAttributeValue("type");
   FGOutputType* Output = 0;
 
   if (debug_lvl > 0) cout << endl << "  Output data set: " << idx << "  " << endl;
@@ -284,7 +295,8 @@ bool FGOutput::Load(Element* document)
   if (!Output) return false;
 
   Output->SetIdx(idx);
-  Output->Load(document);
+  Output->Load(element);
+  PostLoad(element, PropertyManager);
 
   OutputTypes.push_back(Output);
 
index 1bcae7205fc2313c556ae36be6417243ce8e113a..0857d0fe3682671243ddc88f51122f1914b99d84 100644 (file)
@@ -58,16 +58,14 @@ INCLUDES
 #include "models/propulsion/FGElectric.h"
 #include "models/propulsion/FGTurboProp.h"
 #include "models/propulsion/FGTank.h"
-#include "input_output/FGPropertyManager.h"
-#include "input_output/FGXMLFileRead.h"
-#include "input_output/FGXMLElement.h"
+#include "input_output/FGModelLoader.h"
 #include "math/FGColumnVector3.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.78 2014/05/17 15:13:56 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.80 2014/06/29 10:18:16 bcoconni Exp $");
 IDENT(IdHdr,ID_PROPULSION);
 
 extern short debug_lvl;
@@ -349,29 +347,18 @@ void FGPropulsion::InitRunning(int n)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGPropulsion::Load(Element* elem)
+bool FGPropulsion::Load(Element* el)
 {
-  string type, engine_filename;
-  string separator = "/";
-  Element *el=0;
-  FGXMLFileRead XMLFileRead;
-  FGXMLParse main_file_parser;
+  FGModelLoader ModelLoader(this);
 
   Debug(2);
-
-  string fname="", file="";
-  fname = elem->GetAttributeValue("file");
-  if (!fname.empty()) {
-    file = FDMExec->GetFullAircraftPath() + separator + fname;
-    el = XMLFileRead.LoadXMLDocument(file, main_file_parser);
-    if (el == 0L) return false;
-  } else {
-    el = elem;
-  }
+  ReadingEngine = false;
 
   Name = "Propulsion Model: " + el->GetAttributeValue("name");
 
-  FGModel::Load(el); // Perform base class Load.
+  // Perform base class Pre-Load
+  if (!FGModel::Load(el))
+    return false;
 
   // Process tank definitions first to establish the number of fuel tanks
 
@@ -387,51 +374,47 @@ bool FGPropulsion::Load(Element* elem)
   numSelectedFuelTanks = numFuelTanks;
   numSelectedOxiTanks  = numOxiTanks;
 
+  ReadingEngine = true;
   Element* engine_element = el->FindElement("engine");
   while (engine_element) {
-    engine_filename = engine_element->GetAttributeValue("file");
-
-    if (engine_filename.empty()) {
-      cerr << "Engine definition did not supply an engine file." << endl;
-      return false;
-    }
-
-    engine_filename = FindEngineFullPathname(engine_filename);
-    if (engine_filename.empty()) {
-      // error message already printed by FindEngineFullPathname()
-      return false;
-    }
+    if (!ModelLoader.Open(engine_element)) return false;
 
-    Element* document = XMLFileRead.LoadXMLDocument(engine_filename);
-    document->SetParent(engine_element);
-
-    type = document->GetName();
     try {
-      if (type == "piston_engine") {
+      // Locate the thruster definition
+      Element* thruster_element = engine_element->FindElement("thruster");
+      if (!thruster_element || !ModelLoader.Open(thruster_element))
+        throw("No thruster definition supplied with engine definition.");
+
+      if (engine_element->FindElement("piston_engine")) {
         HavePistonEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGPiston(FDMExec, document, numEngines, in));
-      } else if (type == "turbine_engine") {
+        Element *element = engine_element->FindElement("piston_engine");
+        Engines.push_back(new FGPiston(FDMExec, element, numEngines, in));
+      } else if (engine_element->FindElement("turbine_engine")) {
         HaveTurbineEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGTurbine(FDMExec, document, numEngines, in));
-      } else if (type == "turboprop_engine") {
+        Element *element = engine_element->FindElement("turbine_engine");
+        Engines.push_back(new FGTurbine(FDMExec, element, numEngines, in));
+      } else if (engine_element->FindElement("turboprop_engine")) {
         HaveTurboPropEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGTurboProp(FDMExec, document, numEngines, in));
-      } else if (type == "rocket_engine") {
+        Element *element = engine_element->FindElement("turboprop_engine");
+        Engines.push_back(new FGTurboProp(FDMExec, element, numEngines, in));
+      } else if (engine_element->FindElement("rocket_engine")) {
         HaveRocketEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGRocket(FDMExec, document, numEngines, in));
-      } else if (type == "electric_engine") {
+        Element *element = engine_element->FindElement("rocket_engine");
+        Engines.push_back(new FGRocket(FDMExec, element, numEngines, in));
+      } else if (engine_element->FindElement("electric_engine")) {
         HaveElectricEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGElectric(FDMExec, document, numEngines, in));
+        Element *element = engine_element->FindElement("electric_engine");
+        Engines.push_back(new FGElectric(FDMExec, element, numEngines, in));
       } else {
-        cerr << "Unknown engine type: " << type << endl;
-        exit(-5);
+        cerr << engine_element->ReadFrom() << " Unknown engine type" << endl;
+        return false;
       }
-    } catch (std::string str) {
+    } catch (std::string& str) {
       cerr << endl << fgred << str << reset << endl;
       return false;
     }
@@ -439,7 +422,6 @@ bool FGPropulsion::Load(Element* elem)
     numEngines++;
 
     engine_element = el->FindNextElement("engine");
-    XMLFileRead.ResetParser();
   }
 
   CalculateTankInertias();
@@ -455,55 +437,14 @@ bool FGPropulsion::Load(Element* elem)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGPropulsion::FindEngineFullPathname(const string& engine_filename)
+string FGPropulsion::FindFullPathName(const string& filename) const
 {
-  string fullpath, localpath;
-  string enginePath = FDMExec->GetEnginePath();
-  string aircraftPath = FDMExec->GetFullAircraftPath();
-  ifstream engine_file;
-
-  string separator = "/";
-
-  fullpath = enginePath + separator;
-  localpath = aircraftPath + separator + "Engines" + separator;
-
-  engine_file.open(string(localpath + engine_filename + ".xml").c_str());
-  if ( !engine_file.is_open()) {
-    engine_file.open(string(fullpath + engine_filename + ".xml").c_str());
-      if ( !engine_file.is_open()) {
-        cerr << " Could not open engine file: " << engine_filename << " in path "
-             << fullpath << " or " << localpath << endl;
-        return string("");
-      } else {
-        return string(fullpath + engine_filename + ".xml");
-      }
-  }
-  return string(localpath + engine_filename + ".xml");
-}
+  if (!ReadingEngine) return FGModel::FindFullPathName(filename);
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  string name = CheckFullPathName(FDMExec->GetFullAircraftPath() + "/Engines", filename);
+  if (!name.empty()) return name;
 
-ifstream* FGPropulsion::FindEngineFile(const string& engine_filename)
-{
-  string fullpath, localpath;
-  string enginePath = FDMExec->GetEnginePath();
-  string aircraftPath = FDMExec->GetFullAircraftPath();
-  ifstream* engine_file = new ifstream();
-
-  string separator = "/";
-
-  fullpath = enginePath + separator;
-  localpath = aircraftPath + separator + "Engines" + separator;
-
-  engine_file->open(string(localpath + engine_filename + ".xml").c_str());
-  if ( !engine_file->is_open()) {
-    engine_file->open(string(fullpath + engine_filename + ".xml").c_str());
-      if ( !engine_file->is_open()) {
-        cerr << " Could not open engine file: " << engine_filename << " in path "
-             << localpath << " or " << fullpath << endl;
-      }
-  }
-  return engine_file;
+  return CheckFullPathName(FDMExec->GetEnginePath(), filename);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index a04916ada590f12a28fd4095292cef69115a3d5e..eb5a087d206a9deb4ee5793856975219640c1ff5 100644 (file)
@@ -49,7 +49,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.33 2014/04/13 11:19:15 bcoconni Exp $"
+#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.34 2014/06/09 11:52:07 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -91,7 +91,7 @@ CLASS DOCUMENTATION
   @endcode
 
     @author Jon S. Berndt
-    @version $Id: FGPropulsion.h,v 1.33 2014/04/13 11:19:15 bcoconni Exp $
+    @version $Id: FGPropulsion.h,v 1.34 2014/06/09 11:52:07 bcoconni Exp $
     @see
     FGEngine
     FGTank
@@ -182,8 +182,7 @@ public:
   const FGColumnVector3& GetTanksMoment(void);
   double GetTanksWeight(void) const;
 
-  std::ifstream* FindEngineFile(const std::string& filename);
-  std::string FindEngineFullPathname(const std::string& engine_filename);
+  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;}
@@ -225,6 +224,8 @@ private:
   bool HaveElectricEngine;
   void ConsumeFuel(FGEngine* engine);
 
+  bool ReadingEngine;
+
   void bind();
   void Debug(int from);
 };
index e6fedc1031ba4f42de41d0a68fd68c7da09990d0..dd4d1c2277966d338bd5b85967ea3edbb72166d9 100644 (file)
@@ -51,7 +51,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGWinds.cpp,v 1.12 2014/02/17 05:02:38 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGWinds.cpp,v 1.14 2014/09/03 17:40:59 bcoconni Exp $");
 IDENT(IdHdr,ID_WINDS);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -87,6 +87,7 @@ FGWinds::FGWinds(FGFDMExec* fdmex) : FGModel(fdmex)
 
   vGustNED.InitMatrix();
   vTurbulenceNED.InitMatrix();
+  vCosineGust.InitMatrix();
 
   // Milspec turbulence model
   windspeed_at_20ft = 0.;
@@ -120,7 +121,18 @@ FGWinds::~FGWinds()
 
 bool FGWinds::InitModel(void)
 {
-  return FGModel::InitModel();
+  if (!FGModel::InitModel()) return false;
+
+  psiw = 0.0;
+
+  vGustNED.InitMatrix();
+  vTurbulenceNED.InitMatrix();
+  vCosineGust.InitMatrix();
+
+  oneMinusCosineGust.gustProfile.Running = false;
+  oneMinusCosineGust.gustProfile.elapsedTime = 0.0;
+
+  return true;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index ed6ee967fd7c3abd5ce122e37922d0e3874ded3e..dd492c4aff6a35806a2999e430d952dc883e3494 100644 (file)
@@ -41,12 +41,13 @@ INCLUDES
 
 #include "FGActuator.h"
 #include "input_output/FGXMLElement.h"
+#include "math/FGRealValue.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGActuator.cpp,v 1.36 2014/08/09 17:40:51 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGActuator.cpp,v 1.37 2014/08/28 13:44:28 bcoconni Exp $");
 IDENT(IdHdr,ID_ACTUATOR);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -65,9 +66,7 @@ FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, eleme
   PreviousRateLimOutput = 0.0;
   PreviousLagInput = PreviousLagOutput = 0.0;
   bias = lag = hysteresis_width = deadband_width = 0.0;
-  rate_limited = false;
-  rate_limit = rate_limit_incr = rate_limit_decr = 0.0; // no limit
-  rate_limit_incr_prop = rate_limit_decr_prop = 0;
+  rate_limit_incr = rate_limit_decr = 0; // no limit
   fail_zero = fail_hardover = fail_stuck = false;
   ca = cb = 0.0;
   initialized = 0;
@@ -85,38 +84,32 @@ FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, eleme
   // a property.
   Element* ratelim_el = element->FindElement("rate_limit");
   while ( ratelim_el ) {
-    rate_limited = true;
-    FGPropertyNode* rate_limit_prop=0;
-
+    FGParameter* rate_limit = 0;
     string rate_limit_str = ratelim_el->GetDataLine();
+
     trim(rate_limit_str);
-    if (is_number(rate_limit_str)) {
-      rate_limit = fabs(atof(rate_limit_str.c_str()));
-    else {
+    if (is_number(rate_limit_str))
+      rate_limit = new FGRealValue(fabs(atof(rate_limit_str.c_str())));
+    else {
       if (rate_limit_str[0] == '-') rate_limit_str.erase(0,1);
-      rate_limit_prop = PropertyManager->GetNode(rate_limit_str, true);
-      if (rate_limit_prop == 0)
+      FGPropertyNode* rate_limit_prop = PropertyManager->GetNode(rate_limit_str, true);
+      if (!rate_limit_prop) {
         std::cerr << "No such property, " << rate_limit_str << " for rate limiting" << std::endl;
+        ratelim_el = element->FindNextElement("rate_limit");
+        continue;
+      }
+      rate_limit = new FGPropertyValue(rate_limit_prop);
     }
 
     if (ratelim_el->HasAttribute("sense")) {
       string sense = ratelim_el->GetAttributeValue("sense");
-      if (sense.substr(0,4) == "incr") {
-        if (rate_limit_prop != 0) rate_limit_incr_prop = rate_limit_prop;
-        else                      rate_limit_incr = rate_limit;
-      } else if (sense.substr(0,4) == "decr") {
-        if (rate_limit_prop != 0) rate_limit_decr_prop = rate_limit_prop;
-        else                      rate_limit_decr = rate_limit;
-      }
-    } else {
-      if (rate_limit_prop != 0) {
-        rate_limit_incr_prop = rate_limit_prop;
-        rate_limit_decr_prop = rate_limit_prop;
-      }
-      else {
+      if (sense.substr(0,4) == "incr")
         rate_limit_incr = rate_limit;
+      else if (sense.substr(0,4) == "decr")
         rate_limit_decr = rate_limit;
-      }
+    } else {
+      rate_limit_incr = rate_limit;
+      rate_limit_decr = rate_limit;
     }
     ratelim_el = element->FindNextElement("rate_limit");
   }
@@ -141,6 +134,10 @@ FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, eleme
 
 FGActuator::~FGActuator()
 {
+  delete rate_limit_incr;
+  if (rate_limit_decr != rate_limit_incr)
+    delete rate_limit_decr;
+
   Debug(1);
 }
 
@@ -176,8 +173,7 @@ bool FGActuator::Run(void )
     Output = PreviousOutput;
   } else {
     if (lag != 0.0)              Lag();        // models actuator lag
-    if (rate_limit != 0 || (rate_limit_incr_prop != 0
-        || rate_limit_decr_prop != 0)) RateLimit();  // limit the actuator rate
+    if (rate_limit_incr != 0 || rate_limit_decr != 0) RateLimit();  // limit the actuator rate
     if (deadband_width != 0.0)   Deadband();
     if (hysteresis_width != 0.0) Hysteresis();
     if (bias != 0.0)             Bias();       // models a finite bias
@@ -252,12 +248,15 @@ void FGActuator::RateLimit(void)
   double input = Output;
   if ( initialized ) {
     double delta = input - PreviousRateLimOutput;
-    if (rate_limit_incr_prop != 0) rate_limit_incr = rate_limit_incr_prop->getDoubleValue();
-    if (rate_limit_decr_prop != 0) rate_limit_decr = rate_limit_decr_prop->getDoubleValue();
-    if (delta > dt * rate_limit_incr) {
-      Output = PreviousRateLimOutput + rate_limit_incr * dt;
-    } else if (delta < -dt * rate_limit_decr) {
-      Output = PreviousRateLimOutput - rate_limit_decr * dt;
+    if (rate_limit_incr) {
+      double rate_limit = rate_limit_incr->GetValue();
+      if (delta > dt * rate_limit)
+        Output = PreviousRateLimOutput + rate_limit * dt;
+    }
+    if (rate_limit_decr) {
+      double rate_limit = -rate_limit_decr->GetValue();
+      if (delta < dt * rate_limit)
+        Output = PreviousRateLimOutput + rate_limit * dt;
     }
   }
   PreviousRateLimOutput = Output;
@@ -335,17 +334,11 @@ void FGActuator::Debug(int from)
           cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
       }
       if (bias != 0.0) cout << "      Bias: " << bias << endl;
-      if (rate_limited) {
-        if (rate_limit_incr_prop != 0) {
-          cout << "      Increasing rate limit: " << rate_limit_incr_prop->GetName() << endl;
-        } else {
-          cout << "      Increasing rate limit: " << rate_limit_incr << endl;
-        }
-        if (rate_limit_decr_prop != 0) {
-          cout << "      Decreasing rate limit: " << rate_limit_decr_prop->GetName() << endl;
-        } else {
-          cout << "      Decreasing rate limit: " << rate_limit_decr << endl;
-        }
+      if (rate_limit_incr != 0) {
+        cout << "      Increasing rate limit: " << rate_limit_incr->GetName() << endl;
+      }
+      if (rate_limit_decr != 0) {
+        cout << "      Decreasing rate limit: " << rate_limit_decr->GetName() << endl;
       }
       if (lag != 0) cout << "      Actuator lag: " << lag << endl;
       if (hysteresis_width != 0) cout << "      Hysteresis width: " << hysteresis_width << endl;
index d131d7ab919191ba72dedd4fadffb0ca6667d5fa..9f9df8c494a22ac555a12b3655eae125a9413f4b 100644 (file)
@@ -43,7 +43,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ACTUATOR "$Id: FGActuator.h,v 1.18 2014/01/02 21:58:42 bcoconni Exp $"
+#define ID_ACTUATOR "$Id: FGActuator.h,v 1.19 2014/08/28 13:44:28 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -119,7 +119,7 @@ Example:
 @endcode
 
 @author Jon S. Berndt
-@version $Revision: 1.18 $
+@version $Revision: 1.19 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -156,12 +156,8 @@ public:
 private:
   double span;
   double bias;
-  bool rate_limited;
-  double rate_limit;
-  double rate_limit_incr;
-  double rate_limit_decr;
-  FGPropertyNode_ptr rate_limit_incr_prop;
-  FGPropertyNode_ptr rate_limit_decr_prop;
+  FGParameter* rate_limit_incr;
+  FGParameter* rate_limit_decr;
   double hysteresis_width;
   double deadband_width;
   double lag;
index b211981d6b877f3f85cd892a8006e5aacbb5a71f..41fba7d7fc603e451f974faa2f0480b2d7cf9a63 100644 (file)
@@ -50,7 +50,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGElectric.cpp,v 1.16 2014/01/13 10:46:10 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGElectric.cpp,v 1.18 2014/06/08 12:00:35 bcoconni Exp $");
 IDENT(IdHdr,ID_ELECTRIC);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -58,10 +58,12 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 FGElectric::FGElectric(FGFDMExec* exec, Element *el, int engine_number, struct FGEngine::Inputs& input)
-  : FGEngine(exec, el, engine_number, input)
+  : FGEngine(exec, engine_number, input)
 {
   string token;
 
+  Load(exec,el);
+
   Type = etElectric;
   PowerWatts = 745.7;
   hptowatts = 745.7;
index 75f07bd3e0dbdaf1fdc1f7983c6243ec8b24d21d..9f649a419213ee7b74c20c131d6831873450b0c7 100644 (file)
@@ -46,7 +46,6 @@ INCLUDES
 #include "FGPropeller.h"
 #include "FGNozzle.h"
 #include "FGRotor.h"
-#include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
 #include "math/FGColumnVector3.h"
 
@@ -54,19 +53,16 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGEngine.cpp,v 1.57 2014/01/13 10:46:10 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGEngine.cpp,v 1.60 2014/06/09 11:52:07 bcoconni Exp $");
 IDENT(IdHdr,ID_ENGINE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number, struct Inputs& input)
+FGEngine::FGEngine(FGFDMExec* exec, int engine_number, struct Inputs& input)
                       : in(input), EngineNumber(engine_number)
 {
-  Element* local_element;
-  FGColumnVector3 location, orientation;
-
   Name = "";
   Type = etUnknown;
   X = Y = Z = 0.0;
@@ -76,66 +72,6 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number,
   MaxThrottle = 1.0;
   MinThrottle = 0.0;
 
-  FDMExec = exec;
-
-  PropertyManager = FDMExec->GetPropertyManager();
-
-  Name = engine_element->GetAttributeValue("name");
-
-  Load(engine_element, PropertyManager, to_string((int)EngineNumber)); // Call ModelFunctions loader
-
-// Find and set engine location
-
-  local_element = engine_element->GetParent()->FindElement("location");
-  if (local_element)  location = local_element->FindElementTripletConvertTo("IN");
-//  else      cerr << "No engine location found for this engine." << endl;
-// Jon: The engine location is not important - the nozzle location is.
-
-  local_element = engine_element->GetParent()->FindElement("orient");
-  if (local_element)  orientation = local_element->FindElementTripletConvertTo("RAD");
-//  else          cerr << "No engine orientation found for this engine." << endl;
-// Jon: The engine orientation has a default and is not normally used.
-
-  SetPlacement(location, orientation);
-
-  // Load thruster
-  local_element = engine_element->GetParent()->FindElement("thruster");
-  if (local_element) {
-    try {
-      if (!LoadThruster(local_element)) exit(-1);
-    } catch (std::string str) {
-      throw("Error loading engine " + Name + ". " + str);
-    }
-  } else {
-    cerr << "No thruster definition supplied with engine definition." << endl;
-  }
-
-  ResetToIC(); // initialize dynamic terms
-
-  // Load feed tank[s] references
-  local_element = engine_element->GetParent()->FindElement("feed");
-  while (local_element) {
-    int tankID = (int)local_element->GetDataAsNumber();
-    SourceTanks.push_back(tankID);
-    local_element = engine_element->GetParent()->FindNextElement("feed");
-  }
-
-  string property_name, base_property_name;
-  base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
-
-  property_name = base_property_name + "/set-running";
-  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetRunning, &FGEngine::SetRunning );
-  property_name = base_property_name + "/thrust-lbs";
-  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-flow-rate-gph";
-  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelFlowRateGPH);
-  property_name = base_property_name + "/fuel-used-lbs";
-  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelUsedLbs);
-
-  PostLoad(engine_element, PropertyManager, to_string((int)EngineNumber));
-
   Debug(0);
 }
 
@@ -236,59 +172,100 @@ void FGEngine::LoadThrusterInputs()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGEngine::LoadThruster(Element *thruster_element)
+void FGEngine::LoadThruster(Element *thruster_element)
 {
-  string token, fullpath, localpath;
-  string thruster_filename, thruster_fullpathname, thrType;
-  string enginePath = FDMExec->GetEnginePath();
-  string aircraftPath = FDMExec->GetFullAircraftPath();
-  ifstream thruster_file;
-  FGColumnVector3 location, orientation;
-  string separator = "/";
-
-  fullpath = enginePath + separator;
-  localpath = aircraftPath + separator + "Engines" + separator;
-
-  thruster_filename = thruster_element->GetAttributeValue("file");
-  if ( !thruster_filename.empty()) {
-    thruster_fullpathname = localpath + thruster_filename + ".xml";
-    thruster_file.open(thruster_fullpathname.c_str());
-    if ( !thruster_file.is_open()) {
-      thruster_fullpathname = fullpath + thruster_filename + ".xml";
-      thruster_file.open(thruster_fullpathname.c_str());
-      if ( !thruster_file.is_open()) {
-        cerr << "Could not open thruster file: " << thruster_filename << ".xml" << endl;
-        return false;
-      } else {
-        thruster_file.close();
-      }
-    } else {
-      thruster_file.close();
-    }
-  } else {
-    cerr << "No thruster filename given." << endl;
-    return false;
-  }
-
-  FGXMLFileRead XMLFileRead;
-  Element *document = XMLFileRead.LoadXMLDocument(thruster_fullpathname);
-  document->SetParent(thruster_element);
-
-  thrType = document->GetName();
-
-  if (thrType == "propeller") {
+  if (thruster_element->FindElement("propeller")) {
+    Element *document = thruster_element->FindElement("propeller");
     Thruster = new FGPropeller(FDMExec, document, EngineNumber);
-  } else if (thrType == "nozzle") {
+  } else if (thruster_element->FindElement("nozzle")) {
+    Element *document = thruster_element->FindElement("nozzle");
     Thruster = new FGNozzle(FDMExec, document, EngineNumber);
-  } else if (thrType == "rotor") {
+  } else if (thruster_element->FindElement("rotor")) {
+    Element *document = thruster_element->FindElement("rotor");
     Thruster = new FGRotor(FDMExec, document, EngineNumber);
-  } else if (thrType == "direct") {
+  } else if (thruster_element->FindElement("direct")) {
+    Element *document = thruster_element->FindElement("direct");
     Thruster = new FGThruster( FDMExec, document, EngineNumber);
+  } else {
+    cerr << thruster_element->ReadFrom() << " Unknown thruster type" << endl;
+    throw("Failed to load the thruster");
   }
 
   Thruster->SetdeltaT(in.TotalDeltaT);
 
   Debug(2);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGEngine::Load(FGFDMExec *exec, Element *engine_element)
+{
+  Element* parent_element = engine_element->GetParent();
+  Element* local_element;
+  FGColumnVector3 location, orientation;
+
+  FDMExec = exec;
+
+  PropertyManager = FDMExec->GetPropertyManager();
+
+  Name = engine_element->GetAttributeValue("name");
+
+  FGModelFunctions::Load(engine_element, PropertyManager, to_string((int)EngineNumber)); // Call ModelFunctions loader
+
+// Find and set engine location
+
+  local_element = parent_element->FindElement("location");
+  if (local_element)  location = local_element->FindElementTripletConvertTo("IN");
+//  else      cerr << "No engine location found for this engine." << endl;
+// Jon: The engine location is not important - the nozzle location is.
+
+  local_element = parent_element->FindElement("orient");
+  if (local_element)  orientation = local_element->FindElementTripletConvertTo("RAD");
+//  else          cerr << "No engine orientation found for this engine." << endl;
+// Jon: The engine orientation has a default and is not normally used.
+
+  SetPlacement(location, orientation);
+
+  // Load thruster
+  local_element = parent_element->FindElement("thruster");
+  if (local_element) {
+    try {
+      LoadThruster(local_element);
+    } catch (std::string str) {
+      throw("Error loading engine " + Name + ". " + str);
+    }
+  } else {
+    cerr << "No thruster definition supplied with engine definition." << endl;
+  }
+
+  ResetToIC(); // initialize dynamic terms
+
+  // Load feed tank[s] references
+  local_element = parent_element->FindElement("feed");
+  while (local_element) {
+    int tankID = (int)local_element->GetDataAsNumber();
+    SourceTanks.push_back(tankID);
+    local_element = parent_element->FindNextElement("feed");
+  }
+
+  string property_name, base_property_name;
+  base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
+
+  property_name = base_property_name + "/set-running";
+  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetRunning, &FGEngine::SetRunning );
+  property_name = base_property_name + "/thrust-lbs";
+  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-flow-rate-gph";
+  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelFlowRateGPH);
+  property_name = base_property_name + "/fuel-used-lbs";
+  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelUsedLbs);
+
+  PostLoad(engine_element, PropertyManager, to_string((int)EngineNumber));
+
+  Debug(0);
+
   return true;
 }
 
index 942a6b4fab886c70475ebabda17030289e28277c..89e81cb393e888505c53ceec26830db0e5a98e01 100644 (file)
@@ -53,7 +53,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ENGINE "$Id: FGEngine.h,v 1.39 2013/12/22 17:14:37 bcoconni Exp $"
+#define ID_ENGINE "$Id: FGEngine.h,v 1.42 2014/06/09 11:52:07 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -111,7 +111,7 @@ CLASS DOCUMENTATION
   documentation for engine and thruster classes.
 </pre>     
     @author Jon S. Berndt
-    @version $Id: FGEngine.h,v 1.39 2013/12/22 17:14:37 bcoconni Exp $
+    @version $Id: FGEngine.h,v 1.42 2014/06/09 11:52:07 bcoconni Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -150,7 +150,7 @@ public:
     double TotalDeltaT;
   };
 
-  FGEngine(FGFDMExec* exec, Element* el, int engine_number, struct Inputs& input);
+  FGEngine(FGFDMExec* exec, int engine_number, struct Inputs& input);
   virtual ~FGEngine();
 
   enum EngineType {etUnknown, etRocket, etPiston, etTurbine, etTurboprop, etElectric};
@@ -207,7 +207,7 @@ public:
   virtual const FGColumnVector3& GetBodyForces(void);
   virtual const FGColumnVector3& GetMoments(void);
 
-  bool LoadThruster(Element *el);
+  void LoadThruster(Element *el);
   FGThruster* GetThruster(void) const {return Thruster;}
 
   unsigned int GetSourceTank(unsigned int i) const;
@@ -256,6 +256,7 @@ protected:
 
   std::vector <int> SourceTanks;
 
+  virtual bool Load(FGFDMExec *exec, Element *el);
   void Debug(int from);
 };
 }
index 48e723728c8043c16516e40de3f630e2792b7d47..1b45cdb95b461f499a9d2a492c999bd791ea6a6d 100644 (file)
@@ -51,7 +51,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGPiston.cpp,v 1.74 2014/01/13 10:46:10 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGPiston.cpp,v 1.77 2014/06/08 12:00:35 bcoconni Exp $");
 IDENT(IdHdr,ID_PISTON);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -59,7 +59,7 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Inputs& input)
-  : FGEngine(exec, el, engine_number, input),
+  : FGEngine(exec, engine_number, input),
   R_air(287.3),                  // Gas constant for air J/Kg/K
   rho_fuel(800),                 // estimate
   calorific_value_fuel(47.3e6),  // J/Kg
@@ -67,6 +67,8 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Input
   Cp_fuel(1700),
   standard_pressure(101320.73)
 {
+  Load(exec, el);
+
   Element *table_element;
   string token;
   string name="";
@@ -245,6 +247,10 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Input
         cerr << "Unknown table type: " << name << " in piston engine definition." << endl;
       }
     } catch (std::string str) {
+      // Make sure allocated resources are freed before rethrowing.
+      // (C++ standard guarantees that a null pointer deletion is no-op).
+      delete Lookup_Combustion_Efficiency;
+      delete Mixture_Efficiency_Correlation;
       throw("Error loading piston engine table:" + name + ". " + str);
     }
   }
index 230e7483d8f2fbe6c10bdecaa2ef6c610f99f8b4..220d1bbd4c37e46a0bda3286881e1e1a14565f9a 100644 (file)
@@ -49,7 +49,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGRocket.cpp,v 1.35 2014/05/17 15:04:14 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGRocket.cpp,v 1.37 2014/06/08 12:00:35 bcoconni Exp $");
 IDENT(IdHdr,ID_ROCKET);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -57,8 +57,10 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 FGRocket::FGRocket(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
-  : FGEngine(exec, el, engine_number, input), isp_function(0L)
+  : FGEngine(exec, engine_number, input), isp_function(0L)
 {
+  Load(exec, el);
+
   Type = etRocket;
   Element* thrust_table_element = 0;
   ThrustTable = 0L;
index 6ab51091dc10e802ce1365537d82288b365eeb10..5a609f29d646f7dec5fe010e0691bef75a35e375 100644 (file)
@@ -42,6 +42,7 @@ INCLUDES
 #include <iostream>
 #include <sstream>
 
+#include "math/FGFunction.h"
 #include "FGTurbine.h"
 #include "FGThruster.h"
 #include "input_output/FGXMLElement.h"
@@ -50,7 +51,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGTurbine.cpp,v 1.40 2014/01/13 10:46:10 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGTurbine.cpp,v 1.43 2014/06/08 12:50:05 bcoconni Exp $");
 IDENT(IdHdr,ID_TURBINE);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -59,7 +60,7 @@ CLASS IMPLEMENTATION
 
 
 FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
-  : FGEngine(exec, el, engine_number, input)
+  : FGEngine(exec, engine_number, input)
 {
   Type = etTurbine;
 
@@ -75,8 +76,6 @@ FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number, struct Inp
   N1_spinup = 1.0; N2_spinup = 3.0; 
   EPR = 1.0;
 
-  ResetToIC();
-
   Load(exec, el);
   Debug(0);
 }
@@ -85,10 +84,6 @@ FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number, struct Inp
 
 FGTurbine::~FGTurbine()
 {
-  delete IdleThrustLookup;
-  delete MilThrustLookup;
-  delete MaxThrustLookup;
-  delete InjectionLookup;
   Debug(1);
 }
 
@@ -416,8 +411,19 @@ double FGTurbine::Seek(double *var, double target, double accel, double decel) {
 
 bool FGTurbine::Load(FGFDMExec* exec, Element *el)
 {
-  string property_name, property_prefix;
-  property_prefix = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
+  Element* function_element = el->FindElement("function");
+
+  while(function_element) {
+    string name = function_element->GetAttributeValue("name");
+    if (name == "IdleThrust" || name == "MilThrust" || name == "AugThrust" || name == "Injection")
+      function_element->SetAttributeValue("name", string("propulsion/engine[#]/") + name);
+
+    function_element = el->FindNextElement("function");
+  }
+
+  FGEngine::Load(exec, el);
+
+  ResetToIC();
 
   if (el->FindElement("milthrust"))
     MilThrust = el->FindElementValueAsNumberConvertTo("milthrust","LBS");
@@ -452,24 +458,12 @@ bool FGTurbine::Load(FGFDMExec* exec, Element *el)
   if (el->FindElement("injection-time"))
     InjectionTime = el->FindElementValueAsNumber("injection-time");
 
-  Element *function_element;
-  string name;
-  FGPropertyManager* PropertyManager = exec->GetPropertyManager();
+  string property_prefix = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
 
-  while (true) {
-    function_element = el->FindNextElement("function");
-    if (!function_element) break;
-    name = function_element->GetAttributeValue("name");
-    if (name == "IdleThrust") {
-      IdleThrustLookup = new FGFunction(PropertyManager, function_element, property_prefix);
-    } else if (name == "MilThrust") {
-      MilThrustLookup = new FGFunction(PropertyManager, function_element, property_prefix);
-    } else if (name == "AugThrust") {
-      MaxThrustLookup = new FGFunction(PropertyManager, function_element, property_prefix);
-    } else if (name == "Injection") {
-      InjectionLookup = new FGFunction(PropertyManager, function_element, property_prefix);
-    }
-  }
+  IdleThrustLookup = GetPreFunction(property_prefix+"/IdleThrust");
+  MilThrustLookup = GetPreFunction(property_prefix+"/MilThrust");
+  MaxThrustLookup = GetPreFunction(property_prefix+"/AugThrust");
+  InjectionLookup = GetPreFunction(property_prefix+"/Injection");
 
   // Pre-calculations and initializations
 
index f1920554506b7f3591c4ae172fc5962c884faaae..8216a5ca7d50eedc8c8042edef1213d170cd7709 100644 (file)
@@ -54,7 +54,7 @@ using namespace std;
 
 namespace JSBSim {
 
-IDENT(IdSrc,"$Id: FGTurboProp.cpp,v 1.28 2014/01/13 10:46:10 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGTurboProp.cpp,v 1.30 2014/06/08 12:00:35 bcoconni Exp $");
 IDENT(IdHdr,ID_TURBOPROP);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -62,9 +62,10 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
-  : FGEngine(exec, el, engine_number, input),
+  : FGEngine(exec, engine_number, input),
     ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL), CombustionEfficiency_N1(NULL)
 {
+  FGEngine::Load(exec, el);
   SetDefaults();
   thrusterType = Thruster->GetType();