From 1ca94a72c008cc422a1464beaf1f20d5f1d6ff96 Mon Sep 17 00:00:00 2001 From: tony Date: Sun, 22 Sep 2002 15:31:09 +0000 Subject: [PATCH] Latest updates, including a thrust-only turbofan model. It should produce realistic thrust (including time-dependent effects), but does not provide N1, N2, EPR, etc. --- src/FDM/JSBSim/FGAuxiliary.cpp | 3 + src/FDM/JSBSim/FGCoefficient.cpp | 4 +- src/FDM/JSBSim/FGFCS.cpp | 2 + src/FDM/JSBSim/FGFCS.h | 1 - src/FDM/JSBSim/FGFDMExec.cpp | 80 +++++--- src/FDM/JSBSim/FGFDMExec.h | 64 +++++-- src/FDM/JSBSim/FGInitialCondition.cpp | 25 ++- src/FDM/JSBSim/FGInitialCondition.h | 2 +- src/FDM/JSBSim/FGJSBBase.cpp | 17 ++ src/FDM/JSBSim/FGJSBBase.h | 2 + src/FDM/JSBSim/FGPropertyManager.h | 261 ++++++++------------------ src/FDM/JSBSim/FGPropulsion.cpp | 15 +- src/FDM/JSBSim/FGScript.cpp | 8 +- src/FDM/JSBSim/FGScript.h | 2 +- src/FDM/JSBSim/FGState.cpp | 65 ------- src/FDM/JSBSim/FGState.h | 59 ++---- src/FDM/JSBSim/FGThruster.cpp | 10 + src/FDM/JSBSim/FGThruster.h | 3 +- src/FDM/JSBSim/FGTrim.cpp | 121 ++++++------ src/FDM/JSBSim/FGTrim.h | 20 +- src/FDM/JSBSim/FGTrimAxis.cpp | 8 +- src/FDM/JSBSim/FGTrimAxis.h | 16 +- src/FDM/JSBSim/FGTurbine.cpp | 92 ++++++++- src/FDM/JSBSim/FGTurbine.h | 19 +- src/FDM/JSBSim/JSBSim.cxx | 10 +- src/FDM/JSBSim/Makefile.am | 2 +- 26 files changed, 468 insertions(+), 443 deletions(-) diff --git a/src/FDM/JSBSim/FGAuxiliary.cpp b/src/FDM/JSBSim/FGAuxiliary.cpp index 698c7faab..0ef2a3221 100644 --- a/src/FDM/JSBSim/FGAuxiliary.cpp +++ b/src/FDM/JSBSim/FGAuxiliary.cpp @@ -41,6 +41,7 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #include "FGAuxiliary.h" +#include "FGAerodynamics.h" #include "FGTranslation.h" #include "FGRotation.h" #include "FGAtmosphere.h" @@ -73,6 +74,8 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex) vPilotAccelN.InitMatrix(); + bind(); + Debug(0); } diff --git a/src/FDM/JSBSim/FGCoefficient.cpp b/src/FDM/JSBSim/FGCoefficient.cpp index b143fe94e..d430af3e4 100644 --- a/src/FDM/JSBSim/FGCoefficient.cpp +++ b/src/FDM/JSBSim/FGCoefficient.cpp @@ -44,6 +44,8 @@ HISTORY INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include + #include "FGCoefficient.h" #include "FGState.h" #include "FGFDMExec.h" @@ -208,7 +210,7 @@ double FGCoefficient::Value(double rVal, double cVal) double FGCoefficient::Value(double Val) { double Value; - + SD = Value = gain*Table->GetValue(Val) + bias; for (unsigned int midx=0; midx < multipliers.size(); midx++) diff --git a/src/FDM/JSBSim/FGFCS.cpp b/src/FDM/JSBSim/FGFCS.cpp index e75f7df61..0ac825348 100644 --- a/src/FDM/JSBSim/FGFCS.cpp +++ b/src/FDM/JSBSim/FGFCS.cpp @@ -419,6 +419,7 @@ double FGFCS::GetComponentOutput(int idx) cerr << "Unknown FCS mode" << endl; break; } + return 0.0; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -434,6 +435,7 @@ string FGFCS::GetComponentName(int idx) cerr << "Unknown FCS mode" << endl; break; } + return string(""); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/FGFCS.h b/src/FDM/JSBSim/FGFCS.h index a5387de27..a1a3a55c2 100644 --- a/src/FDM/JSBSim/FGFCS.h +++ b/src/FDM/JSBSim/FGFCS.h @@ -645,7 +645,6 @@ private: void Debug(int from); }; -#include "FGState.h" #endif diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index fa8191660..20cacbe67 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -109,6 +109,8 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root) Position = 0; Auxiliary = 0; Output = 0; + IC = 0; + Trim = 0; terminate = false; frozen = false; @@ -227,7 +229,11 @@ bool FGFDMExec::Allocate(void) Error+=4096;} if (Error > 0) result = false; + + IC = new FGInitialCondition(this); + //Trim is allocated as needed by GetTrim() + // Schedule a model. The second arg (the integer) is the pass number. For // instance, the atmosphere model gets executed every fifth pass it is called // by the executive. Everything else here gets executed each pass. @@ -245,6 +251,9 @@ bool FGFDMExec::Allocate(void) Schedule(Position, 1); Schedule(Auxiliary, 1); Schedule(Output, 1); + //IC and Trim are *not* scheduled objects + + modelLoaded = false; @@ -255,20 +264,23 @@ bool FGFDMExec::Allocate(void) bool FGFDMExec::DeAllocate(void) { - if ( Atmosphere != 0 ) delete Atmosphere; - if ( FCS != 0 ) delete FCS; - if ( Propulsion != 0) delete Propulsion; - if ( MassBalance != 0) delete MassBalance; - if ( Aerodynamics != 0) delete Aerodynamics; - if ( Inertial != 0) delete Inertial; - if ( GroundReactions != 0) delete GroundReactions; - if ( Aircraft != 0 ) delete Aircraft; - if ( Translation != 0 ) delete Translation; - if ( Rotation != 0 ) delete Rotation; - if ( Position != 0 ) delete Position; - if ( Auxiliary != 0 ) delete Auxiliary; - if ( Output != 0 ) delete Output; - if ( State != 0 ) delete State; + delete Atmosphere; + delete FCS; + delete Propulsion; + delete MassBalance; + delete Aerodynamics; + delete Inertial; + delete GroundReactions; + delete Aircraft; + delete Translation; + delete Rotation; + delete Position; + delete Auxiliary; + delete Output; + delete State; + + delete IC; + delete Trim; FirstModel = 0L; Error = 0; @@ -349,10 +361,10 @@ bool FGFDMExec::Run(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGFDMExec::RunIC(FGInitialCondition *fgic) +bool FGFDMExec::RunIC(void) { State->Suspend(); - State->Initialize(fgic); + State->Initialize(IC); Run(); State->Resume(); return true; @@ -375,15 +387,26 @@ vector FGFDMExec::EnumerateFDMs(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGFDMExec::LoadModel(string APath, string EPath, string model) +bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model) { + FGFDMExec::AircraftPath=AircraftPath; + FGFDMExec::EnginePath=EnginePath; + return LoadModel(model); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +bool FGFDMExec::LoadModel(string model) { bool result = true; string token; string aircraftCfgFileName; - AircraftPath = APath; - EnginePath = EPath; - + if( AircraftPath.empty() || EnginePath.empty() ) { + cerr << "Error: attempted to load aircraft with undefined "; + cerr << "aircraft and engine paths" << endl; + return false; + } + # ifndef macintosh aircraftCfgFileName = AircraftPath + "/" + model + "/" + model + ".xml"; # else @@ -392,7 +415,9 @@ bool FGFDMExec::LoadModel(string APath, string EPath, string model) FGConfigFile AC_cfg(aircraftCfgFileName); if (!AC_cfg.IsOpen()) return false; - + + modelName = model; + if (modelLoaded) { DeAllocate(); Allocate(); @@ -495,7 +520,10 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg) string AircraftName = AC_cfg->GetValue("FILE"); debug_lvl = 0; // turn off debug output for slave vehicle - SlaveFDMList.back()->exec->LoadModel("aircraft", "engine", AircraftName); + + SlaveFDMList.back()->exec->SetAircraftPath( AircraftPath ); + SlaveFDMList.back()->exec->SetEnginePath( EnginePath ); + SlaveFDMList.back()->exec->LoadModel(AircraftName); debug_lvl = saved_debug_lvl; // turn debug output back on for master vehicle AC_cfg->GetNextConfigLine(); @@ -594,6 +622,14 @@ FGPropertyManager* FGFDMExec::GetPropertyManager(void) { return instance; } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FGTrim* FGFDMExec::GetTrim(void) { + delete Trim; + Trim = new FGTrim(this,tNone); + return Trim; +} + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // The bitmasked value choices are as follows: // unset: In this case (the default) JSBSim would only print diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h index 10262d8d3..08f6161bc 100644 --- a/src/FDM/JSBSim/FGFDMExec.h +++ b/src/FDM/JSBSim/FGFDMExec.h @@ -41,10 +41,12 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #include "FGModel.h" +#include "FGTrim.h" #include "FGInitialCondition.h" #include "FGJSBBase.h" #include "FGPropertyManager.h" + #include /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEFINITIONS @@ -56,8 +58,6 @@ DEFINITIONS FORWARD DECLARATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -class FGInitialCondition; - /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -138,20 +138,19 @@ public: @return true if successful, false if sim should be ended */ bool Run(void); - /** Initializes the sim with a set of initial conditions. - @param fgic A pointer to a filled out initial conditions class which - describes the desired initial conditions. + /** Initializes the sim from the initial condition object and executes + each scheduled model without integrating i.e. dt=0. @return true if successful */ - bool RunIC(FGInitialCondition *fgic); + bool RunIC(void); /// Freezes the sim void Freeze(void) {frozen = true;} /// Resumes the sim void Resume(void) {frozen = false;} - - /** Loads an aircraft model. + + /** Loads an aircraft model. @param AircraftPath path to the aircraft directory. For instance: "aircraft". Under aircraft, then, would be directories for various modeled aircraft such as C172/, x15/, etc. @@ -163,10 +162,39 @@ public: instance: "aircraft/x15/x15.xml" @return true if successful*/ bool LoadModel(string AircraftPath, string EnginePath, string model); + + + /** Loads an aircraft model. The paths to the aircraft and engine + config file directories must be set prior to calling this. See + below. + @param model the name of the aircraft model itself. This file will + be looked for in the directory specified in the AircraftPath variable, + and in turn under the directory with the same name as the model. For + instance: "aircraft/x15/x15.xml" + @return true if successful*/ + bool LoadModel(string model); + - bool SetEnginePath(string path) {EnginePath = path; return true;} - bool SetAircraftPath(string path) {AircraftPath = path; return true;} + /** Sets the path to the engine config file directories. + @param EnginePath path to the directory under which engine config + files are kept, for instance "engine" + */ + bool SetEnginePath(string path) { EnginePath = path; return true; } + /** Sets the path to the aircraft config file directories. + @param AircraftPath path to the aircraft directory. For instance: + "aircraft". Under aircraft, then, would be directories for various + modeled aircraft such as C172/, x15/, etc. + */ + bool SetAircraftPath(string path) { AircraftPath = path; return true; } + + /** Sets the path to the autopilot config file directories. + @param ControlPath path to the control directory. For instance: + "control". + */ + bool SetControlPath(string path) { ControlPath = path; return true; } + + /// @name Top-level executive State and Model retrieval mechanism //@{ /// Returns the FGState pointer. @@ -197,12 +225,20 @@ public: inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;} /// Returns the FGOutput pointer. inline FGOutput* GetOutput(void) {return Output;} + // Returns a pointer to the FGInitialCondition object + inline FGInitialCondition* GetIC(void) {return IC;} + // Returns a pointer to the FGTrim object + FGTrim* GetTrim(void); //@} - + /// Retrieves the engine path. inline string GetEnginePath(void) {return EnginePath;} /// Retrieves the aircraft path. inline string GetAircraftPath(void) {return AircraftPath;} + /// Retrieves the control path. + inline string GetControlPath(void) {return ControlPath;} + + string GetModelName(void) { return modelName; } FGPropertyManager* GetPropertyManager(void); vector EnumerateFDMs(void); @@ -218,6 +254,7 @@ private: unsigned int IdFDM; static unsigned int FDMctr; bool modelLoaded; + string modelName; bool IsSlave; static FGPropertyManager *master; FGPropertyManager *instance; @@ -243,6 +280,8 @@ private: string AircraftPath; string EnginePath; + string ControlPath; + string CFGVersion; FGState* State; @@ -259,6 +298,9 @@ private: FGPosition* Position; FGAuxiliary* Auxiliary; FGOutput* Output; + + FGInitialCondition* IC; + FGTrim *Trim; vector SlaveFDMList; diff --git a/src/FDM/JSBSim/FGInitialCondition.cpp b/src/FDM/JSBSim/FGInitialCondition.cpp index 58d739053..f9fbc31b5 100644 --- a/src/FDM/JSBSim/FGInitialCondition.cpp +++ b/src/FDM/JSBSim/FGInitialCondition.cpp @@ -46,6 +46,7 @@ INCLUDES #include "FGFDMExec.h" #include "FGState.h" #include "FGAtmosphere.h" +#include "FGAerodynamics.h" #include "FGFCS.h" #include "FGAircraft.h" #include "FGTranslation.h" @@ -717,19 +718,25 @@ double FGInitialCondition::GetWindDirDegIC(void) { //****************************************************************************** -bool FGInitialCondition::Load(string acpath, string acname, string rstfile) +bool FGInitialCondition::Load(string rstfile, bool useStoredPath) { string resetDef; string token=""; double temp; - -# ifndef macintosh - resetDef = acpath + "/" + acname + "/" + rstfile + ".xml"; -# else - resetDef = acpath + ";" + acname + ";" + rstfile + ".xml"; -# endif - + # ifndef macintosh + string sep = "/"; + # else + string sep = ";"; + #endif + + if( useStoredPath ) { + string acpath = fdmex->GetAircraftPath() + sep + fdmex->GetModelName(); + resetDef = acpath + sep + rstfile + ".xml"; + } else { + resetDef = rstfile; + } + FGConfigFile resetfile(resetDef); if (!resetfile.IsOpen()) { cerr << "Failed to open reset file: " << resetDef << endl; @@ -770,7 +777,7 @@ bool FGInitialCondition::Load(string acpath, string acname, string rstfile) resetfile >> token; } - fdmex->RunIC(this); + fdmex->RunIC(); return true; } diff --git a/src/FDM/JSBSim/FGInitialCondition.h b/src/FDM/JSBSim/FGInitialCondition.h index a68bd0063..753b26dc2 100644 --- a/src/FDM/JSBSim/FGInitialCondition.h +++ b/src/FDM/JSBSim/FGInitialCondition.h @@ -252,7 +252,7 @@ public: inline speedset GetSpeedSet(void) { return lastSpeedSet; } inline windset GetWindSet(void) { return lastWindSet; } - bool Load(string acpath, string acname, string rstname); + bool Load(string rstname, bool useStoredPath = true ); void bind(void); void unbind(void); diff --git a/src/FDM/JSBSim/FGJSBBase.cpp b/src/FDM/JSBSim/FGJSBBase.cpp index 591a9897e..7ad08bb31 100644 --- a/src/FDM/JSBSim/FGJSBBase.cpp +++ b/src/FDM/JSBSim/FGJSBBase.cpp @@ -167,3 +167,20 @@ FGJSBBase::Message* FGJSBBase::ProcessMessage(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +void FGJSBBase::disableHighLighting(void) { + highint[0]='\0'; + halfint[0]='\0'; + normint[0]='\0'; + reset[0]='\0'; + underon[0]='\0'; + underoff[0]='\0'; + fgblue[0]='\0'; + fgcyan[0]='\0'; + fgred[0]='\0'; + fggreen[0]='\0'; + fgdef[0]='\0'; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + diff --git a/src/FDM/JSBSim/FGJSBBase.h b/src/FDM/JSBSim/FGJSBBase.h index 6f4fe91c9..4b522d3f2 100644 --- a/src/FDM/JSBSim/FGJSBBase.h +++ b/src/FDM/JSBSim/FGJSBBase.h @@ -301,6 +301,8 @@ public: Message* ProcessMessage(void); //@} string GetVersion(void) {return JSBSim_version;} + + void disableHighLighting(void); protected: static Message localMsg; diff --git a/src/FDM/JSBSim/FGPropertyManager.h b/src/FDM/JSBSim/FGPropertyManager.h index 95001a307..06eea8498 100644 --- a/src/FDM/JSBSim/FGPropertyManager.h +++ b/src/FDM/JSBSim/FGPropertyManager.h @@ -35,6 +35,7 @@ SENTRY INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include #include /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -69,16 +70,22 @@ CLASS DOCUMENTATION CLASS DECLARATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -class FGPropertyManager:public SGPropertyNode { +class FGPropertyManager : public SGPropertyNode { public: /// Constructor - FGPropertyManager(void) { - - } + FGPropertyManager(void) {} /// Destructor - ~FGPropertyManager(void) { - - } + ~FGPropertyManager(void) {} + + /** Property-ify a name + * replaces spaces with '-' and, optionally, makes name all lower case + * @param name string to change + * @param lowercase true to change all upper case chars to lower + * NOTE: this function changes its argument and thus relies + * on pass by value + */ + string mkPropertyName(string name, bool lowercase); + /** * Get a property node. * @@ -86,22 +93,11 @@ class FGPropertyManager:public SGPropertyNode { * @param create true to create the node if it doesn't exist. * @return The node, or 0 if none exists and none was created. */ - inline FGPropertyManager* - GetNode (const string &path, bool create = false) - { - SGPropertyNode* node=this->getNode(path.c_str(), create); - if(node == 0) - cout << "FGPropertyManager::GetNode() No node found for " - << path << endl; - return (FGPropertyManager*)node; - } + FGPropertyManager* + GetNode (const string &path, bool create = false); - inline FGPropertyManager* - GetNode (const string &relpath, int index, bool create = false) - { - return (FGPropertyManager*)getNode(relpath.c_str(),index,create); - } - + FGPropertyManager* + GetNode (const string &relpath, int index, bool create = false); /** * Test whether a given node exists. @@ -109,19 +105,12 @@ class FGPropertyManager:public SGPropertyNode { * @param path The path of the node, relative to root. * @return true if the node exists, false otherwise. */ - inline bool - HasNode (const string &path) - { - return (GetNode(path, false) != 0); - } + bool HasNode (const string &path); /** * Get the name of a node */ - inline string - GetName( void ) { - return string( getName() ); - } + string GetName( void ); /** * Get a bool value for a property. @@ -137,10 +126,7 @@ class FGPropertyManager:public SGPropertyNode { * does not exist. * @return The property's value as a bool, or the default value provided. */ - inline bool GetBool (const string &name, bool defaultValue = false) - { - return getBoolValue(name.c_str(), defaultValue); - } + bool GetBool (const string &name, bool defaultValue = false); /** @@ -157,10 +143,7 @@ class FGPropertyManager:public SGPropertyNode { * does not exist. * @return The property's value as an int, or the default value provided. */ - inline int GetInt (const string &name, int defaultValue = 0) - { - return getIntValue(name.c_str(), defaultValue); - } + int GetInt (const string &name, int defaultValue = 0); /** @@ -177,10 +160,7 @@ class FGPropertyManager:public SGPropertyNode { * does not exist. * @return The property's value as a long, or the default value provided. */ - inline int GetLong (const string &name, long defaultValue = 0L) - { - return getLongValue(name.c_str(), defaultValue); - } + int GetLong (const string &name, long defaultValue = 0L); /** @@ -197,10 +177,7 @@ class FGPropertyManager:public SGPropertyNode { * does not exist. * @return The property's value as a float, or the default value provided. */ - inline float GetFloat (const string &name, float defaultValue = 0.0) - { - return getFloatValue(name.c_str(), defaultValue); - } + float GetFloat (const string &name, float defaultValue = 0.0); /** @@ -217,10 +194,7 @@ class FGPropertyManager:public SGPropertyNode { * does not exist. * @return The property's value as a double, or the default value provided. */ - inline double GetDouble (const string &name, double defaultValue = 0.0) - { - return getDoubleValue(name.c_str(), defaultValue); - } + double GetDouble (const string &name, double defaultValue = 0.0); /** @@ -237,10 +211,7 @@ class FGPropertyManager:public SGPropertyNode { * does not exist. * @return The property's value as a string, or the default value provided. */ - inline string GetString (const string &name, string defaultValue = "") - { - return string(getStringValue(name.c_str(), defaultValue.c_str())); - } + string GetString (const string &name, string defaultValue = ""); /** @@ -256,10 +227,7 @@ class FGPropertyManager:public SGPropertyNode { * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ - inline bool SetBool (const string &name, bool val) - { - return setBoolValue(name.c_str(), val); - } + bool SetBool (const string &name, bool val); /** @@ -275,10 +243,7 @@ class FGPropertyManager:public SGPropertyNode { * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ - inline bool SetInt (const string &name, int val) - { - return setIntValue(name.c_str(), val); - } + bool SetInt (const string &name, int val); /** @@ -294,10 +259,7 @@ class FGPropertyManager:public SGPropertyNode { * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ - inline bool SetLong (const string &name, long val) - { - return setLongValue(name.c_str(), val); - } + bool SetLong (const string &name, long val); /** @@ -313,10 +275,7 @@ class FGPropertyManager:public SGPropertyNode { * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ - inline bool SetFloat (const string &name, float val) - { - return setFloatValue(name.c_str(), val); - } + bool SetFloat (const string &name, float val); /** @@ -332,10 +291,7 @@ class FGPropertyManager:public SGPropertyNode { * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ - inline bool SetDouble (const string &name, double val) - { - return setDoubleValue(name.c_str(), val); - } + bool SetDouble (const string &name, double val); /** @@ -351,10 +307,7 @@ class FGPropertyManager:public SGPropertyNode { * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ - inline bool SetString (const string &name, const string &val) - { - return setStringValue(name.c_str(), val.c_str()); - } + bool SetString (const string &name, const string &val); //////////////////////////////////////////////////////////////////////// @@ -374,17 +327,7 @@ class FGPropertyManager:public SGPropertyNode { * @param name The property name. * @param state The state of the archive attribute (defaults to true). */ - inline void - SetArchivable (const string &name, bool state = true) - { - SGPropertyNode * node = getNode(name.c_str()); - if (node == 0) - cout << - "Attempt to set archive flag for non-existant property " - << name << endl; - else - node->setAttribute(SGPropertyNode::ARCHIVE, state); - } + void SetArchivable (const string &name, bool state = true); /** @@ -399,17 +342,7 @@ class FGPropertyManager:public SGPropertyNode { * @param name The property name. * @param state The state of the read attribute (defaults to true). */ - inline void - SetReadable (const string &name, bool state = true) - { - SGPropertyNode * node = getNode(name.c_str()); - if (node == 0) - cout << - "Attempt to set read flag for non-existant property " - << name << endl; - else - node->setAttribute(SGPropertyNode::READ, state); - } + void SetReadable (const string &name, bool state = true); /** @@ -424,17 +357,7 @@ class FGPropertyManager:public SGPropertyNode { * @param name The property name. * @param state The state of the write attribute (defaults to true). */ - inline void - SetWritable (const string &name, bool state = true) - { - SGPropertyNode * node = getNode(name.c_str()); - if (node == 0) - cout << - "Attempt to set write flag for non-existant property " - << name << endl; - else - node->setAttribute(SGPropertyNode::WRITE, state); - } + void SetWritable (const string &name, bool state = true); //////////////////////////////////////////////////////////////////////// @@ -448,12 +371,7 @@ class FGPropertyManager:public SGPropertyNode { * Classes should use this function to release control of any * properties they are managing. */ - inline void - Untie (const string &name) - { - if (!untie(name.c_str())) - cout << "Failed to untie property " << name << endl; - } + void Untie (const string &name); // Templates cause ambiguity here @@ -470,14 +388,8 @@ class FGPropertyManager:public SGPropertyNode { * copied to the variable; false if the variable should not * be modified; defaults to true. */ - inline void - Tie (const string &name, bool *pointer, bool useDefault = true) - { - if (!tie(name.c_str(), SGRawValuePointer(pointer), - useDefault)) - cout << - "Failed to tie property " << name << " to a pointer" << endl; - } + void + Tie (const string &name, bool *pointer, bool useDefault = true); /** @@ -492,14 +404,8 @@ class FGPropertyManager:public SGPropertyNode { * copied to the variable; false if the variable should not * be modified; defaults to true. */ - inline void - Tie (const string &name, int *pointer, bool useDefault = true) - { - if (!tie(name.c_str(), SGRawValuePointer(pointer), - useDefault)) - cout << - "Failed to tie property " << name << " to a pointer" << endl; - } + void + Tie (const string &name, int *pointer, bool useDefault = true); /** @@ -514,14 +420,8 @@ class FGPropertyManager:public SGPropertyNode { * copied to the variable; false if the variable should not * be modified; defaults to true. */ - inline void - Tie (const string &name, long *pointer, bool useDefault = true) - { - if (!tie(name.c_str(), SGRawValuePointer(pointer), - useDefault)) - cout << - "Failed to tie property " << name << " to a pointer" << endl; - } + void + Tie (const string &name, long *pointer, bool useDefault = true); /** @@ -536,15 +436,8 @@ class FGPropertyManager:public SGPropertyNode { * copied to the variable; false if the variable should not * be modified; defaults to true. */ - inline void - Tie (const string &name, float *pointer, bool useDefault = true) - { - if (!tie(name.c_str(), SGRawValuePointer(pointer), - useDefault)) - cout << - "Failed to tie property " << name << " to a pointer" << endl; - } - + void + Tie (const string &name, float *pointer, bool useDefault = true); /** * Tie a property to an external double variable. @@ -558,15 +451,16 @@ class FGPropertyManager:public SGPropertyNode { * copied to the variable; false if the variable should not * be modified; defaults to true. */ - inline void - Tie (const string &name, double *pointer, bool useDefault = true) - { - if (!tie(name.c_str(), SGRawValuePointer(pointer), - useDefault)) - cout << - "Failed to tie property " << name << " to a pointer" << endl; - } - + void + Tie (const string &name, double *pointer, bool useDefault = true); + +//============================================================================ +// +// All of the following functions *must* be inlined, otherwise linker +// errors will result +// +//============================================================================ + /* template void Tie (const string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true); @@ -584,7 +478,7 @@ class FGPropertyManager:public SGPropertyNode { V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true); */ -/** + /** * Tie a property to a pair of simple functions. * * Every time the property value is queried, the getter (if any) will @@ -600,10 +494,10 @@ class FGPropertyManager:public SGPropertyNode { * property value should be; false if the old value should be * discarded; defaults to true. */ - template - inline void + + template inline void Tie (const string &name, V (*getter)(), void (*setter)(V) = 0, - bool useDefault = true) + bool useDefault = true) { if (!tie(name.c_str(), SGRawValueFunctions(getter, setter), useDefault)) @@ -630,9 +524,8 @@ class FGPropertyManager:public SGPropertyNode { * property value should be; false if the old value should be * discarded; defaults to true. */ - template - inline void - Tie (const string &name, int index, V (*getter)(int), + template inline void Tie (const string &name, + int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) { if (!tie(name.c_str(), @@ -664,19 +557,17 @@ class FGPropertyManager:public SGPropertyNode { * property value should be; false if the old value should be * discarded; defaults to true. */ - template - inline void + template inline void Tie (const string &name, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) { if (!tie(name.c_str(), - SGRawValueMethods(*obj, getter, setter), - useDefault)) + SGRawValueMethods(*obj, getter, setter), + useDefault)) cout << - "Failed to tie property " << name << " to object methods" << endl; + "Failed to tie property " << name << " to object methods" << endl; } - - + /** * Tie a property to a pair of indexed object methods. * @@ -696,23 +587,21 @@ class FGPropertyManager:public SGPropertyNode { * property value should be; false if the old value should be * discarded; defaults to true. */ - template - inline void + template inline void Tie (const string &name, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, - bool useDefault = true) + bool useDefault = true) { if (!tie(name.c_str(), - SGRawValueMethodsIndexed(*obj, - index, - getter, - setter), - useDefault)) + SGRawValueMethodsIndexed(*obj, + index, + getter, + setter), + useDefault)) cout << - "Failed to tie property " << name << " to indexed object methods" << endl; - } - -}; + "Failed to tie property " << name << " to indexed object methods" << endl; + } +}; #endif // FGPROPERTYMANAGER_H diff --git a/src/FDM/JSBSim/FGPropulsion.cpp b/src/FDM/JSBSim/FGPropulsion.cpp index 1c4082bf3..3ee7b2058 100644 --- a/src/FDM/JSBSim/FGPropulsion.cpp +++ b/src/FDM/JSBSim/FGPropulsion.cpp @@ -150,7 +150,7 @@ bool FGPropulsion::GetSteadyState(void) } else { steady_count=0; } - j++; + j++; } vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces vMoments += Thrusters[i]->GetMoments(); // sum body frame moments @@ -173,7 +173,7 @@ bool FGPropulsion::ICEngineStart(void) vForces.InitMatrix(); vMoments.InitMatrix(); - + for (unsigned int i=0; iSetTrimMode(true); Thrusters[i]->SetdeltaT(dt*rate); @@ -181,7 +181,7 @@ bool FGPropulsion::ICEngineStart(void) while (!Engines[i]->GetRunning() && j < 2000) { PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired()); Thrusters[i]->Calculate(PowerAvailable); - j++; + j++; } vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces vMoments += Thrusters[i]->GetMoments(); // sum body frame moments @@ -225,6 +225,7 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg) if (Eng_cfg.IsOpen()) { Eng_cfg.GetNextConfigLine(); engType = Eng_cfg.GetValue(); + cout << engType << endl; FCS->AddThrottle(); ThrottleAdded = true; @@ -308,8 +309,10 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg) if (thrType == "FG_PROPELLER") { Thrusters.push_back(new FGPropeller(FDMExec, &Thruster_cfg)); } else if (thrType == "FG_NOZZLE") { - Thrusters.push_back(new FGNozzle(FDMExec, &Thruster_cfg)); - } + Thrusters.push_back(new FGNozzle(FDMExec, &Thruster_cfg )); + } else if (thrType == "FG_DIRECT") { + Thrusters.push_back(new FGThruster( FDMExec, &Thruster_cfg) ); + } AC_cfg->GetNextConfigLine(); while ((token = AC_cfg->GetValue()) != string("/AC_THRUSTER")) { @@ -402,7 +405,7 @@ string FGPropulsion::GetPropulsionStrings(void) default: PropulsionStrings += "INVALID THRUSTER TYPE"; break; - } + } } return PropulsionStrings; diff --git a/src/FDM/JSBSim/FGScript.cpp b/src/FDM/JSBSim/FGScript.cpp index c8f736284..13526278f 100644 --- a/src/FDM/JSBSim/FGScript.cpp +++ b/src/FDM/JSBSim/FGScript.cpp @@ -86,7 +86,7 @@ FGScript::~FGScript() //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGScript::LoadScript(string script) +bool FGScript::LoadScript( string script ) { FGConfigFile Script(script); string token=""; @@ -115,7 +115,7 @@ bool FGScript::LoadScript(string script) if (token == "use") { if ((token = Script.GetValue("aircraft")) != string("")) { aircraft = token; - result = FDMExec->LoadModel("aircraft", "engine", aircraft); + result = FDMExec->LoadModel(aircraft); if (!result) { cerr << "Aircraft file " << aircraft << " was not found" << endl; exit(-1); @@ -204,8 +204,8 @@ bool FGScript::LoadScript(string script) Debug(4); - FGInitialCondition IC(FDMExec); - if ( ! IC.Load("aircraft", aircraft, initialize)) { + FGInitialCondition *IC=FDMExec->GetIC(); + if ( ! IC->Load( initialize )) { cerr << "Initialization unsuccessful" << endl; exit(-1); } diff --git a/src/FDM/JSBSim/FGScript.h b/src/FDM/JSBSim/FGScript.h index 0aa7d5d2c..b188d6855 100644 --- a/src/FDM/JSBSim/FGScript.h +++ b/src/FDM/JSBSim/FGScript.h @@ -146,7 +146,7 @@ public: The language is the Simple Script Directives for JSBSim (SSDJ). @param script the filename (including path name, if any) for the script. @return true if successful */ - bool LoadScript(string script); + bool LoadScript( string script ); /** This function is called each pass through the executive Run() method IF scripting is enabled. diff --git a/src/FDM/JSBSim/FGState.cpp b/src/FDM/JSBSim/FGState.cpp index dd1a4ddca..4ca4edc77 100644 --- a/src/FDM/JSBSim/FGState.cpp +++ b/src/FDM/JSBSim/FGState.cpp @@ -101,71 +101,6 @@ FGState::~FGState() Debug(1); } -//*************************************************************************** -// -// Reset: Assume all angles READ FROM FILE IN DEGREES !! -// - -bool FGState::Reset(string path, string acname, string fname) -{ - string resetDef; - string token=""; - - double U, V, W; - double phi, tht, psi; - double latitude, longitude, h; - double wdir, wmag, wnorth, weast; - -# ifndef macintosh - resetDef = path + "/" + acname + "/" + fname + ".xml"; -# else - resetDef = path + ";" + acname + ";" + fname + ".xml"; -# endif - - FGConfigFile resetfile(resetDef); - if (!resetfile.IsOpen()) return false; - - resetfile.GetNextConfigLine(); - token = resetfile.GetValue(); - if (token != string("initialize")) { - cerr << "The reset file " << resetDef - << " does not appear to be a reset file" << endl; - return false; - } else { - resetfile.GetNextConfigLine(); - resetfile >> token; - cout << "Resetting using: " << token << endl << endl; - } - - while (token != string("/initialize") && token != string("EOF")) { - if (token == "UBODY") resetfile >> U; - if (token == "VBODY") resetfile >> V; - if (token == "WBODY") resetfile >> W; - if (token == "LATITUDE") resetfile >> latitude; - if (token == "LONGITUDE") resetfile >> longitude; - if (token == "PHI") resetfile >> phi; - if (token == "THETA") resetfile >> tht; - if (token == "PSI") resetfile >> psi; - if (token == "ALTITUDE") resetfile >> h; - if (token == "WINDDIR") resetfile >> wdir; - if (token == "VWIND") resetfile >> wmag; - - resetfile >> token; - } - - Position->SetLatitude(latitude*degtorad); - Position->SetLongitude(longitude*degtorad); - Position->Seth(h); - - wnorth = wmag*ktstofps*cos(wdir*degtorad); - weast = wmag*ktstofps*sin(wdir*degtorad); - - Initialize(U, V, W, phi*degtorad, tht*degtorad, psi*degtorad, - latitude*degtorad, longitude*degtorad, h, wnorth, weast, 0.0); - - return true; -} - //*************************************************************************** // // Initialize: Assume all angles GIVEN IN RADIANS !! diff --git a/src/FDM/JSBSim/FGState.h b/src/FDM/JSBSim/FGState.h index 681e94611..37cd93173 100644 --- a/src/FDM/JSBSim/FGState.h +++ b/src/FDM/JSBSim/FGState.h @@ -64,6 +64,19 @@ INCLUDES #include "FGColumnVector3.h" #include "FGColumnVector4.h" +#include "FGFDMExec.h" +#include "FGAtmosphere.h" +#include "FGFCS.h" +#include "FGTranslation.h" +#include "FGRotation.h" +#include "FGPosition.h" +#include "FGAerodynamics.h" +#include "FGOutput.h" +#include "FGAircraft.h" +#include "FGGroundReactions.h" +#include "FGPropulsion.h" + + /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -74,16 +87,6 @@ DEFINITIONS FORWARD DECLARATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -class FGAircraft; -class FGTranslation; -class FGRotation; -class FGAtmosphere; -class FGOutput; -class FGPosition; -class FGFDMExec; -class FGGroundReactions; -class FGPropulsion; - /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -114,30 +117,7 @@ public: /// Destructor ~FGState(); - /** Specifies the Reset file to use. - The reset file normally resides in the same directory as an aircraft config file. - it includes the following information: -
    -
  • U, the body X-Axis velocity
  • -
  • V, the body Y-Axis velocity
  • -
  • W, the body Z-Axis velocity
  • -
  • Latitude measured in radians from the equator, negative values are south.
  • -
  • Longitude, measured in radians from the Greenwich meridian, negative values are west.
  • -
  • Phi, the roll angle in radians.
  • -
  • Theta, the pitch attitude in radians.
  • -
  • Psi, the heading angle in radians.
  • -
  • H, the altitude in feet
  • -
  • Wind Direction, the direction the wind is coming from.
  • -
  • Wind magnitude, the wind speed in fps.
  • -
- @param path the path string leading to the specific aircraft file, i.e. "aircraft". - @param aircraft the name of the aircraft, i.e. "c172". - @param filename the name of the reset file without an extension, i.e. "reset00". - @return true if successful, false if the file could not be opened. - */ - bool Reset(string path, string aircraft, string filename); - - /** Initializes the simulation state based on the passed-in parameters. + /** Initializes the simulation state based on the passed-in parameters. @param U the body X-Axis velocity in fps. @param V the body Y-Axis velocity in fps. @param W the body Z-Axis velocity in fps. @@ -392,17 +372,6 @@ private: //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -#include "FGFDMExec.h" -#include "FGAtmosphere.h" -#include "FGFCS.h" -#include "FGTranslation.h" -#include "FGRotation.h" -#include "FGPosition.h" -#include "FGAerodynamics.h" -#include "FGOutput.h" -#include "FGAircraft.h" -#include "FGGroundReactions.h" -#include "FGPropulsion.h" #endif diff --git a/src/FDM/JSBSim/FGThruster.cpp b/src/FDM/JSBSim/FGThruster.cpp index 1a574a6a5..f1330f967 100644 --- a/src/FDM/JSBSim/FGThruster.cpp +++ b/src/FDM/JSBSim/FGThruster.cpp @@ -55,6 +55,16 @@ FGThruster::FGThruster(FGFDMExec *FDMExec) : FGForce(FDMExec), //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +FGThruster::FGThruster(FGFDMExec *FDMExec, + FGConfigFile *Eng_cfg ): FGForce(FDMExec) { + ThrusterNumber=0; + SetTransformType(FGForce::tCustom); + Name=Eng_cfg->GetValue(); + Debug(0); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + FGThruster::~FGThruster() { Debug(1); diff --git a/src/FDM/JSBSim/FGThruster.h b/src/FDM/JSBSim/FGThruster.h index d62a3c455..cba795d41 100644 --- a/src/FDM/JSBSim/FGThruster.h +++ b/src/FDM/JSBSim/FGThruster.h @@ -69,12 +69,13 @@ class FGThruster : public FGForce { public: /// Constructor FGThruster(FGFDMExec *FDMExec); + FGThruster(FGFDMExec *FDMExec, FGConfigFile *Eng_cfg ); /// Destructor virtual ~FGThruster(); enum eType {ttNozzle, ttRotor, ttPropeller}; - virtual double Calculate(double) {return 0.0;} + virtual double Calculate(double Thrust) { vFn(1)=Thrust; return 0.0; } void SetName(string name) {Name = name;} void SetThrusterNumber(int nn) {ThrusterNumber = nn;} virtual void SetRPM(double rpm) {}; diff --git a/src/FDM/JSBSim/FGTrim.cpp b/src/FDM/JSBSim/FGTrim.cpp index a5fc75d9e..48fb0cfd7 100644 --- a/src/FDM/JSBSim/FGTrim.cpp +++ b/src/FDM/JSBSim/FGTrim.cpp @@ -63,7 +63,7 @@ static const char *IdHdr = ID_TRIM; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) { +FGTrim::FGTrim(FGFDMExec *FDMExec,TrimMode tt) { N=Nsub=0; max_iterations=60; @@ -73,7 +73,7 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) { Debug=0;DebugLevel=0; fdmex=FDMExec; - fgic=FGIC; + fgic=fdmex->GetIC(); total_its=0; trimudot=true; gamma_fallback=true; @@ -82,56 +82,7 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) { xlo=xhi=alo=ahi=0.0; targetNlf=1.0; debug_axis=tAll; - switch(mode) { - case tFull: - cout << " Full Trim" << endl; - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder )); - break; - case tLongitudinal: - cout << " Longitudinal Trim" << endl; - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); - break; - case tGround: - cout << " Ground Trim" << endl; - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAltAGL )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta )); - //TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tPhi )); - break; - case tPullup: - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tNlf,tAlpha )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder )); - break; - case tTurn: - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tBeta )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron )); - TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder )); - break; - case tCustom: - case tNone: - break; -} - //cout << "TrimAxes.size(): " << TrimAxes.size() << endl; - sub_iterations=new double[TrimAxes.size()]; - successful=new double[TrimAxes.size()]; - solution=new bool[TrimAxes.size()]; - current_axis=0; - + SetMode(tt); if (debug_lvl & 2) cout << "Instantiated: FGTrim" << endl; } @@ -588,6 +539,8 @@ bool FGTrim::checkLimits(void) { return solutionExists; } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void FGTrim::setupPullup() { float g,q,cgamma; FGColumnVector3 vPQR; @@ -601,7 +554,9 @@ void FGTrim::setupPullup() { cout << "setPitchRateInPullup() complete" << endl; } - + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void FGTrim::setupTurn(void){ double g,phi; phi = fgic->GetRollAngleRadIC(); @@ -614,6 +569,8 @@ void FGTrim::setupTurn(void){ } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void FGTrim::updateRates(void){ if( mode == tTurn ) { double phi = fgic->GetRollAngleRadIC(); @@ -640,6 +597,8 @@ void FGTrim::updateRates(void){ } } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void FGTrim::setDebug(void) { if(debug_axis == tAll || TrimAxes[current_axis]->GetStateType() == debug_axis ) { @@ -650,6 +609,60 @@ void FGTrim::setDebug(void) { return; } } - + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGTrim::SetMode(TrimMode tt) { + ClearStates(); + switch(tt) { + case tFull: + cout << " Full Trim" << endl; + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder )); + break; + case tLongitudinal: + cout << " Longitudinal Trim" << endl; + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); + break; + case tGround: + cout << " Ground Trim" << endl; + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAltAGL )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta )); + //TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tPhi )); + break; + case tPullup: + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tNlf,tAlpha )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder )); + break; + case tTurn: + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tBeta )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron )); + TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder )); + break; + case tCustom: + case tNone: + break; + } + //cout << "TrimAxes.size(): " << TrimAxes.size() << endl; + sub_iterations=new double[TrimAxes.size()]; + successful=new double[TrimAxes.size()]; + solution=new bool[TrimAxes.size()]; + current_axis=0; +} //YOU WERE WARNED, BUT YOU DID IT ANYWAY. diff --git a/src/FDM/JSBSim/FGTrim.h b/src/FDM/JSBSim/FGTrim.h index f86657095..0b207ec20 100644 --- a/src/FDM/JSBSim/FGTrim.h +++ b/src/FDM/JSBSim/FGTrim.h @@ -52,16 +52,6 @@ INCLUDES #include "FGFDMExec.h" #include "FGJSBBase.h" -#include "FGRotation.h" -#include "FGAtmosphere.h" -#include "FGState.h" -#include "FGFCS.h" -#include "FGAircraft.h" -#include "FGTranslation.h" -#include "FGPosition.h" -#include "FGAuxiliary.h" -#include "FGOutput.h" -#include "FGTrim.h" #include "FGTrimAxis.h" #include @@ -206,10 +196,8 @@ public: /** Initializes the trimming class @param FDMExec pointer to a JSBSim executive object. @param FGIC pointer to a FGInitialCondition object - @param TrimMode the set of axes to trim. Can be: - tLongitudinal, tFull, tGround, tCustom, or tNone */ - FGTrim(FGFDMExec *FDMExec, FGInitialCondition *FGIC, TrimMode tt); + FGTrim(FGFDMExec *FDMExec, TrimMode tt=tGround ); ~FGTrim(void); @@ -227,6 +215,12 @@ public: /** Iteration statistics */ void TrimStats(); + + /** Clear all state-control pairs and set a predefined trim mode + @param TrimMode the set of axes to trim. Can be: + tLongitudinal, tFull, tGround, tCustom, or tNone + */ + void SetMode(TrimMode tt); /** Clear all state-control pairs from the current configuration. The trimming routine must have at least one state-control pair diff --git a/src/FDM/JSBSim/FGTrimAxis.cpp b/src/FDM/JSBSim/FGTrimAxis.cpp index 41f3043eb..485dbd5c2 100644 --- a/src/FDM/JSBSim/FGTrimAxis.cpp +++ b/src/FDM/JSBSim/FGTrimAxis.cpp @@ -45,6 +45,8 @@ INCLUDES #include "FGTrimAxis.h" #include "FGAircraft.h" #include "FGPropulsion.h" +#include "FGAerodynamics.h" + static const char *IdSrc = "$Id$"; static const char *IdHdr = ID_TRIMAXIS; @@ -321,7 +323,7 @@ bool FGTrimAxis::initTheta(void) { while(!level && (i < 100)) { theta+=2.0*zDiff; fgic->SetPitchAngleDegIC(theta); - fdmex->RunIC(fgic); + fdmex->RunIC(); zAft=fdmex->GetGroundReactions()->GetGearUnit(1)->GetLocalGear(3); zForward=fdmex->GetGroundReactions()->GetGearUnit(0)->GetLocalGear(3); zDiff = zForward - zAft; @@ -386,7 +388,7 @@ void FGTrimAxis::Run(void) { while(!stable) { i++; last_state_value=state_value; - fdmex->RunIC(fgic); + fdmex->RunIC(); getState(); if(i > 1) { if((fabs(last_state_value - state_value) < tolerance) || (i >= 100) ) @@ -409,7 +411,7 @@ void FGTrimAxis::setThrottlesPct(void) { //cout << "setThrottlespct: " << i << ", " << control_min << ", " << control_max << ", " << control_value; fdmex->GetFCS()->SetThrottleCmd(i,tMin+control_value*(tMax-tMin)); //cout << "setThrottlespct: " << fdmex->GetFCS()->GetThrottleCmd(i) << endl; - fdmex->RunIC(fgic); //apply throttle change + fdmex->RunIC(); //apply throttle change fdmex->GetPropulsion()->GetSteadyState(); } } diff --git a/src/FDM/JSBSim/FGTrimAxis.h b/src/FDM/JSBSim/FGTrimAxis.h index 86537800a..e687a2771 100644 --- a/src/FDM/JSBSim/FGTrimAxis.h +++ b/src/FDM/JSBSim/FGTrimAxis.h @@ -42,15 +42,7 @@ INCLUDES #include "FGFDMExec.h" #include "FGJSBBase.h" -#include "FGRotation.h" -#include "FGAtmosphere.h" -#include "FGState.h" -#include "FGFCS.h" -#include "FGAircraft.h" -#include "FGTranslation.h" -#include "FGPosition.h" -#include "FGAuxiliary.h" -#include "FGOutput.h" +#include "FGInitialCondition.h" #define ID_TRIMAXIS "$Id$" @@ -67,6 +59,8 @@ const string ControlNames[14]= { "Throttle","Sideslip","Angle of Attack", "Heading" }; +class FGInitialCondition; + /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS DECLARATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -78,7 +72,9 @@ enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL, class FGTrimAxis : public FGJSBBase { public: - FGTrimAxis(FGFDMExec* fdmex, FGInitialCondition *ic, State st, + FGTrimAxis(FGFDMExec* fdmex, + FGInitialCondition *ic, + State st, Control ctrl ); ~FGTrimAxis(); diff --git a/src/FDM/JSBSim/FGTurbine.cpp b/src/FDM/JSBSim/FGTurbine.cpp index d91b9c41a..50f086c8d 100644 --- a/src/FDM/JSBSim/FGTurbine.cpp +++ b/src/FDM/JSBSim/FGTurbine.cpp @@ -38,8 +38,10 @@ HISTORY INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include #include "FGTurbine.h" + static const char *IdSrc = "$Id$"; static const char *IdHdr = ID_TURBINE; @@ -50,6 +52,8 @@ CLASS IMPLEMENTATION FGTurbine::FGTurbine(FGFDMExec* exec, FGConfigFile* cfg) : FGEngine(exec) { + Load(cfg); + PowerCommand=0; Debug(0); } @@ -64,12 +68,82 @@ FGTurbine::~FGTurbine() double FGTurbine::Calculate(double dummy) { + double idle,mil,aug; + double throttle=FCS->GetThrottlePos(EngineNumber); + double dt=State->Getdt(); + if( dt > 0 ) { + PowerCommand+=dt*PowerLag( PowerCommand, + ThrottleToPowerCommand(throttle) ); + if(PowerCommand > 100 ) + PowerCommand=100; + else if(PowerCommand < 0 ) + PowerCommand=0; + + } else { + PowerCommand=ThrottleToPowerCommand(throttle); + } + + mil=MaxMilThrust*ThrustTables[1]->TotalValue(); + + if( PowerCommand <= 50 ) { + idle=MaxMilThrust*ThrustTables[0]->TotalValue(); + Thrust = idle + (mil-idle)*PowerCommand*0.02; + } else { + aug=MaxAugThrust*ThrustTables[2]->TotalValue(); + Thrust = mil + (aug-mil)*(PowerCommand-50)*0.02; + } + ConsumeFuel(); - return 0.0; + + return Thrust; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +double FGTurbine::ThrottleToPowerCommand(double throttle) { + if( throttle <= 0.77 ) + return 64.94*throttle; + else + return 217.38*throttle - 117.38; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +double FGTurbine::PowerLag(double actual_power, double power_command) { + double t, p2; + if( power_command >= 50 ) { + if( actual_power >= 50 ) { + t=5; + p2=power_command; + } else { + p2=60; + t=rtau(p2-actual_power); + } + } else { + if( actual_power >= 50 ) { + t=5; + p2=40; + } else { + p2=power_command; + t=rtau(p2-actual_power); + } + } + return t*(p2-actual_power); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +double FGTurbine::rtau(double delta_power) { + if( delta_power <= 25 ) + return 1.0; + else if ( delta_power >= 50) + return 0.1; + else + return 1.9-0.036*delta_power; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void FGTurbine::doInlet(void) { } @@ -113,8 +187,22 @@ void FGTurbine::doTransition(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGTurbine::Load(FGConfigFile *AC_cfg) +bool FGTurbine::Load(FGConfigFile *Eng_cfg) { + int i; + string token; + Name = Eng_cfg->GetValue("NAME"); + cout << Name << endl; + Eng_cfg->GetNextConfigLine(); + *Eng_cfg >> token >> MaxMilThrust; + *Eng_cfg >> token >> MaxAugThrust; + i=0; + while( Eng_cfg->GetValue() != "/FG_TURBINE" && i < 10){ + ThrustTables.push_back( new FGCoefficient(FDMExec) ); + ThrustTables.back()->Load(Eng_cfg); + i++; + } + return true; } diff --git a/src/FDM/JSBSim/FGTurbine.h b/src/FDM/JSBSim/FGTurbine.h index 25bcedbd3..fee3b66ff 100644 --- a/src/FDM/JSBSim/FGTurbine.h +++ b/src/FDM/JSBSim/FGTurbine.h @@ -42,8 +42,10 @@ SENTRY INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include #include "FGEngine.h" #include "FGConfigFile.h" +#include "FGCoefficient.h" #define ID_TURBINE "$Id$" @@ -58,8 +60,21 @@ public: ~FGTurbine(); double Calculate(double); - + private: + typedef vector CoeffArray; + CoeffArray ThrustTables; + + string name; + double MaxMilThrust; + double MaxAugThrust; + + double PowerCommand; + + double ThrottleToPowerCommand(double throttle); + double PowerLag(double actual_power, double power_command); + double rtau(double delta_power); + void doInlet(void); void doCompressor(void); void doBleedDuct(void); @@ -69,7 +84,7 @@ private: void doTransition(void); - bool Load(FGConfigFile *AC_cfg); + bool Load(FGConfigFile *ENG_cfg); void Debug(int from); }; diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index 753529405..1fbc7b054 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -87,7 +87,7 @@ FGJSBsim::FGJSBsim( double dt ) Aerodynamics = fdmex->GetAerodynamics(); GroundReactions = fdmex->GetGroundReactions(); - fgic=new FGInitialCondition(fdmex); + fgic=fdmex->GetIC(); needTrim=true; SGPath aircraft_path( globals->get_fg_root() ); @@ -231,7 +231,7 @@ void FGJSBsim::init() { copy_to_JSBsim(); - fdmex->RunIC(fgic); //loop JSBSim once w/o integrating + fdmex->RunIC(); //loop JSBSim once w/o integrating copy_from_JSBsim(); //update the bus SG_LOG( SG_FLIGHT, SG_INFO, " Initialized JSBSim with:" ); @@ -315,7 +315,7 @@ FGJSBsim::update( double dt ) { fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() ); do_trim(); } else { - fdmex->RunIC(fgic); //apply any changes made through the set_ functions + fdmex->RunIC(); //apply any changes made through the set_ functions } needTrim = false; } @@ -756,9 +756,9 @@ void FGJSBsim::do_trim(void) { FGTrim *fgtrim; if( fgGetBool("/sim/startup/onground") ) { fgic->SetVcalibratedKtsIC(0.0); - fgtrim=new FGTrim(fdmex,fgic,tGround); + fgtrim=new FGTrim(fdmex,tGround); } else { - fgtrim=new FGTrim(fdmex,fgic,tLongitudinal); + fgtrim=new FGTrim(fdmex,tLongitudinal); } if( !fgtrim->DoTrim() ) { fgtrim->Report(); diff --git a/src/FDM/JSBSim/Makefile.am b/src/FDM/JSBSim/Makefile.am index 977c12d00..9c337da37 100644 --- a/src/FDM/JSBSim/Makefile.am +++ b/src/FDM/JSBSim/Makefile.am @@ -49,7 +49,7 @@ libJSBSim_a_SOURCES = \ FGTank.cpp FGTank.h \ FGfdmSocket.cpp FGfdmSocket.h \ FGTurbine.cpp FGTurbine.h \ - FGPropertyManager.h \ + FGPropertyManager.cpp FGPropertyManager.h \ JSBSim.cxx JSBSim.hxx -- 2.39.5