1
0
Fork 0

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.
This commit is contained in:
tony 2002-09-22 15:31:09 +00:00
parent c3a1a9335e
commit 1ca94a72c0
26 changed files with 467 additions and 442 deletions

View file

@ -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);
}

View file

@ -44,6 +44,8 @@ HISTORY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <stdio.h>
#include "FGCoefficient.h"
#include "FGState.h"
#include "FGFDMExec.h"

View file

@ -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("");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -645,7 +645,6 @@ private:
void Debug(int from);
};
#include "FGState.h"
#endif

View file

@ -109,6 +109,8 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
Position = 0;
Auxiliary = 0;
Output = 0;
IC = 0;
Trim = 0;
terminate = false;
frozen = false;
@ -228,6 +230,10 @@ bool FGFDMExec::Allocate(void)
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,14 +387,25 @@ vector <string> 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";
@ -393,6 +416,8 @@ 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

View file

@ -41,10 +41,12 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGModel.h"
#include "FGTrim.h"
#include "FGInitialCondition.h"
#include "FGJSBBase.h"
#include "FGPropertyManager.h"
#include <vector>
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
@ -56,8 +58,6 @@ DEFINITIONS
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGInitialCondition;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@ -138,12 +138,11 @@ 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;}
@ -164,8 +163,37 @@ public:
@return true if successful*/
bool LoadModel(string AircraftPath, string EnginePath, string model);
bool SetEnginePath(string path) {EnginePath = path; return true;}
bool SetAircraftPath(string path) {AircraftPath = path; return true;}
/** 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);
/** 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
//@{
@ -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 <string> 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;
@ -260,6 +299,9 @@ private:
FGAuxiliary* Auxiliary;
FGOutput* Output;
FGInitialCondition* IC;
FGTrim *Trim;
vector <slaveData*> SlaveFDMList;
bool ReadMetrics(FGConfigFile*);

View file

@ -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,18 +718,24 @@ 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
string sep = "/";
# else
string sep = ";";
#endif
# ifndef macintosh
resetDef = acpath + "/" + acname + "/" + rstfile + ".xml";
# else
resetDef = acpath + ";" + acname + ";" + rstfile + ".xml";
# endif
if( useStoredPath ) {
string acpath = fdmex->GetAircraftPath() + sep + fdmex->GetModelName();
resetDef = acpath + sep + rstfile + ".xml";
} else {
resetDef = rstfile;
}
FGConfigFile resetfile(resetDef);
if (!resetfile.IsOpen()) {
@ -770,7 +777,7 @@ bool FGInitialCondition::Load(string acpath, string acname, string rstfile)
resetfile >> token;
}
fdmex->RunIC(this);
fdmex->RunIC();
return true;
}

View file

@ -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);

View file

@ -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';
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -302,6 +302,8 @@ public:
//@}
string GetVersion(void) {return JSBSim_version;}
void disableHighLighting(void);
protected:
static Message localMsg;

View file

@ -35,6 +35,7 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <string>
#include <simgear/misc/props.hxx>
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -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;
}
inline FGPropertyManager*
GetNode (const string &relpath, int index, bool create = false)
{
return (FGPropertyManager*)getNode(relpath.c_str(),index,create);
}
FGPropertyManager*
GetNode (const string &path, bool create = false);
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<bool>(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<int>(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<long>(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<float>(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,14 +451,15 @@ 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<double>(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 <class V> void
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
@ -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,8 +494,8 @@ class FGPropertyManager:public SGPropertyNode {
* property value should be; false if the old value should be
* discarded; defaults to true.
*/
template <class V>
inline void
template <class V> inline void
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
bool useDefault = true)
{
@ -630,9 +524,8 @@ class FGPropertyManager:public SGPropertyNode {
* property value should be; false if the old value should be
* discarded; defaults to true.
*/
template <class V>
inline void
Tie (const string &name, int index, V (*getter)(int),
template <class V> 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,8 +557,7 @@ class FGPropertyManager:public SGPropertyNode {
* property value should be; false if the old value should be
* discarded; defaults to true.
*/
template <class T, class V>
inline void
template <class T, class V> inline void
Tie (const string &name, T * obj, V (T::*getter)() const,
void (T::*setter)(V) = 0, bool useDefault = true)
{
@ -676,7 +568,6 @@ class FGPropertyManager:public SGPropertyNode {
"Failed to tie property " << name << " to object methods" << endl;
}
/**
* Tie a property to a pair of indexed object methods.
*
@ -696,8 +587,7 @@ class FGPropertyManager:public SGPropertyNode {
* property value should be; false if the old value should be
* discarded; defaults to true.
*/
template <class T, class V>
inline void
template <class T, class V> inline void
Tie (const string &name, T * obj, int index,
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
bool useDefault = true)
@ -711,7 +601,6 @@ class FGPropertyManager:public SGPropertyNode {
cout <<
"Failed to tie property " << name << " to indexed object methods" << endl;
}
};
#endif // FGPROPERTYMANAGER_H

View file

@ -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,7 +309,9 @@ 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();

View file

@ -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);
}

View file

@ -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.

View file

@ -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 !!

View file

@ -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,29 +117,6 @@ 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:
<ul>
<li>U, the body X-Axis velocity</li>
<li>V, the body Y-Axis velocity</li>
<li>W, the body Z-Axis velocity</li>
<li>Latitude measured in radians from the equator, negative values are south.</li>
<li>Longitude, measured in radians from the Greenwich meridian, negative values are west.</li>
<li>Phi, the roll angle in radians.</li>
<li>Theta, the pitch attitude in radians.</li>
<li>Psi, the heading angle in radians.</li>
<li>H, the altitude in feet</li>
<li>Wind Direction, the direction the wind is coming <u>from</u>.</li>
<li>Wind magnitude, the wind speed in fps.</li>
</ul>
@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.
@param U the body X-Axis velocity in fps.
@param V the body Y-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

View file

@ -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);

View file

@ -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) {};

View file

@ -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;
@ -602,6 +555,8 @@ void FGTrim::setupPullup() {
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 ) {
@ -651,5 +610,59 @@ void FGTrim::setDebug(void) {
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.

View file

@ -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 <vector>
@ -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);
@ -228,6 +216,12 @@ public:
*/
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
configured to be useful

View file

@ -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();
}
}

View file

@ -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();

View file

@ -38,8 +38,10 @@ HISTORY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <vector>
#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,8 +68,78 @@ 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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -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;
}

View file

@ -42,8 +42,10 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <vector>
#include "FGEngine.h"
#include "FGConfigFile.h"
#include "FGCoefficient.h"
#define ID_TURBINE "$Id$"
@ -60,6 +62,19 @@ public:
double Calculate(double);
private:
typedef vector<FGCoefficient*> 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);
};

View file

@ -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();

View file

@ -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