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:
parent
c3a1a9335e
commit
1ca94a72c0
26 changed files with 467 additions and 442 deletions
|
@ -41,6 +41,7 @@ INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGAuxiliary.h"
|
#include "FGAuxiliary.h"
|
||||||
|
#include "FGAerodynamics.h"
|
||||||
#include "FGTranslation.h"
|
#include "FGTranslation.h"
|
||||||
#include "FGRotation.h"
|
#include "FGRotation.h"
|
||||||
#include "FGAtmosphere.h"
|
#include "FGAtmosphere.h"
|
||||||
|
@ -73,6 +74,8 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
|
|
||||||
vPilotAccelN.InitMatrix();
|
vPilotAccelN.InitMatrix();
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,8 @@ HISTORY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "FGCoefficient.h"
|
#include "FGCoefficient.h"
|
||||||
#include "FGState.h"
|
#include "FGState.h"
|
||||||
#include "FGFDMExec.h"
|
#include "FGFDMExec.h"
|
||||||
|
@ -208,7 +210,7 @@ double FGCoefficient::Value(double rVal, double cVal)
|
||||||
double FGCoefficient::Value(double Val)
|
double FGCoefficient::Value(double Val)
|
||||||
{
|
{
|
||||||
double Value;
|
double Value;
|
||||||
|
|
||||||
SD = Value = gain*Table->GetValue(Val) + bias;
|
SD = Value = gain*Table->GetValue(Val) + bias;
|
||||||
|
|
||||||
for (unsigned int midx=0; midx < multipliers.size(); midx++)
|
for (unsigned int midx=0; midx < multipliers.size(); midx++)
|
||||||
|
|
|
@ -419,6 +419,7 @@ double FGFCS::GetComponentOutput(int idx)
|
||||||
cerr << "Unknown FCS mode" << endl;
|
cerr << "Unknown FCS mode" << endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -434,6 +435,7 @@ string FGFCS::GetComponentName(int idx)
|
||||||
cerr << "Unknown FCS mode" << endl;
|
cerr << "Unknown FCS mode" << endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return string("");
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -645,7 +645,6 @@ private:
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "FGState.h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,8 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
|
||||||
Position = 0;
|
Position = 0;
|
||||||
Auxiliary = 0;
|
Auxiliary = 0;
|
||||||
Output = 0;
|
Output = 0;
|
||||||
|
IC = 0;
|
||||||
|
Trim = 0;
|
||||||
|
|
||||||
terminate = false;
|
terminate = false;
|
||||||
frozen = false;
|
frozen = false;
|
||||||
|
@ -227,7 +229,11 @@ bool FGFDMExec::Allocate(void)
|
||||||
Error+=4096;}
|
Error+=4096;}
|
||||||
|
|
||||||
if (Error > 0) result = false;
|
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
|
// 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
|
// instance, the atmosphere model gets executed every fifth pass it is called
|
||||||
// by the executive. Everything else here gets executed each pass.
|
// by the executive. Everything else here gets executed each pass.
|
||||||
|
@ -245,6 +251,9 @@ bool FGFDMExec::Allocate(void)
|
||||||
Schedule(Position, 1);
|
Schedule(Position, 1);
|
||||||
Schedule(Auxiliary, 1);
|
Schedule(Auxiliary, 1);
|
||||||
Schedule(Output, 1);
|
Schedule(Output, 1);
|
||||||
|
//IC and Trim are *not* scheduled objects
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
modelLoaded = false;
|
modelLoaded = false;
|
||||||
|
|
||||||
|
@ -255,20 +264,23 @@ bool FGFDMExec::Allocate(void)
|
||||||
|
|
||||||
bool FGFDMExec::DeAllocate(void) {
|
bool FGFDMExec::DeAllocate(void) {
|
||||||
|
|
||||||
if ( Atmosphere != 0 ) delete Atmosphere;
|
delete Atmosphere;
|
||||||
if ( FCS != 0 ) delete FCS;
|
delete FCS;
|
||||||
if ( Propulsion != 0) delete Propulsion;
|
delete Propulsion;
|
||||||
if ( MassBalance != 0) delete MassBalance;
|
delete MassBalance;
|
||||||
if ( Aerodynamics != 0) delete Aerodynamics;
|
delete Aerodynamics;
|
||||||
if ( Inertial != 0) delete Inertial;
|
delete Inertial;
|
||||||
if ( GroundReactions != 0) delete GroundReactions;
|
delete GroundReactions;
|
||||||
if ( Aircraft != 0 ) delete Aircraft;
|
delete Aircraft;
|
||||||
if ( Translation != 0 ) delete Translation;
|
delete Translation;
|
||||||
if ( Rotation != 0 ) delete Rotation;
|
delete Rotation;
|
||||||
if ( Position != 0 ) delete Position;
|
delete Position;
|
||||||
if ( Auxiliary != 0 ) delete Auxiliary;
|
delete Auxiliary;
|
||||||
if ( Output != 0 ) delete Output;
|
delete Output;
|
||||||
if ( State != 0 ) delete State;
|
delete State;
|
||||||
|
|
||||||
|
delete IC;
|
||||||
|
delete Trim;
|
||||||
|
|
||||||
FirstModel = 0L;
|
FirstModel = 0L;
|
||||||
Error = 0;
|
Error = 0;
|
||||||
|
@ -349,10 +361,10 @@ bool FGFDMExec::Run(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGFDMExec::RunIC(FGInitialCondition *fgic)
|
bool FGFDMExec::RunIC(void)
|
||||||
{
|
{
|
||||||
State->Suspend();
|
State->Suspend();
|
||||||
State->Initialize(fgic);
|
State->Initialize(IC);
|
||||||
Run();
|
Run();
|
||||||
State->Resume();
|
State->Resume();
|
||||||
return true;
|
return true;
|
||||||
|
@ -375,15 +387,26 @@ 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;
|
bool result = true;
|
||||||
string token;
|
string token;
|
||||||
string aircraftCfgFileName;
|
string aircraftCfgFileName;
|
||||||
|
|
||||||
AircraftPath = APath;
|
if( AircraftPath.empty() || EnginePath.empty() ) {
|
||||||
EnginePath = EPath;
|
cerr << "Error: attempted to load aircraft with undefined ";
|
||||||
|
cerr << "aircraft and engine paths" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
# ifndef macintosh
|
# ifndef macintosh
|
||||||
aircraftCfgFileName = AircraftPath + "/" + model + "/" + model + ".xml";
|
aircraftCfgFileName = AircraftPath + "/" + model + "/" + model + ".xml";
|
||||||
# else
|
# else
|
||||||
|
@ -392,7 +415,9 @@ bool FGFDMExec::LoadModel(string APath, string EPath, string model)
|
||||||
|
|
||||||
FGConfigFile AC_cfg(aircraftCfgFileName);
|
FGConfigFile AC_cfg(aircraftCfgFileName);
|
||||||
if (!AC_cfg.IsOpen()) return false;
|
if (!AC_cfg.IsOpen()) return false;
|
||||||
|
|
||||||
|
modelName = model;
|
||||||
|
|
||||||
if (modelLoaded) {
|
if (modelLoaded) {
|
||||||
DeAllocate();
|
DeAllocate();
|
||||||
Allocate();
|
Allocate();
|
||||||
|
@ -495,7 +520,10 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
|
||||||
string AircraftName = AC_cfg->GetValue("FILE");
|
string AircraftName = AC_cfg->GetValue("FILE");
|
||||||
|
|
||||||
debug_lvl = 0; // turn off debug output for slave vehicle
|
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
|
debug_lvl = saved_debug_lvl; // turn debug output back on for master vehicle
|
||||||
|
|
||||||
AC_cfg->GetNextConfigLine();
|
AC_cfg->GetNextConfigLine();
|
||||||
|
@ -594,6 +622,14 @@ FGPropertyManager* FGFDMExec::GetPropertyManager(void) {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGTrim* FGFDMExec::GetTrim(void) {
|
||||||
|
delete Trim;
|
||||||
|
Trim = new FGTrim(this,tNone);
|
||||||
|
return Trim;
|
||||||
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// The bitmasked value choices are as follows:
|
// The bitmasked value choices are as follows:
|
||||||
// unset: In this case (the default) JSBSim would only print
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
|
|
@ -41,10 +41,12 @@ INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGModel.h"
|
#include "FGModel.h"
|
||||||
|
#include "FGTrim.h"
|
||||||
#include "FGInitialCondition.h"
|
#include "FGInitialCondition.h"
|
||||||
#include "FGJSBBase.h"
|
#include "FGJSBBase.h"
|
||||||
#include "FGPropertyManager.h"
|
#include "FGPropertyManager.h"
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -56,8 +58,6 @@ DEFINITIONS
|
||||||
FORWARD DECLARATIONS
|
FORWARD DECLARATIONS
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
class FGInitialCondition;
|
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
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 */
|
@return true if successful, false if sim should be ended */
|
||||||
bool Run(void);
|
bool Run(void);
|
||||||
|
|
||||||
/** Initializes the sim with a set of initial conditions.
|
/** Initializes the sim from the initial condition object and executes
|
||||||
@param fgic A pointer to a filled out initial conditions class which
|
each scheduled model without integrating i.e. dt=0.
|
||||||
describes the desired initial conditions.
|
|
||||||
@return true if successful
|
@return true if successful
|
||||||
*/
|
*/
|
||||||
bool RunIC(FGInitialCondition *fgic);
|
bool RunIC(void);
|
||||||
|
|
||||||
/// Freezes the sim
|
/// Freezes the sim
|
||||||
void Freeze(void) {frozen = true;}
|
void Freeze(void) {frozen = true;}
|
||||||
|
|
||||||
/// Resumes the sim
|
/// Resumes the sim
|
||||||
void Resume(void) {frozen = false;}
|
void Resume(void) {frozen = false;}
|
||||||
|
|
||||||
/** Loads an aircraft model.
|
/** Loads an aircraft model.
|
||||||
@param AircraftPath path to the aircraft directory. For instance:
|
@param AircraftPath path to the aircraft directory. For instance:
|
||||||
"aircraft". Under aircraft, then, would be directories for various
|
"aircraft". Under aircraft, then, would be directories for various
|
||||||
modeled aircraft such as C172/, x15/, etc.
|
modeled aircraft such as C172/, x15/, etc.
|
||||||
|
@ -163,10 +162,39 @@ public:
|
||||||
instance: "aircraft/x15/x15.xml"
|
instance: "aircraft/x15/x15.xml"
|
||||||
@return true if successful*/
|
@return true if successful*/
|
||||||
bool LoadModel(string AircraftPath, string EnginePath, string model);
|
bool LoadModel(string AircraftPath, string EnginePath, string model);
|
||||||
|
|
||||||
|
|
||||||
bool SetEnginePath(string path) {EnginePath = path; return true;}
|
/** Loads an aircraft model. The paths to the aircraft and engine
|
||||||
bool SetAircraftPath(string path) {AircraftPath = path; return true;}
|
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
|
/// @name Top-level executive State and Model retrieval mechanism
|
||||||
//@{
|
//@{
|
||||||
/// Returns the FGState pointer.
|
/// Returns the FGState pointer.
|
||||||
|
@ -197,12 +225,20 @@ public:
|
||||||
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
|
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
|
||||||
/// Returns the FGOutput pointer.
|
/// Returns the FGOutput pointer.
|
||||||
inline FGOutput* GetOutput(void) {return Output;}
|
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.
|
/// Retrieves the engine path.
|
||||||
inline string GetEnginePath(void) {return EnginePath;}
|
inline string GetEnginePath(void) {return EnginePath;}
|
||||||
/// Retrieves the aircraft path.
|
/// Retrieves the aircraft path.
|
||||||
inline string GetAircraftPath(void) {return AircraftPath;}
|
inline string GetAircraftPath(void) {return AircraftPath;}
|
||||||
|
/// Retrieves the control path.
|
||||||
|
inline string GetControlPath(void) {return ControlPath;}
|
||||||
|
|
||||||
|
string GetModelName(void) { return modelName; }
|
||||||
|
|
||||||
FGPropertyManager* GetPropertyManager(void);
|
FGPropertyManager* GetPropertyManager(void);
|
||||||
vector <string> EnumerateFDMs(void);
|
vector <string> EnumerateFDMs(void);
|
||||||
|
@ -218,6 +254,7 @@ private:
|
||||||
unsigned int IdFDM;
|
unsigned int IdFDM;
|
||||||
static unsigned int FDMctr;
|
static unsigned int FDMctr;
|
||||||
bool modelLoaded;
|
bool modelLoaded;
|
||||||
|
string modelName;
|
||||||
bool IsSlave;
|
bool IsSlave;
|
||||||
static FGPropertyManager *master;
|
static FGPropertyManager *master;
|
||||||
FGPropertyManager *instance;
|
FGPropertyManager *instance;
|
||||||
|
@ -243,6 +280,8 @@ private:
|
||||||
|
|
||||||
string AircraftPath;
|
string AircraftPath;
|
||||||
string EnginePath;
|
string EnginePath;
|
||||||
|
string ControlPath;
|
||||||
|
|
||||||
string CFGVersion;
|
string CFGVersion;
|
||||||
|
|
||||||
FGState* State;
|
FGState* State;
|
||||||
|
@ -259,6 +298,9 @@ private:
|
||||||
FGPosition* Position;
|
FGPosition* Position;
|
||||||
FGAuxiliary* Auxiliary;
|
FGAuxiliary* Auxiliary;
|
||||||
FGOutput* Output;
|
FGOutput* Output;
|
||||||
|
|
||||||
|
FGInitialCondition* IC;
|
||||||
|
FGTrim *Trim;
|
||||||
|
|
||||||
vector <slaveData*> SlaveFDMList;
|
vector <slaveData*> SlaveFDMList;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ INCLUDES
|
||||||
#include "FGFDMExec.h"
|
#include "FGFDMExec.h"
|
||||||
#include "FGState.h"
|
#include "FGState.h"
|
||||||
#include "FGAtmosphere.h"
|
#include "FGAtmosphere.h"
|
||||||
|
#include "FGAerodynamics.h"
|
||||||
#include "FGFCS.h"
|
#include "FGFCS.h"
|
||||||
#include "FGAircraft.h"
|
#include "FGAircraft.h"
|
||||||
#include "FGTranslation.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 resetDef;
|
||||||
string token="";
|
string token="";
|
||||||
|
|
||||||
double temp;
|
double temp;
|
||||||
|
# ifndef macintosh
|
||||||
# ifndef macintosh
|
string sep = "/";
|
||||||
resetDef = acpath + "/" + acname + "/" + rstfile + ".xml";
|
# else
|
||||||
# else
|
string sep = ";";
|
||||||
resetDef = acpath + ";" + acname + ";" + rstfile + ".xml";
|
#endif
|
||||||
# endif
|
|
||||||
|
if( useStoredPath ) {
|
||||||
|
string acpath = fdmex->GetAircraftPath() + sep + fdmex->GetModelName();
|
||||||
|
resetDef = acpath + sep + rstfile + ".xml";
|
||||||
|
} else {
|
||||||
|
resetDef = rstfile;
|
||||||
|
}
|
||||||
|
|
||||||
FGConfigFile resetfile(resetDef);
|
FGConfigFile resetfile(resetDef);
|
||||||
if (!resetfile.IsOpen()) {
|
if (!resetfile.IsOpen()) {
|
||||||
cerr << "Failed to open reset file: " << resetDef << endl;
|
cerr << "Failed to open reset file: " << resetDef << endl;
|
||||||
|
@ -770,7 +777,7 @@ bool FGInitialCondition::Load(string acpath, string acname, string rstfile)
|
||||||
resetfile >> token;
|
resetfile >> token;
|
||||||
}
|
}
|
||||||
|
|
||||||
fdmex->RunIC(this);
|
fdmex->RunIC();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,7 +252,7 @@ public:
|
||||||
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
|
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
|
||||||
inline windset GetWindSet(void) { return lastWindSet; }
|
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 bind(void);
|
||||||
void unbind(void);
|
void unbind(void);
|
||||||
|
|
|
@ -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';
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -301,6 +301,8 @@ public:
|
||||||
Message* ProcessMessage(void);
|
Message* ProcessMessage(void);
|
||||||
//@}
|
//@}
|
||||||
string GetVersion(void) {return JSBSim_version;}
|
string GetVersion(void) {return JSBSim_version;}
|
||||||
|
|
||||||
|
void disableHighLighting(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static Message localMsg;
|
static Message localMsg;
|
||||||
|
|
|
@ -35,6 +35,7 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <simgear/misc/props.hxx>
|
#include <simgear/misc/props.hxx>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -69,16 +70,22 @@ CLASS DOCUMENTATION
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
class FGPropertyManager:public SGPropertyNode {
|
class FGPropertyManager : public SGPropertyNode {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
FGPropertyManager(void) {
|
FGPropertyManager(void) {}
|
||||||
|
|
||||||
}
|
|
||||||
/// Destructor
|
/// 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.
|
* Get a property node.
|
||||||
*
|
*
|
||||||
|
@ -86,22 +93,11 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param create true to create the node if it doesn't exist.
|
* @param create true to create the node if it doesn't exist.
|
||||||
* @return The node, or 0 if none exists and none was created.
|
* @return The node, or 0 if none exists and none was created.
|
||||||
*/
|
*/
|
||||||
inline FGPropertyManager*
|
FGPropertyManager*
|
||||||
GetNode (const string &path, bool create = false)
|
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*
|
FGPropertyManager*
|
||||||
GetNode (const string &relpath, int index, bool create = false)
|
GetNode (const string &relpath, int index, bool create = false);
|
||||||
{
|
|
||||||
return (FGPropertyManager*)getNode(relpath.c_str(),index,create);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether a given node exists.
|
* Test whether a given node exists.
|
||||||
|
@ -109,19 +105,12 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param path The path of the node, relative to root.
|
* @param path The path of the node, relative to root.
|
||||||
* @return true if the node exists, false otherwise.
|
* @return true if the node exists, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool
|
bool HasNode (const string &path);
|
||||||
HasNode (const string &path)
|
|
||||||
{
|
|
||||||
return (GetNode(path, false) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of a node
|
* Get the name of a node
|
||||||
*/
|
*/
|
||||||
inline string
|
string GetName( void );
|
||||||
GetName( void ) {
|
|
||||||
return string( getName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a bool value for a property.
|
* Get a bool value for a property.
|
||||||
|
@ -137,10 +126,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* does not exist.
|
* does not exist.
|
||||||
* @return The property's value as a bool, or the default value provided.
|
* @return The property's value as a bool, or the default value provided.
|
||||||
*/
|
*/
|
||||||
inline bool GetBool (const string &name, bool defaultValue = false)
|
bool GetBool (const string &name, bool defaultValue = false);
|
||||||
{
|
|
||||||
return getBoolValue(name.c_str(), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,10 +143,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* does not exist.
|
* does not exist.
|
||||||
* @return The property's value as an int, or the default value provided.
|
* @return The property's value as an int, or the default value provided.
|
||||||
*/
|
*/
|
||||||
inline int GetInt (const string &name, int defaultValue = 0)
|
int GetInt (const string &name, int defaultValue = 0);
|
||||||
{
|
|
||||||
return getIntValue(name.c_str(), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,10 +160,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* does not exist.
|
* does not exist.
|
||||||
* @return The property's value as a long, or the default value provided.
|
* @return The property's value as a long, or the default value provided.
|
||||||
*/
|
*/
|
||||||
inline int GetLong (const string &name, long defaultValue = 0L)
|
int GetLong (const string &name, long defaultValue = 0L);
|
||||||
{
|
|
||||||
return getLongValue(name.c_str(), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -197,10 +177,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* does not exist.
|
* does not exist.
|
||||||
* @return The property's value as a float, or the default value provided.
|
* @return The property's value as a float, or the default value provided.
|
||||||
*/
|
*/
|
||||||
inline float GetFloat (const string &name, float defaultValue = 0.0)
|
float GetFloat (const string &name, float defaultValue = 0.0);
|
||||||
{
|
|
||||||
return getFloatValue(name.c_str(), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,10 +194,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* does not exist.
|
* does not exist.
|
||||||
* @return The property's value as a double, or the default value provided.
|
* @return The property's value as a double, or the default value provided.
|
||||||
*/
|
*/
|
||||||
inline double GetDouble (const string &name, double defaultValue = 0.0)
|
double GetDouble (const string &name, double defaultValue = 0.0);
|
||||||
{
|
|
||||||
return getDoubleValue(name.c_str(), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,10 +211,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* does not exist.
|
* does not exist.
|
||||||
* @return The property's value as a string, or the default value provided.
|
* @return The property's value as a string, or the default value provided.
|
||||||
*/
|
*/
|
||||||
inline string GetString (const string &name, string defaultValue = "")
|
string GetString (const string &name, string defaultValue = "");
|
||||||
{
|
|
||||||
return string(getStringValue(name.c_str(), defaultValue.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -256,10 +227,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param val The new value for the property.
|
* @param val The new value for the property.
|
||||||
* @return true if the assignment succeeded, false otherwise.
|
* @return true if the assignment succeeded, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool SetBool (const string &name, bool val)
|
bool SetBool (const string &name, bool val);
|
||||||
{
|
|
||||||
return setBoolValue(name.c_str(), val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,10 +243,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param val The new value for the property.
|
* @param val The new value for the property.
|
||||||
* @return true if the assignment succeeded, false otherwise.
|
* @return true if the assignment succeeded, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool SetInt (const string &name, int val)
|
bool SetInt (const string &name, int val);
|
||||||
{
|
|
||||||
return setIntValue(name.c_str(), val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -294,10 +259,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param val The new value for the property.
|
* @param val The new value for the property.
|
||||||
* @return true if the assignment succeeded, false otherwise.
|
* @return true if the assignment succeeded, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool SetLong (const string &name, long val)
|
bool SetLong (const string &name, long val);
|
||||||
{
|
|
||||||
return setLongValue(name.c_str(), val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -313,10 +275,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param val The new value for the property.
|
* @param val The new value for the property.
|
||||||
* @return true if the assignment succeeded, false otherwise.
|
* @return true if the assignment succeeded, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool SetFloat (const string &name, float val)
|
bool SetFloat (const string &name, float val);
|
||||||
{
|
|
||||||
return setFloatValue(name.c_str(), val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -332,10 +291,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param val The new value for the property.
|
* @param val The new value for the property.
|
||||||
* @return true if the assignment succeeded, false otherwise.
|
* @return true if the assignment succeeded, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool SetDouble (const string &name, double val)
|
bool SetDouble (const string &name, double val);
|
||||||
{
|
|
||||||
return setDoubleValue(name.c_str(), val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -351,10 +307,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param val The new value for the property.
|
* @param val The new value for the property.
|
||||||
* @return true if the assignment succeeded, false otherwise.
|
* @return true if the assignment succeeded, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool SetString (const string &name, const string &val)
|
bool SetString (const string &name, const string &val);
|
||||||
{
|
|
||||||
return setStringValue(name.c_str(), val.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -374,17 +327,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param name The property name.
|
* @param name The property name.
|
||||||
* @param state The state of the archive attribute (defaults to true).
|
* @param state The state of the archive attribute (defaults to true).
|
||||||
*/
|
*/
|
||||||
inline void
|
void SetArchivable (const string &name, bool state = true);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -399,17 +342,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param name The property name.
|
* @param name The property name.
|
||||||
* @param state The state of the read attribute (defaults to true).
|
* @param state The state of the read attribute (defaults to true).
|
||||||
*/
|
*/
|
||||||
inline void
|
void SetReadable (const string &name, bool state = true);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -424,17 +357,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* @param name The property name.
|
* @param name The property name.
|
||||||
* @param state The state of the write attribute (defaults to true).
|
* @param state The state of the write attribute (defaults to true).
|
||||||
*/
|
*/
|
||||||
inline void
|
void SetWritable (const string &name, bool state = true);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -448,12 +371,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* Classes should use this function to release control of any
|
* Classes should use this function to release control of any
|
||||||
* properties they are managing.
|
* properties they are managing.
|
||||||
*/
|
*/
|
||||||
inline void
|
void Untie (const string &name);
|
||||||
Untie (const string &name)
|
|
||||||
{
|
|
||||||
if (!untie(name.c_str()))
|
|
||||||
cout << "Failed to untie property " << name << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Templates cause ambiguity here
|
// Templates cause ambiguity here
|
||||||
|
@ -470,14 +388,8 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* copied to the variable; false if the variable should not
|
* copied to the variable; false if the variable should not
|
||||||
* be modified; defaults to true.
|
* be modified; defaults to true.
|
||||||
*/
|
*/
|
||||||
inline void
|
void
|
||||||
Tie (const string &name, bool *pointer, bool useDefault = true)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -492,14 +404,8 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* copied to the variable; false if the variable should not
|
* copied to the variable; false if the variable should not
|
||||||
* be modified; defaults to true.
|
* be modified; defaults to true.
|
||||||
*/
|
*/
|
||||||
inline void
|
void
|
||||||
Tie (const string &name, int *pointer, bool useDefault = true)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -514,14 +420,8 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* copied to the variable; false if the variable should not
|
* copied to the variable; false if the variable should not
|
||||||
* be modified; defaults to true.
|
* be modified; defaults to true.
|
||||||
*/
|
*/
|
||||||
inline void
|
void
|
||||||
Tie (const string &name, long *pointer, bool useDefault = true)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -536,15 +436,8 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* copied to the variable; false if the variable should not
|
* copied to the variable; false if the variable should not
|
||||||
* be modified; defaults to true.
|
* be modified; defaults to true.
|
||||||
*/
|
*/
|
||||||
inline void
|
void
|
||||||
Tie (const string &name, float *pointer, bool useDefault = true)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tie a property to an external double variable.
|
* 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
|
* copied to the variable; false if the variable should not
|
||||||
* be modified; defaults to true.
|
* be modified; defaults to true.
|
||||||
*/
|
*/
|
||||||
inline void
|
void
|
||||||
Tie (const string &name, double *pointer, bool useDefault = true)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// All of the following functions *must* be inlined, otherwise linker
|
||||||
|
// errors will result
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
/* template <class V> void
|
/* template <class V> void
|
||||||
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
|
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
|
||||||
bool useDefault = true);
|
bool useDefault = true);
|
||||||
|
@ -584,7 +478,7 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
|
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
|
||||||
bool useDefault = true); */
|
bool useDefault = true); */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tie a property to a pair of simple functions.
|
* Tie a property to a pair of simple functions.
|
||||||
*
|
*
|
||||||
* Every time the property value is queried, the getter (if any) will
|
* 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
|
* property value should be; false if the old value should be
|
||||||
* discarded; defaults to true.
|
* discarded; defaults to true.
|
||||||
*/
|
*/
|
||||||
template <class V>
|
|
||||||
inline void
|
template <class V> inline void
|
||||||
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
|
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
|
||||||
bool useDefault = true)
|
bool useDefault = true)
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter),
|
if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter),
|
||||||
useDefault))
|
useDefault))
|
||||||
|
@ -630,9 +524,8 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* property value should be; false if the old value should be
|
* property value should be; false if the old value should be
|
||||||
* discarded; defaults to true.
|
* discarded; defaults to true.
|
||||||
*/
|
*/
|
||||||
template <class V>
|
template <class V> inline void Tie (const string &name,
|
||||||
inline void
|
int index, V (*getter)(int),
|
||||||
Tie (const string &name, int index, V (*getter)(int),
|
|
||||||
void (*setter)(int, V) = 0, bool useDefault = true)
|
void (*setter)(int, V) = 0, bool useDefault = true)
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(),
|
if (!tie(name.c_str(),
|
||||||
|
@ -664,19 +557,17 @@ class FGPropertyManager:public SGPropertyNode {
|
||||||
* property value should be; false if the old value should be
|
* property value should be; false if the old value should be
|
||||||
* discarded; defaults to true.
|
* discarded; defaults to true.
|
||||||
*/
|
*/
|
||||||
template <class T, class V>
|
template <class T, class V> inline void
|
||||||
inline void
|
|
||||||
Tie (const string &name, T * obj, V (T::*getter)() const,
|
Tie (const string &name, T * obj, V (T::*getter)() const,
|
||||||
void (T::*setter)(V) = 0, bool useDefault = true)
|
void (T::*setter)(V) = 0, bool useDefault = true)
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(),
|
if (!tie(name.c_str(),
|
||||||
SGRawValueMethods<T,V>(*obj, getter, setter),
|
SGRawValueMethods<T,V>(*obj, getter, setter),
|
||||||
useDefault))
|
useDefault))
|
||||||
cout <<
|
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.
|
* 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
|
* property value should be; false if the old value should be
|
||||||
* discarded; defaults to true.
|
* discarded; defaults to true.
|
||||||
*/
|
*/
|
||||||
template <class T, class V>
|
template <class T, class V> inline void
|
||||||
inline void
|
|
||||||
Tie (const string &name, T * obj, int index,
|
Tie (const string &name, T * obj, int index,
|
||||||
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
|
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
|
||||||
bool useDefault = true)
|
bool useDefault = true)
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(),
|
if (!tie(name.c_str(),
|
||||||
SGRawValueMethodsIndexed<T,V>(*obj,
|
SGRawValueMethodsIndexed<T,V>(*obj,
|
||||||
index,
|
index,
|
||||||
getter,
|
getter,
|
||||||
setter),
|
setter),
|
||||||
useDefault))
|
useDefault))
|
||||||
cout <<
|
cout <<
|
||||||
"Failed to tie property " << name << " to indexed object methods" << endl;
|
"Failed to tie property " << name << " to indexed object methods" << endl;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FGPROPERTYMANAGER_H
|
#endif // FGPROPERTYMANAGER_H
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ bool FGPropulsion::GetSteadyState(void)
|
||||||
} else {
|
} else {
|
||||||
steady_count=0;
|
steady_count=0;
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||||
vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
|
vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
|
||||||
|
@ -173,7 +173,7 @@ bool FGPropulsion::ICEngineStart(void)
|
||||||
|
|
||||||
vForces.InitMatrix();
|
vForces.InitMatrix();
|
||||||
vMoments.InitMatrix();
|
vMoments.InitMatrix();
|
||||||
|
|
||||||
for (unsigned int i=0; i<numEngines; i++) {
|
for (unsigned int i=0; i<numEngines; i++) {
|
||||||
Engines[i]->SetTrimMode(true);
|
Engines[i]->SetTrimMode(true);
|
||||||
Thrusters[i]->SetdeltaT(dt*rate);
|
Thrusters[i]->SetdeltaT(dt*rate);
|
||||||
|
@ -181,7 +181,7 @@ bool FGPropulsion::ICEngineStart(void)
|
||||||
while (!Engines[i]->GetRunning() && j < 2000) {
|
while (!Engines[i]->GetRunning() && j < 2000) {
|
||||||
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
|
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
|
||||||
Thrusters[i]->Calculate(PowerAvailable);
|
Thrusters[i]->Calculate(PowerAvailable);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||||
vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
|
vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
|
||||||
|
@ -225,6 +225,7 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg)
|
||||||
if (Eng_cfg.IsOpen()) {
|
if (Eng_cfg.IsOpen()) {
|
||||||
Eng_cfg.GetNextConfigLine();
|
Eng_cfg.GetNextConfigLine();
|
||||||
engType = Eng_cfg.GetValue();
|
engType = Eng_cfg.GetValue();
|
||||||
|
cout << engType << endl;
|
||||||
|
|
||||||
FCS->AddThrottle();
|
FCS->AddThrottle();
|
||||||
ThrottleAdded = true;
|
ThrottleAdded = true;
|
||||||
|
@ -308,8 +309,10 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg)
|
||||||
if (thrType == "FG_PROPELLER") {
|
if (thrType == "FG_PROPELLER") {
|
||||||
Thrusters.push_back(new FGPropeller(FDMExec, &Thruster_cfg));
|
Thrusters.push_back(new FGPropeller(FDMExec, &Thruster_cfg));
|
||||||
} else if (thrType == "FG_NOZZLE") {
|
} 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();
|
AC_cfg->GetNextConfigLine();
|
||||||
while ((token = AC_cfg->GetValue()) != string("/AC_THRUSTER")) {
|
while ((token = AC_cfg->GetValue()) != string("/AC_THRUSTER")) {
|
||||||
|
@ -402,7 +405,7 @@ string FGPropulsion::GetPropulsionStrings(void)
|
||||||
default:
|
default:
|
||||||
PropulsionStrings += "INVALID THRUSTER TYPE";
|
PropulsionStrings += "INVALID THRUSTER TYPE";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PropulsionStrings;
|
return PropulsionStrings;
|
||||||
|
|
|
@ -86,7 +86,7 @@ FGScript::~FGScript()
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGScript::LoadScript(string script)
|
bool FGScript::LoadScript( string script )
|
||||||
{
|
{
|
||||||
FGConfigFile Script(script);
|
FGConfigFile Script(script);
|
||||||
string token="";
|
string token="";
|
||||||
|
@ -115,7 +115,7 @@ bool FGScript::LoadScript(string script)
|
||||||
if (token == "use") {
|
if (token == "use") {
|
||||||
if ((token = Script.GetValue("aircraft")) != string("")) {
|
if ((token = Script.GetValue("aircraft")) != string("")) {
|
||||||
aircraft = token;
|
aircraft = token;
|
||||||
result = FDMExec->LoadModel("aircraft", "engine", aircraft);
|
result = FDMExec->LoadModel(aircraft);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
cerr << "Aircraft file " << aircraft << " was not found" << endl;
|
cerr << "Aircraft file " << aircraft << " was not found" << endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
@ -204,8 +204,8 @@ bool FGScript::LoadScript(string script)
|
||||||
Debug(4);
|
Debug(4);
|
||||||
|
|
||||||
|
|
||||||
FGInitialCondition IC(FDMExec);
|
FGInitialCondition *IC=FDMExec->GetIC();
|
||||||
if ( ! IC.Load("aircraft", aircraft, initialize)) {
|
if ( ! IC->Load( initialize )) {
|
||||||
cerr << "Initialization unsuccessful" << endl;
|
cerr << "Initialization unsuccessful" << endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,7 +146,7 @@ public:
|
||||||
The language is the Simple Script Directives for JSBSim (SSDJ).
|
The language is the Simple Script Directives for JSBSim (SSDJ).
|
||||||
@param script the filename (including path name, if any) for the script.
|
@param script the filename (including path name, if any) for the script.
|
||||||
@return true if successful */
|
@return true if successful */
|
||||||
bool LoadScript(string script);
|
bool LoadScript( string script );
|
||||||
|
|
||||||
/** This function is called each pass through the executive Run() method IF
|
/** This function is called each pass through the executive Run() method IF
|
||||||
scripting is enabled.
|
scripting is enabled.
|
||||||
|
|
|
@ -101,71 +101,6 @@ FGState::~FGState()
|
||||||
Debug(1);
|
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 !!
|
// Initialize: Assume all angles GIVEN IN RADIANS !!
|
||||||
|
|
|
@ -64,6 +64,19 @@ INCLUDES
|
||||||
#include "FGColumnVector3.h"
|
#include "FGColumnVector3.h"
|
||||||
#include "FGColumnVector4.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
|
DEFINITIONS
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
@ -74,16 +87,6 @@ DEFINITIONS
|
||||||
FORWARD DECLARATIONS
|
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]
|
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
@ -114,30 +117,7 @@ public:
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~FGState();
|
~FGState();
|
||||||
|
|
||||||
/** Specifies the Reset file to use.
|
/** Initializes the simulation state based on the passed-in parameters.
|
||||||
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 U the body X-Axis velocity in fps.
|
||||||
@param V the body Y-Axis velocity in fps.
|
@param V the body Y-Axis velocity in fps.
|
||||||
@param W the body Z-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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -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()
|
FGThruster::~FGThruster()
|
||||||
{
|
{
|
||||||
Debug(1);
|
Debug(1);
|
||||||
|
|
|
@ -69,12 +69,13 @@ class FGThruster : public FGForce {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
FGThruster(FGFDMExec *FDMExec);
|
FGThruster(FGFDMExec *FDMExec);
|
||||||
|
FGThruster(FGFDMExec *FDMExec, FGConfigFile *Eng_cfg );
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~FGThruster();
|
virtual ~FGThruster();
|
||||||
|
|
||||||
enum eType {ttNozzle, ttRotor, ttPropeller};
|
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 SetName(string name) {Name = name;}
|
||||||
void SetThrusterNumber(int nn) {ThrusterNumber = nn;}
|
void SetThrusterNumber(int nn) {ThrusterNumber = nn;}
|
||||||
virtual void SetRPM(double rpm) {};
|
virtual void SetRPM(double rpm) {};
|
||||||
|
|
|
@ -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;
|
N=Nsub=0;
|
||||||
max_iterations=60;
|
max_iterations=60;
|
||||||
|
@ -73,7 +73,7 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
|
||||||
|
|
||||||
Debug=0;DebugLevel=0;
|
Debug=0;DebugLevel=0;
|
||||||
fdmex=FDMExec;
|
fdmex=FDMExec;
|
||||||
fgic=FGIC;
|
fgic=fdmex->GetIC();
|
||||||
total_its=0;
|
total_its=0;
|
||||||
trimudot=true;
|
trimudot=true;
|
||||||
gamma_fallback=true;
|
gamma_fallback=true;
|
||||||
|
@ -82,56 +82,7 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
|
||||||
xlo=xhi=alo=ahi=0.0;
|
xlo=xhi=alo=ahi=0.0;
|
||||||
targetNlf=1.0;
|
targetNlf=1.0;
|
||||||
debug_axis=tAll;
|
debug_axis=tAll;
|
||||||
switch(mode) {
|
SetMode(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;
|
|
||||||
|
|
||||||
if (debug_lvl & 2) cout << "Instantiated: FGTrim" << endl;
|
if (debug_lvl & 2) cout << "Instantiated: FGTrim" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,6 +539,8 @@ bool FGTrim::checkLimits(void) {
|
||||||
return solutionExists;
|
return solutionExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGTrim::setupPullup() {
|
void FGTrim::setupPullup() {
|
||||||
float g,q,cgamma;
|
float g,q,cgamma;
|
||||||
FGColumnVector3 vPQR;
|
FGColumnVector3 vPQR;
|
||||||
|
@ -601,7 +554,9 @@ void FGTrim::setupPullup() {
|
||||||
cout << "setPitchRateInPullup() complete" << endl;
|
cout << "setPitchRateInPullup() complete" << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGTrim::setupTurn(void){
|
void FGTrim::setupTurn(void){
|
||||||
double g,phi;
|
double g,phi;
|
||||||
phi = fgic->GetRollAngleRadIC();
|
phi = fgic->GetRollAngleRadIC();
|
||||||
|
@ -614,6 +569,8 @@ void FGTrim::setupTurn(void){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGTrim::updateRates(void){
|
void FGTrim::updateRates(void){
|
||||||
if( mode == tTurn ) {
|
if( mode == tTurn ) {
|
||||||
double phi = fgic->GetRollAngleRadIC();
|
double phi = fgic->GetRollAngleRadIC();
|
||||||
|
@ -640,6 +597,8 @@ void FGTrim::updateRates(void){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGTrim::setDebug(void) {
|
void FGTrim::setDebug(void) {
|
||||||
if(debug_axis == tAll ||
|
if(debug_axis == tAll ||
|
||||||
TrimAxes[current_axis]->GetStateType() == debug_axis ) {
|
TrimAxes[current_axis]->GetStateType() == debug_axis ) {
|
||||||
|
@ -650,6 +609,60 @@ void FGTrim::setDebug(void) {
|
||||||
return;
|
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.
|
//YOU WERE WARNED, BUT YOU DID IT ANYWAY.
|
||||||
|
|
||||||
|
|
|
@ -52,16 +52,6 @@ INCLUDES
|
||||||
|
|
||||||
#include "FGFDMExec.h"
|
#include "FGFDMExec.h"
|
||||||
#include "FGJSBBase.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 "FGTrimAxis.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -206,10 +196,8 @@ public:
|
||||||
/** Initializes the trimming class
|
/** Initializes the trimming class
|
||||||
@param FDMExec pointer to a JSBSim executive object.
|
@param FDMExec pointer to a JSBSim executive object.
|
||||||
@param FGIC pointer to a FGInitialCondition 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);
|
~FGTrim(void);
|
||||||
|
|
||||||
|
@ -227,6 +215,12 @@ public:
|
||||||
/** Iteration statistics
|
/** Iteration statistics
|
||||||
*/
|
*/
|
||||||
void TrimStats();
|
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.
|
/** Clear all state-control pairs from the current configuration.
|
||||||
The trimming routine must have at least one state-control pair
|
The trimming routine must have at least one state-control pair
|
||||||
|
|
|
@ -45,6 +45,8 @@ INCLUDES
|
||||||
#include "FGTrimAxis.h"
|
#include "FGTrimAxis.h"
|
||||||
#include "FGAircraft.h"
|
#include "FGAircraft.h"
|
||||||
#include "FGPropulsion.h"
|
#include "FGPropulsion.h"
|
||||||
|
#include "FGAerodynamics.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *IdSrc = "$Id$";
|
static const char *IdSrc = "$Id$";
|
||||||
static const char *IdHdr = ID_TRIMAXIS;
|
static const char *IdHdr = ID_TRIMAXIS;
|
||||||
|
@ -321,7 +323,7 @@ bool FGTrimAxis::initTheta(void) {
|
||||||
while(!level && (i < 100)) {
|
while(!level && (i < 100)) {
|
||||||
theta+=2.0*zDiff;
|
theta+=2.0*zDiff;
|
||||||
fgic->SetPitchAngleDegIC(theta);
|
fgic->SetPitchAngleDegIC(theta);
|
||||||
fdmex->RunIC(fgic);
|
fdmex->RunIC();
|
||||||
zAft=fdmex->GetGroundReactions()->GetGearUnit(1)->GetLocalGear(3);
|
zAft=fdmex->GetGroundReactions()->GetGearUnit(1)->GetLocalGear(3);
|
||||||
zForward=fdmex->GetGroundReactions()->GetGearUnit(0)->GetLocalGear(3);
|
zForward=fdmex->GetGroundReactions()->GetGearUnit(0)->GetLocalGear(3);
|
||||||
zDiff = zForward - zAft;
|
zDiff = zForward - zAft;
|
||||||
|
@ -386,7 +388,7 @@ void FGTrimAxis::Run(void) {
|
||||||
while(!stable) {
|
while(!stable) {
|
||||||
i++;
|
i++;
|
||||||
last_state_value=state_value;
|
last_state_value=state_value;
|
||||||
fdmex->RunIC(fgic);
|
fdmex->RunIC();
|
||||||
getState();
|
getState();
|
||||||
if(i > 1) {
|
if(i > 1) {
|
||||||
if((fabs(last_state_value - state_value) < tolerance) || (i >= 100) )
|
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;
|
//cout << "setThrottlespct: " << i << ", " << control_min << ", " << control_max << ", " << control_value;
|
||||||
fdmex->GetFCS()->SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
|
fdmex->GetFCS()->SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
|
||||||
//cout << "setThrottlespct: " << fdmex->GetFCS()->GetThrottleCmd(i) << endl;
|
//cout << "setThrottlespct: " << fdmex->GetFCS()->GetThrottleCmd(i) << endl;
|
||||||
fdmex->RunIC(fgic); //apply throttle change
|
fdmex->RunIC(); //apply throttle change
|
||||||
fdmex->GetPropulsion()->GetSteadyState();
|
fdmex->GetPropulsion()->GetSteadyState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,15 +42,7 @@ INCLUDES
|
||||||
|
|
||||||
#include "FGFDMExec.h"
|
#include "FGFDMExec.h"
|
||||||
#include "FGJSBBase.h"
|
#include "FGJSBBase.h"
|
||||||
#include "FGRotation.h"
|
#include "FGInitialCondition.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"
|
|
||||||
|
|
||||||
#define ID_TRIMAXIS "$Id$"
|
#define ID_TRIMAXIS "$Id$"
|
||||||
|
|
||||||
|
@ -67,6 +59,8 @@ const string ControlNames[14]= { "Throttle","Sideslip","Angle of Attack",
|
||||||
"Heading"
|
"Heading"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FGInitialCondition;
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
@ -78,7 +72,9 @@ enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL,
|
||||||
class FGTrimAxis : public FGJSBBase
|
class FGTrimAxis : public FGJSBBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGTrimAxis(FGFDMExec* fdmex, FGInitialCondition *ic, State st,
|
FGTrimAxis(FGFDMExec* fdmex,
|
||||||
|
FGInitialCondition *ic,
|
||||||
|
State st,
|
||||||
Control ctrl );
|
Control ctrl );
|
||||||
~FGTrimAxis();
|
~FGTrimAxis();
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,10 @@ HISTORY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "FGTurbine.h"
|
#include "FGTurbine.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *IdSrc = "$Id$";
|
static const char *IdSrc = "$Id$";
|
||||||
static const char *IdHdr = ID_TURBINE;
|
static const char *IdHdr = ID_TURBINE;
|
||||||
|
|
||||||
|
@ -50,6 +52,8 @@ CLASS IMPLEMENTATION
|
||||||
|
|
||||||
FGTurbine::FGTurbine(FGFDMExec* exec, FGConfigFile* cfg) : FGEngine(exec)
|
FGTurbine::FGTurbine(FGFDMExec* exec, FGConfigFile* cfg) : FGEngine(exec)
|
||||||
{
|
{
|
||||||
|
Load(cfg);
|
||||||
|
PowerCommand=0;
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,12 +68,82 @@ FGTurbine::~FGTurbine()
|
||||||
|
|
||||||
double FGTurbine::Calculate(double dummy)
|
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();
|
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)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,10 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "FGEngine.h"
|
#include "FGEngine.h"
|
||||||
#include "FGConfigFile.h"
|
#include "FGConfigFile.h"
|
||||||
|
#include "FGCoefficient.h"
|
||||||
|
|
||||||
#define ID_TURBINE "$Id$"
|
#define ID_TURBINE "$Id$"
|
||||||
|
|
||||||
|
@ -58,8 +60,21 @@ public:
|
||||||
~FGTurbine();
|
~FGTurbine();
|
||||||
|
|
||||||
double Calculate(double);
|
double Calculate(double);
|
||||||
|
|
||||||
private:
|
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 doInlet(void);
|
||||||
void doCompressor(void);
|
void doCompressor(void);
|
||||||
void doBleedDuct(void);
|
void doBleedDuct(void);
|
||||||
|
@ -69,7 +84,7 @@ private:
|
||||||
|
|
||||||
void doTransition(void);
|
void doTransition(void);
|
||||||
|
|
||||||
bool Load(FGConfigFile *AC_cfg);
|
bool Load(FGConfigFile *ENG_cfg);
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,7 +87,7 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
Aerodynamics = fdmex->GetAerodynamics();
|
Aerodynamics = fdmex->GetAerodynamics();
|
||||||
GroundReactions = fdmex->GetGroundReactions();
|
GroundReactions = fdmex->GetGroundReactions();
|
||||||
|
|
||||||
fgic=new FGInitialCondition(fdmex);
|
fgic=fdmex->GetIC();
|
||||||
needTrim=true;
|
needTrim=true;
|
||||||
|
|
||||||
SGPath aircraft_path( globals->get_fg_root() );
|
SGPath aircraft_path( globals->get_fg_root() );
|
||||||
|
@ -231,7 +231,7 @@ void FGJSBsim::init() {
|
||||||
copy_to_JSBsim();
|
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
|
copy_from_JSBsim(); //update the bus
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Initialized JSBSim with:" );
|
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() );
|
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
|
||||||
do_trim();
|
do_trim();
|
||||||
} else {
|
} else {
|
||||||
fdmex->RunIC(fgic); //apply any changes made through the set_ functions
|
fdmex->RunIC(); //apply any changes made through the set_ functions
|
||||||
}
|
}
|
||||||
needTrim = false;
|
needTrim = false;
|
||||||
}
|
}
|
||||||
|
@ -756,9 +756,9 @@ void FGJSBsim::do_trim(void) {
|
||||||
FGTrim *fgtrim;
|
FGTrim *fgtrim;
|
||||||
if( fgGetBool("/sim/startup/onground") ) {
|
if( fgGetBool("/sim/startup/onground") ) {
|
||||||
fgic->SetVcalibratedKtsIC(0.0);
|
fgic->SetVcalibratedKtsIC(0.0);
|
||||||
fgtrim=new FGTrim(fdmex,fgic,tGround);
|
fgtrim=new FGTrim(fdmex,tGround);
|
||||||
} else {
|
} else {
|
||||||
fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
|
fgtrim=new FGTrim(fdmex,tLongitudinal);
|
||||||
}
|
}
|
||||||
if( !fgtrim->DoTrim() ) {
|
if( !fgtrim->DoTrim() ) {
|
||||||
fgtrim->Report();
|
fgtrim->Report();
|
||||||
|
|
|
@ -49,7 +49,7 @@ libJSBSim_a_SOURCES = \
|
||||||
FGTank.cpp FGTank.h \
|
FGTank.cpp FGTank.h \
|
||||||
FGfdmSocket.cpp FGfdmSocket.h \
|
FGfdmSocket.cpp FGfdmSocket.h \
|
||||||
FGTurbine.cpp FGTurbine.h \
|
FGTurbine.cpp FGTurbine.h \
|
||||||
FGPropertyManager.h \
|
FGPropertyManager.cpp FGPropertyManager.h \
|
||||||
JSBSim.cxx JSBSim.hxx
|
JSBSim.cxx JSBSim.hxx
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue