sync. with JSBSim v. 2.0
This commit is contained in:
parent
fcfe5d2010
commit
932b38a87e
134 changed files with 18734 additions and 2844 deletions
|
@ -514,7 +514,13 @@ AC_CONFIG_FILES([ \
|
||||||
src/FDM/ExternalNet/Makefile \
|
src/FDM/ExternalNet/Makefile \
|
||||||
src/FDM/ExternalPipe/Makefile \
|
src/FDM/ExternalPipe/Makefile \
|
||||||
src/FDM/JSBSim/Makefile \
|
src/FDM/JSBSim/Makefile \
|
||||||
src/FDM/JSBSim/filtersjb/Makefile \
|
src/FDM/JSBSim/initialization/Makefile \
|
||||||
|
src/FDM/JSBSim/input_output/Makefile \
|
||||||
|
src/FDM/JSBSim/math/Makefile \
|
||||||
|
src/FDM/JSBSim/models/Makefile \
|
||||||
|
src/FDM/JSBSim/models/flight_control/Makefile \
|
||||||
|
src/FDM/JSBSim/models/atmosphere/Makefile \
|
||||||
|
src/FDM/JSBSim/models/propulsion/Makefile \
|
||||||
src/FDM/LaRCsim/Makefile \
|
src/FDM/LaRCsim/Makefile \
|
||||||
src/FDM/SP/Makefile \
|
src/FDM/SP/Makefile \
|
||||||
src/FDM/UIUCModel/Makefile \
|
src/FDM/UIUCModel/Makefile \
|
||||||
|
|
|
@ -41,10 +41,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
# include <simgear/compiler.h>
|
# include <simgear/compiler.h>
|
||||||
# include STL_IOSTREAM
|
# include STL_IOSTREAM
|
||||||
|
@ -60,21 +56,22 @@ INCLUDES
|
||||||
|
|
||||||
#include "FGFDMExec.h"
|
#include "FGFDMExec.h"
|
||||||
#include "FGState.h"
|
#include "FGState.h"
|
||||||
#include "FGAtmosphere.h"
|
#include <models/FGAtmosphere.h>
|
||||||
#include "FGFCS.h"
|
#include <models/atmosphere/FGMSIS.h>
|
||||||
#include "FGGroundCallback.h"
|
#include <models/atmosphere/FGMars.h>
|
||||||
#include "FGPropulsion.h"
|
#include <models/FGFCS.h>
|
||||||
#include "FGMassBalance.h"
|
#include <models/FGPropulsion.h>
|
||||||
#include "FGGroundReactions.h"
|
#include <models/FGMassBalance.h>
|
||||||
#include "FGAerodynamics.h"
|
#include <models/FGGroundReactions.h>
|
||||||
#include "FGInertial.h"
|
#include <models/FGAerodynamics.h>
|
||||||
#include "FGAircraft.h"
|
#include <models/FGInertial.h>
|
||||||
#include "FGPropagate.h"
|
#include <models/FGAircraft.h>
|
||||||
#include "FGAuxiliary.h"
|
#include <models/FGPropagate.h>
|
||||||
#include "FGOutput.h"
|
#include <models/FGAuxiliary.h>
|
||||||
#include "FGConfigFile.h"
|
#include <models/FGInput.h>
|
||||||
#include "FGInitialCondition.h"
|
#include <models/FGOutput.h>
|
||||||
#include "FGPropertyManager.h"
|
#include <initialization/FGInitialCondition.h>
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -110,12 +107,13 @@ void checkTied ( FGPropertyManager *node )
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// Constructor
|
// Constructor
|
||||||
|
|
||||||
FGFDMExec::FGFDMExec(FGPropertyManager* root)
|
FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
|
||||||
{
|
{
|
||||||
|
|
||||||
Frame = 0;
|
Frame = 0;
|
||||||
FirstModel = 0;
|
FirstModel = 0;
|
||||||
Error = 0;
|
Error = 0;
|
||||||
|
GroundCallback = 0;
|
||||||
State = 0;
|
State = 0;
|
||||||
Atmosphere = 0;
|
Atmosphere = 0;
|
||||||
FCS = 0;
|
FCS = 0;
|
||||||
|
@ -125,22 +123,25 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
|
||||||
Inertial = 0;
|
Inertial = 0;
|
||||||
GroundReactions = 0;
|
GroundReactions = 0;
|
||||||
Aircraft = 0;
|
Aircraft = 0;
|
||||||
GroundCallback = 0;
|
|
||||||
Propagate = 0;
|
Propagate = 0;
|
||||||
Auxiliary = 0;
|
Auxiliary = 0;
|
||||||
Output = 0;
|
Input = 0;
|
||||||
IC = 0;
|
IC = 0;
|
||||||
Trim = 0;
|
Trim = 0;
|
||||||
|
|
||||||
terminate = false;
|
terminate = false;
|
||||||
frozen = false;
|
|
||||||
modelLoaded = false;
|
modelLoaded = false;
|
||||||
IsSlave = false;
|
IsSlave = false;
|
||||||
|
holding = false;
|
||||||
|
|
||||||
|
|
||||||
// Multiple FDM's are stopped for now. We need to ensure that
|
// Multiple FDM's are stopped for now. We need to ensure that
|
||||||
// the "user" instance always gets the zeroeth instance number,
|
// the "user" instance always gets the zeroeth instance number,
|
||||||
// because there may be instruments or scripts tied to properties
|
// because there may be instruments or scripts tied to properties
|
||||||
// in the jsbsim[0] node.
|
// in the jsbsim[0] node.
|
||||||
|
// ToDo: it could be that when JSBSim is reset and a new FDM is wanted, that
|
||||||
|
// process might try setting FDMctr = 0. Then the line below would not need
|
||||||
|
// to be commented out.
|
||||||
IdFDM = FDMctr;
|
IdFDM = FDMctr;
|
||||||
//FDMctr++;
|
//FDMctr++;
|
||||||
|
|
||||||
|
@ -151,31 +152,35 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
|
||||||
debug_lvl = 1;
|
debug_lvl = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root == 0) master= new FGPropertyManager;
|
if (Root == 0) master= new FGPropertyManager;
|
||||||
else master = root;
|
else master = Root;
|
||||||
|
|
||||||
instance = master->GetNode("/fdm/jsbsim",IdFDM,true);
|
instance = master->GetNode("/fdm/jsbsim",IdFDM,true);
|
||||||
|
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
|
// this is to catch errors in binding member functions to the property tree.
|
||||||
// this is here to catch errors in binding member functions
|
|
||||||
// to the property tree.
|
|
||||||
try {
|
try {
|
||||||
Allocate();
|
Allocate();
|
||||||
} catch ( string msg ) {
|
} catch ( string msg ) {
|
||||||
cout << "Caught error: " << msg << endl;
|
cout << "Caught error: " << msg << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constructing = true;
|
||||||
|
typedef int (FGFDMExec::*iPMF)(void) const;
|
||||||
|
instance->Tie("simulation/do_trim", this, (iPMF)0, &FGFDMExec::DoTrim);
|
||||||
|
Constructing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGFDMExec::~FGFDMExec()
|
FGFDMExec::~FGFDMExec()
|
||||||
{
|
{
|
||||||
|
instance->Untie("simulation/do_trim");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DeAllocate();
|
DeAllocate();
|
||||||
checkTied( instance );
|
checkTied( instance );
|
||||||
|
if (Root == 0) delete master;
|
||||||
} catch ( string msg ) {
|
} catch ( string msg ) {
|
||||||
cout << "Caught error: " << msg << endl;
|
cout << "Caught error: " << msg << endl;
|
||||||
}
|
}
|
||||||
|
@ -200,14 +205,14 @@ bool FGFDMExec::Allocate(void)
|
||||||
Inertial = new FGInertial(this);
|
Inertial = new FGInertial(this);
|
||||||
GroundReactions = new FGGroundReactions(this);
|
GroundReactions = new FGGroundReactions(this);
|
||||||
Aircraft = new FGAircraft(this);
|
Aircraft = new FGAircraft(this);
|
||||||
GroundCallback = new FGGroundCallback();
|
|
||||||
Propagate = new FGPropagate(this);
|
Propagate = new FGPropagate(this);
|
||||||
Auxiliary = new FGAuxiliary(this);
|
Auxiliary = new FGAuxiliary(this);
|
||||||
Output = new FGOutput(this);
|
Input = new FGInput(this);
|
||||||
|
|
||||||
State = new FGState(this); // This must be done here, as the FGState
|
GroundCallback = new FGGroundCallback();
|
||||||
// class needs valid pointers to the above
|
State = new FGState(this); // This must be done here, as the FGState
|
||||||
// model classes
|
// class needs valid pointers to the above
|
||||||
|
// model classes
|
||||||
|
|
||||||
// Initialize models so they can communicate with each other
|
// Initialize models so they can communicate with each other
|
||||||
|
|
||||||
|
@ -237,23 +242,23 @@ bool FGFDMExec::Allocate(void)
|
||||||
Error+=128;}
|
Error+=128;}
|
||||||
if (!Propagate->InitModel()) {
|
if (!Propagate->InitModel()) {
|
||||||
cerr << fgred << "Propagate model init failed" << fgdef << endl;
|
cerr << fgred << "Propagate model init failed" << fgdef << endl;
|
||||||
Error+=512;}
|
Error+=256;}
|
||||||
if (!Auxiliary->InitModel()) {
|
if (!Auxiliary->InitModel()) {
|
||||||
cerr << fgred << "Auxiliary model init failed" << fgdef << endl;
|
cerr << fgred << "Auxiliary model init failed" << fgdef << endl;
|
||||||
Error+=2058;}
|
Error+=512;}
|
||||||
if (!Output->InitModel()) {
|
if (!Input->InitModel()) {
|
||||||
cerr << fgred << "Output model init failed" << fgdef << endl;
|
cerr << fgred << "Input model init failed" << fgdef << endl;
|
||||||
Error+=4096;}
|
Error+=1024;}
|
||||||
|
|
||||||
if (Error > 0) result = false;
|
if (Error > 0) result = false;
|
||||||
|
|
||||||
IC = new FGInitialCondition(this);
|
IC = new FGInitialCondition(this);
|
||||||
|
|
||||||
// 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 could get executed every fifth pass it is called
|
||||||
// by the executive. Everything else here gets executed each pass.
|
// by the executive. IC and Trim objects are NOT scheduled.
|
||||||
// IC and Trim objects are NOT scheduled.
|
|
||||||
|
|
||||||
|
Schedule(Input, 1);
|
||||||
Schedule(Atmosphere, 1);
|
Schedule(Atmosphere, 1);
|
||||||
Schedule(FCS, 1);
|
Schedule(FCS, 1);
|
||||||
Schedule(Propulsion, 1);
|
Schedule(Propulsion, 1);
|
||||||
|
@ -264,7 +269,6 @@ bool FGFDMExec::Allocate(void)
|
||||||
Schedule(Aircraft, 1);
|
Schedule(Aircraft, 1);
|
||||||
Schedule(Propagate, 1);
|
Schedule(Propagate, 1);
|
||||||
Schedule(Auxiliary, 1);
|
Schedule(Auxiliary, 1);
|
||||||
Schedule(Output, 1);
|
|
||||||
|
|
||||||
modelLoaded = false;
|
modelLoaded = false;
|
||||||
|
|
||||||
|
@ -275,6 +279,7 @@ bool FGFDMExec::Allocate(void)
|
||||||
|
|
||||||
bool FGFDMExec::DeAllocate(void)
|
bool FGFDMExec::DeAllocate(void)
|
||||||
{
|
{
|
||||||
|
delete Input;
|
||||||
delete Atmosphere;
|
delete Atmosphere;
|
||||||
delete FCS;
|
delete FCS;
|
||||||
delete Propulsion;
|
delete Propulsion;
|
||||||
|
@ -285,9 +290,14 @@ bool FGFDMExec::DeAllocate(void)
|
||||||
delete Aircraft;
|
delete Aircraft;
|
||||||
delete Propagate;
|
delete Propagate;
|
||||||
delete Auxiliary;
|
delete Auxiliary;
|
||||||
delete Output;
|
|
||||||
delete State;
|
delete State;
|
||||||
|
|
||||||
|
for (int i=0; i<Outputs.size(); i++) {
|
||||||
|
if (Outputs[i]) delete Outputs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
Outputs.clear();
|
||||||
|
|
||||||
delete IC;
|
delete IC;
|
||||||
delete Trim;
|
delete Trim;
|
||||||
|
|
||||||
|
@ -297,6 +307,7 @@ bool FGFDMExec::DeAllocate(void)
|
||||||
Error = 0;
|
Error = 0;
|
||||||
|
|
||||||
State = 0;
|
State = 0;
|
||||||
|
Input = 0;
|
||||||
Atmosphere = 0;
|
Atmosphere = 0;
|
||||||
FCS = 0;
|
FCS = 0;
|
||||||
Propulsion = 0;
|
Propulsion = 0;
|
||||||
|
@ -307,7 +318,6 @@ bool FGFDMExec::DeAllocate(void)
|
||||||
Aircraft = 0;
|
Aircraft = 0;
|
||||||
Propagate = 0;
|
Propagate = 0;
|
||||||
Auxiliary = 0;
|
Auxiliary = 0;
|
||||||
Output = 0;
|
|
||||||
|
|
||||||
modelLoaded = false;
|
modelLoaded = false;
|
||||||
return modelLoaded;
|
return modelLoaded;
|
||||||
|
@ -346,8 +356,6 @@ bool FGFDMExec::Run(void)
|
||||||
{
|
{
|
||||||
FGModel* model_iterator;
|
FGModel* model_iterator;
|
||||||
|
|
||||||
if (frozen) return true;
|
|
||||||
|
|
||||||
model_iterator = FirstModel;
|
model_iterator = FirstModel;
|
||||||
if (model_iterator == 0L) return false;
|
if (model_iterator == 0L) return false;
|
||||||
|
|
||||||
|
@ -364,27 +372,29 @@ bool FGFDMExec::Run(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = Frame++;
|
frame = Frame++;
|
||||||
State->IncrTime();
|
if (!Holding()) State->IncrTime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// This call will cause the sim time to reset to 0.0
|
||||||
|
|
||||||
bool FGFDMExec::RunIC(void)
|
bool FGFDMExec::RunIC(void)
|
||||||
{
|
{
|
||||||
State->Suspend();
|
State->SuspendIntegration();
|
||||||
State->Initialize(IC);
|
State->Initialize(IC);
|
||||||
Run();
|
Run();
|
||||||
State->Resume();
|
State->ResumeIntegration();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGFDMExec::SetGroundCallback(FGGroundCallback* p) {
|
void FGFDMExec::SetGroundCallback(FGGroundCallback* p)
|
||||||
if (GroundCallback)
|
{
|
||||||
delete GroundCallback;
|
if (GroundCallback) delete GroundCallback;
|
||||||
|
|
||||||
GroundCallback = p;
|
GroundCallback = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +418,6 @@ vector <string> FGFDMExec::EnumerateFDMs(void)
|
||||||
bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model,
|
bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model,
|
||||||
bool addModelToPath)
|
bool addModelToPath)
|
||||||
{
|
{
|
||||||
|
|
||||||
FGFDMExec::AircraftPath = AircraftPath;
|
FGFDMExec::AircraftPath = AircraftPath;
|
||||||
FGFDMExec::EnginePath = EnginePath;
|
FGFDMExec::EnginePath = EnginePath;
|
||||||
|
|
||||||
|
@ -417,13 +426,15 @@ bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model,
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool result = true;
|
|
||||||
string token;
|
string token;
|
||||||
string aircraftCfgFileName;
|
string aircraftCfgFileName;
|
||||||
|
string separator = "/";
|
||||||
|
|
||||||
|
# ifdef macintosh
|
||||||
|
separator = ";";
|
||||||
|
# endif
|
||||||
|
|
||||||
if( AircraftPath.empty() || EnginePath.empty() ) {
|
if( AircraftPath.empty() || EnginePath.empty() ) {
|
||||||
cerr << "Error: attempted to load aircraft with undefined ";
|
cerr << "Error: attempted to load aircraft with undefined ";
|
||||||
|
@ -432,16 +443,16 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
aircraftCfgFileName = AircraftPath;
|
aircraftCfgFileName = AircraftPath;
|
||||||
# ifndef macintosh
|
if (addModelToPath) aircraftCfgFileName += separator + model;
|
||||||
if (addModelToPath) aircraftCfgFileName += "/" + model;
|
aircraftCfgFileName += separator + model + ".xml";
|
||||||
aircraftCfgFileName += "/" + model + ".xml";
|
|
||||||
# else
|
|
||||||
if (addModelToPath) aircraftCfgFileName += ";" + model;
|
|
||||||
aircraftCfgFileName += ";" + model + ".xml";
|
|
||||||
# endif
|
|
||||||
|
|
||||||
FGConfigFile AC_cfg(aircraftCfgFileName);
|
FGXMLParse *XMLParse = new FGXMLParse();
|
||||||
if (!AC_cfg.IsOpen()) return false;
|
Element* element = 0L;
|
||||||
|
Element* document;
|
||||||
|
|
||||||
|
ifstream input_file(aircraftCfgFileName.c_str());
|
||||||
|
readXML(input_file, *XMLParse);
|
||||||
|
document = XMLParse->GetDocument();
|
||||||
|
|
||||||
modelName = model;
|
modelName = model;
|
||||||
|
|
||||||
|
@ -450,36 +461,35 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
||||||
Allocate();
|
Allocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ReadPrologue(&AC_cfg)) return false;
|
ReadPrologue(document);
|
||||||
|
element = document->GetElement();
|
||||||
|
|
||||||
while ((AC_cfg.GetNextConfigLine() != string("EOF")) &&
|
bool result = true;
|
||||||
(token = AC_cfg.GetValue()) != string("/FDM_CONFIG")) {
|
while (element && result) {
|
||||||
if (token == "METRICS") {
|
string element_name = element->GetName();
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Metrics" << fgdef << endl;
|
if (element_name == "fileheader" ) result = ReadFileHeader(element);
|
||||||
if (!ReadMetrics(&AC_cfg)) result = false;
|
else if (element_name == "slave") result = ReadSlave(element);
|
||||||
} else if (token == "SLAVE") {
|
else if (element_name == "metrics") result = Aircraft->Load(element);
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Slave flight vehicle: " << fgdef
|
else if (element_name == "mass_balance") result = MassBalance->Load(element);
|
||||||
<< AC_cfg.GetValue("NAME") << endl;
|
else if (element_name == "ground_reactions") result = GroundReactions->Load(element);
|
||||||
if (!ReadSlave(&AC_cfg)) result = false;
|
else if (element_name == "propulsion") result = Propulsion->Load(element);
|
||||||
} else if (token == "AERODYNAMICS") {
|
else if (element_name == "autopilot") result = FCS->Load(element);
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Aerodynamics" << fgdef << endl;
|
else if (element_name == "flight_control") result = FCS->Load(element);
|
||||||
if (!ReadAerodynamics(&AC_cfg)) result = false;
|
else if (element_name == "aerodynamics") result = Aerodynamics->Load(element);
|
||||||
} else if (token == "UNDERCARRIAGE") {
|
else if (element_name == "input") result = Input->Load(element);
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Landing Gear" << fgdef << endl;
|
else if (element_name == "output") {
|
||||||
if (!ReadUndercarriage(&AC_cfg)) result = false;
|
FGOutput* Output = new FGOutput(this);
|
||||||
} else if (token == "PROPULSION") {
|
Output->InitModel();
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Propulsion" << fgdef << endl;
|
Schedule(Output, 1);
|
||||||
if (!ReadPropulsion(&AC_cfg)) result = false;
|
Outputs.push_back(Output);
|
||||||
} else if (token == "FLIGHT_CONTROL") {
|
result = Output->Load(element);
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Flight Control" << fgdef << endl;
|
|
||||||
if (!ReadFlightControls(&AC_cfg)) result = false;
|
|
||||||
} else if (token == "AUTOPILOT") {
|
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Autopilot" << fgdef << endl;
|
|
||||||
if (!ReadFlightControls(&AC_cfg)) result = false;
|
|
||||||
} else if (token == "OUTPUT") {
|
|
||||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Output directives" << fgdef << endl;
|
|
||||||
if (!ReadOutput(&AC_cfg)) result = false;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
cerr << "Found unexpected subsystem: " << element_name << ", exiting." << endl;
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
element = document->GetNextElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
@ -487,32 +497,93 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
||||||
Debug(3);
|
Debug(3);
|
||||||
} else {
|
} else {
|
||||||
cerr << fgred
|
cerr << fgred
|
||||||
<< " FGFDMExec: Failed to load aircraft and/or engine model"
|
<< " JSBSim failed to load aircraft and/or engine model"
|
||||||
<< fgdef << endl;
|
<< fgdef << endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PropertyCatalogStructure masterPCS;
|
||||||
|
masterPCS.base_string = "";
|
||||||
|
masterPCS.node = (FGPropertyManager*)master;
|
||||||
|
|
||||||
|
BuildPropertyCatalog(&masterPCS);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
|
void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
|
||||||
{
|
{
|
||||||
string token = AC_cfg->GetValue();
|
struct PropertyCatalogStructure* pcsNew = new struct PropertyCatalogStructure;
|
||||||
string scratch;
|
int node_idx = 0;
|
||||||
string AircraftName;
|
char int_buf[10];
|
||||||
|
|
||||||
AircraftName = AC_cfg->GetValue("NAME");
|
for (int i=0; i<pcs->node->nChildren(); i++) {
|
||||||
|
pcsNew->base_string = pcs->base_string + "/" + pcs->node->getChild(i)->getName();
|
||||||
|
node_idx = pcs->node->getChild(i)->getIndex();
|
||||||
|
sprintf(int_buf, "[%d]", node_idx);
|
||||||
|
if (node_idx != 0) pcsNew->base_string += string(int_buf);
|
||||||
|
if (pcs->node->getChild(i)->nChildren() == 0) {
|
||||||
|
PropertyCatalog.push_back(pcsNew->base_string);
|
||||||
|
} else {
|
||||||
|
pcsNew->node = (FGPropertyManager*)pcs->node->getChild(i);
|
||||||
|
BuildPropertyCatalog(pcsNew);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete pcsNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGFDMExec::QueryPropertyCatalog(string in)
|
||||||
|
{
|
||||||
|
string results="";
|
||||||
|
for (int i=0; i<PropertyCatalog.size(); i++) {
|
||||||
|
if (PropertyCatalog[i].find(in) != string::npos) results += PropertyCatalog[i] + "\n";
|
||||||
|
}
|
||||||
|
if (results.empty()) return "No matches found\n";
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGFDMExec::ReadFileHeader(Element* el)
|
||||||
|
{
|
||||||
|
bool result = true; // true for success
|
||||||
|
|
||||||
|
if (debug_lvl & ~1) return result;
|
||||||
|
|
||||||
|
if (el->FindElement("author"))
|
||||||
|
cout << " Model Author: " << el->FindElement("author")->GetDataLine() << endl;
|
||||||
|
if (el->FindElement("filecreationdate"))
|
||||||
|
cout << " Creation Date: " << el->FindElement("filecreationdate")->GetDataLine() << endl;
|
||||||
|
if (el->FindElement("version"))
|
||||||
|
cout << " Version: " << el->FindElement("version")->GetDataLine() << endl;
|
||||||
|
if (el->FindElement("description"))
|
||||||
|
cout << " Description: " << el->FindElement("description")->GetDataLine() << endl;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGFDMExec::ReadPrologue(Element* el) // el for ReadPrologue is the document element
|
||||||
|
{
|
||||||
|
bool result = true; // true for success
|
||||||
|
|
||||||
|
if (!el) return false;
|
||||||
|
|
||||||
|
string AircraftName = el->GetAttributeValue("name");
|
||||||
Aircraft->SetAircraftName(AircraftName);
|
Aircraft->SetAircraftName(AircraftName);
|
||||||
|
|
||||||
if (debug_lvl > 0) cout << underon << "Reading Aircraft Configuration File"
|
if (debug_lvl & 1) cout << underon << "Reading Aircraft Configuration File"
|
||||||
<< underoff << ": " << highint << AircraftName << normint << endl;
|
<< underoff << ": " << highint << AircraftName << normint << endl;
|
||||||
scratch = AC_cfg->GetValue("VERSION").c_str();
|
|
||||||
|
|
||||||
CFGVersion = AC_cfg->GetValue("VERSION");
|
CFGVersion = el->GetAttributeValue("version");
|
||||||
Release = AC_cfg->GetValue("RELEASE");
|
Release = el->GetAttributeValue("release");
|
||||||
|
|
||||||
if (debug_lvl > 0)
|
if (debug_lvl & 1)
|
||||||
cout << " Version: " << highint << CFGVersion
|
cout << " Version: " << highint << CFGVersion
|
||||||
<< normint << endl;
|
<< normint << endl;
|
||||||
if (CFGVersion != needed_cfg_version) {
|
if (CFGVersion != needed_cfg_version) {
|
||||||
|
@ -523,10 +594,7 @@ bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Release == "ALPHA" && debug_lvl > 0) {
|
if (Release == "ALPHA" && (debug_lvl & 1)) {
|
||||||
#ifndef _MSC_VER
|
|
||||||
system("banner ALPHA");
|
|
||||||
#endif
|
|
||||||
cout << endl << endl
|
cout << endl << endl
|
||||||
<< highint << "This aircraft model is an " << fgred << Release
|
<< highint << "This aircraft model is an " << fgred << Release
|
||||||
<< reset << highint << " release!!!" << endl << endl << reset
|
<< reset << highint << " release!!!" << endl << endl << reset
|
||||||
|
@ -534,24 +602,33 @@ bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
|
||||||
<< " will not fly as expected." << endl << endl
|
<< " will not fly as expected." << endl << endl
|
||||||
<< fgred << highint << "Use this model for development purposes ONLY!!!"
|
<< fgred << highint << "Use this model for development purposes ONLY!!!"
|
||||||
<< normint << reset << endl << endl;
|
<< normint << reset << endl << endl;
|
||||||
} else if (Release == "BETA" && debug_lvl > 0) {
|
} else if (Release == "BETA" && (debug_lvl & 1)) {
|
||||||
#ifndef _MSC_VER
|
|
||||||
system("banner BETA");
|
|
||||||
#endif
|
|
||||||
cout << endl << endl
|
cout << endl << endl
|
||||||
<< highint << "This aircraft model is a " << fgred << Release
|
<< highint << "This aircraft model is a " << fgred << Release
|
||||||
<< reset << highint << " release!!!" << endl << endl << reset
|
<< reset << highint << " release!!!" << endl << endl << reset
|
||||||
<< "This aircraft model probably will not fly as expected." << endl << endl
|
<< "This aircraft model probably will not fly as expected." << endl << endl
|
||||||
<< fgblue << highint << "Use this model for development purposes ONLY!!!"
|
<< fgblue << highint << "Use this model for development purposes ONLY!!!"
|
||||||
<< normint << reset << endl << endl;
|
<< normint << reset << endl << endl;
|
||||||
|
} else if (Release == "PRODUCTION" && (debug_lvl & 1)) {
|
||||||
|
cout << endl << endl
|
||||||
|
<< highint << "This aircraft model is a " << fgblue << Release
|
||||||
|
<< reset << highint << " release." << endl << endl << reset;
|
||||||
|
} else if (debug_lvl & 1) {
|
||||||
|
cout << endl << endl
|
||||||
|
<< highint << "This aircraft model is an " << fgred << Release
|
||||||
|
<< reset << highint << " release!!!" << endl << endl << reset
|
||||||
|
<< "This aircraft model may not even properly load, and probably"
|
||||||
|
<< " will not fly as expected." << endl << endl
|
||||||
|
<< fgred << highint << "Use this model for development purposes ONLY!!!"
|
||||||
|
<< normint << reset << endl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
|
bool FGFDMExec::ReadSlave(Element* el)
|
||||||
{
|
{
|
||||||
// Add a new slaveData object to the slave FDM list
|
// Add a new slaveData object to the slave FDM list
|
||||||
// Populate that slaveData element with a new FDMExec object
|
// Populate that slaveData element with a new FDMExec object
|
||||||
|
@ -567,8 +644,8 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
|
||||||
SlaveFDMList.push_back(new slaveData);
|
SlaveFDMList.push_back(new slaveData);
|
||||||
SlaveFDMList.back()->exec = new FGFDMExec();
|
SlaveFDMList.back()->exec = new FGFDMExec();
|
||||||
SlaveFDMList.back()->exec->SetSlave();
|
SlaveFDMList.back()->exec->SetSlave();
|
||||||
|
/*
|
||||||
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
|
||||||
|
|
||||||
|
@ -580,15 +657,15 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
|
||||||
AC_cfg->GetNextConfigLine();
|
AC_cfg->GetNextConfigLine();
|
||||||
while ((token = AC_cfg->GetValue()) != string("/SLAVE")) {
|
while ((token = AC_cfg->GetValue()) != string("/SLAVE")) {
|
||||||
*AC_cfg >> token;
|
*AC_cfg >> token;
|
||||||
if (token == "XLOC") { *AC_cfg >> SlaveFDMList.back()->x; }
|
if (token == "xloc") { *AC_cfg >> SlaveFDMList.back()->x; }
|
||||||
else if (token == "YLOC") { *AC_cfg >> SlaveFDMList.back()->y; }
|
else if (token == "yloc") { *AC_cfg >> SlaveFDMList.back()->y; }
|
||||||
else if (token == "ZLOC") { *AC_cfg >> SlaveFDMList.back()->z; }
|
else if (token == "zloc") { *AC_cfg >> SlaveFDMList.back()->z; }
|
||||||
else if (token == "PITCH") { *AC_cfg >> SlaveFDMList.back()->pitch;}
|
else if (token == "pitch") { *AC_cfg >> SlaveFDMList.back()->pitch;}
|
||||||
else if (token == "YAW") { *AC_cfg >> SlaveFDMList.back()->yaw; }
|
else if (token == "yaw") { *AC_cfg >> SlaveFDMList.back()->yaw; }
|
||||||
else if (token == "ROLL") { *AC_cfg >> SlaveFDMList.back()->roll; }
|
else if (token == "roll") { *AC_cfg >> SlaveFDMList.back()->roll; }
|
||||||
else cerr << "Unknown identifier: " << token << " in slave vehicle definition" << endl;
|
else cerr << "Unknown identifier: " << token << " in slave vehicle definition" << endl;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (debug_lvl > 0) {
|
if (debug_lvl > 0) {
|
||||||
cout << " X = " << SlaveFDMList.back()->x << endl;
|
cout << " X = " << SlaveFDMList.back()->x << endl;
|
||||||
cout << " Y = " << SlaveFDMList.back()->y << endl;
|
cout << " Y = " << SlaveFDMList.back()->y << endl;
|
||||||
|
@ -603,84 +680,87 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGFDMExec::ReadPropulsion(FGConfigFile* AC_cfg)
|
FGPropertyManager* FGFDMExec::GetPropertyManager(void)
|
||||||
{
|
{
|
||||||
if (!Propulsion->Load(AC_cfg)) {
|
|
||||||
cerr << " Propulsion not successfully loaded" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
bool FGFDMExec::ReadFlightControls(FGConfigFile* AC_cfg)
|
|
||||||
{
|
|
||||||
if (!FCS->Load(AC_cfg)) {
|
|
||||||
cerr << " Flight Controls not successfully loaded" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
bool FGFDMExec::ReadAerodynamics(FGConfigFile* AC_cfg)
|
|
||||||
{
|
|
||||||
if (!Aerodynamics->Load(AC_cfg)) {
|
|
||||||
cerr << " Aerodynamics not successfully loaded" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
bool FGFDMExec::ReadUndercarriage(FGConfigFile* AC_cfg)
|
|
||||||
{
|
|
||||||
if (!GroundReactions->Load(AC_cfg)) {
|
|
||||||
cerr << " Ground Reactions not successfully loaded" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
bool FGFDMExec::ReadMetrics(FGConfigFile* AC_cfg)
|
|
||||||
{
|
|
||||||
if (!Aircraft->Load(AC_cfg)) {
|
|
||||||
cerr << " Aircraft metrics not successfully loaded" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
bool FGFDMExec::ReadOutput(FGConfigFile* AC_cfg)
|
|
||||||
{
|
|
||||||
if (!Output->Load(AC_cfg)) {
|
|
||||||
cerr << " Output not successfully loaded" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
FGPropertyManager* FGFDMExec::GetPropertyManager(void) {
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGTrim* FGFDMExec::GetTrim(void) {
|
FGTrim* FGFDMExec::GetTrim(void)
|
||||||
|
{
|
||||||
delete Trim;
|
delete Trim;
|
||||||
Trim = new FGTrim(this,tNone);
|
Trim = new FGTrim(this,tNone);
|
||||||
return Trim;
|
return Trim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFDMExec::DisableOutput(void)
|
||||||
|
{
|
||||||
|
for (int i=0; i<Outputs.size(); i++) {
|
||||||
|
Outputs[i]->Disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFDMExec::EnableOutput(void)
|
||||||
|
{
|
||||||
|
for (int i=0; i<Outputs.size(); i++) {
|
||||||
|
Outputs[i]->Enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFDMExec::DoTrim(int mode)
|
||||||
|
{
|
||||||
|
double saved_time;
|
||||||
|
|
||||||
|
cout << "DoTrim called" << endl;
|
||||||
|
|
||||||
|
if (Constructing) return;
|
||||||
|
|
||||||
|
if (mode < 0 || mode > JSBSim::tNone) {
|
||||||
|
cerr << endl << "Illegal trimming mode!" << endl << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
saved_time = State->Getsim_time();
|
||||||
|
FGTrim trim(this, (JSBSim::TrimMode)mode);
|
||||||
|
if ( !trim.DoTrim() ) cerr << endl << "Trim Failed" << endl << endl;
|
||||||
|
trim.Report();
|
||||||
|
State->Setsim_time(saved_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFDMExec::UseAtmosphereMSIS(void)
|
||||||
|
{
|
||||||
|
FGAtmosphere *oldAtmosphere = Atmosphere;
|
||||||
|
Atmosphere = new MSIS(this);
|
||||||
|
if (!Atmosphere->InitModel()) {
|
||||||
|
cerr << fgred << "MSIS Atmosphere model init failed" << fgdef << endl;
|
||||||
|
Error+=1;
|
||||||
|
}
|
||||||
|
delete oldAtmosphere;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFDMExec::UseAtmosphereMars(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
FGAtmosphere *oldAtmosphere = Atmosphere;
|
||||||
|
Atmosphere = new FGMars(this);
|
||||||
|
if (!Atmosphere->InitModel()) {
|
||||||
|
cerr << fgred << "Mars Atmosphere model init failed" << fgdef << endl;
|
||||||
|
Error+=1;
|
||||||
|
}
|
||||||
|
delete oldAtmosphere;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// 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
|
||||||
|
@ -721,7 +801,7 @@ void FGFDMExec::Debug(int from)
|
||||||
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
if (from == 2) {
|
if (from == 2) {
|
||||||
cout << "================== Frame: " << Frame << " Time: "
|
cout << "================== Frame: " << Frame << " Time: "
|
||||||
<< State->Getsim_time() << endl;
|
<< State->Getsim_time() << " dt: " << State->Getdt() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debug_lvl & 8 ) { // Runtime state variables
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
@ -737,3 +817,4 @@ void FGFDMExec::Debug(int from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,13 +40,16 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGModel.h"
|
#include <models/FGModel.h>
|
||||||
#include "FGTrim.h"
|
#include <models/FGOutput.h>
|
||||||
#include "FGInitialCondition.h"
|
#include <models/FGInput.h>
|
||||||
#include "FGJSBBase.h"
|
#include <initialization/FGTrim.h>
|
||||||
#include "FGGroundCallback.h"
|
#include <initialization/FGInitialCondition.h>
|
||||||
#include "FGPropertyManager.h"
|
#include <FGJSBBase.h>
|
||||||
#include "FGPropagate.h"
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
#include <input_output/FGXMLParse.h>
|
||||||
|
#include <input_output/FGGroundCallback.h>
|
||||||
|
#include <models/FGPropagate.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -74,8 +77,7 @@ CLASS DOCUMENTATION
|
||||||
|
|
||||||
When an aircraft model is loaded the config file is parsed and for each of the
|
When an aircraft model is loaded the config file is parsed and for each of the
|
||||||
sections of the config file (propulsion, flight control, etc.) the
|
sections of the config file (propulsion, flight control, etc.) the
|
||||||
corresponding "ReadXXX()" method is called. From within this method the
|
corresponding Load() method is called (e.g. LoadFCS).
|
||||||
"Load()" method of that system is called (e.g. LoadFCS).
|
|
||||||
|
|
||||||
<h4>JSBSim Debugging Directives</h4>
|
<h4>JSBSim Debugging Directives</h4>
|
||||||
|
|
||||||
|
@ -134,17 +136,12 @@ public:
|
||||||
|
|
||||||
/** Initializes the sim from the initial condition object and executes
|
/** Initializes the sim from the initial condition object and executes
|
||||||
each scheduled model without integrating i.e. dt=0.
|
each scheduled model without integrating i.e. dt=0.
|
||||||
@return true if successful
|
@return true if successful */
|
||||||
*/
|
|
||||||
bool RunIC(void);
|
bool RunIC(void);
|
||||||
|
|
||||||
/// Freezes the sim
|
/** Sets the ground callback pointer.
|
||||||
void Freeze(void) {frozen = true;}
|
@param gc A pointer to a ground callback object. */
|
||||||
|
void SetGroundCallback(FGGroundCallback* gc);
|
||||||
/// Resumes the sim
|
|
||||||
void Resume(void) {frozen = false;}
|
|
||||||
|
|
||||||
void SetGroundCallback(FGGroundCallback*);
|
|
||||||
|
|
||||||
/** 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:
|
||||||
|
@ -162,7 +159,6 @@ public:
|
||||||
bool LoadModel(string AircraftPath, string EnginePath, string model,
|
bool LoadModel(string AircraftPath, string EnginePath, string model,
|
||||||
bool addModelToPath = true);
|
bool addModelToPath = true);
|
||||||
|
|
||||||
|
|
||||||
/** Loads an aircraft model. The paths to the aircraft and engine
|
/** Loads an aircraft model. The paths to the aircraft and engine
|
||||||
config file directories must be set prior to calling this. See
|
config file directories must be set prior to calling this. See
|
||||||
below.
|
below.
|
||||||
|
@ -175,37 +171,23 @@ public:
|
||||||
@return true if successful*/
|
@return true if successful*/
|
||||||
bool LoadModel(string model, bool addModelToPath = true);
|
bool LoadModel(string model, bool addModelToPath = true);
|
||||||
|
|
||||||
|
|
||||||
/** Sets the path to the engine config file directories.
|
/** Sets the path to the engine config file directories.
|
||||||
@param path path to the directory under which engine config
|
@param path path to the directory under which engine config
|
||||||
files are kept, for instance "engine"
|
files are kept, for instance "engine" */
|
||||||
*/
|
|
||||||
bool SetEnginePath(string path) { EnginePath = path; return true; }
|
bool SetEnginePath(string path) { EnginePath = path; return true; }
|
||||||
|
|
||||||
/** Sets the path to the aircraft config file directories.
|
/** Sets the path to the aircraft config file directories.
|
||||||
@param path path to the aircraft directory. For instance:
|
@param path 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. */
|
||||||
*/
|
|
||||||
bool SetAircraftPath(string path) { AircraftPath = path; return true; }
|
bool SetAircraftPath(string path) { AircraftPath = path; return true; }
|
||||||
|
|
||||||
/** Sets the path to the autopilot config file directories.
|
|
||||||
@param path 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.
|
|
||||||
inline FGState* GetState(void) {return State;}
|
|
||||||
/// Returns the FGAtmosphere pointer.
|
/// Returns the FGAtmosphere pointer.
|
||||||
inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
|
inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
|
||||||
/// Returns the FGFCS pointer.
|
/// Returns the FGFCS pointer.
|
||||||
inline FGFCS* GetFCS(void) {return FCS;}
|
inline FGFCS* GetFCS(void) {return FCS;}
|
||||||
/// Returns the FGGroundCallback pointer.
|
|
||||||
inline FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
|
|
||||||
/// Returns the FGPropulsion pointer.
|
/// Returns the FGPropulsion pointer.
|
||||||
inline FGPropulsion* GetPropulsion(void) {return Propulsion;}
|
inline FGPropulsion* GetPropulsion(void) {return Propulsion;}
|
||||||
/// Returns the FGAircraft pointer.
|
/// Returns the FGAircraft pointer.
|
||||||
|
@ -222,41 +204,100 @@ public:
|
||||||
inline FGPropagate* GetPropagate(void) {return Propagate;}
|
inline FGPropagate* GetPropagate(void) {return Propagate;}
|
||||||
/// Returns the FGAuxiliary pointer.
|
/// Returns the FGAuxiliary pointer.
|
||||||
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
|
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
|
||||||
/// Returns the FGOutput pointer.
|
/// Returns the FGInput pointer.
|
||||||
inline FGOutput* GetOutput(void) {return Output;}
|
inline FGInput* GetInput(void) {return Input;}
|
||||||
|
/// Returns the FGGroundCallback pointer.
|
||||||
|
inline FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
|
||||||
|
/// Returns the FGState pointer.
|
||||||
|
inline FGState* GetState(void) {return State;}
|
||||||
// Returns a pointer to the FGInitialCondition object
|
// Returns a pointer to the FGInitialCondition object
|
||||||
inline FGInitialCondition* GetIC(void) {return IC;}
|
inline FGInitialCondition* GetIC(void) {return IC;}
|
||||||
// Returns a pointer to the FGTrim object
|
// Returns a pointer to the FGTrim object
|
||||||
FGTrim* GetTrim(void);
|
inline 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;}
|
|
||||||
|
|
||||||
|
/// Returns the model name.
|
||||||
string GetModelName(void) { return modelName; }
|
string GetModelName(void) { return modelName; }
|
||||||
|
|
||||||
|
/// Returns a pointer to the property manager object.
|
||||||
FGPropertyManager* GetPropertyManager(void);
|
FGPropertyManager* GetPropertyManager(void);
|
||||||
|
/// Returns a vector of strings representing the names of all loaded models (future)
|
||||||
vector <string> EnumerateFDMs(void);
|
vector <string> EnumerateFDMs(void);
|
||||||
|
/// Marks this instance of the Exec object as a "slave" object.
|
||||||
void SetSlave(void) {IsSlave = true;}
|
void SetSlave(void) {IsSlave = true;}
|
||||||
|
|
||||||
|
/** Executes trimming in the selected mode.
|
||||||
|
* @param mode Specifies how to trim:
|
||||||
|
* - tLongitudinal=0
|
||||||
|
* - tFull
|
||||||
|
* - tGround
|
||||||
|
* - tPullup
|
||||||
|
* - tCustom
|
||||||
|
* - tTurn
|
||||||
|
* - tNone
|
||||||
|
*/
|
||||||
|
void DoTrim(int mode);
|
||||||
|
|
||||||
|
/// Disables data logging to all outputs.
|
||||||
|
void DisableOutput(void);
|
||||||
|
/// Enables data logging to all outputs.
|
||||||
|
void EnableOutput(void);
|
||||||
|
/// Pauses execution by preventing time from incrementing.
|
||||||
|
void Hold(void) {holding = true;}
|
||||||
|
/// Resumes execution from a "Hold".
|
||||||
|
void Resume(void) {holding = false;}
|
||||||
|
/// Returns true if the simulation is Holding (i.e. simulation time is not moving).
|
||||||
|
bool Holding(void) {return holding;}
|
||||||
|
|
||||||
|
struct PropertyCatalogStructure {
|
||||||
|
/// Name of the property.
|
||||||
|
string base_string;
|
||||||
|
/// The node for the property.
|
||||||
|
FGPropertyManager *node;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Builds a catalog of properties.
|
||||||
|
* This function descends the property tree and creates a list (an STL vector)
|
||||||
|
* containing the name and node for all properties.
|
||||||
|
* @param pcs The "root" property catalog structure pointer. */
|
||||||
|
void BuildPropertyCatalog(struct PropertyCatalogStructure* pcs);
|
||||||
|
|
||||||
|
/** Retrieves property or properties matching the supplied string.
|
||||||
|
* A string is returned that contains a carriage return delimited list of all
|
||||||
|
* strings in the property catalog that matches the supplied chack string.
|
||||||
|
* @param check The string to search for in the property catalog.
|
||||||
|
* @return the carriage-return-delimited string containing all matching strings
|
||||||
|
* in the catalog. */
|
||||||
|
string QueryPropertyCatalog(string check);
|
||||||
|
|
||||||
|
/// Use the MSIS atmosphere model.
|
||||||
|
void UseAtmosphereMSIS(void);
|
||||||
|
|
||||||
|
/// Use the Mars atmosphere model. (Not operative yet.)
|
||||||
|
void UseAtmosphereMars(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGModel* FirstModel;
|
FGModel* FirstModel;
|
||||||
|
|
||||||
bool frozen;
|
|
||||||
bool terminate;
|
bool terminate;
|
||||||
|
bool holding;
|
||||||
|
bool Constructing;
|
||||||
int Error;
|
int Error;
|
||||||
unsigned int Frame;
|
unsigned int Frame;
|
||||||
unsigned int IdFDM;
|
unsigned int IdFDM;
|
||||||
|
FGPropertyManager* Root;
|
||||||
static unsigned int FDMctr;
|
static unsigned int FDMctr;
|
||||||
bool modelLoaded;
|
bool modelLoaded;
|
||||||
string modelName;
|
string modelName;
|
||||||
bool IsSlave;
|
bool IsSlave;
|
||||||
static FGPropertyManager *master;
|
static FGPropertyManager *master;
|
||||||
FGPropertyManager *instance;
|
FGPropertyManager *instance;
|
||||||
|
vector <string> PropertyCatalog;
|
||||||
|
|
||||||
struct slaveData {
|
struct slaveData {
|
||||||
FGFDMExec* exec;
|
FGFDMExec* exec;
|
||||||
|
@ -279,15 +320,14 @@ private:
|
||||||
|
|
||||||
string AircraftPath;
|
string AircraftPath;
|
||||||
string EnginePath;
|
string EnginePath;
|
||||||
// string ControlPath;
|
|
||||||
|
|
||||||
string CFGVersion;
|
string CFGVersion;
|
||||||
string Release;
|
string Release;
|
||||||
|
|
||||||
|
FGGroundCallback* GroundCallback;
|
||||||
FGState* State;
|
FGState* State;
|
||||||
FGAtmosphere* Atmosphere;
|
FGAtmosphere* Atmosphere;
|
||||||
FGFCS* FCS;
|
FGFCS* FCS;
|
||||||
FGGroundCallback* GroundCallback;
|
|
||||||
FGPropulsion* Propulsion;
|
FGPropulsion* Propulsion;
|
||||||
FGMassBalance* MassBalance;
|
FGMassBalance* MassBalance;
|
||||||
FGAerodynamics* Aerodynamics;
|
FGAerodynamics* Aerodynamics;
|
||||||
|
@ -296,21 +336,17 @@ private:
|
||||||
FGAircraft* Aircraft;
|
FGAircraft* Aircraft;
|
||||||
FGPropagate* Propagate;
|
FGPropagate* Propagate;
|
||||||
FGAuxiliary* Auxiliary;
|
FGAuxiliary* Auxiliary;
|
||||||
FGOutput* Output;
|
FGInput* Input;
|
||||||
|
vector <FGOutput*> Outputs;
|
||||||
|
|
||||||
FGInitialCondition* IC;
|
FGInitialCondition* IC;
|
||||||
FGTrim *Trim;
|
FGTrim *Trim;
|
||||||
|
|
||||||
vector <slaveData*> SlaveFDMList;
|
vector <slaveData*> SlaveFDMList;
|
||||||
|
|
||||||
bool ReadMetrics(FGConfigFile*);
|
bool ReadFileHeader(Element*);
|
||||||
bool ReadSlave(FGConfigFile*);
|
bool ReadSlave(Element*);
|
||||||
bool ReadPropulsion(FGConfigFile*);
|
bool ReadPrologue(Element*);
|
||||||
bool ReadFlightControls(FGConfigFile*);
|
|
||||||
bool ReadAerodynamics(FGConfigFile*);
|
|
||||||
bool ReadUndercarriage(FGConfigFile*);
|
|
||||||
bool ReadPrologue(FGConfigFile*);
|
|
||||||
bool ReadOutput(FGConfigFile*);
|
|
||||||
|
|
||||||
bool Allocate(void);
|
bool Allocate(void);
|
||||||
bool DeAllocate(void);
|
bool DeAllocate(void);
|
||||||
|
|
|
@ -76,6 +76,7 @@ const double FGJSBBase::radtodeg = 57.29578;
|
||||||
const double FGJSBBase::degtorad = 1.745329E-2;
|
const double FGJSBBase::degtorad = 1.745329E-2;
|
||||||
const double FGJSBBase::hptoftlbssec = 550.0;
|
const double FGJSBBase::hptoftlbssec = 550.0;
|
||||||
const double FGJSBBase::psftoinhg = 0.014138;
|
const double FGJSBBase::psftoinhg = 0.014138;
|
||||||
|
const double FGJSBBase::psftopa = 47.88;
|
||||||
const double FGJSBBase::fpstokts = 0.592484;
|
const double FGJSBBase::fpstokts = 0.592484;
|
||||||
const double FGJSBBase::ktstofps = 1.68781;
|
const double FGJSBBase::ktstofps = 1.68781;
|
||||||
const double FGJSBBase::inchtoft = 0.08333333;
|
const double FGJSBBase::inchtoft = 0.08333333;
|
||||||
|
@ -92,8 +93,8 @@ const double FGJSBBase::SHRatio = 1.40;
|
||||||
const double FGJSBBase::slugtolb = 32.174049;
|
const double FGJSBBase::slugtolb = 32.174049;
|
||||||
const double FGJSBBase::lbtoslug = 1.0/slugtolb;
|
const double FGJSBBase::lbtoslug = 1.0/slugtolb;
|
||||||
|
|
||||||
const string FGJSBBase::needed_cfg_version = "1.65";
|
const string FGJSBBase::needed_cfg_version = "2.0";
|
||||||
const string FGJSBBase::JSBSim_version = "0.9.5";
|
const string FGJSBBase::JSBSim_version = "0.9.10.111805";
|
||||||
|
|
||||||
std::queue <FGJSBBase::Message*> FGJSBBase::Messages;
|
std::queue <FGJSBBase::Message*> FGJSBBase::Messages;
|
||||||
FGJSBBase::Message FGJSBBase::localMsg;
|
FGJSBBase::Message FGJSBBase::localMsg;
|
||||||
|
|
|
@ -42,18 +42,18 @@ INCLUDES
|
||||||
|
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
# include <simgear/compiler.h>
|
# include <simgear/compiler.h>
|
||||||
# include <simgear/constants.h>
|
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
# include <queue>
|
# include <queue>
|
||||||
# include STL_STRING
|
# include STL_STRING
|
||||||
|
|
||||||
SG_USING_STD(string);
|
SG_USING_STD(string);
|
||||||
|
|
||||||
# ifndef M_PI
|
# ifndef M_PI
|
||||||
# define M_PI SG_PI
|
# include <simgear/constants.h>
|
||||||
# endif
|
# define M_PI SG_PI
|
||||||
|
# endif
|
||||||
|
|
||||||
#else
|
#else // JSBSim section
|
||||||
|
|
||||||
# include <queue>
|
# include <queue>
|
||||||
# include <string>
|
# include <string>
|
||||||
|
@ -65,13 +65,27 @@ SG_USING_STD(string);
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
# ifndef M_PI
|
# if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||||
# define M_PI 3.14159265358979323846
|
# ifndef max
|
||||||
# endif
|
# define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef min
|
||||||
|
# define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
|
||||||
|
using std::fabs;
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef M_PI
|
||||||
|
# define M_PI 3.14159265358979323846
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(WIN32) || defined(__GNUC__) || ( defined(_MSC_VER) && (_MSC_VER >= 1400))
|
#if !defined(WIN32) || defined(__GNUC__)
|
||||||
using std::max;
|
using std::max;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -92,6 +106,8 @@ CLASS DOCUMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
/** JSBSim Base class.
|
/** JSBSim Base class.
|
||||||
|
* This class provides universal constants, utility functions, messaging
|
||||||
|
* functions, and enumerated constants to JSBSim.
|
||||||
@author Jon S. Berndt
|
@author Jon S. Berndt
|
||||||
@version $Id$
|
@version $Id$
|
||||||
*/
|
*/
|
||||||
|
@ -178,23 +194,40 @@ public:
|
||||||
@return pointer to a Message structure (or NULL if no mesage) */
|
@return pointer to a Message structure (or NULL if no mesage) */
|
||||||
Message* ProcessMessage(void);
|
Message* ProcessMessage(void);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
/** Returns the version number of JSBSim.
|
||||||
|
* @return The version number of JSBSim. */
|
||||||
string GetVersion(void) {return JSBSim_version;}
|
string GetVersion(void) {return JSBSim_version;}
|
||||||
|
|
||||||
|
/// Disables highlighting in the console output.
|
||||||
void disableHighLighting(void);
|
void disableHighLighting(void);
|
||||||
|
|
||||||
static short debug_lvl;
|
static short debug_lvl;
|
||||||
|
|
||||||
|
/** Converts from degrees Kelvin to degrees Fahrenheit.
|
||||||
|
* @param kelvin The temperature in degrees Kelvin.
|
||||||
|
* @return The temperature in Fahrenheit. */
|
||||||
static double KelvinToFahrenheit (double kelvin) {
|
static double KelvinToFahrenheit (double kelvin) {
|
||||||
return 1.8*kelvin - 459.4;
|
return 1.8*kelvin - 459.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts from degrees Rankine to degrees Celsius.
|
||||||
|
* @param rankine The temperature in degrees Rankine.
|
||||||
|
* @return The temperature in Celsius. */
|
||||||
static double RankineToCelsius (double rankine) {
|
static double RankineToCelsius (double rankine) {
|
||||||
return (rankine - 491.67)/1.8;
|
return (rankine - 491.67)/1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts from degrees Fahrenheit to degrees Celsius.
|
||||||
|
* @param fahrenheit The temperature in degrees Fahrenheit.
|
||||||
|
* @return The temperature in Celsius. */
|
||||||
static double FahrenheitToCelsius (double fahrenheit) {
|
static double FahrenheitToCelsius (double fahrenheit) {
|
||||||
return (fahrenheit - 32.0)/1.8;
|
return (fahrenheit - 32.0)/1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts from degrees Celsius to degrees Fahrenheit.
|
||||||
|
* @param celsius The temperature in degrees Celsius.
|
||||||
|
* @return The temperature in Fahrenheit. */
|
||||||
static double CelsiusToFahrenheit (double celsius) {
|
static double CelsiusToFahrenheit (double celsius) {
|
||||||
return celsius * 1.8 + 32.0;
|
return celsius * 1.8 + 32.0;
|
||||||
}
|
}
|
||||||
|
@ -247,6 +280,7 @@ protected:
|
||||||
static const double degtorad;
|
static const double degtorad;
|
||||||
static const double hptoftlbssec;
|
static const double hptoftlbssec;
|
||||||
static const double psftoinhg;
|
static const double psftoinhg;
|
||||||
|
static const double psftopa;
|
||||||
static const double fpstokts;
|
static const double fpstokts;
|
||||||
static const double ktstofps;
|
static const double ktstofps;
|
||||||
static const double inchtoft;
|
static const double inchtoft;
|
||||||
|
@ -257,8 +291,8 @@ protected:
|
||||||
static const double slugtolb;
|
static const double slugtolb;
|
||||||
static const string needed_cfg_version;
|
static const string needed_cfg_version;
|
||||||
static const string JSBSim_version;
|
static const string JSBSim_version;
|
||||||
};
|
|
||||||
|
|
||||||
|
public:
|
||||||
/// Moments L, M, N
|
/// Moments L, M, N
|
||||||
enum {eL = 1, eM, eN };
|
enum {eL = 1, eM, eN };
|
||||||
/// Rates P, Q, R
|
/// Rates P, Q, R
|
||||||
|
@ -280,6 +314,8 @@ enum {eLat = 1, eLong, eRad };
|
||||||
/// Conversion specifiers
|
/// Conversion specifiers
|
||||||
enum {inNone = 0, inDegrees, inRadians, inMeters, inFeet };
|
enum {inNone = 0, inDegrees, inRadians, inMeters, inFeet };
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,10 +36,6 @@ HISTORY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
# include <simgear/compiler.h>
|
# include <simgear/compiler.h>
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
|
@ -81,7 +77,6 @@ FGState::FGState(FGFDMExec* fdex)
|
||||||
Propagate = FDMExec->GetPropagate();
|
Propagate = FDMExec->GetPropagate();
|
||||||
Auxiliary = FDMExec->GetAuxiliary();
|
Auxiliary = FDMExec->GetAuxiliary();
|
||||||
FCS = FDMExec->GetFCS();
|
FCS = FDMExec->GetFCS();
|
||||||
Output = FDMExec->GetOutput();
|
|
||||||
Atmosphere = FDMExec->GetAtmosphere();
|
Atmosphere = FDMExec->GetAtmosphere();
|
||||||
Aerodynamics = FDMExec->GetAerodynamics();
|
Aerodynamics = FDMExec->GetAerodynamics();
|
||||||
GroundReactions = FDMExec->GetGroundReactions();
|
GroundReactions = FDMExec->GetGroundReactions();
|
||||||
|
|
|
@ -59,20 +59,19 @@ INCLUDES
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "FGJSBBase.h"
|
#include "FGJSBBase.h"
|
||||||
#include "FGInitialCondition.h"
|
#include <initialization/FGInitialCondition.h>
|
||||||
#include "FGMatrix33.h"
|
#include <math/FGMatrix33.h>
|
||||||
#include "FGColumnVector3.h"
|
#include <math/FGColumnVector3.h>
|
||||||
#include "FGQuaternion.h"
|
#include <math/FGQuaternion.h>
|
||||||
#include "FGFDMExec.h"
|
#include "FGFDMExec.h"
|
||||||
#include "FGAtmosphere.h"
|
#include <models/FGAtmosphere.h>
|
||||||
#include "FGFCS.h"
|
#include <models/FGFCS.h>
|
||||||
#include "FGPropagate.h"
|
#include <models/FGPropagate.h>
|
||||||
#include "FGAuxiliary.h"
|
#include <models/FGAuxiliary.h>
|
||||||
#include "FGAerodynamics.h"
|
#include <models/FGAerodynamics.h>
|
||||||
#include "FGOutput.h"
|
#include <models/FGAircraft.h>
|
||||||
#include "FGAircraft.h"
|
#include <models/FGGroundReactions.h>
|
||||||
#include "FGGroundReactions.h"
|
#include <models/FGPropulsion.h>
|
||||||
#include "FGPropulsion.h"
|
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -117,12 +116,16 @@ public:
|
||||||
/// Returns the simulation time in seconds.
|
/// Returns the simulation time in seconds.
|
||||||
inline double Getsim_time(void) const { return sim_time; }
|
inline double Getsim_time(void) const { return sim_time; }
|
||||||
/// Returns the simulation delta T.
|
/// Returns the simulation delta T.
|
||||||
inline double Getdt(void) { return dt; }
|
inline double Getdt(void) {
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
|
||||||
/// Suspends the simulation and sets the delta T to zero.
|
/// Suspends the simulation and sets the delta T to zero.
|
||||||
inline void Suspend(void) {saved_dt = dt; dt = 0.0;}
|
inline void SuspendIntegration(void) {saved_dt = dt; dt = 0.0;}
|
||||||
/// Resumes the simulation by resetting delta T to the correct value.
|
/// Resumes the simulation by resetting delta T to the correct value.
|
||||||
inline void Resume(void) {dt = saved_dt;}
|
inline void ResumeIntegration(void) {dt = saved_dt;}
|
||||||
|
|
||||||
|
bool IntegrationSuspended(void) {return dt == 0.0;}
|
||||||
|
|
||||||
/** Sets the current sim time.
|
/** Sets the current sim time.
|
||||||
@param cur_time the current time
|
@param cur_time the current time
|
||||||
|
@ -136,7 +139,9 @@ public:
|
||||||
/** Sets the integration time step for the simulation executive.
|
/** Sets the integration time step for the simulation executive.
|
||||||
@param delta_t the time step in seconds.
|
@param delta_t the time step in seconds.
|
||||||
*/
|
*/
|
||||||
inline void Setdt(double delta_t) { dt = delta_t; }
|
inline void Setdt(double delta_t) {
|
||||||
|
dt = delta_t;
|
||||||
|
}
|
||||||
|
|
||||||
/** Increments the simulation time.
|
/** Increments the simulation time.
|
||||||
@return the new simulation time.
|
@return the new simulation time.
|
||||||
|
@ -174,7 +179,6 @@ private:
|
||||||
|
|
||||||
FGAircraft* Aircraft;
|
FGAircraft* Aircraft;
|
||||||
FGPropagate* Propagate;
|
FGPropagate* Propagate;
|
||||||
FGOutput* Output;
|
|
||||||
FGAtmosphere* Atmosphere;
|
FGAtmosphere* Atmosphere;
|
||||||
FGFCS* FCS;
|
FGFCS* FCS;
|
||||||
FGAerodynamics* Aerodynamics;
|
FGAerodynamics* Aerodynamics;
|
||||||
|
|
|
@ -47,30 +47,35 @@
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
#include <FDM/JSBSim/FGFDMExec.h>
|
|
||||||
#include <FDM/JSBSim/FGAircraft.h>
|
|
||||||
#include <FDM/JSBSim/FGFCS.h>
|
|
||||||
#include <FDM/JSBSim/FGPropagate.h>
|
|
||||||
#include <FDM/JSBSim/FGState.h>
|
|
||||||
#include <FDM/JSBSim/FGAuxiliary.h>
|
|
||||||
#include <FDM/JSBSim/FGInitialCondition.h>
|
|
||||||
#include <FDM/JSBSim/FGTrim.h>
|
|
||||||
#include <FDM/JSBSim/FGAtmosphere.h>
|
|
||||||
#include <FDM/JSBSim/FGMassBalance.h>
|
|
||||||
#include <FDM/JSBSim/FGAerodynamics.h>
|
|
||||||
#include <FDM/JSBSim/FGLGear.h>
|
|
||||||
#include <FDM/JSBSim/FGPropertyManager.h>
|
|
||||||
#include <FDM/JSBSim/FGEngine.h>
|
|
||||||
#include <FDM/JSBSim/FGPiston.h>
|
|
||||||
#include <FDM/JSBSim/FGGroundCallback.h>
|
|
||||||
#include <FDM/JSBSim/FGTurbine.h>
|
|
||||||
#include <FDM/JSBSim/FGRocket.h>
|
|
||||||
#include <FDM/JSBSim/FGElectric.h>
|
|
||||||
#include <FDM/JSBSim/FGNozzle.h>
|
|
||||||
#include <FDM/JSBSim/FGPropeller.h>
|
|
||||||
#include <FDM/JSBSim/FGRotor.h>
|
|
||||||
#include <FDM/JSBSim/FGTank.h>
|
|
||||||
#include "JSBSim.hxx"
|
#include "JSBSim.hxx"
|
||||||
|
#include <FDM/JSBSim/FGFDMExec.h>
|
||||||
|
#include <FDM/JSBSim/FGJSBBase.h>
|
||||||
|
#include <FDM/JSBSim/FGState.h>
|
||||||
|
#include <FDM/JSBSim/initialization/FGInitialCondition.h>
|
||||||
|
#include <FDM/JSBSim/initialization/FGTrim.h>
|
||||||
|
#include <FDM/JSBSim/models/FGModel.h>
|
||||||
|
#include <FDM/JSBSim/models/FGAircraft.h>
|
||||||
|
#include <FDM/JSBSim/models/FGFCS.h>
|
||||||
|
#include <FDM/JSBSim/models/FGPropagate.h>
|
||||||
|
#include <FDM/JSBSim/models/FGAuxiliary.h>
|
||||||
|
#include <FDM/JSBSim/models/FGAtmosphere.h>
|
||||||
|
#include <FDM/JSBSim/models/FGMassBalance.h>
|
||||||
|
#include <FDM/JSBSim/models/FGAerodynamics.h>
|
||||||
|
#include <FDM/JSBSim/models/FGLGear.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGEngine.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGPiston.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGTurbine.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGTurboProp.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGRocket.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGElectric.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGNozzle.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGPropeller.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGRotor.h>
|
||||||
|
#include <FDM/JSBSim/models/propulsion/FGTank.h>
|
||||||
|
#include <FDM/JSBSim/input_output/FGPropertyManager.h>
|
||||||
|
#include <FDM/JSBSim/input_output/FGGroundCallback.h>
|
||||||
|
|
||||||
|
using namespace JSBSim;
|
||||||
|
|
||||||
static inline double
|
static inline double
|
||||||
FMAX (double a, double b)
|
FMAX (double a, double b)
|
||||||
|
@ -142,10 +147,6 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_on_crash = fgGetBool("/sim/reset-on-crash", false);
|
|
||||||
crashed = false;
|
|
||||||
fgSetBool("/sim/crashed", false);
|
|
||||||
|
|
||||||
fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() );
|
fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() );
|
||||||
|
|
||||||
// Register ground callback.
|
// Register ground callback.
|
||||||
|
@ -288,9 +289,6 @@ void FGJSBsim::init()
|
||||||
// Explicitly call the superclass's
|
// Explicitly call the superclass's
|
||||||
// init method first.
|
// init method first.
|
||||||
|
|
||||||
#ifdef FG_WEATHERCM
|
|
||||||
Atmosphere->UseInternal();
|
|
||||||
#else
|
|
||||||
if (fgGetBool("/environment/params/control-fdm-atmosphere")) {
|
if (fgGetBool("/environment/params/control-fdm-atmosphere")) {
|
||||||
Atmosphere->UseExternal();
|
Atmosphere->UseExternal();
|
||||||
Atmosphere->SetExTemperature(
|
Atmosphere->SetExTemperature(
|
||||||
|
@ -307,7 +305,6 @@ void FGJSBsim::init()
|
||||||
} else {
|
} else {
|
||||||
Atmosphere->UseInternal();
|
Atmosphere->UseInternal();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
fgic->SetVnorthFpsIC( wind_from_north->getDoubleValue() );
|
fgic->SetVnorthFpsIC( wind_from_north->getDoubleValue() );
|
||||||
fgic->SetVeastFpsIC( wind_from_east->getDoubleValue() );
|
fgic->SetVeastFpsIC( wind_from_east->getDoubleValue() );
|
||||||
|
@ -339,9 +336,9 @@ void FGJSBsim::init()
|
||||||
switch(fgic->GetSpeedSet()) {
|
switch(fgic->GetSpeedSet()) {
|
||||||
case setned:
|
case setned:
|
||||||
SG_LOG(SG_FLIGHT,SG_INFO, " Vn,Ve,Vd= "
|
SG_LOG(SG_FLIGHT,SG_INFO, " Vn,Ve,Vd= "
|
||||||
<< Propagate->GetVel(eNorth) << ", "
|
<< Propagate->GetVel(FGJSBBase::eNorth) << ", "
|
||||||
<< Propagate->GetVel(eEast) << ", "
|
<< Propagate->GetVel(FGJSBBase::eEast) << ", "
|
||||||
<< Propagate->GetVel(eDown) << " ft/s");
|
<< Propagate->GetVel(FGJSBBase::eDown) << " ft/s");
|
||||||
break;
|
break;
|
||||||
case setuvw:
|
case setuvw:
|
||||||
SG_LOG(SG_FLIGHT,SG_INFO, " U,V,W= "
|
SG_LOG(SG_FLIGHT,SG_INFO, " U,V,W= "
|
||||||
|
@ -363,11 +360,11 @@ void FGJSBsim::init()
|
||||||
stall_warning->setDoubleValue(0);
|
stall_warning->setDoubleValue(0);
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
||||||
<< Propagate->GetEuler(ePhi)*RADTODEG << " deg" );
|
<< Propagate->GetEuler(FGJSBBase::ePhi)*RADTODEG << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Pitch Angle: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Pitch Angle: "
|
||||||
<< Propagate->GetEuler(eTht)*RADTODEG << " deg" );
|
<< Propagate->GetEuler(FGJSBBase::eTht)*RADTODEG << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " True Heading: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " True Heading: "
|
||||||
<< Propagate->GetEuler(ePsi)*RADTODEG << " deg" );
|
<< Propagate->GetEuler(FGJSBBase::ePsi)*RADTODEG << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Latitude: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Latitude: "
|
||||||
<< Propagate->GetLocation().GetLatitudeDeg() << " deg" );
|
<< Propagate->GetLocation().GetLatitudeDeg() << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Longitude: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Longitude: "
|
||||||
|
@ -487,12 +484,6 @@ void FGJSBsim::update( double dt )
|
||||||
// translate JSBsim back to FG structure so that the
|
// translate JSBsim back to FG structure so that the
|
||||||
// autopilot (and the rest of the sim can use the updated values
|
// autopilot (and the rest of the sim can use the updated values
|
||||||
copy_from_JSBsim();
|
copy_from_JSBsim();
|
||||||
|
|
||||||
// crashed (altitude AGL < 0)
|
|
||||||
if (get_Altitude_AGL() < 0.0) {
|
|
||||||
crash_message = "Attempted to fly under ground.";
|
|
||||||
crash_handler();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -534,6 +525,7 @@ bool FGJSBsim::copy_to_JSBsim()
|
||||||
FCS->SetThrottleCmd(i, globals->get_controls()->get_throttle(i));
|
FCS->SetThrottleCmd(i, globals->get_controls()->get_throttle(i));
|
||||||
FCS->SetMixtureCmd(i, globals->get_controls()->get_mixture(i));
|
FCS->SetMixtureCmd(i, globals->get_controls()->get_mixture(i));
|
||||||
FCS->SetPropAdvanceCmd(i, globals->get_controls()->get_prop_advance(i));
|
FCS->SetPropAdvanceCmd(i, globals->get_controls()->get_prop_advance(i));
|
||||||
|
FCS->SetFeatherCmd(i, globals->get_controls()->get_feather(i));
|
||||||
|
|
||||||
switch (Propulsion->GetEngine(i)->GetType()) {
|
switch (Propulsion->GetEngine(i)->GetType()) {
|
||||||
case FGEngine::etPiston:
|
case FGEngine::etPiston:
|
||||||
|
@ -557,6 +549,17 @@ bool FGJSBsim::copy_to_JSBsim()
|
||||||
FGRocket* eng = (FGRocket*)Propulsion->GetEngine(i);
|
FGRocket* eng = (FGRocket*)Propulsion->GetEngine(i);
|
||||||
break;
|
break;
|
||||||
} // end FGRocket code block
|
} // end FGRocket code block
|
||||||
|
case FGEngine::etTurboprop:
|
||||||
|
{ // FGTurboProp code block
|
||||||
|
FGTurboProp* eng = (FGTurboProp*)Propulsion->GetEngine(i);
|
||||||
|
eng->SetReverse( globals->get_controls()->get_reverser(i) );
|
||||||
|
eng->SetCutoff( globals->get_controls()->get_cutoff(i) );
|
||||||
|
eng->SetIgnition( globals->get_controls()->get_ignition(i) );
|
||||||
|
|
||||||
|
eng->SetGeneratorPower( globals->get_controls()->get_generator_breaker(i) );
|
||||||
|
eng->SetCondition( globals->get_controls()->get_condition(i) );
|
||||||
|
break;
|
||||||
|
} // end FGTurboProp code block
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // FGEngine code block
|
{ // FGEngine code block
|
||||||
|
@ -636,18 +639,18 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
|
|
||||||
// Velocities
|
// Velocities
|
||||||
|
|
||||||
_set_Velocities_Local( Propagate->GetVel(eNorth),
|
_set_Velocities_Local( Propagate->GetVel(FGJSBBase::eNorth),
|
||||||
Propagate->GetVel(eEast),
|
Propagate->GetVel(FGJSBBase::eEast),
|
||||||
Propagate->GetVel(eDown) );
|
Propagate->GetVel(FGJSBBase::eDown) );
|
||||||
|
|
||||||
_set_Velocities_Wind_Body( Propagate->GetUVW(1),
|
_set_Velocities_Wind_Body( Propagate->GetUVW(1),
|
||||||
Propagate->GetUVW(2),
|
Propagate->GetUVW(2),
|
||||||
Propagate->GetUVW(3) );
|
Propagate->GetUVW(3) );
|
||||||
|
|
||||||
// Make the HUD work ...
|
// Make the HUD work ...
|
||||||
_set_Velocities_Ground( Propagate->GetVel(eNorth),
|
_set_Velocities_Ground( Propagate->GetVel(FGJSBBase::eNorth),
|
||||||
Propagate->GetVel(eEast),
|
Propagate->GetVel(FGJSBBase::eEast),
|
||||||
-Propagate->GetVel(eDown) );
|
-Propagate->GetVel(FGJSBBase::eDown) );
|
||||||
|
|
||||||
_set_V_rel_wind( Auxiliary->GetVt() );
|
_set_V_rel_wind( Auxiliary->GetVt() );
|
||||||
|
|
||||||
|
@ -657,13 +660,13 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
|
|
||||||
_set_V_ground_speed( Auxiliary->GetVground() );
|
_set_V_ground_speed( Auxiliary->GetVground() );
|
||||||
|
|
||||||
_set_Omega_Body( Propagate->GetPQR(eP),
|
_set_Omega_Body( Propagate->GetPQR(FGJSBBase::eP),
|
||||||
Propagate->GetPQR(eQ),
|
Propagate->GetPQR(FGJSBBase::eQ),
|
||||||
Propagate->GetPQR(eR) );
|
Propagate->GetPQR(FGJSBBase::eR) );
|
||||||
|
|
||||||
_set_Euler_Rates( Auxiliary->GetEulerRates(ePhi),
|
_set_Euler_Rates( Auxiliary->GetEulerRates(FGJSBBase::ePhi),
|
||||||
Auxiliary->GetEulerRates(eTht),
|
Auxiliary->GetEulerRates(FGJSBBase::eTht),
|
||||||
Auxiliary->GetEulerRates(ePsi) );
|
Auxiliary->GetEulerRates(FGJSBBase::ePsi) );
|
||||||
|
|
||||||
_set_Mach_number( Auxiliary->GetMach() );
|
_set_Mach_number( Auxiliary->GetMach() );
|
||||||
|
|
||||||
|
@ -674,7 +677,7 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
|
|
||||||
_set_Altitude_AGL( Propagate->GetDistanceAGL() );
|
_set_Altitude_AGL( Propagate->GetDistanceAGL() );
|
||||||
{
|
{
|
||||||
double loc_cart[3] = { l(eX), l(eY), l(eZ) };
|
double loc_cart[3] = { l(FGJSBBase::eX), l(FGJSBBase::eY), l(FGJSBBase::eZ) };
|
||||||
double contact[3], d[3], sd, t;
|
double contact[3], d[3], sd, t;
|
||||||
int id;
|
int id;
|
||||||
is_valid_m(&t, d, &sd);
|
is_valid_m(&t, d, &sd);
|
||||||
|
@ -684,9 +687,9 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
_set_Runway_altitude( rwrad - get_Sea_level_radius() );
|
_set_Runway_altitude( rwrad - get_Sea_level_radius() );
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_Euler_Angles( Propagate->GetEuler(ePhi),
|
_set_Euler_Angles( Propagate->GetEuler(FGJSBBase::ePhi),
|
||||||
Propagate->GetEuler(eTht),
|
Propagate->GetEuler(FGJSBBase::eTht),
|
||||||
Propagate->GetEuler(ePsi) );
|
Propagate->GetEuler(FGJSBBase::ePsi) );
|
||||||
|
|
||||||
_set_Alpha( Auxiliary->Getalpha() );
|
_set_Alpha( Auxiliary->Getalpha() );
|
||||||
_set_Beta( Auxiliary->Getbeta() );
|
_set_Beta( Auxiliary->Getbeta() );
|
||||||
|
@ -751,6 +754,28 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
globals->get_controls()->set_augmentation(i, eng->GetAugmentation() );
|
globals->get_controls()->set_augmentation(i, eng->GetAugmentation() );
|
||||||
} // end FGTurbine code block
|
} // end FGTurbine code block
|
||||||
break;
|
break;
|
||||||
|
case FGEngine::etTurboprop:
|
||||||
|
{ // FGTurboProp code block
|
||||||
|
FGTurboProp* eng = (FGTurboProp*)Propulsion->GetEngine(i);
|
||||||
|
node->setDoubleValue("n1", eng->GetN1());
|
||||||
|
//node->setDoubleValue("n2", eng->GetN2());
|
||||||
|
node->setDoubleValue("itt_degf", 32 + eng->GetITT()*9/5);
|
||||||
|
node->setBoolValue("ignition", eng->GetIgnition());
|
||||||
|
node->setDoubleValue("nozzle-pos-norm", eng->GetNozzle());
|
||||||
|
node->setDoubleValue("inlet-pos-norm", eng->GetInlet());
|
||||||
|
node->setDoubleValue("oil-pressure-psi", eng->getOilPressure_psi());
|
||||||
|
node->setBoolValue("reversed", eng->GetReversed());
|
||||||
|
node->setBoolValue("cutoff", eng->GetCutoff());
|
||||||
|
node->setBoolValue("starting", eng->GetEngStarting());
|
||||||
|
node->setBoolValue("generator-power", eng->GetGeneratorPower());
|
||||||
|
node->setBoolValue("damaged", eng->GetCondition());
|
||||||
|
node->setBoolValue("ielu-intervent", eng->GetIeluIntervent());
|
||||||
|
node->setDoubleValue("oil-temperature-degf", eng->getOilTemp_degF());
|
||||||
|
// node->setBoolValue("onfire", eng->GetFire());
|
||||||
|
globals->get_controls()->set_reverser(i, eng->GetReversed() );
|
||||||
|
globals->get_controls()->set_cutoff(i, eng->GetCutoff() );
|
||||||
|
} // end FGTurboProp code block
|
||||||
|
break;
|
||||||
case FGEngine::etElectric:
|
case FGEngine::etElectric:
|
||||||
{ // FGElectric code block
|
{ // FGElectric code block
|
||||||
FGElectric* eng = (FGElectric*)Propulsion->GetEngine(i);
|
FGElectric* eng = (FGElectric*)Propulsion->GetEngine(i);
|
||||||
|
@ -782,6 +807,7 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
tnode->setDoubleValue("rpm", thruster->GetRPM());
|
tnode->setDoubleValue("rpm", thruster->GetRPM());
|
||||||
tnode->setDoubleValue("pitch", prop->GetPitch());
|
tnode->setDoubleValue("pitch", prop->GetPitch());
|
||||||
tnode->setDoubleValue("torque", prop->GetTorque());
|
tnode->setDoubleValue("torque", prop->GetTorque());
|
||||||
|
tnode->setBoolValue("feathered", prop->GetFeather());
|
||||||
} // end FGPropeller code block
|
} // end FGPropeller code block
|
||||||
break;
|
break;
|
||||||
case FGThruster::ttRotor:
|
case FGThruster::ttRotor:
|
||||||
|
@ -823,23 +849,32 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
speedbrake_pos_pct->setDoubleValue( FCS->GetDsbPos(ofNorm) );
|
speedbrake_pos_pct->setDoubleValue( FCS->GetDsbPos(ofNorm) );
|
||||||
spoilers_pos_pct->setDoubleValue( FCS->GetDspPos(ofNorm) );
|
spoilers_pos_pct->setDoubleValue( FCS->GetDspPos(ofNorm) );
|
||||||
|
|
||||||
|
// force a sim reset if crashed (altitude AGL < 0)
|
||||||
|
if (get_Altitude_AGL() < 0.0) {
|
||||||
|
fgSetBool("/sim/crashed", true);
|
||||||
|
SGPropertyNode* node = fgGetNode("/sim/presets", true);
|
||||||
|
globals->get_commands()->execute("old-reinit-dialog", node);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FGJSBsim::ToggleDataLogging(void)
|
bool FGJSBsim::ToggleDataLogging(void)
|
||||||
{
|
{
|
||||||
return fdmex->GetOutput()->Toggle();
|
// ToDo: handle this properly
|
||||||
|
fdmex->DisableOutput();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FGJSBsim::ToggleDataLogging(bool state)
|
bool FGJSBsim::ToggleDataLogging(bool state)
|
||||||
{
|
{
|
||||||
if (state) {
|
if (state) {
|
||||||
fdmex->GetOutput()->Enable();
|
fdmex->EnableOutput();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
fdmex->GetOutput()->Disable();
|
fdmex->DisableOutput();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1098,17 +1133,3 @@ void FGJSBsim::update_ic(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGJSBsim::crash_handler(void)
|
|
||||||
{
|
|
||||||
if (crashed) return; // we already crashed
|
|
||||||
crashed = true;
|
|
||||||
fgSetBool("/sim/crashed", true);
|
|
||||||
SG_LOG( SG_FLIGHT, SG_WARN, " Crash: " << crash_message );
|
|
||||||
if (reset_on_crash) {
|
|
||||||
SGPropertyNode* node = fgGetNode("/sim/presets", true);
|
|
||||||
globals->get_commands()->execute("old-reinit-dialog", node);
|
|
||||||
} else {
|
|
||||||
fgSetBool("/sim/freeze/master", true);
|
|
||||||
fgSetBool("/sim/freeze/clock", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -72,7 +72,8 @@ class FGOutput;
|
||||||
class FGInitialCondition;
|
class FGInitialCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace JSBSim;
|
// Adding it here will cause a namespace clash in FlightGear -EMH-
|
||||||
|
// using namespace JSBSim;
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
CLASS DOCUMENTATION
|
CLASS DOCUMENTATION
|
||||||
|
@ -205,24 +206,21 @@ public:
|
||||||
void do_trim(void);
|
void do_trim(void);
|
||||||
void update_ic(void);
|
void update_ic(void);
|
||||||
|
|
||||||
//** Handle a crash of the user aircraft. */
|
|
||||||
void crash_handler();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGFDMExec *fdmex;
|
JSBSim::FGFDMExec *fdmex;
|
||||||
FGInitialCondition *fgic;
|
JSBSim::FGInitialCondition *fgic;
|
||||||
bool needTrim;
|
bool needTrim;
|
||||||
|
|
||||||
FGState* State;
|
JSBSim::FGState* State;
|
||||||
FGAtmosphere* Atmosphere;
|
JSBSim::FGAtmosphere* Atmosphere;
|
||||||
FGFCS* FCS;
|
JSBSim::FGFCS* FCS;
|
||||||
FGPropulsion* Propulsion;
|
JSBSim::FGPropulsion* Propulsion;
|
||||||
FGMassBalance* MassBalance;
|
JSBSim::FGMassBalance* MassBalance;
|
||||||
FGAircraft* Aircraft;
|
JSBSim::FGAircraft* Aircraft;
|
||||||
FGPropagate* Propagate;
|
JSBSim::FGPropagate* Propagate;
|
||||||
FGAuxiliary* Auxiliary;
|
JSBSim::FGAuxiliary* Auxiliary;
|
||||||
FGAerodynamics* Aerodynamics;
|
JSBSim::FGAerodynamics* Aerodynamics;
|
||||||
FGGroundReactions *GroundReactions;
|
JSBSim::FGGroundReactions *GroundReactions;
|
||||||
|
|
||||||
int runcount;
|
int runcount;
|
||||||
double trim_elev;
|
double trim_elev;
|
||||||
|
@ -266,10 +264,6 @@ private:
|
||||||
void init_gear(void);
|
void init_gear(void);
|
||||||
void update_gear(void);
|
void update_gear(void);
|
||||||
|
|
||||||
bool reset_on_crash;
|
|
||||||
bool crashed;
|
|
||||||
string crash_message;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,58 +1,9 @@
|
||||||
SUBDIRS = filtersjb
|
SUBDIRS = initialization models input_output math
|
||||||
|
|
||||||
EXTRA_DIST = Makefile.solo
|
|
||||||
|
|
||||||
noinst_LIBRARIES = libJSBSim.a
|
noinst_LIBRARIES = libJSBSim.a
|
||||||
|
|
||||||
libJSBSim_a_SOURCES = \
|
libJSBSim_a_SOURCES = FGFDMExec.cpp FGJSBBase.cpp FGState.cpp JSBSim.cxx
|
||||||
FGAerodynamics.cpp FGAerodynamics.h \
|
|
||||||
FGAircraft.cpp FGAircraft.h \
|
|
||||||
FGAtmosphere.cpp FGAtmosphere.h \
|
|
||||||
FGAuxiliary.cpp FGAuxiliary.h \
|
|
||||||
FGCoefficient.cpp FGCoefficient.h \
|
|
||||||
FGColumnVector3.cpp FGColumnVector3.h \
|
|
||||||
FGConfigFile.cpp FGConfigFile.h \
|
|
||||||
FGFCS.cpp FGFCS.h \
|
|
||||||
FGFDMExec.cpp FGFDMExec.h \
|
|
||||||
FGFactorGroup.cpp FGFactorGroup.h \
|
|
||||||
FGForce.cpp FGForce.h \
|
|
||||||
FGGroundReactions.cpp FGGroundReactions.h \
|
|
||||||
FGInertial.cpp FGInertial.h \
|
|
||||||
FGInitialCondition.cpp FGInitialCondition.h \
|
|
||||||
FGJSBBase.cpp FGJSBBase.h \
|
|
||||||
FGLGear.cpp FGLGear.h \
|
|
||||||
FGMassBalance.cpp FGMassBalance.h \
|
|
||||||
FGMatrix33.cpp FGMatrix33.h \
|
|
||||||
FGModel.cpp FGModel.h \
|
|
||||||
FGNozzle.cpp FGNozzle.h \
|
|
||||||
FGOutput.cpp FGOutput.h \
|
|
||||||
FGPiston.cpp FGPiston.h \
|
|
||||||
FGPropeller.cpp FGPropeller.h \
|
|
||||||
FGPropulsion.cpp FGPropulsion.h \
|
|
||||||
FGRotor.cpp FGRotor.h \
|
|
||||||
FGRocket.cpp FGRocket.h \
|
|
||||||
FGScript.cpp FGScript.h \
|
|
||||||
FGState.cpp FGState.h \
|
|
||||||
FGTable.cpp FGTable.h \
|
|
||||||
FGThruster.cpp FGThruster.h \
|
|
||||||
FGTrim.cpp FGTrim.h \
|
|
||||||
FGTrimAxis.cpp FGTrimAxis.h \
|
|
||||||
FGTurbine.cpp FGTurbine.h \
|
|
||||||
FGEngine.cpp FGEngine.h \
|
|
||||||
FGTank.cpp FGTank.h \
|
|
||||||
FGfdmSocket.cpp FGfdmSocket.h \
|
|
||||||
FGTurbine.cpp FGTurbine.h \
|
|
||||||
FGPropertyManager.cpp FGPropertyManager.h \
|
|
||||||
FGPropagate.cpp FGPropagate.h \
|
|
||||||
FGLocation.cpp FGLocation.h \
|
|
||||||
FGQuaternion.cpp FGQuaternion.h \
|
|
||||||
FGElectric.cpp FGElectric.h \
|
|
||||||
FGGroundCallback.cpp FGGroundCallback.h \
|
|
||||||
JSBSim.cxx JSBSim.hxx
|
|
||||||
|
|
||||||
|
noinst_HEADERS = FGFDMExec.h FGJSBBase.h FGState.h JSBSim.hxx
|
||||||
|
|
||||||
# noinst_PROGRAMS = testJSBsim
|
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim
|
||||||
|
|
||||||
AM_CXXFLAGS = -DFGFS
|
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
|
||||||
|
|
|
@ -1,413 +0,0 @@
|
||||||
CC = g++
|
|
||||||
INCLUDES = -I.
|
|
||||||
LINKDIR= -Lfiltersjb/
|
|
||||||
JSBSim_objects = FGAircraft.o FGAtmosphere.o FGCoefficient.o FGFCS.o FGFDMExec.o\
|
|
||||||
FGModel.o FGOutput.o FGPosition.o FGRotation.o FGState.o FGTranslation.o\
|
|
||||||
FGUtility.o FGTank.o FGAuxiliary.o FGfdmSocket.o FGTrim.o FGTrimAxis.o\
|
|
||||||
FGConfigFile.o FGInitialCondition.o FGLGear.o FGMatrix.o FGPropulsion.o FGRocket.o\
|
|
||||||
FGTurboShaft.o FGTurboJet.o FGTurboProp.o FGPiston.o FGForce.o FGThruster.o FGEngine.o\
|
|
||||||
FGTable.o FGPropeller.o FGNozzle.o FGAerodynamics.o FGMassBalance.o FGInertial.o\
|
|
||||||
FGFactorGroup.o
|
|
||||||
|
|
||||||
JSBSim : $(JSBSim_objects) JSBSim.o libFCSComponents.a
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) $(LINKDIR) $(JSBSim_objects) JSBSim.o -oJSBSim -lm -lFCSComponents
|
|
||||||
|
|
||||||
libFCSComponents.a:
|
|
||||||
cd filtersjb; make -fMakefile.solo; cd ..
|
|
||||||
|
|
||||||
FGAerodynamics.o: FGAerodynamics.cpp FGAerodynamics.h FGModel.h \
|
|
||||||
FGDefs.h FGConfigFile.h FGState.h FGInitialCondition.h FGFDMExec.h \
|
|
||||||
FGAtmosphere.h FGMatrix.h FGFCS.h filtersjb/FGFCSComponent.h \
|
|
||||||
filtersjb/../FGDefs.h filtersjb/../FGFCS.h FGLGear.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGRotation.h \
|
|
||||||
FGPosition.h FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGTable.h FGNozzle.h FGMassBalance.h \
|
|
||||||
FGCoefficient.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGAerodynamics.cpp
|
|
||||||
|
|
||||||
FGAircraft.o: FGAircraft.cpp FGAircraft.h FGModel.h FGDefs.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGState.h FGInitialCondition.h \
|
|
||||||
FGFDMExec.h FGAtmosphere.h FGMatrix.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGConfigFile.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGTranslation.h FGAerodynamics.h FGCoefficient.h FGTable.h \
|
|
||||||
FGFactorGroup.h FGOutput.h FGfdmSocket.h FGAuxiliary.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGNozzle.h FGInertial.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGAircraft.cpp
|
|
||||||
|
|
||||||
FGAtmosphere.o: FGAtmosphere.cpp FGAtmosphere.h FGModel.h FGDefs.h \
|
|
||||||
FGMatrix.h FGState.h FGInitialCondition.h FGFDMExec.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGConfigFile.h FGAircraft.h FGPropulsion.h FGRocket.h \
|
|
||||||
FGEngine.h FGTranslation.h FGRotation.h FGPosition.h FGAuxiliary.h \
|
|
||||||
FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGNozzle.h FGMassBalance.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGAtmosphere.cpp
|
|
||||||
|
|
||||||
FGAuxiliary.o: FGAuxiliary.cpp FGAuxiliary.h FGModel.h FGDefs.h \
|
|
||||||
FGMatrix.h FGTranslation.h FGRotation.h FGAtmosphere.h FGState.h \
|
|
||||||
FGInitialCondition.h FGFDMExec.h FGFCS.h filtersjb/FGFCSComponent.h \
|
|
||||||
filtersjb/../FGDefs.h filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h \
|
|
||||||
FGAircraft.h FGPropulsion.h FGRocket.h FGEngine.h FGPosition.h \
|
|
||||||
FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGNozzle.h FGMassBalance.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGAuxiliary.cpp
|
|
||||||
|
|
||||||
FGCoefficient.o: FGCoefficient.cpp FGCoefficient.h FGConfigFile.h \
|
|
||||||
FGDefs.h FGTable.h FGState.h FGInitialCondition.h FGFDMExec.h \
|
|
||||||
FGModel.h FGAtmosphere.h FGMatrix.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGAircraft.h FGPropulsion.h FGRocket.h FGEngine.h \
|
|
||||||
FGTranslation.h FGRotation.h FGPosition.h FGAuxiliary.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h FGTurboProp.h \
|
|
||||||
FGTank.h FGPropeller.h FGThruster.h FGForce.h FGNozzle.h \
|
|
||||||
FGMassBalance.h FGAerodynamics.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGCoefficient.cpp
|
|
||||||
|
|
||||||
FGColumnVector3.o: FGColumnVector3.cpp FGColumnVector3.h FGMatrix.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGColumnVector3.cpp
|
|
||||||
|
|
||||||
FGConfigFile.o: FGConfigFile.cpp FGConfigFile.h FGDefs.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGConfigFile.cpp
|
|
||||||
|
|
||||||
FGEngine.o: FGEngine.cpp FGEngine.h FGState.h FGDefs.h \
|
|
||||||
FGInitialCondition.h FGFDMExec.h FGModel.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGTranslation.h FGNozzle.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGEngine.cpp
|
|
||||||
|
|
||||||
FGFCS.o: FGFCS.cpp FGDefs.h FGFCS.h filtersjb/FGFCSComponent.h \
|
|
||||||
filtersjb/../FGDefs.h filtersjb/../FGFCS.h FGModel.h FGLGear.h \
|
|
||||||
FGConfigFile.h FGMatrix.h FGFDMExec.h FGInitialCondition.h \
|
|
||||||
FGAtmosphere.h FGAircraft.h FGPropulsion.h FGRocket.h FGEngine.h \
|
|
||||||
FGState.h FGTranslation.h FGRotation.h FGPosition.h FGAerodynamics.h \
|
|
||||||
FGMassBalance.h FGCoefficient.h FGTable.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h \
|
|
||||||
FGNozzle.h filtersjb/FGFilter.h filtersjb/../FGConfigFile.h \
|
|
||||||
filtersjb/FGDeadBand.h filtersjb/FGGain.h filtersjb/../FGTable.h \
|
|
||||||
filtersjb/FGGradient.h filtersjb/FGSwitch.h filtersjb/FGSummer.h \
|
|
||||||
filtersjb/FGFlaps.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGFCS.cpp
|
|
||||||
|
|
||||||
FGFDMExec.o: FGFDMExec.cpp FGFDMExec.h FGModel.h FGDefs.h \
|
|
||||||
FGInitialCondition.h FGAtmosphere.h FGMatrix.h FGState.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGConfigFile.h FGAircraft.h FGPropulsion.h FGRocket.h \
|
|
||||||
FGEngine.h FGTranslation.h FGRotation.h FGPosition.h FGAuxiliary.h \
|
|
||||||
FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGNozzle.h FGMassBalance.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGFactorGroup.h FGInertial.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGFDMExec.cpp
|
|
||||||
|
|
||||||
FGFactorGroup.o: FGFactorGroup.cpp FGCoefficient.h FGConfigFile.h \
|
|
||||||
FGDefs.h FGTable.h FGFactorGroup.h FGAerodynamics.h FGModel.h \
|
|
||||||
FGState.h FGInitialCondition.h FGFDMExec.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGAircraft.h FGPropulsion.h FGRocket.h \
|
|
||||||
FGEngine.h FGTranslation.h FGRotation.h FGPosition.h FGAuxiliary.h \
|
|
||||||
FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h \
|
|
||||||
FGNozzle.h FGMassBalance.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGFactorGroup.cpp
|
|
||||||
|
|
||||||
FGForce.o: FGForce.cpp FGFDMExec.h FGModel.h FGDefs.h \
|
|
||||||
FGInitialCondition.h FGAtmosphere.h FGMatrix.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGState.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGConfigFile.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGTranslation.h FGAerodynamics.h FGCoefficient.h FGTable.h \
|
|
||||||
FGFactorGroup.h FGOutput.h FGfdmSocket.h FGAuxiliary.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGNozzle.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGForce.cpp
|
|
||||||
|
|
||||||
FGGroundReactions.o: FGGroundReactions.cpp FGGroundReactions.h \
|
|
||||||
FGModel.h FGDefs.h FGConfigFile.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGGroundReactions.cpp
|
|
||||||
|
|
||||||
FGInertial.o: FGInertial.cpp FGInertial.h FGModel.h FGDefs.h \
|
|
||||||
FGConfigFile.h FGMatrix.h FGPosition.h FGMassBalance.h FGPropulsion.h \
|
|
||||||
FGRocket.h FGEngine.h FGState.h FGInitialCondition.h FGFDMExec.h \
|
|
||||||
FGAtmosphere.h FGFCS.h filtersjb/FGFCSComponent.h \
|
|
||||||
filtersjb/../FGDefs.h filtersjb/../FGFCS.h FGLGear.h FGAircraft.h \
|
|
||||||
FGRotation.h FGTranslation.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGTable.h FGFactorGroup.h FGOutput.h FGfdmSocket.h FGAuxiliary.h \
|
|
||||||
FGPiston.h FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h \
|
|
||||||
FGPropeller.h FGThruster.h FGForce.h FGNozzle.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGInertial.cpp
|
|
||||||
|
|
||||||
FGInitialCondition.o: FGInitialCondition.cpp FGInitialCondition.h \
|
|
||||||
FGFDMExec.h FGModel.h FGDefs.h FGAtmosphere.h FGMatrix.h FGState.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGRotation.h \
|
|
||||||
FGPosition.h FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGTable.h FGNozzle.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGInitialCondition.cpp
|
|
||||||
|
|
||||||
FGLGear.o: FGLGear.cpp FGLGear.h FGConfigFile.h FGDefs.h FGMatrix.h \
|
|
||||||
FGFDMExec.h FGModel.h FGInitialCondition.h FGAtmosphere.h \
|
|
||||||
FGAircraft.h FGPropulsion.h FGRocket.h FGEngine.h FGState.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGTranslation.h FGRotation.h FGPosition.h FGAerodynamics.h \
|
|
||||||
FGMassBalance.h FGCoefficient.h FGTable.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h \
|
|
||||||
FGNozzle.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGLGear.cpp
|
|
||||||
|
|
||||||
FGMassBalance.o: FGMassBalance.cpp FGMassBalance.h FGModel.h FGDefs.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGState.h FGInitialCondition.h \
|
|
||||||
FGFDMExec.h FGAtmosphere.h FGMatrix.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGConfigFile.h FGAircraft.h FGPosition.h FGRotation.h \
|
|
||||||
FGTranslation.h FGAerodynamics.h FGCoefficient.h FGTable.h \
|
|
||||||
FGFactorGroup.h FGOutput.h FGfdmSocket.h FGAuxiliary.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGNozzle.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGMassBalance.cpp
|
|
||||||
|
|
||||||
FGMatrix.o: FGMatrix.cpp FGMatrix.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGMatrix.cpp
|
|
||||||
|
|
||||||
FGModel.o: FGModel.cpp FGModel.h FGDefs.h FGState.h \
|
|
||||||
FGInitialCondition.h FGFDMExec.h FGAtmosphere.h FGMatrix.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGConfigFile.h FGAircraft.h FGPropulsion.h FGRocket.h \
|
|
||||||
FGEngine.h FGTranslation.h FGRotation.h FGPosition.h FGAuxiliary.h \
|
|
||||||
FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGNozzle.h FGMassBalance.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGFactorGroup.h FGInertial.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGModel.cpp
|
|
||||||
|
|
||||||
FGNozzle.o: FGNozzle.cpp FGNozzle.h FGThruster.h FGForce.h FGFDMExec.h \
|
|
||||||
FGModel.h FGDefs.h FGInitialCondition.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGConfigFile.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGNozzle.cpp
|
|
||||||
|
|
||||||
FGOutput.o: FGOutput.cpp FGOutput.h FGModel.h FGDefs.h FGfdmSocket.h \
|
|
||||||
FGState.h FGInitialCondition.h FGFDMExec.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGRotation.h \
|
|
||||||
FGPosition.h FGAuxiliary.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGNozzle.h FGMassBalance.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGOutput.cpp
|
|
||||||
|
|
||||||
FGPiston.o: FGPiston.cpp FGDefs.h FGPiston.h FGEngine.h FGState.h \
|
|
||||||
FGInitialCondition.h FGFDMExec.h FGModel.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGTurboShaft.h FGTurboJet.h FGTurboProp.h \
|
|
||||||
FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGTranslation.h FGNozzle.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGPiston.cpp
|
|
||||||
|
|
||||||
FGPosition.o: FGPosition.cpp FGPosition.h FGModel.h FGDefs.h \
|
|
||||||
FGMatrix.h FGAtmosphere.h FGState.h FGInitialCondition.h FGFDMExec.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGRotation.h \
|
|
||||||
FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h \
|
|
||||||
FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h \
|
|
||||||
FGForce.h FGTable.h FGNozzle.h FGMassBalance.h FGAerodynamics.h \
|
|
||||||
FGCoefficient.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGPosition.cpp
|
|
||||||
|
|
||||||
FGPropeller.o: FGPropeller.cpp FGPropeller.h FGThruster.h FGForce.h \
|
|
||||||
FGFDMExec.h FGModel.h FGDefs.h FGInitialCondition.h FGAtmosphere.h \
|
|
||||||
FGMatrix.h FGConfigFile.h FGTable.h FGTranslation.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGPropeller.cpp
|
|
||||||
|
|
||||||
FGPropulsion.o: FGPropulsion.cpp FGPropulsion.h FGModel.h FGDefs.h \
|
|
||||||
FGRocket.h FGEngine.h FGState.h FGInitialCondition.h FGFDMExec.h \
|
|
||||||
FGAtmosphere.h FGMatrix.h FGFCS.h filtersjb/FGFCSComponent.h \
|
|
||||||
filtersjb/../FGDefs.h filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h \
|
|
||||||
FGAircraft.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGTranslation.h FGAerodynamics.h FGCoefficient.h FGTable.h \
|
|
||||||
FGFactorGroup.h FGOutput.h FGfdmSocket.h FGAuxiliary.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGNozzle.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGPropulsion.cpp
|
|
||||||
|
|
||||||
FGRocket.o: FGRocket.cpp FGDefs.h FGRocket.h FGEngine.h FGState.h \
|
|
||||||
FGInitialCondition.h FGFDMExec.h FGModel.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGPiston.h FGTurboShaft.h FGTurboJet.h FGTurboProp.h \
|
|
||||||
FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGTranslation.h FGNozzle.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGRocket.cpp
|
|
||||||
|
|
||||||
FGRotation.o: FGRotation.cpp FGRotation.h FGModel.h FGDefs.h \
|
|
||||||
FGMatrix.h FGAtmosphere.h FGState.h FGInitialCondition.h FGFDMExec.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGPosition.h \
|
|
||||||
FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h \
|
|
||||||
FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h \
|
|
||||||
FGForce.h FGTable.h FGNozzle.h FGMassBalance.h FGAerodynamics.h \
|
|
||||||
FGCoefficient.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGRotation.cpp
|
|
||||||
|
|
||||||
FGRotor.o: FGRotor.cpp FGRotor.h FGThruster.h FGForce.h FGFDMExec.h \
|
|
||||||
FGModel.h FGDefs.h FGInitialCondition.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGConfigFile.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGRotor.cpp
|
|
||||||
|
|
||||||
FGState.o: FGState.cpp FGState.h FGDefs.h FGInitialCondition.h \
|
|
||||||
FGFDMExec.h FGModel.h FGAtmosphere.h FGMatrix.h FGFCS.h \
|
|
||||||
filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h filtersjb/../FGFCS.h \
|
|
||||||
FGLGear.h FGConfigFile.h FGAircraft.h FGPropulsion.h FGRocket.h \
|
|
||||||
FGEngine.h FGTranslation.h FGRotation.h FGPosition.h FGAuxiliary.h \
|
|
||||||
FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGNozzle.h FGMassBalance.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGState.cpp
|
|
||||||
|
|
||||||
FGTable.o: FGTable.cpp FGTable.h FGConfigFile.h FGDefs.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTable.cpp
|
|
||||||
|
|
||||||
FGTank.o: FGTank.cpp FGDefs.h FGTank.h FGConfigFile.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTank.cpp
|
|
||||||
|
|
||||||
FGThruster.o: FGThruster.cpp FGThruster.h FGForce.h FGFDMExec.h \
|
|
||||||
FGModel.h FGDefs.h FGInitialCondition.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGConfigFile.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGThruster.cpp
|
|
||||||
|
|
||||||
FGTranslation.o: FGTranslation.cpp FGTranslation.h FGModel.h FGDefs.h \
|
|
||||||
FGMatrix.h FGRotation.h FGAtmosphere.h FGState.h FGInitialCondition.h \
|
|
||||||
FGFDMExec.h FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGPosition.h FGAuxiliary.h \
|
|
||||||
FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGNozzle.h FGMassBalance.h FGAerodynamics.h FGCoefficient.h \
|
|
||||||
FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTranslation.cpp
|
|
||||||
|
|
||||||
FGTrim.o: FGTrim.cpp FGFDMExec.h FGModel.h FGDefs.h \
|
|
||||||
FGInitialCondition.h FGAtmosphere.h FGMatrix.h FGTrim.h FGRotation.h \
|
|
||||||
FGState.h FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGPosition.h \
|
|
||||||
FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h \
|
|
||||||
FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h \
|
|
||||||
FGForce.h FGTable.h FGNozzle.h FGMassBalance.h FGAerodynamics.h \
|
|
||||||
FGCoefficient.h FGFactorGroup.h FGTrimAxis.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTrim.cpp
|
|
||||||
|
|
||||||
FGTrimAxis.o: FGTrimAxis.cpp FGFDMExec.h FGModel.h FGDefs.h \
|
|
||||||
FGInitialCondition.h FGAtmosphere.h FGMatrix.h FGTrimAxis.h \
|
|
||||||
FGRotation.h FGState.h FGFCS.h filtersjb/FGFCSComponent.h \
|
|
||||||
filtersjb/../FGDefs.h filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h \
|
|
||||||
FGAircraft.h FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h \
|
|
||||||
FGPosition.h FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGTable.h FGNozzle.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTrimAxis.cpp
|
|
||||||
|
|
||||||
FGTurboJet.o: FGTurboJet.cpp FGTurboJet.h FGEngine.h FGState.h \
|
|
||||||
FGDefs.h FGInitialCondition.h FGFDMExec.h FGModel.h FGAtmosphere.h \
|
|
||||||
FGMatrix.h FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGPiston.h FGTurboShaft.h FGTurboProp.h \
|
|
||||||
FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGTranslation.h FGNozzle.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTurboJet.cpp
|
|
||||||
|
|
||||||
FGTurboProp.o: FGTurboProp.cpp FGTurboProp.h FGEngine.h FGState.h \
|
|
||||||
FGDefs.h FGInitialCondition.h FGFDMExec.h FGModel.h FGAtmosphere.h \
|
|
||||||
FGMatrix.h FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGPiston.h FGTurboShaft.h FGTurboJet.h \
|
|
||||||
FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGTranslation.h FGNozzle.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTurboProp.cpp
|
|
||||||
|
|
||||||
FGTurboShaft.o: FGTurboShaft.cpp FGTurboShaft.h FGEngine.h FGState.h \
|
|
||||||
FGDefs.h FGInitialCondition.h FGFDMExec.h FGModel.h FGAtmosphere.h \
|
|
||||||
FGMatrix.h FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGPiston.h FGTurboJet.h FGTurboProp.h \
|
|
||||||
FGTank.h FGPropeller.h FGThruster.h FGForce.h FGTable.h \
|
|
||||||
FGTranslation.h FGNozzle.h FGPosition.h FGRotation.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h FGOutput.h \
|
|
||||||
FGfdmSocket.h FGAuxiliary.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGTurboShaft.cpp
|
|
||||||
|
|
||||||
FGUtility.o: FGUtility.cpp FGUtility.h FGState.h FGDefs.h \
|
|
||||||
FGInitialCondition.h FGFDMExec.h FGModel.h FGAtmosphere.h FGMatrix.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGRotation.h \
|
|
||||||
FGPosition.h FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h \
|
|
||||||
FGTurboShaft.h FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h \
|
|
||||||
FGThruster.h FGForce.h FGTable.h FGNozzle.h FGMassBalance.h \
|
|
||||||
FGAerodynamics.h FGCoefficient.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGUtility.cpp
|
|
||||||
|
|
||||||
FGfdmSocket.o: FGfdmSocket.cpp FGfdmSocket.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c FGfdmSocket.cpp
|
|
||||||
|
|
||||||
JSBSim.o: JSBSim.cpp FGFDMExec.h FGModel.h FGDefs.h \
|
|
||||||
FGInitialCondition.h FGAtmosphere.h FGMatrix.h FGRotation.h FGState.h \
|
|
||||||
FGFCS.h filtersjb/FGFCSComponent.h filtersjb/../FGDefs.h \
|
|
||||||
filtersjb/../FGFCS.h FGLGear.h FGConfigFile.h FGAircraft.h \
|
|
||||||
FGPropulsion.h FGRocket.h FGEngine.h FGTranslation.h FGPosition.h \
|
|
||||||
FGAuxiliary.h FGOutput.h FGfdmSocket.h FGPiston.h FGTurboShaft.h \
|
|
||||||
FGTurboJet.h FGTurboProp.h FGTank.h FGPropeller.h FGThruster.h \
|
|
||||||
FGForce.h FGTable.h FGNozzle.h FGMassBalance.h FGAerodynamics.h \
|
|
||||||
FGCoefficient.h FGFactorGroup.h
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c JSBSim.cpp
|
|
||||||
|
|
||||||
|
|
||||||
x15trim.o:x15trim.cpp
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) -c x15trim.cpp
|
|
||||||
|
|
||||||
x15trim:$(JSBSim_objects) x15trim.o libFCSComponents.a
|
|
||||||
$(CC) $(INCLUDES) $(CCOPTS) $(LINKDIR) $(JSBSim_objects) x15trim.o -ox15trim -lm -lFCSComponents
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-mv *.*~ backup
|
|
||||||
-rm *.o
|
|
||||||
|
|
||||||
all:
|
|
||||||
touch *.cpp
|
|
||||||
cd filtersjb; make all -fMakefile.solo; cd ..
|
|
||||||
make JSBSim -fMakefile.solo
|
|
||||||
|
|
||||||
debug:
|
|
||||||
touch *.cpp
|
|
||||||
touch filtersjb/*.cpp
|
|
||||||
cd filtersjb; make debug CCOPTS=-g -fMakefile.solo; cd ..
|
|
||||||
make JSBSim CCOPTS=-g -fMakefile.solo
|
|
|
@ -1,76 +0,0 @@
|
||||||
Contents
|
|
||||||
--------
|
|
||||||
|
|
||||||
1) Introduction
|
|
||||||
2) Building with autoconf/automake
|
|
||||||
3) Contact
|
|
||||||
|
|
||||||
|
|
||||||
1) Introduction
|
|
||||||
---------------
|
|
||||||
|
|
||||||
JSBSim is a multi-platform, general purpose object-oriented Flight
|
|
||||||
Dynamics Model (FDM) written in C++. Jon Berndt and Tony Peden began
|
|
||||||
about mid-1998 writing JSBSim. As of this writing it is the default
|
|
||||||
FDM for FlightGear. JSBSim can also be run in a standalone batch mode
|
|
||||||
for testing and study. More information on JSBSim can be found at the
|
|
||||||
JSBSim home page here:
|
|
||||||
|
|
||||||
http://jsbsim.sourceforge.net
|
|
||||||
|
|
||||||
The standalone version of JSBSim can be easily built from the command
|
|
||||||
line of a unix or unix-like (CygWin/Linux/Unix/IRIX, etc.) system like
|
|
||||||
this:
|
|
||||||
|
|
||||||
make -fMakefile.solo
|
|
||||||
|
|
||||||
If you are on an IRIX machine you can use the Makefile.irix makefile.
|
|
||||||
Directions are also provided below for using traditional auto* utilities
|
|
||||||
also provided with JSBSim.
|
|
||||||
|
|
||||||
|
|
||||||
2) Building with autoconf/automake
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
Unpack the distribution tarball (if needed - CVS users will have
|
|
||||||
downloaded the code directly) using your preferred method, and change
|
|
||||||
to the working directory. For example :
|
|
||||||
|
|
||||||
$ tar xvfz JSBSim-0.1.2.tar.gz
|
|
||||||
$ cd JSBSim-0.1.2
|
|
||||||
|
|
||||||
NOTE for CVS users: If you are using JSBSim from a CVS checkout, or
|
|
||||||
snapshot, you will need to create the initial configure script. The
|
|
||||||
commands to do this have been included in the 'autogen.sh' script, so
|
|
||||||
just :
|
|
||||||
|
|
||||||
$ ./autogen.sh
|
|
||||||
|
|
||||||
If you wish to customise your version of JSBSim, use the following to
|
|
||||||
determine any build-time options you may be interested in.
|
|
||||||
|
|
||||||
$ ./configure --help
|
|
||||||
|
|
||||||
Then :
|
|
||||||
|
|
||||||
$ ./configure
|
|
||||||
|
|
||||||
This will check your system platform, compiler and other local
|
|
||||||
configuration variables needed to build JSBSim, and generates the
|
|
||||||
necessary Makefiles. Next :
|
|
||||||
|
|
||||||
$ make
|
|
||||||
|
|
||||||
Will compile the various classes, and link the library. Finally :
|
|
||||||
|
|
||||||
$ make install
|
|
||||||
|
|
||||||
Unless specified otherwise (with --prefix configure option), this will
|
|
||||||
install 'JSBSim.a' into '/usr/local/lib'.
|
|
||||||
|
|
||||||
|
|
||||||
3) Contact
|
|
||||||
----------
|
|
||||||
|
|
||||||
For more information on JSBSim contact Jon Berndt at jsbsim@hal-pc.org.
|
|
||||||
|
|
1077
src/FDM/JSBSim/initialization/FGInitialCondition.cpp
Normal file
1077
src/FDM/JSBSim/initialization/FGInitialCondition.cpp
Normal file
File diff suppressed because it is too large
Load diff
328
src/FDM/JSBSim/initialization/FGInitialCondition.h
Normal file
328
src/FDM/JSBSim/initialization/FGInitialCondition.h
Normal file
|
@ -0,0 +1,328 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGInitialCondition.h
|
||||||
|
Author: Tony Peden
|
||||||
|
Date started: 7/1/99
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
7/1/99 TP Created
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
The purpose of this class is to take a set of initial conditions and provide
|
||||||
|
a kinematically consistent set of body axis velocity components, euler
|
||||||
|
angles, and altitude. This class does not attempt to trim the model i.e.
|
||||||
|
the sim will most likely start in a very dynamic state (unless, of course,
|
||||||
|
you have chosen your IC's wisely) even after setting it up with this class.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGINITIALCONDITION_H
|
||||||
|
#define FGINITIALCONDITION_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <FGFDMExec.h>
|
||||||
|
#include <FGJSBBase.h>
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_INITIALCONDITION "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
|
||||||
|
typedef enum { setwned, setwmd, setwhc } windset;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Takes a set of initial conditions and provide a kinematically consistent set
|
||||||
|
of body axis velocity components, euler angles, and altitude. This class
|
||||||
|
does not attempt to trim the model i.e. the sim will most likely start in a
|
||||||
|
very dynamic state (unless, of course, you have chosen your IC's wisely)
|
||||||
|
even after setting it up with this class.
|
||||||
|
|
||||||
|
USAGE NOTES
|
||||||
|
|
||||||
|
With a valid object of FGFDMExec and an aircraft model loaded
|
||||||
|
FGInitialCondition fgic=new FGInitialCondition(FDMExec);
|
||||||
|
fgic->SetVcalibratedKtsIC()
|
||||||
|
fgic->SetAltitudeFtIC();
|
||||||
|
|
||||||
|
//to directly into Run
|
||||||
|
FDMExec->GetState()->Initialize(fgic)
|
||||||
|
delete fgic;
|
||||||
|
FDMExec->Run()
|
||||||
|
|
||||||
|
//or to loop the sim w/o integrating
|
||||||
|
FDMExec->RunIC(fgic)
|
||||||
|
|
||||||
|
Speed:
|
||||||
|
|
||||||
|
Since vc, ve, vt, and mach all represent speed, the remaining
|
||||||
|
three are recalculated each time one of them is set (using the
|
||||||
|
current altitude). The most recent speed set is remembered so
|
||||||
|
that if and when altitude is reset, the last set speed is used
|
||||||
|
to recalculate the remaining three. Setting any of the body
|
||||||
|
components forces a recalculation of vt and vt then becomes the
|
||||||
|
most recent speed set.
|
||||||
|
|
||||||
|
Alpha,Gamma, and Theta:
|
||||||
|
|
||||||
|
This class assumes that it will be used to set up the sim for a
|
||||||
|
steady, zero pitch rate condition. Since any two of those angles
|
||||||
|
specifies the third gamma (flight path angle) is favored when setting
|
||||||
|
alpha and theta and alpha is favored when setting gamma. i.e.
|
||||||
|
|
||||||
|
- set alpha : recalculate theta using gamma as currently set
|
||||||
|
- set theta : recalculate alpha using gamma as currently set
|
||||||
|
- set gamma : recalculate theta using alpha as currently set
|
||||||
|
|
||||||
|
The idea being that gamma is most interesting to pilots (since it
|
||||||
|
is indicative of climb rate).
|
||||||
|
|
||||||
|
Setting climb rate is, for the purpose of this discussion,
|
||||||
|
considered equivalent to setting gamma.
|
||||||
|
|
||||||
|
These are the items that can be set in an initialization file:
|
||||||
|
|
||||||
|
UBODY <velocity, ft/sec>
|
||||||
|
VBODY <velocity, ft/sec>
|
||||||
|
WBODY <velocity, ft/sec>
|
||||||
|
LATITUDE <position, degrees>
|
||||||
|
LONGITUDE <position, degrees>
|
||||||
|
PHI <orientation, degrees>
|
||||||
|
THETA <orientation, degrees>
|
||||||
|
PSI <orientation, degrees>
|
||||||
|
ALPHA <angle, degrees>
|
||||||
|
BETA <angle, degrees>
|
||||||
|
GAMMA <angle, degrees>
|
||||||
|
ROC <vertical velocity, ft/sec>
|
||||||
|
ALTITUDE <altitude, ft>
|
||||||
|
WINDDIR <wind from-angle, degrees>
|
||||||
|
VWIND <magnitude wind speed, ft/sec>
|
||||||
|
HWIND <headwind speed, knots>
|
||||||
|
XWIND <crosswind speed, knots>
|
||||||
|
VC <calibrated airspeed, ft/sec>
|
||||||
|
MACH <mach>
|
||||||
|
VGROUND <ground speed, ft/sec>
|
||||||
|
RUNNING <0 or 1>
|
||||||
|
|
||||||
|
|
||||||
|
@author Tony Peden
|
||||||
|
@version "$Id$"
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGInitialCondition : public FGJSBBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
FGInitialCondition(FGFDMExec *fdmex);
|
||||||
|
/// Destructor
|
||||||
|
~FGInitialCondition();
|
||||||
|
|
||||||
|
void SetVcalibratedKtsIC(double tt);
|
||||||
|
void SetVequivalentKtsIC(double tt);
|
||||||
|
inline void SetVtrueKtsIC(double tt) { SetVtrueFpsIC(tt*ktstofps); }
|
||||||
|
inline void SetVgroundKtsIC(double tt) { SetVgroundFpsIC(tt*ktstofps); }
|
||||||
|
void SetMachIC(double tt);
|
||||||
|
|
||||||
|
inline void SetAlphaDegIC(double tt) { SetAlphaRadIC(tt*degtorad); }
|
||||||
|
inline void SetBetaDegIC(double tt) { SetBetaRadIC(tt*degtorad);}
|
||||||
|
|
||||||
|
inline void SetPitchAngleDegIC(double tt) { SetPitchAngleRadIC(tt*degtorad); }
|
||||||
|
inline void SetRollAngleDegIC(double tt) { SetRollAngleRadIC(tt*degtorad);}
|
||||||
|
inline void SetTrueHeadingDegIC(double tt){ SetTrueHeadingRadIC(tt*degtorad); }
|
||||||
|
|
||||||
|
void SetClimbRateFpmIC(double tt);
|
||||||
|
inline void SetFlightPathAngleDegIC(double tt) { SetFlightPathAngleRadIC(tt*degtorad); }
|
||||||
|
|
||||||
|
void SetAltitudeFtIC(double tt);
|
||||||
|
void SetAltitudeAGLFtIC(double tt);
|
||||||
|
|
||||||
|
void SetSeaLevelRadiusFtIC(double tt);
|
||||||
|
void SetTerrainAltitudeFtIC(double tt);
|
||||||
|
|
||||||
|
inline void SetLatitudeDegIC(double tt) { latitude=tt*degtorad; }
|
||||||
|
inline void SetLongitudeDegIC(double tt) { longitude=tt*degtorad; }
|
||||||
|
|
||||||
|
|
||||||
|
inline double GetVcalibratedKtsIC(void) const { return vc*fpstokts; }
|
||||||
|
inline double GetVequivalentKtsIC(void) const { return ve*fpstokts; }
|
||||||
|
inline double GetVgroundKtsIC(void) const { return vg*fpstokts; }
|
||||||
|
inline double GetVtrueKtsIC(void) const { return vt*fpstokts; }
|
||||||
|
inline double GetMachIC(void) const { return mach; }
|
||||||
|
|
||||||
|
inline double GetClimbRateFpmIC(void) const { return hdot*60; }
|
||||||
|
inline double GetFlightPathAngleDegIC(void)const { return gamma*radtodeg; }
|
||||||
|
|
||||||
|
inline double GetAlphaDegIC(void) const { return alpha*radtodeg; }
|
||||||
|
inline double GetBetaDegIC(void) const { return beta*radtodeg; }
|
||||||
|
|
||||||
|
inline double GetPitchAngleDegIC(void) const { return theta*radtodeg; }
|
||||||
|
inline double GetRollAngleDegIC(void) const { return phi*radtodeg; }
|
||||||
|
inline double GetHeadingDegIC(void) const { return psi*radtodeg; }
|
||||||
|
|
||||||
|
inline double GetLatitudeDegIC(void) const { return latitude*radtodeg; }
|
||||||
|
inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; }
|
||||||
|
|
||||||
|
inline double GetAltitudeFtIC(void) const { return altitude; }
|
||||||
|
inline double GetAltitudeAGLFtIC(void) const { return altitude - terrain_altitude; }
|
||||||
|
|
||||||
|
inline double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; }
|
||||||
|
inline double GetTerrainAltitudeFtIC(void) const { return terrain_altitude; }
|
||||||
|
|
||||||
|
void SetVgroundFpsIC(double tt);
|
||||||
|
void SetVtrueFpsIC(double tt);
|
||||||
|
void SetUBodyFpsIC(double tt);
|
||||||
|
void SetVBodyFpsIC(double tt);
|
||||||
|
void SetWBodyFpsIC(double tt);
|
||||||
|
void SetVnorthFpsIC(double tt);
|
||||||
|
void SetVeastFpsIC(double tt);
|
||||||
|
void SetVdownFpsIC(double tt);
|
||||||
|
void SetPRadpsIC(double tt) { p = tt; }
|
||||||
|
void SetQRadpsIC(double tt) { q = tt; }
|
||||||
|
void SetRRadpsIC(double tt) { r = tt; }
|
||||||
|
|
||||||
|
void SetWindNEDFpsIC(double wN, double wE, double wD);
|
||||||
|
|
||||||
|
void SetWindMagKtsIC(double mag);
|
||||||
|
void SetWindDirDegIC(double dir);
|
||||||
|
|
||||||
|
void SetHeadWindKtsIC(double head);
|
||||||
|
void SetCrossWindKtsIC(double cross);// positive from left
|
||||||
|
|
||||||
|
void SetWindDownKtsIC(double wD);
|
||||||
|
|
||||||
|
void SetClimbRateFpsIC(double tt);
|
||||||
|
inline double GetVgroundFpsIC(void) const { return vg; }
|
||||||
|
inline double GetVtrueFpsIC(void) const { return vt; }
|
||||||
|
inline double GetWindUFpsIC(void) const { return uw; }
|
||||||
|
inline double GetWindVFpsIC(void) const { return vw; }
|
||||||
|
inline double GetWindWFpsIC(void) const { return ww; }
|
||||||
|
inline double GetWindNFpsIC(void) const { return wnorth; }
|
||||||
|
inline double GetWindEFpsIC(void) const { return weast; }
|
||||||
|
inline double GetWindDFpsIC(void) const { return wdown; }
|
||||||
|
inline double GetWindFpsIC(void) const { return sqrt(wnorth*wnorth + weast*weast); }
|
||||||
|
double GetWindDirDegIC(void);
|
||||||
|
inline double GetClimbRateFpsIC(void) const { return hdot; }
|
||||||
|
double GetUBodyFpsIC(void) const;
|
||||||
|
double GetVBodyFpsIC(void) const;
|
||||||
|
double GetWBodyFpsIC(void) const;
|
||||||
|
double GetPRadpsIC() const { return p; }
|
||||||
|
double GetQRadpsIC() const { return q; }
|
||||||
|
double GetRRadpsIC() const { return r; }
|
||||||
|
void SetFlightPathAngleRadIC(double tt);
|
||||||
|
void SetAlphaRadIC(double tt);
|
||||||
|
void SetPitchAngleRadIC(double tt);
|
||||||
|
void SetBetaRadIC(double tt);
|
||||||
|
void SetRollAngleRadIC(double tt);
|
||||||
|
void SetTrueHeadingRadIC(double tt);
|
||||||
|
inline void SetLatitudeRadIC(double tt) { latitude=tt; }
|
||||||
|
inline void SetLongitudeRadIC(double tt) { longitude=tt; }
|
||||||
|
inline double GetFlightPathAngleRadIC(void) const { return gamma; }
|
||||||
|
inline double GetAlphaRadIC(void) const { return alpha; }
|
||||||
|
inline double GetPitchAngleRadIC(void) const { return theta; }
|
||||||
|
inline double GetBetaRadIC(void) const { return beta; }
|
||||||
|
inline double GetRollAngleRadIC(void) const { return phi; }
|
||||||
|
inline double GetHeadingRadIC(void) const { return psi; }
|
||||||
|
inline double GetLatitudeRadIC(void) const { return latitude; }
|
||||||
|
inline double GetLongitudeRadIC(void) const { return longitude; }
|
||||||
|
inline double GetThetaRadIC(void) const { return theta; }
|
||||||
|
inline double GetPhiRadIC(void) const { return phi; }
|
||||||
|
inline double GetPsiRadIC(void) const { return psi; }
|
||||||
|
|
||||||
|
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
|
||||||
|
inline windset GetWindSet(void) { return lastWindSet; }
|
||||||
|
|
||||||
|
bool Load(string rstname, bool useStoredPath = true );
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
double vt,vc,ve,vg;
|
||||||
|
double mach;
|
||||||
|
double altitude,hdot;
|
||||||
|
double latitude,longitude;
|
||||||
|
double u,v,w;
|
||||||
|
double p,q,r;
|
||||||
|
double uw,vw,ww;
|
||||||
|
double vnorth,veast,vdown;
|
||||||
|
double wnorth,weast,wdown;
|
||||||
|
double whead, wcross, wdir, wmag;
|
||||||
|
double sea_level_radius;
|
||||||
|
double terrain_altitude;
|
||||||
|
double radius_to_vehicle;
|
||||||
|
|
||||||
|
double alpha, beta, theta, phi, psi, gamma;
|
||||||
|
double salpha,sbeta,stheta,sphi,spsi,sgamma;
|
||||||
|
double calpha,cbeta,ctheta,cphi,cpsi,cgamma;
|
||||||
|
|
||||||
|
double xlo, xhi,xmin,xmax;
|
||||||
|
|
||||||
|
typedef double (FGInitialCondition::*fp)(double x);
|
||||||
|
fp sfunc;
|
||||||
|
|
||||||
|
speedset lastSpeedSet;
|
||||||
|
windset lastWindSet;
|
||||||
|
|
||||||
|
FGFDMExec *fdmex;
|
||||||
|
FGPropertyManager *PropertyManager;
|
||||||
|
|
||||||
|
bool getAlpha(void);
|
||||||
|
bool getTheta(void);
|
||||||
|
bool getMachFromVcas(double *Mach,double vcas);
|
||||||
|
|
||||||
|
double GammaEqOfTheta(double Theta);
|
||||||
|
double GammaEqOfAlpha(double Alpha);
|
||||||
|
double calcVcas(double Mach);
|
||||||
|
void calcUVWfromNED(void);
|
||||||
|
void calcWindUVW(void);
|
||||||
|
|
||||||
|
bool findInterval(double x,double guess);
|
||||||
|
bool solve(double *y, double x);
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -39,23 +39,22 @@ scheme. */
|
||||||
|
|
||||||
// !!!!!!! BEWARE ALL YE WHO ENTER HERE !!!!!!!
|
// !!!!!!! BEWARE ALL YE WHO ENTER HERE !!!!!!!
|
||||||
|
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "FGFDMExec.h"
|
#include <FGFDMExec.h>
|
||||||
#include "FGAtmosphere.h"
|
#include <models/FGAtmosphere.h>
|
||||||
#include "FGInitialCondition.h"
|
#include "FGInitialCondition.h"
|
||||||
#include "FGTrim.h"
|
#include "FGTrim.h"
|
||||||
#include "FGAircraft.h"
|
#include <models/FGAircraft.h>
|
||||||
#include "FGMassBalance.h"
|
#include <models/FGMassBalance.h>
|
||||||
#include "FGGroundReactions.h"
|
#include <models/FGGroundReactions.h>
|
||||||
#include "FGInertial.h"
|
#include <models/FGInertial.h>
|
||||||
#include "FGAerodynamics.h"
|
#include <models/FGAerodynamics.h>
|
||||||
#include "FGColumnVector3.h"
|
#include <math/FGColumnVector3.h>
|
||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
#pragma warning (disable : 4786 4788)
|
#pragma warning (disable : 4786 4788)
|
||||||
|
@ -241,7 +240,7 @@ bool FGTrim::DoTrim(void) {
|
||||||
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(false);
|
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fdmex->GetOutput()->Disable();
|
fdmex->DisableOutput();
|
||||||
|
|
||||||
fgic->SetPRadpsIC(0.0);
|
fgic->SetPRadpsIC(0.0);
|
||||||
fgic->SetQRadpsIC(0.0);
|
fgic->SetQRadpsIC(0.0);
|
||||||
|
@ -358,7 +357,7 @@ bool FGTrim::DoTrim(void) {
|
||||||
for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
||||||
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(true);
|
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(true);
|
||||||
}
|
}
|
||||||
fdmex->GetOutput()->Enable();
|
fdmex->EnableOutput();
|
||||||
return !trim_failed;
|
return !trim_failed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,9 +72,8 @@ FORWARD DECLARATIONS
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
typedef enum { tLongitudinal, tFull, tGround, tPullup,
|
typedef enum { tLongitudinal=0, tFull, tGround, tPullup,
|
||||||
tCustom, tNone, tTurn
|
tCustom, tTurn, tNone } TrimMode;
|
||||||
} TrimMode;
|
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
CLASS DOCUMENTATION
|
CLASS DOCUMENTATION
|
|
@ -36,20 +36,16 @@ INCLUDES
|
||||||
# pragma warning (disable : 4786)
|
# pragma warning (disable : 4786)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "FGFDMExec.h"
|
#include <FGFDMExec.h>
|
||||||
#include "FGAtmosphere.h"
|
#include <models/FGAtmosphere.h>
|
||||||
#include "FGInitialCondition.h"
|
#include "FGInitialCondition.h"
|
||||||
#include "FGTrimAxis.h"
|
#include "FGTrimAxis.h"
|
||||||
#include "FGAircraft.h"
|
#include <models/FGAircraft.h>
|
||||||
#include "FGPropulsion.h"
|
#include <models/FGPropulsion.h>
|
||||||
#include "FGAerodynamics.h"
|
#include <models/FGAerodynamics.h>
|
||||||
|
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
7
src/FDM/JSBSim/initialization/Makefile.am
Normal file
7
src/FDM/JSBSim/initialization/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
noinst_LIBRARIES = libInit.a
|
||||||
|
|
||||||
|
libInit_a_SOURCES = FGInitialCondition.cpp FGTrim.cpp FGTrimAxis.cpp
|
||||||
|
|
||||||
|
noinst_HEADERS = FGInitialCondition.h FGTrim.h FGTrimAxis.h
|
||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
|
74
src/FDM/JSBSim/input_output/FGGroundCallback.cpp
Normal file
74
src/FDM/JSBSim/input_output/FGGroundCallback.cpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGGroundCallback.cpp
|
||||||
|
Author: Mathias Froehlich
|
||||||
|
Date started: 05/21/04
|
||||||
|
|
||||||
|
------ Copyright (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) -------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
05/21/00 MF Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
#include <math/FGLocation.h>
|
||||||
|
#include "FGGroundCallback.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGGroundCallback::FGGroundCallback()
|
||||||
|
{
|
||||||
|
mReferenceRadius = 20925650.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGGroundCallback::~FGGroundCallback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGGroundCallback::GetAltitude(const FGLocation& loc) const
|
||||||
|
{
|
||||||
|
return loc.GetRadius() - mReferenceRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGGroundCallback::GetAGLevel(double t, const FGLocation& loc,
|
||||||
|
FGLocation& contact, FGColumnVector3& normal,
|
||||||
|
FGColumnVector3& vel) const
|
||||||
|
{
|
||||||
|
vel = FGColumnVector3(0.0, 0.0, 0.0);
|
||||||
|
normal = (-1/FGColumnVector3(loc).Magnitude())*FGColumnVector3(loc);
|
||||||
|
double radius = loc.GetRadius();
|
||||||
|
double agl = GetAltitude(loc);
|
||||||
|
contact = ((radius-agl)/radius)*FGColumnVector3(loc);
|
||||||
|
return agl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
87
src/FDM/JSBSim/input_output/FGGroundCallback.h
Normal file
87
src/FDM/JSBSim/input_output/FGGroundCallback.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGGroundCallback.h
|
||||||
|
Author: Mathias Froehlich
|
||||||
|
Date started: 05/21/04
|
||||||
|
|
||||||
|
------ Copyright (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) -------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
05/21/00 MF Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGGROUNDCALLBACK_H
|
||||||
|
#define FGGROUNDCALLBACK_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
#include <math/FGLocation.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_GROUNDCALLBACK "$Id$"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** This class provides callback slots to get ground specific data like
|
||||||
|
ground elevation and such.
|
||||||
|
There is a default implementation, which returns values for a
|
||||||
|
ball formed earth.
|
||||||
|
|
||||||
|
@author Mathias Froehlich
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGGroundCallback : public FGJSBBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGGroundCallback();
|
||||||
|
virtual ~FGGroundCallback();
|
||||||
|
|
||||||
|
/** Compute the altitude above sealevel. */
|
||||||
|
virtual double GetAltitude(const FGLocation& l) const;
|
||||||
|
/** Compute the altitude above ground. Defaults to sealevel altitude. */
|
||||||
|
virtual double GetAGLevel(double t, const FGLocation& l, FGLocation& cont,
|
||||||
|
FGColumnVector3& n, FGColumnVector3& v) const;
|
||||||
|
private:
|
||||||
|
/// Reference radius.
|
||||||
|
double mReferenceRadius;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
58
src/FDM/JSBSim/FGPropertyManager.cpp → src/FDM/JSBSim/input_output/FGPropertyManager.cpp
Normal file → Executable file
58
src/FDM/JSBSim/FGPropertyManager.cpp → src/FDM/JSBSim/input_output/FGPropertyManager.cpp
Normal file → Executable file
|
@ -61,11 +61,12 @@ string FGPropertyManager::mkPropertyName(string name, bool lowercase) {
|
||||||
else if( isspace(name[i]) )
|
else if( isspace(name[i]) )
|
||||||
name[i]='-';
|
name[i]='-';
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
for(i=0;i<name.length();i++) {
|
for(i=0;i<name.length();i++) {
|
||||||
if( name[i] == '/' )
|
if( name[i] == '/' )
|
||||||
name.erase(i,1);
|
name.erase(i,1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +76,9 @@ FGPropertyManager*
|
||||||
FGPropertyManager::GetNode (const string &path, bool create)
|
FGPropertyManager::GetNode (const string &path, bool create)
|
||||||
{
|
{
|
||||||
SGPropertyNode* node=this->getNode(path.c_str(), create);
|
SGPropertyNode* node=this->getNode(path.c_str(), create);
|
||||||
//if(node == 0)
|
if (node == 0 && !suppress_warning)
|
||||||
// cout << "FGPropertyManager::GetNode() No node found for "
|
cout << "FGPropertyManager::GetNode() No node found for "
|
||||||
// << path << endl;
|
<< path << endl;
|
||||||
return (FGPropertyManager*)node;
|
return (FGPropertyManager*)node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +95,11 @@ FGPropertyManager::GetNode (const string &relpath, int index, bool create)
|
||||||
|
|
||||||
bool FGPropertyManager::HasNode (const string &path)
|
bool FGPropertyManager::HasNode (const string &path)
|
||||||
{
|
{
|
||||||
return (GetNode(path, false) != 0);
|
// Checking if a node exists shouldn't write a warning if it doesn't exist
|
||||||
|
suppress_warning = true;
|
||||||
|
bool has_node = (GetNode(path, false) != 0);
|
||||||
|
suppress_warning = false;
|
||||||
|
return has_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -264,10 +269,10 @@ void FGPropertyManager::Untie (const string &name)
|
||||||
|
|
||||||
void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
|
void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer),
|
if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer), useDefault))
|
||||||
useDefault))
|
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||||
cout <<
|
else if (debug_lvl & 0x20)
|
||||||
"Failed to tie property " << name << " to a pointer" << endl;
|
cout << name << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -275,10 +280,10 @@ void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
|
||||||
void FGPropertyManager::Tie (const string &name, int *pointer,
|
void FGPropertyManager::Tie (const string &name, int *pointer,
|
||||||
bool useDefault )
|
bool useDefault )
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(), SGRawValuePointer<int>(pointer),
|
if (!tie(name.c_str(), SGRawValuePointer<int>(pointer), useDefault))
|
||||||
useDefault))
|
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||||
cout <<
|
else if (debug_lvl & 0x20)
|
||||||
"Failed to tie property " << name << " to a pointer" << endl;
|
cout << name << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -286,10 +291,10 @@ void FGPropertyManager::Tie (const string &name, int *pointer,
|
||||||
void FGPropertyManager::Tie (const string &name, long *pointer,
|
void FGPropertyManager::Tie (const string &name, long *pointer,
|
||||||
bool useDefault )
|
bool useDefault )
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(), SGRawValuePointer<long>(pointer),
|
if (!tie(name.c_str(), SGRawValuePointer<long>(pointer), useDefault))
|
||||||
useDefault))
|
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||||
cout <<
|
else if (debug_lvl & 0x20)
|
||||||
"Failed to tie property " << name << " to a pointer" << endl;
|
cout << name << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -297,21 +302,20 @@ void FGPropertyManager::Tie (const string &name, long *pointer,
|
||||||
void FGPropertyManager::Tie (const string &name, float *pointer,
|
void FGPropertyManager::Tie (const string &name, float *pointer,
|
||||||
bool useDefault )
|
bool useDefault )
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(), SGRawValuePointer<float>(pointer),
|
if (!tie(name.c_str(), SGRawValuePointer<float>(pointer), useDefault))
|
||||||
useDefault))
|
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||||
cout <<
|
else if (debug_lvl & 0x20)
|
||||||
"Failed to tie property " << name << " to a pointer" << endl;
|
cout << name << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGPropertyManager::Tie (const string &name, double *pointer,
|
void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
|
||||||
bool useDefault)
|
|
||||||
{
|
{
|
||||||
if (!tie(name.c_str(), SGRawValuePointer<double>(pointer),
|
if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault))
|
||||||
useDefault))
|
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||||
cout <<
|
else if (debug_lvl & 0x20)
|
||||||
"Failed to tie property " << name << " to a pointer" << endl;
|
cout << name << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace JSBSim
|
} // namespace JSBSim
|
|
@ -37,11 +37,13 @@ INCLUDES
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
#include <simgear/props/props.hxx>
|
# include <simgear/props/props.hxx>
|
||||||
#else
|
#else
|
||||||
#include "simgear/props/props.hxx"
|
# include "simgear/props/props.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "FGJSBBase.h"
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
@ -68,10 +70,13 @@ CLASS DOCUMENTATION
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
class FGPropertyManager : public SGPropertyNode {
|
class FGPropertyManager : public SGPropertyNode, public FGJSBBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool suppress_warning;
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
FGPropertyManager(void) {}
|
FGPropertyManager(void) {suppress_warning = false;}
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~FGPropertyManager(void) {}
|
~FGPropertyManager(void) {}
|
||||||
|
|
||||||
|
@ -500,15 +505,12 @@ class FGPropertyManager : public SGPropertyNode {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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))
|
cout << "Failed to tie property " << name << " to functions" << endl;
|
||||||
{
|
else if (debug_lvl & 0x20)
|
||||||
cout <<
|
cout << name << endl;
|
||||||
"Failed to tie property " << name << " to functions" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -527,19 +529,16 @@ class FGPropertyManager : public SGPropertyNode {
|
||||||
* @param getter The getter function, or 0 if the value is unreadable.
|
* @param getter The getter function, or 0 if the value is unreadable.
|
||||||
* @param setter The setter function, or 0 if the value is unmodifiable.
|
* @param setter The setter function, or 0 if the value is unmodifiable.
|
||||||
* @param useDefault true if the setter should be invoked with any existing
|
* @param useDefault true if the setter should be invoked with any existing
|
||||||
* property value should be; false if the old value should be
|
* property value should there be one; false if the old value should be
|
||||||
* discarded; defaults to true.
|
* discarded; defaults to true.
|
||||||
*/
|
*/
|
||||||
template <class V> inline void Tie (const string &name,
|
template <class V> inline void Tie (const string &name, int index, V (*getter)(int),
|
||||||
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(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
|
||||||
SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
|
cout << "Failed to tie property " << name << " to indexed functions" << endl;
|
||||||
{
|
else if (debug_lvl & 0x20)
|
||||||
cout <<
|
cout << name << endl;
|
||||||
"Failed to tie property " << name << " to indexed functions" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -566,12 +565,10 @@ class FGPropertyManager : public SGPropertyNode {
|
||||||
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), useDefault))
|
||||||
SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
|
cout << "Failed to tie property " << name << " to object methods" << endl;
|
||||||
{
|
else if (debug_lvl & 0x20)
|
||||||
cout <<
|
cout << name << endl;
|
||||||
"Failed to tie property " << name << " to object methods" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -594,16 +591,13 @@ class FGPropertyManager : public SGPropertyNode {
|
||||||
* discarded; defaults to true.
|
* 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,
|
Tie (const string &name, T * obj, int index, V (T::*getter)(int) const,
|
||||||
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
|
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, index, getter, setter), useDefault))
|
||||||
SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
|
cout << "Failed to tie property " << name << " to indexed object methods" << endl;
|
||||||
{
|
else if (debug_lvl & 0x20)
|
||||||
cout <<
|
cout << name << endl;
|
||||||
"Failed to tie property " << name << " to indexed object methods" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
225
src/FDM/JSBSim/FGScript.cpp → src/FDM/JSBSim/input_output/FGScript.cpp
Normal file → Executable file
225
src/FDM/JSBSim/FGScript.cpp → src/FDM/JSBSim/input_output/FGScript.cpp
Normal file → Executable file
|
@ -41,10 +41,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
# include <simgear/compiler.h>
|
# include <simgear/compiler.h>
|
||||||
# include STL_IOSTREAM
|
# include STL_IOSTREAM
|
||||||
|
@ -59,8 +55,8 @@ INCLUDES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "FGScript.h"
|
#include "FGScript.h"
|
||||||
#include "FGConfigFile.h"
|
#include "FGXMLParse.h"
|
||||||
#include "FGTrim.h"
|
#include <initialization/FGTrim.h>
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -95,134 +91,126 @@ FGScript::~FGScript()
|
||||||
|
|
||||||
bool FGScript::LoadScript( string script )
|
bool FGScript::LoadScript( string script )
|
||||||
{
|
{
|
||||||
FGConfigFile Script(script);
|
string aircraft="", initialize="", comparison = "", prop_name="";
|
||||||
string token="";
|
Element *document=0, *element=0, *run_element=0, *when_element=0;
|
||||||
string aircraft="";
|
Element *parameter_element=0, *set_element=0;
|
||||||
string initialize="";
|
|
||||||
string prop_name;
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
double dt = 0.0;
|
double dt = 0.0, value = 0.0;
|
||||||
|
FGXMLParse script_file_parser;
|
||||||
struct condition *newCondition;
|
struct condition *newCondition;
|
||||||
|
ifstream script_file(script.c_str());
|
||||||
|
|
||||||
if (!Script.IsOpen()) return false;
|
if ( !script_file ) return false;
|
||||||
|
|
||||||
Script.GetNextConfigLine();
|
readXML(script_file, script_file_parser);
|
||||||
if (Script.GetValue("runscript").length() <= 0) {
|
document = script_file_parser.GetDocument();
|
||||||
|
|
||||||
|
if (document->GetName() != string("runscript")) {
|
||||||
cerr << "File: " << script << " is not a script file" << endl;
|
cerr << "File: " << script << " is not a script file" << endl;
|
||||||
delete FDMExec;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ScriptName = Script.GetValue("name");
|
|
||||||
Scripted = true;
|
|
||||||
|
|
||||||
if (debug_lvl > 0) cout << "Reading and running from script file " << ScriptName << endl << endl;
|
// read aircraft and initialization files
|
||||||
|
|
||||||
while (Script.GetNextConfigLine() != string("EOF") && Script.GetValue() != string("/runscript")) {
|
element = document->FindElement("use");
|
||||||
token = Script.GetValue();
|
if (element) {
|
||||||
if (token == "use") {
|
aircraft = element->GetAttributeValue("aircraft");
|
||||||
if ((token = Script.GetValue("aircraft")) != string("")) {
|
if (!aircraft.empty()) {
|
||||||
aircraft = token;
|
result = FDMExec->LoadModel(aircraft);
|
||||||
result = FDMExec->LoadModel(aircraft);
|
if (!result) return false;
|
||||||
if (!result) {
|
|
||||||
cerr << "Aircraft file " << aircraft << " was not found" << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if (debug_lvl > 0) cout << " Use aircraft: " << token << endl;
|
|
||||||
} else if ((token = Script.GetValue("initialize")) != string("")) {
|
|
||||||
initialize = token;
|
|
||||||
if (debug_lvl > 0) cout << " Use reset file: " << token << endl;
|
|
||||||
} else {
|
|
||||||
cerr << "Unknown 'use' keyword: \"" << token << "\"" << endl;
|
|
||||||
}
|
|
||||||
} else if (token == "run") {
|
|
||||||
StartTime = strtod(Script.GetValue("start").c_str(), NULL);
|
|
||||||
State->Setsim_time(StartTime);
|
|
||||||
EndTime = strtod(Script.GetValue("end").c_str(), NULL);
|
|
||||||
dt = strtod(Script.GetValue("dt").c_str(), NULL);
|
|
||||||
State->Setdt(dt);
|
|
||||||
Script.GetNextConfigLine();
|
|
||||||
token = Script.GetValue();
|
|
||||||
while (token != string("/run")) {
|
|
||||||
|
|
||||||
if (token == "when") {
|
|
||||||
Script.GetNextConfigLine();
|
|
||||||
token = Script.GetValue();
|
|
||||||
newCondition = new struct condition();
|
|
||||||
while (token != string("/when")) {
|
|
||||||
if (token == "parameter") {
|
|
||||||
prop_name = Script.GetValue("name");
|
|
||||||
newCondition->TestParam.push_back( PropertyManager->GetNode(prop_name) );
|
|
||||||
newCondition->TestValue.push_back(strtod(Script.GetValue("value").c_str(), NULL));
|
|
||||||
newCondition->Comparison.push_back(Script.GetValue("comparison"));
|
|
||||||
} else if (token == "set") {
|
|
||||||
prop_name = Script.GetValue("name");
|
|
||||||
newCondition->SetParam.push_back( PropertyManager->GetNode(prop_name) );
|
|
||||||
newCondition->SetValue.push_back(strtod(Script.GetValue("value").c_str(), NULL));
|
|
||||||
newCondition->Triggered.push_back(false);
|
|
||||||
newCondition->OriginalValue.push_back(0.0);
|
|
||||||
newCondition->newValue.push_back(0.0);
|
|
||||||
newCondition->StartTime.push_back(0.0);
|
|
||||||
newCondition->EndTime.push_back(0.0);
|
|
||||||
string tempCompare = Script.GetValue("type");
|
|
||||||
if (tempCompare == "FG_DELTA") newCondition->Type.push_back(FG_DELTA);
|
|
||||||
else if (tempCompare == "FG_BOOL") newCondition->Type.push_back(FG_BOOL);
|
|
||||||
else if (tempCompare == "FG_VALUE") newCondition->Type.push_back(FG_VALUE);
|
|
||||||
else newCondition->Type.push_back((eType)0);
|
|
||||||
tempCompare = Script.GetValue("action");
|
|
||||||
if (tempCompare == "FG_RAMP") newCondition->Action.push_back(FG_RAMP);
|
|
||||||
else if (tempCompare == "FG_STEP") newCondition->Action.push_back(FG_STEP);
|
|
||||||
else if (tempCompare == "FG_EXP") newCondition->Action.push_back(FG_EXP);
|
|
||||||
else newCondition->Action.push_back((eAction)0);
|
|
||||||
|
|
||||||
if (Script.GetValue("persistent") == "true")
|
|
||||||
newCondition->Persistent.push_back(true);
|
|
||||||
else
|
|
||||||
newCondition->Persistent.push_back(false);
|
|
||||||
|
|
||||||
newCondition->TC.push_back(strtod(Script.GetValue("tc").c_str(), NULL));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cerr << "Unrecognized keyword in script file: \" [when] " << token << "\"" << endl;
|
|
||||||
}
|
|
||||||
Script.GetNextConfigLine();
|
|
||||||
token = Script.GetValue();
|
|
||||||
}
|
|
||||||
Conditions.push_back(*newCondition);
|
|
||||||
Script.GetNextConfigLine();
|
|
||||||
token = Script.GetValue();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cerr << "Error reading script file: expected \"when\", got \"" << token << "\"" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (token.empty()) {
|
|
||||||
// do nothing
|
|
||||||
} else {
|
} else {
|
||||||
cerr << "Unrecognized keyword in script file: \"" << token << "\" [runscript] " << endl;
|
cerr << "Aircraft must be specified first in script file." << endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
element = document->FindNextElement("use");
|
||||||
|
initialize = element->GetAttributeValue("initialize");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cerr << "No \"use\" directives in the script file." << endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aircraft == "") {
|
run_element = document->FindElement("run");
|
||||||
cerr << "Aircraft file not loaded in script" << endl;
|
|
||||||
exit(-1);
|
if (!run_element) {
|
||||||
|
cerr << "No \"run\" element found in script." << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sim timing
|
||||||
|
|
||||||
|
StartTime = run_element->GetAttributeValueAsNumber("start");
|
||||||
|
State->Setsim_time(StartTime);
|
||||||
|
EndTime = run_element->GetAttributeValueAsNumber("end");
|
||||||
|
dt = run_element->GetAttributeValueAsNumber("dt");
|
||||||
|
State->Setdt(dt);
|
||||||
|
|
||||||
|
// read "when" tests from script
|
||||||
|
|
||||||
|
when_element = run_element->FindElement("when");
|
||||||
|
while (when_element) { // "when" processing
|
||||||
|
newCondition = new struct condition();
|
||||||
|
|
||||||
|
// read parameters
|
||||||
|
parameter_element = when_element->FindElement("parameter");
|
||||||
|
while (parameter_element) {
|
||||||
|
prop_name = parameter_element->GetAttributeValue("name");
|
||||||
|
newCondition->TestParam.push_back( PropertyManager->GetNode(prop_name) );
|
||||||
|
value = parameter_element->GetAttributeValueAsNumber("value");
|
||||||
|
newCondition->TestValue.push_back(value);
|
||||||
|
comparison = parameter_element->GetAttributeValue("comparison");
|
||||||
|
newCondition->Comparison.push_back(comparison);
|
||||||
|
parameter_element = when_element->FindNextElement("parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read set definitions
|
||||||
|
set_element = when_element->FindElement("set");
|
||||||
|
while (set_element) {
|
||||||
|
prop_name = set_element->GetAttributeValue("name");
|
||||||
|
newCondition->SetParam.push_back( PropertyManager->GetNode(prop_name) );
|
||||||
|
value = set_element->GetAttributeValueAsNumber("value");
|
||||||
|
newCondition->SetValue.push_back(value);
|
||||||
|
newCondition->Triggered.push_back(false);
|
||||||
|
newCondition->OriginalValue.push_back(0.0);
|
||||||
|
newCondition->newValue.push_back(0.0);
|
||||||
|
newCondition->StartTime.push_back(0.0);
|
||||||
|
newCondition->EndTime.push_back(0.0);
|
||||||
|
string tempCompare = set_element->GetAttributeValue("type");
|
||||||
|
if (tempCompare == "FG_DELTA") newCondition->Type.push_back(FG_DELTA);
|
||||||
|
else if (tempCompare == "FG_BOOL") newCondition->Type.push_back(FG_BOOL);
|
||||||
|
else if (tempCompare == "FG_VALUE") newCondition->Type.push_back(FG_VALUE);
|
||||||
|
else newCondition->Type.push_back(FG_VALUE); // DEFAULT
|
||||||
|
tempCompare = set_element->GetAttributeValue("action");
|
||||||
|
if (tempCompare == "FG_RAMP") newCondition->Action.push_back(FG_RAMP);
|
||||||
|
else if (tempCompare == "FG_STEP") newCondition->Action.push_back(FG_STEP);
|
||||||
|
else if (tempCompare == "FG_EXP") newCondition->Action.push_back(FG_EXP);
|
||||||
|
else newCondition->Action.push_back(FG_STEP); // DEFAULT
|
||||||
|
|
||||||
|
if (set_element->GetAttributeValue("persistent") == "true")
|
||||||
|
newCondition->Persistent.push_back(true);
|
||||||
|
else
|
||||||
|
newCondition->Persistent.push_back(false); // DEFAULT
|
||||||
|
|
||||||
|
if (!set_element->GetAttributeValue("tc").empty())
|
||||||
|
newCondition->TC.push_back(set_element->GetAttributeValueAsNumber("tc"));
|
||||||
|
else
|
||||||
|
newCondition->TC.push_back(1.0); // DEFAULT
|
||||||
|
|
||||||
|
set_element = when_element->FindNextElement("set");
|
||||||
|
}
|
||||||
|
Conditions.push_back(*newCondition);
|
||||||
|
when_element = run_element->FindNextElement("when");
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(4);
|
Debug(4);
|
||||||
|
|
||||||
|
|
||||||
FGInitialCondition *IC=FDMExec->GetIC();
|
FGInitialCondition *IC=FDMExec->GetIC();
|
||||||
if ( ! IC->Load( initialize )) {
|
if ( ! IC->Load( initialize )) {
|
||||||
cerr << "Initialization unsuccessful" << endl;
|
cerr << "Initialization unsuccessful" << endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
/* comment this out for conversion capability
|
|
||||||
FGTrim fgt(FDMExec, tFull);
|
|
||||||
if ( !fgt.DoTrim() ) {
|
|
||||||
cout << "Trim Failed" << endl;
|
|
||||||
}
|
|
||||||
fgt.Report();
|
|
||||||
*/
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,18 +277,21 @@ bool FGScript::RunScript(void)
|
||||||
iC->StartTime[i] = currentTime;
|
iC->StartTime[i] = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double time_span = currentTime - iC->StartTime[i];
|
||||||
|
double value_span = iC->newValue[i] - iC->OriginalValue[i];
|
||||||
|
|
||||||
switch (iC->Action[i]) {
|
switch (iC->Action[i]) {
|
||||||
case FG_RAMP:
|
case FG_RAMP:
|
||||||
newSetValue = (currentTime - iC->StartTime[i])/(iC->TC[i])
|
if (time_span <= iC->TC[i])
|
||||||
* (iC->newValue[i] - iC->OriginalValue[i]) + iC->OriginalValue[i];
|
newSetValue = time_span/iC->TC[i] * value_span + iC->OriginalValue[i];
|
||||||
if (newSetValue > iC->newValue[i]) newSetValue = iC->newValue[i];
|
else
|
||||||
|
newSetValue = iC->newValue[i];
|
||||||
break;
|
break;
|
||||||
case FG_STEP:
|
case FG_STEP:
|
||||||
newSetValue = iC->newValue[i];
|
newSetValue = iC->newValue[i];
|
||||||
break;
|
break;
|
||||||
case FG_EXP:
|
case FG_EXP:
|
||||||
newSetValue = (1 - exp(-(currentTime - iC->StartTime[i])/(iC->TC[i])))
|
newSetValue = (1 - exp( -time_span/iC->TC[i] )) * value_span + iC->OriginalValue[i];
|
||||||
* (iC->newValue[i] - iC->OriginalValue[i]) + iC->OriginalValue[i];
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cerr << "Invalid Action specified" << endl;
|
cerr << "Invalid Action specified" << endl;
|
417
src/FDM/JSBSim/input_output/FGXMLElement.cpp
Executable file
417
src/FDM/JSBSim/input_output/FGXMLElement.cpp
Executable file
|
@ -0,0 +1,417 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 09/28/2004
|
||||||
|
Purpose: XML element class
|
||||||
|
Called by: FGXMLParse
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGXMLElement.h"
|
||||||
|
#ifdef FGFS
|
||||||
|
# ifndef __BORLANDC__
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# endif
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <cmath>
|
||||||
|
# include <cstdlib>
|
||||||
|
# else
|
||||||
|
# include <math.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if defined (sgi) && !defined(__GNUC__)
|
||||||
|
# include <math.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# else
|
||||||
|
# include <cmath>
|
||||||
|
# include <cstdlib>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_XMLELEMENT;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
Element::Element(string nm)
|
||||||
|
{
|
||||||
|
name = nm;
|
||||||
|
parent = 0L;
|
||||||
|
element_index = 0;
|
||||||
|
|
||||||
|
// convert ["from"]["to"] = factor, so: from * factor = to
|
||||||
|
convert["M"]["FT"] = 3.2808399;
|
||||||
|
convert["FT"]["M"] = 1.0/convert["M"]["FT"];
|
||||||
|
convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
|
||||||
|
convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
|
||||||
|
convert["FT"]["IN"] = 12.0;
|
||||||
|
convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
|
||||||
|
convert["LBS"]["KG"] = 0.45359237;
|
||||||
|
convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
|
||||||
|
convert["SLUG*FT2"]["KG*M2"] = 1.35594;
|
||||||
|
convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
|
||||||
|
convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926);
|
||||||
|
convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
|
||||||
|
convert["LBS/FT"]["N/M"] = 14.5939;
|
||||||
|
convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
|
||||||
|
convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
|
||||||
|
convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
|
||||||
|
convert["WATTS"]["HP"] = 0.001341022;
|
||||||
|
convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
|
||||||
|
convert["N"]["LBS"] = 0.22482;
|
||||||
|
convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
|
||||||
|
convert["KTS"]["FT/SEC"] = 1.68781;
|
||||||
|
convert["FT/SEC"]["KTS"] = 1.0/convert["KTS"]["FT/SEC"];
|
||||||
|
convert["FT*LBS"]["N*M"] = 1.35581795;
|
||||||
|
convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
|
||||||
|
|
||||||
|
convert["M"]["M"] = 1.00;
|
||||||
|
convert["FT"]["FT"] = 1.00;
|
||||||
|
convert["IN"]["IN"] = 1.00;
|
||||||
|
convert["IN3"]["IN3"] = 1.00;
|
||||||
|
convert["DEG"]["DEG"] = 1.00;
|
||||||
|
convert["RAD"]["RAD"] = 1.00;
|
||||||
|
convert["M2"]["M2"] = 1.00;
|
||||||
|
convert["FT2"]["FT2"] = 1.00;
|
||||||
|
convert["KG*M2"]["KG*M2"] = 1.00;
|
||||||
|
convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
|
||||||
|
convert["KG"]["KG"] = 1.00;
|
||||||
|
convert["LBS"]["LBS"] = 1.00;
|
||||||
|
convert["LBS/FT"]["LBS/FT"] = 1.00;
|
||||||
|
convert["LBS/SEC"]["LBS/SEC"] = 1.00;
|
||||||
|
convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
|
||||||
|
convert["N/M"]["N/M"] = 1.00;
|
||||||
|
convert["N/M/SEC"]["N/M/SEC"] = 1.00;
|
||||||
|
convert["PSI"]["PSI"] = 1.00;
|
||||||
|
convert["PSF"]["PSF"] = 1.00;
|
||||||
|
convert["INHG"]["INHG"] = 1.00;
|
||||||
|
convert["HP"]["HP"] = 1.00;
|
||||||
|
convert["N"]["N"] = 1.00;
|
||||||
|
convert["WATTS"]["WATTS"] = 1.00;
|
||||||
|
convert["LBS/SEC"]["LBS/SEC"] = 1.00;
|
||||||
|
convert["FT/SEC"]["FT/SEC"] = 1.00;
|
||||||
|
convert["KTS"]["KTS"] = 1.00;
|
||||||
|
convert["FT*LBS"]["FT*LBS"] = 1.00;
|
||||||
|
convert["N*M"]["N*M"] = 1.00;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Element::~Element(void)
|
||||||
|
{
|
||||||
|
for (int i=0; i<children.size(); i++) delete children[i];
|
||||||
|
data_lines.clear();
|
||||||
|
attributes.clear();
|
||||||
|
attribute_key.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string Element::GetAttributeValue(string attr)
|
||||||
|
{
|
||||||
|
int select=-1;
|
||||||
|
for (int i=0; i<attribute_key.size(); i++) {
|
||||||
|
if (attribute_key[i] == attr) select = i;
|
||||||
|
}
|
||||||
|
if (select < 0) return string("");
|
||||||
|
else return attributes[attr];
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double Element::GetAttributeValueAsNumber(string attr)
|
||||||
|
{
|
||||||
|
string attribute = GetAttributeValue(attr);
|
||||||
|
|
||||||
|
if (attribute.empty()) return 99e99;
|
||||||
|
else return (atof(attribute.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Element* Element::GetElement(int el)
|
||||||
|
{
|
||||||
|
if (children.size() > el) {
|
||||||
|
element_index = el;
|
||||||
|
return children[el];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
element_index = 0;
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Element* Element::GetNextElement(void)
|
||||||
|
{
|
||||||
|
if (children.size() > element_index+1) {
|
||||||
|
element_index++;
|
||||||
|
return children[element_index];
|
||||||
|
} else {
|
||||||
|
element_index = 0;
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string Element::GetDataLine(int i)
|
||||||
|
{
|
||||||
|
if (data_lines.size() > 0) return data_lines[i];
|
||||||
|
else return string("");
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double Element::GetDataAsNumber(void)
|
||||||
|
{
|
||||||
|
if (data_lines.size() == 1) {
|
||||||
|
return atof(data_lines[0].c_str());
|
||||||
|
} else {
|
||||||
|
return 99e99;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
int Element::GetNumElements(string element_name)
|
||||||
|
{
|
||||||
|
int number_of_elements=0;
|
||||||
|
Element* el=FindElement(element_name);
|
||||||
|
while (el) {
|
||||||
|
number_of_elements++;
|
||||||
|
el=FindNextElement(element_name);
|
||||||
|
}
|
||||||
|
return number_of_elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Element* Element::FindElement(string el)
|
||||||
|
{
|
||||||
|
if (el.empty() && children.size() >= 1) {
|
||||||
|
element_index = 1;
|
||||||
|
return children[0];
|
||||||
|
}
|
||||||
|
for (int i=0; i<children.size(); i++) {
|
||||||
|
if (el == children[i]->GetName()) {
|
||||||
|
element_index = i+1;
|
||||||
|
return children[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
element_index = 0;
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Element* Element::FindNextElement(string el)
|
||||||
|
{
|
||||||
|
if (el.empty()) {
|
||||||
|
if (element_index < children.size()) {
|
||||||
|
return children[element_index++];
|
||||||
|
} else {
|
||||||
|
element_index = 0;
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i=element_index; i<children.size(); i++) {
|
||||||
|
if (el == children[i]->GetName()) {
|
||||||
|
element_index = i+1;
|
||||||
|
return children[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
element_index = 0;
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double Element::FindElementValueAsNumber(string el)
|
||||||
|
{
|
||||||
|
Element* element = FindElement(el);
|
||||||
|
if (element) {
|
||||||
|
return element->GetDataAsNumber();
|
||||||
|
} else {
|
||||||
|
return 99e99;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string Element::FindElementValue(string el)
|
||||||
|
{
|
||||||
|
Element* element = FindElement(el);
|
||||||
|
if (element) {
|
||||||
|
return element->GetDataLine();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double Element::FindElementValueAsNumberConvertTo(string el, string target_units)
|
||||||
|
{
|
||||||
|
Element* element = FindElement(el);
|
||||||
|
double value;
|
||||||
|
string supplied_units="";
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
value = element->GetDataAsNumber();
|
||||||
|
supplied_units = element->GetAttributeValue("unit");
|
||||||
|
if (!supplied_units.empty()) {
|
||||||
|
if (convert.find(supplied_units) != convert.end()) {
|
||||||
|
if (convert[supplied_units].find(target_units) != convert[supplied_units].end()) {
|
||||||
|
value *= convert[supplied_units][target_units];
|
||||||
|
} else {
|
||||||
|
cerr << endl << "Target unit: \"" << target_units << "\" does not exist (typo?). Add new unit"
|
||||||
|
<< " conversion in FGXMLElement.cpp." << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
|
||||||
|
<< " conversion in FGXMLElement.cpp." << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 99e99;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double Element::FindElementValueAsNumberConvertFromTo( string el,
|
||||||
|
string supplied_units,
|
||||||
|
string target_units)
|
||||||
|
{
|
||||||
|
Element* element = FindElement(el);
|
||||||
|
double value;
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
value = element->GetDataAsNumber();
|
||||||
|
if (!supplied_units.empty()) {
|
||||||
|
if (convert.find(supplied_units) != convert.end()) {
|
||||||
|
if (convert[supplied_units].find(target_units) != convert[supplied_units].end()) {
|
||||||
|
value *= convert[supplied_units][target_units];
|
||||||
|
} else {
|
||||||
|
cerr << endl << "Target unit: \"" << target_units << "\" does not exist (typo?). Add new unit"
|
||||||
|
<< " conversion in FGXMLElement.cpp." << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
|
||||||
|
<< " conversion in FGXMLElement.cpp." << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 99e99;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGColumnVector3 Element::FindElementTripletConvertTo( string target_units)
|
||||||
|
{
|
||||||
|
FGColumnVector3 triplet;
|
||||||
|
Element* item;
|
||||||
|
double value=0.0;
|
||||||
|
string supplied_units = GetAttributeValue("unit");
|
||||||
|
|
||||||
|
item = FindElement("x");
|
||||||
|
if (!item) item = FindElement("roll");
|
||||||
|
if (item) {
|
||||||
|
value = item->GetDataAsNumber();
|
||||||
|
if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
|
||||||
|
} else {
|
||||||
|
value = 0.0;
|
||||||
|
cerr << "Could not find an X triplet item for this column vector." << endl;
|
||||||
|
}
|
||||||
|
triplet(1) = value;
|
||||||
|
|
||||||
|
item = FindElement("y");
|
||||||
|
if (!item) item = FindElement("pitch");
|
||||||
|
if (item) {
|
||||||
|
value = item->GetDataAsNumber();
|
||||||
|
if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
|
||||||
|
} else {
|
||||||
|
value = 0.0;
|
||||||
|
cerr << "Could not find a Y triplet item for this column vector." << endl;
|
||||||
|
}
|
||||||
|
triplet(2) = value;
|
||||||
|
|
||||||
|
item = FindElement("z");
|
||||||
|
if (!item) item = FindElement("yaw");
|
||||||
|
if (item) {
|
||||||
|
value = item->GetDataAsNumber();
|
||||||
|
if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
|
||||||
|
} else {
|
||||||
|
value = 0.0;
|
||||||
|
cerr << "Could not find a Z triplet item for this column vector." << endl;
|
||||||
|
}
|
||||||
|
triplet(3) = value;
|
||||||
|
|
||||||
|
return triplet;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void Element::Print(int level)
|
||||||
|
{
|
||||||
|
int i, spaces;
|
||||||
|
|
||||||
|
level+=2;
|
||||||
|
for (int spaces=0; spaces<=level; spaces++) cout << " "; // format output
|
||||||
|
cout << "Element Name: " << name;
|
||||||
|
for (int i=0; i<attributes.size(); i++) {
|
||||||
|
cout << " " << attribute_key[i] << " = " << attributes[attribute_key[i]];
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
for (i=0; i<data_lines.size(); i++) {
|
||||||
|
for (spaces=0; spaces<=level; spaces++) cout << " "; // format output
|
||||||
|
cout << data_lines[i] << endl;
|
||||||
|
}
|
||||||
|
for (i=0; i<children.size(); i++) {
|
||||||
|
children[i]->Print(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void Element::AddAttribute(string name, string value)
|
||||||
|
{
|
||||||
|
attribute_key.push_back(name);
|
||||||
|
attributes[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void Element::AddData(string d)
|
||||||
|
{
|
||||||
|
int string_start = d.find_first_not_of(" ");
|
||||||
|
if (string_start > 0) d.erase(0,string_start-1);
|
||||||
|
data_lines.push_back(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
} // end namespace JSBSim
|
354
src/FDM/JSBSim/input_output/FGXMLElement.h
Executable file
354
src/FDM/JSBSim/input_output/FGXMLElement.h
Executable file
|
@ -0,0 +1,354 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
File: FGXMLElement.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 9/28/04
|
||||||
|
|
||||||
|
------------- Copyright (C) 2004 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef XMLELEMENT_H
|
||||||
|
#define XMLELEMENT_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <string>
|
||||||
|
# include <vector>
|
||||||
|
# include <iostream>
|
||||||
|
# include <map>
|
||||||
|
# else
|
||||||
|
# include <vector.h>
|
||||||
|
# include <string>
|
||||||
|
# include <iostream.h>
|
||||||
|
# include <map.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include <string>
|
||||||
|
# include <map>
|
||||||
|
# include <iostream>
|
||||||
|
# include <vector>
|
||||||
|
using std::string;
|
||||||
|
using std::map;
|
||||||
|
using std::vector;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
#endif
|
||||||
|
using std::string;
|
||||||
|
using std::map;
|
||||||
|
using std::vector;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_XMLELEMENT "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Encapsulates an XML element.
|
||||||
|
This class handles the creation, storage, and manipulation of XML elements.
|
||||||
|
This class also can convert supplied values as follows:
|
||||||
|
|
||||||
|
convert ["from"]["to"] = factor, so: from * factor = to
|
||||||
|
- convert["M"]["FT"] = 3.2808399;
|
||||||
|
- convert["FT"]["M"] = 1.0/convert["M"]["FT"];
|
||||||
|
- convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
|
||||||
|
- convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
|
||||||
|
- convert["FT"]["IN"] = 12.0;
|
||||||
|
- convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
|
||||||
|
- convert["LBS"]["KG"] = 0.45359237;
|
||||||
|
- convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
|
||||||
|
- convert["SLUG*FT2"]["KG*M2"] = 1.35594;
|
||||||
|
- convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
|
||||||
|
- convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926);
|
||||||
|
- convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
|
||||||
|
- convert["LBS/FT"]["N/M"] = 14.5939;
|
||||||
|
- convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
|
||||||
|
- convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
|
||||||
|
- convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
|
||||||
|
- convert["WATTS"]["HP"] = 0.001341022;
|
||||||
|
- convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
|
||||||
|
- convert["N"]["LBS"] = 0.22482;
|
||||||
|
- convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
|
||||||
|
- convert["KTS"]["FT/SEC"] = ktstofps;
|
||||||
|
|
||||||
|
- convert["M"]["M"] = 1.00;
|
||||||
|
- convert["FT"]["FT"] = 1.00;
|
||||||
|
- convert["IN"]["IN"] = 1.00;
|
||||||
|
- convert["DEG"]["DEG"] = 1.00;
|
||||||
|
- convert["RAD"]["RAD"] = 1.00;
|
||||||
|
- convert["M2"]["M2"] = 1.00;
|
||||||
|
- convert["FT2"]["FT2"] = 1.00;
|
||||||
|
- convert["KG*M2"]["KG*M2"] = 1.00;
|
||||||
|
- convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
|
||||||
|
- convert["KG"]["KG"] = 1.00;
|
||||||
|
- convert["LBS"]["LBS"] = 1.00;
|
||||||
|
- convert["LBS/FT"]["LBS/FT"] = 1.00;
|
||||||
|
- convert["N/M"]["N/M"] = 1.00;
|
||||||
|
- convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
|
||||||
|
- convert["N/M/SEC"]["N/M/SEC"] = 1.00;
|
||||||
|
- convert["PSI"]["PSI"] = 1.00;
|
||||||
|
- convert["INHG"]["INHG"] = 1.00;
|
||||||
|
- convert["HP"]["HP"] = 1.00;
|
||||||
|
- convert["N"]["N"] = 1.00;
|
||||||
|
- convert["WATTS"]["WATTS"] = 1.00;
|
||||||
|
- convert["KTS"]["KTS"] = 1.0;
|
||||||
|
- convert["FT/SEC"]["FT/SEC"] = 1.0;
|
||||||
|
|
||||||
|
Where:
|
||||||
|
- N = newtons
|
||||||
|
- M = meters
|
||||||
|
- M2 = meters squared
|
||||||
|
- KG = kilograms
|
||||||
|
- LBS = pounds force
|
||||||
|
- FT = feet
|
||||||
|
- FT2 = feet squared
|
||||||
|
- SEC = seconds
|
||||||
|
- SLUG = slug
|
||||||
|
- DEG = degrees
|
||||||
|
- RAD = radians
|
||||||
|
- WATTS = watts
|
||||||
|
|
||||||
|
@author Jon S. Berndt
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class Element {
|
||||||
|
public:
|
||||||
|
/** Constructor
|
||||||
|
@param nm the name of this element (if given)
|
||||||
|
*/
|
||||||
|
Element(string nm);
|
||||||
|
/// Destructor
|
||||||
|
~Element(void);
|
||||||
|
|
||||||
|
/** Retrieves an attribute.
|
||||||
|
@param key specifies the attribute key to retrieve the value of.
|
||||||
|
@return the key value (as a string), or the empty string if no such
|
||||||
|
attribute exists. */
|
||||||
|
string GetAttributeValue(string key);
|
||||||
|
|
||||||
|
/** Retrieves an attribute value as a double precision real number.
|
||||||
|
@param key specifies the attribute key to retrieve the value of.
|
||||||
|
@return the key value (as a number), or the HUGE_VAL if no such
|
||||||
|
attribute exists. */
|
||||||
|
double GetAttributeValueAsNumber(string key);
|
||||||
|
|
||||||
|
/** Retrieves the element name.
|
||||||
|
@return the element name, or the empty string if no name has been set.*/
|
||||||
|
string GetName(void) {return name;}
|
||||||
|
|
||||||
|
/** Gets a line of data belonging to an element.
|
||||||
|
@param i the index of the data line to return (0 by default).
|
||||||
|
@return a string representing the data line requested, or the empty string
|
||||||
|
if none exists.*/
|
||||||
|
string GetDataLine(int i=0);
|
||||||
|
|
||||||
|
/// Returns the number of lines of data stored
|
||||||
|
int GetNumDataLines(void) {return data_lines.size();}
|
||||||
|
|
||||||
|
/// Returns the number of child elements for this element.
|
||||||
|
int GetNumElements(void) {return children.size();}
|
||||||
|
|
||||||
|
/// Returns the number of named child elements for this element.
|
||||||
|
int GetNumElements(string);
|
||||||
|
|
||||||
|
/** Converts the element data to a number.
|
||||||
|
This function attempts to convert the first (and presumably only) line of
|
||||||
|
data "owned" by the element into a real number. If there is not exactly one
|
||||||
|
line of data owned by the element, then HUGE_VAL is returned.
|
||||||
|
@return the numeric value of the data owned by the element.*/
|
||||||
|
double GetDataAsNumber(void);
|
||||||
|
|
||||||
|
/** Returns a pointer to the element requested by index.
|
||||||
|
This function also resets an internal counter to the index, so that
|
||||||
|
subsequent calls to GetNextElement() will return the following
|
||||||
|
elements sequentially, until the last element is reached. At that point,
|
||||||
|
GetNextElement() will return NULL.
|
||||||
|
@param el the index of the requested element (0 by default)
|
||||||
|
@return a pointer to the Element, or 0 if no valid element exists. */
|
||||||
|
Element* GetElement(int el=0);
|
||||||
|
|
||||||
|
/** Returns a pointer to the next element in the list.
|
||||||
|
The function GetElement() must be called first to be sure that this
|
||||||
|
function will return the correct element. The call to GetElement() resets
|
||||||
|
the internal counter to zero. Subsequent calls to GetNextElement() return
|
||||||
|
a pointer to subsequent elements in the list. When the final element is
|
||||||
|
reached, 0 is returned.
|
||||||
|
@return a pointer to the next Element in the sequence, or 0 if no valid
|
||||||
|
Element is present. */
|
||||||
|
Element* GetNextElement(void);
|
||||||
|
|
||||||
|
/** Returns a pointer to the parent of an element.
|
||||||
|
@return a pointer to the parent Element, or 0 if this is the top level Element. */
|
||||||
|
Element* GetParent(void) {return parent;}
|
||||||
|
|
||||||
|
/** Searches for a specified element.
|
||||||
|
Finds the first element that matches the supplied string, or simply the first
|
||||||
|
element if no search string is supplied. This function call resets the internal
|
||||||
|
element counter to the first element.
|
||||||
|
@param el the search string (empty string by default).
|
||||||
|
@return a pointer to the first element that matches the supplied search string. */
|
||||||
|
Element* FindElement(string el="");
|
||||||
|
|
||||||
|
/** Searches for the next element as specified.
|
||||||
|
This function would be called after FindElement() is first called (in order to
|
||||||
|
reset the internal counter). If no argument is supplied (or the empty string)
|
||||||
|
a pointer to the very next element is returned. Otherwise, the next occurence
|
||||||
|
of the named element is returned. If the end of the list is reached, 0 is
|
||||||
|
returned.
|
||||||
|
@param el the name of the next element to find.
|
||||||
|
@return the pointer to the found element, or 0 if no appropriate element us
|
||||||
|
found.*/
|
||||||
|
Element* FindNextElement(string el="");
|
||||||
|
|
||||||
|
/** Searches for the named element and returns the string data belonging to it.
|
||||||
|
This function allows the data belonging to a named element to be returned
|
||||||
|
as a string. If no element is found, the empty string is returned. If no
|
||||||
|
argument is supplied, the data string for the first element is returned.
|
||||||
|
@param el the name of the element being searched for (the empty string by
|
||||||
|
default)
|
||||||
|
@return the data value for the named element as a string, or the empty
|
||||||
|
string if the element cannot be found. */
|
||||||
|
string FindElementValue(string el="");
|
||||||
|
|
||||||
|
/** Searches for the named element and returns the data belonging to it as a number.
|
||||||
|
This function allows the data belonging to a named element to be returned
|
||||||
|
as a double. If no element is found, HUGE_VAL is returned. If no
|
||||||
|
argument is supplied, the data for the first element is returned.
|
||||||
|
@param el the name of the element being searched for (the empty string by
|
||||||
|
default)
|
||||||
|
@return the data value for the named element as a double, or HUGE_VAL if the
|
||||||
|
data is missing. */
|
||||||
|
double FindElementValueAsNumber(string el="");
|
||||||
|
|
||||||
|
/** Searches for the named element and converts and returns the data belonging to it.
|
||||||
|
This function allows the data belonging to a named element to be returned
|
||||||
|
as a double. If no element is found, HUGE_VAL is returned. If no
|
||||||
|
argument is supplied, the data for the first element is returned. Additionally,
|
||||||
|
this function converts the value from the units specified in the config file (via
|
||||||
|
the UNITS="" attribute in the element definition) to the native units used by
|
||||||
|
JSBSim itself, as specified by the target_units parameter. The currently
|
||||||
|
allowable unit conversions are seen in the source file FGXMLElement.cpp.
|
||||||
|
Also, see above in the main documentation for this class.
|
||||||
|
@param el the name of the element being searched for (the empty string by
|
||||||
|
default)
|
||||||
|
@param target_units the string representing the native units used by JSBSim
|
||||||
|
to which the value returned will be converted.
|
||||||
|
@return the unit-converted data value for the named element as a double,
|
||||||
|
or HUGE_VAL if the data is missing. */
|
||||||
|
double FindElementValueAsNumberConvertTo(string el, string target_units);
|
||||||
|
|
||||||
|
/** Searches for the named element and converts and returns the data belonging to it.
|
||||||
|
This function allows the data belonging to a named element to be returned
|
||||||
|
as a double. If no element is found, HUGE_VAL is returned. If no
|
||||||
|
argument is supplied, the data for the first element is returned. Additionally,
|
||||||
|
this function converts the value from the units specified in the supplied_units
|
||||||
|
parameter to the units specified in the target_units parameter. JSBSim itself,
|
||||||
|
as specified by the target_units parameter. The currently allowable unit
|
||||||
|
conversions are seen in the source file FGXMLElement.cpp. Also, see above
|
||||||
|
in the main documentation for this class.
|
||||||
|
@param el the name of the element being searched for (the empty string by
|
||||||
|
default)
|
||||||
|
@param supplied_units the string representing the units of the value as
|
||||||
|
supplied by the config file.
|
||||||
|
@param target_units the string representing the native units used by JSBSim
|
||||||
|
to which the value returned will be converted.
|
||||||
|
@return the unit-converted data value for the named element as a double,
|
||||||
|
or HUGE_VAL if the data is missing. */
|
||||||
|
double FindElementValueAsNumberConvertFromTo( string el,
|
||||||
|
string supplied_units,
|
||||||
|
string target_units);
|
||||||
|
|
||||||
|
/** Composes a 3-element column vector for the supplied location or orientation.
|
||||||
|
This function processes a LOCATION or ORIENTATION construct, returning a
|
||||||
|
filled-out 3-element column vector containing the X, Y, Z or ROLL, PITCH,
|
||||||
|
YAW elements found in the supplied element. If one of the mentioned components
|
||||||
|
is not found, that component is set to zero and a warning message is printed.
|
||||||
|
All three elements should be supplied.
|
||||||
|
@param target_units the string representing the native units used by JSBSim
|
||||||
|
to which the value returned will be converted.
|
||||||
|
@return a column vector object built from the LOCATION or ORIENT components. */
|
||||||
|
FGColumnVector3 FindElementTripletConvertTo( string target_units);
|
||||||
|
|
||||||
|
/** This function sets the value of the parent class attribute to the supplied
|
||||||
|
Element pointer.
|
||||||
|
@param p pointer to the parent Element. */
|
||||||
|
void SetParent(Element* p) {parent = p;}
|
||||||
|
|
||||||
|
/** Adds a child element to the list of children stored for this element.
|
||||||
|
* @param el Child element to add. */
|
||||||
|
void AddChildElement(Element* el) {children.push_back(el);}
|
||||||
|
|
||||||
|
/** Stores an attribute belonging to this element.
|
||||||
|
* @param name The string name of the attribute.
|
||||||
|
* @param value The string value of the attribute. */
|
||||||
|
void AddAttribute(string name, string value);
|
||||||
|
|
||||||
|
/** Stores data belonging to this element.
|
||||||
|
* @param d the data to store. */
|
||||||
|
void AddData(string d);
|
||||||
|
|
||||||
|
/** Prints the element.
|
||||||
|
* Prints this element and calls the Print routine for child elements.
|
||||||
|
* @param d The tab level. A level corresponds to a single space. */
|
||||||
|
void Print(int level=0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
string name;
|
||||||
|
map <string, string> attributes;
|
||||||
|
vector <string> data_lines;
|
||||||
|
vector <Element*> children;
|
||||||
|
vector <string> attribute_key;
|
||||||
|
Element *parent;
|
||||||
|
int element_index;
|
||||||
|
typedef map <string, map <string, double> > tMapConvert;
|
||||||
|
tMapConvert convert;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
#endif
|
146
src/FDM/JSBSim/input_output/FGXMLParse.cpp
Executable file
146
src/FDM/JSBSim/input_output/FGXMLParse.cpp
Executable file
|
@ -0,0 +1,146 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGXMLParse.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 08/20/2004
|
||||||
|
Purpose: Config file read-in class and XML parser
|
||||||
|
Called by: Various
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGXMLParse.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_XMLPARSE;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGXMLParse.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
FGXMLParse::FGXMLParse(void)
|
||||||
|
{
|
||||||
|
first_element_read = false;
|
||||||
|
current_element = document = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGXMLParse::~FGXMLParse(void)
|
||||||
|
{
|
||||||
|
if (document) delete document;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::startXML(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::reset(void)
|
||||||
|
{
|
||||||
|
if (document) delete document;
|
||||||
|
first_element_read = false;
|
||||||
|
current_element = document = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::endXML(void)
|
||||||
|
{
|
||||||
|
// At this point, document should equal current_element ?
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::startElement (const char * name, const XMLAttributes &atts)
|
||||||
|
{
|
||||||
|
string Name(name);
|
||||||
|
Element *temp_element;
|
||||||
|
|
||||||
|
working_string.erase();
|
||||||
|
|
||||||
|
if (!first_element_read) {
|
||||||
|
document = new Element(Name);
|
||||||
|
current_element = document;
|
||||||
|
first_element_read = true;
|
||||||
|
} else {
|
||||||
|
temp_element = new Element(Name);
|
||||||
|
temp_element->SetParent(current_element);
|
||||||
|
current_element->AddChildElement(temp_element);
|
||||||
|
current_element = temp_element;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_element == 0L) {
|
||||||
|
cerr << "No current element read (no top-level element in XML file?)" << endl;
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<atts.size();i++) {
|
||||||
|
current_element->AddAttribute(atts.getName(i), atts.getValue(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::endElement (const char * name)
|
||||||
|
{
|
||||||
|
int size, pos;
|
||||||
|
string local_work_string;
|
||||||
|
|
||||||
|
while (!working_string.empty()) {
|
||||||
|
// clear leading newlines and spaces
|
||||||
|
while (working_string[0] == '\n' || working_string[0] == ' ')
|
||||||
|
working_string.erase(0,1);
|
||||||
|
|
||||||
|
// remove spaces (only) from end of string
|
||||||
|
size = working_string.size();
|
||||||
|
while (working_string[size-1] == ' ')
|
||||||
|
{
|
||||||
|
working_string.erase(size-1,1);
|
||||||
|
size = working_string.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!working_string.empty()) {
|
||||||
|
pos = working_string.find("\n");
|
||||||
|
if (pos != string::npos) local_work_string = working_string.substr(0,pos);
|
||||||
|
else local_work_string = working_string;
|
||||||
|
current_element->AddData(local_work_string);
|
||||||
|
working_string.erase(0, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current_element = current_element->GetParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::data (const char * s, int length)
|
||||||
|
{
|
||||||
|
working_string += string(s, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::pi (const char * target, const char * data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGXMLParse::warning (const char * message, int line, int column)
|
||||||
|
{
|
||||||
|
cerr << "Warning: " << message << " line: " << line << " column: " << column << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace JSBSim
|
106
src/FDM/JSBSim/input_output/FGXMLParse.h
Executable file
106
src/FDM/JSBSim/input_output/FGXMLParse.h
Executable file
|
@ -0,0 +1,106 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGXMLParse.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 8/20/04
|
||||||
|
|
||||||
|
------------- Copyright (C) 2004 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGXMLPARSE_H
|
||||||
|
#define FGXMLPARSE_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# include STL_STRING
|
||||||
|
#else
|
||||||
|
# include <string>
|
||||||
|
# include <iostream>
|
||||||
|
using std::string;
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGXMLElement.h"
|
||||||
|
#include "simgear/xml/easyxml.hxx"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_XMLPARSE "$Id$"
|
||||||
|
#define VALID_CHARS """`!@#$%^&*()_+`1234567890-={}[];':,.<>/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Encapsulates an XML parser based on the EasyXML parser from the SimGear library.
|
||||||
|
@author Jon S. Berndt
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGXMLParse : public XMLVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGXMLParse(void);
|
||||||
|
virtual ~FGXMLParse(void);
|
||||||
|
|
||||||
|
Element* GetDocument(void) {return document;}
|
||||||
|
|
||||||
|
void startXML();
|
||||||
|
void endXML();
|
||||||
|
void startElement (const char * name, const XMLAttributes &atts);
|
||||||
|
void endElement (const char * name);
|
||||||
|
void data (const char * s, int length);
|
||||||
|
void pi (const char * target, const char * data);
|
||||||
|
void warning (const char * message, int line, int column);
|
||||||
|
void reset(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool first_element_read;
|
||||||
|
mutable string working_string;
|
||||||
|
Element *document;
|
||||||
|
Element *current_element;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
#endif
|
|
@ -37,10 +37,6 @@ HISTORY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGfdmSocket.h"
|
#include "FGfdmSocket.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -54,7 +50,7 @@ CLASS IMPLEMENTATION
|
||||||
|
|
||||||
FGfdmSocket::FGfdmSocket(string address, int port)
|
FGfdmSocket::FGfdmSocket(string address, int port)
|
||||||
{
|
{
|
||||||
size = 0;
|
sckt = sckt_in = size = 0;
|
||||||
connected = false;
|
connected = false;
|
||||||
|
|
||||||
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
@ -100,12 +96,61 @@ FGfdmSocket::FGfdmSocket(string address, int port)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGfdmSocket::FGfdmSocket(int port)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
connected = false;
|
||||||
|
unsigned long NoBlock = true;
|
||||||
|
|
||||||
|
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
WSADATA wsaData;
|
||||||
|
int wsaReturnCode;
|
||||||
|
wsaReturnCode = WSAStartup(MAKEWORD(1,1), &wsaData);
|
||||||
|
if (wsaReturnCode == 0) cout << "Winsock DLL loaded ..." << endl;
|
||||||
|
else cerr << "Winsock DLL not initialized ..." << endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sckt = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (sckt >= 0) { // successful
|
||||||
|
memset(&scktName, 0, sizeof(struct sockaddr_in));
|
||||||
|
scktName.sin_family = AF_INET;
|
||||||
|
scktName.sin_port = htons(port);
|
||||||
|
// memcpy(&scktName.sin_addr, host->h_addr_list[0], host->h_length);
|
||||||
|
int len = sizeof(struct sockaddr_in);
|
||||||
|
if (bind(sckt, (struct sockaddr*)&scktName, len) == 0) { // successful
|
||||||
|
cout << "Successfully bound to socket ..." << endl;
|
||||||
|
if (listen(sckt, 5) >= 0) { // successful listen()
|
||||||
|
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
ioctlsocket(sckt, FIONBIO, &NoBlock);
|
||||||
|
sckt_in = accept(sckt, (struct sockaddr*)&scktName, &len);
|
||||||
|
#else
|
||||||
|
ioctl(sckt, FIONBIO, &NoBlock);
|
||||||
|
sckt_in = accept(sckt, (struct sockaddr*)&scktName, (socklen_t*)&len);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
cerr << "Could not listen ..." << endl;
|
||||||
|
}
|
||||||
|
connected = true;
|
||||||
|
} else { // unsuccessful
|
||||||
|
cerr << "Could not bind to socket ..." << endl;
|
||||||
|
}
|
||||||
|
} else { // unsuccessful
|
||||||
|
cerr << "Could not create socket for FDM, error = " << errno << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGfdmSocket::~FGfdmSocket()
|
FGfdmSocket::~FGfdmSocket()
|
||||||
{
|
{
|
||||||
#ifndef macintosh
|
#ifndef macintosh
|
||||||
if (sckt) shutdown(sckt,2);
|
if (sckt) shutdown(sckt,2);
|
||||||
|
if (sckt_in) shutdown(sckt_in,2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
|
@ -114,6 +159,80 @@ FGfdmSocket::~FGfdmSocket()
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGfdmSocket::Receive(void)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
int len = sizeof(struct sockaddr_in);
|
||||||
|
int num_chars=0;
|
||||||
|
int total_chars = 0;
|
||||||
|
unsigned long NoBlock = true;
|
||||||
|
string data = ""; // todo: should allocate this with a standard size as a
|
||||||
|
// class attribute and pass as a reference?
|
||||||
|
|
||||||
|
if (sckt_in <= 0) {
|
||||||
|
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
sckt_in = accept(sckt, (struct sockaddr*)&scktName, &len);
|
||||||
|
#else
|
||||||
|
sckt_in = accept(sckt, (struct sockaddr*)&scktName, (socklen_t*)&len);
|
||||||
|
#endif
|
||||||
|
if (sckt_in > 0) {
|
||||||
|
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
ioctlsocket(sckt_in, FIONBIO,&NoBlock);
|
||||||
|
#else
|
||||||
|
ioctl(sckt_in, FIONBIO, &NoBlock);
|
||||||
|
#endif
|
||||||
|
send(sckt_in, "Connected to JSBSim server\nJSBSim> ", 35, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sckt_in > 0) {
|
||||||
|
while ((num_chars = recv(sckt_in, buf, 1024, 0)) > 0) {
|
||||||
|
data += string(buf).substr(0,num_chars);
|
||||||
|
total_chars += num_chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
// when nothing received and the error isn't "would block"
|
||||||
|
// then assume that the client has closed the socket.
|
||||||
|
if (num_chars == 0) {
|
||||||
|
DWORD err = WSAGetLastError ();
|
||||||
|
if (err != WSAEWOULDBLOCK) {
|
||||||
|
printf ("Socket Closed. back to listening\n");
|
||||||
|
closesocket (sckt_in);
|
||||||
|
sckt_in = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.substr(0, total_chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
int FGfdmSocket::Reply(string text)
|
||||||
|
{
|
||||||
|
int num_chars_sent=0;
|
||||||
|
|
||||||
|
if (sckt_in >= 0) {
|
||||||
|
num_chars_sent = send(sckt_in, text.c_str(), text.size(), 0);
|
||||||
|
send(sckt_in, "JSBSim> ", 8, 0);
|
||||||
|
} else {
|
||||||
|
cerr << "Socket reply must be to a valid socket" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return num_chars_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGfdmSocket::Close(void)
|
||||||
|
{
|
||||||
|
close(sckt_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGfdmSocket::Clear(void)
|
void FGfdmSocket::Clear(void)
|
||||||
{
|
{
|
||||||
buffer = "";
|
buffer = "";
|
||||||
|
@ -122,6 +241,14 @@ void FGfdmSocket::Clear(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGfdmSocket::Clear(string s)
|
||||||
|
{
|
||||||
|
buffer = s + " ";
|
||||||
|
size = buffer.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGfdmSocket::Append(const char* item)
|
void FGfdmSocket::Append(const char* item)
|
||||||
{
|
{
|
||||||
if (size == 0) buffer += string(item);
|
if (size == 0) buffer += string(item);
|
|
@ -65,11 +65,14 @@ INCLUDES
|
||||||
|
|
||||||
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
|
#include <io.h>
|
||||||
#else
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -96,21 +99,29 @@ CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using std::cerr;
|
||||||
|
|
||||||
class FGfdmSocket : public FGJSBBase
|
class FGfdmSocket : public FGJSBBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGfdmSocket(string, int);
|
FGfdmSocket(string, int);
|
||||||
|
FGfdmSocket(int);
|
||||||
~FGfdmSocket();
|
~FGfdmSocket();
|
||||||
void Send(void);
|
void Send(void);
|
||||||
|
string Receive(void);
|
||||||
|
int Reply(string text);
|
||||||
|
void Append(const string s) {Append(s.c_str());}
|
||||||
void Append(const char*);
|
void Append(const char*);
|
||||||
void Append(double);
|
void Append(double);
|
||||||
void Append(long);
|
void Append(long);
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
|
void Clear(string s);
|
||||||
|
void Close(void);
|
||||||
bool GetConnectStatus(void) {return connected;}
|
bool GetConnectStatus(void) {return connected;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int sckt;
|
int sckt;
|
||||||
|
int sckt_in;
|
||||||
int size;
|
int size;
|
||||||
struct sockaddr_in scktName;
|
struct sockaddr_in scktName;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
7
src/FDM/JSBSim/input_output/Makefile.am
Normal file
7
src/FDM/JSBSim/input_output/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
noinst_LIBRARIES = libInputOutput.a
|
||||||
|
|
||||||
|
libInputOutput_a_SOURCES = FGGroundCallback.cpp FGPropertyManager.cpp FGScript.cpp FGXMLElement.cpp FGXMLParse.cpp FGfdmSocket.cpp
|
||||||
|
|
||||||
|
noinst_HEADERS = FGGroundCallback.h FGPropertyManager.h FGScript.h FGXMLElement.h FGXMLParse.h FGfdmSocket.h
|
||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
|
155
src/FDM/JSBSim/math/FGColumnVector3.cpp
Normal file
155
src/FDM/JSBSim/math/FGColumnVector3.cpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGColumnVector3.cpp
|
||||||
|
Author: Originally by Tony Peden [formatted here (and broken??) by JSB]
|
||||||
|
Date started: 1998
|
||||||
|
Purpose: FGColumnVector3 class
|
||||||
|
Called by: Various
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
??/??/?? TP Created
|
||||||
|
03/16/2000 JSB Added exception throwing
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGColumnVector3.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_COLUMNVECTOR3;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGColumnVector3::FGColumnVector3(void)
|
||||||
|
{
|
||||||
|
data[0] = data[1] = data[2] = 0.0;
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGColumnVector3::Dump(string delimeter) const
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
sprintf(buffer, "%f%s%f%s%f", Entry(1), delimeter.c_str(), Entry(2), delimeter.c_str(), Entry(3));
|
||||||
|
return string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
ostream& operator<<(ostream& os, const FGColumnVector3& col)
|
||||||
|
{
|
||||||
|
os << col(1) << " , " << col(2) << " , " << col(3);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGColumnVector3 FGColumnVector3::operator/(const double scalar) const
|
||||||
|
{
|
||||||
|
if (scalar != 0.0)
|
||||||
|
return operator*( 1.0/scalar );
|
||||||
|
|
||||||
|
cerr << "Attempt to divide by zero in method \
|
||||||
|
FGColumnVector3::operator/(const double scalar), \
|
||||||
|
object " << data[0] << " , " << data[1] << " , " << data[2] << endl;
|
||||||
|
return FGColumnVector3();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGColumnVector3& FGColumnVector3::operator/=(const double scalar)
|
||||||
|
{
|
||||||
|
if (scalar != 0.0)
|
||||||
|
operator*=( 1.0/scalar );
|
||||||
|
else
|
||||||
|
cerr << "Attempt to divide by zero in method \
|
||||||
|
FGColumnVector3::operator/=(const double scalar), \
|
||||||
|
object " << data[0] << " , " << data[1] << " , " << data[2] << endl;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGColumnVector3::Magnitude(void) const
|
||||||
|
{
|
||||||
|
if (Entry(1) == 0.0 && Entry(2) == 0.0 && Entry(3) == 0.0)
|
||||||
|
return 0.0;
|
||||||
|
else
|
||||||
|
return sqrt( Entry(1)*Entry(1) + Entry(2)*Entry(2) + Entry(3)*Entry(3) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGColumnVector3& FGColumnVector3::Normalize(void)
|
||||||
|
{
|
||||||
|
double Mag = Magnitude();
|
||||||
|
|
||||||
|
if (Mag != 0.0)
|
||||||
|
operator*=( 1.0/Mag );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGColumnVector3 FGColumnVector3::multElementWise(const FGColumnVector3& V) const
|
||||||
|
{
|
||||||
|
return FGColumnVector3(Entry(1) * V(1), Entry(2) * V(2), Entry(3) * V(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGColumnVector3::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGColumnVector3" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGColumnVector3" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
308
src/FDM/JSBSim/math/FGColumnVector3.h
Normal file
308
src/FDM/JSBSim/math/FGColumnVector3.h
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGColumnVector3.h
|
||||||
|
Author: Originally by Tony Peden [formatted and adapted here by Jon Berndt]
|
||||||
|
Date started: Unknown
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
??/??/???? ?? Initial version and more.
|
||||||
|
03/06/2004 MF Rework, document and do much inlineing.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGCOLUMNVECTOR3_H
|
||||||
|
#define FGCOLUMNVECTOR3_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <math.h>
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# include STL_STRING
|
||||||
|
# include STL_FSTREAM
|
||||||
|
# include STL_IOSTREAM
|
||||||
|
SG_USING_STD(string);
|
||||||
|
SG_USING_STD(ostream);
|
||||||
|
SG_USING_STD(istream);
|
||||||
|
SG_USING_STD(cerr);
|
||||||
|
SG_USING_STD(cout);
|
||||||
|
SG_USING_STD(endl);
|
||||||
|
#else
|
||||||
|
# include <string>
|
||||||
|
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
|
||||||
|
# include <fstream.h>
|
||||||
|
# include <iostream.h>
|
||||||
|
# include <math.h>
|
||||||
|
# else
|
||||||
|
# include <fstream>
|
||||||
|
# include <iostream>
|
||||||
|
# if defined(sgi) && !defined(__GNUC__)
|
||||||
|
# include <math.h>
|
||||||
|
# else
|
||||||
|
# include <cmath>
|
||||||
|
# endif
|
||||||
|
using std::ostream;
|
||||||
|
using std::istream;
|
||||||
|
using std::cerr;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
# if !(defined(_MSC_VER) && _MSC_VER <= 1200)
|
||||||
|
using std::sqrt;
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
using std::string;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGJSBBase.h"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_COLUMNVECTOR3 "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** This class implements a 3 dimensional vector.
|
||||||
|
@author Jon S. Berndt, Tony Peden, et. al.
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGColumnVector3 : public FGJSBBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Default initializer.
|
||||||
|
Create a zero vector. */
|
||||||
|
FGColumnVector3(void);
|
||||||
|
|
||||||
|
/** Initialization by given values.
|
||||||
|
@param X value of the x-conponent.
|
||||||
|
@param Y value of the y-conponent.
|
||||||
|
@param Z value of the z-conponent.
|
||||||
|
Create a vector from the doubles given in the arguments. */
|
||||||
|
FGColumnVector3(double X, double Y, double Z) {
|
||||||
|
data[0] = X;
|
||||||
|
data[1] = Y;
|
||||||
|
data[2] = Z;
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Copy constructor.
|
||||||
|
@param v Vector which is used for initialization.
|
||||||
|
Create copy of the vector given in the argument. */
|
||||||
|
FGColumnVector3(const FGColumnVector3& v) {
|
||||||
|
data[0] = v.data[0];
|
||||||
|
data[1] = v.data[1];
|
||||||
|
data[2] = v.data[2];
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destructor.
|
||||||
|
~FGColumnVector3(void) { Debug(1); }
|
||||||
|
|
||||||
|
/** Read access the entries of the vector.
|
||||||
|
@param idx the component index.
|
||||||
|
Return the value of the matrix entry at the given index.
|
||||||
|
Indices are counted starting with 1.
|
||||||
|
Note that the index given in the argument is unchecked. */
|
||||||
|
double operator()(unsigned int idx) const { return Entry(idx); }
|
||||||
|
|
||||||
|
/** Write access the entries of the vector.
|
||||||
|
@param idx the component index.
|
||||||
|
Return a reference to the vector entry at the given index.
|
||||||
|
Indices are counted starting with 1.
|
||||||
|
Note that the index given in the argument is unchecked. */
|
||||||
|
double& operator()(unsigned int idx) { return Entry(idx); }
|
||||||
|
|
||||||
|
/** Read access the entries of the vector.
|
||||||
|
@param idx the component index.
|
||||||
|
Return the value of the matrix entry at the given index.
|
||||||
|
Indices are counted starting with 1.
|
||||||
|
This function is just a shortcut for the @ref double
|
||||||
|
operator()(unsigned int idx) const function. It is
|
||||||
|
used internally to access the elements in a more convenient way.
|
||||||
|
Note that the index given in the argument is unchecked. */
|
||||||
|
double Entry(unsigned int idx) const { return data[idx-1]; }
|
||||||
|
|
||||||
|
/** Write access the entries of the vector.
|
||||||
|
@param idx the component index.
|
||||||
|
Return a reference to the vector entry at the given index.
|
||||||
|
Indices are counted starting with 1.
|
||||||
|
This function is just a shortcut for the @ref double&
|
||||||
|
operator()(unsigned int idx) function. It is
|
||||||
|
used internally to access the elements in a more convenient way.
|
||||||
|
Note that the index given in the argument is unchecked. */
|
||||||
|
double& Entry(unsigned int idx) { return data[idx-1]; }
|
||||||
|
|
||||||
|
/** Prints the contents of the vector
|
||||||
|
@param delimeter the item separator (tab or comma)
|
||||||
|
@return a string with the delimeter-separated contents of the vector */
|
||||||
|
string Dump(string delimeter) const;
|
||||||
|
|
||||||
|
/** Assignment operator.
|
||||||
|
@param b source vector.
|
||||||
|
Copy the content of the vector given in the argument into *this. */
|
||||||
|
FGColumnVector3& operator=(const FGColumnVector3& b) {
|
||||||
|
data[0] = b.data[0];
|
||||||
|
data[1] = b.data[1];
|
||||||
|
data[2] = b.data[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Comparison operator.
|
||||||
|
@param b other vector.
|
||||||
|
Returns true if both vectors are exactly the same. */
|
||||||
|
bool operator==(const FGColumnVector3& b) const {
|
||||||
|
return data[0] == b.data[0] && data[1] == b.data[1] && data[2] == b.data[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Comparison operator.
|
||||||
|
@param b other vector.
|
||||||
|
Returns false if both vectors are exactly the same. */
|
||||||
|
bool operator!=(const FGColumnVector3& b) const { return ! operator==(b); }
|
||||||
|
|
||||||
|
/** Multiplication by a scalar.
|
||||||
|
@param scalar scalar value to multiply the vector with.
|
||||||
|
@return The resulting vector from the multiplication with that scalar.
|
||||||
|
Multiply the vector with the scalar given in the argument. */
|
||||||
|
FGColumnVector3 operator*(const double scalar) const {
|
||||||
|
return FGColumnVector3(scalar*Entry(1), scalar*Entry(2), scalar*Entry(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Multiply by 1/scalar.
|
||||||
|
@param scalar scalar value to devide the vector through.
|
||||||
|
@return The resulting vector from the division through that scalar.
|
||||||
|
Multiply the vector with the 1/scalar given in the argument. */
|
||||||
|
FGColumnVector3 operator/(const double scalar) const;
|
||||||
|
|
||||||
|
/** Cross product multiplication.
|
||||||
|
@param v vector to multiply with.
|
||||||
|
@return The resulting vector from the cross product multiplication.
|
||||||
|
Compute and return the cross product of the current vector with
|
||||||
|
the given argument. */
|
||||||
|
FGColumnVector3 operator*(const FGColumnVector3& V) const {
|
||||||
|
return FGColumnVector3( Entry(2) * V(3) - Entry(3) * V(2),
|
||||||
|
Entry(3) * V(1) - Entry(1) * V(3),
|
||||||
|
Entry(1) * V(2) - Entry(2) * V(1) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Addition operator.
|
||||||
|
FGColumnVector3 operator+(const FGColumnVector3& B) const {
|
||||||
|
return FGColumnVector3( Entry(1) + B(1), Entry(2) + B(2), Entry(3) + B(3) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subtraction operator.
|
||||||
|
FGColumnVector3 operator-(const FGColumnVector3& B) const {
|
||||||
|
return FGColumnVector3( Entry(1) - B(1), Entry(2) - B(2), Entry(3) - B(3) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subtract an other vector.
|
||||||
|
FGColumnVector3& operator-=(const FGColumnVector3 &B) {
|
||||||
|
Entry(1) -= B(1);
|
||||||
|
Entry(2) -= B(2);
|
||||||
|
Entry(3) -= B(3);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add an other vector.
|
||||||
|
FGColumnVector3& operator+=(const FGColumnVector3 &B) {
|
||||||
|
Entry(1) += B(1);
|
||||||
|
Entry(2) += B(2);
|
||||||
|
Entry(3) += B(3);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Scale by a scalar.
|
||||||
|
FGColumnVector3& operator*=(const double scalar) {
|
||||||
|
Entry(1) *= scalar;
|
||||||
|
Entry(2) *= scalar;
|
||||||
|
Entry(3) *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Scale by a 1/scalar.
|
||||||
|
FGColumnVector3& operator/=(const double scalar);
|
||||||
|
|
||||||
|
void InitMatrix(void) { data[0] = data[1] = data[2] = 0.0; }
|
||||||
|
void InitMatrix(double a) { data[0] = data[1] = data[2] = a; }
|
||||||
|
void InitMatrix(double a, double b, double c) {
|
||||||
|
data[0]=a; data[1]=b; data[2]=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Length of the vector.
|
||||||
|
Compute and return the euclidean norm of this vector. */
|
||||||
|
double Magnitude(void) const;
|
||||||
|
|
||||||
|
/** Length of the vector in a coordinate axis plane.
|
||||||
|
Compute and return the euclidean norm of this vector projected into
|
||||||
|
the coordinate axis plane idx1-idx2. */
|
||||||
|
double Magnitude(int idx1, int idx2) const {
|
||||||
|
return sqrt( Entry(idx1)*Entry(idx1) + Entry(idx2)*Entry(idx2) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Normalize.
|
||||||
|
Normalize the vector to have the Magnitude() == 1.0. If the vector
|
||||||
|
is equal to zero it is left untouched. */
|
||||||
|
FGColumnVector3& Normalize(void);
|
||||||
|
|
||||||
|
// ??? Is this something sensible ??
|
||||||
|
FGColumnVector3 multElementWise(const FGColumnVector3& V) const;
|
||||||
|
|
||||||
|
// little trick here.
|
||||||
|
struct AssignRef {
|
||||||
|
AssignRef(FGColumnVector3& r, int i) : Ref(r), idx(i) {}
|
||||||
|
AssignRef operator<<(const double ff) {
|
||||||
|
Ref.Entry(idx) = ff;
|
||||||
|
return AssignRef(Ref, idx+1);
|
||||||
|
}
|
||||||
|
FGColumnVector3& Ref;
|
||||||
|
int idx;
|
||||||
|
};
|
||||||
|
AssignRef operator<<(const double ff) {
|
||||||
|
Entry(1) = ff;
|
||||||
|
return AssignRef(*this, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double data[3];
|
||||||
|
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Scalar multiplication.
|
||||||
|
@param scalar scalar value to multiply with.
|
||||||
|
@param A Vector to multiply.
|
||||||
|
Multiply the Vector with a scalar value.*/
|
||||||
|
inline FGColumnVector3 operator*(double scalar, const FGColumnVector3& A) {
|
||||||
|
// use already defined operation.
|
||||||
|
return A*scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write vector to a stream.
|
||||||
|
@param os Stream to write to.
|
||||||
|
@param M Matrix to write.
|
||||||
|
Write the matrix to a stream.*/
|
||||||
|
ostream& operator<<(ostream& os, const FGColumnVector3& col);
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
257
src/FDM/JSBSim/math/FGFunction.cpp
Executable file
257
src/FDM/JSBSim/math/FGFunction.cpp
Executable file
|
@ -0,0 +1,257 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGFunction.cpp
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 8/25/2004
|
||||||
|
Purpose: Stores various parameter types for functions
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "FGFunction.h"
|
||||||
|
#include "FGTable.h"
|
||||||
|
#include "FGPropertyValue.h"
|
||||||
|
#include "FGRealValue.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_FUNCTION;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, string prefix)
|
||||||
|
: PropertyManager(propMan), Prefix(prefix)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Element* element;
|
||||||
|
string operation, property_name;
|
||||||
|
int size = el->GetNumElements();
|
||||||
|
cached = false;
|
||||||
|
cachedValue = -HUGE_VAL;
|
||||||
|
|
||||||
|
Name = el->GetAttributeValue("name");
|
||||||
|
operation = el->GetName();
|
||||||
|
if (operation == string("function")) {
|
||||||
|
Type = eTopLevel;
|
||||||
|
bind();
|
||||||
|
} else if (operation == string("product")) {
|
||||||
|
Type = eProduct;
|
||||||
|
} else if (operation == string("difference")) {
|
||||||
|
Type = eDifference;
|
||||||
|
} else if (operation == string("sum")) {
|
||||||
|
Type = eSum;
|
||||||
|
} else if (operation == string("quotient")) {
|
||||||
|
Type = eQuotient;
|
||||||
|
} else if (operation == string("pow")) {
|
||||||
|
Type = ePow;
|
||||||
|
} else if (operation == string("abs")) {
|
||||||
|
Type = eAbs;
|
||||||
|
} else if (operation == string("sin")) {
|
||||||
|
Type = eSin;
|
||||||
|
} else if (operation == string("cos")) {
|
||||||
|
Type = eCos;
|
||||||
|
} else if (operation == string("tan")) {
|
||||||
|
Type = eTan;
|
||||||
|
} else if (operation == string("asin")) {
|
||||||
|
Type = eASin;
|
||||||
|
} else if (operation == string("acos")) {
|
||||||
|
Type = eACos;
|
||||||
|
} else if (operation == string("atan")) {
|
||||||
|
Type = eATan;
|
||||||
|
} else if (operation == string("atan2")) {
|
||||||
|
Type = eATan2;
|
||||||
|
} else if (operation != string("description")) {
|
||||||
|
cerr << "Bad operation " << operation << " detected in configuration file" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
element = el->GetElement();
|
||||||
|
while (element) {
|
||||||
|
operation = element->GetName();
|
||||||
|
|
||||||
|
// data types
|
||||||
|
if (operation == string("property")) {
|
||||||
|
property_name = element->GetDataLine();
|
||||||
|
Parameters.push_back(new FGPropertyValue(PropertyManager->GetNode(property_name)));
|
||||||
|
} else if (operation == string("value")) {
|
||||||
|
Parameters.push_back(new FGRealValue(element->GetDataAsNumber()));
|
||||||
|
} else if (operation == string("table")) {
|
||||||
|
Parameters.push_back(new FGTable(PropertyManager, element));
|
||||||
|
// operations
|
||||||
|
} else if (operation == string("product") ||
|
||||||
|
operation == string("difference") ||
|
||||||
|
operation == string("sum") ||
|
||||||
|
operation == string("quotient") ||
|
||||||
|
operation == string("pow") ||
|
||||||
|
operation == string("abs") ||
|
||||||
|
operation == string("sin") ||
|
||||||
|
operation == string("cos") ||
|
||||||
|
operation == string("tan") ||
|
||||||
|
operation == string("asin") ||
|
||||||
|
operation == string("acos") ||
|
||||||
|
operation == string("atan") ||
|
||||||
|
operation == string("atan2"))
|
||||||
|
{
|
||||||
|
Parameters.push_back(new FGFunction(PropertyManager, element));
|
||||||
|
} else if (operation != string("description")) {
|
||||||
|
cerr << "Bad operation " << operation << " detected in configuration file" << endl;
|
||||||
|
}
|
||||||
|
element = el->GetNextElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGFunction::~FGFunction(void)
|
||||||
|
{
|
||||||
|
string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case
|
||||||
|
PropertyManager->Untie(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFunction::cacheValue(bool cache)
|
||||||
|
{
|
||||||
|
cached = false; // Must set cached to false prior to calling GetValue(), else
|
||||||
|
// it will _never_ calculate the value;
|
||||||
|
if (cache) {
|
||||||
|
cachedValue = GetValue();
|
||||||
|
cached = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGFunction::GetValue(void) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cached) return cachedValue;
|
||||||
|
|
||||||
|
double temp = Parameters[0]->GetValue();
|
||||||
|
|
||||||
|
switch (Type) {
|
||||||
|
case eTopLevel:
|
||||||
|
break;
|
||||||
|
case eProduct:
|
||||||
|
for (i=1;i<Parameters.size();i++) temp *= Parameters[i]->GetValue();
|
||||||
|
break;
|
||||||
|
case eDifference:
|
||||||
|
for (i=1;i<Parameters.size();i++) temp -= Parameters[i]->GetValue();
|
||||||
|
break;
|
||||||
|
case eSum:
|
||||||
|
for (i=1;i<Parameters.size();i++) temp += Parameters[i]->GetValue();
|
||||||
|
break;
|
||||||
|
case eQuotient:
|
||||||
|
temp /= Parameters[1]->GetValue();
|
||||||
|
break;
|
||||||
|
case ePow:
|
||||||
|
temp = pow(temp,Parameters[1]->GetValue());
|
||||||
|
break;
|
||||||
|
case eAbs:
|
||||||
|
temp = abs(temp);
|
||||||
|
break;
|
||||||
|
case eSin:
|
||||||
|
temp = sin(temp);
|
||||||
|
break;
|
||||||
|
case eCos:
|
||||||
|
temp = cos(temp);
|
||||||
|
break;
|
||||||
|
case eTan:
|
||||||
|
temp = tan(temp);
|
||||||
|
break;
|
||||||
|
case eACos:
|
||||||
|
temp = acos(temp);
|
||||||
|
break;
|
||||||
|
case eASin:
|
||||||
|
temp = asin(temp);
|
||||||
|
break;
|
||||||
|
case eATan:
|
||||||
|
temp = atan(temp);
|
||||||
|
break;
|
||||||
|
case eATan2:
|
||||||
|
temp = atan2(temp, Parameters[1]->GetValue());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cerr << "Unknown function operation type" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGFunction::GetValueAsString(void) const
|
||||||
|
{
|
||||||
|
char buffer[20];
|
||||||
|
string value;
|
||||||
|
|
||||||
|
sprintf(buffer,"%9.6f",GetValue());
|
||||||
|
value = string(buffer);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFunction::bind(void)
|
||||||
|
{
|
||||||
|
string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case
|
||||||
|
PropertyManager->Tie( tmp, this, &FGFunction::GetValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGFunction::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
if (Type == eTopLevel)
|
||||||
|
cout << " Function: " << Name << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGGroundReactions" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGGroundReactions" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
75
src/FDM/JSBSim/math/FGFunction.h
Executable file
75
src/FDM/JSBSim/math/FGFunction.h
Executable file
|
@ -0,0 +1,75 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGFunction.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: August 25 2004
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGFUNCTION_H
|
||||||
|
#define FGFUNCTION_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "FGParameter.h"
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_FUNCTION "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Represents various types of parameters.
|
||||||
|
@author Jon Berndt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DECLARATION: FGFunction
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGFunction : public FGParameter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGFunction(FGPropertyManager* propMan, Element* el, string prefix="");
|
||||||
|
~FGFunction();
|
||||||
|
|
||||||
|
double GetValue(void) const;
|
||||||
|
string GetValueAsString(void) const;
|
||||||
|
string GetName(void) const {return Name;}
|
||||||
|
void cacheValue(bool);
|
||||||
|
|
||||||
|
private:
|
||||||
|
vector <FGParameter*> Parameters;
|
||||||
|
FGPropertyManager* const PropertyManager;
|
||||||
|
bool cached;
|
||||||
|
string Prefix;
|
||||||
|
double cachedValue;
|
||||||
|
enum functionType {eTopLevel=0, eProduct, eDifference, eSum, eQuotient, ePow,
|
||||||
|
eAbs, eSin, eCos, eTan, eASin, eACos, eATan, eATan2} Type;
|
||||||
|
string Name;
|
||||||
|
void bind(void);
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
#endif
|
221
src/FDM/JSBSim/math/FGLocation.cpp
Normal file
221
src/FDM/JSBSim/math/FGLocation.cpp
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGLocation.cpp
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 04/04/2004
|
||||||
|
Purpose: Store an arbitrary location on the globe
|
||||||
|
|
||||||
|
------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------------
|
||||||
|
------- (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) ----
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This class encapsulates an arbitrary position in the globe with its accessors.
|
||||||
|
It has vector properties, so you can add multiply ....
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
04/04/2004 MF Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <cmath>
|
||||||
|
# else
|
||||||
|
# include <math.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if defined(sgi) && !defined(__GNUC__)
|
||||||
|
# include <math.h>
|
||||||
|
# else
|
||||||
|
# include <cmath>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGLocation.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_LOCATION;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGLocation::FGLocation(double lon, double lat, double radius)
|
||||||
|
{
|
||||||
|
mCacheValid = false;
|
||||||
|
|
||||||
|
double sinLat = sin(lat);
|
||||||
|
double cosLat = cos(lat);
|
||||||
|
double sinLon = sin(lon);
|
||||||
|
double cosLon = cos(lon);
|
||||||
|
mECLoc = FGColumnVector3( radius*cosLat*cosLon,
|
||||||
|
radius*cosLat*sinLon,
|
||||||
|
radius*sinLat );
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLocation::SetLongitude(double longitude)
|
||||||
|
{
|
||||||
|
double rtmp = mECLoc.Magnitude(eX, eY);
|
||||||
|
// Check if we have zero radius.
|
||||||
|
// If so set it to 1, so that we can set a position
|
||||||
|
if (0.0 == mECLoc.Magnitude())
|
||||||
|
rtmp = 1.0;
|
||||||
|
|
||||||
|
// Fast return if we are on the north or south pole ...
|
||||||
|
if (rtmp == 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mCacheValid = false;
|
||||||
|
|
||||||
|
mECLoc(eX) = rtmp*cos(longitude);
|
||||||
|
mECLoc(eY) = rtmp*sin(longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLocation::SetLatitude(double latitude)
|
||||||
|
{
|
||||||
|
mCacheValid = false;
|
||||||
|
|
||||||
|
double r = mECLoc.Magnitude();
|
||||||
|
if (r == 0.0) {
|
||||||
|
mECLoc(eX) = 1.0;
|
||||||
|
r = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double rtmp = mECLoc.Magnitude(eX, eY);
|
||||||
|
if (rtmp != 0.0) {
|
||||||
|
double fac = r/rtmp*cos(latitude);
|
||||||
|
mECLoc(eX) *= fac;
|
||||||
|
mECLoc(eY) *= fac;
|
||||||
|
} else {
|
||||||
|
mECLoc(eX) = r*cos(latitude);
|
||||||
|
mECLoc(eY) = 0.0;
|
||||||
|
}
|
||||||
|
mECLoc(eZ) = r*sin(latitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLocation::SetRadius(double radius)
|
||||||
|
{
|
||||||
|
mCacheValid = false;
|
||||||
|
|
||||||
|
double rold = mECLoc.Magnitude();
|
||||||
|
if (rold == 0.0)
|
||||||
|
mECLoc(eX) = radius;
|
||||||
|
else
|
||||||
|
mECLoc *= radius/rold;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLocation::ComputeDerivedUnconditional(void) const
|
||||||
|
{
|
||||||
|
// The radius is just the Euclidean norm of the vector.
|
||||||
|
mRadius = mECLoc.Magnitude();
|
||||||
|
|
||||||
|
// The distance of the location to the y-axis, which is the axis
|
||||||
|
// through the poles.
|
||||||
|
double rxy = sqrt(mECLoc(eX)*mECLoc(eX) + mECLoc(eY)*mECLoc(eY));
|
||||||
|
|
||||||
|
// Compute the sin/cos values of the longitude
|
||||||
|
double sinLon, cosLon;
|
||||||
|
if (rxy == 0.0) {
|
||||||
|
sinLon = 0.0;
|
||||||
|
cosLon = 1.0;
|
||||||
|
} else {
|
||||||
|
sinLon = mECLoc(eY)/rxy;
|
||||||
|
cosLon = mECLoc(eX)/rxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the sin/cos values of the latitude
|
||||||
|
double sinLat, cosLat;
|
||||||
|
if (mRadius == 0.0) {
|
||||||
|
sinLat = 0.0;
|
||||||
|
cosLat = 1.0;
|
||||||
|
} else {
|
||||||
|
sinLat = mECLoc(eZ)/mRadius;
|
||||||
|
cosLat = rxy/mRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the longitude and latitude itself
|
||||||
|
if ( mECLoc( eX ) == 0.0 && mECLoc( eY ) == 0.0 )
|
||||||
|
mLon = 0.0;
|
||||||
|
else
|
||||||
|
mLon = atan2( mECLoc( eY ), mECLoc( eX ) );
|
||||||
|
|
||||||
|
if ( rxy == 0.0 && mECLoc( eZ ) == 0.0 )
|
||||||
|
mLat = 0.0;
|
||||||
|
else
|
||||||
|
mLat = atan2( mECLoc(eZ), rxy );
|
||||||
|
|
||||||
|
// Compute the transform matrices from and to the earth centered frame.
|
||||||
|
// see Durham Chapter 4, problem 1, page 52
|
||||||
|
mTec2l = FGMatrix33( -cosLon*sinLat, -sinLon*sinLat, cosLat,
|
||||||
|
-sinLon , cosLon , 0.0 ,
|
||||||
|
-cosLon*cosLat, -sinLon*cosLat, -sinLat );
|
||||||
|
|
||||||
|
mTl2ec = mTec2l.Transposed();
|
||||||
|
|
||||||
|
// Mark the cached values as valid
|
||||||
|
mCacheValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLocation::bind(FGPropertyManager* PropertyManager, const string& prefix) const
|
||||||
|
{
|
||||||
|
PropertyManager->Tie(prefix + "lat-gc-rad", (FGLocation*)this,
|
||||||
|
&FGLocation::GetLatitude);
|
||||||
|
PropertyManager->Tie(prefix + "lat-gc-deg", (FGLocation*)this,
|
||||||
|
&FGLocation::GetLatitudeDeg);
|
||||||
|
PropertyManager->Tie(prefix + "long-gc-rad", (FGLocation*)this,
|
||||||
|
&FGLocation::GetLongitude);
|
||||||
|
PropertyManager->Tie(prefix + "long-gc-deg", (FGLocation*)this,
|
||||||
|
&FGLocation::GetLongitudeDeg);
|
||||||
|
PropertyManager->Tie(prefix + "radius-ft", (FGLocation*)this,
|
||||||
|
&FGLocation::GetRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLocation::unbind(FGPropertyManager* PropertyManager, const string& prefix) const
|
||||||
|
{
|
||||||
|
PropertyManager->Untie(prefix + "lat-gc-rad");
|
||||||
|
PropertyManager->Untie(prefix + "lat-gc-deg");
|
||||||
|
PropertyManager->Untie(prefix + "long-gc-rad");
|
||||||
|
PropertyManager->Untie(prefix + "long-gc-deg");
|
||||||
|
PropertyManager->Untie(prefix + "radius-ft");
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
|
@ -39,8 +39,8 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGJSBBase.h"
|
#include <FGJSBBase.h>
|
||||||
#include "FGPropertyManager.h"
|
#include <input_output/FGPropertyManager.h>
|
||||||
#include "FGColumnVector3.h"
|
#include "FGColumnVector3.h"
|
||||||
#include "FGMatrix33.h"
|
#include "FGMatrix33.h"
|
||||||
|
|
|
@ -18,10 +18,6 @@ HISTORY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGMatrix33.h"
|
#include "FGMatrix33.h"
|
||||||
#include "FGColumnVector3.h"
|
#include "FGColumnVector3.h"
|
||||||
|
|
|
@ -113,12 +113,17 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Default initializer.
|
/** Default initializer.
|
||||||
Create a zero matrix. */
|
|
||||||
|
Create a zero matrix.
|
||||||
|
*/
|
||||||
FGMatrix33(void);
|
FGMatrix33(void);
|
||||||
|
|
||||||
/** Copy constructor.
|
/** Copy constructor.
|
||||||
|
|
||||||
@param M Matrix which is used for initialization.
|
@param M Matrix which is used for initialization.
|
||||||
Create copy of the matrix given in the argument. */
|
|
||||||
|
Create copy of the matrix given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33(const FGMatrix33& M) {
|
FGMatrix33(const FGMatrix33& M) {
|
||||||
Entry(1,1) = M.Entry(1,1);
|
Entry(1,1) = M.Entry(1,1);
|
||||||
Entry(2,1) = M.Entry(2,1);
|
Entry(2,1) = M.Entry(2,1);
|
||||||
|
@ -134,6 +139,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialization by given values.
|
/** Initialization by given values.
|
||||||
|
|
||||||
@param m11 value of the 1,1 Matrix element.
|
@param m11 value of the 1,1 Matrix element.
|
||||||
@param m12 value of the 1,2 Matrix element.
|
@param m12 value of the 1,2 Matrix element.
|
||||||
@param m13 value of the 1,3 Matrix element.
|
@param m13 value of the 1,3 Matrix element.
|
||||||
|
@ -143,7 +149,9 @@ public:
|
||||||
@param m31 value of the 3,1 Matrix element.
|
@param m31 value of the 3,1 Matrix element.
|
||||||
@param m32 value of the 3,2 Matrix element.
|
@param m32 value of the 3,2 Matrix element.
|
||||||
@param m33 value of the 3,3 Matrix element.
|
@param m33 value of the 3,3 Matrix element.
|
||||||
Create a matrix from the doubles given in the arguments. */
|
|
||||||
|
Create a matrix from the doubles given in the arguments.
|
||||||
|
*/
|
||||||
FGMatrix33(double m11, double m12, double m13,
|
FGMatrix33(double m11, double m12, double m13,
|
||||||
double m21, double m22, double m23,
|
double m21, double m22, double m23,
|
||||||
double m31, double m32, double m33) {
|
double m31, double m32, double m33) {
|
||||||
|
@ -160,24 +168,30 @@ public:
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor.
|
/** Destructor.
|
||||||
|
*/
|
||||||
~FGMatrix33(void) { Debug(1); }
|
~FGMatrix33(void) { Debug(1); }
|
||||||
|
|
||||||
/** Read access the entries of the matrix.
|
/** Read access the entries of the matrix.
|
||||||
@param row Row index.
|
@param row Row index.
|
||||||
@param col Column index.
|
@param col Column index.
|
||||||
|
|
||||||
@return the value of the matrix entry at the given row and
|
@return the value of the matrix entry at the given row and
|
||||||
column indices. Indices are counted starting with 1. */
|
column indices. Indices are counted starting with 1.
|
||||||
|
*/
|
||||||
double operator()(unsigned int row, unsigned int col) const {
|
double operator()(unsigned int row, unsigned int col) const {
|
||||||
return Entry(row, col);
|
return Entry(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write access the entries of the matrix.
|
/** Write access the entries of the matrix.
|
||||||
Note that the indices given in the arguments are unchecked.
|
Note that the indices given in the arguments are unchecked.
|
||||||
|
|
||||||
@param row Row index.
|
@param row Row index.
|
||||||
@param col Column index.
|
@param col Column index.
|
||||||
|
|
||||||
@return a reference to the matrix entry at the given row and
|
@return a reference to the matrix entry at the given row and
|
||||||
column indices. Indices are counted starting with 1. */
|
column indices. Indices are counted starting with 1.
|
||||||
|
*/
|
||||||
double& operator()(unsigned int row, unsigned int col) {
|
double& operator()(unsigned int row, unsigned int col) {
|
||||||
return Entry(row, col);
|
return Entry(row, col);
|
||||||
}
|
}
|
||||||
|
@ -186,11 +200,15 @@ public:
|
||||||
This function is just a shortcut for the @ref double&
|
This function is just a shortcut for the @ref double&
|
||||||
operator()(unsigned int row, unsigned int col) function. It is
|
operator()(unsigned int row, unsigned int col) function. It is
|
||||||
used internally to access the elements in a more convenient way.
|
used internally to access the elements in a more convenient way.
|
||||||
|
|
||||||
Note that the indices given in the arguments are unchecked.
|
Note that the indices given in the arguments are unchecked.
|
||||||
|
|
||||||
@param row Row index.
|
@param row Row index.
|
||||||
@param col Column index.
|
@param col Column index.
|
||||||
|
|
||||||
@return the value of the matrix entry at the given row and
|
@return the value of the matrix entry at the given row and
|
||||||
column indices. Indices are counted starting with 1. */
|
column indices. Indices are counted starting with 1.
|
||||||
|
*/
|
||||||
double Entry(unsigned int row, unsigned int col) const {
|
double Entry(unsigned int row, unsigned int col) const {
|
||||||
return data[(col-1)*eRows+row-1];
|
return data[(col-1)*eRows+row-1];
|
||||||
}
|
}
|
||||||
|
@ -199,27 +217,34 @@ public:
|
||||||
This function is just a shortcut for the @ref double&
|
This function is just a shortcut for the @ref double&
|
||||||
operator()(unsigned int row, unsigned int col) function. It is
|
operator()(unsigned int row, unsigned int col) function. It is
|
||||||
used internally to access the elements in a more convenient way.
|
used internally to access the elements in a more convenient way.
|
||||||
|
|
||||||
Note that the indices given in the arguments are unchecked.
|
Note that the indices given in the arguments are unchecked.
|
||||||
|
|
||||||
@param row Row index.
|
@param row Row index.
|
||||||
@param col Column index.
|
@param col Column index.
|
||||||
|
|
||||||
@return a reference to the matrix entry at the given row and
|
@return a reference to the matrix entry at the given row and
|
||||||
column indices. Indices are counted starting with 1. */
|
column indices. Indices are counted starting with 1.
|
||||||
|
*/
|
||||||
double& Entry(unsigned int row, unsigned int col) {
|
double& Entry(unsigned int row, unsigned int col) {
|
||||||
return data[(col-1)*eRows+row-1];
|
return data[(col-1)*eRows+row-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Number of rows in the matrix.
|
/** Number of rows in the matrix.
|
||||||
@return the number of rows in the matrix. */
|
@return the number of rows in the matrix.
|
||||||
|
*/
|
||||||
unsigned int Rows(void) const { return eRows; }
|
unsigned int Rows(void) const { return eRows; }
|
||||||
|
|
||||||
/** Number of cloumns in the matrix.
|
/** Number of cloumns in the matrix.
|
||||||
@return the number of columns in the matrix. */
|
@return the number of columns in the matrix.
|
||||||
|
*/
|
||||||
unsigned int Cols(void) const { return eColumns; }
|
unsigned int Cols(void) const { return eColumns; }
|
||||||
|
|
||||||
/** Transposed matrix.
|
/** Transposed matrix.
|
||||||
This function only returns the transpose of this matrix. This matrix itself
|
This function only returns the transpose of this matrix. This matrix itself
|
||||||
remains unchanged.
|
remains unchanged.
|
||||||
@return the transposed matrix. */
|
@return the transposed matrix.
|
||||||
|
*/
|
||||||
FGMatrix33 Transposed(void) const {
|
FGMatrix33 Transposed(void) const {
|
||||||
return FGMatrix33( Entry(1,1), Entry(2,1), Entry(3,1),
|
return FGMatrix33( Entry(1,1), Entry(2,1), Entry(3,1),
|
||||||
Entry(1,2), Entry(2,2), Entry(3,2),
|
Entry(1,2), Entry(2,2), Entry(3,2),
|
||||||
|
@ -227,15 +252,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Transposes this matrix.
|
/** Transposes this matrix.
|
||||||
This function only transposes this matrix. Nothing is returned. */
|
This function only transposes this matrix. Nothing is returned.
|
||||||
|
*/
|
||||||
void T(void);
|
void T(void);
|
||||||
|
|
||||||
/** Initialize the matrix.
|
/** Initialize the matrix.
|
||||||
This function initializes a matrix to all 0.0. */
|
This function initializes a matrix to all 0.0.
|
||||||
|
*/
|
||||||
void InitMatrix(void);
|
void InitMatrix(void);
|
||||||
|
|
||||||
/** Initialize the matrix.
|
/** Initialize the matrix.
|
||||||
This function initializes a matrix to user specified values. */
|
This function initializes a matrix to user specified values.
|
||||||
|
*/
|
||||||
void InitMatrix(double m11, double m12, double m13,
|
void InitMatrix(double m11, double m12, double m13,
|
||||||
double m21, double m22, double m23,
|
double m21, double m22, double m23,
|
||||||
double m31, double m32, double m33) {
|
double m31, double m32, double m33) {
|
||||||
|
@ -251,7 +279,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determinant of the matrix.
|
/** Determinant of the matrix.
|
||||||
@return the determinant of the matrix. */
|
@return the determinant of the matrix.
|
||||||
|
*/
|
||||||
double Determinant(void) const;
|
double Determinant(void) const;
|
||||||
|
|
||||||
/** Return if the matrix is invertible.
|
/** Return if the matrix is invertible.
|
||||||
|
@ -259,19 +288,24 @@ public:
|
||||||
invertible. This is done by simply computing the determinant and
|
invertible. This is done by simply computing the determinant and
|
||||||
check if it is zero. Note that this test does not cover any
|
check if it is zero. Note that this test does not cover any
|
||||||
instabilities caused by nearly singular matirces using finite
|
instabilities caused by nearly singular matirces using finite
|
||||||
arithmetics. It only checks exact singularity. */
|
arithmetics. It only checks exact singularity.
|
||||||
|
*/
|
||||||
bool Invertible(void) const { return 0.0 != Determinant(); }
|
bool Invertible(void) const { return 0.0 != Determinant(); }
|
||||||
|
|
||||||
/** Return the inverse of the matrix.
|
/** Return the inverse of the matrix.
|
||||||
Computes and returns if the inverse of the matrix. It is computed
|
Computes and returns if the inverse of the matrix. It is computed
|
||||||
by Cramers Rule. Also there are no checks performed if the matrix
|
by Cramers Rule. Also there are no checks performed if the matrix
|
||||||
is invertible. If you are not sure that it really is check this
|
is invertible. If you are not sure that it really is check this
|
||||||
with the @ref Invertible() call before. */
|
with the @ref Invertible() call before.
|
||||||
|
*/
|
||||||
FGMatrix33 Inverse(void) const;
|
FGMatrix33 Inverse(void) const;
|
||||||
|
|
||||||
/** Assignment operator.
|
/** Assignment operator.
|
||||||
|
|
||||||
@param A source matrix.
|
@param A source matrix.
|
||||||
Copy the content of the matrix given in the argument into *this. */
|
|
||||||
|
Copy the content of the matrix given in the argument into *this.
|
||||||
|
*/
|
||||||
FGMatrix33& operator=(const FGMatrix33& A) {
|
FGMatrix33& operator=(const FGMatrix33& A) {
|
||||||
data[0] = A.data[0];
|
data[0] = A.data[0];
|
||||||
data[1] = A.data[1];
|
data[1] = A.data[1];
|
||||||
|
@ -286,80 +320,113 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Matrix vector multiplication.
|
/** Matrix vector multiplication.
|
||||||
|
|
||||||
@param v vector to multiply with.
|
@param v vector to multiply with.
|
||||||
@return matric vector product.
|
@return matric vector product.
|
||||||
|
|
||||||
Compute and return the product of the current matrix with the
|
Compute and return the product of the current matrix with the
|
||||||
vector given in the argument. */
|
vector given in the argument.
|
||||||
|
*/
|
||||||
FGColumnVector3 operator*(const FGColumnVector3& v) const;
|
FGColumnVector3 operator*(const FGColumnVector3& v) const;
|
||||||
|
|
||||||
/** Matrix subtraction.
|
/** Matrix subtraction.
|
||||||
|
|
||||||
@param B matrix to add to.
|
@param B matrix to add to.
|
||||||
@return difference of the matrices.
|
@return difference of the matrices.
|
||||||
|
|
||||||
Compute and return the sum of the current matrix and the matrix
|
Compute and return the sum of the current matrix and the matrix
|
||||||
B given in the argument. */
|
B given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33 operator-(const FGMatrix33& B) const;
|
FGMatrix33 operator-(const FGMatrix33& B) const;
|
||||||
|
|
||||||
/** Matrix addition.
|
/** Matrix addition.
|
||||||
|
|
||||||
@param B matrix to add to.
|
@param B matrix to add to.
|
||||||
@return sum of the matrices.
|
@return sum of the matrices.
|
||||||
|
|
||||||
Compute and return the sum of the current matrix and the matrix
|
Compute and return the sum of the current matrix and the matrix
|
||||||
B given in the argument. */
|
B given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33 operator+(const FGMatrix33& B) const;
|
FGMatrix33 operator+(const FGMatrix33& B) const;
|
||||||
|
|
||||||
/** Matrix product.
|
/** Matrix product.
|
||||||
|
|
||||||
@param B matrix to add to.
|
@param B matrix to add to.
|
||||||
@return product of the matrices.
|
@return product of the matrices.
|
||||||
|
|
||||||
Compute and return the product of the current matrix and the matrix
|
Compute and return the product of the current matrix and the matrix
|
||||||
B given in the argument. */
|
B given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33 operator*(const FGMatrix33& B) const;
|
FGMatrix33 operator*(const FGMatrix33& B) const;
|
||||||
|
|
||||||
/** Multiply the matrix with a scalar.
|
/** Multiply the matrix with a scalar.
|
||||||
|
|
||||||
@param scalar scalar factor to multiply with.
|
@param scalar scalar factor to multiply with.
|
||||||
@return scaled matrix.
|
@return scaled matrix.
|
||||||
|
|
||||||
Compute and return the product of the current matrix with the
|
Compute and return the product of the current matrix with the
|
||||||
scalar value scalar given in the argument. */
|
scalar value scalar given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33 operator*(const double scalar) const;
|
FGMatrix33 operator*(const double scalar) const;
|
||||||
|
|
||||||
/** Multiply the matrix with 1.0/scalar.
|
/** Multiply the matrix with 1.0/scalar.
|
||||||
|
|
||||||
@param scalar scalar factor to divide through.
|
@param scalar scalar factor to divide through.
|
||||||
@return scaled matrix.
|
@return scaled matrix.
|
||||||
|
|
||||||
Compute and return the product of the current matrix with the
|
Compute and return the product of the current matrix with the
|
||||||
scalar value 1.0/scalar, where scalar is given in the argument. */
|
scalar value 1.0/scalar, where scalar is given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33 operator/(const double scalar) const;
|
FGMatrix33 operator/(const double scalar) const;
|
||||||
|
|
||||||
/** In place matrix subtraction.
|
/** In place matrix subtraction.
|
||||||
|
|
||||||
@param B matrix to subtract.
|
@param B matrix to subtract.
|
||||||
@return reference to the current matrix.
|
@return reference to the current matrix.
|
||||||
|
|
||||||
Compute the diffence from the current matrix and the matrix B
|
Compute the diffence from the current matrix and the matrix B
|
||||||
given in the argument. */
|
given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33& operator-=(const FGMatrix33 &B);
|
FGMatrix33& operator-=(const FGMatrix33 &B);
|
||||||
|
|
||||||
/** In place matrix addition.
|
/** In place matrix addition.
|
||||||
|
|
||||||
@param B matrix to add.
|
@param B matrix to add.
|
||||||
@return reference to the current matrix.
|
@return reference to the current matrix.
|
||||||
|
|
||||||
Compute the sum of the current matrix and the matrix B
|
Compute the sum of the current matrix and the matrix B
|
||||||
given in the argument. */
|
given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33& operator+=(const FGMatrix33 &B);
|
FGMatrix33& operator+=(const FGMatrix33 &B);
|
||||||
|
|
||||||
/** In place matrix multiplication.
|
/** In place matrix multiplication.
|
||||||
|
|
||||||
@param B matrix to multiply with.
|
@param B matrix to multiply with.
|
||||||
@return reference to the current matrix.
|
@return reference to the current matrix.
|
||||||
|
|
||||||
Compute the product of the current matrix and the matrix B
|
Compute the product of the current matrix and the matrix B
|
||||||
given in the argument. */
|
given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33& operator*=(const FGMatrix33 &B);
|
FGMatrix33& operator*=(const FGMatrix33 &B);
|
||||||
|
|
||||||
/** In place matrix scale.
|
/** In place matrix scale.
|
||||||
|
|
||||||
@param scalar scalar value to multiply with.
|
@param scalar scalar value to multiply with.
|
||||||
@return reference to the current matrix.
|
@return reference to the current matrix.
|
||||||
|
|
||||||
Compute the product of the current matrix and the scalar value scalar
|
Compute the product of the current matrix and the scalar value scalar
|
||||||
given in the argument. */
|
given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33& operator*=(const double scalar);
|
FGMatrix33& operator*=(const double scalar);
|
||||||
|
|
||||||
/** In place matrix scale.
|
/** In place matrix scale.
|
||||||
|
|
||||||
@param scalar scalar value to divide through.
|
@param scalar scalar value to divide through.
|
||||||
@return reference to the current matrix.
|
@return reference to the current matrix.
|
||||||
|
|
||||||
Compute the product of the current matrix and the scalar value
|
Compute the product of the current matrix and the scalar value
|
||||||
1.0/scalar, where scalar is given in the argument. */
|
1.0/scalar, where scalar is given in the argument.
|
||||||
|
*/
|
||||||
FGMatrix33& operator/=(const double scalar);
|
FGMatrix33& operator/=(const double scalar);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -369,24 +436,33 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Scalar multiplication.
|
/** Scalar multiplication.
|
||||||
|
|
||||||
@param scalar scalar value to multiply with.
|
@param scalar scalar value to multiply with.
|
||||||
@param A Matrix to multiply.
|
@param A Matrix to multiply.
|
||||||
Multiply the Matrix with a scalar value.*/
|
|
||||||
|
Multiply the Matrix with a scalar value.
|
||||||
|
*/
|
||||||
inline FGMatrix33 operator*(double scalar, const FGMatrix33& A) {
|
inline FGMatrix33 operator*(double scalar, const FGMatrix33& A) {
|
||||||
// use already defined operation.
|
// use already defined operation.
|
||||||
return A*scalar;
|
return A*scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write matrix to a stream.
|
/** Write matrix to a stream.
|
||||||
|
|
||||||
@param os Stream to write to.
|
@param os Stream to write to.
|
||||||
@param M Matrix to write.
|
@param M Matrix to write.
|
||||||
Write the matrix to a stream.*/
|
|
||||||
|
Write the matrix to a stream.
|
||||||
|
*/
|
||||||
ostream& operator<<(ostream& os, const FGMatrix33& M);
|
ostream& operator<<(ostream& os, const FGMatrix33& M);
|
||||||
|
|
||||||
/** Read matrix from a stream.
|
/** Read matrix from a stream.
|
||||||
|
|
||||||
@param os Stream to read from.
|
@param os Stream to read from.
|
||||||
@param M Matrix to initialize with the values from the stream.
|
@param M Matrix to initialize with the values from the stream.
|
||||||
Read matrix from a stream.*/
|
|
||||||
|
Read matrix from a stream.
|
||||||
|
*/
|
||||||
istream& operator>>(istream& is, FGMatrix33& M);
|
istream& operator>>(istream& is, FGMatrix33& M);
|
||||||
|
|
||||||
} // namespace JSBSim
|
} // namespace JSBSim
|
55
src/FDM/JSBSim/math/FGParameter.h
Executable file
55
src/FDM/JSBSim/math/FGParameter.h
Executable file
|
@ -0,0 +1,55 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGParameter.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: August 25 2004
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGPARAMETER_H
|
||||||
|
#define FGPARAMETER_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGJSBBase.h"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_PARAMETER "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Represents various types of parameters.
|
||||||
|
@author Jon Berndt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DECLARATION: FGParameter
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGParameter : public FGJSBBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual double GetValue(void) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
#endif
|
34
src/FDM/JSBSim/math/FGPropertyValue.cpp
Executable file
34
src/FDM/JSBSim/math/FGPropertyValue.cpp
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGPropertyValue.cpp
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 12/10/2004
|
||||||
|
Purpose: Stores property values
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGPropertyValue.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_PROPERTYVALUE;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGPropertyValue::FGPropertyValue(FGPropertyManager* propNode) : PropertyManager(propNode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGPropertyValue::GetValue(void) const
|
||||||
|
{
|
||||||
|
return PropertyManager->getDoubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
60
src/FDM/JSBSim/math/FGPropertyValue.h
Executable file
60
src/FDM/JSBSim/math/FGPropertyValue.h
Executable file
|
@ -0,0 +1,60 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGPropertyValue.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: December 10 2004
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGPROPERTYVALUE_H
|
||||||
|
#define FGPROPERTYVALUE_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGParameter.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_PROPERTYVALUE "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Represents a property value
|
||||||
|
@author Jon Berndt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DECLARATION: FGPropertyValue
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGPropertyValue : public FGParameter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGPropertyValue(FGPropertyManager* propNode);
|
||||||
|
~FGPropertyValue() {};
|
||||||
|
|
||||||
|
double GetValue(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FGPropertyManager* PropertyManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
#endif
|
|
@ -38,10 +38,6 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
# include <simgear/compiler.h>
|
# include <simgear/compiler.h>
|
|
@ -40,10 +40,10 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGJSBBase.h"
|
#include <FGJSBBase.h>
|
||||||
#include "FGMatrix33.h"
|
#include "FGMatrix33.h"
|
||||||
#include "FGColumnVector3.h"
|
#include "FGColumnVector3.h"
|
||||||
#include "FGPropertyManager.h"
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
34
src/FDM/JSBSim/math/FGRealValue.cpp
Executable file
34
src/FDM/JSBSim/math/FGRealValue.cpp
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGRealValue.cpp
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 12/10/2004
|
||||||
|
Purpose: Stores real values
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGRealValue.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_REALVALUE;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGRealValue::FGRealValue(double value) : Value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGRealValue::GetValue(void) const
|
||||||
|
{
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
59
src/FDM/JSBSim/math/FGRealValue.h
Executable file
59
src/FDM/JSBSim/math/FGRealValue.h
Executable file
|
@ -0,0 +1,59 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGRealValue.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: December 10 2004
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGREALVALUE_H
|
||||||
|
#define FGREALVALUE_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGParameter.h"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_REALVALUE "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Represents a real value
|
||||||
|
@author Jon Berndt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DECLARATION: FGRealValue
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGRealValue : public FGParameter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGRealValue(double val);
|
||||||
|
~FGRealValue() {};
|
||||||
|
|
||||||
|
double GetValue(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
double Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
#endif
|
|
@ -36,16 +36,12 @@ JSB 1/9/00 Created
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGTable.h"
|
#include "FGTable.h"
|
||||||
|
|
||||||
#if defined ( sgi ) && !defined( __GNUC__ ) && (_COMPILER_VERSION < 740)
|
#if defined ( sgi ) && !defined( __GNUC__ ) && (_COMPILER_VERSION < 740)
|
||||||
#include <iomanip.h>
|
# include <iomanip.h>
|
||||||
#else
|
#else
|
||||||
#include <iomanip>
|
# include <iomanip>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -59,50 +55,12 @@ static const char *IdHdr = ID_TABLE;
|
||||||
CLASS IMPLEMENTATION
|
CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGTable::FGTable(int NRows) : nRows(NRows), nCols(1), PropertyManager(0)
|
||||||
FGTable::FGTable(int NRows, int NCols, int NTables)
|
|
||||||
: nRows(NTables), nCols(1), nTables(NTables)
|
|
||||||
{
|
|
||||||
Type = tt3D;
|
|
||||||
colCounter = 1;
|
|
||||||
rowCounter = 1;
|
|
||||||
|
|
||||||
Data = Allocate(); // this data array will contain the keys for the associated tables
|
|
||||||
Tables.reserve(nTables);
|
|
||||||
for (int i=0; i<nTables; i++) Tables.push_back(FGTable(NRows, NCols));
|
|
||||||
lastRowIndex=lastColumnIndex=2;
|
|
||||||
|
|
||||||
Debug(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
FGTable::FGTable(int NRows, int NCols) : nRows(NRows), nCols(NCols)
|
|
||||||
{
|
|
||||||
if (NCols > 1) {
|
|
||||||
Type = tt2D;
|
|
||||||
colCounter = 1;
|
|
||||||
rowCounter = 0;
|
|
||||||
} else if (NCols == 1) {
|
|
||||||
Type = tt1D;
|
|
||||||
colCounter = 0;
|
|
||||||
rowCounter = 1;
|
|
||||||
} else {
|
|
||||||
cerr << "FGTable cannot accept 'Rows=0'" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
Data = Allocate();
|
|
||||||
lastRowIndex=lastColumnIndex=2;
|
|
||||||
Debug(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
FGTable::FGTable(int NRows) : nRows(NRows), nCols(1)
|
|
||||||
{
|
{
|
||||||
Type = tt1D;
|
Type = tt1D;
|
||||||
colCounter = 0;
|
colCounter = 0;
|
||||||
rowCounter = 1;
|
rowCounter = 1;
|
||||||
|
nTables = 0;
|
||||||
|
|
||||||
Data = Allocate();
|
Data = Allocate();
|
||||||
Debug(0);
|
Debug(0);
|
||||||
|
@ -111,16 +69,17 @@ FGTable::FGTable(int NRows) : nRows(NRows), nCols(1)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGTable::FGTable(const FGTable& t)
|
FGTable::FGTable(const FGTable& t) : PropertyManager(t.PropertyManager)
|
||||||
{
|
{
|
||||||
Type = t.Type;
|
Type = t.Type;
|
||||||
colCounter = t.colCounter;
|
colCounter = t.colCounter;
|
||||||
rowCounter = t.rowCounter;
|
rowCounter = t.rowCounter;
|
||||||
tableCounter = t.tableCounter;
|
tableCounter = t.tableCounter;
|
||||||
|
|
||||||
nRows = t.nRows;
|
nRows = t.nRows;
|
||||||
nCols = t.nCols;
|
nCols = t.nCols;
|
||||||
nTables = t.nTables;
|
nTables = t.nTables;
|
||||||
|
dimension = t.dimension;
|
||||||
|
internal = t.internal;
|
||||||
|
|
||||||
Tables = t.Tables;
|
Tables = t.Tables;
|
||||||
Data = Allocate();
|
Data = Allocate();
|
||||||
|
@ -136,6 +95,168 @@ FGTable::FGTable(const FGTable& t)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(propMan)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
stringstream buf;
|
||||||
|
string property_string;
|
||||||
|
string lookup_axis;
|
||||||
|
string call_type;
|
||||||
|
string parent_type;
|
||||||
|
FGPropertyManager* node;
|
||||||
|
Element *tableData;
|
||||||
|
Element *parent_element;
|
||||||
|
Element *axisElement;
|
||||||
|
string operation_types = "function, product, sum, difference, quotient,"
|
||||||
|
"pow, abs, sin, cos, asin, acos, tan, atan, table";
|
||||||
|
|
||||||
|
nTables = 0;
|
||||||
|
|
||||||
|
// Is this an internal lookup table?
|
||||||
|
|
||||||
|
internal = false;
|
||||||
|
call_type = el->GetAttributeValue("type");
|
||||||
|
if (call_type == string("internal")) {
|
||||||
|
parent_element = el->GetParent();
|
||||||
|
parent_type = parent_element->GetName();
|
||||||
|
if (operation_types.find(parent_type) == string::npos) {
|
||||||
|
internal = true;
|
||||||
|
} else {
|
||||||
|
// internal table is a child element of a restricted type
|
||||||
|
cerr << endl << fgred << " An internal table cannot be nested within another type," << endl;
|
||||||
|
cerr << " such as a function. The 'internal' keyword is ignored." << fgdef << endl << endl;
|
||||||
|
}
|
||||||
|
} else if (!call_type.empty()) {
|
||||||
|
cerr << endl << fgred << " An unknown table type attribute is listed: " << call_type
|
||||||
|
<< ". Execution cannot continue." << fgdef << endl << endl;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine and store the lookup properties for this table unless this table
|
||||||
|
// is part of a 3D table, in which case its independentVar property indexes will
|
||||||
|
// be set by a call from the owning table during creation
|
||||||
|
|
||||||
|
dimension = 0;
|
||||||
|
|
||||||
|
axisElement = el->FindElement("independentVar");
|
||||||
|
if (axisElement) {
|
||||||
|
|
||||||
|
// The 'internal' attribute of the table element cannot be specified
|
||||||
|
// at the same time that independentVars are specified.
|
||||||
|
if (internal) {
|
||||||
|
cerr << endl << fgred << " This table specifies both 'internal' call type" << endl;
|
||||||
|
cerr << " and specific lookup properties via the 'independentVar' element." << endl;
|
||||||
|
cerr << " These are mutually exclusive specifications. The 'internal'" << endl;
|
||||||
|
cerr << " attribute will be ignored." << fgdef << endl << endl;
|
||||||
|
internal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<3; i++) lookupProperty[i] = 0;
|
||||||
|
|
||||||
|
while (axisElement) {
|
||||||
|
property_string = axisElement->GetDataLine();
|
||||||
|
node = PropertyManager->GetNode(property_string);
|
||||||
|
|
||||||
|
lookup_axis = axisElement->GetAttributeValue("lookup");
|
||||||
|
if (lookup_axis == string("row")) {
|
||||||
|
lookupProperty[eRow] = node;
|
||||||
|
} else if (lookup_axis == string("column")) {
|
||||||
|
lookupProperty[eColumn] = node;
|
||||||
|
} else if (lookup_axis == string("table")) {
|
||||||
|
lookupProperty[eTable] = node;
|
||||||
|
} else { // assumed single dimension table; row lookup
|
||||||
|
lookupProperty[eRow] = node;
|
||||||
|
}
|
||||||
|
dimension++;
|
||||||
|
axisElement = el->FindNextElement("independentVar");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (internal) { // This table is an internal table
|
||||||
|
|
||||||
|
// determine how many rows, columns, and tables in this table (dimension).
|
||||||
|
|
||||||
|
if (el->GetNumElements("tableData") > 1) {
|
||||||
|
dimension = 3; // this is a 3D table
|
||||||
|
} else {
|
||||||
|
tableData = el->FindElement("tableData");
|
||||||
|
string test_line = tableData->GetDataLine(1); // examine second line in table for dimension
|
||||||
|
if (FindNumColumns(test_line) == 2) dimension = 1; // 1D table
|
||||||
|
else if (FindNumColumns(test_line) > 2) dimension = 2; // 2D table
|
||||||
|
else {
|
||||||
|
cerr << "Invalid number of columns in table" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // no independentVars found, and table is not marked as internal
|
||||||
|
cerr << endl << fgred << "No independent variable found for table." << fgdef << endl << endl;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// end lookup property code
|
||||||
|
|
||||||
|
tableData = el->FindElement("tableData");
|
||||||
|
for (int i=0; i<tableData->GetNumDataLines(); i++) {
|
||||||
|
buf << tableData->GetDataLine(i) << string(" ");
|
||||||
|
}
|
||||||
|
switch (dimension) {
|
||||||
|
case 1:
|
||||||
|
nRows = tableData->GetNumDataLines();
|
||||||
|
nCols = 1;
|
||||||
|
Type = tt1D;
|
||||||
|
colCounter = 0;
|
||||||
|
rowCounter = 1;
|
||||||
|
Data = Allocate();
|
||||||
|
Debug(0);
|
||||||
|
lastRowIndex = lastColumnIndex = 2;
|
||||||
|
*this << buf;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
nRows = tableData->GetNumDataLines()-1;
|
||||||
|
|
||||||
|
if (nRows >= 2) nCols = FindNumColumns(tableData->GetDataLine(0));
|
||||||
|
else {
|
||||||
|
cerr << endl << fgred << "Not enough rows in this table." << fgdef << endl;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type = tt2D;
|
||||||
|
colCounter = 1;
|
||||||
|
rowCounter = 0;
|
||||||
|
|
||||||
|
Data = Allocate();
|
||||||
|
lastRowIndex = lastColumnIndex = 2;
|
||||||
|
*this << buf;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
nTables = el->GetNumElements("tableData");
|
||||||
|
nRows = nTables;
|
||||||
|
nCols = 1;
|
||||||
|
Type = tt3D;
|
||||||
|
colCounter = 1;
|
||||||
|
rowCounter = 1;
|
||||||
|
|
||||||
|
Data = Allocate(); // this data array will contain the keys for the associated tables
|
||||||
|
Tables.reserve(nTables); // necessary?
|
||||||
|
tableData = el->FindElement("tableData");
|
||||||
|
for (i=0; i<nTables; i++) {
|
||||||
|
Tables.push_back(new FGTable(PropertyManager, tableData));
|
||||||
|
Data[i+1][1] = tableData->GetAttributeValueAsNumber("breakPoint");
|
||||||
|
Tables[i]->SetRowIndexProperty(lookupProperty[eRow]);
|
||||||
|
Tables[i]->SetColumnIndexProperty(lookupProperty[eColumn]);
|
||||||
|
tableData = el->FindNextElement("tableData");
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cout << "No dimension given" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 1) Print();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
double** FGTable::Allocate(void)
|
double** FGTable::Allocate(void)
|
||||||
{
|
{
|
||||||
Data = new double*[nRows+1];
|
Data = new double*[nRows+1];
|
||||||
|
@ -152,7 +273,11 @@ double** FGTable::Allocate(void)
|
||||||
|
|
||||||
FGTable::~FGTable()
|
FGTable::~FGTable()
|
||||||
{
|
{
|
||||||
if (nTables > 0) Tables.clear();
|
if (nTables > 0) {
|
||||||
|
cout << "nTables = " << nTables << endl;
|
||||||
|
for (int i=0; i<nTables; i++) delete Tables[i];
|
||||||
|
Tables.clear();
|
||||||
|
}
|
||||||
for (int r=0; r<=nRows; r++) if (Data[r]) delete[] Data[r];
|
for (int r=0; r<=nRows; r++) if (Data[r]) delete[] Data[r];
|
||||||
if (Data) delete[] Data;
|
if (Data) delete[] Data;
|
||||||
Debug(1);
|
Debug(1);
|
||||||
|
@ -160,7 +285,46 @@ FGTable::~FGTable()
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
double FGTable::GetValue(double key)
|
int FGTable::FindNumColumns(string test_line)
|
||||||
|
{
|
||||||
|
// determine number of data columns in table (first column is row lookup - don't count)
|
||||||
|
int position=0;
|
||||||
|
int nCols=0;
|
||||||
|
while ((position = test_line.find_first_not_of(" \t", position)) != string::npos) {
|
||||||
|
nCols++;
|
||||||
|
position = test_line.find_first_of(" \t", position);
|
||||||
|
}
|
||||||
|
return nCols;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGTable::GetValue(void) const
|
||||||
|
{
|
||||||
|
double temp = 0;
|
||||||
|
double temp2 = 0;
|
||||||
|
|
||||||
|
switch (Type) {
|
||||||
|
case tt1D:
|
||||||
|
temp = lookupProperty[eRow]->getDoubleValue();
|
||||||
|
temp2 = GetValue(temp);
|
||||||
|
return temp2;
|
||||||
|
case tt2D:
|
||||||
|
return GetValue(lookupProperty[eRow]->getDoubleValue(),
|
||||||
|
lookupProperty[eColumn]->getDoubleValue());
|
||||||
|
case tt3D:
|
||||||
|
return GetValue(lookupProperty[eRow]->getDoubleValue(),
|
||||||
|
lookupProperty[eColumn]->getDoubleValue(),
|
||||||
|
lookupProperty[eTable]->getDoubleValue());
|
||||||
|
default:
|
||||||
|
cerr << "Attempted to GetValue() for invalid/unknown table type" << endl;
|
||||||
|
throw(string("Attempted to GetValue() for invalid/unknown table type"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGTable::GetValue(double key) const
|
||||||
{
|
{
|
||||||
double Factor, Value, Span;
|
double Factor, Value, Span;
|
||||||
int r=lastRowIndex;
|
int r=lastRowIndex;
|
||||||
|
@ -205,8 +369,7 @@ double FGTable::GetValue(double key)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGTable::GetValue(double rowKey, double colKey) const
|
||||||
double FGTable::GetValue(double rowKey, double colKey)
|
|
||||||
{
|
{
|
||||||
double rFactor, cFactor, col1temp, col2temp, Value;
|
double rFactor, cFactor, col1temp, col2temp, Value;
|
||||||
int r=lastRowIndex;
|
int r=lastRowIndex;
|
||||||
|
@ -215,7 +378,6 @@ double FGTable::GetValue(double rowKey, double colKey)
|
||||||
if ( r > 2 && Data[r-1][0] > rowKey ) {
|
if ( r > 2 && Data[r-1][0] > rowKey ) {
|
||||||
while ( Data[r-1][0] > rowKey && r > 2) { r--; }
|
while ( Data[r-1][0] > rowKey && r > 2) { r--; }
|
||||||
} else if ( Data[r][0] < rowKey ) {
|
} else if ( Data[r][0] < rowKey ) {
|
||||||
// cout << Data[r][0] << endl;
|
|
||||||
while ( r <= nRows && Data[r][0] <= rowKey ) { r++; }
|
while ( r <= nRows && Data[r][0] <= rowKey ) { r++; }
|
||||||
if ( r > nRows ) r = nRows;
|
if ( r > nRows ) r = nRows;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +411,7 @@ double FGTable::GetValue(double rowKey, double colKey)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
double FGTable::GetValue(double rowKey, double colKey, double tableKey)
|
double FGTable::GetValue(double rowKey, double colKey, double tableKey) const
|
||||||
{
|
{
|
||||||
double Factor, Value, Span;
|
double Factor, Value, Span;
|
||||||
int r=lastRowIndex;
|
int r=lastRowIndex;
|
||||||
|
@ -259,10 +421,10 @@ double FGTable::GetValue(double rowKey, double colKey, double tableKey)
|
||||||
|
|
||||||
if( tableKey <= Data[1][1] ) {
|
if( tableKey <= Data[1][1] ) {
|
||||||
lastRowIndex=2;
|
lastRowIndex=2;
|
||||||
return Tables[0].GetValue(rowKey, colKey);
|
return Tables[0]->GetValue(rowKey, colKey);
|
||||||
} else if ( tableKey >= Data[nRows][1] ) {
|
} else if ( tableKey >= Data[nRows][1] ) {
|
||||||
lastRowIndex=nRows;
|
lastRowIndex=nRows;
|
||||||
return Tables[nRows-1].GetValue(rowKey, colKey);
|
return Tables[nRows-1]->GetValue(rowKey, colKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the key is somewhere in the middle, search for the right breakpoint
|
// the key is somewhere in the middle, search for the right breakpoint
|
||||||
|
@ -286,19 +448,18 @@ double FGTable::GetValue(double rowKey, double colKey, double tableKey)
|
||||||
Factor = 1.0;
|
Factor = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value = Factor*(Tables[r-1].GetValue(rowKey, colKey) - Tables[r-2].GetValue(rowKey, colKey))
|
Value = Factor*(Tables[r-1]->GetValue(rowKey, colKey) - Tables[r-2]->GetValue(rowKey, colKey))
|
||||||
+ Tables[r-2].GetValue(rowKey, colKey);
|
+ Tables[r-2]->GetValue(rowKey, colKey);
|
||||||
|
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGTable::operator<<(FGConfigFile& infile)
|
void FGTable::operator<<(stringstream& in_stream)
|
||||||
{
|
{
|
||||||
int startRow=0;
|
int startRow=0;
|
||||||
int startCol=0;
|
int startCol=0;
|
||||||
int tableCtr=0;
|
|
||||||
|
|
||||||
if (Type == tt1D || Type == tt3D) startRow = 1;
|
if (Type == tt1D || Type == tt3D) startRow = 1;
|
||||||
if (Type == tt3D) startCol = 1;
|
if (Type == tt3D) startCol = 1;
|
||||||
|
@ -306,11 +467,7 @@ void FGTable::operator<<(FGConfigFile& infile)
|
||||||
for (int r=startRow; r<=nRows; r++) {
|
for (int r=startRow; r<=nRows; r++) {
|
||||||
for (int c=startCol; c<=nCols; c++) {
|
for (int c=startCol; c<=nCols; c++) {
|
||||||
if (r != 0 || c != 0) {
|
if (r != 0 || c != 0) {
|
||||||
infile >> Data[r][c];
|
in_stream >> Data[r][c];
|
||||||
if (Type == tt3D) {
|
|
||||||
Tables[tableCtr] << infile;
|
|
||||||
tableCtr++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,9 +497,8 @@ FGTable& FGTable::operator<<(const int n)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGTable::Print(int spaces)
|
void FGTable::Print(void)
|
||||||
{
|
{
|
||||||
string tabspace;
|
|
||||||
int startRow=0;
|
int startRow=0;
|
||||||
int startCol=0;
|
int startCol=0;
|
||||||
|
|
||||||
|
@ -355,11 +511,22 @@ void FGTable::Print(int spaces)
|
||||||
ios::fmtflags flags = cout.setf(ios::fixed); // set up output stream
|
ios::fmtflags flags = cout.setf(ios::fixed); // set up output stream
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i=0;i<spaces;i++) tabspace+=" ";
|
switch(Type) {
|
||||||
|
case tt1D:
|
||||||
|
cout << " 1 dimensional table with " << nRows << " rows." << endl;
|
||||||
|
break;
|
||||||
|
case tt2D:
|
||||||
|
cout << " 2 dimensional table with " << nRows << " rows, " << nCols << " columns." << endl;
|
||||||
|
break;
|
||||||
|
case tt3D:
|
||||||
|
cout << " 3 dimensional table with " << nRows << " rows, "
|
||||||
|
<< nCols << " columns "
|
||||||
|
<< nTables << " tables." << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
cout.precision(4);
|
cout.precision(4);
|
||||||
for (int r=startRow; r<=nRows; r++) {
|
for (int r=startRow; r<=nRows; r++) {
|
||||||
cout << tabspace;
|
cout << " ";
|
||||||
for (int c=startCol; c<=nCols; c++) {
|
for (int c=startCol; c<=nCols; c++) {
|
||||||
if (r == 0 && c == 0) {
|
if (r == 0 && c == 0) {
|
||||||
cout << " ";
|
cout << " ";
|
||||||
|
@ -367,7 +534,7 @@ void FGTable::Print(int spaces)
|
||||||
cout << Data[r][c] << " ";
|
cout << Data[r][c] << " ";
|
||||||
if (Type == tt3D) {
|
if (Type == tt3D) {
|
||||||
cout << endl;
|
cout << endl;
|
||||||
Tables[r-1].Print(spaces);
|
Tables[r-1]->Print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,8 +38,10 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGConfigFile.h"
|
#include <input_output/FGXMLElement.h>
|
||||||
#include "FGJSBBase.h"
|
#include "FGParameter.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -53,6 +55,7 @@ FORWARD DECLARATIONS
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using std::stringstream;
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -199,7 +202,7 @@ CLASS DOCUMENTATION
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
class FGTable : public FGJSBBase
|
class FGTable : public FGParameter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Destructor
|
/// Destructor
|
||||||
|
@ -209,14 +212,13 @@ public:
|
||||||
@param table a const reference to a table.*/
|
@param table a const reference to a table.*/
|
||||||
FGTable(const FGTable& table);
|
FGTable(const FGTable& table);
|
||||||
|
|
||||||
/** The constructor for a VECTOR table
|
/// The constructor for a table
|
||||||
@param nRows the number of rows in this VECTOR table. */
|
FGTable (FGPropertyManager* propMan, Element* el);
|
||||||
FGTable(int nRows);
|
FGTable (int );
|
||||||
FGTable(int nRows, int nCols);
|
double GetValue(void) const;
|
||||||
FGTable(int nRows, int nCols, int numTables);
|
double GetValue(double key) const;
|
||||||
double GetValue(double key);
|
double GetValue(double rowKey, double colKey) const;
|
||||||
double GetValue(double rowKey, double colKey);
|
double GetValue(double rowKey, double colKey, double TableKey) const;
|
||||||
double GetValue(double rowKey, double colKey, double TableKey);
|
|
||||||
/** Read the table in.
|
/** Read the table in.
|
||||||
Data in the config file should be in matrix format with the row
|
Data in the config file should be in matrix format with the row
|
||||||
independents as the first column and the column independents in
|
independents as the first column and the column independents in
|
||||||
|
@ -239,21 +241,32 @@ public:
|
||||||
</pre>
|
</pre>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void operator<<(FGConfigFile&);
|
void operator<<(stringstream&);
|
||||||
FGTable& operator<<(const double n);
|
FGTable& operator<<(const double n);
|
||||||
FGTable& operator<<(const int n);
|
FGTable& operator<<(const int n);
|
||||||
|
|
||||||
inline double GetElement(int r, int c) {return Data[r][c];}
|
inline double GetElement(int r, int c) {return Data[r][c];}
|
||||||
inline double GetElement(int r, int c, int t);
|
inline double GetElement(int r, int c, int t);
|
||||||
void Print(int spaces=0);
|
|
||||||
|
void SetRowIndexProperty(FGPropertyManager *node) {lookupProperty[eRow] = node;}
|
||||||
|
void SetColumnIndexProperty(FGPropertyManager *node) {lookupProperty[eColumn] = node;}
|
||||||
|
|
||||||
|
void Print(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum type {tt1D, tt2D, tt3D} Type;
|
enum type {tt1D, tt2D, tt3D} Type;
|
||||||
|
enum axis {eRow=0, eColumn, eTable};
|
||||||
|
bool internal;
|
||||||
|
FGPropertyManager *lookupProperty[3];
|
||||||
double** Data;
|
double** Data;
|
||||||
vector <FGTable> Tables;
|
vector <FGTable*> Tables;
|
||||||
int nRows, nCols, nTables;
|
int FindNumColumns(string);
|
||||||
|
int nRows, nCols, nTables, dimension;
|
||||||
int colCounter, rowCounter, tableCounter;
|
int colCounter, rowCounter, tableCounter;
|
||||||
int lastRowIndex, lastColumnIndex, lastTableIndex;
|
mutable int lastRowIndex, lastColumnIndex, lastTableIndex;
|
||||||
double** Allocate(void);
|
double** Allocate(void);
|
||||||
|
FGPropertyManager* const PropertyManager;
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
||||||
}
|
}
|
9
src/FDM/JSBSim/math/Makefile.am
Normal file
9
src/FDM/JSBSim/math/Makefile.am
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
noinst_LIBRARIES = libMath.a
|
||||||
|
|
||||||
|
libMath_a_SOURCES = FGColumnVector3.cpp FGFunction.cpp FGLocation.cpp FGMatrix33.cpp \
|
||||||
|
FGPropertyValue.cpp FGQuaternion.cpp FGRealValue.cpp FGTable.cpp
|
||||||
|
|
||||||
|
noinst_HEADERS = FGColumnVector3.h FGFunction.h FGLocation.h FGMatrix33.h \
|
||||||
|
FGParameter.h FGPropertyValue.h FGQuaternion.h FGRealValue.h FGTable.h
|
||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
|
403
src/FDM/JSBSim/models/FGAerodynamics.cpp
Normal file
403
src/FDM/JSBSim/models/FGAerodynamics.cpp
Normal file
|
@ -0,0 +1,403 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGAerodynamics.cpp
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 09/13/00
|
||||||
|
Purpose: Encapsulates the aerodynamic forces
|
||||||
|
|
||||||
|
------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
09/13/00 JSB Created
|
||||||
|
04/22/01 JSB Moved code into here from FGAircraft
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGAerodynamics.h"
|
||||||
|
#include "FGPropagate.h"
|
||||||
|
#include "FGAircraft.h"
|
||||||
|
#include "FGState.h"
|
||||||
|
#include "FGMassBalance.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_AERODYNAMICS;
|
||||||
|
|
||||||
|
const unsigned NAxes=6;
|
||||||
|
const char* AxisNames[] = { "drag", "side-force", "lift", "rolling-moment",
|
||||||
|
"pitching-moment","yawing-moment" };
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
|
FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec)
|
||||||
|
{
|
||||||
|
Name = "FGAerodynamics";
|
||||||
|
|
||||||
|
AxisIdx["DRAG"] = 0;
|
||||||
|
AxisIdx["SIDE"] = 1;
|
||||||
|
AxisIdx["LIFT"] = 2;
|
||||||
|
AxisIdx["ROLL"] = 3;
|
||||||
|
AxisIdx["PITCH"] = 4;
|
||||||
|
AxisIdx["YAW"] = 5;
|
||||||
|
|
||||||
|
Coeff = new CoeffArray[6];
|
||||||
|
|
||||||
|
impending_stall = stall_hyst = 0.0;
|
||||||
|
alphaclmin = alphaclmax = 0.0;
|
||||||
|
alphahystmin = alphahystmax = 0.0;
|
||||||
|
clsq = lod = 0.0;
|
||||||
|
alphaw = 0.0;
|
||||||
|
bi2vel = ci2vel = 0.0;
|
||||||
|
bind();
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGAerodynamics::~FGAerodynamics()
|
||||||
|
{
|
||||||
|
unsigned int i,j;
|
||||||
|
|
||||||
|
unbind();
|
||||||
|
|
||||||
|
for (i=0; i<6; i++)
|
||||||
|
for (j=0; j<Coeff[i].size(); j++)
|
||||||
|
delete Coeff[i][j];
|
||||||
|
|
||||||
|
delete[] Coeff;
|
||||||
|
|
||||||
|
for (i=0; i<variables.size(); i++)
|
||||||
|
delete variables[i];
|
||||||
|
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGAerodynamics::Run(void)
|
||||||
|
{
|
||||||
|
unsigned int axis_ctr, ctr, i;
|
||||||
|
double alpha, twovel;
|
||||||
|
|
||||||
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false; // if paused don't execute
|
||||||
|
|
||||||
|
// calculate some oft-used quantities for speed
|
||||||
|
|
||||||
|
twovel = 2*Auxiliary->GetVt();
|
||||||
|
if (twovel != 0) {
|
||||||
|
bi2vel = Aircraft->GetWingSpan() / twovel;
|
||||||
|
ci2vel = Aircraft->Getcbar() / twovel;
|
||||||
|
}
|
||||||
|
alphaw = Auxiliary->Getalpha() + Aircraft->GetWingIncidence();
|
||||||
|
alpha = Auxiliary->Getalpha();
|
||||||
|
qbar_area = Aircraft->GetWingArea() * Auxiliary->Getqbar();
|
||||||
|
|
||||||
|
if (alphaclmax != 0) {
|
||||||
|
if (alpha > 0.85*alphaclmax) {
|
||||||
|
impending_stall = 10*(alpha/alphaclmax - 0.85);
|
||||||
|
} else {
|
||||||
|
impending_stall = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alphahystmax != 0.0 && alphahystmin != 0.0) {
|
||||||
|
if (alpha > alphahystmax) {
|
||||||
|
stall_hyst = 1;
|
||||||
|
} else if (alpha < alphahystmin) {
|
||||||
|
stall_hyst = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vLastFs = vFs;
|
||||||
|
vFs.InitMatrix();
|
||||||
|
|
||||||
|
// Tell the variable functions to cache their values, so while the aerodynamic
|
||||||
|
// functions are being calculated for each axis, these functions do not get
|
||||||
|
// calculated each time, but instead use the values that have already
|
||||||
|
// been calculated for this frame.
|
||||||
|
for (i=0; i<variables.size(); i++) variables[i]->cacheValue(true);
|
||||||
|
|
||||||
|
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
|
||||||
|
for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
|
||||||
|
vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate lift coefficient squared
|
||||||
|
if ( Auxiliary->Getqbar() > 0) {
|
||||||
|
clsq = vFs(eLift) / (Aircraft->GetWingArea()*Auxiliary->Getqbar());
|
||||||
|
clsq *= clsq;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( vFs(eDrag) > 0) {
|
||||||
|
lod = vFs(eLift) / vFs(eDrag);
|
||||||
|
}
|
||||||
|
|
||||||
|
//correct signs of drag and lift to wind axes convention
|
||||||
|
//positive forward, right, down
|
||||||
|
vFs(eDrag)*=-1; vFs(eLift)*=-1;
|
||||||
|
|
||||||
|
// transform stability axis forces into body axes
|
||||||
|
vForces = State->GetTs2b()*vFs;
|
||||||
|
|
||||||
|
vDXYZcg = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
|
||||||
|
|
||||||
|
vMoments = vDXYZcg*vForces; // M = r X F
|
||||||
|
|
||||||
|
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
|
||||||
|
for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
|
||||||
|
vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGAerodynamics::Load(Element *element)
|
||||||
|
{
|
||||||
|
string parameter, axis, scratch;
|
||||||
|
Element *temp_element, *axis_element, *function_element;
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
|
||||||
|
if (temp_element = element->FindElement("alphalimits")) {
|
||||||
|
alphaclmin = temp_element->FindElementValueAsNumberConvertTo("min", "DEG");
|
||||||
|
alphaclmax = temp_element->FindElementValueAsNumberConvertTo("max", "DEG");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_element = element->FindElement("hysteresis_limits")) {
|
||||||
|
alphahystmin = temp_element->FindElementValueAsNumberConvertTo("min", "DEG");
|
||||||
|
alphahystmax = temp_element->FindElementValueAsNumberConvertTo("max", "DEG");
|
||||||
|
}
|
||||||
|
|
||||||
|
function_element = element->FindElement("function");
|
||||||
|
while (function_element) {
|
||||||
|
variables.push_back( new FGFunction(PropertyManager, function_element) );
|
||||||
|
function_element = element->FindNextElement("function");
|
||||||
|
}
|
||||||
|
|
||||||
|
axis_element = element->FindElement("axis");
|
||||||
|
while (axis_element) {
|
||||||
|
CoeffArray ca;
|
||||||
|
axis = axis_element->GetAttributeValue("name");
|
||||||
|
function_element = axis_element->FindElement("function");
|
||||||
|
while (function_element) {
|
||||||
|
ca.push_back( new FGFunction(PropertyManager, function_element) );
|
||||||
|
function_element = axis_element->FindNextElement("function");
|
||||||
|
}
|
||||||
|
Coeff[AxisIdx[axis]] = ca;
|
||||||
|
axis_element = element->FindNextElement("axis");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGAerodynamics::GetCoefficientStrings(string delimeter)
|
||||||
|
{
|
||||||
|
string CoeffStrings = "";
|
||||||
|
bool firstime = true;
|
||||||
|
unsigned int axis, sd;
|
||||||
|
|
||||||
|
for (sd = 0; sd < variables.size(); sd++) {
|
||||||
|
if (firstime) {
|
||||||
|
firstime = false;
|
||||||
|
} else {
|
||||||
|
CoeffStrings += delimeter;
|
||||||
|
}
|
||||||
|
CoeffStrings += variables[sd]->GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (axis = 0; axis < 6; axis++) {
|
||||||
|
for (sd = 0; sd < Coeff[axis].size(); sd++) {
|
||||||
|
CoeffStrings += delimeter;
|
||||||
|
CoeffStrings += Coeff[axis][sd]->GetName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CoeffStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGAerodynamics::GetCoefficientValues(string delimeter)
|
||||||
|
{
|
||||||
|
string SDValues = "";
|
||||||
|
bool firstime = true;
|
||||||
|
unsigned int sd;
|
||||||
|
|
||||||
|
for (sd = 0; sd < variables.size(); sd++) {
|
||||||
|
if (firstime) {
|
||||||
|
firstime = false;
|
||||||
|
} else {
|
||||||
|
SDValues += delimeter;
|
||||||
|
}
|
||||||
|
SDValues += variables[sd]->GetValueAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int axis = 0; axis < 6; axis++) {
|
||||||
|
for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
|
||||||
|
SDValues += delimeter;
|
||||||
|
SDValues += Coeff[axis][sd]->GetValueAsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SDValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAerodynamics::bind(void)
|
||||||
|
{
|
||||||
|
typedef double (FGAerodynamics::*PMF)(int) const;
|
||||||
|
|
||||||
|
PropertyManager->Tie("forces/fbx-aero-lbs", this,1,
|
||||||
|
(PMF)&FGAerodynamics::GetForces);
|
||||||
|
PropertyManager->Tie("forces/fby-aero-lbs", this,2,
|
||||||
|
(PMF)&FGAerodynamics::GetForces);
|
||||||
|
PropertyManager->Tie("forces/fbz-aero-lbs", this,3,
|
||||||
|
(PMF)&FGAerodynamics::GetForces);
|
||||||
|
PropertyManager->Tie("moments/l-aero-lbsft", this,1,
|
||||||
|
(PMF)&FGAerodynamics::GetMoments);
|
||||||
|
PropertyManager->Tie("moments/m-aero-lbsft", this,2,
|
||||||
|
(PMF)&FGAerodynamics::GetMoments);
|
||||||
|
PropertyManager->Tie("moments/n-aero-lbsft", this,3,
|
||||||
|
(PMF)&FGAerodynamics::GetMoments);
|
||||||
|
PropertyManager->Tie("forces/fwx-aero-lbs", this,1,
|
||||||
|
(PMF)&FGAerodynamics::GetvFs);
|
||||||
|
PropertyManager->Tie("forces/fwy-aero-lbs", this,2,
|
||||||
|
(PMF)&FGAerodynamics::GetvFs);
|
||||||
|
PropertyManager->Tie("forces/fwz-aero-lbs", this,3,
|
||||||
|
(PMF)&FGAerodynamics::GetvFs);
|
||||||
|
PropertyManager->Tie("forces/lod-norm", this,
|
||||||
|
&FGAerodynamics::GetLoD);
|
||||||
|
PropertyManager->Tie("aero/cl-squared", this,
|
||||||
|
&FGAerodynamics::GetClSquared);
|
||||||
|
PropertyManager->Tie("aero/qbar-area", &qbar_area);
|
||||||
|
PropertyManager->Tie("aero/alpha-max-deg", this,
|
||||||
|
&FGAerodynamics::GetAlphaCLMax,
|
||||||
|
&FGAerodynamics::SetAlphaCLMax,
|
||||||
|
true);
|
||||||
|
PropertyManager->Tie("aero/alpha-min-deg", this,
|
||||||
|
&FGAerodynamics::GetAlphaCLMin,
|
||||||
|
&FGAerodynamics::SetAlphaCLMin,
|
||||||
|
true);
|
||||||
|
PropertyManager->Tie("aero/bi2vel", this,
|
||||||
|
&FGAerodynamics::GetBI2Vel);
|
||||||
|
PropertyManager->Tie("aero/ci2vel", this,
|
||||||
|
&FGAerodynamics::GetCI2Vel);
|
||||||
|
PropertyManager->Tie("aero/alpha-wing-rad", this,
|
||||||
|
&FGAerodynamics::GetAlphaW);
|
||||||
|
PropertyManager->Tie("systems/stall-warn-norm", this,
|
||||||
|
&FGAerodynamics::GetStallWarn);
|
||||||
|
PropertyManager->Tie("aero/stall-hyst-norm", this,
|
||||||
|
&FGAerodynamics::GetHysteresisParm);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAerodynamics::unbind(void)
|
||||||
|
{
|
||||||
|
unsigned i,j;
|
||||||
|
|
||||||
|
PropertyManager->Untie("forces/fbx-aero-lbs");
|
||||||
|
PropertyManager->Untie("forces/fby-aero-lbs");
|
||||||
|
PropertyManager->Untie("forces/fbz-aero-lbs");
|
||||||
|
PropertyManager->Untie("moments/l-aero-lbsft");
|
||||||
|
PropertyManager->Untie("moments/m-aero-lbsft");
|
||||||
|
PropertyManager->Untie("moments/n-aero-lbsft");
|
||||||
|
PropertyManager->Untie("forces/fwx-aero-lbs");
|
||||||
|
PropertyManager->Untie("forces/fwy-aero-lbs");
|
||||||
|
PropertyManager->Untie("forces/fwz-aero-lbs");
|
||||||
|
PropertyManager->Untie("forces/lod-norm");
|
||||||
|
PropertyManager->Untie("aero/cl-squared");
|
||||||
|
PropertyManager->Untie("aero/qbar-area");
|
||||||
|
PropertyManager->Untie("aero/alpha-max-deg");
|
||||||
|
PropertyManager->Untie("aero/alpha-min-deg");
|
||||||
|
PropertyManager->Untie("aero/bi2vel");
|
||||||
|
PropertyManager->Untie("aero/ci2vel");
|
||||||
|
PropertyManager->Untie("aero/alpha-wing-rad");
|
||||||
|
PropertyManager->Untie("aero/stall-hyst-norm");
|
||||||
|
PropertyManager->Untie("systems/stall-warn-norm");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGAerodynamics::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 2) { // Loader
|
||||||
|
cout << endl << " Aerodynamics: " << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGAerodynamics" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGAerodynamics" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
196
src/FDM/JSBSim/models/FGAerodynamics.h
Normal file
196
src/FDM/JSBSim/models/FGAerodynamics.h
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGAerodynamics.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 09/13/00
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
09/13/00 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGAERODYNAMICS_H
|
||||||
|
#define FGAERODYNAMICS_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <vector>
|
||||||
|
# include <map>
|
||||||
|
# else
|
||||||
|
# include <vector.h>
|
||||||
|
# include <map.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include <vector>
|
||||||
|
# include <map>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGModel.h"
|
||||||
|
#include <math/FGFunction.h>
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_AERODYNAMICS "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Encapsulates the aerodynamic calculations.
|
||||||
|
This class owns and contains the list of coefficients that define the
|
||||||
|
aerodynamic properties of this aircraft. Here also, such unique phenomena
|
||||||
|
as ground effect and maximum lift curve tailoff are handled.
|
||||||
|
@config
|
||||||
|
<pre>
|
||||||
|
\<AERODYNAMICS>
|
||||||
|
\<AXIS NAME="{LIFT|DRAG|SIDE|ROLL|PITCH|YAW}">
|
||||||
|
{Coefficient definitions}
|
||||||
|
\</AXIS>
|
||||||
|
{Additional axis definitions}
|
||||||
|
\</AERODYNAMICS> </pre>
|
||||||
|
|
||||||
|
@author Jon S. Berndt, Tony Peden
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGAerodynamics : public FGModel {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructor
|
||||||
|
@param Executive a pointer to the parent executive object */
|
||||||
|
FGAerodynamics(FGFDMExec* Executive);
|
||||||
|
/// Destructor
|
||||||
|
~FGAerodynamics();
|
||||||
|
|
||||||
|
/** Runs the Aerodynamics model; called by the Executive
|
||||||
|
@return false if no error */
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
/** Loads the Aerodynamics model.
|
||||||
|
The Load function for this class expects the XML parser to
|
||||||
|
have found the AERODYNAMICS keyword in the configuration file.
|
||||||
|
@param element pointer to the current XML element for aerodynamics parameters.
|
||||||
|
@return true if successful */
|
||||||
|
bool Load(Element* element);
|
||||||
|
|
||||||
|
/** Gets the total aerodynamic force vector.
|
||||||
|
@return a force vector reference. */
|
||||||
|
FGColumnVector3& GetForces(void) {return vForces;}
|
||||||
|
|
||||||
|
/** Gets the aerodynamic force for an axis.
|
||||||
|
@param n Axis index. This could be 0, 1, or 2, or one of the
|
||||||
|
axis enums: eX, eY, eZ.
|
||||||
|
@return the force acting on an axis */
|
||||||
|
double GetForces(int n) const {return vForces(n);}
|
||||||
|
|
||||||
|
/** Gets the total aerodynamic moment vector.
|
||||||
|
@return a moment vector reference. */
|
||||||
|
FGColumnVector3& GetMoments(void) {return vMoments;}
|
||||||
|
|
||||||
|
/** Gets the aerodynamic moment for an axis.
|
||||||
|
@return the moment about a single axis (as described also in the
|
||||||
|
similar call to GetForces(int n).*/
|
||||||
|
double GetMoments(int n) const {return vMoments(n);}
|
||||||
|
|
||||||
|
FGColumnVector3& GetvLastFs(void) { return vLastFs; }
|
||||||
|
double GetvLastFs(int axis) const { return vLastFs(axis); }
|
||||||
|
FGColumnVector3& GetvFs(void) { return vFs; }
|
||||||
|
double GetvFs(int axis) const { return vFs(axis); }
|
||||||
|
inline double GetLoD(void) const { return lod; }
|
||||||
|
inline double GetClSquared(void) const { return clsq; }
|
||||||
|
inline double GetAlphaCLMax(void) const { return alphaclmax; }
|
||||||
|
inline double GetAlphaCLMin(void) const { return alphaclmin; }
|
||||||
|
|
||||||
|
inline double GetAlphaHystMax(void) const { return alphahystmax; }
|
||||||
|
inline double GetAlphaHystMin(void) const { return alphahystmin; }
|
||||||
|
inline double GetHysteresisParm(void) const { return stall_hyst; }
|
||||||
|
inline double GetStallWarn(void) const { return impending_stall; }
|
||||||
|
double GetAlphaW(void) const { return alphaw; }
|
||||||
|
|
||||||
|
double GetBI2Vel(void) const { return bi2vel; }
|
||||||
|
double GetCI2Vel(void) const { return ci2vel; }
|
||||||
|
|
||||||
|
inline void SetAlphaCLMax(double tt) { alphaclmax=tt; }
|
||||||
|
inline void SetAlphaCLMin(double tt) { alphaclmin=tt; }
|
||||||
|
|
||||||
|
/** Gets the strings for the current set of coefficients.
|
||||||
|
@param delimeter either a tab or comma string depending on output type
|
||||||
|
@return a string containing the descriptive names for all coefficients */
|
||||||
|
string GetCoefficientStrings(string delimeter);
|
||||||
|
|
||||||
|
/** Gets the coefficient values.
|
||||||
|
@param delimeter either a tab or comma string depending on output type
|
||||||
|
@return a string containing the numeric values for the current set of
|
||||||
|
coefficients */
|
||||||
|
string GetCoefficientValues(string delimeter);
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef map<string,int> AxisIndex;
|
||||||
|
AxisIndex AxisIdx;
|
||||||
|
vector <FGFunction*> variables;
|
||||||
|
typedef vector <FGFunction*> CoeffArray;
|
||||||
|
CoeffArray* Coeff;
|
||||||
|
FGColumnVector3 vFs;
|
||||||
|
FGColumnVector3 vForces;
|
||||||
|
FGColumnVector3 vMoments;
|
||||||
|
FGColumnVector3 vLastFs;
|
||||||
|
FGColumnVector3 vDXYZcg;
|
||||||
|
double alphaclmax, alphaclmin;
|
||||||
|
double alphahystmax, alphahystmin;
|
||||||
|
double impending_stall, stall_hyst;
|
||||||
|
double bi2vel, ci2vel,alphaw;
|
||||||
|
double clsq, lod, qbar_area;
|
||||||
|
|
||||||
|
typedef double (FGAerodynamics::*PMF)(int) const;
|
||||||
|
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
||||||
|
|
324
src/FDM/JSBSim/models/FGAircraft.cpp
Normal file
324
src/FDM/JSBSim/models/FGAircraft.cpp
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGAircraft.cpp
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 12/12/98
|
||||||
|
Purpose: Encapsulates an aircraft
|
||||||
|
Called by: FGFDMExec
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Models the aircraft reactions and forces. This class is instantiated by the
|
||||||
|
FGFDMExec class and scheduled as an FDM entry.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
COMMENTS, REFERENCES, and NOTES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# ifndef __BORLANDC__
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# endif
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <cmath>
|
||||||
|
# else
|
||||||
|
# include <math.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if defined (sgi) && !defined(__GNUC__)
|
||||||
|
# include <math.h>
|
||||||
|
# else
|
||||||
|
# include <cmath>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGAircraft.h"
|
||||||
|
#include "FGMassBalance.h"
|
||||||
|
#include "FGInertial.h"
|
||||||
|
#include "FGGroundReactions.h"
|
||||||
|
#include "FGAerodynamics.h"
|
||||||
|
#include <FGState.h>
|
||||||
|
#include <FGFDMExec.h>
|
||||||
|
#include "FGPropagate.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
GLOBAL DATA
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_AIRCRAFT;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
|
{
|
||||||
|
Name = "FGAircraft";
|
||||||
|
WingSpan = 0.0;
|
||||||
|
HTailArea = VTailArea = 0.0;
|
||||||
|
HTailArm = VTailArm = 0.0;
|
||||||
|
lbarh = lbarv = 0.0;
|
||||||
|
vbarh = vbarv = 0.0;
|
||||||
|
WingIncidence = 0.0;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGAircraft::~FGAircraft()
|
||||||
|
{
|
||||||
|
unbind();
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGAircraft::Run(void)
|
||||||
|
{
|
||||||
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
|
vForces.InitMatrix();
|
||||||
|
vForces += Aerodynamics->GetForces();
|
||||||
|
vForces += Propulsion->GetForces();
|
||||||
|
vForces += GroundReactions->GetForces();
|
||||||
|
|
||||||
|
vMoments.InitMatrix();
|
||||||
|
vMoments += Aerodynamics->GetMoments();
|
||||||
|
vMoments += Propulsion->GetMoments();
|
||||||
|
vMoments += GroundReactions->GetMoments();
|
||||||
|
|
||||||
|
// printf("%s:%i\n", __FILE__, __LINE__);
|
||||||
|
vBodyAccel = vForces/MassBalance->GetMass();
|
||||||
|
|
||||||
|
// printf("%s:%i\n", __FILE__, __LINE__);
|
||||||
|
vNcg = vBodyAccel/Inertial->gravity();
|
||||||
|
|
||||||
|
vNwcg = State->GetTb2s() * vNcg;
|
||||||
|
vNwcg(3) = -1*vNwcg(3) + 1;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGAircraft::GetNlf(void)
|
||||||
|
{
|
||||||
|
return -1*Aerodynamics->GetvFs(3)/MassBalance->GetWeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGAircraft::Load(Element* el)
|
||||||
|
{
|
||||||
|
string element_name;
|
||||||
|
Element* element;
|
||||||
|
|
||||||
|
if (el->FindElement("wingarea"))
|
||||||
|
WingArea = el->FindElementValueAsNumberConvertTo("wingarea", "FT2");
|
||||||
|
if (el->FindElement("wingspan"))
|
||||||
|
WingSpan = el->FindElementValueAsNumberConvertTo("wingspan", "FT");
|
||||||
|
if (el->FindElement("chord"))
|
||||||
|
cbar = el->FindElementValueAsNumberConvertTo("chord", "FT");
|
||||||
|
if (el->FindElement("wing_incidence"))
|
||||||
|
WingIncidence = el->FindElementValueAsNumberConvertTo("wing_incidence", "DEG");
|
||||||
|
if (el->FindElement("htailarea"))
|
||||||
|
HTailArea = el->FindElementValueAsNumberConvertTo("htailarea", "FT2");
|
||||||
|
if (el->FindElement("htailarm"))
|
||||||
|
HTailArm = el->FindElementValueAsNumberConvertTo("htailarm", "FT");
|
||||||
|
if (el->FindElement("vtailarea"))
|
||||||
|
VTailArea = el->FindElementValueAsNumberConvertTo("vtailarea", "FT2");
|
||||||
|
if (el->FindElement("vtailarm"))
|
||||||
|
VTailArm = el->FindElementValueAsNumberConvertTo("vtailarm", "FT");
|
||||||
|
|
||||||
|
// Find all LOCATION elements that descend from this METRICS branch of the
|
||||||
|
// config file. This would be CG location, eyepoint, etc.
|
||||||
|
|
||||||
|
element = el->FindElement("location");
|
||||||
|
while (element) {
|
||||||
|
element_name = element->GetAttributeValue("name");
|
||||||
|
|
||||||
|
if (element_name == "AERORP") vXYZrp = element->FindElementTripletConvertTo("IN");
|
||||||
|
else if (element_name == "EYEPOINT") vXYZep = element->FindElementTripletConvertTo("IN");
|
||||||
|
else if (element_name == "VRP") vXYZvrp = element->FindElementTripletConvertTo("IN");
|
||||||
|
|
||||||
|
element = el->FindNextElement("location");
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate some derived parameters
|
||||||
|
if (cbar != 0.0) {
|
||||||
|
lbarh = HTailArm/cbar;
|
||||||
|
lbarv = VTailArm/cbar;
|
||||||
|
if (WingArea != 0.0) {
|
||||||
|
vbarh = HTailArm*HTailArea / (cbar*WingArea);
|
||||||
|
vbarv = VTailArm*VTailArea / (cbar*WingArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAircraft::bind(void)
|
||||||
|
{
|
||||||
|
typedef double (FGAircraft::*PMF)(int) const;
|
||||||
|
PropertyManager->Tie("metrics/Sw-sqft", this, &FGAircraft::GetWingArea);
|
||||||
|
PropertyManager->Tie("metrics/bw-ft", this, &FGAircraft::GetWingSpan);
|
||||||
|
PropertyManager->Tie("metrics/cbarw-ft", this, &FGAircraft::Getcbar);
|
||||||
|
PropertyManager->Tie("metrics/iw-deg", this, &FGAircraft::GetWingIncidence);
|
||||||
|
PropertyManager->Tie("metrics/Sh-sqft", this, &FGAircraft::GetHTailArea);
|
||||||
|
PropertyManager->Tie("metrics/lh-ft", this, &FGAircraft::GetHTailArm);
|
||||||
|
PropertyManager->Tie("metrics/Sv-sqft", this, &FGAircraft::GetVTailArea);
|
||||||
|
PropertyManager->Tie("metrics/lv-ft", this, &FGAircraft::GetVTailArm);
|
||||||
|
PropertyManager->Tie("metrics/lh-norm", this, &FGAircraft::Getlbarh);
|
||||||
|
PropertyManager->Tie("metrics/lv-norm", this, &FGAircraft::Getlbarv);
|
||||||
|
PropertyManager->Tie("metrics/vbarh-norm", this, &FGAircraft::Getvbarh);
|
||||||
|
PropertyManager->Tie("metrics/vbarv-norm", this, &FGAircraft::Getvbarv);
|
||||||
|
PropertyManager->Tie("moments/l-total-lbsft", this, eL, (PMF)&FGAircraft::GetMoments);
|
||||||
|
PropertyManager->Tie("moments/m-total-lbsft", this, eM, (PMF)&FGAircraft::GetMoments);
|
||||||
|
PropertyManager->Tie("moments/n-total-lbsft", this, eN, (PMF)&FGAircraft::GetMoments);
|
||||||
|
PropertyManager->Tie("forces/fbx-total-lbs", this, eX, (PMF)&FGAircraft::GetForces);
|
||||||
|
PropertyManager->Tie("forces/fby-total-lbs", this, eY, (PMF)&FGAircraft::GetForces);
|
||||||
|
PropertyManager->Tie("forces/fbz-total-lbs", this, eZ, (PMF)&FGAircraft::GetForces);
|
||||||
|
PropertyManager->Tie("metrics/aero-rp-x-in", this, eX, (PMF)&FGAircraft::GetXYZrp);
|
||||||
|
PropertyManager->Tie("metrics/aero-rp-y-in", this, eY, (PMF)&FGAircraft::GetXYZrp);
|
||||||
|
PropertyManager->Tie("metrics/aero-rp-z-in", this, eZ, (PMF)&FGAircraft::GetXYZrp);
|
||||||
|
PropertyManager->Tie("metrics/eyepoint-x-in", this, eX, (PMF)&FGAircraft::GetXYZep);
|
||||||
|
PropertyManager->Tie("metrics/eyepoint-y-in", this, eY,(PMF)&FGAircraft::GetXYZep);
|
||||||
|
PropertyManager->Tie("metrics/eyepoint-z-in", this, eZ, (PMF)&FGAircraft::GetXYZep);
|
||||||
|
PropertyManager->Tie("metrics/visualrefpoint-x-in", this, eX, (PMF)&FGAircraft::GetXYZvrp);
|
||||||
|
PropertyManager->Tie("metrics/visualrefpoint-y-in", this, eY, (PMF)&FGAircraft::GetXYZvrp);
|
||||||
|
PropertyManager->Tie("metrics/visualrefpoint-z-in", this, eZ, (PMF)&FGAircraft::GetXYZvrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAircraft::unbind(void)
|
||||||
|
{
|
||||||
|
PropertyManager->Untie("metrics/Sw-sqft");
|
||||||
|
PropertyManager->Untie("metrics/bw-ft");
|
||||||
|
PropertyManager->Untie("metrics/cbarw-ft");
|
||||||
|
PropertyManager->Untie("metrics/iw-deg");
|
||||||
|
PropertyManager->Untie("metrics/Sh-sqft");
|
||||||
|
PropertyManager->Untie("metrics/lh-ft");
|
||||||
|
PropertyManager->Untie("metrics/Sv-sqft");
|
||||||
|
PropertyManager->Untie("metrics/lv-ft");
|
||||||
|
PropertyManager->Untie("metrics/lh-norm");
|
||||||
|
PropertyManager->Untie("metrics/lv-norm");
|
||||||
|
PropertyManager->Untie("metrics/vbarh-norm");
|
||||||
|
PropertyManager->Untie("metrics/vbarv-norm");
|
||||||
|
PropertyManager->Untie("moments/l-total-lbsft");
|
||||||
|
PropertyManager->Untie("moments/m-total-lbsft");
|
||||||
|
PropertyManager->Untie("moments/n-total-lbsft");
|
||||||
|
PropertyManager->Untie("forces/fbx-total-lbs");
|
||||||
|
PropertyManager->Untie("forces/fby-total-lbs");
|
||||||
|
PropertyManager->Untie("forces/fbz-total-lbs");
|
||||||
|
PropertyManager->Untie("metrics/aero-rp-x-in");
|
||||||
|
PropertyManager->Untie("metrics/aero-rp-y-in");
|
||||||
|
PropertyManager->Untie("metrics/aero-rp-z-in");
|
||||||
|
PropertyManager->Untie("metrics/eyepoint-x-in");
|
||||||
|
PropertyManager->Untie("metrics/eyepoint-y-in");
|
||||||
|
PropertyManager->Untie("metrics/eyepoint-z-in");
|
||||||
|
PropertyManager->Untie("metrics/visualrefpoint-x-in");
|
||||||
|
PropertyManager->Untie("metrics/visualrefpoint-y-in");
|
||||||
|
PropertyManager->Untie("metrics/visualrefpoint-z-in");
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGAircraft::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 2) { // Loading
|
||||||
|
cout << endl << " Aircraft Metrics:" << endl;
|
||||||
|
cout << " WingArea: " << WingArea << endl;
|
||||||
|
cout << " WingSpan: " << WingSpan << endl;
|
||||||
|
cout << " Incidence: " << WingIncidence << endl;
|
||||||
|
cout << " Chord: " << cbar << endl;
|
||||||
|
cout << " H. Tail Area: " << HTailArea << endl;
|
||||||
|
cout << " H. Tail Arm: " << HTailArm << endl;
|
||||||
|
cout << " V. Tail Area: " << VTailArea << endl;
|
||||||
|
cout << " V. Tail Arm: " << VTailArm << endl;
|
||||||
|
cout << " Eyepoint (x, y, z): " << vXYZep << endl;
|
||||||
|
cout << " Ref Pt (x, y, z): " << vXYZrp << endl;
|
||||||
|
cout << " Visual Ref Pt (x, y, z): " << vXYZvrp << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGAircraft" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGAircraft" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
184
src/FDM/JSBSim/models/FGAircraft.h
Normal file
184
src/FDM/JSBSim/models/FGAircraft.h
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGAircraft.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 12/12/98
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
12/12/98 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGAIRCRAFT_H
|
||||||
|
#define FGAIRCRAFT_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <vector>
|
||||||
|
# include <iterator>
|
||||||
|
# else
|
||||||
|
# include <vector.h>
|
||||||
|
# include <iterator.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include <vector>
|
||||||
|
# include <iterator>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGModel.h"
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_AIRCRAFT "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Encapsulates an Aircraft and its systems.
|
||||||
|
Owns all the parts (other classes) which make up this aircraft. This includes
|
||||||
|
the Engines, Tanks, Propellers, Nozzles, Aerodynamic and Mass properties,
|
||||||
|
landing gear, etc. These constituent parts may actually run as separate
|
||||||
|
JSBSim models themselves, but the responsibility for initializing them and
|
||||||
|
for retrieving their force and moment contributions falls to FGAircraft.
|
||||||
|
@author Jon S. Berndt
|
||||||
|
@version $Id$
|
||||||
|
@see Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
|
||||||
|
Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
|
||||||
|
School, January 1994
|
||||||
|
@see D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
|
||||||
|
JSC 12960, July 1977
|
||||||
|
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
|
||||||
|
NASA-Ames", NASA CR-2497, January 1975
|
||||||
|
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
|
||||||
|
Wiley & Sons, 1979 ISBN 0-471-03032-5
|
||||||
|
@see Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
|
||||||
|
1982 ISBN 0-471-08936-2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGAircraft : public FGModel {
|
||||||
|
public:
|
||||||
|
/** Constructor
|
||||||
|
@param Executive a pointer to the parent executive object */
|
||||||
|
FGAircraft(FGFDMExec *Executive);
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
~FGAircraft();
|
||||||
|
|
||||||
|
/** Runs the Aircraft model; called by the Executive
|
||||||
|
@see JSBSim.cpp documentation
|
||||||
|
@return false if no error */
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
/** Loads the aircraft.
|
||||||
|
The executive calls this method to load the aircraft into JSBSim.
|
||||||
|
@param el a pointer to the element tree
|
||||||
|
@return true if successful */
|
||||||
|
bool Load(Element* el);
|
||||||
|
|
||||||
|
/** Gets the aircraft name
|
||||||
|
@return the name of the aircraft as a string type */
|
||||||
|
inline string GetAircraftName(void) { return AircraftName; }
|
||||||
|
|
||||||
|
/// Gets the wing area
|
||||||
|
double GetWingArea(void) const { return WingArea; }
|
||||||
|
/// Gets the wing span
|
||||||
|
double GetWingSpan(void) const { return WingSpan; }
|
||||||
|
/// Gets the average wing chord
|
||||||
|
double Getcbar(void) const { return cbar; }
|
||||||
|
inline double GetWingIncidence(void) const { return WingIncidence; }
|
||||||
|
inline double GetHTailArea(void) const { return HTailArea; }
|
||||||
|
inline double GetHTailArm(void) const { return HTailArm; }
|
||||||
|
inline double GetVTailArea(void) const { return VTailArea; }
|
||||||
|
inline double GetVTailArm(void) const { return VTailArm; }
|
||||||
|
inline double Getlbarh(void) const { return lbarh; } // HTailArm / cbar
|
||||||
|
inline double Getlbarv(void) const { return lbarv; } // VTailArm / cbar
|
||||||
|
inline double Getvbarh(void) const { return vbarh; } // H. Tail Volume
|
||||||
|
inline double Getvbarv(void) const { return vbarv; } // V. Tail Volume
|
||||||
|
inline FGColumnVector3& GetMoments(void) { return vMoments; }
|
||||||
|
inline double GetMoments(int idx) const { return vMoments(idx); }
|
||||||
|
inline FGColumnVector3& GetForces(void) { return vForces; }
|
||||||
|
inline double GetForces(int idx) const { return vForces(idx); }
|
||||||
|
inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
|
||||||
|
inline double GetBodyAccel(int idx) { return vBodyAccel(idx); }
|
||||||
|
inline FGColumnVector3& GetNcg (void) { return vNcg; }
|
||||||
|
inline double GetNcg(int idx) { return vNcg(idx); }
|
||||||
|
inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
|
||||||
|
inline FGColumnVector3& GetXYZvrp(void) { return vXYZvrp; }
|
||||||
|
inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
|
||||||
|
inline double GetXYZrp(int idx) const { return vXYZrp(idx); }
|
||||||
|
inline double GetXYZvrp(int idx) const { return vXYZvrp(idx); }
|
||||||
|
inline double GetXYZep(int idx) const { return vXYZep(idx); }
|
||||||
|
inline void SetAircraftName(string name) {AircraftName = name;}
|
||||||
|
|
||||||
|
double GetNlf(void);
|
||||||
|
|
||||||
|
inline FGColumnVector3& GetNwcg(void) { return vNwcg; }
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FGColumnVector3 vMoments;
|
||||||
|
FGColumnVector3 vForces;
|
||||||
|
FGColumnVector3 vXYZrp;
|
||||||
|
FGColumnVector3 vXYZvrp;
|
||||||
|
FGColumnVector3 vXYZep;
|
||||||
|
FGColumnVector3 vDXYZcg;
|
||||||
|
FGColumnVector3 vBodyAccel;
|
||||||
|
FGColumnVector3 vNcg;
|
||||||
|
FGColumnVector3 vNwcg;
|
||||||
|
|
||||||
|
double WingArea, WingSpan, cbar, WingIncidence;
|
||||||
|
double HTailArea, VTailArea, HTailArm, VTailArm;
|
||||||
|
double lbarh,lbarv,vbarh,vbarv;
|
||||||
|
string AircraftName;
|
||||||
|
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
||||||
|
|
582
src/FDM/JSBSim/models/FGAtmosphere.cpp
Normal file
582
src/FDM/JSBSim/models/FGAtmosphere.cpp
Normal file
|
@ -0,0 +1,582 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGAtmosphere.cpp
|
||||||
|
Author: Jon Berndt
|
||||||
|
Implementation of 1959 Standard Atmosphere added by Tony Peden
|
||||||
|
Date started: 11/24/98
|
||||||
|
Purpose: Models the atmosphere
|
||||||
|
Called by: FGSimExec
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Models the atmosphere. The equation used below was determined by a third order
|
||||||
|
curve fit using Excel. The data is from the ICAO atmosphere model.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
11/24/98 JSB Created
|
||||||
|
07/23/99 TP Added implementation of 1959 Standard Atmosphere
|
||||||
|
Moved calculation of Mach number to FGPropagate
|
||||||
|
Later updated to '76 model
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
COMMENTS, REFERENCES, and NOTES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
[1] Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
|
||||||
|
1989, ISBN 0-07-001641-0
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGAtmosphere.h"
|
||||||
|
#include <FGState.h>
|
||||||
|
#include <FGFDMExec.h>
|
||||||
|
#include "FGAircraft.h"
|
||||||
|
#include "FGPropagate.h"
|
||||||
|
#include "FGInertial.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_ATMOSPHERE;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
|
FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
|
{
|
||||||
|
Name = "FGAtmosphere";
|
||||||
|
lastIndex = 0;
|
||||||
|
h = 0.0;
|
||||||
|
psiw = 0.0;
|
||||||
|
htab[0]=0;
|
||||||
|
htab[1]=36089.239;
|
||||||
|
htab[2]=65616.798;
|
||||||
|
htab[3]=104986.878;
|
||||||
|
htab[4]=154199.475;
|
||||||
|
htab[5]=170603.675;
|
||||||
|
htab[6]=200131.234;
|
||||||
|
htab[7]=259186.352; //ft.
|
||||||
|
|
||||||
|
MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
|
||||||
|
// turbType = ttNone;
|
||||||
|
turbType = ttStandard;
|
||||||
|
// turbType = ttBerndt;
|
||||||
|
TurbGain = 0.0;
|
||||||
|
TurbRate = 1.0;
|
||||||
|
|
||||||
|
T_dev_sl = T_dev = delta_T = 0.0;
|
||||||
|
StandardTempOnly = false;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGAtmosphere::~FGAtmosphere()
|
||||||
|
{
|
||||||
|
unbind();
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGAtmosphere::InitModel(void)
|
||||||
|
{
|
||||||
|
FGModel::InitModel();
|
||||||
|
|
||||||
|
UseInternal(); // this is the default
|
||||||
|
|
||||||
|
Calculate(h);
|
||||||
|
StdSLtemperature = SLtemperature = 518.67;
|
||||||
|
StdSLpressure = SLpressure = 2116.22;
|
||||||
|
StdSLdensity = SLdensity = 0.00237767;
|
||||||
|
StdSLsoundspeed = SLsoundspeed = sqrt(SHRatio*Reng*StdSLtemperature);
|
||||||
|
rSLtemperature = 1.0/StdSLtemperature;
|
||||||
|
rSLpressure = 1.0/StdSLpressure;
|
||||||
|
rSLdensity = 1.0/StdSLdensity;
|
||||||
|
rSLsoundspeed = 1.0/StdSLsoundspeed;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGAtmosphere::Run(void)
|
||||||
|
{
|
||||||
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
|
T_dev = 0.0;
|
||||||
|
h = Propagate->Geth();
|
||||||
|
|
||||||
|
if (!useExternal) {
|
||||||
|
Calculate(h);
|
||||||
|
CalculateDerived();
|
||||||
|
} else {
|
||||||
|
CalculateDerived();
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
//
|
||||||
|
// See reference 1
|
||||||
|
|
||||||
|
void FGAtmosphere::Calculate(double altitude)
|
||||||
|
{
|
||||||
|
double slope, reftemp, refpress;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
i = lastIndex;
|
||||||
|
if (altitude < htab[lastIndex]) {
|
||||||
|
if (altitude <= 0) {
|
||||||
|
i = 0;
|
||||||
|
altitude=0;
|
||||||
|
} else {
|
||||||
|
i = lastIndex-1;
|
||||||
|
while (htab[i] > altitude) i--;
|
||||||
|
}
|
||||||
|
} else if (altitude > htab[lastIndex+1]) {
|
||||||
|
if (altitude >= htab[7]) {
|
||||||
|
i = 7;
|
||||||
|
altitude = htab[7];
|
||||||
|
} else {
|
||||||
|
i = lastIndex+1;
|
||||||
|
while (htab[i+1] < altitude) i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(i) {
|
||||||
|
case 1: // 36089 ft.
|
||||||
|
slope = 0;
|
||||||
|
reftemp = 389.97;
|
||||||
|
refpress = 472.452;
|
||||||
|
//refdens = 0.000706032;
|
||||||
|
break;
|
||||||
|
case 2: // 65616 ft.
|
||||||
|
slope = 0.00054864;
|
||||||
|
reftemp = 389.97;
|
||||||
|
refpress = 114.636;
|
||||||
|
//refdens = 0.000171306;
|
||||||
|
break;
|
||||||
|
case 3: // 104986 ft.
|
||||||
|
slope = 0.00153619;
|
||||||
|
reftemp = 411.57;
|
||||||
|
refpress = 8.36364;
|
||||||
|
//refdens = 1.18422e-05;
|
||||||
|
break;
|
||||||
|
case 4: // 154199 ft.
|
||||||
|
slope = 0;
|
||||||
|
reftemp = 487.17;
|
||||||
|
refpress = 0.334882;
|
||||||
|
//refdens = 4.00585e-7;
|
||||||
|
break;
|
||||||
|
case 5: // 170603 ft.
|
||||||
|
slope = -0.00109728;
|
||||||
|
reftemp = 487.17;
|
||||||
|
refpress = 0.683084;
|
||||||
|
//refdens = 8.17102e-7;
|
||||||
|
break;
|
||||||
|
case 6: // 200131 ft.
|
||||||
|
slope = -0.00219456;
|
||||||
|
reftemp = 454.17;
|
||||||
|
refpress = 0.00684986;
|
||||||
|
//refdens = 8.77702e-9;
|
||||||
|
break;
|
||||||
|
case 7: // 259186 ft.
|
||||||
|
slope = 0;
|
||||||
|
reftemp = 325.17;
|
||||||
|
refpress = 0.000122276;
|
||||||
|
//refdens = 2.19541e-10;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default: // sea level
|
||||||
|
slope = -0.00356616; // R/ft.
|
||||||
|
reftemp = 518.67; // R
|
||||||
|
refpress = 2116.22; // psf
|
||||||
|
//refdens = 0.00237767; // slugs/cubic ft.
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If delta_T is set, then that is our temperature deviation at any altitude.
|
||||||
|
// If not, then we'll estimate a deviation based on the sea level deviation (if set).
|
||||||
|
|
||||||
|
if(!StandardTempOnly) {
|
||||||
|
T_dev = 0.0;
|
||||||
|
if (delta_T != 0.0) {
|
||||||
|
T_dev = delta_T;
|
||||||
|
} else {
|
||||||
|
if ((altitude < 36089.239) && (T_dev_sl != 0.0)) {
|
||||||
|
T_dev = T_dev_sl * ( 1.0 - (altitude/36089.239));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reftemp+=T_dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slope == 0) {
|
||||||
|
intTemperature = reftemp;
|
||||||
|
intPressure = refpress*exp(-Inertial->SLgravity()/(reftemp*Reng)*(altitude-htab[i]));
|
||||||
|
intDensity = intPressure/(Reng*intTemperature);
|
||||||
|
} else {
|
||||||
|
intTemperature = reftemp+slope*(altitude-htab[i]);
|
||||||
|
intPressure = refpress*pow(intTemperature/reftemp,-Inertial->SLgravity()/(slope*Reng));
|
||||||
|
intDensity = intPressure/(Reng*intTemperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastIndex=i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Calculate parameters derived from T, P and rho
|
||||||
|
|
||||||
|
void FGAtmosphere::CalculateDerived(void)
|
||||||
|
{
|
||||||
|
T_dev = (*temperature) - GetTemperature(h);
|
||||||
|
density_altitude = h + T_dev * 66.7;
|
||||||
|
|
||||||
|
if (turbType != ttStandard) {
|
||||||
|
Turbulence();
|
||||||
|
vWindNED += vTurbulence;
|
||||||
|
}
|
||||||
|
if (vWindNED(1) != 0.0) psiw = atan2( vWindNED(2), vWindNED(1) );
|
||||||
|
if (psiw < 0) psiw += 2*M_PI;
|
||||||
|
|
||||||
|
soundspeed = sqrt(SHRatio*Reng*(*temperature));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Get the standard atmospheric properties at a specified altitude
|
||||||
|
|
||||||
|
void FGAtmosphere::GetStdAtmosphere(double altitude) {
|
||||||
|
StandardTempOnly = true;
|
||||||
|
Calculate(altitude);
|
||||||
|
StandardTempOnly = false;
|
||||||
|
atmosphere.Temperature = intTemperature;
|
||||||
|
atmosphere.Pressure = intPressure;
|
||||||
|
atmosphere.Density = intDensity;
|
||||||
|
|
||||||
|
// Reset the internal atmospheric state
|
||||||
|
Calculate(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Get the standard pressure at a specified altitude
|
||||||
|
|
||||||
|
double FGAtmosphere::GetPressure(double altitude) {
|
||||||
|
GetStdAtmosphere(altitude);
|
||||||
|
return atmosphere.Pressure;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Get the standard temperature at a specified altitude
|
||||||
|
|
||||||
|
double FGAtmosphere::GetTemperature(double altitude) {
|
||||||
|
GetStdAtmosphere(altitude);
|
||||||
|
return atmosphere.Temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Get the standard density at a specified altitude
|
||||||
|
|
||||||
|
double FGAtmosphere::GetDensity(double altitude) {
|
||||||
|
GetStdAtmosphere(altitude);
|
||||||
|
return atmosphere.Density;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// square a value, but preserve the original sign
|
||||||
|
|
||||||
|
static inline double square_signed (double value)
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
return value * value * -1;
|
||||||
|
else
|
||||||
|
return value * value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAtmosphere::Turbulence(void)
|
||||||
|
{
|
||||||
|
switch (turbType) {
|
||||||
|
case ttStandard: {
|
||||||
|
vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
|
||||||
|
MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
|
||||||
|
// Scale the magnitude so that it moves
|
||||||
|
// away from the peaks
|
||||||
|
MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) /
|
||||||
|
(1 + fabs(Magnitude)));
|
||||||
|
MagnitudeAccel += MagnitudedAccelDt*rate*TurbRate*State->Getdt();
|
||||||
|
Magnitude += MagnitudeAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
vDirectiondAccelDt.Normalize();
|
||||||
|
|
||||||
|
// deemphasise non-vertical forces
|
||||||
|
vDirectiondAccelDt(eX) = square_signed(vDirectiondAccelDt(eX));
|
||||||
|
vDirectiondAccelDt(eY) = square_signed(vDirectiondAccelDt(eY));
|
||||||
|
|
||||||
|
vDirectionAccel += vDirectiondAccelDt*rate*TurbRate*State->Getdt();
|
||||||
|
vDirectionAccel.Normalize();
|
||||||
|
vDirection += vDirectionAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
vDirection.Normalize();
|
||||||
|
|
||||||
|
// Diminish turbulence within three wingspans
|
||||||
|
// of the ground
|
||||||
|
vTurbulence = TurbGain * Magnitude * vDirection;
|
||||||
|
double HOverBMAC = Auxiliary->GetHOverBMAC();
|
||||||
|
if (HOverBMAC < 3.0)
|
||||||
|
vTurbulence *= (HOverBMAC / 3.0) * (HOverBMAC / 3.0);
|
||||||
|
|
||||||
|
vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
|
||||||
|
|
||||||
|
vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad;
|
||||||
|
|
||||||
|
if (Aircraft->GetWingSpan() > 0) {
|
||||||
|
vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan();
|
||||||
|
} else {
|
||||||
|
vTurbPQR(eP) = vBodyTurbGrad(eY)/30.0;
|
||||||
|
}
|
||||||
|
// if (Aircraft->GetHTailArm() != 0.0)
|
||||||
|
// vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm();
|
||||||
|
// else
|
||||||
|
// vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
|
||||||
|
|
||||||
|
if (Aircraft->GetVTailArm() > 0)
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm();
|
||||||
|
else
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
|
||||||
|
|
||||||
|
// Clear the horizontal forces
|
||||||
|
// actually felt by the plane, now
|
||||||
|
// that we've used them to calculate
|
||||||
|
// moments.
|
||||||
|
vTurbulence(eX) = 0.0;
|
||||||
|
vTurbulence(eY) = 0.0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ttBerndt: {
|
||||||
|
vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
|
||||||
|
|
||||||
|
MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
|
||||||
|
MagnitudeAccel += MagnitudedAccelDt*rate*State->Getdt();
|
||||||
|
Magnitude += MagnitudeAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
vDirectiondAccelDt.Normalize();
|
||||||
|
vDirectionAccel += vDirectiondAccelDt*rate*State->Getdt();
|
||||||
|
vDirectionAccel.Normalize();
|
||||||
|
vDirection += vDirectionAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
// Diminish z-vector within two wingspans
|
||||||
|
// of the ground
|
||||||
|
double HOverBMAC = Auxiliary->GetHOverBMAC();
|
||||||
|
if (HOverBMAC < 2.0)
|
||||||
|
vDirection(eZ) *= HOverBMAC / 2.0;
|
||||||
|
|
||||||
|
vDirection.Normalize();
|
||||||
|
|
||||||
|
vTurbulence = TurbGain*Magnitude * vDirection;
|
||||||
|
vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
|
||||||
|
|
||||||
|
vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad;
|
||||||
|
vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan();
|
||||||
|
if (Aircraft->GetHTailArm() > 0)
|
||||||
|
vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm();
|
||||||
|
else
|
||||||
|
vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
|
||||||
|
|
||||||
|
if (Aircraft->GetVTailArm() > 0)
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm();
|
||||||
|
else
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAtmosphere::UseExternal(void)
|
||||||
|
{
|
||||||
|
temperature=&exTemperature;
|
||||||
|
pressure=&exPressure;
|
||||||
|
density=&exDensity;
|
||||||
|
useExternal=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAtmosphere::UseInternal(void)
|
||||||
|
{
|
||||||
|
temperature=&intTemperature;
|
||||||
|
pressure=&intPressure;
|
||||||
|
density=&intDensity;
|
||||||
|
useExternal=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAtmosphere::bind(void)
|
||||||
|
{
|
||||||
|
typedef double (FGAtmosphere::*PMF)(int) const;
|
||||||
|
PropertyManager->Tie("atmosphere/T-R", this,
|
||||||
|
&FGAtmosphere::GetTemperature);
|
||||||
|
PropertyManager->Tie("atmosphere/rho-slugs_ft3", this,
|
||||||
|
&FGAtmosphere::GetDensity);
|
||||||
|
// PropertyManager->Tie("atmosphere/P-psf", this,
|
||||||
|
// &FGAtmosphere::GetPressure);
|
||||||
|
PropertyManager->Tie("atmosphere/a-fps", this,
|
||||||
|
&FGAtmosphere::GetSoundSpeed);
|
||||||
|
PropertyManager->Tie("atmosphere/T-sl-R", this,
|
||||||
|
&FGAtmosphere::GetTemperatureSL);
|
||||||
|
PropertyManager->Tie("atmosphere/rho-sl-slugs_ft3", this,
|
||||||
|
&FGAtmosphere::GetDensitySL);
|
||||||
|
PropertyManager->Tie("atmosphere/P-sl-psf", this,
|
||||||
|
&FGAtmosphere::GetPressureSL);
|
||||||
|
PropertyManager->Tie("atmosphere/a-sl-fps", this,
|
||||||
|
&FGAtmosphere::GetSoundSpeedSL);
|
||||||
|
PropertyManager->Tie("atmosphere/theta", this,
|
||||||
|
&FGAtmosphere::GetTemperatureRatio);
|
||||||
|
PropertyManager->Tie("atmosphere/sigma", this,
|
||||||
|
&FGAtmosphere::GetDensityRatio);
|
||||||
|
PropertyManager->Tie("atmosphere/delta", this,
|
||||||
|
&FGAtmosphere::GetPressureRatio);
|
||||||
|
PropertyManager->Tie("atmosphere/a-ratio", this,
|
||||||
|
&FGAtmosphere::GetSoundSpeedRatio);
|
||||||
|
PropertyManager->Tie("atmosphere/psiw-rad", this,
|
||||||
|
&FGAtmosphere::GetWindPsi);
|
||||||
|
PropertyManager->Tie("atmosphere/delta-T", this,
|
||||||
|
&FGAtmosphere::GetDeltaT, &FGAtmosphere::SetDeltaT);
|
||||||
|
PropertyManager->Tie("atmosphere/T-sl-dev-F", this,
|
||||||
|
&FGAtmosphere::GetSLTempDev, &FGAtmosphere::SetSLTempDev);
|
||||||
|
PropertyManager->Tie("atmosphere/density-altitude", this,
|
||||||
|
&FGAtmosphere::GetDensityAltitude);
|
||||||
|
PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1,
|
||||||
|
(PMF)&FGAtmosphere::GetTurbPQR);
|
||||||
|
PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2,
|
||||||
|
(PMF)&FGAtmosphere::GetTurbPQR);
|
||||||
|
PropertyManager->Tie("atmosphere/r-turb-rad_sec", this,3,
|
||||||
|
(PMF)&FGAtmosphere::GetTurbPQR);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAtmosphere::unbind(void)
|
||||||
|
{
|
||||||
|
PropertyManager->Untie("atmosphere/T-R");
|
||||||
|
PropertyManager->Untie("atmosphere/rho-slugs_ft3");
|
||||||
|
// PropertyManager->Untie("atmosphere/P-psf");
|
||||||
|
PropertyManager->Untie("atmosphere/a-fps");
|
||||||
|
PropertyManager->Untie("atmosphere/T-sl-R");
|
||||||
|
PropertyManager->Untie("atmosphere/rho-sl-slugs_ft3");
|
||||||
|
PropertyManager->Untie("atmosphere/P-sl-psf");
|
||||||
|
PropertyManager->Untie("atmosphere/a-sl-fps");
|
||||||
|
PropertyManager->Untie("atmosphere/delta-T");
|
||||||
|
PropertyManager->Untie("atmosphere/T-sl-dev-F");
|
||||||
|
PropertyManager->Untie("atmosphere/density-altitude");
|
||||||
|
PropertyManager->Untie("atmosphere/theta");
|
||||||
|
PropertyManager->Untie("atmosphere/sigma");
|
||||||
|
PropertyManager->Untie("atmosphere/delta");
|
||||||
|
PropertyManager->Untie("atmosphere/a-ratio");
|
||||||
|
PropertyManager->Untie("atmosphere/psiw-rad");
|
||||||
|
PropertyManager->Untie("atmosphere/p-turb-rad_sec");
|
||||||
|
PropertyManager->Untie("atmosphere/q-turb-rad_sec");
|
||||||
|
PropertyManager->Untie("atmosphere/r-turb-rad_sec");
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGAtmosphere::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGAtmosphere" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGAtmosphere" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 128) { // Turbulence
|
||||||
|
if (frame == 0 && from == 2) {
|
||||||
|
cout << "vTurbulence(X), vTurbulence(Y), vTurbulence(Z), "
|
||||||
|
<< "vTurbulenceGrad(X), vTurbulenceGrad(Y), vTurbulenceGrad(Z), "
|
||||||
|
<< "vDirection(X), vDirection(Y), vDirection(Z), "
|
||||||
|
<< "Magnitude, "
|
||||||
|
<< "vTurbPQR(P), vTurbPQR(Q), vTurbPQR(R), " << endl;
|
||||||
|
} else if (from == 2) {
|
||||||
|
cout << vTurbulence << ", " << vTurbulenceGrad << ", " << vDirection << ", " << Magnitude << ", " << vTurbPQR << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
217
src/FDM/JSBSim/models/FGAtmosphere.h
Normal file
217
src/FDM/JSBSim/models/FGAtmosphere.h
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGAtmosphere.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Implementation of 1959 Standard Atmosphere added by Tony Peden
|
||||||
|
Date started: 11/24/98
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
11/24/98 JSB Created
|
||||||
|
07/23/99 TP Added implementation of 1959 Standard Atmosphere
|
||||||
|
Moved calculation of Mach number to FGPropagate
|
||||||
|
Updated to '76 model
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGAtmosphere_H
|
||||||
|
#define FGAtmosphere_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGModel.h"
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_ATMOSPHERE "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Models the standard atmosphere.
|
||||||
|
@author Tony Peden, Jon Berndt
|
||||||
|
@version $Id$
|
||||||
|
@see Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
|
||||||
|
1989, ISBN 0-07-001641-0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGAtmosphere : public FGModel {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
FGAtmosphere(FGFDMExec*);
|
||||||
|
/// Destructor
|
||||||
|
~FGAtmosphere();
|
||||||
|
/** Runs the Atmosphere model; called by the Executive
|
||||||
|
@return false if no error */
|
||||||
|
bool Run(void);
|
||||||
|
bool InitModel(void);
|
||||||
|
|
||||||
|
/// Returns the temperature in degrees Rankine.
|
||||||
|
inline double GetTemperature(void) const {return *temperature;}
|
||||||
|
/** Returns the density in slugs/ft^3.
|
||||||
|
<i>This function may <b>only</b> be used if Run() is called first.</i> */
|
||||||
|
inline double GetDensity(void) const {return *density;}
|
||||||
|
/// Returns the pressure in psf.
|
||||||
|
inline double GetPressure(void) const {return *pressure;}
|
||||||
|
/// Returns the standard pressure at a specified altitude
|
||||||
|
double GetPressure(double altitude);
|
||||||
|
/// Returns the standard temperature at a specified altitude
|
||||||
|
double GetTemperature(double altitude);
|
||||||
|
/// Returns the standard density at a specified altitude
|
||||||
|
double GetDensity(double altitude);
|
||||||
|
/// Returns the speed of sound in ft/sec.
|
||||||
|
inline double GetSoundSpeed(void) const {return soundspeed;}
|
||||||
|
|
||||||
|
/// Returns the sea level temperature in degrees Rankine.
|
||||||
|
inline double GetTemperatureSL(void) const { return SLtemperature; }
|
||||||
|
/// Returns the sea level density in slugs/ft^3
|
||||||
|
inline double GetDensitySL(void) const { return SLdensity; }
|
||||||
|
/// Returns the sea level pressure in psf.
|
||||||
|
inline double GetPressureSL(void) const { return SLpressure; }
|
||||||
|
/// Returns the sea level speed of sound in ft/sec.
|
||||||
|
inline double GetSoundSpeedSL(void) const { return SLsoundspeed; }
|
||||||
|
|
||||||
|
/// Returns the ratio of at-altitude temperature over the sea level value.
|
||||||
|
inline double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; }
|
||||||
|
/// Returns the ratio of at-altitude density over the sea level value.
|
||||||
|
inline double GetDensityRatio(void) const { return (*density)*rSLdensity; }
|
||||||
|
/// Returns the ratio of at-altitude pressure over the sea level value.
|
||||||
|
inline double GetPressureRatio(void) const { return (*pressure)*rSLpressure; }
|
||||||
|
/// Returns the ratio of at-altitude sound speed over the sea level value.
|
||||||
|
inline double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; }
|
||||||
|
|
||||||
|
/// Tells the simulator to use an externally calculated atmosphere model.
|
||||||
|
void UseExternal(void);
|
||||||
|
/// Tells the simulator to use the internal atmosphere model.
|
||||||
|
void UseInternal(void); //this is the default
|
||||||
|
/// Gets the boolean that tells if the external atmosphere model is being used.
|
||||||
|
bool External(void) { return useExternal; }
|
||||||
|
|
||||||
|
/// Provides the external atmosphere model with an interface to set the temperature.
|
||||||
|
inline void SetExTemperature(double t) { exTemperature=t; }
|
||||||
|
/// Provides the external atmosphere model with an interface to set the density.
|
||||||
|
inline void SetExDensity(double d) { exDensity=d; }
|
||||||
|
/// Provides the external atmosphere model with an interface to set the pressure.
|
||||||
|
inline void SetExPressure(double p) { exPressure=p; }
|
||||||
|
|
||||||
|
/// Sets the temperature deviation at sea-level in degrees Fahrenheit
|
||||||
|
inline void SetSLTempDev(double d) { T_dev_sl = d; }
|
||||||
|
/// Gets the temperature deviation at sea-level in degrees Fahrenheit
|
||||||
|
inline double GetSLTempDev(void) const { return T_dev_sl; }
|
||||||
|
/// Sets the current delta-T in degrees Fahrenheit
|
||||||
|
inline void SetDeltaT(double d) { delta_T = d; }
|
||||||
|
/// Gets the current delta-T in degrees Fahrenheit
|
||||||
|
inline double GetDeltaT(void) const { return delta_T; }
|
||||||
|
/// Gets the at-altitude temperature deviation in degrees Fahrenheit
|
||||||
|
inline double GetTempDev(void) const { return T_dev; }
|
||||||
|
/// Gets the density altitude in feet
|
||||||
|
inline double GetDensityAltitude(void) const { return density_altitude; }
|
||||||
|
|
||||||
|
/// Sets the wind components in NED frame.
|
||||||
|
inline void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
|
||||||
|
|
||||||
|
/// Retrieves the wind components in NED frame.
|
||||||
|
inline FGColumnVector3& GetWindNED(void) { return vWindNED; }
|
||||||
|
|
||||||
|
/** Retrieves the wind direction. The direction is defined as north=0 and
|
||||||
|
increases counterclockwise. The wind heading is returned in radians.*/
|
||||||
|
inline double GetWindPsi(void) const { return psiw; }
|
||||||
|
|
||||||
|
inline void SetTurbGain(double tt) {TurbGain = tt;}
|
||||||
|
inline void SetTurbRate(double tt) {TurbRate = tt;}
|
||||||
|
|
||||||
|
inline double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
|
||||||
|
inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double rho;
|
||||||
|
|
||||||
|
enum tType {ttStandard, ttBerndt, ttNone} turbType;
|
||||||
|
struct atmType {double Temperature; double Pressure; double Density;};
|
||||||
|
|
||||||
|
int lastIndex;
|
||||||
|
double h;
|
||||||
|
double htab[8];
|
||||||
|
double StdSLtemperature,StdSLdensity,StdSLpressure,StdSLsoundspeed;
|
||||||
|
double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
|
||||||
|
double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
|
||||||
|
double *temperature,*density,*pressure;
|
||||||
|
double soundspeed;
|
||||||
|
bool useExternal;
|
||||||
|
double exTemperature,exDensity,exPressure;
|
||||||
|
double intTemperature, intDensity, intPressure;
|
||||||
|
double T_dev_sl, T_dev, delta_T, density_altitude;
|
||||||
|
atmType atmosphere;
|
||||||
|
bool StandardTempOnly;
|
||||||
|
|
||||||
|
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
|
||||||
|
double TurbGain;
|
||||||
|
double TurbRate;
|
||||||
|
FGColumnVector3 vDirectiondAccelDt;
|
||||||
|
FGColumnVector3 vDirectionAccel;
|
||||||
|
FGColumnVector3 vDirection;
|
||||||
|
FGColumnVector3 vTurbulence;
|
||||||
|
FGColumnVector3 vTurbulenceGrad;
|
||||||
|
FGColumnVector3 vBodyTurbGrad;
|
||||||
|
FGColumnVector3 vTurbPQR;
|
||||||
|
|
||||||
|
FGColumnVector3 vWindNED;
|
||||||
|
double psiw;
|
||||||
|
|
||||||
|
/// Calculate the atmosphere for the given altitude, including effects of temperature deviation.
|
||||||
|
void Calculate(double altitude);
|
||||||
|
/// Calculate atmospheric properties other than the basic T, P and rho.
|
||||||
|
void CalculateDerived(void);
|
||||||
|
/// Get T, P and rho for a standard atmosphere at the given altitude.
|
||||||
|
void GetStdAtmosphere(double altitude);
|
||||||
|
void Turbulence(void);
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
||||||
|
|
428
src/FDM/JSBSim/models/FGAuxiliary.cpp
Executable file
428
src/FDM/JSBSim/models/FGAuxiliary.cpp
Executable file
|
@ -0,0 +1,428 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGAuxiliary.cpp
|
||||||
|
Author: Tony Peden, Jon Berndt
|
||||||
|
Date started: 01/26/99
|
||||||
|
Purpose: Calculates additional parameters needed by the visual system, etc.
|
||||||
|
Called by: FGSimExec
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
This class calculates various auxiliary parameters.
|
||||||
|
|
||||||
|
REFERENCES
|
||||||
|
Anderson, John D. "Introduction to Flight", 3rd Edition, McGraw-Hill, 1989
|
||||||
|
pgs. 112-126
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
01/26/99 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGAuxiliary.h"
|
||||||
|
#include "FGAerodynamics.h"
|
||||||
|
#include "FGPropagate.h"
|
||||||
|
#include "FGAtmosphere.h"
|
||||||
|
#include <FGState.h>
|
||||||
|
#include <FGFDMExec.h>
|
||||||
|
#include "FGAircraft.h"
|
||||||
|
#include "FGInertial.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_AUXILIARY;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
|
FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
|
{
|
||||||
|
Name = "FGAuxiliary";
|
||||||
|
vcas = veas = pt = tat = 0;
|
||||||
|
psl = rhosl = 1;
|
||||||
|
earthPosAngle = 0.0;
|
||||||
|
qbar = 0;
|
||||||
|
qbarUW = 0.0;
|
||||||
|
qbarUV = 0.0;
|
||||||
|
Mach = 0.0;
|
||||||
|
alpha = beta = 0.0;
|
||||||
|
adot = bdot = 0.0;
|
||||||
|
gamma = Vt = Vground = 0.0;
|
||||||
|
psigt = 0.0;
|
||||||
|
day_of_year = 1;
|
||||||
|
seconds_in_day = 0.0;
|
||||||
|
hoverbmac = hoverbcg = 0.0;
|
||||||
|
|
||||||
|
vPilotAccel.InitMatrix();
|
||||||
|
vPilotAccelN.InitMatrix();
|
||||||
|
vToEyePt.InitMatrix();
|
||||||
|
vAeroPQR.InitMatrix();
|
||||||
|
vEulerRates.InitMatrix();
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGAuxiliary::~FGAuxiliary()
|
||||||
|
{
|
||||||
|
unbind();
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGAuxiliary::Run()
|
||||||
|
{
|
||||||
|
double A,B,D, hdot_Vt;
|
||||||
|
const FGColumnVector3& vPQR = Propagate->GetPQR();
|
||||||
|
const FGColumnVector3& vUVW = Propagate->GetUVW();
|
||||||
|
const FGColumnVector3& vUVWdot = Propagate->GetUVWdot();
|
||||||
|
const FGColumnVector3& vVel = Propagate->GetVel();
|
||||||
|
|
||||||
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
|
p = Atmosphere->GetPressure();
|
||||||
|
rhosl = Atmosphere->GetDensitySL();
|
||||||
|
psl = Atmosphere->GetPressureSL();
|
||||||
|
sat = Atmosphere->GetTemperature();
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
|
||||||
|
double cTht = Propagate->GetCosEuler(eTht);
|
||||||
|
double cPhi = Propagate->GetCosEuler(ePhi);
|
||||||
|
double sPhi = Propagate->GetSinEuler(ePhi);
|
||||||
|
|
||||||
|
vEulerRates(eTht) = vPQR(eQ)*cPhi - vPQR(eR)*sPhi;
|
||||||
|
if (cTht != 0.0) {
|
||||||
|
vEulerRates(ePsi) = (vPQR(eQ)*sPhi + vPQR(eR)*cPhi)/cTht;
|
||||||
|
vEulerRates(ePhi) = vPQR(eP) + vEulerRates(ePsi)*sPhi;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12/16/2005, JSB: For ground handling purposes, at this time, let's ramp
|
||||||
|
// in the effects of wind from 10 fps to 30 fps when there is weight on the
|
||||||
|
// landing gear wheels.
|
||||||
|
|
||||||
|
if (GroundReactions->GetWOW() && vUVW(eU) < 10) {
|
||||||
|
vAeroPQR = vPQR;
|
||||||
|
vAeroUVW = vUVW;
|
||||||
|
} else if (GroundReactions->GetWOW() && vUVW(eU) < 30) {
|
||||||
|
double factor = (vUVW(eU) - 10.0)/20.0;
|
||||||
|
vAeroPQR = vPQR + factor*Atmosphere->GetTurbPQR();
|
||||||
|
vAeroUVW = vUVW + factor*Propagate->GetTl2b()*Atmosphere->GetWindNED();
|
||||||
|
} else {
|
||||||
|
vAeroPQR = vPQR + Atmosphere->GetTurbPQR();
|
||||||
|
vAeroUVW = vUVW + Propagate->GetTl2b()*Atmosphere->GetWindNED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vt = vAeroUVW.Magnitude();
|
||||||
|
if ( Vt > 0.05) {
|
||||||
|
if (vAeroUVW(eW) != 0.0)
|
||||||
|
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
|
||||||
|
if (vAeroUVW(eV) != 0.0)
|
||||||
|
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV),
|
||||||
|
sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
|
||||||
|
|
||||||
|
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
|
||||||
|
double signU=1;
|
||||||
|
if (vAeroUVW(eU) != 0.0)
|
||||||
|
signU = vAeroUVW(eU)/fabs(vAeroUVW(eU));
|
||||||
|
|
||||||
|
if ( (mUW == 0.0) || (Vt == 0.0) ) {
|
||||||
|
adot = 0.0;
|
||||||
|
bdot = 0.0;
|
||||||
|
} else {
|
||||||
|
adot = (vAeroUVW(eU)*vUVWdot(eW) - vAeroUVW(eW)*vUVWdot(eU))/mUW;
|
||||||
|
bdot = (signU*mUW*vUVWdot(eV) - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU)
|
||||||
|
+ vAeroUVW(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alpha = beta = adot = bdot = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qbar = 0.5*Atmosphere->GetDensity()*Vt*Vt;
|
||||||
|
qbarUW = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
|
||||||
|
qbarUV = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
|
||||||
|
Mach = Vt / Atmosphere->GetSoundSpeed();
|
||||||
|
MachU = vMachUVW(eU) = vAeroUVW(eU) / Atmosphere->GetSoundSpeed();
|
||||||
|
vMachUVW(eV) = vAeroUVW(eV) / Atmosphere->GetSoundSpeed();
|
||||||
|
vMachUVW(eW) = vAeroUVW(eW) / Atmosphere->GetSoundSpeed();
|
||||||
|
|
||||||
|
// Position
|
||||||
|
|
||||||
|
Vground = sqrt( vVel(eNorth)*vVel(eNorth) + vVel(eEast)*vVel(eEast) );
|
||||||
|
|
||||||
|
if (vVel(eNorth) == 0) psigt = 0;
|
||||||
|
else psigt = atan2(vVel(eEast), vVel(eNorth));
|
||||||
|
|
||||||
|
if (psigt < 0.0) psigt += 2*M_PI;
|
||||||
|
|
||||||
|
if (Vt != 0) {
|
||||||
|
hdot_Vt = -vVel(eDown)/Vt;
|
||||||
|
if (fabs(hdot_Vt) <= 1) gamma = asin(hdot_Vt);
|
||||||
|
} else {
|
||||||
|
gamma = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tat = sat*(1 + 0.2*Mach*Mach); // Total Temperature, isentropic flow
|
||||||
|
tatc = RankineToCelsius(tat);
|
||||||
|
|
||||||
|
if (MachU < 1) { // Calculate total pressure assuming isentropic flow
|
||||||
|
pt = p*pow((1 + 0.2*MachU*MachU),3.5);
|
||||||
|
} else {
|
||||||
|
// Use Rayleigh pitot tube formula for normal shock in front of pitot tube
|
||||||
|
B = 5.76*MachU*MachU/(5.6*MachU*MachU - 0.8);
|
||||||
|
D = (2.8*MachU*MachU-0.4)*0.4167;
|
||||||
|
pt = p*pow(B,3.5)*D;
|
||||||
|
}
|
||||||
|
|
||||||
|
A = pow(((pt-p)/psl+1),0.28571);
|
||||||
|
if (MachU > 0.0) {
|
||||||
|
vcas = sqrt(7*psl/rhosl*(A-1));
|
||||||
|
veas = sqrt(2*qbar/rhosl);
|
||||||
|
} else {
|
||||||
|
vcas = veas = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vPilotAccel.InitMatrix();
|
||||||
|
if ( Vt > 1.0 ) {
|
||||||
|
vPilotAccel = Aerodynamics->GetForces()
|
||||||
|
+ Propulsion->GetForces()
|
||||||
|
+ GroundReactions->GetForces();
|
||||||
|
vPilotAccel /= MassBalance->GetMass();
|
||||||
|
vToEyePt = MassBalance->StructuralToBody(Aircraft->GetXYZep());
|
||||||
|
vPilotAccel += Propagate->GetPQRdot() * vToEyePt;
|
||||||
|
vPilotAccel += vPQR * (vPQR * vToEyePt);
|
||||||
|
} else {
|
||||||
|
vPilotAccel = Propagate->GetTl2b() * FGColumnVector3( 0.0, 0.0, Inertial->gravity() );
|
||||||
|
}
|
||||||
|
|
||||||
|
vPilotAccelN = vPilotAccel/Inertial->gravity();
|
||||||
|
|
||||||
|
earthPosAngle += State->Getdt()*Inertial->omega();
|
||||||
|
|
||||||
|
// VRP computation
|
||||||
|
const FGLocation& vLocation = Propagate->GetLocation();
|
||||||
|
FGColumnVector3 vrpStructural = Aircraft->GetXYZvrp();
|
||||||
|
FGColumnVector3 vrpBody = MassBalance->StructuralToBody( vrpStructural );
|
||||||
|
FGColumnVector3 vrpLocal = Propagate->GetTb2l() * vrpBody;
|
||||||
|
vLocationVRP = vLocation.LocalToLocation( vrpLocal );
|
||||||
|
|
||||||
|
// Recompute some derived values now that we know the dependent parameters values ...
|
||||||
|
hoverbcg = Propagate->GetDistanceAGL() / Aircraft->GetWingSpan();
|
||||||
|
|
||||||
|
FGColumnVector3 vMac = Propagate->GetTb2l()*MassBalance->StructuralToBody(Aircraft->GetXYZrp());
|
||||||
|
hoverbmac = (Propagate->GetDistanceAGL() + vMac(3)) / Aircraft->GetWingSpan();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGAuxiliary::GetHeadWind(void)
|
||||||
|
{
|
||||||
|
double psiw,vw;
|
||||||
|
|
||||||
|
psiw = Atmosphere->GetWindPsi();
|
||||||
|
vw = Atmosphere->GetWindNED().Magnitude();
|
||||||
|
|
||||||
|
return vw*cos(psiw - Propagate->GetEuler(ePsi));
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGAuxiliary::GetCrossWind(void)
|
||||||
|
{
|
||||||
|
double psiw,vw;
|
||||||
|
|
||||||
|
psiw = Atmosphere->GetWindPsi();
|
||||||
|
vw = Atmosphere->GetWindNED().Magnitude();
|
||||||
|
|
||||||
|
return vw*sin(psiw - Propagate->GetEuler(ePsi));
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAuxiliary::bind(void)
|
||||||
|
{
|
||||||
|
typedef double (FGAuxiliary::*PMF)(int) const;
|
||||||
|
typedef double (FGAuxiliary::*PF)(void) const;
|
||||||
|
PropertyManager->Tie("velocities/vc-fps", this, &FGAuxiliary::GetVcalibratedFPS);
|
||||||
|
PropertyManager->Tie("velocities/vc-kts", this, &FGAuxiliary::GetVcalibratedKTS);
|
||||||
|
PropertyManager->Tie("velocities/ve-fps", this, &FGAuxiliary::GetVequivalentFPS);
|
||||||
|
PropertyManager->Tie("velocities/ve-kts", this, &FGAuxiliary::GetVequivalentKTS);
|
||||||
|
PropertyManager->Tie("velocities/machU", this, &FGAuxiliary::GetMachU);
|
||||||
|
PropertyManager->Tie("velocities/tat-r", this, &FGAuxiliary::GetTotalTemperature);
|
||||||
|
PropertyManager->Tie("velocities/tat-c", this, &FGAuxiliary::GetTAT_C);
|
||||||
|
PropertyManager->Tie("velocities/pt-lbs_sqft", this, &FGAuxiliary::GetTotalPressure);
|
||||||
|
PropertyManager->Tie("velocities/p-aero-rad_sec", this, eX, (PMF)&FGAuxiliary::GetAeroPQR);
|
||||||
|
PropertyManager->Tie("velocities/q-aero-rad_sec", this, eY, (PMF)&FGAuxiliary::GetAeroPQR);
|
||||||
|
PropertyManager->Tie("velocities/r-aero-rad_sec", this, eZ, (PMF)&FGAuxiliary::GetAeroPQR);
|
||||||
|
PropertyManager->Tie("velocities/phidot-rad_sec", this, ePhi, (PMF)&FGAuxiliary::GetEulerRates);
|
||||||
|
PropertyManager->Tie("velocities/thetadot-rad_sec", this, eTht, (PMF)&FGAuxiliary::GetEulerRates);
|
||||||
|
PropertyManager->Tie("velocities/psidot-rad_sec", this, ePsi, (PMF)&FGAuxiliary::GetEulerRates);
|
||||||
|
PropertyManager->Tie("velocities/u-aero-fps", this, eU, (PMF)&FGAuxiliary::GetAeroUVW);
|
||||||
|
PropertyManager->Tie("velocities/v-aero-fps", this, eV, (PMF)&FGAuxiliary::GetAeroUVW);
|
||||||
|
PropertyManager->Tie("velocities/w-aero-fps", this, eW, (PMF)&FGAuxiliary::GetAeroUVW);
|
||||||
|
PropertyManager->Tie("velocities/vt-fps", this, &FGAuxiliary::GetVt, &FGAuxiliary::SetVt, true);
|
||||||
|
PropertyManager->Tie("velocities/mach", this, &FGAuxiliary::GetMach, &FGAuxiliary::SetMach, true);
|
||||||
|
PropertyManager->Tie("velocities/vg-fps", this, &FGAuxiliary::GetVground);
|
||||||
|
PropertyManager->Tie("accelerations/a-pilot-x-ft_sec2", this, eX, (PMF)&FGAuxiliary::GetPilotAccel);
|
||||||
|
PropertyManager->Tie("accelerations/a-pilot-y-ft_sec2", this, eY, (PMF)&FGAuxiliary::GetPilotAccel);
|
||||||
|
PropertyManager->Tie("accelerations/a-pilot-z-ft_sec2", this, eZ, (PMF)&FGAuxiliary::GetPilotAccel);
|
||||||
|
PropertyManager->Tie("accelerations/n-pilot-x-norm", this, eX, (PMF)&FGAuxiliary::GetNpilot);
|
||||||
|
PropertyManager->Tie("accelerations/n-pilot-y-norm", this, eY, (PMF)&FGAuxiliary::GetNpilot);
|
||||||
|
PropertyManager->Tie("accelerations/n-pilot-z-norm", this, eZ, (PMF)&FGAuxiliary::GetNpilot);
|
||||||
|
PropertyManager->Tie("position/epa-rad", this, &FGAuxiliary::GetEarthPositionAngle);
|
||||||
|
/* PropertyManager->Tie("atmosphere/headwind-fps", this, &FGAuxiliary::GetHeadWind, true);
|
||||||
|
PropertyManager->Tie("atmosphere/crosswind-fps", this, &FGAuxiliary::GetCrossWind, true); */
|
||||||
|
PropertyManager->Tie("aero/alpha-rad", this, (PF)&FGAuxiliary::Getalpha, &FGAuxiliary::Setalpha, true);
|
||||||
|
PropertyManager->Tie("aero/beta-rad", this, (PF)&FGAuxiliary::Getbeta, &FGAuxiliary::Setbeta, true);
|
||||||
|
PropertyManager->Tie("aero/mag-beta-rad", this, (PF)&FGAuxiliary::GetMagBeta);
|
||||||
|
PropertyManager->Tie("aero/alpha-deg", this, inDegrees, (PMF)&FGAuxiliary::Getalpha);
|
||||||
|
PropertyManager->Tie("aero/beta-deg", this, inDegrees, (PMF)&FGAuxiliary::Getbeta);
|
||||||
|
PropertyManager->Tie("aero/mag-beta-deg", this, inDegrees, (PMF)&FGAuxiliary::GetMagBeta);
|
||||||
|
PropertyManager->Tie("aero/qbar-psf", this, &FGAuxiliary::Getqbar, &FGAuxiliary::Setqbar, true);
|
||||||
|
PropertyManager->Tie("aero/qbarUW-psf", this, &FGAuxiliary::GetqbarUW, &FGAuxiliary::SetqbarUW, true);
|
||||||
|
PropertyManager->Tie("aero/qbarUV-psf", this, &FGAuxiliary::GetqbarUV, &FGAuxiliary::SetqbarUV, true);
|
||||||
|
PropertyManager->Tie("aero/alphadot-rad_sec", this, (PF)&FGAuxiliary::Getadot, &FGAuxiliary::Setadot, true);
|
||||||
|
PropertyManager->Tie("aero/betadot-rad_sec", this, (PF)&FGAuxiliary::Getbdot, &FGAuxiliary::Setbdot, true);
|
||||||
|
PropertyManager->Tie("aero/alphadot-deg_sec", this, inDegrees, (PMF)&FGAuxiliary::Getadot);
|
||||||
|
PropertyManager->Tie("aero/betadot-deg_sec", this, inDegrees, (PMF)&FGAuxiliary::Getbdot);
|
||||||
|
PropertyManager->Tie("aero/h_b-cg-ft", this, &FGAuxiliary::GetHOverBCG);
|
||||||
|
PropertyManager->Tie("aero/h_b-mac-ft", this, &FGAuxiliary::GetHOverBMAC);
|
||||||
|
PropertyManager->Tie("flight-path/gamma-rad", this, &FGAuxiliary::GetGamma, &FGAuxiliary::SetGamma);
|
||||||
|
PropertyManager->Tie("flight-path/psi-gt-rad", this, &FGAuxiliary::GetGroundTrack);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGAuxiliary::unbind(void)
|
||||||
|
{
|
||||||
|
PropertyManager->Untie("velocities/vc-fps");
|
||||||
|
PropertyManager->Untie("velocities/vc-kts");
|
||||||
|
PropertyManager->Untie("velocities/ve-fps");
|
||||||
|
PropertyManager->Untie("velocities/ve-kts");
|
||||||
|
PropertyManager->Untie("velocities/machU");
|
||||||
|
PropertyManager->Untie("velocities/tat-r");
|
||||||
|
PropertyManager->Untie("velocities/tat-c");
|
||||||
|
PropertyManager->Untie("velocities/p-aero-rad_sec");
|
||||||
|
PropertyManager->Untie("velocities/q-aero-rad_sec");
|
||||||
|
PropertyManager->Untie("velocities/r-aero-rad_sec");
|
||||||
|
PropertyManager->Untie("velocities/pt-lbs_sqft");
|
||||||
|
PropertyManager->Untie("velocities/phidot-rad_sec");
|
||||||
|
PropertyManager->Untie("velocities/thetadot-rad_sec");
|
||||||
|
PropertyManager->Untie("velocities/psidot-rad_sec");
|
||||||
|
PropertyManager->Untie("velocities/u-aero-fps");
|
||||||
|
PropertyManager->Untie("velocities/v-aero-fps");
|
||||||
|
PropertyManager->Untie("velocities/w-aero-fps");
|
||||||
|
PropertyManager->Untie("velocities/vt-fps");
|
||||||
|
PropertyManager->Untie("velocities/mach");
|
||||||
|
PropertyManager->Untie("velocities/vg-fps");
|
||||||
|
PropertyManager->Untie("accelerations/a-pilot-x-ft_sec2");
|
||||||
|
PropertyManager->Untie("accelerations/a-pilot-y-ft_sec2");
|
||||||
|
PropertyManager->Untie("accelerations/a-pilot-z-ft_sec2");
|
||||||
|
PropertyManager->Untie("accelerations/n-pilot-x-norm");
|
||||||
|
PropertyManager->Untie("accelerations/n-pilot-y-norm");
|
||||||
|
PropertyManager->Untie("accelerations/n-pilot-z-norm");
|
||||||
|
PropertyManager->Untie("position/epa-rad");
|
||||||
|
/* PropertyManager->Untie("atmosphere/headwind-fps");
|
||||||
|
PropertyManager->Untie("atmosphere/crosswind-fps"); */
|
||||||
|
PropertyManager->Untie("aero/qbar-psf");
|
||||||
|
PropertyManager->Untie("aero/qbarUW-psf");
|
||||||
|
PropertyManager->Untie("aero/qbarUV-psf");
|
||||||
|
PropertyManager->Untie("aero/alpha-rad");
|
||||||
|
PropertyManager->Untie("aero/beta-rad");
|
||||||
|
PropertyManager->Untie("aero/alpha-deg");
|
||||||
|
PropertyManager->Untie("aero/beta-deg");
|
||||||
|
PropertyManager->Untie("aero/alphadot-rad_sec");
|
||||||
|
PropertyManager->Untie("aero/betadot-rad_sec");
|
||||||
|
PropertyManager->Untie("aero/mag-beta-rad");
|
||||||
|
PropertyManager->Untie("aero/alphadot-deg_sec");
|
||||||
|
PropertyManager->Untie("aero/betadot-deg_sec");
|
||||||
|
PropertyManager->Untie("aero/mag-beta-deg");
|
||||||
|
PropertyManager->Untie("aero/h_b-cg-ft");
|
||||||
|
PropertyManager->Untie("aero/h_b-mac-ft");
|
||||||
|
PropertyManager->Untie("flight-path/gamma-rad");
|
||||||
|
PropertyManager->Untie("flight-path/psi-gt-rad");
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGAuxiliary::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGAuxiliary" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGAuxiliary" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
if (Mach > 100 || Mach < 0.00)
|
||||||
|
cout << "FGPropagate::Mach is out of bounds: " << Mach << endl;
|
||||||
|
if (qbar > 1e6 || qbar < 0.00)
|
||||||
|
cout << "FGPropagate::qbar is out of bounds: " << qbar << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
245
src/FDM/JSBSim/models/FGAuxiliary.h
Normal file
245
src/FDM/JSBSim/models/FGAuxiliary.h
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGAuxiliary.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 01/26/99
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
11/22/98 JSB Created
|
||||||
|
1/1/00 TP Added calcs and getters for VTAS, VCAS, VEAS, Vground, in knots
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGAUXILIARY_H
|
||||||
|
#define FGAUXILIARY_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGModel.h"
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
#include <math/FGLocation.h>
|
||||||
|
#include "FGPropagate.h"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_AUXILIARY "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Encapsulates various uncategorized scheduled functions.
|
||||||
|
Pilot sensed accelerations are calculated here. This is used
|
||||||
|
for the coordinated turn ball instrument. Motion base platforms sometimes
|
||||||
|
use the derivative of pilot sensed accelerations as the driving parameter,
|
||||||
|
rather than straight accelerations.
|
||||||
|
|
||||||
|
The theory behind pilot-sensed calculations is presented:
|
||||||
|
|
||||||
|
For purposes of discussion and calculation, assume for a minute that the
|
||||||
|
pilot is in space and motionless in inertial space. She will feel
|
||||||
|
no accelerations. If the aircraft begins to accelerate along any axis or
|
||||||
|
axes (without rotating), the pilot will sense those accelerations. If
|
||||||
|
any rotational moment is applied, the pilot will sense an acceleration
|
||||||
|
due to that motion in the amount:
|
||||||
|
|
||||||
|
[wdot X R] + [w X (w X R)]
|
||||||
|
Term I Term II
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
wdot = omegadot, the rotational acceleration rate vector
|
||||||
|
w = omega, the rotational rate vector
|
||||||
|
R = the vector from the aircraft CG to the pilot eyepoint
|
||||||
|
|
||||||
|
The sum total of these two terms plus the acceleration of the aircraft
|
||||||
|
body axis gives the acceleration the pilot senses in inertial space.
|
||||||
|
In the presence of a large body such as a planet, a gravity field also
|
||||||
|
provides an accelerating attraction. This acceleration can be transformed
|
||||||
|
from the reference frame of the planet so as to be expressed in the frame
|
||||||
|
of reference of the aircraft. This gravity field accelerating attraction
|
||||||
|
is felt by the pilot as a force on her tushie as she sits in her aircraft
|
||||||
|
on the runway awaiting takeoff clearance.
|
||||||
|
|
||||||
|
In JSBSim the acceleration of the body frame in inertial space is given
|
||||||
|
by the F = ma relation. If the vForces vector is divided by the aircraft
|
||||||
|
mass, the acceleration vector is calculated. The term wdot is equivalent
|
||||||
|
to the JSBSim vPQRdot vector, and the w parameter is equivalent to vPQR.
|
||||||
|
The radius R is calculated below in the vector vToEyePt.
|
||||||
|
|
||||||
|
@author Tony Peden, Jon Berndt
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGAuxiliary : public FGModel {
|
||||||
|
public:
|
||||||
|
/** Constructor
|
||||||
|
@param Executive a pointer to the parent executive object */
|
||||||
|
FGAuxiliary(FGFDMExec* Executive);
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
~FGAuxiliary();
|
||||||
|
|
||||||
|
/** Runs the Auxiliary routines; called by the Executive
|
||||||
|
@return false if no error */
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
// GET functions
|
||||||
|
|
||||||
|
// Atmospheric parameters GET functions
|
||||||
|
double GetVcalibratedFPS(void) const { return vcas; }
|
||||||
|
double GetVcalibratedKTS(void) const { return vcas*fpstokts; }
|
||||||
|
double GetVequivalentFPS(void) const { return veas; }
|
||||||
|
double GetVequivalentKTS(void) const { return veas*fpstokts; }
|
||||||
|
|
||||||
|
// total pressure above is freestream total pressure for subsonic only
|
||||||
|
// for supersonic it is the 1D total pressure behind a normal shock
|
||||||
|
double GetTotalPressure(void) const { return pt; }
|
||||||
|
double GetTotalTemperature(void) const { return tat; }
|
||||||
|
double GetTAT_C(void) const { return tatc; }
|
||||||
|
|
||||||
|
double GetPilotAccel(int idx) const { return vPilotAccel(idx); }
|
||||||
|
double GetNpilot(int idx) const { return vPilotAccelN(idx); }
|
||||||
|
double GetAeroPQR(int axis) const { return vAeroPQR(axis); }
|
||||||
|
double GetEulerRates(int axis) const { return vEulerRates(axis); }
|
||||||
|
|
||||||
|
const FGColumnVector3& GetPilotAccel (void) const { return vPilotAccel; }
|
||||||
|
const FGColumnVector3& GetNpilot (void) const { return vPilotAccelN; }
|
||||||
|
const FGColumnVector3& GetAeroPQR (void) const { return vAeroPQR; }
|
||||||
|
const FGColumnVector3& GetEulerRates (void) const { return vEulerRates; }
|
||||||
|
const FGColumnVector3& GetAeroUVW (void) const { return vAeroUVW; }
|
||||||
|
const FGLocation& GetLocationVRP(void) const { return vLocationVRP; }
|
||||||
|
|
||||||
|
double GethVRP(void) const { return vLocationVRP.GetRadius() - Propagate->GetSeaLevelRadius(); }
|
||||||
|
double GetAeroUVW (int idx) const { return vAeroUVW(idx); }
|
||||||
|
double Getalpha (void) const { return alpha; }
|
||||||
|
double Getbeta (void) const { return beta; }
|
||||||
|
double Getadot (void) const { return adot; }
|
||||||
|
double Getbdot (void) const { return bdot; }
|
||||||
|
double GetMagBeta (void) const { return fabs(beta); }
|
||||||
|
|
||||||
|
double Getalpha (int unit) const { if (unit == inDegrees) return alpha*radtodeg;
|
||||||
|
else cerr << "Bad units" << endl; return 0.0;}
|
||||||
|
double Getbeta (int unit) const { if (unit == inDegrees) return beta*radtodeg;
|
||||||
|
else cerr << "Bad units" << endl; return 0.0;}
|
||||||
|
double Getadot (int unit) const { if (unit == inDegrees) return adot*radtodeg;
|
||||||
|
else cerr << "Bad units" << endl; return 0.0;}
|
||||||
|
double Getbdot (int unit) const { if (unit == inDegrees) return bdot*radtodeg;
|
||||||
|
else cerr << "Bad units" << endl; return 0.0;}
|
||||||
|
double GetMagBeta (int unit) const { if (unit == inDegrees) return fabs(beta)*radtodeg;
|
||||||
|
else cerr << "Bad units" << endl; return 0.0;}
|
||||||
|
|
||||||
|
double Getqbar (void) const { return qbar; }
|
||||||
|
double GetqbarUW (void) const { return qbarUW; }
|
||||||
|
double GetqbarUV (void) const { return qbarUV; }
|
||||||
|
double GetVt (void) const { return Vt; }
|
||||||
|
double GetVground (void) const { return Vground; }
|
||||||
|
double GetMach (void) const { return Mach; }
|
||||||
|
double GetMachU (void) const { return MachU; }
|
||||||
|
|
||||||
|
double GetHOverBCG(void) const { return hoverbcg; }
|
||||||
|
double GetHOverBMAC(void) const { return hoverbmac; }
|
||||||
|
|
||||||
|
double GetGamma(void) const { return gamma; }
|
||||||
|
double GetGroundTrack(void) const { return psigt; }
|
||||||
|
double GetEarthPositionAngle(void) const { return earthPosAngle; }
|
||||||
|
|
||||||
|
double GetHeadWind(void);
|
||||||
|
double GetCrossWind(void);
|
||||||
|
|
||||||
|
// SET functions
|
||||||
|
|
||||||
|
void SetAeroUVW(FGColumnVector3 tt) { vAeroUVW = tt; }
|
||||||
|
|
||||||
|
void Setalpha (double tt) { alpha = tt; }
|
||||||
|
void Setbeta (double tt) { beta = tt; }
|
||||||
|
void Setqbar (double tt) { qbar = tt; }
|
||||||
|
void SetqbarUW (double tt) { qbarUW = tt; }
|
||||||
|
void SetqbarUV (double tt) { qbarUV = tt; }
|
||||||
|
void SetVt (double tt) { Vt = tt; }
|
||||||
|
void SetMach (double tt) { Mach=tt; }
|
||||||
|
void Setadot (double tt) { adot = tt; }
|
||||||
|
void Setbdot (double tt) { bdot = tt; }
|
||||||
|
|
||||||
|
void SetAB (double t1, double t2) { alpha=t1; beta=t2; }
|
||||||
|
void SetGamma (double tt) { gamma = tt; }
|
||||||
|
|
||||||
|
// Time routines, SET and GET functions
|
||||||
|
|
||||||
|
void SetDayOfYear (int doy) { day_of_year = doy; }
|
||||||
|
void SetSecondsInDay (double sid) { seconds_in_day = sid; }
|
||||||
|
|
||||||
|
int GetDayOfYear (void) const { return day_of_year; }
|
||||||
|
double GetSecondsInDay (void) const { return seconds_in_day; }
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
double vcas, veas;
|
||||||
|
double rhosl, rho, p, psl, pt, tat, sat, tatc; // Don't add a getter for pt!
|
||||||
|
|
||||||
|
FGColumnVector3 vPilotAccel;
|
||||||
|
FGColumnVector3 vPilotAccelN;
|
||||||
|
FGColumnVector3 vToEyePt;
|
||||||
|
FGColumnVector3 vAeroPQR;
|
||||||
|
FGColumnVector3 vAeroUVW;
|
||||||
|
FGColumnVector3 vEuler;
|
||||||
|
FGColumnVector3 vEulerRates;
|
||||||
|
FGColumnVector3 vMachUVW;
|
||||||
|
FGLocation vLocationVRP;
|
||||||
|
|
||||||
|
double Vt, Vground, Mach, MachU;
|
||||||
|
double qbar, qbarUW, qbarUV;
|
||||||
|
double alpha, beta;
|
||||||
|
double adot,bdot;
|
||||||
|
double psigt, gamma;
|
||||||
|
double seconds_in_day; // seconds since current GMT day began
|
||||||
|
int day_of_year; // GMT day, 1 .. 366
|
||||||
|
|
||||||
|
double earthPosAngle;
|
||||||
|
double hoverbcg, hoverbmac;
|
||||||
|
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
844
src/FDM/JSBSim/models/FGFCS.cpp
Normal file
844
src/FDM/JSBSim/models/FGFCS.cpp
Normal file
|
@ -0,0 +1,844 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGFCS.cpp
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 12/12/98
|
||||||
|
Purpose: Model the flight controls
|
||||||
|
Called by: FDMExec
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
This class models the flight controls for a specific airplane
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
12/12/98 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGFCS.h"
|
||||||
|
#include <FGFDMExec.h>
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <models/flight_control/FGFilter.h>
|
||||||
|
#include <models/flight_control/FGDeadBand.h>
|
||||||
|
#include <models/flight_control/FGGain.h>
|
||||||
|
#include <models/flight_control/FGGradient.h>
|
||||||
|
#include <models/flight_control/FGSwitch.h>
|
||||||
|
#include <models/flight_control/FGSummer.h>
|
||||||
|
#include <models/flight_control/FGKinemat.h>
|
||||||
|
#include <models/flight_control/FGFCSFunction.h>
|
||||||
|
#include <models/flight_control/FGSensor.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_FCS;
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Name = "FGFCS";
|
||||||
|
|
||||||
|
DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
|
||||||
|
PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
|
||||||
|
GearCmd = GearPos = 1; // default to gear down
|
||||||
|
LeftBrake = RightBrake = CenterBrake = 0.0;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
for (i=0;i<=NForms;i++) {
|
||||||
|
DePos[i] = DaLPos[i] = DaRPos[i] = DrPos[i] = 0.0;
|
||||||
|
DfPos[i] = DsbPos[i] = DspPos[i] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGFCS::~FGFCS()
|
||||||
|
{
|
||||||
|
if (PropertyManager->HasNode("fcs")) unbind( PropertyManager->GetNode("fcs") );
|
||||||
|
if (PropertyManager->HasNode("ap")) unbind( PropertyManager->GetNode("ap") );
|
||||||
|
PropertyManager->Untie( "gear/gear-cmd-norm" );
|
||||||
|
PropertyManager->Untie( "gear/gear-pos-norm" );
|
||||||
|
|
||||||
|
ThrottleCmd.clear();
|
||||||
|
ThrottlePos.clear();
|
||||||
|
MixtureCmd.clear();
|
||||||
|
MixturePos.clear();
|
||||||
|
PropAdvanceCmd.clear();
|
||||||
|
PropAdvance.clear();
|
||||||
|
SteerPosDeg.clear();
|
||||||
|
PropFeatherCmd.clear();
|
||||||
|
PropFeather.clear();
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i=0;i<APComponents.size();i++) delete APComponents[i];
|
||||||
|
for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
|
||||||
|
for (i=0;i<sensors.size();i++) delete sensors[i];
|
||||||
|
|
||||||
|
APComponents.clear();
|
||||||
|
FCSComponents.clear();
|
||||||
|
sensors.clear();
|
||||||
|
interface_properties.clear();
|
||||||
|
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Notes: In this logic the default engine commands are set. This is simply a
|
||||||
|
// sort of safe-mode method in case the user has not defined control laws for
|
||||||
|
// throttle, mixture, and prop-advance. The throttle, mixture, and prop advance
|
||||||
|
// positions are set equal to the respective commands. Any control logic that is
|
||||||
|
// actually present in the flight_control or autopilot section will override
|
||||||
|
// these simple assignments.
|
||||||
|
|
||||||
|
bool FGFCS::Run(void)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (FGModel::Run()) return true; // fast exit if nothing to do
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
|
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
|
||||||
|
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
|
||||||
|
for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
|
||||||
|
for (i=0; i<PropFeather.size(); i++) PropFeather[i] = PropFeatherCmd[i];
|
||||||
|
|
||||||
|
|
||||||
|
// Set the default steering angle
|
||||||
|
for (i=0; i<SteerPosDeg.size(); i++) {
|
||||||
|
FGLGear* gear = GroundReactions->GetGearUnit(i);
|
||||||
|
SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycle through the sensor, autopilot, and flight control components
|
||||||
|
for (i=0; i<sensors.size(); i++) sensors[i]->Run();
|
||||||
|
for (i=0; i<APComponents.size(); i++) APComponents[i]->Run();
|
||||||
|
for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->Run();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetDaLPos( int form , double pos )
|
||||||
|
{
|
||||||
|
switch(form) {
|
||||||
|
case ofRad:
|
||||||
|
DaLPos[ofRad] = pos;
|
||||||
|
DaLPos[ofDeg] = pos*radtodeg;
|
||||||
|
break;
|
||||||
|
case ofDeg:
|
||||||
|
DaLPos[ofRad] = pos*degtorad;
|
||||||
|
DaLPos[ofDeg] = pos;
|
||||||
|
break;
|
||||||
|
case ofNorm:
|
||||||
|
DaLPos[ofNorm] = pos;
|
||||||
|
}
|
||||||
|
DaLPos[ofMag] = fabs(DaLPos[ofRad]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetDaRPos( int form , double pos )
|
||||||
|
{
|
||||||
|
switch(form) {
|
||||||
|
case ofRad:
|
||||||
|
DaRPos[ofRad] = pos;
|
||||||
|
DaRPos[ofDeg] = pos*radtodeg;
|
||||||
|
break;
|
||||||
|
case ofDeg:
|
||||||
|
DaRPos[ofRad] = pos*degtorad;
|
||||||
|
DaRPos[ofDeg] = pos;
|
||||||
|
break;
|
||||||
|
case ofNorm:
|
||||||
|
DaRPos[ofNorm] = pos;
|
||||||
|
}
|
||||||
|
DaRPos[ofMag] = fabs(DaRPos[ofRad]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetDePos( int form , double pos )
|
||||||
|
{
|
||||||
|
switch(form) {
|
||||||
|
case ofRad:
|
||||||
|
DePos[ofRad] = pos;
|
||||||
|
DePos[ofDeg] = pos*radtodeg;
|
||||||
|
break;
|
||||||
|
case ofDeg:
|
||||||
|
DePos[ofRad] = pos*degtorad;
|
||||||
|
DePos[ofDeg] = pos;
|
||||||
|
break;
|
||||||
|
case ofNorm:
|
||||||
|
DePos[ofNorm] = pos;
|
||||||
|
}
|
||||||
|
DePos[ofMag] = fabs(DePos[ofRad]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetDrPos( int form , double pos )
|
||||||
|
{
|
||||||
|
switch(form) {
|
||||||
|
case ofRad:
|
||||||
|
DrPos[ofRad] = pos;
|
||||||
|
DrPos[ofDeg] = pos*radtodeg;
|
||||||
|
break;
|
||||||
|
case ofDeg:
|
||||||
|
DrPos[ofRad] = pos*degtorad;
|
||||||
|
DrPos[ofDeg] = pos;
|
||||||
|
break;
|
||||||
|
case ofNorm:
|
||||||
|
DrPos[ofNorm] = pos;
|
||||||
|
}
|
||||||
|
DrPos[ofMag] = fabs(DrPos[ofRad]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetDfPos( int form , double pos )
|
||||||
|
{
|
||||||
|
switch(form) {
|
||||||
|
case ofRad:
|
||||||
|
DfPos[ofRad] = pos;
|
||||||
|
DfPos[ofDeg] = pos*radtodeg;
|
||||||
|
break;
|
||||||
|
case ofDeg:
|
||||||
|
DfPos[ofRad] = pos*degtorad;
|
||||||
|
DfPos[ofDeg] = pos;
|
||||||
|
break;
|
||||||
|
case ofNorm:
|
||||||
|
DfPos[ofNorm] = pos;
|
||||||
|
}
|
||||||
|
DfPos[ofMag] = fabs(DfPos[ofRad]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetDsbPos( int form , double pos )
|
||||||
|
{
|
||||||
|
switch(form) {
|
||||||
|
case ofRad:
|
||||||
|
DsbPos[ofRad] = pos;
|
||||||
|
DsbPos[ofDeg] = pos*radtodeg;
|
||||||
|
break;
|
||||||
|
case ofDeg:
|
||||||
|
DsbPos[ofRad] = pos*degtorad;
|
||||||
|
DsbPos[ofDeg] = pos;
|
||||||
|
break;
|
||||||
|
case ofNorm:
|
||||||
|
DsbPos[ofNorm] = pos;
|
||||||
|
}
|
||||||
|
DsbPos[ofMag] = fabs(DsbPos[ofRad]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetDspPos( int form , double pos )
|
||||||
|
{
|
||||||
|
switch(form) {
|
||||||
|
case ofRad:
|
||||||
|
DspPos[ofRad] = pos;
|
||||||
|
DspPos[ofDeg] = pos*radtodeg;
|
||||||
|
break;
|
||||||
|
case ofDeg:
|
||||||
|
DspPos[ofRad] = pos*degtorad;
|
||||||
|
DspPos[ofDeg] = pos;
|
||||||
|
break;
|
||||||
|
case ofNorm:
|
||||||
|
DspPos[ofNorm] = pos;
|
||||||
|
}
|
||||||
|
DspPos[ofMag] = fabs(DspPos[ofRad]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetThrottleCmd(int engineNum, double setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting;
|
||||||
|
} else {
|
||||||
|
ThrottleCmd[engineNum] = setting;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
|
||||||
|
<< " engines exist, but attempted throttle command is for engine "
|
||||||
|
<< engineNum << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetThrottlePos(int engineNum, double setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<ThrottlePos.size();ctr++) ThrottlePos[ctr] = setting;
|
||||||
|
} else {
|
||||||
|
ThrottlePos[engineNum] = setting;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
|
||||||
|
<< " engines exist, but attempted throttle position setting is for engine "
|
||||||
|
<< engineNum << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGFCS::GetThrottleCmd(int engineNum) const
|
||||||
|
{
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
cerr << "Cannot get throttle value for ALL engines" << endl;
|
||||||
|
} else {
|
||||||
|
return ThrottleCmd[engineNum];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
|
||||||
|
<< " engines exist, but throttle setting for engine " << engineNum
|
||||||
|
<< " is selected" << endl;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGFCS::GetThrottlePos(int engineNum) const
|
||||||
|
{
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
cerr << "Cannot get throttle value for ALL engines" << endl;
|
||||||
|
} else {
|
||||||
|
return ThrottlePos[engineNum];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
|
||||||
|
<< " engines exist, but attempted throttle position setting is for engine "
|
||||||
|
<< engineNum << endl;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetMixtureCmd(int engineNum, double setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<MixtureCmd.size();ctr++) MixtureCmd[ctr] = setting;
|
||||||
|
} else {
|
||||||
|
MixtureCmd[engineNum] = setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetMixturePos(int engineNum, double setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<=MixtureCmd.size();ctr++) MixturePos[ctr] = MixtureCmd[ctr];
|
||||||
|
} else {
|
||||||
|
MixturePos[engineNum] = setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetPropAdvanceCmd(int engineNum, double setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<PropAdvanceCmd.size();ctr++) PropAdvanceCmd[ctr] = setting;
|
||||||
|
} else {
|
||||||
|
PropAdvanceCmd[engineNum] = setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetPropAdvance(int engineNum, double setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<=PropAdvanceCmd.size();ctr++) PropAdvance[ctr] = PropAdvanceCmd[ctr];
|
||||||
|
} else {
|
||||||
|
PropAdvance[engineNum] = setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetFeatherCmd(int engineNum, bool setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<PropFeatherCmd.size();ctr++) PropFeatherCmd[ctr] = setting;
|
||||||
|
} else {
|
||||||
|
PropFeatherCmd[engineNum] = setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::SetPropFeather(int engineNum, bool setting)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
|
||||||
|
if (engineNum < (int)ThrottlePos.size()) {
|
||||||
|
if (engineNum < 0) {
|
||||||
|
for (ctr=0;ctr<=PropFeatherCmd.size();ctr++) PropFeather[ctr] = PropFeatherCmd[ctr];
|
||||||
|
} else {
|
||||||
|
PropFeather[engineNum] = setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGFCS::Load(Element* el)
|
||||||
|
{
|
||||||
|
string name, file, fname, comp_name, interface_property_string;
|
||||||
|
unsigned i;
|
||||||
|
vector <FGFCSComponent*> *Components;
|
||||||
|
Element *FCS_cfg, *document, *component_element, *property_element, *sensor_element;
|
||||||
|
Element *channel_element;
|
||||||
|
ifstream* controls_file = new ifstream();
|
||||||
|
FGXMLParse controls_file_parser;
|
||||||
|
|
||||||
|
Components=0;
|
||||||
|
// Determine if the FCS/Autopilot is defined inline in the aircraft configuration
|
||||||
|
// file or in a separate file. Set up the Element pointer as appropriate.
|
||||||
|
|
||||||
|
string separator = "/";
|
||||||
|
#ifdef macintosh
|
||||||
|
separator = ";";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
name = el->GetAttributeValue("name");
|
||||||
|
|
||||||
|
if (name.empty()) {
|
||||||
|
fname = el->GetAttributeValue("file");
|
||||||
|
file = FDMExec->GetAircraftPath() + separator + FDMExec->GetModelName() + separator + fname + ".xml";
|
||||||
|
if (fname.empty()) {
|
||||||
|
cerr << "FCS/Autopilot does not appear to be defined inline nor in a file" << endl;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
controls_file->open(file.c_str());
|
||||||
|
readXML(*controls_file, controls_file_parser);
|
||||||
|
delete controls_file;
|
||||||
|
document = controls_file_parser.GetDocument();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document = el;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document->GetName() == "autopilot") {
|
||||||
|
Components = &APComponents;
|
||||||
|
Name = "Autopilot: " + document->GetAttributeValue("name");
|
||||||
|
} else if (document->GetName() == "flight_control") {
|
||||||
|
Components = &FCSComponents;
|
||||||
|
Name = "FCS: " + document->GetAttributeValue("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
|
||||||
|
// ToDo: How do these get untied?
|
||||||
|
// ToDo: Consider having INPUT and OUTPUT interface properties. Would then
|
||||||
|
// have to duplicate this block of code after channel read code.
|
||||||
|
// Input properties could be write only (nah), and output could be read
|
||||||
|
// only.
|
||||||
|
|
||||||
|
if (document->GetName() == "flight_control") bindModel();
|
||||||
|
|
||||||
|
property_element = document->FindElement("property");
|
||||||
|
while (property_element) {
|
||||||
|
interface_properties.push_back(new double(0));
|
||||||
|
interface_property_string = property_element->GetDataLine();
|
||||||
|
PropertyManager->Tie(interface_property_string, interface_properties.back());
|
||||||
|
property_element = document->FindNextElement("property");
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_element = document->FindElement("sensor");
|
||||||
|
while (sensor_element) {
|
||||||
|
try {
|
||||||
|
sensors.push_back(new FGSensor(this, sensor_element));
|
||||||
|
} catch (string s) {
|
||||||
|
cerr << highint << fgred << endl << " " << s << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sensor_element = document->FindNextElement("sensor");
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_element = document->FindElement("channel");
|
||||||
|
while (channel_element) {
|
||||||
|
component_element = channel_element->FindElement("component");
|
||||||
|
if (component_element) {
|
||||||
|
cout << "This form of the component specification is being deprecated" << endl;
|
||||||
|
} else {
|
||||||
|
component_element = channel_element->GetElement();
|
||||||
|
}
|
||||||
|
while (component_element) {
|
||||||
|
comp_name = component_element->GetAttributeValue("type");
|
||||||
|
try {
|
||||||
|
if ((comp_name == "LAG_FILTER") ||
|
||||||
|
(comp_name == "LEAD_LAG_FILTER") ||
|
||||||
|
(comp_name == "SECOND_ORDER_FILTER") ||
|
||||||
|
(comp_name == "WASHOUT_FILTER") ||
|
||||||
|
(comp_name == "INTEGRATOR") ||
|
||||||
|
(component_element->GetName() == string("lag_filter")) ||
|
||||||
|
(component_element->GetName() == string("lead_lag_filter")) ||
|
||||||
|
(component_element->GetName() == string("washout_filter")) ||
|
||||||
|
(component_element->GetName() == string("second_order_filter")) ||
|
||||||
|
(component_element->GetName() == string("integrator")) )
|
||||||
|
{
|
||||||
|
Components->push_back(new FGFilter(this, component_element));
|
||||||
|
} else if ((comp_name == "PURE_GAIN") ||
|
||||||
|
(comp_name == "SCHEDULED_GAIN") ||
|
||||||
|
(comp_name == "AEROSURFACE_SCALE") ||
|
||||||
|
(component_element->GetName() == string("pure_gain")) ||
|
||||||
|
(component_element->GetName() == string("scheduled_gain")) ||
|
||||||
|
(component_element->GetName() == string("aerosurface_scale")))
|
||||||
|
{
|
||||||
|
Components->push_back(new FGGain(this, component_element));
|
||||||
|
} else if ((comp_name == "SUMMER") || (component_element->GetName() == string("summer"))) {
|
||||||
|
Components->push_back(new FGSummer(this, component_element));
|
||||||
|
} else if ((comp_name == "DEADBAND") || (component_element->GetName() == string("deadband"))) {
|
||||||
|
Components->push_back(new FGDeadBand(this, component_element));
|
||||||
|
} else if (comp_name == "GRADIENT") {
|
||||||
|
Components->push_back(new FGGradient(this, component_element));
|
||||||
|
} else if ((comp_name == "SWITCH") || (component_element->GetName() == string("switch"))) {
|
||||||
|
Components->push_back(new FGSwitch(this, component_element));
|
||||||
|
} else if ((comp_name == "KINEMAT") || (component_element->GetName() == string("kinematic"))) {
|
||||||
|
Components->push_back(new FGKinemat(this, component_element));
|
||||||
|
} else if ((comp_name == "FUNCTION") || (component_element->GetName() == string("fcs_function"))) {
|
||||||
|
Components->push_back(new FGFCSFunction(this, component_element));
|
||||||
|
} else {
|
||||||
|
cerr << "Unknown FCS component: " << comp_name << endl;
|
||||||
|
}
|
||||||
|
} catch(string s) {
|
||||||
|
cerr << highint << fgred << endl << " " << s << endl;
|
||||||
|
cerr << reset << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (comp_name.empty()) { // comp_name will be empty if using new format
|
||||||
|
component_element = channel_element->GetNextElement();
|
||||||
|
} else {
|
||||||
|
component_element = channel_element->FindNextElement("component");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
channel_element = document->FindNextElement("channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
|
||||||
|
{
|
||||||
|
switch (bg) {
|
||||||
|
case FGLGear::bgLeft:
|
||||||
|
return LeftBrake;
|
||||||
|
case FGLGear::bgRight:
|
||||||
|
return RightBrake;
|
||||||
|
case FGLGear::bgCenter:
|
||||||
|
return CenterBrake;
|
||||||
|
default:
|
||||||
|
cerr << "GetBrake asked to return a bogus brake value" << endl;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGFCS::GetComponentStrings(string delimeter)
|
||||||
|
{
|
||||||
|
unsigned int comp;
|
||||||
|
string CompStrings = "";
|
||||||
|
bool firstime = true;
|
||||||
|
|
||||||
|
for (comp = 0; comp < FCSComponents.size(); comp++) {
|
||||||
|
if (firstime) firstime = false;
|
||||||
|
else CompStrings += delimeter;
|
||||||
|
|
||||||
|
CompStrings += FCSComponents[comp]->GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (comp = 0; comp < APComponents.size(); comp++)
|
||||||
|
{
|
||||||
|
CompStrings += delimeter;
|
||||||
|
CompStrings += APComponents[comp]->GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGFCS::GetComponentValues(string delimeter)
|
||||||
|
{
|
||||||
|
unsigned int comp;
|
||||||
|
string CompValues = "";
|
||||||
|
char buffer[12];
|
||||||
|
bool firstime = true;
|
||||||
|
|
||||||
|
for (comp = 0; comp < FCSComponents.size(); comp++) {
|
||||||
|
if (firstime) firstime = false;
|
||||||
|
else CompValues += delimeter;
|
||||||
|
|
||||||
|
sprintf(buffer, "%9.6f", FCSComponents[comp]->GetOutput());
|
||||||
|
CompValues += string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (comp = 0; comp < APComponents.size(); comp++) {
|
||||||
|
sprintf(buffer, "%s%9.6f", delimeter.c_str(), APComponents[comp]->GetOutput());
|
||||||
|
CompValues += string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::AddThrottle(void)
|
||||||
|
{
|
||||||
|
ThrottleCmd.push_back(0.0);
|
||||||
|
ThrottlePos.push_back(0.0);
|
||||||
|
MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
|
||||||
|
MixturePos.push_back(0.0);
|
||||||
|
PropAdvanceCmd.push_back(0.0); // assume throttle and prop pitch are coupled
|
||||||
|
PropAdvance.push_back(0.0);
|
||||||
|
PropFeatherCmd.push_back(false);
|
||||||
|
PropFeather.push_back(false);
|
||||||
|
|
||||||
|
unsigned int num = ThrottleCmd.size()-1;
|
||||||
|
bindThrottle(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::AddGear(void)
|
||||||
|
{
|
||||||
|
SteerPosDeg.push_back(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::bind(void)
|
||||||
|
{
|
||||||
|
PropertyManager->Tie("fcs/aileron-cmd-norm", this, &FGFCS::GetDaCmd, &FGFCS::SetDaCmd);
|
||||||
|
PropertyManager->Tie("fcs/elevator-cmd-norm", this, &FGFCS::GetDeCmd, &FGFCS::SetDeCmd);
|
||||||
|
PropertyManager->Tie("fcs/rudder-cmd-norm", this, &FGFCS::GetDrCmd, &FGFCS::SetDrCmd);
|
||||||
|
PropertyManager->Tie("fcs/steer-cmd-norm", this, &FGFCS::GetDsCmd, &FGFCS::SetDsCmd);
|
||||||
|
PropertyManager->Tie("fcs/flap-cmd-norm", this, &FGFCS::GetDfCmd, &FGFCS::SetDfCmd);
|
||||||
|
PropertyManager->Tie("fcs/speedbrake-cmd-norm", this, &FGFCS::GetDsbCmd, &FGFCS::SetDsbCmd);
|
||||||
|
PropertyManager->Tie("fcs/spoiler-cmd-norm", this, &FGFCS::GetDspCmd, &FGFCS::SetDspCmd);
|
||||||
|
PropertyManager->Tie("fcs/pitch-trim-cmd-norm", this, &FGFCS::GetPitchTrimCmd, &FGFCS::SetPitchTrimCmd);
|
||||||
|
PropertyManager->Tie("fcs/roll-trim-cmd-norm", this, &FGFCS::GetRollTrimCmd, &FGFCS::SetRollTrimCmd);
|
||||||
|
PropertyManager->Tie("fcs/yaw-trim-cmd-norm", this, &FGFCS::GetYawTrimCmd, &FGFCS::SetYawTrimCmd);
|
||||||
|
PropertyManager->Tie("gear/gear-cmd-norm", this, &FGFCS::GetGearCmd, &FGFCS::SetGearCmd);
|
||||||
|
|
||||||
|
PropertyManager->Tie("fcs/left-aileron-pos-rad", this, ofRad, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
|
||||||
|
PropertyManager->Tie("fcs/left-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
|
||||||
|
PropertyManager->Tie("fcs/left-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
|
||||||
|
PropertyManager->Tie("fcs/mag-left-aileron-pos-rad", this, ofMag, &FGFCS::GetDaLPos);
|
||||||
|
|
||||||
|
PropertyManager->Tie("fcs/right-aileron-pos-rad", this, ofRad, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
|
||||||
|
PropertyManager->Tie("fcs/right-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
|
||||||
|
PropertyManager->Tie("fcs/right-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
|
||||||
|
PropertyManager->Tie("fcs/mag-right-aileron-pos-rad", this, ofMag, &FGFCS::GetDaRPos);
|
||||||
|
|
||||||
|
PropertyManager->Tie("fcs/elevator-pos-rad", this, ofRad, &FGFCS::GetDePos, &FGFCS::SetDePos);
|
||||||
|
PropertyManager->Tie("fcs/elevator-pos-deg", this, ofDeg, &FGFCS::GetDePos, &FGFCS::SetDePos);
|
||||||
|
PropertyManager->Tie("fcs/elevator-pos-norm", this, ofNorm, &FGFCS::GetDePos, &FGFCS::SetDePos);
|
||||||
|
PropertyManager->Tie("fcs/mag-elevator-pos-rad", this, ofMag, &FGFCS::GetDePos);
|
||||||
|
|
||||||
|
PropertyManager->Tie("fcs/rudder-pos-rad", this,ofRad, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
|
||||||
|
PropertyManager->Tie("fcs/rudder-pos-deg", this,ofDeg, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
|
||||||
|
PropertyManager->Tie("fcs/rudder-pos-norm", this,ofNorm, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
|
||||||
|
PropertyManager->Tie("fcs/mag-rudder-pos-rad", this,ofMag, &FGFCS::GetDrPos);
|
||||||
|
|
||||||
|
PropertyManager->Tie("fcs/flap-pos-rad", this,ofRad, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
|
||||||
|
PropertyManager->Tie("fcs/flap-pos-deg", this,ofDeg, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
|
||||||
|
PropertyManager->Tie("fcs/flap-pos-norm", this,ofNorm, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
|
||||||
|
|
||||||
|
PropertyManager->Tie("fcs/speedbrake-pos-rad", this,ofRad, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
|
||||||
|
PropertyManager->Tie("fcs/speedbrake-pos-deg", this,ofDeg, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
|
||||||
|
PropertyManager->Tie("fcs/speedbrake-pos-norm", this,ofNorm, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
|
||||||
|
PropertyManager->Tie("fcs/mag-speedbrake-pos-rad", this,ofMag, &FGFCS::GetDsbPos);
|
||||||
|
|
||||||
|
PropertyManager->Tie("fcs/spoiler-pos-rad", this, ofRad, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
|
||||||
|
PropertyManager->Tie("fcs/spoiler-pos-deg", this, ofDeg, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
|
||||||
|
PropertyManager->Tie("fcs/spoiler-pos-norm", this, ofNorm, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
|
||||||
|
PropertyManager->Tie("fcs/mag-spoiler-pos-rad", this, ofMag, &FGFCS::GetDspPos);
|
||||||
|
|
||||||
|
PropertyManager->Tie("gear/gear-pos-norm", this, &FGFCS::GetGearPos, &FGFCS::SetGearPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Technically, this function should probably bind propulsion type specific controls
|
||||||
|
// rather than mixture and prop-advance.
|
||||||
|
//
|
||||||
|
|
||||||
|
void FGFCS::bindThrottle(unsigned int num)
|
||||||
|
{
|
||||||
|
char tmp[80];
|
||||||
|
|
||||||
|
snprintf(tmp, 80, "fcs/throttle-cmd-norm[%u]",num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetThrottleCmd,
|
||||||
|
&FGFCS::SetThrottleCmd);
|
||||||
|
snprintf(tmp, 80, "fcs/throttle-pos-norm[%u]",num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetThrottlePos,
|
||||||
|
&FGFCS::SetThrottlePos);
|
||||||
|
snprintf(tmp, 80, "fcs/mixture-cmd-norm[%u]",num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetMixtureCmd,
|
||||||
|
&FGFCS::SetMixtureCmd);
|
||||||
|
snprintf(tmp, 80, "fcs/mixture-pos-norm[%u]",num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetMixturePos,
|
||||||
|
&FGFCS::SetMixturePos);
|
||||||
|
snprintf(tmp, 80, "fcs/advance-cmd-norm[%u]",num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetPropAdvanceCmd,
|
||||||
|
&FGFCS::SetPropAdvanceCmd);
|
||||||
|
snprintf(tmp, 80, "fcs/advance-pos-norm[%u]", num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetPropAdvance,
|
||||||
|
&FGFCS::SetPropAdvance);
|
||||||
|
snprintf(tmp, 80, "fcs/feather-cmd-norm[%u]", num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetFeatherCmd,
|
||||||
|
&FGFCS::SetFeatherCmd);
|
||||||
|
snprintf(tmp, 80, "fcs/feather-pos-norm[%u]", num);
|
||||||
|
PropertyManager->Tie( tmp, this, num, &FGFCS::GetPropFeather,
|
||||||
|
&FGFCS::SetPropFeather);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::bindModel(void)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
char tmp[80];
|
||||||
|
|
||||||
|
for (i=0; i<SteerPosDeg.size(); i++) {
|
||||||
|
if (GroundReactions->GetGearUnit(i)->GetSteerable()) {
|
||||||
|
snprintf(tmp,80,"fcs/steer-pos-deg[%u]",i);
|
||||||
|
PropertyManager->Tie( tmp, this, i, &FGFCS::GetSteerPosDeg, &FGFCS::SetSteerPosDeg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::unbind(FGPropertyManager *node)
|
||||||
|
{
|
||||||
|
int N = node->nChildren();
|
||||||
|
for (int i=0; i<N; i++) {
|
||||||
|
if (node->getChild(i)->nChildren() ) {
|
||||||
|
unbind( (FGPropertyManager*)node->getChild(i) );
|
||||||
|
} else if ( node->getChild(i)->isTied() ) {
|
||||||
|
node->getChild(i)->untie();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGFCS::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 2) { // Loader
|
||||||
|
cout << endl << " Flight Control (" << Name << ")" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGFCS" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGFCS" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
506
src/FDM/JSBSim/models/FGFCS.h
Normal file
506
src/FDM/JSBSim/models/FGFCS.h
Normal file
|
@ -0,0 +1,506 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGGFCS.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 12/12/98
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
12/12/98 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGFCS_H
|
||||||
|
#define FGFCS_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <vector>
|
||||||
|
# else
|
||||||
|
# include <vector.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <models/flight_control/FGFCSComponent.h>
|
||||||
|
#include <models/FGModel.h>
|
||||||
|
#include <models/FGLGear.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_FCS "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
typedef enum { ofRad=0, ofDeg, ofNorm, ofMag , NForms} OutputForm;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Encapsulates the Flight Control System (FCS) functionality.
|
||||||
|
This class owns and contains the list of FGFCSComponents
|
||||||
|
that define the control system for this aircraft. The config file for the
|
||||||
|
aircraft contains a description of the control path that starts at an input
|
||||||
|
or command and ends at an effector, e.g. an aerosurface. The FCS components
|
||||||
|
which comprise the control laws for an axis are defined sequentially in
|
||||||
|
the configuration file. For instance, for the X-15:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
\<flight_control name="X-15 SAS">
|
||||||
|
\<channel>
|
||||||
|
\<component name="Pitch Trim Sum" type="SUMMER">
|
||||||
|
<input> fcs/elevator-cmd-norm </input>
|
||||||
|
<input> fcs/pitch-trim-cmd-norm </input>
|
||||||
|
<clipto>
|
||||||
|
<min>-1</min>
|
||||||
|
<max>1</max>
|
||||||
|
</clipto>
|
||||||
|
\</component>
|
||||||
|
|
||||||
|
\<component name="Pitch Command Scale" TYPE="AEROSURFACE_SCALE">
|
||||||
|
<input> fcs/pitch-trim-sum </input>
|
||||||
|
<limit>
|
||||||
|
<min> -50 </min>
|
||||||
|
<max> 50 </max>
|
||||||
|
</limit>
|
||||||
|
\</component>
|
||||||
|
|
||||||
|
... etc.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
In the above case we can see the first few components of the pitch channel
|
||||||
|
defined. The input to the first component, as can be seen in the "Pitch trim
|
||||||
|
sum" component, is really the sum of two parameters: elevator command (from
|
||||||
|
the stick - a pilot input), and pitch trim. The type of this component is
|
||||||
|
"Summer".
|
||||||
|
The next component created is an aerosurface scale component - a type of
|
||||||
|
gain (see the LoadFCS() method for insight on how the various types of
|
||||||
|
components map into the actual component classes). This continues until the
|
||||||
|
final component for an axis when the
|
||||||
|
\<output> element specifies where the output is supposed to go. See the
|
||||||
|
individual components for more information on how they are mechanized.
|
||||||
|
|
||||||
|
Another option for the flight controls portion of the config file is that in
|
||||||
|
addition to using the "NAME" attribute in,
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
\<flight_control name="X-15 SAS">
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
one can also supply a filename:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
\<flight_control name="X-15 SAS" file="X15.xml">
|
||||||
|
\</flight_control>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
In this case, the FCS would be read in from another file.
|
||||||
|
|
||||||
|
@author Jon S. Berndt
|
||||||
|
@version $Id$
|
||||||
|
@see FGFCSComponent
|
||||||
|
@see FGXMLElement
|
||||||
|
@see FGGain
|
||||||
|
@see FGSummer
|
||||||
|
@see FGSwitch
|
||||||
|
@see FGGradient
|
||||||
|
@see FGFilter
|
||||||
|
@see FGDeadBand
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGFCS : public FGModel {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructor
|
||||||
|
@param Executive a pointer to the parent executive object */
|
||||||
|
FGFCS(FGFDMExec*);
|
||||||
|
/// Destructor
|
||||||
|
~FGFCS();
|
||||||
|
|
||||||
|
/** Runs the Flight Controls model; called by the Executive
|
||||||
|
@return false if no error */
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
/// @name Pilot input command retrieval
|
||||||
|
//@{
|
||||||
|
/** Gets the aileron command.
|
||||||
|
@return aileron command in range from -1.0 - 1.0 */
|
||||||
|
inline double GetDaCmd(void) const { return DaCmd; }
|
||||||
|
|
||||||
|
/** Gets the elevator command.
|
||||||
|
@return elevator command in range from -1.0 - 1.0 */
|
||||||
|
inline double GetDeCmd(void) const { return DeCmd; }
|
||||||
|
|
||||||
|
/** Gets the rudder command.
|
||||||
|
@return rudder command in range from -1.0 - 1.0 */
|
||||||
|
inline double GetDrCmd(void) const { return DrCmd; }
|
||||||
|
|
||||||
|
/** Gets the steering command.
|
||||||
|
@return steering command in range from -1.0 - 1.0 */
|
||||||
|
inline double GetDsCmd(void) const { return DsCmd; }
|
||||||
|
|
||||||
|
/** Gets the flaps command.
|
||||||
|
@return flaps command in range from 0 to 1.0 */
|
||||||
|
inline double GetDfCmd(void) const { return DfCmd; }
|
||||||
|
|
||||||
|
/** Gets the speedbrake command.
|
||||||
|
@return speedbrake command in range from 0 to 1.0 */
|
||||||
|
inline double GetDsbCmd(void) const { return DsbCmd; }
|
||||||
|
|
||||||
|
/** Gets the spoiler command.
|
||||||
|
@return spoiler command in range from 0 to 1.0 */
|
||||||
|
inline double GetDspCmd(void) const { return DspCmd; }
|
||||||
|
|
||||||
|
/** Gets the throttle command.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return throttle command in range from 0 - 1.0 for the given engine */
|
||||||
|
double GetThrottleCmd(int engine) const;
|
||||||
|
|
||||||
|
/** Gets the mixture command.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return mixture command in range from 0 - 1.0 for the given engine */
|
||||||
|
inline double GetMixtureCmd(int engine) const { return MixtureCmd[engine]; }
|
||||||
|
|
||||||
|
/** Gets the prop pitch command.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return pitch command in range from 0.0 - 1.0 for the given engine */
|
||||||
|
inline double GetPropAdvanceCmd(int engine) const { return PropAdvanceCmd[engine]; }
|
||||||
|
|
||||||
|
/** Gets the prop feather command.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return feather command for the given engine (on / off)*/
|
||||||
|
inline bool GetFeatherCmd(int engine) const { return PropFeatherCmd[engine]; }
|
||||||
|
|
||||||
|
/** Gets the pitch trim command.
|
||||||
|
@return pitch trim command in range from -1.0 to 1.0 */
|
||||||
|
inline double GetPitchTrimCmd(void) const { return PTrimCmd; }
|
||||||
|
|
||||||
|
/** Gets the rudder trim command.
|
||||||
|
@return rudder trim command in range from -1.0 - 1.0 */
|
||||||
|
inline double GetYawTrimCmd(void) const { return YTrimCmd; }
|
||||||
|
|
||||||
|
/** Gets the aileron trim command.
|
||||||
|
@return aileron trim command in range from -1.0 - 1.0 */
|
||||||
|
inline double GetRollTrimCmd(void) const { return RTrimCmd; }
|
||||||
|
|
||||||
|
/** Get the gear extend/retract command. 0 commands gear up, 1 down.
|
||||||
|
defaults to down.
|
||||||
|
@return the current value of the gear extend/retract command*/
|
||||||
|
inline double GetGearCmd(void) const { return GearCmd; }
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/// @name Aerosurface position retrieval
|
||||||
|
//@{
|
||||||
|
/** Gets the left aileron position.
|
||||||
|
@return aileron position in radians */
|
||||||
|
inline double GetDaLPos( int form = ofRad )
|
||||||
|
const { return DaLPos[form]; }
|
||||||
|
|
||||||
|
/// @name Aerosurface position retrieval
|
||||||
|
//@{
|
||||||
|
/** Gets the right aileron position.
|
||||||
|
@return aileron position in radians */
|
||||||
|
inline double GetDaRPos( int form = ofRad )
|
||||||
|
const { return DaRPos[form]; }
|
||||||
|
|
||||||
|
/** Gets the elevator position.
|
||||||
|
@return elevator position in radians */
|
||||||
|
inline double GetDePos( int form = ofRad )
|
||||||
|
const { return DePos[form]; }
|
||||||
|
|
||||||
|
/** Gets the rudder position.
|
||||||
|
@return rudder position in radians */
|
||||||
|
inline double GetDrPos( int form = ofRad )
|
||||||
|
const { return DrPos[form]; }
|
||||||
|
|
||||||
|
/** Gets the speedbrake position.
|
||||||
|
@return speedbrake position in radians */
|
||||||
|
inline double GetDsbPos( int form = ofRad )
|
||||||
|
const { return DsbPos[form]; }
|
||||||
|
|
||||||
|
/** Gets the spoiler position.
|
||||||
|
@return spoiler position in radians */
|
||||||
|
inline double GetDspPos( int form = ofRad )
|
||||||
|
const { return DspPos[form]; }
|
||||||
|
|
||||||
|
/** Gets the flaps position.
|
||||||
|
@return flaps position in radians */
|
||||||
|
inline double GetDfPos( int form = ofRad )
|
||||||
|
const { return DfPos[form]; }
|
||||||
|
|
||||||
|
/** Gets the throttle position.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return throttle position for the given engine in range from 0 - 1.0 */
|
||||||
|
double GetThrottlePos(int engine) const;
|
||||||
|
|
||||||
|
/** Gets the mixture position.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return mixture position for the given engine in range from 0 - 1.0 */
|
||||||
|
inline double GetMixturePos(int engine) const { return MixturePos[engine]; }
|
||||||
|
|
||||||
|
/** Gets the steering position.
|
||||||
|
@return steering position in degrees */
|
||||||
|
double GetSteerPosDeg(int gear) const { return SteerPosDeg[gear]; }
|
||||||
|
|
||||||
|
/** Gets the gear position (0 up, 1 down), defaults to down
|
||||||
|
@return gear position (0 up, 1 down) */
|
||||||
|
inline double GetGearPos(void) const { return GearPos; }
|
||||||
|
|
||||||
|
/** Gets the prop pitch position.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return prop pitch position for the given engine in range from 0 - 1.0 */
|
||||||
|
inline double GetPropAdvance(int engine) const { return PropAdvance[engine]; }
|
||||||
|
|
||||||
|
/** Gets the prop feather position.
|
||||||
|
@param engine engine ID number
|
||||||
|
@return prop fether for the given engine (on / off)*/
|
||||||
|
inline bool GetPropFeather(int engine) const { return PropFeather[engine]; }
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** Retrieves the State object pointer.
|
||||||
|
This is used by the FGFCS-owned components.
|
||||||
|
@return pointer to the State object */
|
||||||
|
inline FGState* GetState(void) { return State; }
|
||||||
|
|
||||||
|
/** Retrieves all component names for inclusion in output stream
|
||||||
|
@param delimeter either a tab or comma string depending on output type
|
||||||
|
@return a string containing the descriptive names for all components */
|
||||||
|
string GetComponentStrings(string delimeter);
|
||||||
|
|
||||||
|
/** Retrieves all component outputs for inclusion in output stream
|
||||||
|
@param delimeter either a tab or comma string depending on output type
|
||||||
|
@return a string containing the numeric values for the current set of
|
||||||
|
component outputs */
|
||||||
|
string GetComponentValues(string delimeter);
|
||||||
|
|
||||||
|
/// @name Pilot input command setting
|
||||||
|
//@{
|
||||||
|
/** Sets the aileron command
|
||||||
|
@param cmd aileron command */
|
||||||
|
inline void SetDaCmd( double cmd ) { DaCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the elevator command
|
||||||
|
@param cmd elevator command in percent*/
|
||||||
|
inline void SetDeCmd(double cmd ) { DeCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the rudder command
|
||||||
|
@param cmd rudder command in percent*/
|
||||||
|
inline void SetDrCmd(double cmd) { DrCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the steering command
|
||||||
|
@param cmd steering command in percent*/
|
||||||
|
inline void SetDsCmd(double cmd) { DsCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the flaps command
|
||||||
|
@param cmd flaps command in percent*/
|
||||||
|
inline void SetDfCmd(double cmd) { DfCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the speedbrake command
|
||||||
|
@param cmd speedbrake command in percent*/
|
||||||
|
inline void SetDsbCmd(double cmd) { DsbCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the spoilers command
|
||||||
|
@param cmd spoilers command in percent*/
|
||||||
|
inline void SetDspCmd(double cmd) { DspCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the pitch trim command
|
||||||
|
@param cmd pitch trim command in percent*/
|
||||||
|
inline void SetPitchTrimCmd(double cmd) { PTrimCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the rudder trim command
|
||||||
|
@param cmd rudder trim command in percent*/
|
||||||
|
inline void SetYawTrimCmd(double cmd) { YTrimCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the aileron trim command
|
||||||
|
@param cmd aileron trim command in percent*/
|
||||||
|
inline void SetRollTrimCmd(double cmd) { RTrimCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the throttle command for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd throttle command in percent (0 - 100)*/
|
||||||
|
void SetThrottleCmd(int engine, double cmd);
|
||||||
|
|
||||||
|
/** Sets the mixture command for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd mixture command in percent (0 - 100)*/
|
||||||
|
void SetMixtureCmd(int engine, double cmd);
|
||||||
|
|
||||||
|
/** Set the gear extend/retract command, defaults to down
|
||||||
|
@param gear command 0 for up, 1 for down */
|
||||||
|
void SetGearCmd(double gearcmd) { GearCmd = gearcmd; }
|
||||||
|
|
||||||
|
/** Sets the propeller pitch command for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd mixture command in percent (0.0 - 1.0)*/
|
||||||
|
void SetPropAdvanceCmd(int engine, double cmd);
|
||||||
|
|
||||||
|
/** Sets the propeller feather command for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd feather (bool)*/
|
||||||
|
void SetFeatherCmd(int engine, bool cmd);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/// @name Aerosurface position setting
|
||||||
|
//@{
|
||||||
|
/** Sets the left aileron position
|
||||||
|
@param cmd left aileron position in radians*/
|
||||||
|
inline void SetDaLPos( int form , double pos );
|
||||||
|
|
||||||
|
/** Sets the right aileron position
|
||||||
|
@param cmd right aileron position in radians*/
|
||||||
|
inline void SetDaRPos( int form , double pos );
|
||||||
|
|
||||||
|
/** Sets the elevator position
|
||||||
|
@param cmd elevator position in radians*/
|
||||||
|
inline void SetDePos( int form , double pos );
|
||||||
|
|
||||||
|
/** Sets the rudder position
|
||||||
|
@param cmd rudder position in radians*/
|
||||||
|
inline void SetDrPos( int form , double pos );
|
||||||
|
|
||||||
|
/** Sets the flaps position
|
||||||
|
@param cmd flaps position in radians*/
|
||||||
|
inline void SetDfPos( int form , double pos );
|
||||||
|
|
||||||
|
/** Sets the speedbrake position
|
||||||
|
@param cmd speedbrake position in radians*/
|
||||||
|
inline void SetDsbPos( int form , double pos );
|
||||||
|
|
||||||
|
/** Sets the spoiler position
|
||||||
|
@param cmd spoiler position in radians*/
|
||||||
|
inline void SetDspPos( int form , double pos );
|
||||||
|
|
||||||
|
/** Sets the actual throttle setting for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd throttle setting in percent (0 - 100)*/
|
||||||
|
void SetThrottlePos(int engine, double cmd);
|
||||||
|
|
||||||
|
/** Sets the actual mixture setting for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd mixture setting in percent (0 - 100)*/
|
||||||
|
void SetMixturePos(int engine, double cmd);
|
||||||
|
|
||||||
|
/** Sets the steering position
|
||||||
|
@param cmd steering position in degrees*/
|
||||||
|
void SetSteerPosDeg(int gear, double pos) { SteerPosDeg[gear] = pos; }
|
||||||
|
|
||||||
|
/** Set the gear extend/retract position, defaults to down
|
||||||
|
@param gear position 0 up, 1 down */
|
||||||
|
void SetGearPos(double gearpos) { GearPos = gearpos; }
|
||||||
|
|
||||||
|
|
||||||
|
/** Sets the actual prop pitch setting for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd prop pitch setting in percent (0.0 - 1.0)*/
|
||||||
|
void SetPropAdvance(int engine, double cmd);
|
||||||
|
|
||||||
|
/** Sets the actual prop feather setting for the specified engine
|
||||||
|
@param engine engine ID number
|
||||||
|
@param cmd prop fether setting (bool)*/
|
||||||
|
void SetPropFeather(int engine, bool cmd);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/// @name Landing Gear brakes
|
||||||
|
//@{
|
||||||
|
/** Sets the left brake group
|
||||||
|
@param cmd brake setting in percent (0.0 - 1.0) */
|
||||||
|
void SetLBrake(double cmd) {LeftBrake = cmd;}
|
||||||
|
|
||||||
|
/** Sets the right brake group
|
||||||
|
@param cmd brake setting in percent (0.0 - 1.0) */
|
||||||
|
void SetRBrake(double cmd) {RightBrake = cmd;}
|
||||||
|
|
||||||
|
/** Sets the center brake group
|
||||||
|
@param cmd brake setting in percent (0.0 - 1.0) */
|
||||||
|
void SetCBrake(double cmd) {CenterBrake = cmd;}
|
||||||
|
|
||||||
|
/** Gets the brake for a specified group.
|
||||||
|
@param bg which brakegroup to retrieve the command for
|
||||||
|
@return the brake setting for the supplied brake group argument */
|
||||||
|
double GetBrake(FGLGear::BrakeGroup bg);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** Loads the Flight Control System.
|
||||||
|
The FGAircraft instance is actually responsible for reading the config file
|
||||||
|
and calling the various Load() methods of the other systems, passing in
|
||||||
|
the XML Element instance pointer. Load() is called from FGAircraft.
|
||||||
|
@param el pointer to the Element instance
|
||||||
|
@return true if succesful */
|
||||||
|
bool Load(Element* el);
|
||||||
|
|
||||||
|
void AddThrottle(void);
|
||||||
|
void AddGear(void);
|
||||||
|
|
||||||
|
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
|
||||||
|
double DePos[NForms], DaLPos[NForms], DaRPos[NForms], DrPos[NForms];
|
||||||
|
double DfPos[NForms], DsbPos[NForms], DspPos[NForms];
|
||||||
|
double PTrimCmd, YTrimCmd, RTrimCmd;
|
||||||
|
vector <double> ThrottleCmd;
|
||||||
|
vector <double> ThrottlePos;
|
||||||
|
vector <double> MixtureCmd;
|
||||||
|
vector <double> MixturePos;
|
||||||
|
vector <double> PropAdvanceCmd;
|
||||||
|
vector <double> PropAdvance;
|
||||||
|
vector <bool> PropFeatherCmd;
|
||||||
|
vector <bool> PropFeather;
|
||||||
|
vector <double> SteerPosDeg;
|
||||||
|
double LeftBrake, RightBrake, CenterBrake; // Brake settings
|
||||||
|
double GearCmd,GearPos;
|
||||||
|
|
||||||
|
vector <FGFCSComponent*> FCSComponents;
|
||||||
|
vector <FGFCSComponent*> APComponents;
|
||||||
|
vector <double*> interface_properties;
|
||||||
|
vector <FGFCSComponent*> sensors;
|
||||||
|
void bind(void);
|
||||||
|
void bindModel(void);
|
||||||
|
void bindThrottle(unsigned int);
|
||||||
|
void unbind(FGPropertyManager *node);
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
272
src/FDM/JSBSim/models/FGGroundReactions.cpp
Normal file
272
src/FDM/JSBSim/models/FGGroundReactions.cpp
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGGroundReactions.cpp
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 09/13/00
|
||||||
|
Purpose: Encapsulates the ground reaction forces (gear and collision)
|
||||||
|
|
||||||
|
------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
09/13/00 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
#include "FGGroundReactions.h"
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_GROUNDREACTIONS;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
|
FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex)
|
||||||
|
{
|
||||||
|
Name = "FGGroundReactions";
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGGroundReactions::~FGGroundReactions(void)
|
||||||
|
{
|
||||||
|
for (int i=0; i<lGear.size();i++) lGear[i].unbind();
|
||||||
|
lGear.clear();
|
||||||
|
|
||||||
|
unbind();
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGGroundReactions::Run(void)
|
||||||
|
{
|
||||||
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
|
vForces.InitMatrix();
|
||||||
|
vMoments.InitMatrix();
|
||||||
|
|
||||||
|
if ( Propagate->GetDistanceAGL() < 300.0 ) { // Only execute gear code below 300 feet
|
||||||
|
vector <FGLGear>::iterator iGear = lGear.begin();
|
||||||
|
|
||||||
|
// Sum forces and moments for all gear, here.
|
||||||
|
// Some optimizations may be made here - or rather in the gear code itself.
|
||||||
|
// The gear ::Run() method is called several times - once for each gear.
|
||||||
|
// Perhaps there is some commonality for things which only need to be
|
||||||
|
// calculated once.
|
||||||
|
|
||||||
|
while (iGear != lGear.end()) {
|
||||||
|
vForces += iGear->Force();
|
||||||
|
vMoments += iGear->Moment();
|
||||||
|
iGear++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGGroundReactions::GetWOW(void)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (int i=0; i<lGear.size(); i++) {
|
||||||
|
if (lGear[i].IsBogey() && lGear[i].GetWOW()) {
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGGroundReactions::Load(Element* el)
|
||||||
|
{
|
||||||
|
int num=0;
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
|
||||||
|
Element* contact_element = el->FindElement("contact");
|
||||||
|
while (contact_element) {
|
||||||
|
lGear.push_back(FGLGear(contact_element, FDMExec, num++));
|
||||||
|
FCS->AddGear(); // make the FCS aware of the landing gear
|
||||||
|
contact_element = el->FindNextElement("contact");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<lGear.size();i++) lGear[i].bind();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGGroundReactions::GetGroundReactionStrings(string delimeter)
|
||||||
|
{
|
||||||
|
std::ostringstream buf;
|
||||||
|
|
||||||
|
for (unsigned int i=0;i<lGear.size();i++) {
|
||||||
|
string name = lGear[i].GetName();
|
||||||
|
buf << name << "_WOW" << delimeter
|
||||||
|
<< name << "_stroke" << delimeter
|
||||||
|
<< name << "_strokeVel" << delimeter
|
||||||
|
<< name << "_CompressForce" << delimeter
|
||||||
|
<< name << "_WhlSideForce" << delimeter
|
||||||
|
<< name << "_WhlVelVecX" << delimeter
|
||||||
|
<< name << "_WhlVelVecY" << delimeter
|
||||||
|
<< name << "_WhlRollForce" << delimeter
|
||||||
|
<< name << "_BodyXForce" << delimeter
|
||||||
|
<< name << "_BodyYForce" << delimeter
|
||||||
|
<< name << "_WhlSlipDegrees" << delimeter;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf << "TotalGearForce_X" << delimeter
|
||||||
|
<< "TotalGearForce_Y" << delimeter
|
||||||
|
<< "TotalGearForce_Z" << delimeter
|
||||||
|
<< "TotalGearMoment_L" << delimeter
|
||||||
|
<< "TotalGearMoment_M" << delimeter
|
||||||
|
<< "TotalGearMoment_N";
|
||||||
|
|
||||||
|
return buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGGroundReactions::GetGroundReactionValues(string delimeter)
|
||||||
|
{
|
||||||
|
std::ostringstream buf;
|
||||||
|
|
||||||
|
for (unsigned int i=0;i<lGear.size();i++) {
|
||||||
|
FGLGear& gear = lGear[i];
|
||||||
|
buf << (gear.GetWOW() ? "1, " : "0, ")
|
||||||
|
<< setprecision(5) << gear.GetCompLen() << delimeter
|
||||||
|
<< setprecision(6) << gear.GetCompVel() << delimeter
|
||||||
|
<< setprecision(10) << gear.GetCompForce() << delimeter
|
||||||
|
<< setprecision(6) << gear.GetWheelVel(eX) << delimeter
|
||||||
|
<< gear.GetWheelVel(eY) << delimeter
|
||||||
|
<< gear.GetWheelSideForce() << delimeter
|
||||||
|
<< gear.GetWheelRollForce() << delimeter
|
||||||
|
<< gear.GetBodyXForce() << delimeter
|
||||||
|
<< gear.GetBodyYForce() << delimeter
|
||||||
|
<< gear.GetWheelSlipAngle() << delimeter;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf << vForces(eX) << delimeter
|
||||||
|
<< vForces(eY) << delimeter
|
||||||
|
<< vForces(eZ) << delimeter
|
||||||
|
<< vMoments(eX) << delimeter
|
||||||
|
<< vMoments(eY) << delimeter
|
||||||
|
<< vMoments(eZ);
|
||||||
|
|
||||||
|
return buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGGroundReactions::bind(void)
|
||||||
|
{
|
||||||
|
typedef double (FGGroundReactions::*PMF)(int) const;
|
||||||
|
PropertyManager->Tie("gear/num-units", this, &FGGroundReactions::GetNumGearUnits);
|
||||||
|
PropertyManager->Tie("moments/l-gear-lbsft", this, eL, (PMF)&FGGroundReactions::GetMoments);
|
||||||
|
PropertyManager->Tie("moments/m-gear-lbsft", this, eM, (PMF)&FGGroundReactions::GetMoments);
|
||||||
|
PropertyManager->Tie("moments/n-gear-lbsft", this, eN, (PMF)&FGGroundReactions::GetMoments);
|
||||||
|
PropertyManager->Tie("forces/fbx-gear-lbs", this, eX, (PMF)&FGGroundReactions::GetForces);
|
||||||
|
PropertyManager->Tie("forces/fby-gear-lbs", this, eY, (PMF)&FGGroundReactions::GetForces);
|
||||||
|
PropertyManager->Tie("forces/fbz-gear-lbs", this, eZ, (PMF)&FGGroundReactions::GetForces);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGGroundReactions::unbind(void)
|
||||||
|
{
|
||||||
|
PropertyManager->Untie("gear/num-units");
|
||||||
|
PropertyManager->Untie("moments/l-gear-lbsft");
|
||||||
|
PropertyManager->Untie("moments/m-gear-lbsft");
|
||||||
|
PropertyManager->Untie("moments/n-gear-lbsft");
|
||||||
|
PropertyManager->Untie("forces/fbx-gear-lbs");
|
||||||
|
PropertyManager->Untie("forces/fby-gear-lbs");
|
||||||
|
PropertyManager->Untie("forces/fbz-gear-lbs");
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGGroundReactions::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 2) { // Loading
|
||||||
|
cout << endl << " Ground Reactions: " << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGGroundReactions" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGGroundReactions" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
114
src/FDM/JSBSim/models/FGGroundReactions.h
Normal file
114
src/FDM/JSBSim/models/FGGroundReactions.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGGroundReactions.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 09/13/00
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
09/13/00 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGGROUNDREACTIONS_H
|
||||||
|
#define FGGROUNDREACTIONS_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <vector>
|
||||||
|
# else
|
||||||
|
# include <vector.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGModel.h"
|
||||||
|
#include "FGLGear.h"
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
|
#define ID_GROUNDREACTIONS "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Manages ground reactions modeling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGGroundReactions : public FGModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGGroundReactions(FGFDMExec*);
|
||||||
|
~FGGroundReactions(void);
|
||||||
|
|
||||||
|
bool Run(void);
|
||||||
|
bool Load(Element* el);
|
||||||
|
FGColumnVector3& GetForces(void) {return vForces;}
|
||||||
|
double GetForces(int idx) const {return vForces(idx);}
|
||||||
|
FGColumnVector3& GetMoments(void) {return vMoments;}
|
||||||
|
double GetMoments(int idx) const {return vMoments(idx);}
|
||||||
|
string GetGroundReactionStrings(string delimeter);
|
||||||
|
string GetGroundReactionValues(string delimeter);
|
||||||
|
bool GetWOW(void);
|
||||||
|
|
||||||
|
inline int GetNumGearUnits(void) const { return lGear.size(); }
|
||||||
|
|
||||||
|
/** Gets a gear instance
|
||||||
|
@param gear index of gear instance
|
||||||
|
@return a pointer to the FGLGear instance of the gear unit requested */
|
||||||
|
inline FGLGear* GetGearUnit(int gear) { return &(lGear[gear]); }
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
vector <FGLGear> lGear;
|
||||||
|
FGColumnVector3 vForces;
|
||||||
|
FGColumnVector3 vMoments;
|
||||||
|
FGColumnVector3 vMaxStaticGrip;
|
||||||
|
FGColumnVector3 vMaxMomentResist;
|
||||||
|
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
||||||
|
|
134
src/FDM/JSBSim/models/FGInertial.cpp
Normal file
134
src/FDM/JSBSim/models/FGInertial.cpp
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGInertial.cpp
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 09/13/00
|
||||||
|
Purpose: Encapsulates the inertial frame forces (coriolis and centrifugal)
|
||||||
|
|
||||||
|
------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
09/13/00 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGInertial.h"
|
||||||
|
#include "FGPropagate.h"
|
||||||
|
#include "FGState.h"
|
||||||
|
#include "FGMassBalance.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_INERTIAL;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
|
FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
|
||||||
|
{
|
||||||
|
Name = "FGInertial";
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
RotationRate = 0.00007272205217;
|
||||||
|
GM = 14.06252720E15;
|
||||||
|
RadiusReference = 20925650.00;
|
||||||
|
gAccelReference = GM/(RadiusReference*RadiusReference);
|
||||||
|
gAccel = GM/(RadiusReference*RadiusReference);
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGInertial::~FGInertial(void)
|
||||||
|
{
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGInertial::Run(void)
|
||||||
|
{
|
||||||
|
// Fast return if we have nothing to do ...
|
||||||
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
|
// Gravitation accel
|
||||||
|
double r = Propagate->GetRadius();
|
||||||
|
gAccel = GetGAccel(r);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGInertial::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGInertial" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGInertial" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
101
src/FDM/JSBSim/models/FGInertial.h
Normal file
101
src/FDM/JSBSim/models/FGInertial.h
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGInertial.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 09/13/00
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
09/13/00 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGINERTIAL_H
|
||||||
|
#define FGINERTIAL_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
# include <vector>
|
||||||
|
# else
|
||||||
|
# include <vector.h>
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGModel.h"
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_INERTIAL "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Models inertial forces (e.g. centripetal and coriolis accelerations).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGInertial : public FGModel {
|
||||||
|
|
||||||
|
public:
|
||||||
|
FGInertial(FGFDMExec*);
|
||||||
|
~FGInertial(void);
|
||||||
|
|
||||||
|
bool Run(void);
|
||||||
|
double SLgravity(void) const {return gAccelReference;}
|
||||||
|
double gravity(void) const {return gAccel;}
|
||||||
|
double omega(void) const {return RotationRate;}
|
||||||
|
double GetGAccel(double r) const { return GM/(r*r); }
|
||||||
|
double RefRadius(void) const {return RadiusReference;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double gAccel;
|
||||||
|
double gAccelReference;
|
||||||
|
double RadiusReference;
|
||||||
|
double RotationRate;
|
||||||
|
double GM;
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
269
src/FDM/JSBSim/models/FGInput.cpp
Executable file
269
src/FDM/JSBSim/models/FGInput.cpp
Executable file
|
@ -0,0 +1,269 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGInput.cpp
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 12/02/98
|
||||||
|
Purpose: Manage output of sim parameters to file or stdout
|
||||||
|
Called by: FGSimExec
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
This is the place where you create output routines to dump data for perusal
|
||||||
|
later.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
12/02/98 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGInput.h"
|
||||||
|
#include "FGState.h"
|
||||||
|
#include "FGFDMExec.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_INPUT;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGInput::FGInput(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
|
{
|
||||||
|
Name = "FGInput";
|
||||||
|
sFirstPass = dFirstPass = true;
|
||||||
|
socket = 0;
|
||||||
|
port = 0;
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGInput::~FGInput()
|
||||||
|
{
|
||||||
|
if (socket) delete socket;
|
||||||
|
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
//
|
||||||
|
// This function handles accepting input commands from the socket interface.
|
||||||
|
//
|
||||||
|
|
||||||
|
bool FGInput::Run(void)
|
||||||
|
{
|
||||||
|
string line, token, info_string;
|
||||||
|
int start=0, string_start=0, string_end=0;
|
||||||
|
int token_start=0, token_end=0;
|
||||||
|
char buf[100];
|
||||||
|
double value=0;
|
||||||
|
FGPropertyManager* node=0;
|
||||||
|
|
||||||
|
if (FGModel::Run()) return true; // fast exit if nothing to do
|
||||||
|
if (port == 0) return true; // Do nothing here if port not defined
|
||||||
|
// This model DOES execute if "Exec->Holding"
|
||||||
|
|
||||||
|
data = socket->Receive(); // get socket transmission if present
|
||||||
|
|
||||||
|
if (data.size() > 0) {
|
||||||
|
// parse lines
|
||||||
|
while (1) {
|
||||||
|
string_start = data.find_first_not_of("\r\n", start);
|
||||||
|
if (string_start == string::npos) break;
|
||||||
|
string_end = data.find_first_of("\r\n", string_start);
|
||||||
|
if (string_end == string::npos) break;
|
||||||
|
line = data.substr(string_start, string_end-string_start);
|
||||||
|
if (line.size() == 0) break;
|
||||||
|
|
||||||
|
// now parse individual line
|
||||||
|
token_start = line.find_first_not_of(" ", 0);
|
||||||
|
token_end = line.find_first_of(" ", token_start);
|
||||||
|
token = line.substr(token_start, token_end - token_start);
|
||||||
|
|
||||||
|
if (token == "set" || token == "SET" ) { // SET PROPERTY
|
||||||
|
|
||||||
|
token_start = line.find_first_not_of(" ", token_end);
|
||||||
|
token_end = line.find_first_of(" ", token_start);
|
||||||
|
token = line.substr(token_start, token_end-token_start);
|
||||||
|
node = PropertyManager->GetNode(token);
|
||||||
|
if (node == 0) socket->Reply("Unknown property\n");
|
||||||
|
else {
|
||||||
|
token_start = line.find_first_not_of(" ", token_end);
|
||||||
|
token_end = line.find_first_of(" ", token_start);
|
||||||
|
token = line.substr(token_start, token_end-token_start);
|
||||||
|
value = atof(token.c_str());
|
||||||
|
node->setDoubleValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (token == "get" || token == "GET") { // GET PROPERTY
|
||||||
|
|
||||||
|
token_start = line.find_first_not_of(" ", token_end);
|
||||||
|
if (token_start == string::npos) {
|
||||||
|
socket->Reply("No property argument supplied.\n");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
token = line.substr(token_start, line.size()-token_start);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
node = PropertyManager->GetNode(token);
|
||||||
|
} catch(...) {
|
||||||
|
socket->Reply("Badly formed property query\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (node == 0) {
|
||||||
|
if (FDMExec->Holding()) { // if holding can query property list
|
||||||
|
string query = FDMExec->QueryPropertyCatalog(token);
|
||||||
|
socket->Reply(query);
|
||||||
|
} else {
|
||||||
|
socket->Reply("Must be in HOLD to search properties\n");
|
||||||
|
}
|
||||||
|
} else if (node > 0) {
|
||||||
|
sprintf(buf, "%s = %12.6f\n", token.c_str(), node->getDoubleValue());
|
||||||
|
socket->Reply(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (token == "hold" || token == "HOLD") { // PAUSE
|
||||||
|
|
||||||
|
FDMExec->Hold();
|
||||||
|
|
||||||
|
} else if (token == "resume" || token == "RESUME") { // RESUME
|
||||||
|
|
||||||
|
FDMExec->Resume();
|
||||||
|
|
||||||
|
} else if (token == "quit" || token == "QUIT") { // QUIT
|
||||||
|
|
||||||
|
// close the socket connection
|
||||||
|
socket->Reply("");
|
||||||
|
socket->Close();
|
||||||
|
|
||||||
|
} else if (token == "info" || token == "INFO") { // INFO
|
||||||
|
|
||||||
|
// get info about the sim run and/or aircraft, etc.
|
||||||
|
sprintf(buf, "%8.3f\0", State->Getsim_time());
|
||||||
|
info_string = "JSBSim version: " + JSBSim_version + "\n";
|
||||||
|
info_string += "Config File version: " + needed_cfg_version + "\n";
|
||||||
|
info_string += "Aircraft simulated: " + Aircraft->GetAircraftName() + "\n";
|
||||||
|
info_string += "Simulation time: " + string(buf) + "\n";
|
||||||
|
socket->Reply(info_string);
|
||||||
|
|
||||||
|
} else if (token == "help" || token == "HELP") { // HELP
|
||||||
|
|
||||||
|
socket->Reply(
|
||||||
|
" JSBSim Server commands:\n\n"
|
||||||
|
" get {property name}\n"
|
||||||
|
" set {property name} {value}\n"
|
||||||
|
" hold\n"
|
||||||
|
" resume\n"
|
||||||
|
" help\n"
|
||||||
|
" quit\n"
|
||||||
|
" info\n\n");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
socket->Reply(string("Unknown command: ") + token + string("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
start = string_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGInput::Load(Element* element)
|
||||||
|
{
|
||||||
|
string type="", parameter="";
|
||||||
|
string name="", fname="";
|
||||||
|
string property;
|
||||||
|
|
||||||
|
port = element->GetAttributeValueAsNumber("port");
|
||||||
|
if (port == 0) {
|
||||||
|
cerr << endl << "No port assigned in input element" << endl;
|
||||||
|
} else {
|
||||||
|
socket = new FGfdmSocket(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGInput::Debug(int from)
|
||||||
|
{
|
||||||
|
string scratch="";
|
||||||
|
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
}
|
||||||
|
if (from == 2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGInput" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGInput" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
107
src/FDM/JSBSim/models/FGInput.h
Executable file
107
src/FDM/JSBSim/models/FGInput.h
Executable file
|
@ -0,0 +1,107 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGInput.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 12/2/98
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
12/02/98 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGINPUT_H
|
||||||
|
#define FGINPUT_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGModel.h"
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
# include STL_IOSTREAM
|
||||||
|
# include STL_FSTREAM
|
||||||
|
#else
|
||||||
|
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
|
||||||
|
# include <iostream.h>
|
||||||
|
# include <fstream.h>
|
||||||
|
# else
|
||||||
|
# include <iostream>
|
||||||
|
# include <fstream>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <input_output/FGfdmSocket.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_INPUT "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Handles simulation input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGInput : public FGModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGInput(FGFDMExec*);
|
||||||
|
~FGInput();
|
||||||
|
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
void SetType(string);
|
||||||
|
inline void Enable(void) { enabled = true; }
|
||||||
|
inline void Disable(void) { enabled = false; }
|
||||||
|
inline bool Toggle(void) {enabled = !enabled; return enabled;}
|
||||||
|
bool Load(Element* el);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool sFirstPass, dFirstPass, enabled;
|
||||||
|
unsigned int port;
|
||||||
|
FGfdmSocket* socket;
|
||||||
|
string data;
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
||||||
|
|
694
src/FDM/JSBSim/models/FGLGear.cpp
Normal file
694
src/FDM/JSBSim/models/FGLGear.cpp
Normal file
|
@ -0,0 +1,694 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGLGear.cpp
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Norman H. Princen
|
||||||
|
Date started: 11/18/99
|
||||||
|
Purpose: Encapsulates the landing gear elements
|
||||||
|
Called by: FGAircraft
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
11/18/99 JSB Created
|
||||||
|
01/30/01 NHP Extended gear model to properly simulate steering and braking
|
||||||
|
|
||||||
|
/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGLGear.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
GLOBAL DATA
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_LGEAR;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) : Exec(fdmex),
|
||||||
|
GearNumber(number)
|
||||||
|
{
|
||||||
|
Element *force_table=0;
|
||||||
|
string force_type="";
|
||||||
|
|
||||||
|
kSpring = bDamp = bDampRebound = dynamicFCoeff = staticFCoeff = rollingFCoeff = maxSteerAngle = 0;
|
||||||
|
sSteerType = sBrakeGroup = sSteerType = "";
|
||||||
|
isRetractable = 0;
|
||||||
|
|
||||||
|
name = el->GetAttributeValue("name");
|
||||||
|
sContactType = el->GetAttributeValue("type");
|
||||||
|
if (el->FindElement("spring_coeff"))
|
||||||
|
kSpring = el->FindElementValueAsNumberConvertTo("spring_coeff", "LBS/FT");
|
||||||
|
if (el->FindElement("damping_coeff"))
|
||||||
|
bDamp = el->FindElementValueAsNumberConvertTo("damping_coeff", "LBS/FT/SEC");
|
||||||
|
|
||||||
|
if (el->FindElement("damping_coeff_rebound"))
|
||||||
|
bDampRebound = el->FindElementValueAsNumberConvertTo("damping_coeff_rebound", "LBS/FT/SEC");
|
||||||
|
else
|
||||||
|
bDampRebound = bDamp;
|
||||||
|
|
||||||
|
if (el->FindElement("dynamic_friction"))
|
||||||
|
dynamicFCoeff = el->FindElementValueAsNumber("dynamic_friction");
|
||||||
|
if (el->FindElement("static_friction"))
|
||||||
|
staticFCoeff = el->FindElementValueAsNumber("static_friction");
|
||||||
|
if (el->FindElement("rolling_friction"))
|
||||||
|
rollingFCoeff = el->FindElementValueAsNumber("rolling_friction");
|
||||||
|
if (el->FindElement("max_steer"))
|
||||||
|
maxSteerAngle = el->FindElementValueAsNumberConvertTo("max_steer", "DEG");
|
||||||
|
if (el->FindElement("retractable"))
|
||||||
|
isRetractable = (int)el->FindElementValueAsNumber("retractable");
|
||||||
|
|
||||||
|
ForceY_Table = 0;
|
||||||
|
force_table = el->FindElement("table");
|
||||||
|
while (force_table) {
|
||||||
|
force_type = force_table->GetAttributeValue("type");
|
||||||
|
if (force_type == "CORNERING_COEFF") {
|
||||||
|
ForceY_Table = new FGTable(Exec->GetPropertyManager(), force_table);
|
||||||
|
} else {
|
||||||
|
cerr << "Undefined force table for " << name << " contact point" << endl;
|
||||||
|
}
|
||||||
|
force_table = el->FindNextElement("table");
|
||||||
|
}
|
||||||
|
|
||||||
|
sBrakeGroup = el->FindElementValue("brake_group");
|
||||||
|
|
||||||
|
if (maxSteerAngle == 360) sSteerType = "CASTERED";
|
||||||
|
else if (maxSteerAngle == 0.0) sSteerType = "FIXED";
|
||||||
|
else sSteerType = "STEERABLE";
|
||||||
|
|
||||||
|
Element* element = el->FindElement("location");
|
||||||
|
if (element) vXYZ = element->FindElementTripletConvertTo("IN");
|
||||||
|
else {cerr << "No location given for contact " << name << endl; exit(-1);}
|
||||||
|
|
||||||
|
if (sBrakeGroup == "LEFT" ) eBrakeGrp = bgLeft;
|
||||||
|
else if (sBrakeGroup == "RIGHT" ) eBrakeGrp = bgRight;
|
||||||
|
else if (sBrakeGroup == "CENTER") eBrakeGrp = bgCenter;
|
||||||
|
else if (sBrakeGroup == "NOSE" ) eBrakeGrp = bgNose;
|
||||||
|
else if (sBrakeGroup == "TAIL" ) eBrakeGrp = bgTail;
|
||||||
|
else if (sBrakeGroup == "NONE" ) eBrakeGrp = bgNone;
|
||||||
|
else if (sBrakeGroup.empty() ) {eBrakeGrp = bgNone;
|
||||||
|
sBrakeGroup = "NONE (defaulted)";}
|
||||||
|
else {
|
||||||
|
cerr << "Improper braking group specification in config file: "
|
||||||
|
<< sBrakeGroup << " is undefined." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sSteerType == "STEERABLE") eSteerType = stSteer;
|
||||||
|
else if (sSteerType == "FIXED" ) eSteerType = stFixed;
|
||||||
|
else if (sSteerType == "CASTERED" ) eSteerType = stCaster;
|
||||||
|
else if (sSteerType.empty() ) {eSteerType = stFixed;
|
||||||
|
sSteerType = "FIXED (defaulted)";}
|
||||||
|
else {
|
||||||
|
cerr << "Improper steering type specification in config file: "
|
||||||
|
<< sSteerType << " is undefined." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
GearUp = false;
|
||||||
|
GearDown = true;
|
||||||
|
Servicable = true;
|
||||||
|
|
||||||
|
// Add some AI here to determine if gear is located properly according to its
|
||||||
|
// brake group type ??
|
||||||
|
|
||||||
|
State = Exec->GetState();
|
||||||
|
Aircraft = Exec->GetAircraft();
|
||||||
|
Propagate = Exec->GetPropagate();
|
||||||
|
Auxiliary = Exec->GetAuxiliary();
|
||||||
|
FCS = Exec->GetFCS();
|
||||||
|
MassBalance = Exec->GetMassBalance();
|
||||||
|
|
||||||
|
WOW = lastWOW = true; // should the value be initialized to true?
|
||||||
|
ReportEnable = true;
|
||||||
|
FirstContact = false;
|
||||||
|
StartedGroundRun = false;
|
||||||
|
TakeoffReported = LandingReported = false;
|
||||||
|
LandingDistanceTraveled = TakeoffDistanceTraveled = TakeoffDistanceTraveled50ft = 0.0;
|
||||||
|
MaximumStrutForce = MaximumStrutTravel = 0.0;
|
||||||
|
SideForce = RollingForce = 0.0;
|
||||||
|
SinkRate = GroundSpeed = 0.0;
|
||||||
|
|
||||||
|
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
|
||||||
|
|
||||||
|
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec;
|
||||||
|
|
||||||
|
compressLength = 0.0;
|
||||||
|
compressSpeed = 0.0;
|
||||||
|
brakePct = 0.0;
|
||||||
|
maxCompLen = 0.0;
|
||||||
|
|
||||||
|
WheelSlip = last_WheelSlip = 0.0;
|
||||||
|
TirePressureNorm = 1.0;
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGLGear::FGLGear(const FGLGear& lgear)
|
||||||
|
{
|
||||||
|
GearNumber = lgear.GearNumber;
|
||||||
|
State = lgear.State;
|
||||||
|
Aircraft = lgear.Aircraft;
|
||||||
|
Propagate = lgear.Propagate;
|
||||||
|
Auxiliary = lgear.Auxiliary;
|
||||||
|
Exec = lgear.Exec;
|
||||||
|
FCS = lgear.FCS;
|
||||||
|
MassBalance = lgear.MassBalance;
|
||||||
|
|
||||||
|
vXYZ = lgear.vXYZ;
|
||||||
|
vMoment = lgear.vMoment;
|
||||||
|
vWhlBodyVec = lgear.vWhlBodyVec;
|
||||||
|
vLocalGear = lgear.vLocalGear;
|
||||||
|
|
||||||
|
WOW = lgear.WOW;
|
||||||
|
lastWOW = lgear.lastWOW;
|
||||||
|
ReportEnable = lgear.ReportEnable;
|
||||||
|
FirstContact = lgear.FirstContact;
|
||||||
|
StartedGroundRun = lgear.StartedGroundRun;
|
||||||
|
LandingDistanceTraveled = lgear.LandingDistanceTraveled;
|
||||||
|
TakeoffDistanceTraveled = lgear.TakeoffDistanceTraveled;
|
||||||
|
TakeoffDistanceTraveled50ft = lgear.TakeoffDistanceTraveled50ft;
|
||||||
|
MaximumStrutForce = lgear.MaximumStrutForce;
|
||||||
|
MaximumStrutTravel = lgear.MaximumStrutTravel;
|
||||||
|
SideForce = lgear.SideForce;
|
||||||
|
RollingForce = lgear.RollingForce;
|
||||||
|
|
||||||
|
kSpring = lgear.kSpring;
|
||||||
|
bDamp = lgear.bDamp;
|
||||||
|
bDampRebound = lgear.bDampRebound;
|
||||||
|
compressLength = lgear.compressLength;
|
||||||
|
compressSpeed = lgear.compressSpeed;
|
||||||
|
staticFCoeff = lgear.staticFCoeff;
|
||||||
|
dynamicFCoeff = lgear.dynamicFCoeff;
|
||||||
|
rollingFCoeff = lgear.rollingFCoeff;
|
||||||
|
brakePct = lgear.brakePct;
|
||||||
|
maxCompLen = lgear.maxCompLen;
|
||||||
|
SinkRate = lgear.SinkRate;
|
||||||
|
GroundSpeed = lgear.GroundSpeed;
|
||||||
|
LandingReported = lgear.LandingReported;
|
||||||
|
TakeoffReported = lgear.TakeoffReported;
|
||||||
|
name = lgear.name;
|
||||||
|
sSteerType = lgear.sSteerType;
|
||||||
|
sRetractable = lgear.sRetractable;
|
||||||
|
sContactType = lgear.sContactType;
|
||||||
|
sBrakeGroup = lgear.sBrakeGroup;
|
||||||
|
eSteerType = lgear.eSteerType;
|
||||||
|
eBrakeGrp = lgear.eBrakeGrp;
|
||||||
|
maxSteerAngle = lgear.maxSteerAngle;
|
||||||
|
isRetractable = lgear.isRetractable;
|
||||||
|
GearUp = lgear.GearUp;
|
||||||
|
GearDown = lgear.GearDown;
|
||||||
|
WheelSlip = lgear.WheelSlip;
|
||||||
|
TirePressureNorm = lgear.TirePressureNorm;
|
||||||
|
Servicable = lgear.Servicable;
|
||||||
|
ForceY_Table = lgear.ForceY_Table;
|
||||||
|
CosWheel = lgear.CosWheel;
|
||||||
|
SinWheel = lgear.SinWheel;
|
||||||
|
In = lgear.In;
|
||||||
|
prevIn = lgear.prevIn;
|
||||||
|
prevOut = lgear.prevOut;
|
||||||
|
slipIn = lgear.slipIn;
|
||||||
|
last_SlipIn = lgear.last_SlipIn;
|
||||||
|
last_WheelSlip = lgear.last_WheelSlip;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGLGear::~FGLGear()
|
||||||
|
{
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGColumnVector3& FGLGear::Force(void)
|
||||||
|
{
|
||||||
|
FGColumnVector3 normal, cvel;
|
||||||
|
FGLocation contact, gearLoc;
|
||||||
|
double t = Exec->GetState()->Getsim_time();
|
||||||
|
|
||||||
|
vForce.InitMatrix();
|
||||||
|
vMoment.InitMatrix();
|
||||||
|
|
||||||
|
if (isRetractable) ComputeRetractionState();
|
||||||
|
|
||||||
|
if (GearUp) return vForce;
|
||||||
|
|
||||||
|
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ); // Get wheel in body frame
|
||||||
|
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location
|
||||||
|
|
||||||
|
gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
|
||||||
|
compressLength = -Exec->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
|
||||||
|
|
||||||
|
// The compression length is measured in the Z-axis, only, at this time.
|
||||||
|
|
||||||
|
if (compressLength > 0.00) {
|
||||||
|
|
||||||
|
WOW = true;
|
||||||
|
|
||||||
|
// [The next equation should really use the vector to the contact patch of
|
||||||
|
// the tire including the strut compression and not the original vWhlBodyVec.]
|
||||||
|
|
||||||
|
vWhlVelVec = Propagate->GetTb2l() * (Propagate->GetPQR() * vWhlBodyVec);
|
||||||
|
vWhlVelVec += Propagate->GetVel() - cvel;
|
||||||
|
compressSpeed = vWhlVelVec(eZ);
|
||||||
|
|
||||||
|
InitializeReporting();
|
||||||
|
ComputeBrakeForceCoefficient();
|
||||||
|
ComputeSteeringAngle();
|
||||||
|
ComputeSlipAngle();
|
||||||
|
ComputeSideForceCoefficient();
|
||||||
|
ComputeVerticalStrutForce();
|
||||||
|
|
||||||
|
// Compute the forces in the wheel ground plane.
|
||||||
|
|
||||||
|
RollingForce = (1.0 - TirePressureNorm) * 30
|
||||||
|
+ vLocalForce(eZ) * BrakeFCoeff * (RollingWhlVel>=0?1.0:-1.0);
|
||||||
|
SideForce = vLocalForce(eZ) * FCoeff;
|
||||||
|
|
||||||
|
// Transform these forces back to the local reference frame.
|
||||||
|
|
||||||
|
vLocalForce(eX) = RollingForce*CosWheel - SideForce*SinWheel;
|
||||||
|
vLocalForce(eY) = SideForce*CosWheel + RollingForce*SinWheel;
|
||||||
|
|
||||||
|
// Transform the forces back to the body frame and compute the moment.
|
||||||
|
|
||||||
|
vForce = Propagate->GetTl2b() * vLocalForce;
|
||||||
|
|
||||||
|
// Lag and attenuate the XY-plane forces dependent on velocity
|
||||||
|
|
||||||
|
double RFRV = 0.015; // Rolling force relaxation velocity
|
||||||
|
double SFRV = 0.25; // Side force relaxation velocity
|
||||||
|
double dT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
|
||||||
|
|
||||||
|
In = vForce;
|
||||||
|
vForce(eX) = (0.25)*(In(eX) + prevIn(eX)) + (0.50)*prevOut(eX);
|
||||||
|
vForce(eY) = (0.15)*(In(eY) + prevIn(eY)) + (0.70)*prevOut(eY);
|
||||||
|
prevOut = vForce;
|
||||||
|
prevIn = In;
|
||||||
|
|
||||||
|
if (fabs(RollingWhlVel) <= RFRV) vForce(eX) *= fabs(RollingWhlVel)/RFRV;
|
||||||
|
if (fabs(SideWhlVel) <= SFRV) vForce(eY) *= fabs(SideWhlVel)/SFRV;
|
||||||
|
|
||||||
|
vMoment = vWhlBodyVec * vForce;
|
||||||
|
|
||||||
|
} else { // Gear is NOT compressed
|
||||||
|
|
||||||
|
WOW = false;
|
||||||
|
compressLength = 0.0;
|
||||||
|
|
||||||
|
// Return to neutral position between 1.0 and 0.8 gear pos.
|
||||||
|
SteerAngle *= max(FCS->GetGearPos()-0.8, 0.0)/0.2;
|
||||||
|
|
||||||
|
ResetReporting();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReportTakeoffOrLanding();
|
||||||
|
CrashDetect();
|
||||||
|
|
||||||
|
return vForce;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLGear::ComputeRetractionState(void)
|
||||||
|
{
|
||||||
|
if (FCS->GetGearPos() < 0.01) {
|
||||||
|
GearUp = true;
|
||||||
|
GearDown = false;
|
||||||
|
} else if (FCS->GetGearPos() > 0.99) {
|
||||||
|
GearDown = true;
|
||||||
|
GearUp = false;
|
||||||
|
} else {
|
||||||
|
GearUp = false;
|
||||||
|
GearDown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLGear::ComputeSlipAngle(void)
|
||||||
|
{
|
||||||
|
double dT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
|
||||||
|
|
||||||
|
// Transform the wheel velocities from the local axis system to the wheel axis system.
|
||||||
|
|
||||||
|
RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
|
||||||
|
SideWhlVel = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
|
||||||
|
|
||||||
|
// Calculate tire slip angle.
|
||||||
|
|
||||||
|
if (fabs(RollingWhlVel) < 0.1 && fabs(SideWhlVel) < 0.01) {
|
||||||
|
WheelSlip = -SteerAngle*radtodeg;
|
||||||
|
} else {
|
||||||
|
WheelSlip = atan2(SideWhlVel, fabs(RollingWhlVel))*radtodeg;
|
||||||
|
}
|
||||||
|
slipIn = WheelSlip;
|
||||||
|
WheelSlip = (0.46)*(slipIn + last_SlipIn) + (0.08)*last_WheelSlip;
|
||||||
|
last_WheelSlip = WheelSlip;
|
||||||
|
last_SlipIn = slipIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Compute the steering angle in any case.
|
||||||
|
// This will also make sure that animations will look right.
|
||||||
|
|
||||||
|
void FGLGear::ComputeSteeringAngle(void)
|
||||||
|
{
|
||||||
|
switch (eSteerType) {
|
||||||
|
case stSteer:
|
||||||
|
SteerAngle = degtorad * FCS->GetSteerPosDeg(GearNumber);
|
||||||
|
break;
|
||||||
|
case stFixed:
|
||||||
|
SteerAngle = 0.0;
|
||||||
|
break;
|
||||||
|
case stCaster:
|
||||||
|
// This is not correct for castering gear. Should make steer angle parallel
|
||||||
|
// to the actual velocity vector of the wheel, given aircraft velocity vector
|
||||||
|
// and omega.
|
||||||
|
SteerAngle = 0.0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cerr << "Improper steering type membership detected for this gear." << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SinWheel = sin(Propagate->GetEuler(ePsi) + SteerAngle);
|
||||||
|
CosWheel = cos(Propagate->GetEuler(ePsi) + SteerAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Reset reporting functionality after takeoff
|
||||||
|
|
||||||
|
void FGLGear::ResetReporting(void)
|
||||||
|
{
|
||||||
|
if (Propagate->GetDistanceAGL() > 200.0) {
|
||||||
|
FirstContact = false;
|
||||||
|
StartedGroundRun = false;
|
||||||
|
LandingReported = false;
|
||||||
|
LandingDistanceTraveled = 0.0;
|
||||||
|
MaximumStrutForce = MaximumStrutTravel = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLGear::InitializeReporting(void)
|
||||||
|
{
|
||||||
|
// If this is the first time the wheel has made contact, remember some values
|
||||||
|
// for later printout.
|
||||||
|
|
||||||
|
if (!FirstContact) {
|
||||||
|
FirstContact = true;
|
||||||
|
SinkRate = compressSpeed;
|
||||||
|
GroundSpeed = Propagate->GetVel().Magnitude();
|
||||||
|
TakeoffReported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the takeoff run is starting, initialize.
|
||||||
|
|
||||||
|
if ((Propagate->GetVel().Magnitude() > 0.1) &&
|
||||||
|
(FCS->GetBrake(bgLeft) == 0) &&
|
||||||
|
(FCS->GetBrake(bgRight) == 0) &&
|
||||||
|
(FCS->GetThrottlePos(0) == 1) && !StartedGroundRun)
|
||||||
|
{
|
||||||
|
TakeoffDistanceTraveled = 0;
|
||||||
|
TakeoffDistanceTraveled50ft = 0;
|
||||||
|
StartedGroundRun = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Takeoff and landing reporting functionality
|
||||||
|
|
||||||
|
void FGLGear::ReportTakeoffOrLanding(void)
|
||||||
|
{
|
||||||
|
double deltaT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
|
||||||
|
|
||||||
|
if (FirstContact) LandingDistanceTraveled += Auxiliary->GetVground()*deltaT;
|
||||||
|
|
||||||
|
if (StartedGroundRun) {
|
||||||
|
TakeoffDistanceTraveled50ft += Auxiliary->GetVground()*deltaT;
|
||||||
|
if (WOW) TakeoffDistanceTraveled += Auxiliary->GetVground()*deltaT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReportEnable && Auxiliary->GetVground() <= 0.05 && !LandingReported) {
|
||||||
|
if (debug_lvl > 0) Report(erLand);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReportEnable && !TakeoffReported &&
|
||||||
|
(vLocalGear(eZ) - Propagate->GetDistanceAGL()) < -50.0)
|
||||||
|
{
|
||||||
|
if (debug_lvl > 0) Report(erTakeoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastWOW != WOW) PutMessage("GEAR_CONTACT: " + name, WOW);
|
||||||
|
lastWOW = WOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Crash detection logic (really out-of-bounds detection)
|
||||||
|
|
||||||
|
void FGLGear::CrashDetect(void)
|
||||||
|
{
|
||||||
|
if (compressLength > 500.0 ||
|
||||||
|
vForce.Magnitude() > 100000000.0 ||
|
||||||
|
vMoment.Magnitude() > 5000000000.0 ||
|
||||||
|
SinkRate > 1.4666*30)
|
||||||
|
{
|
||||||
|
PutMessage("Crash Detected: Simulation FREEZE.");
|
||||||
|
State->SuspendIntegration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The following needs work regarding friction coefficients and braking and
|
||||||
|
// steering The BrakeFCoeff formula assumes that an anti-skid system is used.
|
||||||
|
// It also assumes that we won't be turning and braking at the same time.
|
||||||
|
// Will fix this later.
|
||||||
|
// [JSB] The braking force coefficients include normal rolling coefficient +
|
||||||
|
// a percentage of the static friction coefficient based on braking applied.
|
||||||
|
|
||||||
|
void FGLGear::ComputeBrakeForceCoefficient(void)
|
||||||
|
{
|
||||||
|
switch (eBrakeGrp) {
|
||||||
|
case bgLeft:
|
||||||
|
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
|
||||||
|
staticFCoeff*FCS->GetBrake(bgLeft) );
|
||||||
|
break;
|
||||||
|
case bgRight:
|
||||||
|
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
|
||||||
|
staticFCoeff*FCS->GetBrake(bgRight) );
|
||||||
|
break;
|
||||||
|
case bgCenter:
|
||||||
|
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
|
||||||
|
staticFCoeff*FCS->GetBrake(bgCenter) );
|
||||||
|
break;
|
||||||
|
case bgNose:
|
||||||
|
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
|
||||||
|
staticFCoeff*FCS->GetBrake(bgCenter) );
|
||||||
|
break;
|
||||||
|
case bgTail:
|
||||||
|
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
|
||||||
|
staticFCoeff*FCS->GetBrake(bgCenter) );
|
||||||
|
break;
|
||||||
|
case bgNone:
|
||||||
|
BrakeFCoeff = rollingFCoeff;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cerr << "Improper brake group membership detected for this gear." << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Compute the sideforce coefficients using similar assumptions to LaRCSim for now.
|
||||||
|
// Allow a maximum of 10 degrees tire slip angle before wheel slides. At that point,
|
||||||
|
// transition from static to dynamic friction. There are more complicated formulations
|
||||||
|
// of this that avoid the discrete jump (similar to Pacejka). Will fix this later.
|
||||||
|
|
||||||
|
void FGLGear::ComputeSideForceCoefficient(void)
|
||||||
|
{
|
||||||
|
if (ForceY_Table) {
|
||||||
|
|
||||||
|
FCoeff = ForceY_Table->GetValue(WheelSlip);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (fabs(WheelSlip) <= 10.0) {
|
||||||
|
FCoeff = staticFCoeff*WheelSlip/10.0;
|
||||||
|
} else if (fabs(WheelSlip) <= 40.0) {
|
||||||
|
FCoeff = (dynamicFCoeff*(fabs(WheelSlip) - 10.0)/10.0
|
||||||
|
+ staticFCoeff*(40.0 - fabs(WheelSlip))/10.0)*(WheelSlip>=0?1.0:-1.0);
|
||||||
|
} else {
|
||||||
|
FCoeff = dynamicFCoeff*(WheelSlip>=0?1.0:-1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// Compute the vertical force on the wheel using square-law damping (per comment
|
||||||
|
// in paper AIAA-2000-4303 - see header prologue comments). We might consider
|
||||||
|
// allowing for both square and linear damping force calculation. Also need to
|
||||||
|
// possibly give a "rebound damping factor" that differs from the compression
|
||||||
|
// case.
|
||||||
|
|
||||||
|
void FGLGear::ComputeVerticalStrutForce(void)
|
||||||
|
{
|
||||||
|
double springForce = 0;
|
||||||
|
double dampForce = 0;
|
||||||
|
|
||||||
|
springForce = -compressLength * kSpring;
|
||||||
|
|
||||||
|
if (compressSpeed >= 0.0) {
|
||||||
|
dampForce = -compressSpeed * bDamp;
|
||||||
|
} else {
|
||||||
|
dampForce = -compressSpeed * bDampRebound;
|
||||||
|
}
|
||||||
|
vLocalForce(eZ) = min(springForce + dampForce, (double)0.0);
|
||||||
|
|
||||||
|
// Remember these values for reporting
|
||||||
|
MaximumStrutForce = max(MaximumStrutForce, fabs(vLocalForce(eZ)));
|
||||||
|
MaximumStrutTravel = max(MaximumStrutTravel, fabs(compressLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLGear::bind(void)
|
||||||
|
{
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "gear/unit[%d]/slip-angle-deg", GearNumber);
|
||||||
|
Exec->GetPropertyManager()->Tie( property_name, &WheelSlip );
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLGear::unbind(void)
|
||||||
|
{
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "gear/unit[%d]/slip-angle-deg", GearNumber);
|
||||||
|
Exec->GetPropertyManager()->Untie( property_name );
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLGear::Report(ReportType repType)
|
||||||
|
{
|
||||||
|
switch(repType) {
|
||||||
|
case erLand:
|
||||||
|
cout << endl << "Touchdown report for " << name << endl;
|
||||||
|
cout << " Sink rate at contact: " << SinkRate << " fps, "
|
||||||
|
<< SinkRate*0.3048 << " mps" << endl;
|
||||||
|
cout << " Contact ground speed: " << GroundSpeed*.5925 << " knots, "
|
||||||
|
<< GroundSpeed*0.3048 << " mps" << endl;
|
||||||
|
cout << " Maximum contact force: " << MaximumStrutForce << " lbs, "
|
||||||
|
<< MaximumStrutForce*4.448 << " Newtons" << endl;
|
||||||
|
cout << " Maximum strut travel: " << MaximumStrutTravel*12.0 << " inches, "
|
||||||
|
<< MaximumStrutTravel*30.48 << " cm" << endl;
|
||||||
|
cout << " Distance traveled: " << LandingDistanceTraveled << " ft, "
|
||||||
|
<< LandingDistanceTraveled*0.3048 << " meters" << endl;
|
||||||
|
LandingReported = true;
|
||||||
|
break;
|
||||||
|
case erTakeoff:
|
||||||
|
cout << endl << "Takeoff report for " << name << endl;
|
||||||
|
cout << " Distance traveled: " << TakeoffDistanceTraveled
|
||||||
|
<< " ft, " << TakeoffDistanceTraveled*0.3048 << " meters" << endl;
|
||||||
|
cout << " Distance traveled (over 50'): " << TakeoffDistanceTraveled50ft
|
||||||
|
<< " ft, " << TakeoffDistanceTraveled50ft*0.3048 << " meters" << endl;
|
||||||
|
TakeoffReported = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGLGear::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor - loading and initialization
|
||||||
|
cout << " " << sContactType << " " << name << endl;
|
||||||
|
cout << " Location: " << vXYZ << endl;
|
||||||
|
cout << " Spring Constant: " << kSpring << endl;
|
||||||
|
cout << " Damping Constant: " << bDamp << endl;
|
||||||
|
cout << " Dynamic Friction: " << dynamicFCoeff << endl;
|
||||||
|
cout << " Static Friction: " << staticFCoeff << endl;
|
||||||
|
if (sContactType == "BOGEY") {
|
||||||
|
cout << " Rolling Friction: " << rollingFCoeff << endl;
|
||||||
|
cout << " Steering Type: " << sSteerType << endl;
|
||||||
|
cout << " Grouping: " << sBrakeGroup << endl;
|
||||||
|
cout << " Max Steer Angle: " << maxSteerAngle << endl;
|
||||||
|
cout << " Retractable: " << isRetractable << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGLGear" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGLGear" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
347
src/FDM/JSBSim/models/FGLGear.h
Normal file
347
src/FDM/JSBSim/models/FGLGear.h
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGLGear.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 11/18/99
|
||||||
|
|
||||||
|
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
11/18/99 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGLGEAR_H
|
||||||
|
#define FGLGEAR_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifdef FGFS
|
||||||
|
# include <simgear/compiler.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <FGJSBBase.h>
|
||||||
|
#include <FGFDMExec.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
|
#include <math/FGTable.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_LGEAR "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
class FGAircraft;
|
||||||
|
class FGPropagate;
|
||||||
|
class FGFCS;
|
||||||
|
class FGState;
|
||||||
|
class FGMassBalance;
|
||||||
|
class FGAuxiliary;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Landing gear model.
|
||||||
|
Calculates forces and moments due to landing gear reactions. This is done in
|
||||||
|
several steps, and is dependent on what kind of gear is being modeled. Here
|
||||||
|
are the parameters that can be specified in the config file for modeling
|
||||||
|
landing gear:
|
||||||
|
<p>
|
||||||
|
<b><u>Physical Characteristics</u></b><br>
|
||||||
|
<ol>
|
||||||
|
<li>X, Y, Z location, in inches in structural coordinate frame</li>
|
||||||
|
<li>Spring constant, in lbs/ft</li>
|
||||||
|
<li>Damping coefficient, in lbs/ft/sec</li>
|
||||||
|
<li>Dynamic Friction Coefficient</li>
|
||||||
|
<li>Static Friction Coefficient</li>
|
||||||
|
</ol></p><p>
|
||||||
|
<b><u>Operational Properties</b></u><br>
|
||||||
|
<ol>
|
||||||
|
<li>Name</li>
|
||||||
|
<li>Steerability attribute {one of STEERABLE | FIXED | CASTERED}</li>
|
||||||
|
<li>Brake Group Membership {one of LEFT | CENTER | RIGHT | NOSE | TAIL | NONE}</li>
|
||||||
|
<li>Max Steer Angle, in degrees</li>
|
||||||
|
</ol></p>
|
||||||
|
<p>
|
||||||
|
<b><u>Algorithm and Approach to Modeling</u></b><br>
|
||||||
|
<ol>
|
||||||
|
<li>Find the location of the uncompressed landing gear relative to the CG of
|
||||||
|
the aircraft. Remember, the structural coordinate frame that the aircraft is
|
||||||
|
defined in is: X positive towards the tail, Y positive out the right side, Z
|
||||||
|
positive upwards. The locations of the various parts are given in inches in
|
||||||
|
the config file.</li>
|
||||||
|
<li>The vector giving the location of the gear (relative to the cg) is
|
||||||
|
rotated 180 degrees about the Y axis to put the coordinates in body frame (X
|
||||||
|
positive forwards, Y positive out the right side, Z positive downwards, with
|
||||||
|
the origin at the cg). The lengths are also now given in feet.</li>
|
||||||
|
<li>The new gear location is now transformed to the local coordinate frame
|
||||||
|
using the body-to-local matrix. (Mb2l).</li>
|
||||||
|
<li>Knowing the location of the center of gravity relative to the ground
|
||||||
|
(height above ground level or AGL) now enables gear deflection to be
|
||||||
|
calculated. The gear compression value is the local frame gear Z location
|
||||||
|
value minus the height AGL. [Currently, we make the assumption that the gear
|
||||||
|
is oriented - and the deflection occurs in - the Z axis only. Additionally,
|
||||||
|
the vector to the landing gear is currently not modified - which would
|
||||||
|
(correctly) move the point of contact to the actual compressed-gear point of
|
||||||
|
contact. Eventually, articulated gear may be modeled, but initially an
|
||||||
|
effort must be made to model a generic system.] As an example, say the
|
||||||
|
aircraft left main gear location (in local coordinates) is Z = 3 feet
|
||||||
|
(positive) and the height AGL is 2 feet. This tells us that the gear is
|
||||||
|
compressed 1 foot.</li>
|
||||||
|
<li>If the gear is compressed, a Weight-On-Wheels (WOW) flag is set.</li>
|
||||||
|
<li>With the compression length calculated, the compression velocity may now
|
||||||
|
be calculated. This will be used to determine the damping force in the
|
||||||
|
strut. The aircraft rotational rate is multiplied by the vector to the wheel
|
||||||
|
to get a wheel velocity in body frame. That velocity vector is then
|
||||||
|
transformed into the local coordinate frame.</li>
|
||||||
|
<li>The aircraft cg velocity in the local frame is added to the
|
||||||
|
just-calculated wheel velocity (due to rotation) to get a total wheel
|
||||||
|
velocity in the local frame.</li>
|
||||||
|
<li>The compression speed is the Z-component of the vector.</li>
|
||||||
|
<li>With the wheel velocity vector no longer needed, it is normalized and
|
||||||
|
multiplied by a -1 to reverse it. This will be used in the friction force
|
||||||
|
calculation.</li>
|
||||||
|
<li>Since the friction force takes place solely in the runway plane, the Z
|
||||||
|
coordinate of the normalized wheel velocity vector is set to zero.</li>
|
||||||
|
<li>The gear deflection force (the force on the aircraft acting along the
|
||||||
|
local frame Z axis) is now calculated given the spring and damper
|
||||||
|
coefficients, and the gear deflection speed and stroke length. Keep in mind
|
||||||
|
that gear forces always act in the negative direction (in both local and
|
||||||
|
body frames), and are not capable of generating a force in the positive
|
||||||
|
sense (one that would attract the aircraft to the ground). So, the gear
|
||||||
|
forces are always negative - they are limited to values of zero or less. The
|
||||||
|
gear force is simply the negative of the sum of the spring compression
|
||||||
|
length times the spring coefficient and the gear velocity times the damping
|
||||||
|
coefficient.</li>
|
||||||
|
<li>The lateral/directional force acting on the aircraft through the landing
|
||||||
|
|
||||||
|
gear (along the local frame X and Y axes) is calculated next. First, the
|
||||||
|
friction coefficient is multiplied by the recently calculated Z-force. This
|
||||||
|
is the friction force. It must be given direction in addition to magnitude.
|
||||||
|
We want the components in the local frame X and Y axes. From step 9, above,
|
||||||
|
the conditioned wheel velocity vector is taken and the X and Y parts are
|
||||||
|
multiplied by the friction force to get the X and Y components of friction.
|
||||||
|
</li>
|
||||||
|
<li>The wheel force in local frame is next converted to body frame.</li>
|
||||||
|
<li>The moment due to the gear force is calculated by multiplying r x F
|
||||||
|
(radius to wheel crossed into the wheel force). Both of these operands are
|
||||||
|
in body frame.</li>
|
||||||
|
</ol>
|
||||||
|
@author Jon S. Berndt
|
||||||
|
@version $Id$
|
||||||
|
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
|
||||||
|
NASA-Ames", NASA CR-2497, January 1975
|
||||||
|
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
|
||||||
|
Wiley & Sons, 1979 ISBN 0-471-03032-5
|
||||||
|
@see W. A. Ragsdale, "A Generic Landing Gear Dynamics Model for LASRS++",
|
||||||
|
AIAA-2000-4303
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGLGear : public FGJSBBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Brake grouping enumerators
|
||||||
|
enum BrakeGroup {bgNone=0, bgLeft, bgRight, bgCenter, bgNose, bgTail };
|
||||||
|
/// Steering group membership enumerators
|
||||||
|
enum SteerType {stSteer, stFixed, stCaster};
|
||||||
|
/// Report type enumerators
|
||||||
|
enum ReportType {erNone=0, erTakeoff, erLand};
|
||||||
|
/** Constructor
|
||||||
|
@param el a pointer to the XML element that contains the CONTACT info.
|
||||||
|
@param Executive a pointer to the parent executive object
|
||||||
|
@param File a pointer to the config file instance */
|
||||||
|
FGLGear(Element* el, FGFDMExec* Executive, int number);
|
||||||
|
/** Constructor
|
||||||
|
@param lgear a reference to an existing FGLGear object */
|
||||||
|
FGLGear(const FGLGear& lgear);
|
||||||
|
/// Destructor
|
||||||
|
~FGLGear();
|
||||||
|
|
||||||
|
|
||||||
|
/// The Force vector for this gear
|
||||||
|
FGColumnVector3& Force(void);
|
||||||
|
/// The Moment vector for this gear
|
||||||
|
FGColumnVector3& Moment(void) {return vMoment;}
|
||||||
|
|
||||||
|
/// Gets the location of the gear in Body axes
|
||||||
|
FGColumnVector3& GetBodyLocation(void) { return vWhlBodyVec; }
|
||||||
|
double GetBodyLocation(int idx) { return vWhlBodyVec(idx); }
|
||||||
|
|
||||||
|
FGColumnVector3& GetLocalGear(void) { return vLocalGear; }
|
||||||
|
double GetLocalGear(int idx) { return vLocalGear(idx); }
|
||||||
|
|
||||||
|
/// Gets the name of the gear
|
||||||
|
inline string GetName(void) {return name; }
|
||||||
|
/// Gets the Weight On Wheels flag value
|
||||||
|
inline bool GetWOW(void) {return WOW; }
|
||||||
|
/// Gets the current compressed length of the gear in feet
|
||||||
|
inline double GetCompLen(void) {return compressLength;}
|
||||||
|
/// Gets the current gear compression velocity in ft/sec
|
||||||
|
inline double GetCompVel(void) {return compressSpeed; }
|
||||||
|
/// Gets the gear compression force in pounds
|
||||||
|
inline double GetCompForce(void) {return Force()(3); }
|
||||||
|
inline double GetBrakeFCoeff(void) {return BrakeFCoeff;}
|
||||||
|
|
||||||
|
/// Gets the current normalized tire pressure
|
||||||
|
inline double GetTirePressure(void) { return TirePressureNorm; }
|
||||||
|
/// Sets the new normalized tire pressure
|
||||||
|
inline void SetTirePressure(double p) { TirePressureNorm = p; }
|
||||||
|
|
||||||
|
/// Sets the brake value in percent (0 - 100)
|
||||||
|
inline void SetBrake(double bp) {brakePct = bp;}
|
||||||
|
|
||||||
|
/** Set the console touchdown reporting feature
|
||||||
|
@param flag true turns on touchdown reporting, false turns it off */
|
||||||
|
inline void SetReport(bool flag) { ReportEnable = flag; }
|
||||||
|
/** Get the console touchdown reporting feature
|
||||||
|
@return true if reporting is turned on */
|
||||||
|
inline bool GetReport(void) { return ReportEnable; }
|
||||||
|
double GetSteerNorm(void) const { return radtodeg/maxSteerAngle*SteerAngle; }
|
||||||
|
double GetDefaultSteerAngle(double cmd) const { return cmd*maxSteerAngle; }
|
||||||
|
double GetstaticFCoeff(void) { return staticFCoeff; }
|
||||||
|
|
||||||
|
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
|
||||||
|
inline int GetSteerType(void) { return (int)eSteerType; }
|
||||||
|
|
||||||
|
bool GetSteerable(void) const { return eSteerType != stFixed; }
|
||||||
|
inline bool GetRetractable(void) { return isRetractable; }
|
||||||
|
inline bool GetGearUnitUp(void) { return GearUp; }
|
||||||
|
inline bool GetGearUnitDown(void) { return GearDown; }
|
||||||
|
inline double GetWheelSideForce(void) { return SideForce; }
|
||||||
|
inline double GetWheelRollForce(void) { return RollingForce; }
|
||||||
|
inline double GetBodyXForce(void) { return vLocalForce(eX); }
|
||||||
|
inline double GetBodyYForce(void) { return vLocalForce(eY); }
|
||||||
|
inline double GetWheelSlipAngle(void) { return WheelSlip; }
|
||||||
|
double GetWheelVel(int axis) { return vWhlVelVec(axis);}
|
||||||
|
|
||||||
|
bool IsBogey(void) {return (sContactType == string("BOGEY"));}
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int GearNumber;
|
||||||
|
FGColumnVector3 vXYZ;
|
||||||
|
FGColumnVector3 vMoment;
|
||||||
|
FGColumnVector3 vWhlBodyVec;
|
||||||
|
FGColumnVector3 vLocalGear;
|
||||||
|
FGColumnVector3 vForce;
|
||||||
|
FGColumnVector3 last_vForce; // remove this
|
||||||
|
FGColumnVector3 vLocalForce;
|
||||||
|
FGColumnVector3 vWhlVelVec; // Velocity of this wheel (Local)
|
||||||
|
FGColumnVector3 In;
|
||||||
|
FGColumnVector3 prevIn;
|
||||||
|
FGColumnVector3 prevOut;
|
||||||
|
FGTable *ForceY_Table;
|
||||||
|
double SteerAngle;
|
||||||
|
double kSpring;
|
||||||
|
double bDamp;
|
||||||
|
double bDampRebound;
|
||||||
|
double compressLength;
|
||||||
|
double compressSpeed;
|
||||||
|
double staticFCoeff, dynamicFCoeff, rollingFCoeff;
|
||||||
|
double brakePct;
|
||||||
|
double BrakeFCoeff;
|
||||||
|
double maxCompLen;
|
||||||
|
double SinkRate;
|
||||||
|
double GroundSpeed;
|
||||||
|
double TakeoffDistanceTraveled;
|
||||||
|
double TakeoffDistanceTraveled50ft;
|
||||||
|
double LandingDistanceTraveled;
|
||||||
|
double MaximumStrutForce;
|
||||||
|
double MaximumStrutTravel;
|
||||||
|
double SideWhlVel, RollingWhlVel;
|
||||||
|
double RollingForce, SideForce, FCoeff;
|
||||||
|
double WheelSlip;
|
||||||
|
double last_WheelSlip;
|
||||||
|
double slipIn;
|
||||||
|
double last_SlipIn;
|
||||||
|
double TirePressureNorm;
|
||||||
|
double SinWheel, CosWheel;
|
||||||
|
bool WOW;
|
||||||
|
bool lastWOW;
|
||||||
|
bool FirstContact;
|
||||||
|
bool StartedGroundRun;
|
||||||
|
bool LandingReported;
|
||||||
|
bool TakeoffReported;
|
||||||
|
bool ReportEnable;
|
||||||
|
bool isRetractable;
|
||||||
|
bool GearUp, GearDown;
|
||||||
|
bool Servicable;
|
||||||
|
string name;
|
||||||
|
string sSteerType;
|
||||||
|
string sBrakeGroup;
|
||||||
|
string sRetractable;
|
||||||
|
string sContactType;
|
||||||
|
|
||||||
|
BrakeGroup eBrakeGrp;
|
||||||
|
SteerType eSteerType;
|
||||||
|
double maxSteerAngle;
|
||||||
|
|
||||||
|
FGFDMExec* Exec;
|
||||||
|
FGState* State;
|
||||||
|
FGAircraft* Aircraft;
|
||||||
|
FGPropagate* Propagate;
|
||||||
|
FGAuxiliary* Auxiliary;
|
||||||
|
FGFCS* FCS;
|
||||||
|
FGMassBalance* MassBalance;
|
||||||
|
|
||||||
|
void ComputeRetractionState(void);
|
||||||
|
void ComputeBrakeForceCoefficient(void);
|
||||||
|
void ComputeSteeringAngle(void);
|
||||||
|
void ComputeSlipAngle(void);
|
||||||
|
void ComputeSideForceCoefficient(void);
|
||||||
|
void ComputeVerticalStrutForce(void);
|
||||||
|
void CrashDetect(void);
|
||||||
|
void InitializeReporting(void);
|
||||||
|
void ResetReporting(void);
|
||||||
|
void ReportTakeoffOrLanding(void);
|
||||||
|
void Report(ReportType rt);
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#include "FGAircraft.h"
|
||||||
|
#include "FGPropagate.h"
|
||||||
|
#include "FGAuxiliary.h"
|
||||||
|
#include "FGFCS.h"
|
||||||
|
#include "FGMassBalance.h"
|
||||||
|
#include "FGState.h"
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
#endif
|
|
@ -40,7 +40,7 @@ INCLUDES
|
||||||
|
|
||||||
#include "FGMassBalance.h"
|
#include "FGMassBalance.h"
|
||||||
#include "FGPropulsion.h"
|
#include "FGPropulsion.h"
|
||||||
#include "FGPropertyManager.h"
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -73,76 +73,135 @@ FGMassBalance::FGMassBalance(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
FGMassBalance::~FGMassBalance()
|
FGMassBalance::~FGMassBalance()
|
||||||
{
|
{
|
||||||
unbind();
|
unbind();
|
||||||
|
PointMasses.clear();
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGMassBalance::Load(Element* el)
|
||||||
|
{
|
||||||
|
Element *element;
|
||||||
|
string element_name = "";
|
||||||
|
double bixx, biyy, bizz, bixy, bixz, biyz;
|
||||||
|
|
||||||
|
bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
|
||||||
|
if (el->FindElement("ixx"))
|
||||||
|
bixx = el->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2");
|
||||||
|
if (el->FindElement("iyy"))
|
||||||
|
biyy = el->FindElementValueAsNumberConvertTo("iyy", "SLUG*FT2");
|
||||||
|
if (el->FindElement("izz"))
|
||||||
|
bizz = el->FindElementValueAsNumberConvertTo("izz", "SLUG*FT2");
|
||||||
|
if (el->FindElement("ixy"))
|
||||||
|
bixy = el->FindElementValueAsNumberConvertTo("ixy", "SLUG*FT2");
|
||||||
|
if (el->FindElement("ixz"))
|
||||||
|
bixz = el->FindElementValueAsNumberConvertTo("ixz", "SLUG*FT2");
|
||||||
|
if (el->FindElement("iyz"))
|
||||||
|
biyz = el->FindElementValueAsNumberConvertTo("iyz", "SLUG*FT2");
|
||||||
|
SetAircraftBaseInertias(FGMatrix33( bixx, -bixy, -bixz,
|
||||||
|
-bixy, biyy, -biyz,
|
||||||
|
-bixz, -biyz, bizz ));
|
||||||
|
EmptyWeight = el->FindElementValueAsNumberConvertTo("emptywt", "LBS");
|
||||||
|
|
||||||
|
element = el->FindElement("location");
|
||||||
|
while (element) {
|
||||||
|
element_name = element->GetAttributeValue("name");
|
||||||
|
if (element_name == "CG") vbaseXYZcg = element->FindElementTripletConvertTo("IN");
|
||||||
|
element = el->FindNextElement("location");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all POINTMASS elements that descend from this METRICS branch of the
|
||||||
|
// config file.
|
||||||
|
|
||||||
|
element = el->FindElement("pointmass");
|
||||||
|
while (element) {
|
||||||
|
AddPointMass(element);
|
||||||
|
element = el->FindNextElement("pointmass");
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGMassBalance::Run(void)
|
bool FGMassBalance::Run(void)
|
||||||
{
|
{
|
||||||
double denom, k1, k2, k3, k4, k5, k6;
|
double denom, k1, k2, k3, k4, k5, k6;
|
||||||
double Ixx, Iyy, Izz, Ixy, Ixz, Iyz;
|
double Ixx, Iyy, Izz, Ixy, Ixz, Iyz;
|
||||||
|
|
||||||
if (!FGModel::Run()) {
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetPointMassWeight();
|
Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetPointMassWeight();
|
||||||
|
|
||||||
Mass = lbtoslug*Weight;
|
Mass = lbtoslug*Weight;
|
||||||
|
|
||||||
// Calculate new CG
|
// Calculate new CG
|
||||||
|
|
||||||
vXYZcg = (Propulsion->GetTanksMoment() + EmptyWeight*vbaseXYZcg
|
// printf("%s:%i\n", __FILE__, __LINE__);
|
||||||
+ GetPointMassMoment() ) / Weight;
|
vXYZcg = (Propulsion->GetTanksMoment() + EmptyWeight*vbaseXYZcg
|
||||||
|
+ GetPointMassMoment() ) / Weight;
|
||||||
|
|
||||||
// Calculate new total moments of inertia
|
// Calculate new total moments of inertia
|
||||||
|
|
||||||
// At first it is the base configuration inertia matrix ...
|
// At first it is the base configuration inertia matrix ...
|
||||||
mJ = baseJ;
|
mJ = baseJ;
|
||||||
// ... with the additional term originating from the parallel axis theorem.
|
// ... with the additional term originating from the parallel axis theorem.
|
||||||
mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg );
|
mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg );
|
||||||
// Then add the contributions from the additional pointmasses.
|
// Then add the contributions from the additional pointmasses.
|
||||||
mJ += CalculatePMInertias();
|
mJ += CalculatePMInertias();
|
||||||
mJ += Propulsion->CalculateTankInertias();
|
mJ += Propulsion->CalculateTankInertias();
|
||||||
|
|
||||||
Ixx = mJ(1,1);
|
Ixx = mJ(1,1);
|
||||||
Iyy = mJ(2,2);
|
Iyy = mJ(2,2);
|
||||||
Izz = mJ(3,3);
|
Izz = mJ(3,3);
|
||||||
Ixy = -mJ(1,2);
|
Ixy = -mJ(1,2);
|
||||||
Ixz = -mJ(1,3);
|
Ixz = -mJ(1,3);
|
||||||
Iyz = -mJ(2,3);
|
Iyz = -mJ(2,3);
|
||||||
|
|
||||||
// Calculate inertia matrix inverse (ref. Stevens and Lewis, "Flight Control & Simulation")
|
// Calculate inertia matrix inverse (ref. Stevens and Lewis, "Flight Control & Simulation")
|
||||||
|
|
||||||
k1 = (Iyy*Izz - Iyz*Iyz);
|
k1 = (Iyy*Izz - Iyz*Iyz);
|
||||||
k2 = (Iyz*Ixz + Ixy*Izz);
|
k2 = (Iyz*Ixz + Ixy*Izz);
|
||||||
k3 = (Ixy*Iyz + Iyy*Ixz);
|
k3 = (Ixy*Iyz + Iyy*Ixz);
|
||||||
|
|
||||||
denom = 1.0/(Ixx*k1 - Ixy*k2 - Ixz*k3 );
|
denom = 1.0/(Ixx*k1 - Ixy*k2 - Ixz*k3 );
|
||||||
k1 = k1*denom;
|
k1 = k1*denom;
|
||||||
k2 = k2*denom;
|
k2 = k2*denom;
|
||||||
k3 = k3*denom;
|
k3 = k3*denom;
|
||||||
k4 = (Izz*Ixx - Ixz*Ixz)*denom;
|
k4 = (Izz*Ixx - Ixz*Ixz)*denom;
|
||||||
k5 = (Ixy*Ixz + Iyz*Ixx)*denom;
|
k5 = (Ixy*Ixz + Iyz*Ixx)*denom;
|
||||||
k6 = (Ixx*Iyy - Ixy*Ixy)*denom;
|
k6 = (Ixx*Iyy - Ixy*Ixy)*denom;
|
||||||
|
|
||||||
mJinv.InitMatrix( k1, k2, k3,
|
mJinv.InitMatrix( k1, k2, k3,
|
||||||
k2, k4, k5,
|
k2, k4, k5,
|
||||||
k3, k5, k6 );
|
k3, k5, k6 );
|
||||||
|
|
||||||
Debug(2);
|
Debug(0);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGMassBalance::AddPointMass(double weight, double X, double Y, double Z)
|
void FGMassBalance::AddPointMass(Element* el)
|
||||||
{
|
{
|
||||||
PointMassLoc.push_back(FGColumnVector3(X, Y, Z));
|
Element* loc_element = el->FindElement("location");
|
||||||
PointMassWeight.push_back(weight);
|
string pointmass_name = el->GetAttributeValue("name");
|
||||||
|
if (!el) {
|
||||||
|
cerr << "Pointmass " << pointmass_name << "has no location." << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
string loc_unit = loc_element->GetAttributeValue("unit");
|
||||||
|
double w, x, y, z;
|
||||||
|
|
||||||
|
w = el->FindElementValueAsNumberConvertTo("weight", "LBS");
|
||||||
|
x = loc_element->FindElementValueAsNumberConvertTo("x", loc_unit);
|
||||||
|
y = loc_element->FindElementValueAsNumberConvertTo("y", loc_unit);
|
||||||
|
z = loc_element->FindElementValueAsNumberConvertTo("z", loc_unit);
|
||||||
|
|
||||||
|
PointMasses.push_back(PointMass(w, x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -151,8 +210,8 @@ double FGMassBalance::GetPointMassWeight(void)
|
||||||
{
|
{
|
||||||
double PM_total_weight = 0.0;
|
double PM_total_weight = 0.0;
|
||||||
|
|
||||||
for (unsigned int i=0; i<PointMassWeight.size(); i++) {
|
for (unsigned int i=0; i<PointMasses.size(); i++) {
|
||||||
PM_total_weight += PointMassWeight[i];
|
PM_total_weight += PointMasses[i].Weight;
|
||||||
}
|
}
|
||||||
return PM_total_weight;
|
return PM_total_weight;
|
||||||
}
|
}
|
||||||
|
@ -163,8 +222,8 @@ FGColumnVector3& FGMassBalance::GetPointMassMoment(void)
|
||||||
{
|
{
|
||||||
PointMassCG.InitMatrix();
|
PointMassCG.InitMatrix();
|
||||||
|
|
||||||
for (unsigned int i=0; i<PointMassLoc.size(); i++) {
|
for (unsigned int i=0; i<PointMasses.size(); i++) {
|
||||||
PointMassCG += PointMassWeight[i]*PointMassLoc[i];
|
PointMassCG += PointMasses[i].Weight*PointMasses[i].Location;
|
||||||
}
|
}
|
||||||
return PointMassCG;
|
return PointMassCG;
|
||||||
}
|
}
|
||||||
|
@ -175,13 +234,13 @@ FGMatrix33& FGMassBalance::CalculatePMInertias(void)
|
||||||
{
|
{
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
size = PointMassLoc.size();
|
size = PointMasses.size();
|
||||||
if (size == 0) return pmJ;
|
if (size == 0) return pmJ;
|
||||||
|
|
||||||
pmJ = FGMatrix33();
|
pmJ = FGMatrix33();
|
||||||
|
|
||||||
for (unsigned int i=0; i<size; i++)
|
for (unsigned int i=0; i<size; i++)
|
||||||
pmJ += GetPointmassInertia( lbtoslug * PointMassWeight[i], PointMassLoc[i] );
|
pmJ += GetPointmassInertia( lbtoslug * PointMasses[i].Weight, PointMasses[i].Location );
|
||||||
|
|
||||||
return pmJ;
|
return pmJ;
|
||||||
}
|
}
|
||||||
|
@ -271,8 +330,23 @@ void FGMassBalance::Debug(int from)
|
||||||
if (debug_lvl <= 0) return;
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
if (debug_lvl & 1) { // Standard console startup message output
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
if (from == 0) { // Constructor
|
if (from == 2) { // Loading
|
||||||
|
cout << endl << " Mass and Balance:" << endl;
|
||||||
|
cout << " baseIxx: " << baseJ(1,1) << " slug-ft2" << endl;
|
||||||
|
cout << " baseIyy: " << baseJ(2,2) << " slug-ft2" << endl;
|
||||||
|
cout << " baseIzz: " << baseJ(3,3) << " slug-ft2" << endl;
|
||||||
|
cout << " baseIxy: " << baseJ(1,2) << " slug-ft2" << endl;
|
||||||
|
cout << " baseIxz: " << baseJ(1,3) << " slug-ft2" << endl;
|
||||||
|
cout << " baseIyz: " << baseJ(2,3) << " slug-ft2" << endl;
|
||||||
|
cout << " EmptyWeight: " << EmptyWeight << " lbm" << endl;
|
||||||
|
cout << " CG (x, y, z): " << vbaseXYZcg << endl;
|
||||||
|
// ToDo: Need to add point mass outputs here
|
||||||
|
for (int i=0; i<PointMasses.size(); i++) {
|
||||||
|
cout << " Point Mass Object: " << PointMasses[i].Weight << " lbs. at "
|
||||||
|
<< "X, Y, Z (in.): " << PointMasses[i].Location(eX) << " "
|
||||||
|
<< PointMasses[i].Location(eY) << " "
|
||||||
|
<< PointMasses[i].Location(eZ) << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
|
@ -39,8 +39,9 @@ INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGModel.h"
|
#include "FGModel.h"
|
||||||
#include "FGColumnVector3.h"
|
#include <math/FGColumnVector3.h>
|
||||||
#include "FGMatrix33.h"
|
#include <math/FGMatrix33.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -73,14 +74,14 @@ public:
|
||||||
FGMassBalance(FGFDMExec*);
|
FGMassBalance(FGFDMExec*);
|
||||||
~FGMassBalance();
|
~FGMassBalance();
|
||||||
|
|
||||||
|
bool Load(Element* el);
|
||||||
|
|
||||||
bool Run(void);
|
bool Run(void);
|
||||||
|
|
||||||
inline double GetMass(void) const {return Mass;}
|
inline double GetMass(void) const {return Mass;}
|
||||||
inline double GetWeight(void) const {return Weight;}
|
inline double GetWeight(void) const {return Weight;}
|
||||||
inline double GetEmptyWeight(void) const {return EmptyWeight;}
|
|
||||||
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
|
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
|
||||||
inline double GetXYZcg(int axis) const {return vXYZcg(axis);}
|
inline double GetXYZcg(int axis) const {return vXYZcg(axis);}
|
||||||
inline double GetbaseXYZcg(int axis) const {return vbaseXYZcg(axis);}
|
|
||||||
|
|
||||||
/** Computes the inertia contribution of a pointmass.
|
/** Computes the inertia contribution of a pointmass.
|
||||||
Computes and returns the inertia matrix of a pointmass of mass
|
Computes and returns the inertia matrix of a pointmass of mass
|
||||||
|
@ -119,17 +120,13 @@ public:
|
||||||
inline void SetEmptyWeight(double EW) { EmptyWeight = EW;}
|
inline void SetEmptyWeight(double EW) { EmptyWeight = EW;}
|
||||||
inline void SetBaseCG(const FGColumnVector3& CG) {vbaseXYZcg = vXYZcg = CG;}
|
inline void SetBaseCG(const FGColumnVector3& CG) {vbaseXYZcg = vXYZcg = CG;}
|
||||||
|
|
||||||
void AddPointMass(double weight, double X, double Y, double Z);
|
void AddPointMass(Element* el);
|
||||||
double GetPointMassWeight(void);
|
double GetPointMassWeight(void);
|
||||||
FGColumnVector3& GetPointMassMoment(void);
|
FGColumnVector3& GetPointMassMoment(void);
|
||||||
FGMatrix33& GetJ(void) {return mJ;}
|
FGMatrix33& GetJ(void) {return mJ;}
|
||||||
FGMatrix33& GetJinv(void) {return mJinv;}
|
FGMatrix33& GetJinv(void) {return mJinv;}
|
||||||
void SetAircraftBaseInertias(FGMatrix33 BaseJ) {baseJ = BaseJ;}
|
void SetAircraftBaseInertias(FGMatrix33 BaseJ) {baseJ = BaseJ;}
|
||||||
FGMatrix33& GetAircraftBaseInertias(void) {return baseJ;}
|
|
||||||
int GetNumPointMasses(void) {return PointMassLoc.size();}
|
|
||||||
FGColumnVector3& GetPointMassLoc(int i) {return PointMassLoc[i];}
|
|
||||||
double GetPointMassWeight(int i) {return PointMassWeight[i];}
|
|
||||||
|
|
||||||
void bind(void);
|
void bind(void);
|
||||||
void unbind(void);
|
void unbind(void);
|
||||||
|
|
||||||
|
@ -145,11 +142,20 @@ private:
|
||||||
FGColumnVector3 vXYZtank;
|
FGColumnVector3 vXYZtank;
|
||||||
FGColumnVector3 vbaseXYZcg;
|
FGColumnVector3 vbaseXYZcg;
|
||||||
FGColumnVector3 vPMxyz;
|
FGColumnVector3 vPMxyz;
|
||||||
vector <FGColumnVector3> PointMassLoc;
|
|
||||||
vector <double> PointMassWeight;
|
|
||||||
FGColumnVector3 PointMassCG;
|
FGColumnVector3 PointMassCG;
|
||||||
FGMatrix33& CalculatePMInertias(void);
|
FGMatrix33& CalculatePMInertias(void);
|
||||||
|
|
||||||
|
struct PointMass {
|
||||||
|
PointMass(double w, double x, double y, double z) {
|
||||||
|
Weight = w;
|
||||||
|
Location.InitMatrix(x, y, z);
|
||||||
|
}
|
||||||
|
FGColumnVector3 Location;
|
||||||
|
double Weight;
|
||||||
|
};
|
||||||
|
|
||||||
|
vector <struct PointMass> PointMasses;
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -51,7 +51,6 @@ INCLUDES
|
||||||
#include "FGAircraft.h"
|
#include "FGAircraft.h"
|
||||||
#include "FGPropagate.h"
|
#include "FGPropagate.h"
|
||||||
#include "FGAuxiliary.h"
|
#include "FGAuxiliary.h"
|
||||||
#include "FGOutput.h"
|
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -82,7 +81,6 @@ FGModel::FGModel(FGFDMExec* fdmex)
|
||||||
Aircraft = 0;
|
Aircraft = 0;
|
||||||
Propagate = 0;
|
Propagate = 0;
|
||||||
Auxiliary = 0;
|
Auxiliary = 0;
|
||||||
Output = 0;
|
|
||||||
|
|
||||||
//in order for FGModel derived classes to self-bind (that is, call
|
//in order for FGModel derived classes to self-bind (that is, call
|
||||||
//their bind function in the constructor, the PropertyManager pointer
|
//their bind function in the constructor, the PropertyManager pointer
|
||||||
|
@ -117,7 +115,6 @@ bool FGModel::InitModel(void)
|
||||||
Aircraft = FDMExec->GetAircraft();
|
Aircraft = FDMExec->GetAircraft();
|
||||||
Propagate = FDMExec->GetPropagate();
|
Propagate = FDMExec->GetPropagate();
|
||||||
Auxiliary = FDMExec->GetAuxiliary();
|
Auxiliary = FDMExec->GetAuxiliary();
|
||||||
Output = FDMExec->GetOutput();
|
|
||||||
|
|
||||||
if (!State ||
|
if (!State ||
|
||||||
!Atmosphere ||
|
!Atmosphere ||
|
||||||
|
@ -129,8 +126,7 @@ bool FGModel::InitModel(void)
|
||||||
!GroundReactions ||
|
!GroundReactions ||
|
||||||
!Aircraft ||
|
!Aircraft ||
|
||||||
!Propagate ||
|
!Propagate ||
|
||||||
!Auxiliary ||
|
!Auxiliary) return(false);
|
||||||
!Output) return(false);
|
|
||||||
else return(true);
|
else return(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,9 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGJSBBase.h"
|
#include <FGJSBBase.h>
|
||||||
#include "FGPropertyManager.h"
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
# include <simgear/compiler.h>
|
# include <simgear/compiler.h>
|
||||||
|
@ -84,8 +85,6 @@ class FGGroundReactions;
|
||||||
class FGAircraft;
|
class FGAircraft;
|
||||||
class FGPropagate;
|
class FGPropagate;
|
||||||
class FGAuxiliary;
|
class FGAuxiliary;
|
||||||
class FGOutput;
|
|
||||||
class FGConfigFile;
|
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
CLASS DOCUMENTATION
|
CLASS DOCUMENTATION
|
||||||
|
@ -109,9 +108,9 @@ public:
|
||||||
virtual ~FGModel();
|
virtual ~FGModel();
|
||||||
|
|
||||||
/** Loads this model.
|
/** Loads this model.
|
||||||
@param Config a pointer to the config file instance
|
@param el a pointer to the element
|
||||||
@return true if model is successfully loaded*/
|
@return true if model is successfully loaded*/
|
||||||
virtual bool Load(FGConfigFile* Config) {return true;}
|
virtual bool Load(Element* el) {return true;}
|
||||||
|
|
||||||
FGModel* NextModel;
|
FGModel* NextModel;
|
||||||
string Name;
|
string Name;
|
||||||
|
@ -144,7 +143,6 @@ protected:
|
||||||
FGAircraft* Aircraft;
|
FGAircraft* Aircraft;
|
||||||
FGPropagate* Propagate;
|
FGPropagate* Propagate;
|
||||||
FGAuxiliary* Auxiliary;
|
FGAuxiliary* Auxiliary;
|
||||||
FGOutput* Output;
|
|
||||||
FGPropertyManager* PropertyManager;
|
FGPropertyManager* PropertyManager;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -51,6 +51,7 @@ INCLUDES
|
||||||
#include "FGAuxiliary.h"
|
#include "FGAuxiliary.h"
|
||||||
#include "FGInertial.h"
|
#include "FGInertial.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -68,11 +69,10 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
sFirstPass = dFirstPass = true;
|
sFirstPass = dFirstPass = true;
|
||||||
socket = 0;
|
socket = 0;
|
||||||
Type = otNone;
|
Type = otNone;
|
||||||
Filename = "";
|
|
||||||
SubSystems = 0;
|
SubSystems = 0;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
outputInFileName = "";
|
|
||||||
delimeter = ", ";
|
delimeter = ", ";
|
||||||
|
Filename = "";
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
FGOutput::~FGOutput()
|
FGOutput::~FGOutput()
|
||||||
{
|
{
|
||||||
if (socket) delete socket;
|
if (socket) delete socket;
|
||||||
for (unsigned int i=0; i<OutputProperties.size(); i++) delete OutputProperties[i];
|
OutputProperties.clear();
|
||||||
|
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,9 @@ FGOutput::~FGOutput()
|
||||||
|
|
||||||
bool FGOutput::Run(void)
|
bool FGOutput::Run(void)
|
||||||
{
|
{
|
||||||
if (enabled) {
|
if (FGModel::Run()) return true;
|
||||||
if (FGModel::Run()) return true;
|
|
||||||
|
if (enabled && !State->IntegrationSuspended()&& !FDMExec->Holding()) {
|
||||||
if (Type == otSocket) {
|
if (Type == otSocket) {
|
||||||
SocketOutput();
|
SocketOutput();
|
||||||
} else if (Type == otCSV || Type == otTab) {
|
} else if (Type == otCSV || Type == otTab) {
|
||||||
|
@ -187,6 +188,8 @@ void FGOutput::DelimitedOutput(string fname)
|
||||||
if (SubSystems & ssAtmosphere) {
|
if (SubSystems & ssAtmosphere) {
|
||||||
outstream << delimeter;
|
outstream << delimeter;
|
||||||
outstream << "Rho" + delimeter;
|
outstream << "Rho" + delimeter;
|
||||||
|
outstream << "SL pressure" + delimeter;
|
||||||
|
outstream << "Ambient pressure" + delimeter;
|
||||||
outstream << "NWind" + delimeter + "EWind" + delimeter + "DWind";
|
outstream << "NWind" + delimeter + "EWind" + delimeter + "DWind";
|
||||||
}
|
}
|
||||||
if (SubSystems & ssMassProps) {
|
if (SubSystems & ssMassProps) {
|
||||||
|
@ -281,6 +284,8 @@ void FGOutput::DelimitedOutput(string fname)
|
||||||
if (SubSystems & ssAtmosphere) {
|
if (SubSystems & ssAtmosphere) {
|
||||||
outstream << delimeter;
|
outstream << delimeter;
|
||||||
outstream << Atmosphere->GetDensity() << delimeter;
|
outstream << Atmosphere->GetDensity() << delimeter;
|
||||||
|
outstream << Atmosphere->GetPressureSL() << delimeter;
|
||||||
|
outstream << Atmosphere->GetPressure() << delimeter;
|
||||||
outstream << Atmosphere->GetWindNED().Dump(delimeter);
|
outstream << Atmosphere->GetWindNED().Dump(delimeter);
|
||||||
}
|
}
|
||||||
if (SubSystems & ssMassProps) {
|
if (SubSystems & ssMassProps) {
|
||||||
|
@ -329,99 +334,220 @@ void FGOutput::DelimitedOutput(string fname)
|
||||||
|
|
||||||
void FGOutput::SocketOutput(void)
|
void FGOutput::SocketOutput(void)
|
||||||
{
|
{
|
||||||
string asciiData;
|
string asciiData, scratch;
|
||||||
|
|
||||||
if (socket == NULL) return;
|
if (socket == NULL) return;
|
||||||
if (!socket->GetConnectStatus()) return;
|
if (!socket->GetConnectStatus()) return;
|
||||||
|
|
||||||
socket->Clear();
|
socket->Clear();
|
||||||
if (sFirstPass) {
|
if (sFirstPass) {
|
||||||
socket->Append("<LABELS>");
|
socket->Clear("<LABELS>");
|
||||||
socket->Append("Time");
|
socket->Append("Time");
|
||||||
socket->Append("Altitude");
|
|
||||||
socket->Append("Phi");
|
if (SubSystems & ssAerosurfaces) {
|
||||||
socket->Append("Tht");
|
socket->Append("Aileron Command");
|
||||||
socket->Append("Psi");
|
socket->Append("Elevator Command");
|
||||||
socket->Append("Rho");
|
socket->Append("Rudder Command");
|
||||||
socket->Append("Vtotal");
|
socket->Append("Flap Command");
|
||||||
socket->Append("UBody");
|
socket->Append("Left Aileron Position");
|
||||||
socket->Append("VBody");
|
socket->Append("Right Aileron Position");
|
||||||
socket->Append("WBody");
|
socket->Append("Elevator Position");
|
||||||
socket->Append("UAero");
|
socket->Append("Rudder Position");
|
||||||
socket->Append("VAero");
|
socket->Append("Flap Position");
|
||||||
socket->Append("WAero");
|
}
|
||||||
socket->Append("Vn");
|
|
||||||
socket->Append("Ve");
|
if (SubSystems & ssRates) {
|
||||||
socket->Append("Vd");
|
socket->Append("P");
|
||||||
socket->Append("Udot");
|
socket->Append("Q");
|
||||||
socket->Append("Vdot");
|
socket->Append("R");
|
||||||
socket->Append("Wdot");
|
socket->Append("PDot");
|
||||||
socket->Append("P");
|
socket->Append("QDot");
|
||||||
socket->Append("Q");
|
socket->Append("RDot");
|
||||||
socket->Append("R");
|
}
|
||||||
socket->Append("PDot");
|
|
||||||
socket->Append("QDot");
|
if (SubSystems & ssVelocities) {
|
||||||
socket->Append("RDot");
|
socket->Append("QBar");
|
||||||
socket->Append("Fx");
|
socket->Append("Vtotal");
|
||||||
socket->Append("Fy");
|
socket->Append("UBody");
|
||||||
socket->Append("Fz");
|
socket->Append("VBody");
|
||||||
socket->Append("Latitude (Deg)");
|
socket->Append("WBody");
|
||||||
socket->Append("Longitude (Deg)");
|
socket->Append("UAero");
|
||||||
socket->Append("QBar");
|
socket->Append("VAero");
|
||||||
socket->Append("Alpha");
|
socket->Append("WAero");
|
||||||
socket->Append("L");
|
socket->Append("Vn");
|
||||||
socket->Append("M");
|
socket->Append("Ve");
|
||||||
socket->Append("N");
|
socket->Append("Vd");
|
||||||
socket->Append("Throttle Position");
|
}
|
||||||
socket->Append("Left Aileron Position");
|
if (SubSystems & ssForces) {
|
||||||
socket->Append("Right Aileron Position");
|
socket->Append("F_Drag");
|
||||||
socket->Append("Elevator Position");
|
socket->Append("F_Side");
|
||||||
socket->Append("Rudder Position");
|
socket->Append("F_Lift");
|
||||||
|
socket->Append("LoD");
|
||||||
|
socket->Append("Fx");
|
||||||
|
socket->Append("Fy");
|
||||||
|
socket->Append("Fz");
|
||||||
|
}
|
||||||
|
if (SubSystems & ssMoments) {
|
||||||
|
socket->Append("L");
|
||||||
|
socket->Append("M");
|
||||||
|
socket->Append("N");
|
||||||
|
}
|
||||||
|
if (SubSystems & ssAtmosphere) {
|
||||||
|
socket->Append("Rho");
|
||||||
|
socket->Append("SL pressure");
|
||||||
|
socket->Append("Ambient pressure");
|
||||||
|
socket->Append("NWind");
|
||||||
|
socket->Append("EWind");
|
||||||
|
socket->Append("DWind");
|
||||||
|
}
|
||||||
|
if (SubSystems & ssMassProps) {
|
||||||
|
socket->Append("Ixx");
|
||||||
|
socket->Append("Ixy");
|
||||||
|
socket->Append("Ixz");
|
||||||
|
socket->Append("Iyx");
|
||||||
|
socket->Append("Iyy");
|
||||||
|
socket->Append("Iyz");
|
||||||
|
socket->Append("Izx");
|
||||||
|
socket->Append("Izy");
|
||||||
|
socket->Append("Izz");
|
||||||
|
socket->Append("Mass");
|
||||||
|
socket->Append("Xcg");
|
||||||
|
socket->Append("Ycg");
|
||||||
|
socket->Append("Zcg");
|
||||||
|
}
|
||||||
|
if (SubSystems & ssPropagate) {
|
||||||
|
socket->Append("Altitude");
|
||||||
|
socket->Append("Phi");
|
||||||
|
socket->Append("Tht");
|
||||||
|
socket->Append("Psi");
|
||||||
|
socket->Append("Alpha");
|
||||||
|
socket->Append("Beta");
|
||||||
|
socket->Append("Latitude (Deg)");
|
||||||
|
socket->Append("Longitude (Deg)");
|
||||||
|
}
|
||||||
|
if (SubSystems & ssCoefficients) {
|
||||||
|
scratch = Aerodynamics->GetCoefficientStrings(",");
|
||||||
|
if (scratch.length() != 0) socket->Append(scratch);
|
||||||
|
}
|
||||||
|
if (SubSystems & ssFCS) {
|
||||||
|
scratch = FCS->GetComponentStrings(",");
|
||||||
|
if (scratch.length() != 0) socket->Append(scratch);
|
||||||
|
}
|
||||||
|
if (SubSystems & ssGroundReactions) {
|
||||||
|
socket->Append(GroundReactions->GetGroundReactionStrings(","));
|
||||||
|
}
|
||||||
|
if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) {
|
||||||
|
socket->Append(Propulsion->GetPropulsionStrings(","));
|
||||||
|
}
|
||||||
|
if (OutputProperties.size() > 0) {
|
||||||
|
for (unsigned int i=0;i<OutputProperties.size();i++) {
|
||||||
|
socket->Append(OutputProperties[i]->GetName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sFirstPass = false;
|
sFirstPass = false;
|
||||||
socket->Send();
|
socket->Send();
|
||||||
}
|
}
|
||||||
|
|
||||||
socket->Clear();
|
socket->Clear();
|
||||||
socket->Append(State->Getsim_time());
|
socket->Append(State->Getsim_time());
|
||||||
socket->Append(Propagate->Geth());
|
|
||||||
socket->Append(Propagate->GetEuler(ePhi));
|
if (SubSystems & ssAerosurfaces) {
|
||||||
socket->Append(Propagate->GetEuler(eTht));
|
socket->Append(FCS->GetDaCmd());
|
||||||
socket->Append(Propagate->GetEuler(ePsi));
|
socket->Append(FCS->GetDeCmd());
|
||||||
socket->Append(Atmosphere->GetDensity());
|
socket->Append(FCS->GetDrCmd());
|
||||||
socket->Append(Auxiliary->GetVt());
|
socket->Append(FCS->GetDfCmd());
|
||||||
socket->Append(Propagate->GetUVW(eU));
|
socket->Append(FCS->GetDaLPos());
|
||||||
socket->Append(Propagate->GetUVW(eV));
|
socket->Append(FCS->GetDaRPos());
|
||||||
socket->Append(Propagate->GetUVW(eW));
|
socket->Append(FCS->GetDePos());
|
||||||
socket->Append(Auxiliary->GetAeroUVW(eU));
|
socket->Append(FCS->GetDrPos());
|
||||||
socket->Append(Auxiliary->GetAeroUVW(eV));
|
socket->Append(FCS->GetDfPos());
|
||||||
socket->Append(Auxiliary->GetAeroUVW(eW));
|
}
|
||||||
socket->Append(Propagate->GetVel(eNorth));
|
if (SubSystems & ssRates) {
|
||||||
socket->Append(Propagate->GetVel(eEast));
|
socket->Append(Propagate->GetPQR(eP));
|
||||||
socket->Append(Propagate->GetVel(eDown));
|
socket->Append(Propagate->GetPQR(eQ));
|
||||||
socket->Append(Propagate->GetUVWdot(eU));
|
socket->Append(Propagate->GetPQR(eR));
|
||||||
socket->Append(Propagate->GetUVWdot(eV));
|
socket->Append(Propagate->GetPQRdot(eP));
|
||||||
socket->Append(Propagate->GetUVWdot(eW));
|
socket->Append(Propagate->GetPQRdot(eQ));
|
||||||
socket->Append(Propagate->GetPQR(eP));
|
socket->Append(Propagate->GetPQRdot(eR));
|
||||||
socket->Append(Propagate->GetPQR(eQ));
|
}
|
||||||
socket->Append(Propagate->GetPQR(eR));
|
if (SubSystems & ssVelocities) {
|
||||||
socket->Append(Propagate->GetPQRdot(eP));
|
socket->Append(Auxiliary->Getqbar());
|
||||||
socket->Append(Propagate->GetPQRdot(eQ));
|
socket->Append(Auxiliary->GetVt());
|
||||||
socket->Append(Propagate->GetPQRdot(eR));
|
socket->Append(Propagate->GetUVW(eU));
|
||||||
socket->Append(Aircraft->GetForces(eX));
|
socket->Append(Propagate->GetUVW(eV));
|
||||||
socket->Append(Aircraft->GetForces(eY));
|
socket->Append(Propagate->GetUVW(eW));
|
||||||
socket->Append(Aircraft->GetForces(eZ));
|
socket->Append(Auxiliary->GetAeroUVW(eU));
|
||||||
socket->Append(Propagate->GetLocation().GetLatitudeDeg());
|
socket->Append(Auxiliary->GetAeroUVW(eV));
|
||||||
socket->Append(Propagate->GetLocation().GetLongitudeDeg());
|
socket->Append(Auxiliary->GetAeroUVW(eW));
|
||||||
socket->Append(Auxiliary->Getqbar());
|
socket->Append(Propagate->GetVel(eNorth));
|
||||||
socket->Append(Auxiliary->Getalpha(inDegrees));
|
socket->Append(Propagate->GetVel(eEast));
|
||||||
socket->Append(Aircraft->GetMoments(eL));
|
socket->Append(Propagate->GetVel(eDown));
|
||||||
socket->Append(Aircraft->GetMoments(eM));
|
}
|
||||||
socket->Append(Aircraft->GetMoments(eN));
|
if (SubSystems & ssForces) {
|
||||||
socket->Append(FCS->GetThrottlePos(0));
|
socket->Append(Aerodynamics->GetvFs()(eDrag));
|
||||||
socket->Append(FCS->GetDaLPos());
|
socket->Append(Aerodynamics->GetvFs()(eSide));
|
||||||
socket->Append(FCS->GetDaRPos());
|
socket->Append(Aerodynamics->GetvFs()(eLift));
|
||||||
socket->Append(FCS->GetDePos());
|
socket->Append(Aerodynamics->GetLoD());
|
||||||
socket->Append(FCS->GetDrPos());
|
socket->Append(Aircraft->GetForces(eX));
|
||||||
|
socket->Append(Aircraft->GetForces(eY));
|
||||||
|
socket->Append(Aircraft->GetForces(eZ));
|
||||||
|
}
|
||||||
|
if (SubSystems & ssMoments) {
|
||||||
|
socket->Append(Aircraft->GetMoments(eL));
|
||||||
|
socket->Append(Aircraft->GetMoments(eM));
|
||||||
|
socket->Append(Aircraft->GetMoments(eN));
|
||||||
|
}
|
||||||
|
if (SubSystems & ssAtmosphere) {
|
||||||
|
socket->Append(Atmosphere->GetDensity());
|
||||||
|
socket->Append(Atmosphere->GetPressureSL());
|
||||||
|
socket->Append(Atmosphere->GetPressure());
|
||||||
|
socket->Append(Atmosphere->GetWindNED().Dump(","));
|
||||||
|
}
|
||||||
|
if (SubSystems & ssMassProps) {
|
||||||
|
socket->Append(MassBalance->GetJ()(1,1));
|
||||||
|
socket->Append(MassBalance->GetJ()(1,2));
|
||||||
|
socket->Append(MassBalance->GetJ()(1,3));
|
||||||
|
socket->Append(MassBalance->GetJ()(2,1));
|
||||||
|
socket->Append(MassBalance->GetJ()(2,2));
|
||||||
|
socket->Append(MassBalance->GetJ()(2,3));
|
||||||
|
socket->Append(MassBalance->GetJ()(3,1));
|
||||||
|
socket->Append(MassBalance->GetJ()(3,2));
|
||||||
|
socket->Append(MassBalance->GetJ()(3,3));
|
||||||
|
socket->Append(MassBalance->GetMass());
|
||||||
|
socket->Append(MassBalance->GetXYZcg()(eX));
|
||||||
|
socket->Append(MassBalance->GetXYZcg()(eY));
|
||||||
|
socket->Append(MassBalance->GetXYZcg()(eZ));
|
||||||
|
}
|
||||||
|
if (SubSystems & ssPropagate) {
|
||||||
|
socket->Append(Propagate->Geth());
|
||||||
|
socket->Append(Propagate->GetEuler(ePhi));
|
||||||
|
socket->Append(Propagate->GetEuler(eTht));
|
||||||
|
socket->Append(Propagate->GetEuler(ePsi));
|
||||||
|
socket->Append(Auxiliary->Getalpha(inDegrees));
|
||||||
|
socket->Append(Auxiliary->Getbeta(inDegrees));
|
||||||
|
socket->Append(Propagate->GetLocation().GetLatitudeDeg());
|
||||||
|
socket->Append(Propagate->GetLocation().GetLongitudeDeg());
|
||||||
|
}
|
||||||
|
if (SubSystems & ssCoefficients) {
|
||||||
|
scratch = Aerodynamics->GetCoefficientValues(",");
|
||||||
|
if (scratch.length() != 0) socket->Append(scratch);
|
||||||
|
}
|
||||||
|
if (SubSystems & ssFCS) {
|
||||||
|
scratch = FCS->GetComponentValues(",");
|
||||||
|
if (scratch.length() != 0) socket->Append(scratch);
|
||||||
|
}
|
||||||
|
if (SubSystems & ssGroundReactions) {
|
||||||
|
socket->Append(GroundReactions->GetGroundReactionValues(","));
|
||||||
|
}
|
||||||
|
if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) {
|
||||||
|
socket->Append(Propulsion->GetPropulsionValues(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0;i<OutputProperties.size();i++) {
|
||||||
|
socket->Append(OutputProperties[i]->getDoubleValue());
|
||||||
|
}
|
||||||
|
|
||||||
socket->Send();
|
socket->Send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,108 +567,81 @@ void FGOutput::SocketStatusOutput(string out_str)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGOutput::Load(FGConfigFile* AC_cfg)
|
bool FGOutput::Load(Element* element)
|
||||||
{
|
{
|
||||||
string token="", parameter="", separator="";
|
string type="", parameter="";
|
||||||
string name="", fname="";
|
string name="", fname="";
|
||||||
int OutRate = 0;
|
int OutRate = 0;
|
||||||
FGConfigFile* Output_cfg;
|
|
||||||
string property;
|
string property;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
|
FGXMLParse output_file_parser;
|
||||||
|
Element *document, *property_element;
|
||||||
|
ifstream* output_file = new ifstream();
|
||||||
|
|
||||||
# ifndef macintosh
|
string separator = "/";
|
||||||
separator = "/";
|
# ifdef macintosh
|
||||||
# else
|
separator = ";";
|
||||||
separator = ";";
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
name = AC_cfg->GetValue("NAME");
|
fname = element->GetAttributeValue("file");
|
||||||
fname = AC_cfg->GetValue("FILE");
|
|
||||||
token = AC_cfg->GetValue("TYPE");
|
|
||||||
port = atoi(AC_cfg->GetValue("PORT").c_str());
|
|
||||||
|
|
||||||
Output->SetType(token);
|
|
||||||
|
|
||||||
if (token == "SOCKET") {
|
|
||||||
socket = new FGfdmSocket(name,port);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fname.empty()) {
|
if (!fname.empty()) {
|
||||||
outputInFileName = FDMExec->GetAircraftPath() + separator
|
output_file_name = FDMExec->GetAircraftPath() + separator
|
||||||
+ FDMExec->GetModelName() + separator + fname + ".xml";
|
+ FDMExec->GetModelName() + separator + fname + ".xml";
|
||||||
Output_cfg = new FGConfigFile(outputInFileName);
|
|
||||||
if (!Output_cfg->IsOpen()) {
|
output_file->open(output_file_name.c_str());
|
||||||
cerr << "Could not open file: " << outputInFileName << endl;
|
readXML(*output_file, output_file_parser);
|
||||||
return false;
|
delete output_file;
|
||||||
}
|
document = output_file_parser.GetDocument();
|
||||||
} else {
|
} else {
|
||||||
Output_cfg = AC_cfg;
|
document = element;
|
||||||
}
|
}
|
||||||
Output->SetFilename(name);
|
|
||||||
|
|
||||||
while ((token = Output_cfg->GetValue()) != string("/OUTPUT")) {
|
name = document->GetAttributeValue("name");
|
||||||
*Output_cfg >> parameter;
|
type = document->GetAttributeValue("type");
|
||||||
if (parameter == "RATE_IN_HZ") {
|
SetType(type);
|
||||||
*Output_cfg >> OutRate;
|
if (!document->GetAttributeValue("port").empty() && type == string("SOCKET")) {
|
||||||
}
|
port = atoi(document->GetAttributeValue("port").c_str());
|
||||||
if (parameter == "SIMULATION") {
|
socket = new FGfdmSocket(name, port);
|
||||||
*Output_cfg >> parameter;
|
} else {
|
||||||
if (parameter == "ON") SubSystems += ssSimulation;
|
Filename = name;
|
||||||
}
|
}
|
||||||
if (parameter == "AEROSURFACES") {
|
if (!document->GetAttributeValue("rate").empty()) {
|
||||||
*Output_cfg >> parameter;
|
OutRate = (int)document->GetAttributeValueAsNumber("rate");
|
||||||
if (parameter == "ON") SubSystems += ssAerosurfaces;
|
} else {
|
||||||
}
|
OutRate = 1;
|
||||||
if (parameter == "RATES") {
|
}
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssRates;
|
|
||||||
}
|
|
||||||
if (parameter == "VELOCITIES") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssVelocities;
|
|
||||||
}
|
|
||||||
if (parameter == "FORCES") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssForces;
|
|
||||||
}
|
|
||||||
if (parameter == "MOMENTS") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssMoments;
|
|
||||||
}
|
|
||||||
if (parameter == "ATMOSPHERE") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssAtmosphere;
|
|
||||||
}
|
|
||||||
if (parameter == "MASSPROPS") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssMassProps;
|
|
||||||
}
|
|
||||||
if (parameter == "POSITION") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssPropagate;
|
|
||||||
}
|
|
||||||
if (parameter == "COEFFICIENTS") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssCoefficients;
|
|
||||||
}
|
|
||||||
if (parameter == "GROUND_REACTIONS") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssGroundReactions;
|
|
||||||
}
|
|
||||||
if (parameter == "FCS") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssFCS;
|
|
||||||
}
|
|
||||||
if (parameter == "PROPULSION") {
|
|
||||||
*Output_cfg >> parameter;
|
|
||||||
if (parameter == "ON") SubSystems += ssPropulsion;
|
|
||||||
}
|
|
||||||
if (parameter == "PROPERTY") {
|
|
||||||
*Output_cfg >> property;
|
|
||||||
OutputProperties.push_back(PropertyManager->GetNode(property));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameter == "EOF") break;
|
if (document->FindElementValue("simulation") == string("ON"))
|
||||||
|
SubSystems += ssSimulation;
|
||||||
|
if (document->FindElementValue("aerosurfaces") == string("ON"))
|
||||||
|
SubSystems += ssAerosurfaces;
|
||||||
|
if (document->FindElementValue("rates") == string("ON"))
|
||||||
|
SubSystems += ssRates;
|
||||||
|
if (document->FindElementValue("velocities") == string("ON"))
|
||||||
|
SubSystems += ssVelocities;
|
||||||
|
if (document->FindElementValue("forces") == string("ON"))
|
||||||
|
SubSystems += ssForces;
|
||||||
|
if (document->FindElementValue("moments") == string("ON"))
|
||||||
|
SubSystems += ssMoments;
|
||||||
|
if (document->FindElementValue("atmosphere") == string("ON"))
|
||||||
|
SubSystems += ssAtmosphere;
|
||||||
|
if (document->FindElementValue("massprops") == string("ON"))
|
||||||
|
SubSystems += ssMassProps;
|
||||||
|
if (document->FindElementValue("position") == string("ON"))
|
||||||
|
SubSystems += ssPropagate;
|
||||||
|
if (document->FindElementValue("coefficients") == string("ON"))
|
||||||
|
SubSystems += ssCoefficients;
|
||||||
|
if (document->FindElementValue("ground_reactions") == string("ON"))
|
||||||
|
SubSystems += ssGroundReactions;
|
||||||
|
if (document->FindElementValue("fcs") == string("ON"))
|
||||||
|
SubSystems += ssFCS;
|
||||||
|
if (document->FindElementValue("propulsion") == string("ON"))
|
||||||
|
SubSystems += ssPropulsion;
|
||||||
|
property_element = document->FindElement("property");
|
||||||
|
while (property_element) {
|
||||||
|
string property = property_element->GetDataLine();
|
||||||
|
OutputProperties.push_back(PropertyManager->GetNode(property));
|
||||||
|
property_element = document->FindNextElement("property");
|
||||||
}
|
}
|
||||||
|
|
||||||
OutRate = OutRate>120?120:(OutRate<0?0:OutRate);
|
OutRate = OutRate>120?120:(OutRate<0?0:OutRate);
|
||||||
|
@ -583,10 +682,10 @@ void FGOutput::Debug(int from)
|
||||||
|
|
||||||
}
|
}
|
||||||
if (from == 2) {
|
if (from == 2) {
|
||||||
if (outputInFileName.empty())
|
if (output_file_name.empty())
|
||||||
cout << " " << "Output parameters read inline" << endl;
|
cout << " " << "Output parameters read inline" << endl;
|
||||||
else
|
else
|
||||||
cout << " Output parameters read from file: " << outputInFileName << endl;
|
cout << " Output parameters read from file: " << output_file_name << endl;
|
||||||
|
|
||||||
if (Filename == "cout" || Filename == "COUT") {
|
if (Filename == "cout" || Filename == "COUT") {
|
||||||
scratch = " Log output goes to screen console";
|
scratch = " Log output goes to screen console";
|
|
@ -54,7 +54,8 @@ INCLUDES
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "FGfdmSocket.h"
|
#include <input_output/FGfdmSocket.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -133,13 +134,12 @@ public:
|
||||||
void DelimitedOutput(string);
|
void DelimitedOutput(string);
|
||||||
void SocketOutput(void);
|
void SocketOutput(void);
|
||||||
void SocketStatusOutput(string);
|
void SocketStatusOutput(string);
|
||||||
void SetFilename(string fn) {Filename = fn;}
|
|
||||||
void SetType(string);
|
void SetType(string);
|
||||||
void SetSubsystems(int tt) {SubSystems = tt;}
|
void SetSubsystems(int tt) {SubSystems = tt;}
|
||||||
inline void Enable(void) { enabled = true; }
|
inline void Enable(void) { enabled = true; }
|
||||||
inline void Disable(void) { enabled = false; }
|
inline void Disable(void) { enabled = false; }
|
||||||
inline bool Toggle(void) {enabled = !enabled; return enabled;}
|
inline bool Toggle(void) {enabled = !enabled; return enabled;}
|
||||||
bool Load(FGConfigFile* AC_cfg);
|
bool Load(Element* el);
|
||||||
|
|
||||||
/// Subsystem types for specifying which will be output in the FDM data logging
|
/// Subsystem types for specifying which will be output in the FDM data logging
|
||||||
enum eSubSystems {
|
enum eSubSystems {
|
||||||
|
@ -161,7 +161,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool sFirstPass, dFirstPass, enabled;
|
bool sFirstPass, dFirstPass, enabled;
|
||||||
int SubSystems;
|
int SubSystems;
|
||||||
string Filename, outputInFileName, delimeter;
|
string output_file_name, delimeter, Filename;
|
||||||
enum {otNone, otCSV, otTab, otSocket, otTerminal, otUnknown} Type;
|
enum {otNone, otCSV, otTab, otSocket, otTerminal, otUnknown} Type;
|
||||||
ofstream datafile;
|
ofstream datafile;
|
||||||
FGfdmSocket* socket;
|
FGfdmSocket* socket;
|
|
@ -53,10 +53,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FGFS
|
#ifdef FGFS
|
||||||
# include <simgear/compiler.h>
|
# include <simgear/compiler.h>
|
||||||
# ifdef SG_HAVE_STD_INCLUDES
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
@ -81,12 +77,12 @@ INCLUDES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "FGPropagate.h"
|
#include "FGPropagate.h"
|
||||||
#include "FGState.h"
|
#include <FGState.h>
|
||||||
#include "FGFDMExec.h"
|
#include <FGFDMExec.h>
|
||||||
#include "FGAircraft.h"
|
#include "FGAircraft.h"
|
||||||
#include "FGMassBalance.h"
|
#include "FGMassBalance.h"
|
||||||
#include "FGInertial.h"
|
#include "FGInertial.h"
|
||||||
#include "FGPropertyManager.h"
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -157,7 +153,7 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
|
||||||
// Compute some derived values.
|
// Compute some derived values.
|
||||||
vVel = VState.vQtrn.GetTInv()*VState.vUVW;
|
vVel = VState.vQtrn.GetTInv()*VState.vUVW;
|
||||||
|
|
||||||
// Finaly make shure that the quaternion stays normalized.
|
// Finally, make sure that the quaternion stays normalized.
|
||||||
VState.vQtrn.Normalize();
|
VState.vQtrn.Normalize();
|
||||||
|
|
||||||
// Recompute the RunwayRadius level.
|
// Recompute the RunwayRadius level.
|
||||||
|
@ -183,6 +179,7 @@ state values for (now + dt).
|
||||||
bool FGPropagate::Run(void)
|
bool FGPropagate::Run(void)
|
||||||
{
|
{
|
||||||
if (FGModel::Run()) return true; // Fast return if we have nothing to do ...
|
if (FGModel::Run()) return true; // Fast return if we have nothing to do ...
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
RecomputeRunwayRadius();
|
RecomputeRunwayRadius();
|
||||||
|
|
||||||
|
@ -224,9 +221,11 @@ bool FGPropagate::Run(void)
|
||||||
FGColumnVector3 ace = 2.0*omega*ecVel;
|
FGColumnVector3 ace = 2.0*omega*ecVel;
|
||||||
vUVWdot -= Tl2b*(Tec2l*ace);
|
vUVWdot -= Tl2b*(Tec2l*ace);
|
||||||
|
|
||||||
// Centrifugal acceleration.
|
if (!GroundReactions->GetWOW()) {
|
||||||
FGColumnVector3 aeec = omega*(omega*VState.vLocation);
|
// Centrifugal acceleration.
|
||||||
vUVWdot -= Tl2b*(Tec2l*aeec);
|
FGColumnVector3 aeec = omega*(omega*VState.vLocation);
|
||||||
|
vUVWdot -= Tl2b*(Tec2l*aeec);
|
||||||
|
}
|
||||||
|
|
||||||
// Gravitation accel
|
// Gravitation accel
|
||||||
vUVWdot += Tl2b*gAccel;
|
vUVWdot += Tl2b*gAccel;
|
||||||
|
@ -257,8 +256,6 @@ bool FGPropagate::Run(void)
|
||||||
void FGPropagate::RecomputeRunwayRadius(void)
|
void FGPropagate::RecomputeRunwayRadius(void)
|
||||||
{
|
{
|
||||||
// Get the runway radius.
|
// Get the runway radius.
|
||||||
// Boring: this does not belong here, but since Jon placed the RunwayRadius
|
|
||||||
// value here it is better done here than somewhere else.
|
|
||||||
FGLocation contactloc;
|
FGLocation contactloc;
|
||||||
FGColumnVector3 dv;
|
FGColumnVector3 dv;
|
||||||
FGGroundCallback* gcb = FDMExec->GetGroundCallback();
|
FGGroundCallback* gcb = FDMExec->GetGroundCallback();
|
|
@ -38,11 +38,11 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGModel.h"
|
#include <models/FGModel.h>
|
||||||
#include "FGColumnVector3.h"
|
#include <math/FGColumnVector3.h>
|
||||||
#include "FGInitialCondition.h"
|
#include <initialization/FGInitialCondition.h>
|
||||||
#include "FGLocation.h"
|
#include <math/FGLocation.h>
|
||||||
#include "FGQuaternion.h"
|
#include <math/FGQuaternion.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -142,7 +142,6 @@ public:
|
||||||
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
|
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
|
||||||
void SetDistanceAGL(double tt);
|
void SetDistanceAGL(double tt);
|
||||||
void SetInitialState(const FGInitialCondition *);
|
void SetInitialState(const FGInitialCondition *);
|
||||||
|
|
||||||
void RecomputeRunwayRadius(void);
|
void RecomputeRunwayRadius(void);
|
||||||
|
|
||||||
void bind(void);
|
void bind(void);
|
|
@ -44,16 +44,15 @@ HISTORY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGPropulsion.h"
|
#include "FGPropulsion.h"
|
||||||
#include "FGRocket.h"
|
#include <models/propulsion/FGRocket.h>
|
||||||
#include "FGTurbine.h"
|
#include <models/propulsion/FGTurbine.h>
|
||||||
#include "FGPiston.h"
|
#include <models/propulsion/FGPiston.h>
|
||||||
#include "FGElectric.h"
|
#include <models/propulsion/FGElectric.h>
|
||||||
#include "FGPropertyManager.h"
|
#include <models/propulsion/FGTurboProp.h>
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
#include <input_output/FGXMLParse.h>
|
||||||
|
#include <math/FGColumnVector3.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -79,8 +78,13 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
|
||||||
tankJ.InitMatrix();
|
tankJ.InitMatrix();
|
||||||
refuel = false;
|
refuel = false;
|
||||||
fuel_freeze = false;
|
fuel_freeze = false;
|
||||||
|
TotalFuelQuantity = 0.0;
|
||||||
bind();
|
IsBound =
|
||||||
|
HavePistonEngine =
|
||||||
|
HaveTurbineEngine =
|
||||||
|
HaveRocketEngine =
|
||||||
|
HaveTurboPropEngine =
|
||||||
|
HaveElectricEngine = false;
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
@ -102,6 +106,7 @@ bool FGPropulsion::Run(void)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (FGModel::Run()) return true;
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
double dt = State->Getdt();
|
double dt = State->Getdt();
|
||||||
|
|
||||||
|
@ -114,12 +119,16 @@ bool FGPropulsion::Run(void)
|
||||||
vMoments += Engines[i]->GetMoments(); // sum body frame moments
|
vMoments += Engines[i]->GetMoments(); // sum body frame moments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TotalFuelQuantity = 0.0;
|
||||||
for (i=0; i<numTanks; i++) {
|
for (i=0; i<numTanks; i++) {
|
||||||
Tanks[i]->Calculate( dt * rate );
|
Tanks[i]->Calculate( dt * rate );
|
||||||
|
if (Tanks[i]->GetType() == FGTank::ttFUEL) {
|
||||||
|
TotalFuelQuantity += Tanks[i]->GetContents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refuel) DoRefuel( dt * rate );
|
if (refuel) DoRefuel( dt * rate );
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,139 +196,80 @@ bool FGPropulsion::ICEngineStart(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGPropulsion::Load(FGConfigFile* AC_cfg)
|
bool FGPropulsion::Load(Element* el)
|
||||||
{
|
{
|
||||||
string token, fullpath, localpath;
|
string type, engine_filename;
|
||||||
string engineFileName, engType;
|
|
||||||
string parameter;
|
|
||||||
string enginePath = FDMExec->GetEnginePath();
|
|
||||||
string aircraftPath = FDMExec->GetAircraftPath();
|
|
||||||
double xLoc, yLoc, zLoc, Pitch, Yaw;
|
|
||||||
int Feed;
|
int Feed;
|
||||||
bool ThrottleAdded = false;
|
bool ThrottleAdded = false;
|
||||||
FGConfigFile* Cfg_ptr = 0;
|
Element* document;
|
||||||
|
FGXMLParse engine_file_parser;
|
||||||
|
ifstream* engine_file;
|
||||||
|
|
||||||
# ifndef macintosh
|
Debug(2);
|
||||||
fullpath = enginePath + "/";
|
|
||||||
localpath = aircraftPath + "/Engines/";
|
|
||||||
# else
|
|
||||||
fullpath = enginePath + ";";
|
|
||||||
localpath = aircraftPath + ";Engines;";
|
|
||||||
# endif
|
|
||||||
|
|
||||||
AC_cfg->GetNextConfigLine();
|
Element* engine_element = el->FindElement("engine");
|
||||||
|
while (engine_element) {
|
||||||
|
engine_filename = engine_element->GetAttributeValue("file");
|
||||||
|
|
||||||
while ((token = AC_cfg->GetValue()) != string("/PROPULSION")) {
|
if (engine_filename.empty()) {
|
||||||
|
cerr << "Engine definition did not supply an engine file." << endl;
|
||||||
if (token == "AC_ENGINE") { // ============ READING ENGINES
|
return false;
|
||||||
|
|
||||||
engineFileName = AC_cfg->GetValue("FILE");
|
|
||||||
|
|
||||||
// Look in the Aircraft/Engines directory first
|
|
||||||
Cfg_ptr = 0;
|
|
||||||
FGConfigFile Local_cfg(localpath + engineFileName + ".xml");
|
|
||||||
FGConfigFile Eng_cfg(fullpath + engineFileName + ".xml");
|
|
||||||
if (Local_cfg.IsOpen()) {
|
|
||||||
Cfg_ptr = &Local_cfg;
|
|
||||||
if (debug_lvl > 0) cout << "\n Reading engine from file: " << localpath
|
|
||||||
+ engineFileName + ".xml"<< endl;
|
|
||||||
} else {
|
|
||||||
if (Eng_cfg.IsOpen()) {
|
|
||||||
Cfg_ptr = &Eng_cfg;
|
|
||||||
if (debug_lvl > 0) cout << "\n Reading engine from file: " << fullpath
|
|
||||||
+ engineFileName + ".xml"<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cfg_ptr) {
|
|
||||||
Cfg_ptr->GetNextConfigLine();
|
|
||||||
engType = Cfg_ptr->GetValue();
|
|
||||||
|
|
||||||
FCS->AddThrottle();
|
|
||||||
ThrottleAdded = true;
|
|
||||||
|
|
||||||
if (engType == "FG_ROCKET") {
|
|
||||||
Engines.push_back(new FGRocket(FDMExec, Cfg_ptr, numEngines));
|
|
||||||
} else if (engType == "FG_PISTON") {
|
|
||||||
Engines.push_back(new FGPiston(FDMExec, Cfg_ptr, numEngines));
|
|
||||||
} else if (engType == "FG_TURBINE") {
|
|
||||||
Engines.push_back(new FGTurbine(FDMExec, Cfg_ptr, numEngines));
|
|
||||||
} else if (engType == "FG_SIMTURBINE") {
|
|
||||||
cerr << endl;
|
|
||||||
cerr << "The FG_SIMTURBINE engine type has been renamed to FG_TURBINE." << endl;
|
|
||||||
cerr << "To fix this problem, simply replace the FG_SIMTURBINE name " << endl;
|
|
||||||
cerr << "in your engine file to FG_TURBINE." << endl;
|
|
||||||
cerr << endl;
|
|
||||||
Engines.push_back(new FGTurbine(FDMExec, Cfg_ptr, numEngines));
|
|
||||||
} else if (engType == "FG_ELECTRIC") {
|
|
||||||
Engines.push_back(new FGElectric(FDMExec, Cfg_ptr, numEngines));
|
|
||||||
} else {
|
|
||||||
cerr << fgred << " Unrecognized engine type: " << underon << engType
|
|
||||||
<< underoff << " found in config file." << fgdef << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Engines.back()->SetEngineFileName(engineFileName);
|
|
||||||
|
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
while ((token = AC_cfg->GetValue()) != string("/AC_ENGINE")) {
|
|
||||||
*AC_cfg >> token;
|
|
||||||
if (token == "XLOC") { *AC_cfg >> xLoc; }
|
|
||||||
else if (token == "YLOC") { *AC_cfg >> yLoc; }
|
|
||||||
else if (token == "ZLOC") { *AC_cfg >> zLoc; }
|
|
||||||
else if (token == "PITCH") { *AC_cfg >> Pitch;}
|
|
||||||
else if (token == "YAW") { *AC_cfg >> Yaw; }
|
|
||||||
else if (token.find("AC_THRUSTER") != string::npos) {
|
|
||||||
if (debug_lvl > 0) cout << "\n Reading thruster definition" << endl;
|
|
||||||
Engines.back()->LoadThruster(AC_cfg);
|
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
}
|
|
||||||
else if (token == "FEED") {
|
|
||||||
*AC_cfg >> Feed;
|
|
||||||
Engines[numEngines]->AddFeedTank(Feed);
|
|
||||||
if (debug_lvl > 0) cout << " Feed tank: " << Feed << endl;
|
|
||||||
} else cerr << "Unknown identifier: " << token << " in engine file: "
|
|
||||||
<< engineFileName << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_lvl > 0) {
|
|
||||||
cout << " X = " << xLoc << endl;
|
|
||||||
cout << " Y = " << yLoc << endl;
|
|
||||||
cout << " Z = " << zLoc << endl;
|
|
||||||
cout << " Pitch = " << Pitch << endl;
|
|
||||||
cout << " Yaw = " << Yaw << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
|
|
||||||
numEngines++;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
cerr << fgred << "\n Could not read engine config file: " << underon <<
|
|
||||||
engineFileName + ".xml" << underoff << fgdef << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (token == "AC_TANK") { // ============== READING TANKS
|
|
||||||
|
|
||||||
if (debug_lvl > 0) cout << "\n Reading tank definition" << endl;
|
|
||||||
Tanks.push_back(new FGTank(AC_cfg, FDMExec));
|
|
||||||
switch(Tanks[numTanks]->GetType()) {
|
|
||||||
case FGTank::ttFUEL:
|
|
||||||
numSelectedFuelTanks++;
|
|
||||||
numFuelTanks++;
|
|
||||||
break;
|
|
||||||
case FGTank::ttOXIDIZER:
|
|
||||||
numSelectedOxiTanks++;
|
|
||||||
numOxiTanks++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
numTanks++;
|
|
||||||
}
|
}
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
|
engine_filename = FindEngineFullPathname(engine_filename);
|
||||||
|
readXML(engine_filename, engine_file_parser);
|
||||||
|
document = engine_file_parser.GetDocument(); // document holds the engine description
|
||||||
|
document->SetParent(engine_element);
|
||||||
|
|
||||||
|
type = document->GetName();
|
||||||
|
if (type == "piston_engine") {
|
||||||
|
HavePistonEngine = true;
|
||||||
|
if (!IsBound) bind();
|
||||||
|
Engines.push_back(new FGPiston(FDMExec, document, numEngines));
|
||||||
|
} else if (type == "turbine_engine") {
|
||||||
|
HaveTurbineEngine = true;
|
||||||
|
if (!IsBound) bind();
|
||||||
|
Engines.push_back(new FGTurbine(FDMExec, document, numEngines));
|
||||||
|
} else if (type == "turboprop_engine") {
|
||||||
|
HaveTurboPropEngine = true;
|
||||||
|
if (!IsBound) bind();
|
||||||
|
Engines.push_back(new FGTurboProp(FDMExec, document, numEngines));
|
||||||
|
} else if (type == "rocket_engine") {
|
||||||
|
HaveRocketEngine = true;
|
||||||
|
if (!IsBound) bind();
|
||||||
|
Engines.push_back(new FGRocket(FDMExec, document, numEngines));
|
||||||
|
} else if (type == "electric_engine") {
|
||||||
|
HaveElectricEngine = true;
|
||||||
|
if (!IsBound) bind();
|
||||||
|
Engines.push_back(new FGElectric(FDMExec, document, numEngines));
|
||||||
|
} else {
|
||||||
|
cerr << "Unknown engine type: " << type << endl;
|
||||||
|
exit(-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
FCS->AddThrottle();
|
||||||
|
ThrottleAdded = true;
|
||||||
|
|
||||||
|
numEngines++;
|
||||||
|
|
||||||
|
engine_element = el->FindNextElement("engine");
|
||||||
|
engine_file_parser.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process tank definitions
|
||||||
|
|
||||||
|
Element* tank_element = el->FindElement("tank");
|
||||||
|
while (tank_element) {
|
||||||
|
Tanks.push_back(new FGTank(FDMExec, tank_element));
|
||||||
|
if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++;
|
||||||
|
else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++;
|
||||||
|
else {cerr << "Unknown tank type specified." << endl; return false;}
|
||||||
|
numTanks++;
|
||||||
|
tank_element = el->FindNextElement("tank");
|
||||||
|
}
|
||||||
|
numSelectedFuelTanks = numFuelTanks;
|
||||||
|
numSelectedOxiTanks = numOxiTanks;
|
||||||
|
|
||||||
CalculateTankInertias();
|
CalculateTankInertias();
|
||||||
if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle
|
if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle
|
||||||
|
|
||||||
|
@ -328,6 +278,65 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
string FGPropulsion::FindEngineFullPathname(string engine_filename)
|
||||||
|
{
|
||||||
|
string fullpath, localpath;
|
||||||
|
string enginePath = FDMExec->GetEnginePath();
|
||||||
|
string aircraftPath = FDMExec->GetAircraftPath();
|
||||||
|
ifstream* engine_file = new ifstream();
|
||||||
|
|
||||||
|
string separator = "/";
|
||||||
|
# ifdef macintosh
|
||||||
|
separator = ";";
|
||||||
|
# endif
|
||||||
|
|
||||||
|
fullpath = enginePath + separator;
|
||||||
|
localpath = aircraftPath + separator + "Engines" + separator;
|
||||||
|
|
||||||
|
engine_file->open(string(fullpath + engine_filename + ".xml").c_str());
|
||||||
|
if ( !engine_file->is_open()) {
|
||||||
|
engine_file->open(string(localpath + engine_filename + ".xml").c_str());
|
||||||
|
if ( !engine_file->is_open()) {
|
||||||
|
cerr << " Could not open engine file: " << engine_filename << " in path "
|
||||||
|
<< fullpath << " or " << localpath << endl;
|
||||||
|
return string("");
|
||||||
|
} else {
|
||||||
|
return string(localpath + engine_filename + ".xml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(fullpath + engine_filename + ".xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
ifstream* FGPropulsion::FindEngineFile(string engine_filename)
|
||||||
|
{
|
||||||
|
string fullpath, localpath;
|
||||||
|
string enginePath = FDMExec->GetEnginePath();
|
||||||
|
string aircraftPath = FDMExec->GetAircraftPath();
|
||||||
|
ifstream* engine_file = new ifstream();
|
||||||
|
|
||||||
|
string separator = "/";
|
||||||
|
# ifdef macintosh
|
||||||
|
separator = ";";
|
||||||
|
# endif
|
||||||
|
|
||||||
|
fullpath = enginePath + separator;
|
||||||
|
localpath = aircraftPath + separator + "Engines" + separator;
|
||||||
|
|
||||||
|
engine_file->open(string(fullpath + engine_filename + ".xml").c_str());
|
||||||
|
if ( !engine_file->is_open()) {
|
||||||
|
engine_file->open(string(localpath + engine_filename + ".xml").c_str());
|
||||||
|
if ( !engine_file->is_open()) {
|
||||||
|
cerr << " Could not open engine file: " << engine_filename << " in path "
|
||||||
|
<< fullpath << " or " << localpath << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return engine_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
string FGPropulsion::GetPropulsionStrings(string delimeter)
|
string FGPropulsion::GetPropulsionStrings(string delimeter)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -427,6 +436,9 @@ void FGPropulsion::SetMagnetos(int setting)
|
||||||
{
|
{
|
||||||
if (ActiveEngine < 0) {
|
if (ActiveEngine < 0) {
|
||||||
for (unsigned i=0; i<Engines.size(); i++) {
|
for (unsigned i=0; i<Engines.size(); i++) {
|
||||||
|
// ToDo: first need to make sure the engine Type is really appropriate:
|
||||||
|
// do a check to see if it is of type Piston. This should be done for
|
||||||
|
// all of this kind of possibly across-the-board settings.
|
||||||
((FGPiston*)Engines[i])->SetMagnetos(setting);
|
((FGPiston*)Engines[i])->SetMagnetos(setting);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -505,15 +517,17 @@ double FGPropulsion::Transfer(int source, int target, double amount)
|
||||||
|
|
||||||
void FGPropulsion::DoRefuel(double time_slice)
|
void FGPropulsion::DoRefuel(double time_slice)
|
||||||
{
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
double fillrate = 100 * time_slice; // 100 lbs/sec = 6000 lbs/min
|
double fillrate = 100 * time_slice; // 100 lbs/sec = 6000 lbs/min
|
||||||
int TanksNotFull = 0;
|
int TanksNotFull = 0;
|
||||||
|
|
||||||
for (unsigned int i=0; i<numTanks; i++) {
|
for (i=0; i<numTanks; i++) {
|
||||||
if (Tanks[i]->GetPctFull() < 99.99) ++TanksNotFull;
|
if (Tanks[i]->GetPctFull() < 99.99) ++TanksNotFull;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TanksNotFull) {
|
if (TanksNotFull) {
|
||||||
for (unsigned int i=0; i<numTanks; i++) {
|
for (i=0; i<numTanks; i++) {
|
||||||
if (Tanks[i]->GetPctFull() < 99.99)
|
if (Tanks[i]->GetPctFull() < 99.99)
|
||||||
Transfer(-1, i, fillrate/TanksNotFull);
|
Transfer(-1, i, fillrate/TanksNotFull);
|
||||||
}
|
}
|
||||||
|
@ -522,14 +536,14 @@ void FGPropulsion::DoRefuel(double time_slice)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGPropulsion::SetFuelFreeze(bool f)
|
void FGPropulsion::SetFuelFreeze(bool f)
|
||||||
{
|
{
|
||||||
fuel_freeze = f;
|
fuel_freeze = f;
|
||||||
for (unsigned int i=0; i<numEngines; i++) {
|
for (unsigned int i=0; i<numEngines; i++) {
|
||||||
Engines[i]->SetFuelFreeze(f);
|
Engines[i]->SetFuelFreeze(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGPropulsion::bind(void)
|
void FGPropulsion::bind(void)
|
||||||
|
@ -537,44 +551,37 @@ void FGPropulsion::bind(void)
|
||||||
typedef double (FGPropulsion::*PMF)(int) const;
|
typedef double (FGPropulsion::*PMF)(int) const;
|
||||||
typedef int (FGPropulsion::*iPMF)(void) const;
|
typedef int (FGPropulsion::*iPMF)(void) const;
|
||||||
|
|
||||||
PropertyManager->Tie("propulsion/magneto_cmd", this,
|
IsBound = true;
|
||||||
(iPMF)0, &FGPropulsion::SetMagnetos, true);
|
|
||||||
PropertyManager->Tie("propulsion/starter_cmd", this,
|
|
||||||
(iPMF)0, &FGPropulsion::SetStarter, true);
|
|
||||||
PropertyManager->Tie("propulsion/cutoff_cmd", this,
|
|
||||||
(iPMF)0, &FGPropulsion::SetCutoff, true);
|
|
||||||
|
|
||||||
PropertyManager->Tie("forces/fbx-prop-lbs", this,1,
|
if (HaveTurbineEngine) {
|
||||||
(PMF)&FGPropulsion::GetForces);
|
PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, true);
|
||||||
PropertyManager->Tie("forces/fby-prop-lbs", this,2,
|
PropertyManager->Tie("propulsion/cutoff_cmd", this, (iPMF)0, &FGPropulsion::SetCutoff, true);
|
||||||
(PMF)&FGPropulsion::GetForces);
|
}
|
||||||
PropertyManager->Tie("forces/fbz-prop-lbs", this,3,
|
|
||||||
(PMF)&FGPropulsion::GetForces);
|
|
||||||
PropertyManager->Tie("moments/l-prop-lbsft", this,1,
|
|
||||||
(PMF)&FGPropulsion::GetMoments);
|
|
||||||
PropertyManager->Tie("moments/m-prop-lbsft", this,2,
|
|
||||||
(PMF)&FGPropulsion::GetMoments);
|
|
||||||
PropertyManager->Tie("moments/n-prop-lbsft", this,3,
|
|
||||||
(PMF)&FGPropulsion::GetMoments);
|
|
||||||
|
|
||||||
PropertyManager->Tie("propulsion/active_engine", this,
|
if (HavePistonEngine) {
|
||||||
(iPMF)&FGPropulsion::GetActiveEngine, &FGPropulsion::SetActiveEngine, true);
|
PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, true);
|
||||||
|
PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyManager->Tie("propulsion/active_engine", this, (iPMF)&FGPropulsion::GetActiveEngine,
|
||||||
|
&FGPropulsion::SetActiveEngine, true);
|
||||||
|
PropertyManager->Tie("propulsion/total-fuel-lbs", this, &FGPropulsion::GetTotalFuelQuantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGPropulsion::unbind(void)
|
void FGPropulsion::unbind(void)
|
||||||
{
|
{
|
||||||
PropertyManager->Untie("propulsion/magneto_cmd");
|
if (HaveTurbineEngine) {
|
||||||
PropertyManager->Untie("propulsion/starter_cmd");
|
PropertyManager->Untie("propulsion/starter_cmd");
|
||||||
PropertyManager->Untie("propulsion/cutoff_cmd");
|
PropertyManager->Untie("propulsion/cutoff_cmd");
|
||||||
|
}
|
||||||
|
if (HavePistonEngine) {
|
||||||
|
PropertyManager->Untie("propulsion/starter_cmd");
|
||||||
|
PropertyManager->Untie("propulsion/magneto_cmd");
|
||||||
|
}
|
||||||
PropertyManager->Untie("propulsion/active_engine");
|
PropertyManager->Untie("propulsion/active_engine");
|
||||||
PropertyManager->Untie("forces/fbx-prop-lbs");
|
PropertyManager->Untie("propulsion/total-fuel-lbs");
|
||||||
PropertyManager->Untie("forces/fby-prop-lbs");
|
|
||||||
PropertyManager->Untie("forces/fbz-prop-lbs");
|
|
||||||
PropertyManager->Untie("moments/l-prop-lbsft");
|
|
||||||
PropertyManager->Untie("moments/m-prop-lbsft");
|
|
||||||
PropertyManager->Untie("moments/n-prop-lbsft");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -601,8 +608,8 @@ void FGPropulsion::Debug(int from)
|
||||||
if (debug_lvl <= 0) return;
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
if (debug_lvl & 1) { // Standard console startup message output
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
if (from == 0) { // Constructor
|
if (from == 2) { // Loader
|
||||||
|
cout << endl << " Propulsion:" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
|
@ -43,19 +43,23 @@ INCLUDES
|
||||||
# ifdef SG_HAVE_STD_INCLUDES
|
# ifdef SG_HAVE_STD_INCLUDES
|
||||||
# include <vector>
|
# include <vector>
|
||||||
# include <iterator>
|
# include <iterator>
|
||||||
|
# include <fstream>
|
||||||
# else
|
# else
|
||||||
# include <vector.h>
|
# include <vector.h>
|
||||||
# include <iterator.h>
|
# include <iterator.h>
|
||||||
|
# include <fstream.h>
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# include <vector>
|
# include <vector>
|
||||||
# include <iterator>
|
# include <iterator>
|
||||||
|
# include <fstream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "FGModel.h"
|
#include "FGModel.h"
|
||||||
#include "FGEngine.h"
|
#include <models/propulsion/FGEngine.h>
|
||||||
#include "FGTank.h"
|
#include <models/propulsion/FGTank.h>
|
||||||
#include "FGMatrix33.h"
|
#include <math/FGMatrix33.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -110,10 +114,9 @@ public:
|
||||||
|
|
||||||
/** Loads the propulsion system (engine[s] and tank[s]).
|
/** Loads the propulsion system (engine[s] and tank[s]).
|
||||||
Characteristics of the propulsion system are read in from the config file.
|
Characteristics of the propulsion system are read in from the config file.
|
||||||
@param AC_cfg pointer to the config file instance that describes the
|
@param el pointer to an XML element that contains the engine information.
|
||||||
aircraft being modeled.
|
|
||||||
@return true if successfully loaded, otherwise false */
|
@return true if successfully loaded, otherwise false */
|
||||||
bool Load(FGConfigFile* AC_cfg);
|
bool Load(Element* el);
|
||||||
|
|
||||||
/// Retrieves the number of engines defined for the aircraft.
|
/// Retrieves the number of engines defined for the aircraft.
|
||||||
inline unsigned int GetNumEngines(void) const {return Engines.size();}
|
inline unsigned int GetNumEngines(void) const {return Engines.size();}
|
||||||
|
@ -159,26 +162,24 @@ public:
|
||||||
inline double GetMoments(int n) const {return vMoments(n);}
|
inline double GetMoments(int n) const {return vMoments(n);}
|
||||||
|
|
||||||
inline bool GetRefuel(void) {return refuel;}
|
inline bool GetRefuel(void) {return refuel;}
|
||||||
inline void SetRefuel(bool setting) {refuel = setting;}
|
inline void SetRefuel(bool setting) {refuel = setting;}
|
||||||
double Transfer(int source, int target, double amount);
|
double Transfer(int source, int target, double amount);
|
||||||
void DoRefuel(double time_slice);
|
void DoRefuel(double time_slice);
|
||||||
|
|
||||||
FGColumnVector3& GetTanksMoment(void);
|
FGColumnVector3& GetTanksMoment(void);
|
||||||
double GetTanksWeight(void);
|
double GetTanksWeight(void);
|
||||||
|
|
||||||
inline int GetActiveEngine(void) const
|
ifstream* FindEngineFile(string filename);
|
||||||
{
|
string FindEngineFullPathname(string engine_filename);
|
||||||
return ActiveEngine;
|
inline int GetActiveEngine(void) const {return ActiveEngine;}
|
||||||
}
|
|
||||||
|
|
||||||
inline int GetActiveEngine(void);
|
|
||||||
inline bool GetFuelFreeze(void) {return fuel_freeze;}
|
inline bool GetFuelFreeze(void) {return fuel_freeze;}
|
||||||
|
double GetTotalFuelQuantity(void) const {return TotalFuelQuantity;}
|
||||||
|
|
||||||
void SetMagnetos(int setting);
|
void SetMagnetos(int setting);
|
||||||
void SetStarter(int setting);
|
void SetStarter(int setting);
|
||||||
void SetCutoff(int setting=0);
|
void SetCutoff(int setting=0);
|
||||||
void SetActiveEngine(int engine);
|
void SetActiveEngine(int engine);
|
||||||
void SetFuelFreeze(bool f);
|
void SetFuelFreeze(bool f);
|
||||||
FGMatrix33& CalculateTankInertias(void);
|
FGMatrix33& CalculateTankInertias(void);
|
||||||
|
|
||||||
void bind();
|
void bind();
|
||||||
|
@ -202,6 +203,13 @@ private:
|
||||||
FGMatrix33 tankJ;
|
FGMatrix33 tankJ;
|
||||||
bool refuel;
|
bool refuel;
|
||||||
bool fuel_freeze;
|
bool fuel_freeze;
|
||||||
|
double TotalFuelQuantity;
|
||||||
|
bool IsBound;
|
||||||
|
bool HavePistonEngine;
|
||||||
|
bool HaveTurbineEngine;
|
||||||
|
bool HaveTurboPropEngine;
|
||||||
|
bool HaveRocketEngine;
|
||||||
|
bool HaveElectricEngine;
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
14
src/FDM/JSBSim/models/Makefile.am
Normal file
14
src/FDM/JSBSim/models/Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
SUBDIRS = atmosphere propulsion flight_control
|
||||||
|
|
||||||
|
noinst_LIBRARIES = libModels.a
|
||||||
|
|
||||||
|
libModels_a_SOURCES = FGAerodynamics.cpp FGAircraft.cpp FGAtmosphere.cpp \
|
||||||
|
FGAuxiliary.cpp FGFCS.cpp FGGroundReactions.cpp FGInertial.cpp \
|
||||||
|
FGLGear.cpp FGMassBalance.cpp FGModel.cpp FGOutput.cpp \
|
||||||
|
FGPropagate.cpp FGPropulsion.cpp FGInput.cpp
|
||||||
|
|
||||||
|
noinst_HEADERS = FGAerodynamics.h FGAircraft.h FGAtmosphere.h FGAuxiliary.h \
|
||||||
|
FGFCS.h FGGroundReactions.h FGInertial.h FGLGear.h FGMassBalance.h \
|
||||||
|
FGModel.h FGOutput.h FGPropagate.h FGPropulsion.h FGInput.h
|
||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
|
1667
src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
Executable file
1667
src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
Executable file
File diff suppressed because it is too large
Load diff
209
src/FDM/JSBSim/models/atmosphere/FGMSIS.h
Executable file
209
src/FDM/JSBSim/models/atmosphere/FGMSIS.h
Executable file
|
@ -0,0 +1,209 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGMSIS.h
|
||||||
|
Description: MSIS-00 Atmosphere
|
||||||
|
Author: David Culp
|
||||||
|
Date started: 12/14/03
|
||||||
|
|
||||||
|
------------- Copyright (C) 2003 David P. Culp (davidculp2@comcast.net) ------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
12/14/03 DPC Created
|
||||||
|
01/11/04 DPC Derive from FGAtmosphere
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGMSIS_H
|
||||||
|
#define FGMSIS_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <models/FGAtmosphere.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_MSIS "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Models the MSIS-00 atmosphere.
|
||||||
|
This is a wrapper for the NRL-MSIS-00 model 2001:
|
||||||
|
|
||||||
|
This C++ format model wraps the NRLMSISE-00 C source code package - release
|
||||||
|
20020503
|
||||||
|
|
||||||
|
The NRLMSISE-00 model was developed by Mike Picone, Alan Hedin, and
|
||||||
|
Doug Drob. They also wrote a NRLMSISE-00 distribution package in
|
||||||
|
FORTRAN which is available at
|
||||||
|
http://uap-www.nrl.navy.mil/models_web/msis/msis_home.htm
|
||||||
|
|
||||||
|
Dominik Brodowski implemented and maintains this C version. You can
|
||||||
|
reach him at devel@brodo.de. See the file "DOCUMENTATION" for details,
|
||||||
|
and check http://www.brodo.de/english/pub/nrlmsise/index.html for
|
||||||
|
updated releases of this package.
|
||||||
|
@author David Culp
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
STRUCT DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
struct nrlmsise_flags {
|
||||||
|
int switches[24];
|
||||||
|
double sw[24];
|
||||||
|
double swc[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ap_array {
|
||||||
|
double a[7];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nrlmsise_input {
|
||||||
|
int year; /* year, currently ignored */
|
||||||
|
int doy; /* day of year */
|
||||||
|
double sec; /* seconds in day (UT) */
|
||||||
|
double alt; /* altitude in kilometers */
|
||||||
|
double g_lat; /* geodetic latitude */
|
||||||
|
double g_long; /* geodetic longitude */
|
||||||
|
double lst; /* local apparent solar time (hours), see note below */
|
||||||
|
double f107A; /* 81 day average of F10.7 flux (centered on DOY) */
|
||||||
|
double f107; /* daily F10.7 flux for previous day */
|
||||||
|
double ap; /* magnetic index(daily) */
|
||||||
|
struct ap_array *ap_a; /* see above */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nrlmsise_output {
|
||||||
|
double d[9]; /* densities */
|
||||||
|
double t[2]; /* temperatures */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class MSIS : public FGAtmosphere
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
MSIS(FGFDMExec*);
|
||||||
|
/// Destructor
|
||||||
|
~MSIS();
|
||||||
|
/** Runs the MSIS-00 atmosphere model; called by the Executive
|
||||||
|
@return false if no error */
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
bool InitModel(void);
|
||||||
|
|
||||||
|
/// Does nothing. External control is not allowed.
|
||||||
|
void UseExternal(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void Calculate(int day, // day of year (1 to 366)
|
||||||
|
double sec, // seconds in day (0.0 to 86400.0)
|
||||||
|
double alt, // altitude, feet
|
||||||
|
double lat, // geodetic latitude, degrees
|
||||||
|
double lon // geodetic longitude, degrees
|
||||||
|
);
|
||||||
|
|
||||||
|
void Debug(int from);
|
||||||
|
|
||||||
|
nrlmsise_flags flags;
|
||||||
|
nrlmsise_input input;
|
||||||
|
nrlmsise_output output;
|
||||||
|
ap_array aph;
|
||||||
|
|
||||||
|
/* PARMB */
|
||||||
|
double gsurf;
|
||||||
|
double re;
|
||||||
|
|
||||||
|
/* GTS3C */
|
||||||
|
double dd;
|
||||||
|
|
||||||
|
/* DMIX */
|
||||||
|
double dm04, dm16, dm28, dm32, dm40, dm01, dm14;
|
||||||
|
|
||||||
|
/* MESO7 */
|
||||||
|
double meso_tn1[5];
|
||||||
|
double meso_tn2[4];
|
||||||
|
double meso_tn3[3];
|
||||||
|
double meso_tgn1[2];
|
||||||
|
double meso_tgn2[2];
|
||||||
|
double meso_tgn3[2];
|
||||||
|
|
||||||
|
/* LPOLY */
|
||||||
|
double dfa;
|
||||||
|
double plg[4][9];
|
||||||
|
double ctloc, stloc;
|
||||||
|
double c2tloc, s2tloc;
|
||||||
|
double s3tloc, c3tloc;
|
||||||
|
double apdf, apt[4];
|
||||||
|
|
||||||
|
void tselec(struct nrlmsise_flags *flags);
|
||||||
|
void glatf(double lat, double *gv, double *reff);
|
||||||
|
double ccor(double alt, double r, double h1, double zh);
|
||||||
|
double ccor2(double alt, double r, double h1, double zh, double h2);
|
||||||
|
double scalh(double alt, double xm, double temp);
|
||||||
|
double dnet(double dd, double dm, double zhm, double xmm, double xm);
|
||||||
|
void splini(double *xa, double *ya, double *y2a, int n, double x, double *y);
|
||||||
|
void splint(double *xa, double *ya, double *y2a, int n, double x, double *y);
|
||||||
|
void spline(double *x, double *y, int n, double yp1, double ypn, double *y2);
|
||||||
|
double zeta(double zz, double zl);
|
||||||
|
double densm(double alt, double d0, double xm, double *tz, int mn3, double *zn3,
|
||||||
|
double *tn3, double *tgn3, int mn2, double *zn2, double *tn2,
|
||||||
|
double *tgn2);
|
||||||
|
double densu(double alt, double dlb, double tinf, double tlb, double xm,
|
||||||
|
double alpha, double *tz, double zlb, double s2, int mn1,
|
||||||
|
double *zn1, double *tn1, double *tgn1);
|
||||||
|
double g0(double a, double *p);
|
||||||
|
double sumex(double ex);
|
||||||
|
double sg0(double ex, double *p, double *ap);
|
||||||
|
double globe7(double *p, nrlmsise_input *input, nrlmsise_flags *flags);
|
||||||
|
double glob7s(double *p, nrlmsise_input *input, nrlmsise_flags *flags);
|
||||||
|
void gtd7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
|
||||||
|
void gtd7d(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
|
||||||
|
void ghp7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output, double press);
|
||||||
|
void gts7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
||||||
|
|
747
src/FDM/JSBSim/models/atmosphere/FGMSISData.cpp
Executable file
747
src/FDM/JSBSim/models/atmosphere/FGMSISData.cpp
Executable file
|
@ -0,0 +1,747 @@
|
||||||
|
// MSIS-00 Data
|
||||||
|
// Adapted for use in JSBSim
|
||||||
|
// David Culp, davidculp2@comcast.net
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/* --------- N R L M S I S E - 0 0 M O D E L 2 0 0 1 ---------- */
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* This file is part of the NRLMSISE-00 C source code package - release
|
||||||
|
* 20020503
|
||||||
|
*
|
||||||
|
* The NRLMSISE-00 model was developed by Mike Picone, Alan Hedin, and
|
||||||
|
* Doug Drob. They also wrote a NRLMSISE-00 distribution package in
|
||||||
|
* FORTRAN which is available at
|
||||||
|
* http://uap-www.nrl.navy.mil/models_web/msis/msis_home.htm
|
||||||
|
*
|
||||||
|
* Dominik Brodowski implemented and maintains this C version. You can
|
||||||
|
* reach him at devel@brodo.de. See the file "DOCUMENTATION" for details,
|
||||||
|
* and check http://www.brodo.de/english/pub/nrlmsise/index.html for
|
||||||
|
* updated releases of this package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
/* ------------------------ BLOCK DATA GTD7BK ------------------------ */
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/* TEMPERATURE */
|
||||||
|
double pt[150] = {
|
||||||
|
9.86573E-01, 1.62228E-02, 1.55270E-02,-1.04323E-01,-3.75801E-03,
|
||||||
|
-1.18538E-03,-1.24043E-01, 4.56820E-03, 8.76018E-03,-1.36235E-01,
|
||||||
|
-3.52427E-02, 8.84181E-03,-5.92127E-03,-8.61650E+00, 0.00000E+00,
|
||||||
|
1.28492E-02, 0.00000E+00, 1.30096E+02, 1.04567E-02, 1.65686E-03,
|
||||||
|
-5.53887E-06, 2.97810E-03, 0.00000E+00, 5.13122E-03, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00,-7.27026E-06,
|
||||||
|
0.00000E+00, 6.74494E+00, 4.93933E-03, 2.21656E-03, 2.50802E-03,
|
||||||
|
0.00000E+00, 0.00000E+00,-2.08841E-02,-1.79873E+00, 1.45103E-03,
|
||||||
|
2.81769E-04,-1.44703E-03,-5.16394E-05, 8.47001E-02, 1.70147E-01,
|
||||||
|
5.72562E-03, 5.07493E-05, 4.36148E-03, 1.17863E-04, 4.74364E-03,
|
||||||
|
6.61278E-03, 4.34292E-05, 1.44373E-03, 2.41470E-05, 2.84426E-03,
|
||||||
|
8.56560E-04, 2.04028E-03, 0.00000E+00,-3.15994E+03,-2.46423E-03,
|
||||||
|
1.13843E-03, 4.20512E-04, 0.00000E+00,-9.77214E+01, 6.77794E-03,
|
||||||
|
5.27499E-03, 1.14936E-03, 0.00000E+00,-6.61311E-03,-1.84255E-02,
|
||||||
|
-1.96259E-02, 2.98618E+04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
6.44574E+02, 8.84668E-04, 5.05066E-04, 0.00000E+00, 4.02881E+03,
|
||||||
|
-1.89503E-03, 0.00000E+00, 0.00000E+00, 8.21407E-04, 2.06780E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-1.20410E-02,-3.63963E-03, 9.92070E-05,-1.15284E-04,-6.33059E-05,
|
||||||
|
-6.05545E-01, 8.34218E-03,-9.13036E+01, 3.71042E-04, 0.00000E+00,
|
||||||
|
4.19000E-04, 2.70928E-03, 3.31507E-03,-4.44508E-03,-4.96334E-03,
|
||||||
|
-1.60449E-03, 3.95119E-03, 2.48924E-03, 5.09815E-04, 4.05302E-03,
|
||||||
|
2.24076E-03, 0.00000E+00, 6.84256E-03, 4.66354E-04, 0.00000E+00,
|
||||||
|
-3.68328E-04, 0.00000E+00, 0.00000E+00,-1.46870E+02, 0.00000E+00,
|
||||||
|
0.00000E+00, 1.09501E-03, 4.65156E-04, 5.62583E-04, 3.21596E+00,
|
||||||
|
6.43168E-04, 3.14860E-03, 3.40738E-03, 1.78481E-03, 9.62532E-04,
|
||||||
|
5.58171E-04, 3.43731E+00,-2.33195E-01, 5.10289E-04, 0.00000E+00,
|
||||||
|
0.00000E+00,-9.25347E+04, 0.00000E+00,-1.99639E-03, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
};
|
||||||
|
|
||||||
|
double pd[9][150] = {
|
||||||
|
/* HE DENSITY */ {
|
||||||
|
1.09979E+00,-4.88060E-02,-1.97501E-01,-9.10280E-02,-6.96558E-03,
|
||||||
|
2.42136E-02, 3.91333E-01,-7.20068E-03,-3.22718E-02, 1.41508E+00,
|
||||||
|
1.68194E-01, 1.85282E-02, 1.09384E-01,-7.24282E+00, 0.00000E+00,
|
||||||
|
2.96377E-01,-4.97210E-02, 1.04114E+02,-8.61108E-02,-7.29177E-04,
|
||||||
|
1.48998E-06, 1.08629E-03, 0.00000E+00, 0.00000E+00, 8.31090E-02,
|
||||||
|
1.12818E-01,-5.75005E-02,-1.29919E-02,-1.78849E-02,-2.86343E-06,
|
||||||
|
0.00000E+00,-1.51187E+02,-6.65902E-03, 0.00000E+00,-2.02069E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 4.32264E-02,-2.80444E+01,-3.26789E-03,
|
||||||
|
2.47461E-03, 0.00000E+00, 0.00000E+00, 9.82100E-02, 1.22714E-01,
|
||||||
|
-3.96450E-02, 0.00000E+00,-2.76489E-03, 0.00000E+00, 1.87723E-03,
|
||||||
|
-8.09813E-03, 4.34428E-05,-7.70932E-03, 0.00000E+00,-2.28894E-03,
|
||||||
|
-5.69070E-03,-5.22193E-03, 6.00692E-03,-7.80434E+03,-3.48336E-03,
|
||||||
|
-6.38362E-03,-1.82190E-03, 0.00000E+00,-7.58976E+01,-2.17875E-02,
|
||||||
|
-1.72524E-02,-9.06287E-03, 0.00000E+00, 2.44725E-02, 8.66040E-02,
|
||||||
|
1.05712E-01, 3.02543E+04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-6.01364E+03,-5.64668E-03,-2.54157E-03, 0.00000E+00, 3.15611E+02,
|
||||||
|
-5.69158E-03, 0.00000E+00, 0.00000E+00,-4.47216E-03,-4.49523E-03,
|
||||||
|
4.64428E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
4.51236E-02, 2.46520E-02, 6.17794E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
-3.62944E-01,-4.80022E-02,-7.57230E+01,-1.99656E-03, 0.00000E+00,
|
||||||
|
-5.18780E-03,-1.73990E-02,-9.03485E-03, 7.48465E-03, 1.53267E-02,
|
||||||
|
1.06296E-02, 1.18655E-02, 2.55569E-03, 1.69020E-03, 3.51936E-02,
|
||||||
|
-1.81242E-02, 0.00000E+00,-1.00529E-01,-5.10574E-03, 0.00000E+00,
|
||||||
|
2.10228E-03, 0.00000E+00, 0.00000E+00,-1.73255E+02, 5.07833E-01,
|
||||||
|
-2.41408E-01, 8.75414E-03, 2.77527E-03,-8.90353E-05,-5.25148E+00,
|
||||||
|
-5.83899E-03,-2.09122E-02,-9.63530E-03, 9.77164E-03, 4.07051E-03,
|
||||||
|
2.53555E-04,-5.52875E+00,-3.55993E-01,-2.49231E-03, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.86026E+01, 0.00000E+00, 3.42722E-04, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* O DENSITY */ {
|
||||||
|
1.02315E+00,-1.59710E-01,-1.06630E-01,-1.77074E-02,-4.42726E-03,
|
||||||
|
3.44803E-02, 4.45613E-02,-3.33751E-02,-5.73598E-02, 3.50360E-01,
|
||||||
|
6.33053E-02, 2.16221E-02, 5.42577E-02,-5.74193E+00, 0.00000E+00,
|
||||||
|
1.90891E-01,-1.39194E-02, 1.01102E+02, 8.16363E-02, 1.33717E-04,
|
||||||
|
6.54403E-06, 3.10295E-03, 0.00000E+00, 0.00000E+00, 5.38205E-02,
|
||||||
|
1.23910E-01,-1.39831E-02, 0.00000E+00, 0.00000E+00,-3.95915E-06,
|
||||||
|
0.00000E+00,-7.14651E-01,-5.01027E-03, 0.00000E+00,-3.24756E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 4.42173E-02,-1.31598E+01,-3.15626E-03,
|
||||||
|
1.24574E-03,-1.47626E-03,-1.55461E-03, 6.40682E-02, 1.34898E-01,
|
||||||
|
-2.42415E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 6.13666E-04,
|
||||||
|
-5.40373E-03, 2.61635E-05,-3.33012E-03, 0.00000E+00,-3.08101E-03,
|
||||||
|
-2.42679E-03,-3.36086E-03, 0.00000E+00,-1.18979E+03,-5.04738E-02,
|
||||||
|
-2.61547E-03,-1.03132E-03, 1.91583E-04,-8.38132E+01,-1.40517E-02,
|
||||||
|
-1.14167E-02,-4.08012E-03, 1.73522E-04,-1.39644E-02,-6.64128E-02,
|
||||||
|
-6.85152E-02,-1.34414E+04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
6.07916E+02,-4.12220E-03,-2.20996E-03, 0.00000E+00, 1.70277E+03,
|
||||||
|
-4.63015E-03, 0.00000E+00, 0.00000E+00,-2.25360E-03,-2.96204E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
3.92786E-02, 1.31186E-02,-1.78086E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
-3.90083E-01,-2.84741E-02,-7.78400E+01,-1.02601E-03, 0.00000E+00,
|
||||||
|
-7.26485E-04,-5.42181E-03,-5.59305E-03, 1.22825E-02, 1.23868E-02,
|
||||||
|
6.68835E-03,-1.03303E-02,-9.51903E-03, 2.70021E-04,-2.57084E-02,
|
||||||
|
-1.32430E-02, 0.00000E+00,-3.81000E-02,-3.16810E-03, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-9.05762E-04,-2.14590E-03,-1.17824E-03, 3.66732E+00,
|
||||||
|
-3.79729E-04,-6.13966E-03,-5.09082E-03,-1.96332E-03,-3.08280E-03,
|
||||||
|
-9.75222E-04, 4.03315E+00,-2.52710E-01, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* N2 DENSITY */ {
|
||||||
|
1.16112E+00, 0.00000E+00, 0.00000E+00, 3.33725E-02, 0.00000E+00,
|
||||||
|
3.48637E-02,-5.44368E-03, 0.00000E+00,-6.73940E-02, 1.74754E-01,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 1.74712E+02, 0.00000E+00,
|
||||||
|
1.26733E-01, 0.00000E+00, 1.03154E+02, 5.52075E-02, 0.00000E+00,
|
||||||
|
0.00000E+00, 8.13525E-04, 0.00000E+00, 0.00000E+00, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-2.50482E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-2.48894E-03,
|
||||||
|
6.16053E-04,-5.79716E-04, 2.95482E-03, 8.47001E-02, 1.70147E-01,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.47425E-05, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* TLB */ {
|
||||||
|
9.44846E-01, 0.00000E+00, 0.00000E+00,-3.08617E-02, 0.00000E+00,
|
||||||
|
-2.44019E-02, 6.48607E-03, 0.00000E+00, 3.08181E-02, 4.59392E-02,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 1.74712E+02, 0.00000E+00,
|
||||||
|
2.13260E-02, 0.00000E+00,-3.56958E+02, 0.00000E+00, 1.82278E-04,
|
||||||
|
0.00000E+00, 3.07472E-04, 0.00000E+00, 0.00000E+00, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 3.83054E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
-1.93065E-03,-1.45090E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.23493E-03, 1.36736E-03, 8.47001E-02, 1.70147E-01,
|
||||||
|
3.71469E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
5.10250E-03, 2.47425E-05, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 3.68756E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* O2 DENSITY */ {
|
||||||
|
1.35580E+00, 1.44816E-01, 0.00000E+00, 6.07767E-02, 0.00000E+00,
|
||||||
|
2.94777E-02, 7.46900E-02, 0.00000E+00,-9.23822E-02, 8.57342E-02,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 2.38636E+01, 0.00000E+00,
|
||||||
|
7.71653E-02, 0.00000E+00, 8.18751E+01, 1.87736E-02, 0.00000E+00,
|
||||||
|
0.00000E+00, 1.49667E-02, 0.00000E+00, 0.00000E+00, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-3.67874E+02, 5.48158E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 8.47001E-02, 1.70147E-01,
|
||||||
|
1.22631E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
8.17187E-03, 3.71617E-05, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-2.10826E-03,
|
||||||
|
-3.13640E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-7.35742E-02,-5.00266E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 1.94965E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* AR DENSITY */ {
|
||||||
|
1.04761E+00, 2.00165E-01, 2.37697E-01, 3.68552E-02, 0.00000E+00,
|
||||||
|
3.57202E-02,-2.14075E-01, 0.00000E+00,-1.08018E-01,-3.73981E-01,
|
||||||
|
0.00000E+00, 3.10022E-02,-1.16305E-03,-2.07596E+01, 0.00000E+00,
|
||||||
|
8.64502E-02, 0.00000E+00, 9.74908E+01, 5.16707E-02, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 3.46193E+02, 1.34297E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-3.48509E-03,
|
||||||
|
-1.54689E-04, 0.00000E+00, 0.00000E+00, 8.47001E-02, 1.70147E-01,
|
||||||
|
1.47753E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
1.89320E-02, 3.68181E-05, 1.32570E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
3.59719E-03, 7.44328E-03,-1.00023E-03,-6.50528E+03, 0.00000E+00,
|
||||||
|
1.03485E-02,-1.00983E-03,-4.06916E-03,-6.60864E+01,-1.71533E-02,
|
||||||
|
1.10605E-02, 1.20300E-02,-5.20034E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-2.62769E+03, 7.13755E-03, 4.17999E-03, 0.00000E+00, 1.25910E+04,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00,-2.23595E-03, 4.60217E-03,
|
||||||
|
5.71794E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-3.18353E-02,-2.35526E-02,-1.36189E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.03522E-02,-6.67837E+01,-1.09724E-03, 0.00000E+00,
|
||||||
|
-1.38821E-02, 1.60468E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 1.51574E-02,
|
||||||
|
-5.44470E-04, 0.00000E+00, 7.28224E-02, 6.59413E-02, 0.00000E+00,
|
||||||
|
-5.15692E-03, 0.00000E+00, 0.00000E+00,-3.70367E+03, 0.00000E+00,
|
||||||
|
0.00000E+00, 1.36131E-02, 5.38153E-03, 0.00000E+00, 4.76285E+00,
|
||||||
|
-1.75677E-02, 2.26301E-02, 0.00000E+00, 1.76631E-02, 4.77162E-03,
|
||||||
|
0.00000E+00, 5.39354E+00, 0.00000E+00,-7.51710E-03, 0.00000E+00,
|
||||||
|
0.00000E+00,-8.82736E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* H DENSITY */ {
|
||||||
|
1.26376E+00,-2.14304E-01,-1.49984E-01, 2.30404E-01, 2.98237E-02,
|
||||||
|
2.68673E-02, 2.96228E-01, 2.21900E-02,-2.07655E-02, 4.52506E-01,
|
||||||
|
1.20105E-01, 3.24420E-02, 4.24816E-02,-9.14313E+00, 0.00000E+00,
|
||||||
|
2.47178E-02,-2.88229E-02, 8.12805E+01, 5.10380E-02,-5.80611E-03,
|
||||||
|
2.51236E-05,-1.24083E-02, 0.00000E+00, 0.00000E+00, 8.66784E-02,
|
||||||
|
1.58727E-01,-3.48190E-02, 0.00000E+00, 0.00000E+00, 2.89885E-05,
|
||||||
|
0.00000E+00, 1.53595E+02,-1.68604E-02, 0.00000E+00, 1.01015E-02,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.84552E-04,
|
||||||
|
-1.22181E-03, 0.00000E+00, 0.00000E+00, 8.47001E-02, 1.70147E-01,
|
||||||
|
-1.04927E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00,-5.91313E-03,
|
||||||
|
-2.30501E-02, 3.14758E-05, 0.00000E+00, 0.00000E+00, 1.26956E-02,
|
||||||
|
8.35489E-03, 3.10513E-04, 0.00000E+00, 3.42119E+03,-2.45017E-03,
|
||||||
|
-4.27154E-04, 5.45152E-04, 1.89896E-03, 2.89121E+01,-6.49973E-03,
|
||||||
|
-1.93855E-02,-1.48492E-02, 0.00000E+00,-5.10576E-02, 7.87306E-02,
|
||||||
|
9.51981E-02,-1.49422E+04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
2.65503E+02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 6.37110E-03, 3.24789E-04,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
6.14274E-02, 1.00376E-02,-8.41083E-04, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.27099E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-3.94077E-03,-1.28601E-02,-7.97616E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-6.71465E-03,-1.69799E-03, 1.93772E-03, 3.81140E+00,
|
||||||
|
-7.79290E-03,-1.82589E-02,-1.25860E-02,-1.04311E-02,-3.02465E-03,
|
||||||
|
2.43063E-03, 3.63237E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* N DENSITY */ {
|
||||||
|
7.09557E+01,-3.26740E-01, 0.00000E+00,-5.16829E-01,-1.71664E-03,
|
||||||
|
9.09310E-02,-6.71500E-01,-1.47771E-01,-9.27471E-02,-2.30862E-01,
|
||||||
|
-1.56410E-01, 1.34455E-02,-1.19717E-01, 2.52151E+00, 0.00000E+00,
|
||||||
|
-2.41582E-01, 5.92939E-02, 4.39756E+00, 9.15280E-02, 4.41292E-03,
|
||||||
|
0.00000E+00, 8.66807E-03, 0.00000E+00, 0.00000E+00, 8.66784E-02,
|
||||||
|
1.58727E-01, 9.74701E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 6.70217E+01,-1.31660E-03, 0.00000E+00,-1.65317E-02,
|
||||||
|
0.00000E+00, 0.00000E+00, 8.50247E-02, 2.77428E+01, 4.98658E-03,
|
||||||
|
6.15115E-03, 9.50156E-03,-2.12723E-02, 8.47001E-02, 1.70147E-01,
|
||||||
|
-2.38645E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 1.37380E-03,
|
||||||
|
-8.41918E-03, 2.80145E-05, 7.12383E-03, 0.00000E+00,-1.66209E-02,
|
||||||
|
1.03533E-04,-1.68898E-02, 0.00000E+00, 3.64526E+03, 0.00000E+00,
|
||||||
|
6.54077E-03, 3.69130E-04, 9.94419E-04, 8.42803E+01,-1.16124E-02,
|
||||||
|
-7.74414E-03,-1.68844E-03, 1.42809E-03,-1.92955E-03, 1.17225E-01,
|
||||||
|
-2.41512E-02, 1.50521E+04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
1.60261E+03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00,-3.54403E-04,-1.87270E-02,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
2.76439E-02, 6.43207E-03,-3.54300E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-2.80221E-02, 8.11228E+01,-6.75255E-04, 0.00000E+00,
|
||||||
|
-1.05162E-02,-3.48292E-03,-6.97321E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.45546E-03,-1.31970E-02,-3.57751E-03,-1.09021E+00,
|
||||||
|
-1.50181E-02,-7.12841E-03,-6.64590E-03,-3.52610E-03,-1.87773E-02,
|
||||||
|
-2.22432E-03,-3.93895E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}, /* HOT O DENSITY */ {
|
||||||
|
6.04050E-02, 1.57034E+00, 2.99387E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-1.51018E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00,-8.61650E+00, 1.26454E-02,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 5.50878E-03, 0.00000E+00, 0.00000E+00, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 6.23881E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 8.47001E-02, 1.70147E-01,
|
||||||
|
-9.45934E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
}};
|
||||||
|
/* S PARAM */
|
||||||
|
double ps[150] = {
|
||||||
|
9.56827E-01, 6.20637E-02, 3.18433E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
3.94900E-02, 0.00000E+00, 0.00000E+00,-9.24882E-03,-7.94023E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 1.74712E+02, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.74677E-03, 0.00000E+00, 1.54951E-02, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00,-6.99007E-04, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 1.24362E-02,-5.28756E-03, 8.47001E-02, 1.70147E-01,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.47425E-05, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TURBO */
|
||||||
|
double pdl[2][25] = {
|
||||||
|
{ 1.09930E+00, 3.90631E+00, 3.07165E+00, 9.86161E-01, 1.63536E+01,
|
||||||
|
4.63830E+00, 1.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 1.28840E+00, 3.10302E-02, 1.18339E-01 },
|
||||||
|
{ 1.00000E+00, 7.00000E-01, 1.15020E+00, 3.44689E+00, 1.28840E+00,
|
||||||
|
1.00000E+00, 1.08738E+00, 1.22947E+00, 1.10016E+00, 7.34129E-01,
|
||||||
|
1.15241E+00, 2.22784E+00, 7.95046E-01, 4.01612E+00, 4.47749E+00,
|
||||||
|
1.23435E+02,-7.60535E-02, 1.68986E-06, 7.44294E-01, 1.03604E+00,
|
||||||
|
1.72783E+02, 1.15020E+00, 3.44689E+00,-7.46230E-01, 9.49154E-01 }
|
||||||
|
};
|
||||||
|
/* LOWER BOUNDARY */
|
||||||
|
double ptm[50] = {
|
||||||
|
1.04130E+03, 3.86000E+02, 1.95000E+02, 1.66728E+01, 2.13000E+02,
|
||||||
|
1.20000E+02, 2.40000E+02, 1.87000E+02,-2.00000E+00, 0.00000E+00
|
||||||
|
};
|
||||||
|
double pdm[8][10] = {
|
||||||
|
{ 2.45600E+07, 6.71072E-06, 1.00000E+02, 0.00000E+00, 1.10000E+02,
|
||||||
|
1.00000E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00 },\
|
||||||
|
{ 8.59400E+10, 1.00000E+00, 1.05000E+02,-8.00000E+00, 1.10000E+02,
|
||||||
|
1.00000E+01, 9.00000E+01, 2.00000E+00, 0.00000E+00, 0.00000E+00 },\
|
||||||
|
{ 2.81000E+11, 0.00000E+00, 1.05000E+02, 2.80000E+01, 2.89500E+01,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00 },
|
||||||
|
{ 3.30000E+10, 2.68270E-01, 1.05000E+02, 1.00000E+00, 1.10000E+02,
|
||||||
|
1.00000E+01, 1.10000E+02,-1.00000E+01, 0.00000E+00, 0.00000E+00 },
|
||||||
|
{ 1.33000E+09, 1.19615E-02, 1.05000E+02, 0.00000E+00, 1.10000E+02,
|
||||||
|
1.00000E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00 },
|
||||||
|
{ 1.76100E+05, 1.00000E+00, 9.50000E+01,-8.00000E+00, 1.10000E+02,
|
||||||
|
1.00000E+01, 9.00000E+01, 2.00000E+00, 0.00000E+00, 0.00000E+00, },
|
||||||
|
{ 1.00000E+07, 1.00000E+00, 1.05000E+02,-8.00000E+00, 1.10000E+02,
|
||||||
|
1.00000E+01, 9.00000E+01, 2.00000E+00, 0.00000E+00, 0.00000E+00 },
|
||||||
|
{ 1.00000E+06, 1.00000E+00, 1.05000E+02,-8.00000E+00, 5.50000E+02,
|
||||||
|
7.60000E+01, 9.00000E+01, 2.00000E+00, 0.00000E+00, 4.00000E+03 }};
|
||||||
|
|
||||||
|
|
||||||
|
double ptl[4][100] = {
|
||||||
|
/* TN1(2) */ {
|
||||||
|
1.00858E+00, 4.56011E-02,-2.22972E-02,-5.44388E-02, 5.23136E-04,
|
||||||
|
-1.88849E-02, 5.23707E-02,-9.43646E-03, 6.31707E-03,-7.80460E-02,
|
||||||
|
-4.88430E-02, 0.00000E+00, 0.00000E+00,-7.60250E+00, 0.00000E+00,
|
||||||
|
-1.44635E-02,-1.76843E-02,-1.21517E+02, 2.85647E-02, 0.00000E+00,
|
||||||
|
0.00000E+00, 6.31792E-04, 0.00000E+00, 5.77197E-03, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-8.90272E+03, 3.30611E-03, 3.02172E-03, 0.00000E+00,
|
||||||
|
-2.13673E-03,-3.20910E-04, 0.00000E+00, 0.00000E+00, 2.76034E-03,
|
||||||
|
2.82487E-03,-2.97592E-04,-4.21534E-03, 8.47001E-02, 1.70147E-01,
|
||||||
|
8.96456E-03, 0.00000E+00,-1.08596E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
5.57917E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 9.65405E-03, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN1(3) */ {
|
||||||
|
9.39664E-01, 8.56514E-02,-6.79989E-03, 2.65929E-02,-4.74283E-03,
|
||||||
|
1.21855E-02,-2.14905E-02, 6.49651E-03,-2.05477E-02,-4.24952E-02,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 1.19148E+01, 0.00000E+00,
|
||||||
|
1.18777E-02,-7.28230E-02,-8.15965E+01, 1.73887E-02, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-1.44691E-02, 2.80259E-04, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.16584E+02, 3.18713E-03, 7.37479E-03, 0.00000E+00,
|
||||||
|
-2.55018E-03,-3.92806E-03, 0.00000E+00, 0.00000E+00,-2.89757E-03,
|
||||||
|
-1.33549E-03, 1.02661E-03, 3.53775E-04, 8.47001E-02, 1.70147E-01,
|
||||||
|
-9.17497E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
3.56082E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.00902E-02, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN1(4) */ {
|
||||||
|
9.85982E-01,-4.55435E-02, 1.21106E-02, 2.04127E-02,-2.40836E-03,
|
||||||
|
1.11383E-02,-4.51926E-02, 1.35074E-02,-6.54139E-03, 1.15275E-01,
|
||||||
|
1.28247E-01, 0.00000E+00, 0.00000E+00,-5.30705E+00, 0.00000E+00,
|
||||||
|
-3.79332E-02,-6.24741E-02, 7.71062E-01, 2.96315E-02, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 6.81051E-03,-4.34767E-03, 8.66784E-02,
|
||||||
|
1.58727E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 1.07003E+01,-2.76907E-03, 4.32474E-04, 0.00000E+00,
|
||||||
|
1.31497E-03,-6.47517E-04, 0.00000E+00,-2.20621E+01,-1.10804E-03,
|
||||||
|
-8.09338E-04, 4.18184E-04, 4.29650E-03, 8.47001E-02, 1.70147E-01,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-4.04337E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-9.52550E-04,
|
||||||
|
8.56253E-04, 4.33114E-04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 1.21223E-03,
|
||||||
|
2.38694E-04, 9.15245E-04, 1.28385E-03, 8.67668E-04,-5.61425E-06,
|
||||||
|
1.04445E+00, 3.41112E+01, 0.00000E+00,-8.40704E-01,-2.39639E+02,
|
||||||
|
7.06668E-01,-2.05873E+01,-3.63696E-01, 2.39245E+01, 0.00000E+00,
|
||||||
|
-1.06657E-03,-7.67292E-04, 1.54534E-04, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN1(5) TN2(1) */ {
|
||||||
|
1.00320E+00, 3.83501E-02,-2.38983E-03, 2.83950E-03, 4.20956E-03,
|
||||||
|
5.86619E-04, 2.19054E-02,-1.00946E-02,-3.50259E-03, 4.17392E-02,
|
||||||
|
-8.44404E-03, 0.00000E+00, 0.00000E+00, 4.96949E+00, 0.00000E+00,
|
||||||
|
-7.06478E-03,-1.46494E-02, 3.13258E+01,-1.86493E-03, 0.00000E+00,
|
||||||
|
-1.67499E-02, 0.00000E+00, 0.00000E+00, 5.12686E-04, 8.66784E-02,
|
||||||
|
1.58727E-01,-4.64167E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
4.37353E-03,-1.99069E+02, 0.00000E+00,-5.34884E-03, 0.00000E+00,
|
||||||
|
1.62458E-03, 2.93016E-03, 2.67926E-03, 5.90449E+02, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.17266E-03,-3.58890E-04, 8.47001E-02, 1.70147E-01,
|
||||||
|
0.00000E+00, 0.00000E+00, 1.38673E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 1.60571E-03,
|
||||||
|
6.28078E-04, 5.05469E-05, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-1.57829E-03,
|
||||||
|
-4.00855E-04, 5.04077E-05,-1.39001E-03,-2.33406E-03,-4.81197E-04,
|
||||||
|
1.46758E+00, 6.20332E+00, 0.00000E+00, 3.66476E-01,-6.19760E+01,
|
||||||
|
3.09198E-01,-1.98999E+01, 0.00000E+00,-3.29933E+02, 0.00000E+00,
|
||||||
|
-1.10080E-03,-9.39310E-05, 1.39638E-04, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
} };
|
||||||
|
|
||||||
|
double pma[10][100] = {
|
||||||
|
/* TN2(2) */ {
|
||||||
|
9.81637E-01,-1.41317E-03, 3.87323E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-3.58707E-02,
|
||||||
|
-8.63658E-03, 0.00000E+00, 0.00000E+00,-2.02226E+00, 0.00000E+00,
|
||||||
|
-8.69424E-03,-1.91397E-02, 8.76779E+01, 4.52188E-03, 0.00000E+00,
|
||||||
|
2.23760E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-7.07572E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
-4.11210E-03, 3.50060E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-8.36657E-03, 1.61347E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-1.45130E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 1.24152E-03,
|
||||||
|
6.43365E-04, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 1.33255E-03,
|
||||||
|
2.42657E-03, 1.60666E-03,-1.85728E-03,-1.46874E-03,-4.79163E-06,
|
||||||
|
1.22464E+00, 3.53510E+01, 0.00000E+00, 4.49223E-01,-4.77466E+01,
|
||||||
|
4.70681E-01, 8.41861E+00,-2.88198E-01, 1.67854E+02, 0.00000E+00,
|
||||||
|
7.11493E-04, 6.05601E-04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN2(3) */ {
|
||||||
|
1.00422E+00,-7.11212E-03, 5.24480E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-5.28914E-02,
|
||||||
|
-2.41301E-02, 0.00000E+00, 0.00000E+00,-2.12219E+01,-1.03830E-02,
|
||||||
|
-3.28077E-03, 1.65727E-02, 1.68564E+00,-6.68154E-03, 0.00000E+00,
|
||||||
|
1.45155E-02, 0.00000E+00, 8.42365E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-4.34645E-03, 0.00000E+00, 0.00000E+00, 2.16780E-02,
|
||||||
|
0.00000E+00,-1.38459E+02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 7.04573E-03,-4.73204E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 1.08767E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-8.08279E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 5.21769E-04,
|
||||||
|
-2.27387E-04, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 3.26769E-03,
|
||||||
|
3.16901E-03, 4.60316E-04,-1.01431E-04, 1.02131E-03, 9.96601E-04,
|
||||||
|
1.25707E+00, 2.50114E+01, 0.00000E+00, 4.24472E-01,-2.77655E+01,
|
||||||
|
3.44625E-01, 2.75412E+01, 0.00000E+00, 7.94251E+02, 0.00000E+00,
|
||||||
|
2.45835E-03, 1.38871E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN2(4) TN3(1) */ {
|
||||||
|
1.01890E+00,-2.46603E-02, 1.00078E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-6.70977E-02,
|
||||||
|
-4.02286E-02, 0.00000E+00, 0.00000E+00,-2.29466E+01,-7.47019E-03,
|
||||||
|
2.26580E-03, 2.63931E-02, 3.72625E+01,-6.39041E-03, 0.00000E+00,
|
||||||
|
9.58383E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.85291E-03, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 1.39717E+02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 9.19771E-03,-3.69121E+02, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-1.57067E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-7.07265E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-2.92953E-03,
|
||||||
|
-2.77739E-03,-4.40092E-04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.47280E-03,
|
||||||
|
2.95035E-04,-1.81246E-03, 2.81945E-03, 4.27296E-03, 9.78863E-04,
|
||||||
|
1.40545E+00,-6.19173E+00, 0.00000E+00, 0.00000E+00,-7.93632E+01,
|
||||||
|
4.44643E-01,-4.03085E+02, 0.00000E+00, 1.15603E+01, 0.00000E+00,
|
||||||
|
2.25068E-03, 8.48557E-04,-2.98493E-04, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN3(2) */ {
|
||||||
|
9.75801E-01, 3.80680E-02,-3.05198E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 3.85575E-02,
|
||||||
|
5.04057E-02, 0.00000E+00, 0.00000E+00,-1.76046E+02, 1.44594E-02,
|
||||||
|
-1.48297E-03,-3.68560E-03, 3.02185E+01,-3.23338E-03, 0.00000E+00,
|
||||||
|
1.53569E-02, 0.00000E+00,-1.15558E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 4.89620E-03, 0.00000E+00, 0.00000E+00,-1.00616E-02,
|
||||||
|
-8.21324E-03,-1.57757E+02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 6.63564E-03, 4.58410E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-2.51280E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 9.91215E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-8.73148E-04,
|
||||||
|
-1.29648E-03,-7.32026E-05, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-4.68110E-03,
|
||||||
|
-4.66003E-03,-1.31567E-03,-7.39390E-04, 6.32499E-04,-4.65588E-04,
|
||||||
|
-1.29785E+00,-1.57139E+02, 0.00000E+00, 2.58350E-01,-3.69453E+01,
|
||||||
|
4.10672E-01, 9.78196E+00,-1.52064E-01,-3.85084E+03, 0.00000E+00,
|
||||||
|
-8.52706E-04,-1.40945E-03,-7.26786E-04, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN3(3) */ {
|
||||||
|
9.60722E-01, 7.03757E-02,-3.00266E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.22671E-02,
|
||||||
|
4.10423E-02, 0.00000E+00, 0.00000E+00,-1.63070E+02, 1.06073E-02,
|
||||||
|
5.40747E-04, 7.79481E-03, 1.44908E+02, 1.51484E-04, 0.00000E+00,
|
||||||
|
1.97547E-02, 0.00000E+00,-1.41844E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 5.77884E-03, 0.00000E+00, 0.00000E+00, 9.74319E-03,
|
||||||
|
0.00000E+00,-2.88015E+03, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-4.44902E-03,-2.92760E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 2.34419E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 5.36685E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-4.65325E-04,
|
||||||
|
-5.50628E-04, 3.31465E-04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-2.06179E-03,
|
||||||
|
-3.08575E-03,-7.93589E-04,-1.08629E-04, 5.95511E-04,-9.05050E-04,
|
||||||
|
1.18997E+00, 4.15924E+01, 0.00000E+00,-4.72064E-01,-9.47150E+02,
|
||||||
|
3.98723E-01, 1.98304E+01, 0.00000E+00, 3.73219E+03, 0.00000E+00,
|
||||||
|
-1.50040E-03,-1.14933E-03,-1.56769E-04, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN3(4) */ {
|
||||||
|
1.03123E+00,-7.05124E-02, 8.71615E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-3.82621E-02,
|
||||||
|
-9.80975E-03, 0.00000E+00, 0.00000E+00, 2.89286E+01, 9.57341E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 8.66153E+01, 7.91938E-04, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 4.68917E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 7.86638E-03, 0.00000E+00, 0.00000E+00, 9.90827E-03,
|
||||||
|
0.00000E+00, 6.55573E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00,-4.00200E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 7.07457E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 5.72268E-03,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-2.04970E-04,
|
||||||
|
1.21560E-03,-8.05579E-06, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-2.49941E-03,
|
||||||
|
-4.57256E-04,-1.59311E-04, 2.96481E-04,-1.77318E-03,-6.37918E-04,
|
||||||
|
1.02395E+00, 1.28172E+01, 0.00000E+00, 1.49903E-01,-2.63818E+01,
|
||||||
|
0.00000E+00, 4.70628E+01,-2.22139E-01, 4.82292E-02, 0.00000E+00,
|
||||||
|
-8.67075E-04,-5.86479E-04, 5.32462E-04, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TN3(5) SURFACE TEMP TSL */ {
|
||||||
|
1.00828E+00,-9.10404E-02,-2.26549E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-2.32420E-02,
|
||||||
|
-9.08925E-03, 0.00000E+00, 0.00000E+00, 3.36105E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-1.24957E+01,-5.87939E-03, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.79765E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 2.01237E+03, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-1.75553E-02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 3.29699E-03,
|
||||||
|
1.26659E-03, 2.68402E-04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 1.17894E-03,
|
||||||
|
1.48746E-03, 1.06478E-04, 1.34743E-04,-2.20939E-03,-6.23523E-04,
|
||||||
|
6.36539E-01, 1.13621E+01, 0.00000E+00,-3.93777E-01, 2.38687E+03,
|
||||||
|
0.00000E+00, 6.61865E+02,-1.21434E-01, 9.27608E+00, 0.00000E+00,
|
||||||
|
1.68478E-04, 1.24892E-03, 1.71345E-03, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TGN3(2) SURFACE GRAD TSLG */ {
|
||||||
|
1.57293E+00,-6.78400E-01, 6.47500E-01, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-7.62974E-02,
|
||||||
|
-3.60423E-01, 0.00000E+00, 0.00000E+00, 1.28358E+02, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 4.68038E+01, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.67898E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.90994E+04, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 3.15706E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TGN2(1) TGN1(2) */ {
|
||||||
|
8.60028E-01, 3.77052E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-1.17570E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 7.77757E-03, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 1.01024E+02, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 6.54251E+02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,-1.56959E-02,
|
||||||
|
1.91001E-02, 3.15971E-02, 1.00982E-02,-6.71565E-03, 2.57693E-03,
|
||||||
|
1.38692E+00, 2.82132E-01, 0.00000E+00, 0.00000E+00, 3.81511E+02,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
}, /* TGN3(1) TGN2(2) */ {
|
||||||
|
1.06029E+00,-5.25231E-02, 3.73034E-01, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 3.31072E-02,
|
||||||
|
-3.88409E-01, 0.00000E+00, 0.00000E+00,-1.65295E+02,-2.13801E-01,
|
||||||
|
-4.38916E-02,-3.22716E-01,-8.82393E+01, 1.18458E-01, 0.00000E+00,
|
||||||
|
-4.35863E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00,-1.19782E-01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 2.62229E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00,-5.37443E+01, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00,-4.55788E-01, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 3.84009E-02,
|
||||||
|
3.96733E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 5.05494E-02,
|
||||||
|
7.39617E-02, 1.92200E-02,-8.46151E-03,-1.34244E-02, 1.96338E-02,
|
||||||
|
1.50421E+00, 1.88368E+01, 0.00000E+00, 0.00000E+00,-5.13114E+01,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
5.11923E-02, 3.61225E-02, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 2.00000E+00
|
||||||
|
} };
|
||||||
|
|
||||||
|
/* SEMIANNUAL MULT SAM */
|
||||||
|
double sam[100] = {
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00, 1.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00,
|
||||||
|
0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* MIDDLE ATMOSPHERE AVERAGES */
|
||||||
|
double pavgm[10] = {
|
||||||
|
2.61000E+02, 2.64000E+02, 2.29000E+02, 2.17000E+02, 2.17000E+02,
|
||||||
|
2.23000E+02, 2.86760E+02,-2.93940E+00, 2.50000E+00, 0.00000E+00 };
|
||||||
|
|
||||||
|
} // namespace
|
331
src/FDM/JSBSim/models/atmosphere/FGMars.cpp
Executable file
331
src/FDM/JSBSim/models/atmosphere/FGMars.cpp
Executable file
|
@ -0,0 +1,331 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGMars.cpp
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 1/4/04
|
||||||
|
Purpose: Models the Martian atmosphere very simply
|
||||||
|
Called by: FGFDMExec
|
||||||
|
|
||||||
|
------------- Copyright (C) 2004 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Models the Martian atmosphere.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
1/04/2004 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
COMMENTS, REFERENCES, and NOTES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGMars.h"
|
||||||
|
#include "FGState.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_MARS;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
|
FGMars::FGMars(FGFDMExec* fdmex) : FGAtmosphere(fdmex)
|
||||||
|
{
|
||||||
|
Name = "FGMars";
|
||||||
|
Reng = 53.5 * 44.01;
|
||||||
|
|
||||||
|
/*
|
||||||
|
lastIndex = 0;
|
||||||
|
h = 0.0;
|
||||||
|
psiw = 0.0;
|
||||||
|
|
||||||
|
MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
|
||||||
|
// turbType = ttNone;
|
||||||
|
turbType = ttStandard;
|
||||||
|
// turbType = ttBerndt;
|
||||||
|
TurbGain = 0.0;
|
||||||
|
TurbRate = 1.0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
bind();
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
/*
|
||||||
|
FGMars::~FGMars()
|
||||||
|
{
|
||||||
|
unbind();
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGMars::InitModel(void)
|
||||||
|
{
|
||||||
|
FGModel::InitModel();
|
||||||
|
|
||||||
|
Calculate(h);
|
||||||
|
SLtemperature = intTemperature;
|
||||||
|
SLpressure = intPressure;
|
||||||
|
SLdensity = intDensity;
|
||||||
|
SLsoundspeed = sqrt(SHRatio*Reng*intTemperature);
|
||||||
|
rSLtemperature = 1.0/intTemperature;
|
||||||
|
rSLpressure = 1.0/intPressure;
|
||||||
|
rSLdensity = 1.0/intDensity;
|
||||||
|
rSLsoundspeed = 1.0/SLsoundspeed;
|
||||||
|
temperature = &intTemperature;
|
||||||
|
pressure = &intPressure;
|
||||||
|
density = &intDensity;
|
||||||
|
|
||||||
|
useExternal=false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGMars::Run(void)
|
||||||
|
{
|
||||||
|
if (FGModel::Run()) return true;
|
||||||
|
if (FDMExec->Holding()) return false;
|
||||||
|
|
||||||
|
//do temp, pressure, and density first
|
||||||
|
if (!useExternal) {
|
||||||
|
h = Propagate->Geth();
|
||||||
|
Calculate(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turbType != ttNone) {
|
||||||
|
Turbulence();
|
||||||
|
vWindNED += vTurbulence;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vWindNED(1) != 0.0) psiw = atan2( vWindNED(2), vWindNED(1) );
|
||||||
|
|
||||||
|
if (psiw < 0) psiw += 2*M_PI;
|
||||||
|
|
||||||
|
soundspeed = sqrt(SHRatio*Reng*(*temperature));
|
||||||
|
|
||||||
|
Debug(2);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGMars::Calculate(double altitude)
|
||||||
|
{
|
||||||
|
//Calculate reftemp, refpress, and density
|
||||||
|
|
||||||
|
// LIMIT the temperatures so they do not descend below absolute zero.
|
||||||
|
|
||||||
|
if (altitude < 22960.0) {
|
||||||
|
intTemperature = -25.68 - 0.000548*altitude; // Deg Fahrenheit
|
||||||
|
} else {
|
||||||
|
intTemperature = -10.34 - 0.001217*altitude; // Deg Fahrenheit
|
||||||
|
}
|
||||||
|
intPressure = 14.62*exp(-0.00003*altitude); // psf - 14.62 psf =~ 7 millibars
|
||||||
|
intDensity = intPressure/(Reng*intTemperature); // slugs/ft^3 (needs deg R. as input
|
||||||
|
|
||||||
|
//cout << "Atmosphere: h=" << altitude << " rho= " << intDensity << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
// square a value, but preserve the original sign
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
square_signed (double value)
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
return value * value * -1;
|
||||||
|
else
|
||||||
|
return value * value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGMars::Turbulence(void)
|
||||||
|
{
|
||||||
|
switch (turbType) {
|
||||||
|
case ttStandard: {
|
||||||
|
vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
|
||||||
|
MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
|
||||||
|
// Scale the magnitude so that it moves
|
||||||
|
// away from the peaks
|
||||||
|
MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) /
|
||||||
|
(1 + fabs(Magnitude)));
|
||||||
|
MagnitudeAccel += MagnitudedAccelDt*rate*TurbRate*State->Getdt();
|
||||||
|
Magnitude += MagnitudeAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
vDirectiondAccelDt.Normalize();
|
||||||
|
|
||||||
|
// deemphasise non-vertical forces
|
||||||
|
vDirectiondAccelDt(eX) = square_signed(vDirectiondAccelDt(eX));
|
||||||
|
vDirectiondAccelDt(eY) = square_signed(vDirectiondAccelDt(eY));
|
||||||
|
|
||||||
|
vDirectionAccel += vDirectiondAccelDt*rate*TurbRate*State->Getdt();
|
||||||
|
vDirectionAccel.Normalize();
|
||||||
|
vDirection += vDirectionAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
vDirection.Normalize();
|
||||||
|
|
||||||
|
// Diminish turbulence within three wingspans
|
||||||
|
// of the ground
|
||||||
|
vTurbulence = TurbGain * Magnitude * vDirection;
|
||||||
|
double HOverBMAC = Auxiliary->GetHOverBMAC();
|
||||||
|
if (HOverBMAC < 3.0)
|
||||||
|
vTurbulence *= (HOverBMAC / 3.0) * (HOverBMAC / 3.0);
|
||||||
|
|
||||||
|
vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
|
||||||
|
|
||||||
|
vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad;
|
||||||
|
vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan();
|
||||||
|
// if (Aircraft->GetHTailArm() != 0.0)
|
||||||
|
// vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm();
|
||||||
|
// else
|
||||||
|
// vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
|
||||||
|
|
||||||
|
if (Aircraft->GetVTailArm())
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm();
|
||||||
|
else
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
|
||||||
|
|
||||||
|
// Clear the horizontal forces
|
||||||
|
// actually felt by the plane, now
|
||||||
|
// that we've used them to calculate
|
||||||
|
// moments.
|
||||||
|
vTurbulence(eX) = 0.0;
|
||||||
|
vTurbulence(eY) = 0.0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ttBerndt: {
|
||||||
|
vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
|
||||||
|
|
||||||
|
|
||||||
|
MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
|
||||||
|
MagnitudeAccel += MagnitudedAccelDt*rate*State->Getdt();
|
||||||
|
Magnitude += MagnitudeAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
vDirectiondAccelDt.Normalize();
|
||||||
|
vDirectionAccel += vDirectiondAccelDt*rate*State->Getdt();
|
||||||
|
vDirectionAccel.Normalize();
|
||||||
|
vDirection += vDirectionAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
// Diminish z-vector within two wingspans
|
||||||
|
// of the ground
|
||||||
|
double HOverBMAC = Auxiliary->GetHOverBMAC();
|
||||||
|
if (HOverBMAC < 2.0)
|
||||||
|
vDirection(eZ) *= HOverBMAC / 2.0;
|
||||||
|
|
||||||
|
vDirection.Normalize();
|
||||||
|
|
||||||
|
vTurbulence = TurbGain*Magnitude * vDirection;
|
||||||
|
vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
|
||||||
|
|
||||||
|
vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad;
|
||||||
|
vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan();
|
||||||
|
if (Aircraft->GetHTailArm() != 0.0)
|
||||||
|
vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm();
|
||||||
|
else
|
||||||
|
vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
|
||||||
|
|
||||||
|
if (Aircraft->GetVTailArm())
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm();
|
||||||
|
else
|
||||||
|
vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGMars::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGMars" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGMars" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 32) { // Turbulence
|
||||||
|
if (frame == 0 && from == 2) {
|
||||||
|
cout << "vTurbulence(X), vTurbulence(Y), vTurbulence(Z), "
|
||||||
|
<< "vTurbulenceGrad(X), vTurbulenceGrad(Y), vTurbulenceGrad(Z), "
|
||||||
|
<< "vDirection(X), vDirection(Y), vDirection(Z), "
|
||||||
|
<< "Magnitude, "
|
||||||
|
<< "vTurbPQR(P), vTurbPQR(Q), vTurbPQR(R), " << endl;
|
||||||
|
} else if (from == 2) {
|
||||||
|
cout << vTurbulence << ", " << vTurbulenceGrad << ", " << vDirection << ", " << Magnitude << ", " << vTurbPQR << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
182
src/FDM/JSBSim/models/atmosphere/FGMars.h
Executable file
182
src/FDM/JSBSim/models/atmosphere/FGMars.h
Executable file
|
@ -0,0 +1,182 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGMars.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 01/05/2004
|
||||||
|
|
||||||
|
------------- Copyright (C) 2004 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
01/05/2004 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGMars_H
|
||||||
|
#define FGMars_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <models/FGAtmosphere.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_MARS "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Models the Martian atmosphere.
|
||||||
|
@author Jon Berndt
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGMars : public FGAtmosphere {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
FGMars(FGFDMExec*);
|
||||||
|
/// Destructor
|
||||||
|
~FGMars();
|
||||||
|
/** Runs the Martian atmosphere model; called by the Executive
|
||||||
|
@return false if no error */
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
bool InitModel(void);
|
||||||
|
|
||||||
|
/// Returns the temperature in degrees Rankine.
|
||||||
|
inline double GetTemperature(void) const {return *temperature;}
|
||||||
|
/** Returns the density in slugs/ft^3.
|
||||||
|
<i>This function may <b>only</b> be used if Run() is called first.</i> */
|
||||||
|
inline double GetDensity(void) const {return *density;}
|
||||||
|
/// Returns the pressure in psf.
|
||||||
|
inline double GetPressure(void) const {return *pressure;}
|
||||||
|
/// Returns the speed of sound in ft/sec.
|
||||||
|
inline double GetSoundSpeed(void) const {return soundspeed;}
|
||||||
|
|
||||||
|
/// Returns the sea level temperature in degrees Rankine.
|
||||||
|
inline double GetTemperatureSL(void) const { return SLtemperature; }
|
||||||
|
/// Returns the sea level density in slugs/ft^3
|
||||||
|
inline double GetDensitySL(void) const { return SLdensity; }
|
||||||
|
/// Returns the sea level pressure in psf.
|
||||||
|
inline double GetPressureSL(void) const { return SLpressure; }
|
||||||
|
/// Returns the sea level speed of sound in ft/sec.
|
||||||
|
inline double GetSoundSpeedSL(void) const { return SLsoundspeed; }
|
||||||
|
|
||||||
|
/// Returns the ratio of at-altitude temperature over the sea level value.
|
||||||
|
inline double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; }
|
||||||
|
/// Returns the ratio of at-altitude density over the sea level value.
|
||||||
|
inline double GetDensityRatio(void) const { return (*density)*rSLdensity; }
|
||||||
|
/// Returns the ratio of at-altitude pressure over the sea level value.
|
||||||
|
inline double GetPressureRatio(void) const { return (*pressure)*rSLpressure; }
|
||||||
|
/// Returns the ratio of at-altitude sound speed over the sea level value.
|
||||||
|
inline double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; }
|
||||||
|
|
||||||
|
/// Tells the simulator to use an externally calculated atmosphere model.
|
||||||
|
void UseExternal(void);
|
||||||
|
/// Tells the simulator to use the internal atmosphere model.
|
||||||
|
void UseInternal(void); //this is the default
|
||||||
|
/// Gets the boolean that tells if the external atmosphere model is being used.
|
||||||
|
bool External(void) { return useExternal; }
|
||||||
|
|
||||||
|
/// Provides the external atmosphere model with an interface to set the temperature.
|
||||||
|
inline void SetExTemperature(double t) { exTemperature=t; }
|
||||||
|
/// Provides the external atmosphere model with an interface to set the density.
|
||||||
|
inline void SetExDensity(double d) { exDensity=d; }
|
||||||
|
/// Provides the external atmosphere model with an interface to set the pressure.
|
||||||
|
inline void SetExPressure(double p) { exPressure=p; }
|
||||||
|
|
||||||
|
/// Sets the wind components in NED frame.
|
||||||
|
inline void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
|
||||||
|
|
||||||
|
/// Retrieves the wind components in NED frame.
|
||||||
|
inline FGColumnVector3& GetWindNED(void) { return vWindNED; }
|
||||||
|
|
||||||
|
/** Retrieves the wind direction. The direction is defined as north=0 and
|
||||||
|
increases counterclockwise. The wind heading is returned in radians.*/
|
||||||
|
inline double GetWindPsi(void) const { return psiw; }
|
||||||
|
|
||||||
|
inline void SetTurbGain(double tt) {TurbGain = tt;}
|
||||||
|
inline void SetTurbRate(double tt) {TurbRate = tt;}
|
||||||
|
|
||||||
|
inline double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
|
||||||
|
inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
|
||||||
|
|
||||||
|
void bind(void);
|
||||||
|
void unbind(void);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
double rho;
|
||||||
|
|
||||||
|
enum tType {ttStandard, ttBerndt, ttNone} turbType;
|
||||||
|
|
||||||
|
int lastIndex;
|
||||||
|
double h;
|
||||||
|
double htab[8];
|
||||||
|
double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
|
||||||
|
double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
|
||||||
|
double *temperature,*density,*pressure;
|
||||||
|
double soundspeed;
|
||||||
|
bool useExternal;
|
||||||
|
double exTemperature,exDensity,exPressure;
|
||||||
|
double intTemperature, intDensity, intPressure;
|
||||||
|
|
||||||
|
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
|
||||||
|
double TurbGain;
|
||||||
|
double TurbRate;
|
||||||
|
FGColumnVector3 vDirectiondAccelDt;
|
||||||
|
FGColumnVector3 vDirectionAccel;
|
||||||
|
FGColumnVector3 vDirection;
|
||||||
|
FGColumnVector3 vTurbulence;
|
||||||
|
FGColumnVector3 vTurbulenceGrad;
|
||||||
|
FGColumnVector3 vBodyTurbGrad;
|
||||||
|
FGColumnVector3 vTurbPQR;
|
||||||
|
|
||||||
|
FGColumnVector3 vWindNED;
|
||||||
|
double psiw;
|
||||||
|
|
||||||
|
void Calculate(double altitude);
|
||||||
|
void Turbulence(void);
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JSBSim
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
#endif
|
||||||
|
|
7
src/FDM/JSBSim/models/atmosphere/Makefile.am
Normal file
7
src/FDM/JSBSim/models/atmosphere/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
noinst_LIBRARIES = libAtmosphere.a
|
||||||
|
|
||||||
|
libAtmosphere_a_SOURCES = FGMSIS.cpp FGMSISData.cpp FGMars.cpp
|
||||||
|
|
||||||
|
noinst_HEADERS = FGMSIS.h FGMars.h
|
||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
|
|
@ -34,10 +34,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGCondition.h"
|
#include "FGCondition.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -52,21 +48,13 @@ CLASS IMPLEMENTATION
|
||||||
string FGCondition::indent = " ";
|
string FGCondition::indent = " ";
|
||||||
|
|
||||||
|
|
||||||
FGCondition::FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManager) :
|
FGCondition::FGCondition(Element* element, FGPropertyManager* PropertyManager) :
|
||||||
PropertyManager(PropertyManager)
|
PropertyManager(PropertyManager), isGroup(true)
|
||||||
{
|
{
|
||||||
mComparison["EQ"] = eEQ;
|
string property1, property2, logic;
|
||||||
mComparison["NE"] = eNE;
|
Element* condition_element;
|
||||||
mComparison["GT"] = eGT;
|
|
||||||
mComparison["GE"] = eGE;
|
InitializeConditionals();
|
||||||
mComparison["LT"] = eLT;
|
|
||||||
mComparison["LE"] = eLE;
|
|
||||||
mComparison["=="] = eEQ;
|
|
||||||
mComparison["!="] = eNE;
|
|
||||||
mComparison[">"] = eGT;
|
|
||||||
mComparison[">="] = eGE;
|
|
||||||
mComparison["<"] = eLT;
|
|
||||||
mComparison["<="] = eLE;
|
|
||||||
|
|
||||||
TestParam1 = TestParam2 = 0L;
|
TestParam1 = TestParam2 = 0L;
|
||||||
TestValue = 0.0;
|
TestValue = 0.0;
|
||||||
|
@ -74,31 +62,19 @@ FGCondition::FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManage
|
||||||
Logic = elUndef;
|
Logic = elUndef;
|
||||||
conditions.clear();
|
conditions.clear();
|
||||||
|
|
||||||
if (AC_cfg->GetValue("CONDITION_GROUP").empty()) { // define a condition
|
logic = element->GetAttributeValue("logic");
|
||||||
|
if (logic == "OR") Logic = eOR;
|
||||||
*AC_cfg >> property1 >> conditional >> property2;
|
else if (logic == "AND") Logic = eAND;
|
||||||
TestParam1 = PropertyManager->GetNode(property1, true);
|
else { // error
|
||||||
Comparison = mComparison[conditional];
|
cerr << "Unrecognized LOGIC token " << logic << " in switch component: " << logic << endl;
|
||||||
|
}
|
||||||
if (property2.find_first_not_of("-.0123456789eE") == string::npos) {
|
condition_element = element->GetElement();
|
||||||
TestValue = atof(property2.c_str());
|
while (condition_element) {
|
||||||
} else {
|
conditions.push_back(FGCondition(condition_element, PropertyManager));
|
||||||
TestParam2 = PropertyManager->GetNode(property2, true);
|
condition_element = element->GetNextElement();
|
||||||
}
|
}
|
||||||
|
for (int i=0; i<element->GetNumDataLines(); i++) {
|
||||||
isGroup = false;
|
conditions.push_back(FGCondition(element->GetDataLine(i), PropertyManager));
|
||||||
|
|
||||||
} else { // define a condition group
|
|
||||||
|
|
||||||
if (AC_cfg->GetValue("LOGIC") == "OR") Logic = eOR;
|
|
||||||
else if (AC_cfg->GetValue("LOGIC") == "AND") Logic = eAND;
|
|
||||||
|
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
while (AC_cfg->GetValue() != string("/CONDITION_GROUP")) {
|
|
||||||
conditions.push_back(FGCondition(AC_cfg, PropertyManager));
|
|
||||||
}
|
|
||||||
isGroup = true;
|
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
|
@ -106,6 +82,66 @@ FGCondition::FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManage
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGCondition::FGCondition(string test, FGPropertyManager* PropertyManager) :
|
||||||
|
PropertyManager(PropertyManager), isGroup(false)
|
||||||
|
{
|
||||||
|
string property1, property2, compare_string;
|
||||||
|
Element* condition_element;
|
||||||
|
|
||||||
|
InitializeConditionals();
|
||||||
|
|
||||||
|
TestParam1 = TestParam2 = 0L;
|
||||||
|
TestValue = 0.0;
|
||||||
|
Comparison = ecUndef;
|
||||||
|
Logic = elUndef;
|
||||||
|
conditions.clear();
|
||||||
|
|
||||||
|
int start = 0, end = 0;
|
||||||
|
start = test.find_first_not_of(" ");
|
||||||
|
end = test.find_first_of(" ", start+1);
|
||||||
|
property1 = test.substr(start,end-start);
|
||||||
|
start = test.find_first_not_of(" ",end);
|
||||||
|
end = test.find_first_of(" ",start+1);
|
||||||
|
conditional = test.substr(start,end-start);
|
||||||
|
start = test.find_first_not_of(" ",end);
|
||||||
|
end = test.find_first_of(" ",start+1);
|
||||||
|
property2 = test.substr(start,end-start);
|
||||||
|
|
||||||
|
TestParam1 = PropertyManager->GetNode(property1, true);
|
||||||
|
Comparison = mComparison[conditional];
|
||||||
|
if (property2.find_first_not_of("-.0123456789eE") == string::npos) {
|
||||||
|
TestValue = atof(property2.c_str());
|
||||||
|
} else {
|
||||||
|
TestParam2 = PropertyManager->GetNode(property2, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGCondition::InitializeConditionals(void)
|
||||||
|
{
|
||||||
|
mComparison["EQ"] = eEQ;
|
||||||
|
mComparison["NE"] = eNE;
|
||||||
|
mComparison["GT"] = eGT;
|
||||||
|
mComparison["GE"] = eGE;
|
||||||
|
mComparison["LT"] = eLT;
|
||||||
|
mComparison["LE"] = eLE;
|
||||||
|
mComparison["eq"] = eEQ;
|
||||||
|
mComparison["ne"] = eNE;
|
||||||
|
mComparison["gt"] = eGT;
|
||||||
|
mComparison["ge"] = eGE;
|
||||||
|
mComparison["lt"] = eLT;
|
||||||
|
mComparison["le"] = eLE;
|
||||||
|
mComparison["=="] = eEQ;
|
||||||
|
mComparison["!="] = eNE;
|
||||||
|
mComparison[">"] = eGT;
|
||||||
|
mComparison[">="] = eGE;
|
||||||
|
mComparison["<"] = eLT;
|
||||||
|
mComparison["<="] = eLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGCondition::~FGCondition(void)
|
FGCondition::~FGCondition(void)
|
||||||
{
|
{
|
||||||
Debug(1);
|
Debug(1);
|
||||||
|
@ -209,16 +245,6 @@ void FGCondition::PrintCondition(void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
void FGCondition::convert(void)
|
|
||||||
{
|
|
||||||
if (conditions.empty())
|
|
||||||
cout << " " << property1 << " " << conditional << " " << property2 << endl;
|
|
||||||
else
|
|
||||||
for (int i; i<conditions.size(); i++) conditions[i].convert();
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// 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
|
|
@ -37,9 +37,10 @@ SENTRY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "../FGConfigFile.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "../FGPropertyManager.h"
|
#include <FGJSBBase.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -59,7 +60,7 @@ CLASS DOCUMENTATION
|
||||||
|
|
||||||
/** Encapsulates a condition, which is used in parts of JSBSim including switches
|
/** Encapsulates a condition, which is used in parts of JSBSim including switches
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
@ -67,16 +68,14 @@ CLASS DECLARATION
|
||||||
class FGCondition : public FGJSBBase
|
class FGCondition : public FGJSBBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManager);
|
FGCondition(Element* element, FGPropertyManager* PropertyManager);
|
||||||
|
FGCondition(string test, FGPropertyManager* PropertyManager);
|
||||||
~FGCondition(void);
|
~FGCondition(void);
|
||||||
|
|
||||||
bool Evaluate(void);
|
bool Evaluate(void);
|
||||||
void PrintCondition(void);
|
void PrintCondition(void);
|
||||||
void convert(void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGConfigFile* AC_cfg;
|
|
||||||
|
|
||||||
enum eComparison {ecUndef=0, eEQ, eNE, eGT, eGE, eLT, eLE};
|
enum eComparison {ecUndef=0, eEQ, eNE, eGT, eGE, eLT, eLE};
|
||||||
enum eLogic {elUndef=0, eAND, eOR};
|
enum eLogic {elUndef=0, eAND, eOR};
|
||||||
map <string, eComparison> mComparison;
|
map <string, eComparison> mComparison;
|
||||||
|
@ -87,11 +86,11 @@ private:
|
||||||
eComparison Comparison;
|
eComparison Comparison;
|
||||||
bool isGroup;
|
bool isGroup;
|
||||||
string conditional;
|
string conditional;
|
||||||
string property1, property2;
|
|
||||||
|
|
||||||
static string indent;
|
static string indent;
|
||||||
|
|
||||||
vector <FGCondition> conditions;
|
vector <FGCondition> conditions;
|
||||||
|
void InitializeConditionals(void);
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
|
@ -3,7 +3,7 @@
|
||||||
Module: FGDeadBand.cpp
|
Module: FGDeadBand.cpp
|
||||||
Author: Jon S. Berndt
|
Author: Jon S. Berndt
|
||||||
Date started: 11/1999
|
Date started: 11/1999
|
||||||
|
|
||||||
------------- Copyright (C) 2000 -------------
|
------------- Copyright (C) 2000 -------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGDeadBand.h"
|
#include "FGDeadBand.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -54,40 +50,19 @@ CLASS IMPLEMENTATION
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGDeadBand::FGDeadBand(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
FGDeadBand::FGDeadBand(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
AC_cfg(AC_cfg)
|
|
||||||
{
|
{
|
||||||
Type = AC_cfg->GetValue("TYPE");
|
|
||||||
Name = AC_cfg->GetValue("NAME");
|
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
string token;
|
|
||||||
|
|
||||||
clipmax = clipmin = 0.0;
|
|
||||||
clip = false;
|
|
||||||
gain = 1.0;
|
gain = 1.0;
|
||||||
width = 0.0;
|
width = 0.0;
|
||||||
|
|
||||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
if (element->FindElement("width")) {
|
||||||
*AC_cfg >> token;
|
width = element->FindElementValueAsNumber("width");
|
||||||
if (token == "INPUT") {
|
|
||||||
if (InputNodes.size() > 0) {
|
|
||||||
cerr << "Deadband can only accept one input" << endl;
|
|
||||||
} else {
|
|
||||||
*AC_cfg >> token;
|
|
||||||
InputNodes.push_back(resolveSymbol(token));
|
|
||||||
}
|
|
||||||
} else if (token == "WIDTH") {
|
|
||||||
*AC_cfg >> width;
|
|
||||||
} else if (token == "CLIPTO") {
|
|
||||||
*AC_cfg >> clipmin >> clipmax;
|
|
||||||
if (clipmax > clipmin) clip = true;
|
|
||||||
} else if (token == "GAIN") {
|
|
||||||
*AC_cfg >> gain;
|
|
||||||
} else if (token == "OUTPUT") {
|
|
||||||
*AC_cfg >> token;
|
|
||||||
OutputNode = PropertyManager->GetNode(token);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element->FindElement("gain")) {
|
||||||
|
gain = element->FindElementValueAsNumber("gain");
|
||||||
|
}
|
||||||
|
|
||||||
FGFCSComponent::bind();
|
FGFCSComponent::bind();
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
@ -103,9 +78,7 @@ FGDeadBand::~FGDeadBand()
|
||||||
|
|
||||||
bool FGDeadBand::Run(void )
|
bool FGDeadBand::Run(void )
|
||||||
{
|
{
|
||||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||||
|
|
||||||
Input = InputNodes[0]->getDoubleValue();
|
|
||||||
|
|
||||||
if (Input < -width/2.0) {
|
if (Input < -width/2.0) {
|
||||||
Output = (Input + width/2.0)*gain;
|
Output = (Input + width/2.0)*gain;
|
||||||
|
@ -115,43 +88,13 @@ bool FGDeadBand::Run(void )
|
||||||
Output = 0.0;
|
Output = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clip) {
|
Clip();
|
||||||
if (Output > clipmax) Output = clipmax;
|
|
||||||
else if (Output < clipmin) Output = clipmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsOutput) SetOutput();
|
if (IsOutput) SetOutput();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
void FGDeadBand::convert(void)
|
|
||||||
{
|
|
||||||
cout << endl;
|
|
||||||
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
|
|
||||||
|
|
||||||
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
|
|
||||||
|
|
||||||
if (gain != 1.0)
|
|
||||||
cout << " <gain>" << gain << "</gain>" << endl;
|
|
||||||
|
|
||||||
cout << " <width>" << width << "</width>" << endl;
|
|
||||||
|
|
||||||
if (clip) {
|
|
||||||
cout << " <clip>" << endl;
|
|
||||||
cout << " <min>" << clipmin << "</min>" << endl;
|
|
||||||
cout << " <max>" << clipmax << "</max>" << endl;
|
|
||||||
cout << " </clip>" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsOutput)
|
|
||||||
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
|
|
||||||
|
|
||||||
cout << " </component>" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// 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
|
||||||
|
@ -180,7 +123,7 @@ void FGDeadBand::Debug(int from)
|
||||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||||
cout << " DEADBAND WIDTH: " << width << endl;
|
cout << " DEADBAND WIDTH: " << width << endl;
|
||||||
cout << " GAIN: " << gain << endl;
|
cout << " GAIN: " << gain << endl;
|
||||||
if (clip) cout << " CLIPTO: " << clipmin
|
if (clip) cout << " CLIPTO: " << clipmin
|
||||||
<< ", " << clipmax << endl;
|
<< ", " << clipmax << endl;
|
||||||
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
Header: FGDeadBand.h
|
Header: FGDeadBand.h
|
||||||
Author:
|
Author: Jon Berndt
|
||||||
Date started:
|
Date started: 2001
|
||||||
|
|
||||||
------------- Copyright (C) -------------
|
------------- Copyright (C) 2001 Jon S. Berndt -------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -38,7 +38,7 @@ INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGFCSComponent.h"
|
#include "FGFCSComponent.h"
|
||||||
#include "../FGConfigFile.h"
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -81,22 +81,18 @@ CLASS DOCUMENTATION
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
class FGDeadBand : public FGFCSComponent
|
class FGDeadBand : public FGFCSComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGDeadBand(FGFCS* fcs, FGConfigFile* AC_cfg);
|
FGDeadBand(FGFCS* fcs, Element* element);
|
||||||
~FGDeadBand();
|
~FGDeadBand();
|
||||||
|
|
||||||
bool Run(void);
|
bool Run(void);
|
||||||
void convert(void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGConfigFile* AC_cfg;
|
|
||||||
double width;
|
double width;
|
||||||
double clipmax, clipmin;
|
|
||||||
bool clip;
|
|
||||||
double gain;
|
double gain;
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
||||||
}
|
}
|
245
src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
Normal file
245
src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Module: FGFCSComponent.cpp
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 11/1999
|
||||||
|
|
||||||
|
------------- Copyright (C) 2000 -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
COMMENTS, REFERENCES, and NOTES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGFCSComponent.h"
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
static const char *IdSrc = "$Id$";
|
||||||
|
static const char *IdHdr = ID_FCSCOMPONENT;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS IMPLEMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
|
||||||
|
{
|
||||||
|
Element *input_element, *clip_el;
|
||||||
|
Input = Output = clipmin = clipmax = 0.0;
|
||||||
|
OutputNode = treenode = 0;
|
||||||
|
ClipMinPropertyNode = ClipMaxPropertyNode = 0;
|
||||||
|
IsOutput = clip = false;
|
||||||
|
string input, clip_string;
|
||||||
|
|
||||||
|
PropertyManager = fcs->GetPropertyManager();
|
||||||
|
Type = element->GetAttributeValue("type"); // Old, deprecated format
|
||||||
|
if (Type.empty()) {
|
||||||
|
if (element->GetName() == string("lag_filter")) {
|
||||||
|
Type = "LAG_FILTER";
|
||||||
|
} else if (element->GetName() == string("lead_lag_filter")) {
|
||||||
|
Type = "LEAD_LAG_FILTER";
|
||||||
|
} else if (element->GetName() == string("washout_filter")) {
|
||||||
|
Type = "WASHOUT_FILTER";
|
||||||
|
} else if (element->GetName() == string("second_order_filter")) {
|
||||||
|
Type = "SECOND_ORDER_FILTER";
|
||||||
|
} else if (element->GetName() == string("integrator")) {
|
||||||
|
Type = "INTEGRATOR";
|
||||||
|
} else if (element->GetName() == string("summer")) {
|
||||||
|
Type = "SUMMER";
|
||||||
|
} else if (element->GetName() == string("pure_gain")) {
|
||||||
|
Type = "PURE_GAIN";
|
||||||
|
} else if (element->GetName() == string("scheduled_gain")) {
|
||||||
|
Type = "SCHEDULED_GAIN";
|
||||||
|
} else if (element->GetName() == string("aerosurface_scale")) {
|
||||||
|
Type = "AEROSURFACE_SCALE";
|
||||||
|
} else if (element->GetName() == string("switch")) {
|
||||||
|
Type = "SWITCH";
|
||||||
|
} else if (element->GetName() == string("kinematic")) {
|
||||||
|
Type = "KINEMATIC";
|
||||||
|
} else if (element->GetName() == string("deadband")) {
|
||||||
|
Type = "DEADBAND";
|
||||||
|
} else if (element->GetName() == string("fcs_function")) {
|
||||||
|
Type = "FCS_FUNCTION";
|
||||||
|
} else if (element->GetName() == string("sensor")) {
|
||||||
|
Type = "SENSOR";
|
||||||
|
} else { // illegal component in this channel
|
||||||
|
Type = "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Name = element->GetAttributeValue("name");
|
||||||
|
|
||||||
|
input_element = element->FindElement("input");
|
||||||
|
while (input_element) {
|
||||||
|
input = input_element->GetDataLine();
|
||||||
|
if (input[0] == '-') {
|
||||||
|
InputSigns.push_back(-1.0);
|
||||||
|
input.erase(0,1);
|
||||||
|
} else {
|
||||||
|
InputSigns.push_back( 1.0);
|
||||||
|
}
|
||||||
|
InputNodes.push_back( resolveSymbol(input) );
|
||||||
|
input_element = element->FindNextElement("input");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element->FindElement("output")) {
|
||||||
|
IsOutput = true;
|
||||||
|
OutputNode = PropertyManager->GetNode( element->FindElementValue("output") );
|
||||||
|
if (!OutputNode) {
|
||||||
|
cerr << endl << " Unable to process property: " << element->FindElementValue("output") << endl;
|
||||||
|
throw(string("Invalid output property name in flight control definition"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clip_el = element->FindElement("clipto");
|
||||||
|
if (clip_el) {
|
||||||
|
clip_string = clip_el->FindElementValue("min");
|
||||||
|
if (clip_string.find_first_not_of("+-.0123456789") != string::npos) { // it's a property
|
||||||
|
ClipMinPropertyNode = PropertyManager->GetNode( clip_string );
|
||||||
|
} else {
|
||||||
|
clipmin = clip_el->FindElementValueAsNumber("min");
|
||||||
|
}
|
||||||
|
clip_string = clip_el->FindElementValue("max");
|
||||||
|
if (clip_string.find_first_not_of("+-.0123456789") != string::npos) { // it's a property
|
||||||
|
ClipMaxPropertyNode = PropertyManager->GetNode( clip_string );
|
||||||
|
} else {
|
||||||
|
clipmax = clip_el->FindElementValueAsNumber("max");
|
||||||
|
}
|
||||||
|
clip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGFCSComponent::~FGFCSComponent()
|
||||||
|
{
|
||||||
|
// string tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
|
||||||
|
// PropertyManager->Untie( tmp);
|
||||||
|
|
||||||
|
Debug(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCSComponent::SetOutput(void)
|
||||||
|
{
|
||||||
|
OutputNode->setDoubleValue(Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGFCSComponent::Run(void)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCSComponent::Clip(void)
|
||||||
|
{
|
||||||
|
if (clip) {
|
||||||
|
if (ClipMinPropertyNode != 0) clipmin = ClipMinPropertyNode->getDoubleValue();
|
||||||
|
if (ClipMaxPropertyNode != 0) clipmax = ClipMaxPropertyNode->getDoubleValue();
|
||||||
|
if (Output > clipmax) Output = clipmax;
|
||||||
|
else if (Output < clipmin) Output = clipmin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGPropertyManager* FGFCSComponent::resolveSymbol(string token)
|
||||||
|
{
|
||||||
|
string prop;
|
||||||
|
FGPropertyManager* tmp = PropertyManager->GetNode(token,false);
|
||||||
|
if (!tmp) {
|
||||||
|
if (token.find("/") == token.npos) prop = "model/" + token;
|
||||||
|
cerr << "Creating new property " << prop << endl;
|
||||||
|
tmp = PropertyManager->GetNode(token,true);
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCSComponent::bind(void)
|
||||||
|
{
|
||||||
|
string tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
|
||||||
|
PropertyManager->Tie( tmp, this, &FGFCSComponent::GetOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// The bitmasked value choices are as follows:
|
||||||
|
// unset: In this case (the default) JSBSim would only print
|
||||||
|
// out the normally expected messages, essentially echoing
|
||||||
|
// the config files as they are read. If the environment
|
||||||
|
// variable is not set, debug_lvl is set to 1 internally
|
||||||
|
// 0: This requests JSBSim not to output any messages
|
||||||
|
// whatsoever.
|
||||||
|
// 1: This value explicity requests the normal JSBSim
|
||||||
|
// startup messages
|
||||||
|
// 2: This value asks for a message to be printed out when
|
||||||
|
// a class is instantiated
|
||||||
|
// 4: When this value is set, a message is displayed when a
|
||||||
|
// FGModel object executes its Run() method
|
||||||
|
// 8: When this value is set, various runtime state variables
|
||||||
|
// are printed out periodically
|
||||||
|
// 16: When set various parameters are sanity checked and
|
||||||
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
|
void FGFCSComponent::Debug(int from)
|
||||||
|
{
|
||||||
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) {
|
||||||
|
cout << endl << " Loading Component \"" << Name
|
||||||
|
<< "\" of type: " << Type << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
|
if (from == 0) cout << "Instantiated: FGFCSComponent" << endl;
|
||||||
|
if (from == 1) cout << "Destroyed: FGFCSComponent" << endl;
|
||||||
|
}
|
||||||
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
|
}
|
||||||
|
if (debug_lvl & 8 ) { // Runtime state variables
|
||||||
|
}
|
||||||
|
if (debug_lvl & 16) { // Sanity checking
|
||||||
|
}
|
||||||
|
if (debug_lvl & 64) {
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
cout << IdSrc << endl;
|
||||||
|
cout << IdHdr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,8 +43,9 @@ INCLUDES
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../FGJSBBase.h"
|
#include <FGJSBBase.h>
|
||||||
#include "../FGPropertyManager.h"
|
#include <input_output/FGPropertyManager.h>
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -78,11 +79,10 @@ CLASS DOCUMENTATION
|
||||||
- FGDeadBand
|
- FGDeadBand
|
||||||
- FGSummer
|
- FGSummer
|
||||||
- FGGradient
|
- FGGradient
|
||||||
|
|
||||||
@author Jon S. Berndt
|
@author Jon S. Berndt
|
||||||
@version $Id$
|
@version $Id$
|
||||||
@see Documentation for the FGFCS class, and for the configuration file class
|
@see Documentation for the FGFCS class, and for the configuration file class
|
||||||
FGConfigFile.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -93,7 +93,7 @@ class FGFCSComponent : public FGJSBBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
FGFCSComponent(FGFCS*);
|
FGFCSComponent(FGFCS* fcs, Element* el);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~FGFCSComponent();
|
virtual ~FGFCSComponent();
|
||||||
|
|
||||||
|
@ -104,22 +104,28 @@ public:
|
||||||
inline string GetName(void) const {return Name;}
|
inline string GetName(void) const {return Name;}
|
||||||
inline string GetType(void) const { return Type; }
|
inline string GetType(void) const { return Type; }
|
||||||
virtual double GetOutputPct(void) const { return 0; }
|
virtual double GetOutputPct(void) const { return 0; }
|
||||||
virtual void convert(void) {};
|
|
||||||
virtual void bind();
|
|
||||||
FGPropertyManager* resolveSymbol(string token);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FGFCS* fcs;
|
FGFCS* fcs;
|
||||||
FGPropertyManager* PropertyManager;
|
FGPropertyManager* PropertyManager;
|
||||||
FGPropertyManager* treenode;
|
FGPropertyManager* treenode;
|
||||||
string Type;
|
FGPropertyManager* OutputNode;
|
||||||
string Name;
|
FGPropertyManager* ClipMinPropertyNode;
|
||||||
|
FGPropertyManager* ClipMaxPropertyNode;
|
||||||
vector <FGPropertyManager*> InputNodes;
|
vector <FGPropertyManager*> InputNodes;
|
||||||
vector <float> InputSigns;
|
vector <float> InputSigns;
|
||||||
|
string Type;
|
||||||
|
string Name;
|
||||||
double Input;
|
double Input;
|
||||||
FGPropertyManager* OutputNode;
|
|
||||||
double Output;
|
double Output;
|
||||||
|
double clipmax, clipmin;
|
||||||
bool IsOutput;
|
bool IsOutput;
|
||||||
|
bool clip;
|
||||||
|
|
||||||
|
void Clip(void);
|
||||||
|
virtual void bind();
|
||||||
|
FGPropertyManager* resolveSymbol(string token);
|
||||||
|
|
||||||
virtual void Debug(int from);
|
virtual void Debug(int from);
|
||||||
};
|
};
|
||||||
|
|
97
src/FDM/JSBSim/filtersjb/FGFCSComponent.cpp → src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp
Normal file → Executable file
97
src/FDM/JSBSim/filtersjb/FGFCSComponent.cpp → src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp
Normal file → Executable file
|
@ -1,10 +1,10 @@
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
Module: FGFCSComponent.cpp
|
Module: FGFCSFunction.cpp
|
||||||
Author: Jon S. Berndt
|
Author: Jon S. Berndt
|
||||||
Date started: 11/1999
|
Date started: 6/2005
|
||||||
|
|
||||||
------------- Copyright (C) 2000 -------------
|
------------- Copyright (C) 2005 -------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -37,87 +37,54 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#include "FGFCSFunction.h"
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGFCSComponent.h"
|
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
static const char *IdSrc = "$Id$";
|
static const char *IdSrc = "$Id$";
|
||||||
static const char *IdHdr = ID_FCSCOMPONENT;
|
static const char *IdHdr = ID_FCSFUNCTION;
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
CLASS IMPLEMENTATION
|
CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
FGFCSComponent::FGFCSComponent(FGFCS* _fcs) : fcs(_fcs)
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGFCSFunction::FGFCSFunction(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
{
|
{
|
||||||
Type = "";
|
Element *function_element = element->FindElement("function");
|
||||||
Input = 0.0;
|
|
||||||
Output = 0.0;
|
function = new FGFunction(PropertyManager, function_element);
|
||||||
OutputNode = 0;
|
|
||||||
IsOutput = false;
|
FGFCSComponent::bind();
|
||||||
PropertyManager=fcs->GetPropertyManager();
|
|
||||||
treenode = 0;
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGFCSComponent::~FGFCSComponent()
|
FGFCSFunction::~FGFCSFunction()
|
||||||
{
|
{
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGFCSComponent::SetOutput(void)
|
bool FGFCSFunction::Run(void )
|
||||||
{
|
{
|
||||||
OutputNode->setDoubleValue(Output);
|
Output = function->GetValue();
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
if (InputNodes.size() > 0) {
|
||||||
|
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||||
|
Output*= Input;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clip();
|
||||||
|
|
||||||
|
if (IsOutput) SetOutput();
|
||||||
|
|
||||||
bool FGFCSComponent::Run(void)
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
FGPropertyManager* FGFCSComponent::resolveSymbol(string token)
|
|
||||||
{
|
|
||||||
string prop;
|
|
||||||
FGPropertyManager* tmp = PropertyManager->GetNode(token,false);
|
|
||||||
if (!tmp) {
|
|
||||||
if (token.find("/") == token.npos) prop = "model/" + token;
|
|
||||||
//cerr << "Creating new property " << prop << endl;
|
|
||||||
tmp = PropertyManager->GetNode(token,true);
|
|
||||||
}
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
void FGFCSComponent::bind(void)
|
|
||||||
{
|
|
||||||
string tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
|
|
||||||
FGPropertyManager *tmpn;
|
|
||||||
PropertyManager->Tie( tmp,this, &FGFCSComponent::GetOutput);
|
|
||||||
tmp = "fcs/components/" + PropertyManager->mkPropertyName(Name, true);
|
|
||||||
treenode = PropertyManager->GetNode( tmp, true );
|
|
||||||
for(unsigned i=0;i<InputNodes.size();i++) {
|
|
||||||
tmpn=treenode->GetNode( "input-property",(int)i,true );
|
|
||||||
tmpn->setStringValue( InputNodes[i]->GetName().c_str() );
|
|
||||||
}
|
|
||||||
if(OutputNode) treenode->SetString("output-property",OutputNode->GetName());
|
|
||||||
treenode->Tie("output-value",this,&FGFCSComponent::GetOutput);
|
|
||||||
treenode->SetString("type",Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// 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
|
||||||
|
@ -137,15 +104,23 @@ void FGFCSComponent::bind(void)
|
||||||
// 16: When set various parameters are sanity checked and
|
// 16: When set various parameters are sanity checked and
|
||||||
// a message is printed out when they go out of bounds
|
// a message is printed out when they go out of bounds
|
||||||
|
|
||||||
void FGFCSComponent::Debug(int from)
|
void FGFCSFunction::Debug(int from)
|
||||||
{
|
{
|
||||||
if (debug_lvl <= 0) return;
|
if (debug_lvl <= 0) return;
|
||||||
|
|
||||||
if (debug_lvl & 1) { // Standard console startup message output
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
|
if (from == 0) { // Constructor
|
||||||
|
if (InputNodes.size()>0)
|
||||||
|
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||||
|
// cout << " Function: " << endl;
|
||||||
|
if (clip) cout << " CLIPTO: " << clipmin
|
||||||
|
<< ", " << clipmax << endl;
|
||||||
|
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||||
if (from == 0) cout << "Instantiated: FGFCSComponent" << endl;
|
if (from == 0) cout << "Instantiated: FGFCSFunction" << endl;
|
||||||
if (from == 1) cout << "Destroyed: FGFCSComponent" << endl;
|
if (from == 1) cout << "Destroyed: FGFCSFunction" << endl;
|
||||||
}
|
}
|
||||||
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
|
||||||
}
|
}
|
87
src/FDM/JSBSim/models/flight_control/FGFCSFunction.h
Executable file
87
src/FDM/JSBSim/models/flight_control/FGFCSFunction.h
Executable file
|
@ -0,0 +1,87 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: FGFCSFunction.h
|
||||||
|
Author: Jon Berndt
|
||||||
|
Date started: 2005
|
||||||
|
|
||||||
|
------------- Copyright (C) 2005 Jon S. Berndt -------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef FGFCSFUNCTION_H
|
||||||
|
#define FGFCSFUNCTION_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include "FGFCSComponent.h"
|
||||||
|
#include <input_output/FGXMLElement.h>
|
||||||
|
#include <math/FGFunction.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_FCSFUNCTION "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
namespace JSBSim {
|
||||||
|
|
||||||
|
class FGFCS;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
/** Models a FCSFunction object.
|
||||||
|
@author Jon S. Berndt
|
||||||
|
@version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
class FGFCSFunction : public FGFCSComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGFCSFunction(FGFCS* fcs, Element* element);
|
||||||
|
~FGFCSFunction();
|
||||||
|
|
||||||
|
bool Run(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FGFunction* function;
|
||||||
|
|
||||||
|
void Debug(int from);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
#endif
|
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGFilter.h"
|
#include "FGFilter.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -52,16 +48,10 @@ static const char *IdHdr = ID_FILTER;
|
||||||
CLASS IMPLEMENTATION
|
CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
FGFilter::FGFilter(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
AC_cfg(AC_cfg)
|
|
||||||
{
|
{
|
||||||
string token;
|
|
||||||
double denom;
|
double denom;
|
||||||
string sOutputIdx;
|
|
||||||
|
|
||||||
Type = AC_cfg->GetValue("TYPE");
|
|
||||||
Name = AC_cfg->GetValue("NAME");
|
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
dt = fcs->GetState()->Getdt();
|
dt = fcs->GetState()->Getdt();
|
||||||
Trigger = 0;
|
Trigger = 0;
|
||||||
|
|
||||||
|
@ -74,37 +64,14 @@ FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
||||||
else if (Type == "INTEGRATOR") FilterType = eIntegrator ;
|
else if (Type == "INTEGRATOR") FilterType = eIntegrator ;
|
||||||
else FilterType = eUnknown ;
|
else FilterType = eUnknown ;
|
||||||
|
|
||||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
if (element->FindElement("c1")) C1 = element->FindElementValueAsNumber("c1");
|
||||||
*AC_cfg >> token;
|
if (element->FindElement("c2")) C2 = element->FindElementValueAsNumber("c2");
|
||||||
if (token == "C1") *AC_cfg >> C1;
|
if (element->FindElement("c3")) C3 = element->FindElementValueAsNumber("c3");
|
||||||
else if (token == "C2") *AC_cfg >> C2;
|
if (element->FindElement("c4")) C4 = element->FindElementValueAsNumber("c4");
|
||||||
else if (token == "C3") *AC_cfg >> C3;
|
if (element->FindElement("c5")) C5 = element->FindElementValueAsNumber("c5");
|
||||||
else if (token == "C4") *AC_cfg >> C4;
|
if (element->FindElement("c6")) C6 = element->FindElementValueAsNumber("c6");
|
||||||
else if (token == "C5") *AC_cfg >> C5;
|
if (element->FindElement("trigger")) {
|
||||||
else if (token == "C6") *AC_cfg >> C6;
|
Trigger = resolveSymbol(element->FindElementValue("trigger"));
|
||||||
else if (token == "TRIGGER")
|
|
||||||
{
|
|
||||||
token = AC_cfg->GetValue("TRIGGER");
|
|
||||||
*AC_cfg >> token;
|
|
||||||
Trigger = resolveSymbol(token);
|
|
||||||
}
|
|
||||||
else if (token == "INPUT")
|
|
||||||
{
|
|
||||||
token = AC_cfg->GetValue("INPUT");
|
|
||||||
if( InputNodes.size() > 0 ) {
|
|
||||||
cerr << "Filters can only accept one input" << endl;
|
|
||||||
} else {
|
|
||||||
*AC_cfg >> token;
|
|
||||||
InputNodes.push_back( resolveSymbol(token) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (token == "OUTPUT")
|
|
||||||
{
|
|
||||||
IsOutput = true;
|
|
||||||
*AC_cfg >> sOutputIdx;
|
|
||||||
OutputNode = PropertyManager->GetNode( sOutputIdx );
|
|
||||||
}
|
|
||||||
else cerr << "Unknown filter type: " << token << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Initialize = true;
|
Initialize = true;
|
||||||
|
@ -157,25 +124,16 @@ FGFilter::~FGFilter()
|
||||||
|
|
||||||
bool FGFilter::Run(void)
|
bool FGFilter::Run(void)
|
||||||
{
|
{
|
||||||
int test = 0;
|
double test = 0.0;
|
||||||
|
|
||||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
|
||||||
|
|
||||||
if (Initialize) {
|
if (Initialize) {
|
||||||
|
|
||||||
PreviousOutput1 = PreviousInput1 = Output = Input;
|
PreviousOutput1 = PreviousInput1 = Output = Input;
|
||||||
Initialize = false;
|
Initialize = false;
|
||||||
|
|
||||||
} else if (Trigger != 0) {
|
|
||||||
test = Trigger->getIntValue();
|
|
||||||
if (test < 0) {
|
|
||||||
Input = PreviousInput1 = PreviousInput2 = 0.0;
|
|
||||||
} else {
|
|
||||||
Output = PreviousOutput1 = PreviousOutput2 = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Input = InputNodes[0]->getDoubleValue();
|
|
||||||
|
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||||
switch (FilterType) {
|
switch (FilterType) {
|
||||||
case eLag:
|
case eLag:
|
||||||
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
|
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
|
||||||
|
@ -191,6 +149,12 @@ bool FGFilter::Run(void)
|
||||||
Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
|
Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
|
||||||
break;
|
break;
|
||||||
case eIntegrator:
|
case eIntegrator:
|
||||||
|
if (Trigger != 0) {
|
||||||
|
test = Trigger->getDoubleValue();
|
||||||
|
if (fabs(test) > 0.000001) {
|
||||||
|
Input = PreviousInput1 = PreviousInput2 = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1;
|
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1;
|
||||||
break;
|
break;
|
||||||
case eUnknown:
|
case eUnknown:
|
||||||
|
@ -204,35 +168,12 @@ bool FGFilter::Run(void)
|
||||||
PreviousInput2 = PreviousInput1;
|
PreviousInput2 = PreviousInput1;
|
||||||
PreviousInput1 = Input;
|
PreviousInput1 = Input;
|
||||||
|
|
||||||
|
Clip();
|
||||||
if (IsOutput) SetOutput();
|
if (IsOutput) SetOutput();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
void FGFilter::convert(void)
|
|
||||||
{
|
|
||||||
cout << endl;
|
|
||||||
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
|
|
||||||
|
|
||||||
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
|
|
||||||
|
|
||||||
if (C1 != 0) cout << " <c1>" << C1 << "</c1>" << endl;
|
|
||||||
if (C2 != 0) cout << " <c2>" << C2 << "</c2>" << endl;
|
|
||||||
if (C3 != 0) cout << " <c3>" << C3 << "</c3>" << endl;
|
|
||||||
if (C4 != 0) cout << " <c4>" << C4 << "</c4>" << endl;
|
|
||||||
if (C5 != 0) cout << " <c5>" << C5 << "</c5>" << endl;
|
|
||||||
if (C6 != 0) cout << " <c6>" << C6 << "</c6>" << endl;
|
|
||||||
|
|
||||||
if (Trigger != 0) cout << " <trigger>" << Trigger << "</trigger>" << endl;
|
|
||||||
|
|
||||||
if (IsOutput)
|
|
||||||
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
|
|
||||||
|
|
||||||
cout << " </component>" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// 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
|
|
@ -38,7 +38,7 @@ INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGFCSComponent.h"
|
#include "FGFCSComponent.h"
|
||||||
#include "../FGConfigFile.h"
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -62,75 +62,75 @@ Tustin substitution is used to take filter definitions from LaPlace space to the
|
||||||
time domain. The general format for a filter specification is:
|
time domain. The general format for a filter specification is:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="name" TYPE="type">
|
\<component name="name" type="type">
|
||||||
INPUT \<property>
|
\<input> property \</input>
|
||||||
C1 \<value>
|
\<c1> value \<c/1>
|
||||||
[C2 \<value>]
|
[\<c2> value \<c/2>]
|
||||||
[C3 \<value>]
|
[\<c3> value \<c/3>]
|
||||||
[C4 \<value>]
|
[\<c4> value \<c/4>]
|
||||||
[C5 \<value>]
|
[\<c5> value \<c/5>]
|
||||||
[C6 \<value>]
|
[\<c6> value \<c/6>]
|
||||||
[OUTPUT \<property>]
|
[\<output> property \<output>]
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
For a lag filter of the form,
|
For a lag filter of the form,
|
||||||
<pre>
|
<pre>
|
||||||
C1
|
C1
|
||||||
------
|
------
|
||||||
s + C1
|
s + C1
|
||||||
</pre>
|
</pre>
|
||||||
the corresponding filter definition is:
|
the corresponding filter definition is:
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="name" TYPE="LAG_FILTER">
|
\<component name="name" type="LAG_FILTER">
|
||||||
INPUT \<property>
|
\<input> property \</input>
|
||||||
C1 \<value>
|
\<c1> value \<c/1>
|
||||||
[OUTPUT \<property>]
|
[\<output> property \<output>]
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
As an example, for the specific filter:
|
As an example, for the specific filter:
|
||||||
<pre>
|
<pre>
|
||||||
600
|
600
|
||||||
------
|
------
|
||||||
s + 600
|
s + 600
|
||||||
</pre>
|
</pre>
|
||||||
the corresponding filter definition could be:
|
the corresponding filter definition could be:
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="LAG_1" TYPE="LAG_FILTER">
|
\<component name="Heading Roll Error Lag" type="LAG_FILTER">
|
||||||
INPUT aileron_cmd
|
\<input> fcs/heading-command \</input>
|
||||||
C1 600
|
\<c1> 600 \</c1>
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
For a lead-lag filter of the form:
|
For a lead-lag filter of the form:
|
||||||
<pre>
|
<pre>
|
||||||
C1*s + C2
|
C1*s + C2
|
||||||
---------
|
---------
|
||||||
C3*s + C4
|
C3*s + C4
|
||||||
</pre>
|
</pre>
|
||||||
The corresponding filter definition is:
|
The corresponding filter definition is:
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="name" TYPE="LEAD_LAG_FILTER">
|
\<component name="name" type="LEAD_LAG_FILTER">
|
||||||
INPUT \<property>
|
\<input> property \</input>
|
||||||
C1 \<value>
|
\<c1> value \<c/1>
|
||||||
C2 \<value>
|
\<c2> value \<c/2>
|
||||||
C3 \<value>
|
\<c3> value \<c/3>
|
||||||
C4 \<value>
|
\<c4> value \<c/4>
|
||||||
[OUTPUT \<property>]
|
[\<output> property \<output>]
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
For a washout filter of the form:
|
For a washout filter of the form:
|
||||||
<pre>
|
<pre>
|
||||||
s
|
s
|
||||||
------
|
------
|
||||||
s + C1
|
s + C1
|
||||||
</pre>
|
</pre>
|
||||||
The corresponding filter definition is:
|
The corresponding filter definition is:
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="name" TYPE="WASHOUT_FILTER">
|
\<component name="name" type="WASHOUT_FILTER">
|
||||||
INPUT \<property>
|
\<input> property \</input>
|
||||||
C1 \<value>
|
\<c1> value \</c1>
|
||||||
[OUTPUT \<property>]
|
[\<output> property \<output>]
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
For a second order filter of the form:
|
For a second order filter of the form:
|
||||||
<pre>
|
<pre>
|
||||||
|
@ -140,16 +140,16 @@ C4*s^2 + C5*s + C6
|
||||||
</pre>
|
</pre>
|
||||||
The corresponding filter definition is:
|
The corresponding filter definition is:
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="name" TYPE="SECOND_ORDER_FILTER">
|
\<component name="name" type="SECOND_ORDER_FILTER">
|
||||||
INPUT \<property>
|
\<input> property \</input>
|
||||||
C1 \<value>
|
\<c1> value \<c/1>
|
||||||
C2 \<value>
|
\<c2> value \<c/2>
|
||||||
C3 \<value>
|
\<c3> value \<c/3>
|
||||||
C4 \<value>
|
\<c4> value \<c/4>
|
||||||
C5 \<value>
|
\<c5> value \<c/5>
|
||||||
C6 \<value>
|
\<c6> value \<c/6>
|
||||||
[OUTPUT \<property>]
|
[\<output> property \<output>]
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
For an integrator of the form:
|
For an integrator of the form:
|
||||||
<pre>
|
<pre>
|
||||||
|
@ -159,35 +159,35 @@ For an integrator of the form:
|
||||||
</pre>
|
</pre>
|
||||||
The corresponding filter definition is:
|
The corresponding filter definition is:
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="name" TYPE="INTEGRATOR">
|
\<component name="name" type="INTEGRATOR">
|
||||||
INPUT \<property>
|
\<input> property \</input>
|
||||||
C1 \<value>
|
\<c1> value \<c/1>
|
||||||
[OUTPUT \<property>]
|
[\<trigger> property \</trigger>]
|
||||||
[TRIGGER \<property>]
|
[\<output> property \<output>]
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
For the integrator, the TRIGGER features the following behavior, if the TRIGGER
|
For the integrator, the trigger features the following behavior. If the trigger
|
||||||
property value is:
|
property value is:
|
||||||
- -1 (or simply less than zero), all previous inputs and outputs are set to 0.0
|
- 0: no action is taken - the output is calculated normally
|
||||||
- 0, no action is taken - the output is calculated normally
|
- not 0: (or simply greater than zero), all current and previous inputs will
|
||||||
- +1 (or simply greater than zero), all previous outputs (only) will be set to 0.0
|
be set to 0.0
|
||||||
|
|
||||||
In all the filter specifications above, an [OUTPUT] keyword is also seen. This
|
In all the filter specifications above, an \<output> element is also seen. This
|
||||||
is so that the last component in a "string" can copy its value to the appropriate
|
is so that the last component in a "string" can copy its value to the appropriate
|
||||||
output, such as the elevator, or speedbrake, etc.
|
output, such as the elevator, or speedbrake, etc.
|
||||||
|
|
||||||
@author Jon S. Berndt
|
@author Jon S. Berndt
|
||||||
@version $Id$
|
@version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
class FGFilter : public FGFCSComponent
|
class FGFilter : public FGFCSComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg);
|
FGFilter(FGFCS* fcs, Element* element);
|
||||||
~FGFilter();
|
~FGFilter();
|
||||||
|
|
||||||
bool Run (void);
|
bool Run (void);
|
||||||
|
@ -195,7 +195,6 @@ public:
|
||||||
/** When true, causes previous values to be set to current values. This
|
/** When true, causes previous values to be set to current values. This
|
||||||
is particularly useful for first pass. */
|
is particularly useful for first pass. */
|
||||||
bool Initialize;
|
bool Initialize;
|
||||||
void convert(void);
|
|
||||||
|
|
||||||
enum {eLag, eLeadLag, eOrder2, eWashout, eIntegrator, eUnknown} FilterType;
|
enum {eLag, eLeadLag, eOrder2, eWashout, eIntegrator, eUnknown} FilterType;
|
||||||
|
|
||||||
|
@ -216,7 +215,6 @@ private:
|
||||||
double PreviousInput2;
|
double PreviousInput2;
|
||||||
double PreviousOutput1;
|
double PreviousOutput1;
|
||||||
double PreviousOutput2;
|
double PreviousOutput2;
|
||||||
FGConfigFile* AC_cfg;
|
|
||||||
FGPropertyManager* Trigger;
|
FGPropertyManager* Trigger;
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGGain.h"
|
#include "FGGain.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -52,81 +48,74 @@ static const char *IdHdr = ID_GAIN;
|
||||||
CLASS IMPLEMENTATION
|
CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
FGGain::FGGain(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
|
||||||
AC_cfg(AC_cfg)
|
|
||||||
{
|
{
|
||||||
string token;
|
Element *scale_element, *zero_centered;
|
||||||
string strScheduledBy;
|
string strScheduledBy, gain_string, sZeroCentered;
|
||||||
string sOutputIdx;
|
|
||||||
|
|
||||||
State = fcs->GetState();
|
|
||||||
|
|
||||||
|
GainPropertyNode = 0;
|
||||||
Gain = 1.000;
|
Gain = 1.000;
|
||||||
Rows = 0;
|
Rows = 0;
|
||||||
Min = Max = 0.0;
|
Table = 0;
|
||||||
OutputPct = 0;
|
InMin = -1.0;
|
||||||
invert = false;
|
InMax = 1.0;
|
||||||
ScheduledBy = 0;
|
OutMin = OutMax = 0.0;
|
||||||
clip = false;
|
|
||||||
clipmin = clipmax = 0.0;
|
|
||||||
|
|
||||||
Type = AC_cfg->GetValue("TYPE");
|
if (Type == "PURE_GAIN") {
|
||||||
Name = AC_cfg->GetValue("NAME");
|
if ( !element->FindElement("gain") ) {
|
||||||
AC_cfg->GetNextConfigLine();
|
cout << highint << " No GAIN specified (default: 1.0)" << normint << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
if ( element->FindElement("gain") ) {
|
||||||
*AC_cfg >> token;
|
gain_string = element->FindElementValue("gain");
|
||||||
if (token == "INPUT") {
|
if (gain_string.find_first_not_of("+-.0123456789") != string::npos) { // property
|
||||||
*AC_cfg >> token;
|
GainPropertyNode = PropertyManager->GetNode(gain_string);
|
||||||
|
|
||||||
if (token[0] == '-') {
|
|
||||||
invert = true;
|
|
||||||
token.erase(0,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InputNodes.size() > 0) {
|
|
||||||
cerr << "Gains can only accept one input" << endl;
|
|
||||||
} else {
|
|
||||||
InputNodes.push_back( resolveSymbol(token) );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (token == "GAIN") {
|
|
||||||
*AC_cfg >> Gain;
|
|
||||||
} else if (token == "MIN") {
|
|
||||||
*AC_cfg >> Min;
|
|
||||||
} else if (token == "MAX") {
|
|
||||||
*AC_cfg >> Max;
|
|
||||||
} else if (token == "CLIPTO") {
|
|
||||||
*AC_cfg >> clipmin >> clipmax;
|
|
||||||
if (clipmax > clipmin) {
|
|
||||||
clip = true;
|
|
||||||
}
|
|
||||||
} else if (token == "INVERT") {
|
|
||||||
invert = true;
|
|
||||||
cerr << endl << "The INVERT keyword is being deprecated and will not be "
|
|
||||||
"supported in the future. Please use a minus sign in front "
|
|
||||||
"of an input property in the future." << endl << endl;
|
|
||||||
} else if (token == "ROWS") {
|
|
||||||
*AC_cfg >> Rows;
|
|
||||||
Table = new FGTable(Rows);
|
|
||||||
} else if (token == "SCHEDULED_BY") {
|
|
||||||
token = AC_cfg->GetValue("SCHEDULED_BY");
|
|
||||||
*AC_cfg >> strScheduledBy;
|
|
||||||
ScheduledBy = PropertyManager->GetNode( strScheduledBy );
|
|
||||||
} else if (token == "OUTPUT") {
|
|
||||||
IsOutput = true;
|
|
||||||
*AC_cfg >> sOutputIdx;
|
|
||||||
OutputNode = PropertyManager->GetNode( sOutputIdx, true );
|
|
||||||
} else {
|
} else {
|
||||||
AC_cfg->ResetLineIndexToZero();
|
Gain = element->FindElementValueAsNumber("gain");
|
||||||
*Table << *AC_cfg;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type == "AEROSURFACE_SCALE") {
|
||||||
|
scale_element = element->FindElement("domain");
|
||||||
|
if (scale_element) {
|
||||||
|
if (scale_element->FindElement("max") && scale_element->FindElement("min") )
|
||||||
|
{
|
||||||
|
InMax = scale_element->FindElementValueAsNumber("max");
|
||||||
|
InMin = scale_element->FindElementValueAsNumber("min");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scale_element = element->FindElement("range");
|
||||||
|
if (!scale_element) throw(string("No range supplied for aerosurface scale component"));
|
||||||
|
if (scale_element->FindElement("max") && scale_element->FindElement("min") )
|
||||||
|
{
|
||||||
|
OutMax = scale_element->FindElementValueAsNumber("max");
|
||||||
|
OutMin = scale_element->FindElementValueAsNumber("min");
|
||||||
|
} else {
|
||||||
|
cerr << "Maximum and minimum output values must be supplied for the "
|
||||||
|
"aerosurface scale component" << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
ZeroCentered = true;
|
||||||
|
zero_centered = element->FindElement("zero_centered");
|
||||||
|
if (zero_centered) {
|
||||||
|
sZeroCentered = zero_centered->FindElementValue("zero_centered");
|
||||||
|
if (sZeroCentered == string("0") || sZeroCentered == string("false")) {
|
||||||
|
ZeroCentered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type == "SCHEDULED_GAIN") {
|
||||||
|
if (element->FindElement("table")) {
|
||||||
|
Table = new FGTable(PropertyManager, element->FindElement("table"));
|
||||||
|
} else {
|
||||||
|
cerr << "A table must be provided for the scheduled gain component" << endl;
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FGFCSComponent::bind();
|
FGFCSComponent::bind();
|
||||||
if (Type == "AEROSURFACE_SCALE")
|
|
||||||
treenode->Tie( "output-norm", this, &FGGain::GetOutputPct );
|
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
@ -143,12 +132,10 @@ FGGain::~FGGain()
|
||||||
bool FGGain::Run(void )
|
bool FGGain::Run(void )
|
||||||
{
|
{
|
||||||
double SchedGain = 1.0;
|
double SchedGain = 1.0;
|
||||||
double LookupVal = 0;
|
|
||||||
|
|
||||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||||
Input = InputNodes[0]->getDoubleValue();
|
|
||||||
|
|
||||||
if (invert) Input = -Input;
|
if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue();
|
||||||
|
|
||||||
if (Type == "PURE_GAIN") { // PURE_GAIN
|
if (Type == "PURE_GAIN") { // PURE_GAIN
|
||||||
|
|
||||||
|
@ -156,72 +143,32 @@ bool FGGain::Run(void )
|
||||||
|
|
||||||
} else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
|
} else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
|
||||||
|
|
||||||
LookupVal = ScheduledBy->getDoubleValue();
|
SchedGain = Table->GetValue();
|
||||||
SchedGain = Table->GetValue(LookupVal);
|
|
||||||
Output = Gain * SchedGain * Input;
|
Output = Gain * SchedGain * Input;
|
||||||
|
|
||||||
} else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
|
} else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
|
||||||
|
|
||||||
OutputPct = Input;
|
if (ZeroCentered) {
|
||||||
if (Input >= 0.0) Output = Input * Max;
|
if (Input == 0.0) {
|
||||||
else Output = Input * -Min;
|
Output = 0.0;
|
||||||
|
} else if (Input > 0) {
|
||||||
|
Output = (Input / InMax) * OutMax;
|
||||||
|
} else {
|
||||||
|
Output = (Input / InMin) * OutMin;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Output = OutMin + ((Input - InMin) / (InMax - InMin)) * (OutMax - OutMin);
|
||||||
|
}
|
||||||
|
|
||||||
Output *= Gain;
|
Output *= Gain;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clip) {
|
|
||||||
if (Output > clipmax) Output = clipmax;
|
|
||||||
else if (Output < clipmin) Output = clipmin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Clip();
|
||||||
if (IsOutput) SetOutput();
|
if (IsOutput) SetOutput();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
void FGGain::convert(void)
|
|
||||||
{
|
|
||||||
cout << endl;
|
|
||||||
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
|
|
||||||
|
|
||||||
if (invert)
|
|
||||||
cout << " <input>-" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
|
|
||||||
else
|
|
||||||
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
|
|
||||||
|
|
||||||
if (Gain != 1.0)
|
|
||||||
cout << " <gain>" << Gain << "</gain>" << endl;
|
|
||||||
|
|
||||||
if (Type == "PURE_GAIN") { // PURE_GAIN
|
|
||||||
} else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
|
|
||||||
cout << " <table>" << endl;
|
|
||||||
cout << " <independentVar>" << ScheduledBy->GetFullyQualifiedName().substr(12) << "</independentVar>" << endl;
|
|
||||||
cout << " <tableData>" << endl;
|
|
||||||
Table->Print(20);
|
|
||||||
cout << " </tableData>" << endl;
|
|
||||||
cout << " </table>" << endl;
|
|
||||||
} else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
|
|
||||||
cout << " <limit>" << endl;
|
|
||||||
cout << " <min>" << Min << "</min>" << endl;
|
|
||||||
cout << " <max>" << Max << "</max>" << endl;
|
|
||||||
cout << " </limit>" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clip) {
|
|
||||||
cout << " <clip>" << endl;
|
|
||||||
cout << " <min>" << clipmin << "</min>" << endl;
|
|
||||||
cout << " <max>" << clipmax << "</max>" << endl;
|
|
||||||
cout << " </clip>" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsOutput)
|
|
||||||
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
|
|
||||||
|
|
||||||
cout << " </component>" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// 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
|
||||||
|
@ -247,17 +194,22 @@ void FGGain::Debug(int from)
|
||||||
|
|
||||||
if (debug_lvl & 1) { // Standard console startup message output
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
if (from == 0) { // Constructor
|
if (from == 0) { // Constructor
|
||||||
if (invert)
|
if (InputSigns[0] < 0)
|
||||||
cout << " INPUT: -" << InputNodes[0]->getName() << endl;
|
cout << " INPUT: -" << InputNodes[0]->getName() << endl;
|
||||||
else
|
else
|
||||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||||
|
|
||||||
cout << " GAIN: " << Gain << endl;
|
cout << " GAIN: " << Gain << endl;
|
||||||
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
||||||
cout << " MIN: " << Min << endl;
|
if (Type == "AEROSURFACE_SCALE") {
|
||||||
cout << " MAX: " << Max << endl;
|
cout << " In/Out Mapping:" << endl;
|
||||||
if (ScheduledBy != 0) {
|
cout << " Input MIN: " << InMin << endl;
|
||||||
cout << " Scheduled by parameter: " << ScheduledBy->getName() << endl;
|
cout << " Input MAX: " << InMax << endl;
|
||||||
|
cout << " Output MIN: " << OutMin << endl;
|
||||||
|
cout << " Output MAX: " << OutMax << endl;
|
||||||
|
}
|
||||||
|
if (Table != 0) {
|
||||||
|
cout << " Scheduled by table: " << endl;
|
||||||
Table->Print();
|
Table->Print();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,8 +46,8 @@ INCLUDES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "FGFCSComponent.h"
|
#include "FGFCSComponent.h"
|
||||||
#include "../FGConfigFile.h"
|
#include <input_output/FGXMLElement.h>
|
||||||
#include "../FGTable.h"
|
#include <math/FGTable.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -71,11 +71,11 @@ CLASS DOCUMENTATION
|
||||||
The gain component merely multiplies the input by a gain. The form of the
|
The gain component merely multiplies the input by a gain. The form of the
|
||||||
gain component specification is:
|
gain component specification is:
|
||||||
<pre>
|
<pre>
|
||||||
\<COMPONENT NAME="name" TYPE="PURE_GAIN">
|
\<component name="name" type="PURE_GAIN">
|
||||||
INPUT \<property>
|
\<input> property \</input>
|
||||||
GAIN \<value>
|
\<gain> value \</gain>
|
||||||
[OUTPUT \<property>]
|
[\<output> property \</output>]
|
||||||
\</COMPONENT>
|
\</component>
|
||||||
</pre>
|
</pre>
|
||||||
Note: as is the case with the Summer component, the input property name may be
|
Note: as is the case with the Summer component, the input property name may be
|
||||||
immediately preceded by a minus sign to invert that signal.
|
immediately preceded by a minus sign to invert that signal.
|
||||||
|
@ -169,24 +169,18 @@ CLASS DECLARATION
|
||||||
class FGGain : public FGFCSComponent
|
class FGGain : public FGFCSComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGGain(FGFCS* fcs, FGConfigFile* AC_cfg);
|
FGGain(FGFCS* fcs, Element* element);
|
||||||
~FGGain();
|
~FGGain();
|
||||||
|
|
||||||
double GetOutputPct() const { return OutputPct; }
|
|
||||||
void convert(void);
|
|
||||||
bool Run (void);
|
bool Run (void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGConfigFile* AC_cfg;
|
|
||||||
FGTable* Table;
|
FGTable* Table;
|
||||||
FGState* State;
|
FGPropertyManager* GainPropertyNode;
|
||||||
double Gain;
|
double Gain;
|
||||||
double Min, Max;
|
double InMin, InMax, OutMin, OutMax;
|
||||||
double clipmin, clipmax;
|
|
||||||
double OutputPct;
|
|
||||||
bool invert, clip;
|
|
||||||
int Rows;
|
int Rows;
|
||||||
FGPropertyManager* ScheduledBy;
|
bool ZeroCentered;
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
|
@ -1,9 +1,9 @@
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
Module: FGGradient.cpp
|
Module: FGGradient.cpp
|
||||||
Author:
|
Author:
|
||||||
Date started:
|
Date started:
|
||||||
|
|
||||||
------------- Copyright (C) 2000 -------------
|
------------- Copyright (C) 2000 -------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "FGGradient.h"
|
#include "FGGradient.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
@ -53,12 +49,8 @@ CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
FGGradient::FGGradient(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
FGGradient::FGGradient(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
AC_cfg(AC_cfg)
|
|
||||||
{
|
{
|
||||||
Type = AC_cfg->GetValue("TYPE");
|
|
||||||
Name = AC_cfg->GetValue("NAME");
|
|
||||||
|
|
||||||
FGFCSComponent::bind();
|
FGFCSComponent::bind();
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
|
@ -75,8 +67,6 @@ FGGradient::~FGGradient()
|
||||||
|
|
||||||
bool FGGradient::Run(void )
|
bool FGGradient::Run(void )
|
||||||
{
|
{
|
||||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGFCSComponent.h"
|
#include "FGFCSComponent.h"
|
||||||
#include "../FGConfigFile.h"
|
#include <input_output/FGXMLElement.h>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -68,13 +68,12 @@ CLASS DECLARATION
|
||||||
class FGGradient : public FGFCSComponent
|
class FGGradient : public FGFCSComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGGradient(FGFCS* fcs, FGConfigFile* AC_cfg);
|
FGGradient(FGFCS* fcs, Element* element);
|
||||||
~FGGradient();
|
~FGGradient();
|
||||||
|
|
||||||
bool Run (void);
|
bool Run (void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGConfigFile* AC_cfg;
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
|
@ -55,57 +51,39 @@ static const char *IdHdr = ID_FLAPS;
|
||||||
CLASS IMPLEMENTATION
|
CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
FGKinemat::FGKinemat(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
FGKinemat::FGKinemat(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
AC_cfg(AC_cfg)
|
|
||||||
{
|
{
|
||||||
string token,sOutputIdx;
|
Element *traverse_element, *setting_element;
|
||||||
double tmpDetent;
|
double tmpDetent;
|
||||||
double tmpTime;
|
double tmpTime;
|
||||||
|
|
||||||
Detents.clear();
|
Detents.clear();
|
||||||
TransitionTimes.clear();
|
TransitionTimes.clear();
|
||||||
|
|
||||||
OutputPct=0;
|
Output = OutputPct = 0;
|
||||||
DoScale = true;
|
DoScale = true;
|
||||||
|
|
||||||
Type = AC_cfg->GetValue("TYPE");
|
if (element->FindElement("noscale")) DoScale = false;
|
||||||
Name = AC_cfg->GetValue("NAME");
|
|
||||||
AC_cfg->GetNextConfigLine();
|
|
||||||
|
|
||||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
traverse_element = element->FindElement("traverse");
|
||||||
*AC_cfg >> token;
|
setting_element = traverse_element->FindElement("setting");
|
||||||
if (token == "INPUT") {
|
while (setting_element) {
|
||||||
token = AC_cfg->GetValue("INPUT");
|
tmpDetent = setting_element->FindElementValueAsNumber("position");
|
||||||
if( InputNodes.size() > 0 ) {
|
tmpTime = setting_element->FindElementValueAsNumber("time");
|
||||||
cerr << "Kinemat can only accept one input" << endl;
|
Detents.push_back(tmpDetent);
|
||||||
} else {
|
TransitionTimes.push_back(tmpTime);
|
||||||
*AC_cfg >> token;
|
setting_element = traverse_element->FindNextElement("setting");
|
||||||
InputNodes.push_back( resolveSymbol(token) );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ( token == "DETENTS" ) {
|
|
||||||
*AC_cfg >> NumDetents;
|
|
||||||
if (NumDetents < 2) {
|
|
||||||
cerr << "Kinemat must have at least 2 DETENTS" << endl;
|
|
||||||
}
|
|
||||||
for (int i=0;i<NumDetents;i++) {
|
|
||||||
*AC_cfg >> tmpDetent;
|
|
||||||
*AC_cfg >> tmpTime;
|
|
||||||
Detents.push_back(tmpDetent);
|
|
||||||
TransitionTimes.push_back(tmpTime);
|
|
||||||
}
|
|
||||||
} else if (token == "OUTPUT") {
|
|
||||||
|
|
||||||
IsOutput = true;
|
|
||||||
*AC_cfg >> sOutputIdx;
|
|
||||||
OutputNode = PropertyManager->GetNode(sOutputIdx, true);
|
|
||||||
} else if (token == "NOSCALE") {
|
|
||||||
|
|
||||||
DoScale = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
NumDetents = Detents.size();
|
||||||
|
|
||||||
|
if (NumDetents <= 1) {
|
||||||
|
cerr << "Kinematic component " << Name
|
||||||
|
<< " must have more than 1 setting element" << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
FGFCSComponent::bind();
|
FGFCSComponent::bind();
|
||||||
treenode->Tie("output-norm", this, &FGKinemat::GetOutputPct );
|
// treenode->Tie("output-norm", this, &FGKinemat::GetOutputPct );
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
@ -123,11 +101,11 @@ bool FGKinemat::Run(void )
|
||||||
{
|
{
|
||||||
double dt = fcs->GetState()->Getdt();
|
double dt = fcs->GetState()->Getdt();
|
||||||
|
|
||||||
Input = InputNodes[0]->getDoubleValue();
|
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||||
|
|
||||||
if (DoScale) Input *= Detents[NumDetents-1];
|
if (DoScale) Input *= Detents[NumDetents-1];
|
||||||
|
|
||||||
Output = OutputNode->getDoubleValue();
|
if (IsOutput) Output = OutputNode->getDoubleValue();
|
||||||
|
|
||||||
if (Input < Detents[0])
|
if (Input < Detents[0])
|
||||||
Input = Detents[0];
|
Input = Detents[0];
|
||||||
|
@ -177,35 +155,12 @@ bool FGKinemat::Run(void )
|
||||||
|
|
||||||
OutputPct = (Output-Detents[0])/(Detents[NumDetents-1]-Detents[0]);
|
OutputPct = (Output-Detents[0])/(Detents[NumDetents-1]-Detents[0]);
|
||||||
|
|
||||||
|
Clip();
|
||||||
if (IsOutput) SetOutput();
|
if (IsOutput) SetOutput();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
void FGKinemat::convert(void)
|
|
||||||
{
|
|
||||||
cout << endl;
|
|
||||||
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
|
|
||||||
|
|
||||||
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
|
|
||||||
|
|
||||||
cout << " <traverse>" << endl;
|
|
||||||
for (int i=0; i<Detents.size(); i++) {
|
|
||||||
cout << " <setting>" << endl;
|
|
||||||
cout << " <position>" << Detents[i] << "</position>" << endl;
|
|
||||||
cout << " <time>" << TransitionTimes[i] << "</time>" << endl;
|
|
||||||
cout << " </setting>" << endl;
|
|
||||||
}
|
|
||||||
cout << " </traverse>" << endl;
|
|
||||||
|
|
||||||
if (IsOutput)
|
|
||||||
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
|
|
||||||
|
|
||||||
cout << " </component>" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// 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
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue