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
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
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}
}
- // 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");
}
void FGFDMExec::SRand(int sr)
{
+ gaussian_random_number_phase = 0;
srand(sr);
}
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGJSBBase::Message FGJSBBase::localMsg;
unsigned int FGJSBBase::messageId = 0;
+int FGJSBBase::gaussian_random_number_phase = 0;
+
short FGJSBBase::debug_lvl = 1;
using std::cerr;
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 {
} else
X = V2 * sqrt(-2 * log(S) / S);
- phase = 1 - phase;
+ gaussian_random_number_phase = 1 - gaussian_random_number_phase;
return X;
}
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
* 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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
static double sign(double num) {return num>=0.0?1.0:-1.0;}
+ static double GaussianRandomNumber(void);
+
protected:
static Message localMsg;
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
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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;
+}
+}
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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
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;
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"))
}
SetRate(outRate);
- // FIXME : PostLoad should be called in the most derived class ?
- PostLoad(element, PropertyManager);
-
return true;
}
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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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 = "";
}
while (property_element) {
- FGPropertyNode* node = 0;
+ SGPropertyNode* node = 0;
double value=0.0;
if ( ! property_element->GetAttributeValue("value").empty())
value = property_element->GetAttributeValueAsNumber("value");
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"))
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
namespace JSBSim {
class Element;
-class FGPropertyManager;
-class FGPropertyNode;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
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;
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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);
// 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
Debug(4);
- FGInitialCondition *IC=FDMExec->GetIC();
- if ( ! IC->Load( initialize )) {
- cerr << "Initialization unsuccessful" << endl;
- exit(-1);
- }
-
return true;
}
void FGScript::ResetEvents(void)
{
- //ResetToIC();
+ //LocalProperties.ResetToIC();
for (unsigned int i=0; i<Events.size(); i++)
Events[i].reset();
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;
#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
namespace JSBSim {
+class FGFDMExec;
+class FGCondition;
+class FGFunction;
+
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
comes the "run" section, where the conditions are
described in "event" 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
double EndTime;
std::vector <struct event> Events;
+ FGPropertyReader LocalProperties;
+
FGFDMExec* FDMExec;
FGPropertyManager* PropertyManager;
void Debug(int from);
#include "FGXMLElement.h"
#include "string_utilities.h"
+#include "FGJSBBase.h"
using namespace std;
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;
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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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;
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
#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
- 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)
/** 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.
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
*/
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;
typedef std::map <std::string, std::map <std::string, double> > tMapConvert;
static tMapConvert convert;
static bool converterIsInitialized;
- double GaussianRandomNumber(void);
};
} // namespace JSBSim
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)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGXMLParse::~FGXMLParse(void)
-{
- delete document;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
void FGXMLParse::startXML(void)
{
}
void FGXMLParse::reset(void)
{
- delete document;
first_element_read = false;
current_element = document = 0L;
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#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"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/** 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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{
public:
FGXMLParse(void);
- virtual ~FGXMLParse(void);
Element* GetDocument(void) {return document;}
private:
bool first_element_read;
mutable std::string working_string;
- Element *document;
+ Element_ptr document;
Element *current_element;
};
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;
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();
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();
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();
: 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
mTi2l = l.mTi2l;
mTl2i = l.mTl2i;
- initial_longitude = l.initial_longitude;
mGeodLat = l.mGeodLat;
GeodeticAltitude = l.GeodeticAltitude;
}
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
mTi2l = l.mTi2l;
mTl2i = l.mTl2i;
- initial_longitude = l.initial_longitude;
mGeodLat = l.mGeodLat;
GeodeticAltitude = l.GeodeticAltitude;
mCacheValid = false;
- // Need to figure out how to set the initial_longitude here
-
mECLoc(eX) = rtmp*cos(longitude);
mECLoc(eY) = rtmp*sin(longitude);
}
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 );
{
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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#include <iostream>
-
#include "FGJSBBase.h"
#include "FGColumnVector3.h"
#include "FGMatrix33.h"
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
@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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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
#include <iostream>
#include <sstream>
#include <string>
+
#include "FGModelFunctions.h"
#include "FGFunction.h"
#include "input_output/FGXMLElement.h"
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGModelFunctions::InitModel(void)
{
- ResetToIC();
+ LocalProperties.ResetToIC();
return true;
}
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.
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");
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+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 = "";
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
DECLARATION: FGModelFunctions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-class FGModelFunctions : public FGPropertyReader, public FGJSBBase
+class FGModelFunctions : public FGJSBBase
{
public:
virtual ~FGModelFunctions();
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);
};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#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
~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;
#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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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"))) {
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
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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3 vDXYZcg;
FGColumnVector3 vDeltaRP;
double alphaclmax, alphaclmin;
+ double alphaclmax0, alphaclmin0;
double alphahystmax, alphahystmin;
double impending_stall, stall_hyst;
double bi2vel, ci2vel,alphaw;
#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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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) {
#include <string>
#include "FGExternalReactions.h"
-#include "input_output/FGXMLFileRead.h"
#include "input_output/FGXMLElement.h"
using namespace std;
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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);
#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"
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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");
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) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
@property gear/tailhook-pos-norm
@author Jon S. Berndt
- @version $Revision: 1.45 $
+ @version $Revision: 1.46 $
@see FGActuator
@see FGDeadBand
@see FGFCSFunction
@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);
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;
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string token;
Element* element;
- PropertyManager = exec->GetPropertyManager();
+ FGPropertyManager* PropertyManager = exec->GetPropertyManager();
MassBalance = exec->GetMassBalance();
gasCellJ = FGMatrix33();
string token;
Element* element;
- PropertyManager = exec->GetPropertyManager();
+ FGPropertyManager* PropertyManager = exec->GetPropertyManager();
MassBalance = exec->GetMassBalance();
ballonetJ = FGMatrix33();
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
FGMatrix33 gasCellJ; // [slug foot^2]
FGColumnVector3 gasCellM; // [lbs in]
- FGPropertyManager* PropertyManager;
FGMassBalance* MassBalance;
void Debug(int from);
double ValveOpen; // 0 <= ValveOpen <= 1 (or higher).
FGMatrix33 ballonetJ; // [slug foot^2]
- FGPropertyManager* PropertyManager;
FGMassBalance* MassBalance;
void Debug(int from);
#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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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");
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);
#include <cstring>
#include <sstream>
+#include "math/FGFunction.h"
#include "FGLGear.h"
#include "input_output/FGPropertyManager.h"
#include "models/FGGroundReactions.h"
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
#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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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"))
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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
FGFDMExec* GetExec(void) {return FDMExec;}
void SetPropertyManager(FGPropertyManager *fgpm) { PropertyManager=fgpm;}
+ virtual std::string FindFullPathName(const std::string& filename) const;
protected:
int exe_ctr;
/** 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);
#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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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;
if (!Output) return false;
Output->SetIdx(idx);
- Output->Load(document);
+ Output->Load(element);
+ PostLoad(element, PropertyManager);
OutputTypes.push_back(Output);
#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;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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
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;
}
numEngines++;
engine_element = el->FindNextElement("engine");
- XMLFileRead.ResetParser();
}
CalculateTankInertias();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
@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
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;}
bool HaveElectricEngine;
void ConsumeFuel(FGEngine* engine);
+ bool ReadingEngine;
+
void bind();
void Debug(int from);
};
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
vGustNED.InitMatrix();
vTurbulenceNED.InitMatrix();
+ vCosineGust.InitMatrix();
// Milspec turbulence model
windspeed_at_20ft = 0.;
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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
// 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");
}
FGActuator::~FGActuator()
{
+ delete rate_limit_incr;
+ if (rate_limit_decr != rate_limit_incr)
+ delete rate_limit_decr;
+
Debug(1);
}
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
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;
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;
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
@endcode
@author Jon S. Berndt
-@version $Revision: 1.18 $
+@version $Revision: 1.19 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
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;
#include "FGPropeller.h"
#include "FGNozzle.h"
#include "FGRotor.h"
-#include "input_output/FGXMLFileRead.h"
#include "input_output/FGXMLElement.h"
#include "math/FGColumnVector3.h"
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;
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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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;
}
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
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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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};
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;
std::vector <int> SourceTanks;
+ virtual bool Load(FGFDMExec *exec, Element *el);
void Debug(int from);
};
}
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
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
Cp_fuel(1700),
standard_pressure(101320.73)
{
+ Load(exec, el);
+
Element *table_element;
string token;
string name="";
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);
}
}
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
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;
#include <iostream>
#include <sstream>
+#include "math/FGFunction.h"
#include "FGTurbine.h"
#include "FGThruster.h"
#include "input_output/FGXMLElement.h"
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
N1_spinup = 1.0; N2_spinup = 3.0;
EPR = 1.0;
- ResetToIC();
-
Load(exec, el);
Debug(0);
}
FGTurbine::~FGTurbine()
{
- delete IdleThrustLookup;
- delete MilThrustLookup;
- delete MaxThrustLookup;
- delete InjectionLookup;
Debug(1);
}
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");
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
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);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
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();