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/ExternalPipe/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/SP/Makefile \
|
||||
src/FDM/UIUCModel/Makefile \
|
||||
|
|
|
@ -41,10 +41,6 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
# include STL_IOSTREAM
|
||||
|
@ -60,21 +56,22 @@ INCLUDES
|
|||
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGState.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGFCS.h"
|
||||
#include "FGGroundCallback.h"
|
||||
#include "FGPropulsion.h"
|
||||
#include "FGMassBalance.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGPropagate.h"
|
||||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include <models/FGAtmosphere.h>
|
||||
#include <models/atmosphere/FGMSIS.h>
|
||||
#include <models/atmosphere/FGMars.h>
|
||||
#include <models/FGFCS.h>
|
||||
#include <models/FGPropulsion.h>
|
||||
#include <models/FGMassBalance.h>
|
||||
#include <models/FGGroundReactions.h>
|
||||
#include <models/FGAerodynamics.h>
|
||||
#include <models/FGInertial.h>
|
||||
#include <models/FGAircraft.h>
|
||||
#include <models/FGPropagate.h>
|
||||
#include <models/FGAuxiliary.h>
|
||||
#include <models/FGInput.h>
|
||||
#include <models/FGOutput.h>
|
||||
#include <initialization/FGInitialCondition.h>
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -110,12 +107,13 @@ void checkTied ( FGPropertyManager *node )
|
|||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// Constructor
|
||||
|
||||
FGFDMExec::FGFDMExec(FGPropertyManager* root)
|
||||
FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
|
||||
{
|
||||
|
||||
Frame = 0;
|
||||
FirstModel = 0;
|
||||
Error = 0;
|
||||
GroundCallback = 0;
|
||||
State = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
|
@ -125,22 +123,25 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
|
|||
Inertial = 0;
|
||||
GroundReactions = 0;
|
||||
Aircraft = 0;
|
||||
GroundCallback = 0;
|
||||
Propagate = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
Input = 0;
|
||||
IC = 0;
|
||||
Trim = 0;
|
||||
|
||||
terminate = false;
|
||||
frozen = false;
|
||||
modelLoaded = false;
|
||||
IsSlave = false;
|
||||
holding = false;
|
||||
|
||||
|
||||
// Multiple FDM's are stopped for now. We need to ensure that
|
||||
// the "user" instance always gets the zeroeth instance number,
|
||||
// because there may be instruments or scripts tied to properties
|
||||
// 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;
|
||||
//FDMctr++;
|
||||
|
||||
|
@ -151,31 +152,35 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
|
|||
debug_lvl = 1;
|
||||
}
|
||||
|
||||
if (root == 0) master= new FGPropertyManager;
|
||||
else master = root;
|
||||
if (Root == 0) master= new FGPropertyManager;
|
||||
else master = Root;
|
||||
|
||||
instance = master->GetNode("/fdm/jsbsim",IdFDM,true);
|
||||
|
||||
|
||||
Debug(0);
|
||||
|
||||
// this is here to catch errors in binding member functions
|
||||
// to the property tree.
|
||||
// this is to catch errors in binding member functions to the property tree.
|
||||
try {
|
||||
Allocate();
|
||||
} catch ( string msg ) {
|
||||
cout << "Caught error: " << msg << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Constructing = true;
|
||||
typedef int (FGFDMExec::*iPMF)(void) const;
|
||||
instance->Tie("simulation/do_trim", this, (iPMF)0, &FGFDMExec::DoTrim);
|
||||
Constructing = false;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGFDMExec::~FGFDMExec()
|
||||
{
|
||||
instance->Untie("simulation/do_trim");
|
||||
|
||||
try {
|
||||
DeAllocate();
|
||||
checkTied( instance );
|
||||
if (Root == 0) delete master;
|
||||
} catch ( string msg ) {
|
||||
cout << "Caught error: " << msg << endl;
|
||||
}
|
||||
|
@ -200,14 +205,14 @@ bool FGFDMExec::Allocate(void)
|
|||
Inertial = new FGInertial(this);
|
||||
GroundReactions = new FGGroundReactions(this);
|
||||
Aircraft = new FGAircraft(this);
|
||||
GroundCallback = new FGGroundCallback();
|
||||
Propagate = new FGPropagate(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
|
||||
// class needs valid pointers to the above
|
||||
// model classes
|
||||
GroundCallback = new FGGroundCallback();
|
||||
State = new FGState(this); // This must be done here, as the FGState
|
||||
// class needs valid pointers to the above
|
||||
// model classes
|
||||
|
||||
// Initialize models so they can communicate with each other
|
||||
|
||||
|
@ -237,23 +242,23 @@ bool FGFDMExec::Allocate(void)
|
|||
Error+=128;}
|
||||
if (!Propagate->InitModel()) {
|
||||
cerr << fgred << "Propagate model init failed" << fgdef << endl;
|
||||
Error+=512;}
|
||||
Error+=256;}
|
||||
if (!Auxiliary->InitModel()) {
|
||||
cerr << fgred << "Auxiliary model init failed" << fgdef << endl;
|
||||
Error+=2058;}
|
||||
if (!Output->InitModel()) {
|
||||
cerr << fgred << "Output model init failed" << fgdef << endl;
|
||||
Error+=4096;}
|
||||
Error+=512;}
|
||||
if (!Input->InitModel()) {
|
||||
cerr << fgred << "Input model init failed" << fgdef << endl;
|
||||
Error+=1024;}
|
||||
|
||||
if (Error > 0) result = false;
|
||||
|
||||
IC = new FGInitialCondition(this);
|
||||
|
||||
// Schedule a model. The second arg (the integer) is the pass number. For
|
||||
// instance, the atmosphere model gets executed every fifth pass it is called
|
||||
// by the executive. Everything else here gets executed each pass.
|
||||
// IC and Trim objects are NOT scheduled.
|
||||
// instance, the atmosphere model could get executed every fifth pass it is called
|
||||
// by the executive. IC and Trim objects are NOT scheduled.
|
||||
|
||||
Schedule(Input, 1);
|
||||
Schedule(Atmosphere, 1);
|
||||
Schedule(FCS, 1);
|
||||
Schedule(Propulsion, 1);
|
||||
|
@ -264,7 +269,6 @@ bool FGFDMExec::Allocate(void)
|
|||
Schedule(Aircraft, 1);
|
||||
Schedule(Propagate, 1);
|
||||
Schedule(Auxiliary, 1);
|
||||
Schedule(Output, 1);
|
||||
|
||||
modelLoaded = false;
|
||||
|
||||
|
@ -275,6 +279,7 @@ bool FGFDMExec::Allocate(void)
|
|||
|
||||
bool FGFDMExec::DeAllocate(void)
|
||||
{
|
||||
delete Input;
|
||||
delete Atmosphere;
|
||||
delete FCS;
|
||||
delete Propulsion;
|
||||
|
@ -285,9 +290,14 @@ bool FGFDMExec::DeAllocate(void)
|
|||
delete Aircraft;
|
||||
delete Propagate;
|
||||
delete Auxiliary;
|
||||
delete Output;
|
||||
delete State;
|
||||
|
||||
for (int i=0; i<Outputs.size(); i++) {
|
||||
if (Outputs[i]) delete Outputs[i];
|
||||
}
|
||||
|
||||
Outputs.clear();
|
||||
|
||||
delete IC;
|
||||
delete Trim;
|
||||
|
||||
|
@ -297,6 +307,7 @@ bool FGFDMExec::DeAllocate(void)
|
|||
Error = 0;
|
||||
|
||||
State = 0;
|
||||
Input = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
Propulsion = 0;
|
||||
|
@ -307,7 +318,6 @@ bool FGFDMExec::DeAllocate(void)
|
|||
Aircraft = 0;
|
||||
Propagate = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
|
||||
modelLoaded = false;
|
||||
return modelLoaded;
|
||||
|
@ -346,8 +356,6 @@ bool FGFDMExec::Run(void)
|
|||
{
|
||||
FGModel* model_iterator;
|
||||
|
||||
if (frozen) return true;
|
||||
|
||||
model_iterator = FirstModel;
|
||||
if (model_iterator == 0L) return false;
|
||||
|
||||
|
@ -364,27 +372,29 @@ bool FGFDMExec::Run(void)
|
|||
}
|
||||
|
||||
frame = Frame++;
|
||||
State->IncrTime();
|
||||
if (!Holding()) State->IncrTime();
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// This call will cause the sim time to reset to 0.0
|
||||
|
||||
bool FGFDMExec::RunIC(void)
|
||||
{
|
||||
State->Suspend();
|
||||
State->SuspendIntegration();
|
||||
State->Initialize(IC);
|
||||
Run();
|
||||
State->Resume();
|
||||
State->ResumeIntegration();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFDMExec::SetGroundCallback(FGGroundCallback* p) {
|
||||
if (GroundCallback)
|
||||
delete GroundCallback;
|
||||
void FGFDMExec::SetGroundCallback(FGGroundCallback* p)
|
||||
{
|
||||
if (GroundCallback) delete GroundCallback;
|
||||
|
||||
GroundCallback = p;
|
||||
}
|
||||
|
||||
|
@ -408,7 +418,6 @@ vector <string> FGFDMExec::EnumerateFDMs(void)
|
|||
bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model,
|
||||
bool addModelToPath)
|
||||
{
|
||||
|
||||
FGFDMExec::AircraftPath = AircraftPath;
|
||||
FGFDMExec::EnginePath = EnginePath;
|
||||
|
||||
|
@ -417,13 +426,15 @@ bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string model,
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
||||
{
|
||||
|
||||
bool result = true;
|
||||
string token;
|
||||
string aircraftCfgFileName;
|
||||
string separator = "/";
|
||||
|
||||
# ifdef macintosh
|
||||
separator = ";";
|
||||
# endif
|
||||
|
||||
if( AircraftPath.empty() || EnginePath.empty() ) {
|
||||
cerr << "Error: attempted to load aircraft with undefined ";
|
||||
|
@ -432,16 +443,16 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
|||
}
|
||||
|
||||
aircraftCfgFileName = AircraftPath;
|
||||
# ifndef macintosh
|
||||
if (addModelToPath) aircraftCfgFileName += "/" + model;
|
||||
aircraftCfgFileName += "/" + model + ".xml";
|
||||
# else
|
||||
if (addModelToPath) aircraftCfgFileName += ";" + model;
|
||||
aircraftCfgFileName += ";" + model + ".xml";
|
||||
# endif
|
||||
if (addModelToPath) aircraftCfgFileName += separator + model;
|
||||
aircraftCfgFileName += separator + model + ".xml";
|
||||
|
||||
FGConfigFile AC_cfg(aircraftCfgFileName);
|
||||
if (!AC_cfg.IsOpen()) return false;
|
||||
FGXMLParse *XMLParse = new FGXMLParse();
|
||||
Element* element = 0L;
|
||||
Element* document;
|
||||
|
||||
ifstream input_file(aircraftCfgFileName.c_str());
|
||||
readXML(input_file, *XMLParse);
|
||||
document = XMLParse->GetDocument();
|
||||
|
||||
modelName = model;
|
||||
|
||||
|
@ -450,36 +461,35 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
|||
Allocate();
|
||||
}
|
||||
|
||||
if (!ReadPrologue(&AC_cfg)) return false;
|
||||
ReadPrologue(document);
|
||||
element = document->GetElement();
|
||||
|
||||
while ((AC_cfg.GetNextConfigLine() != string("EOF")) &&
|
||||
(token = AC_cfg.GetValue()) != string("/FDM_CONFIG")) {
|
||||
if (token == "METRICS") {
|
||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Metrics" << fgdef << endl;
|
||||
if (!ReadMetrics(&AC_cfg)) result = false;
|
||||
} else if (token == "SLAVE") {
|
||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Slave flight vehicle: " << fgdef
|
||||
<< AC_cfg.GetValue("NAME") << endl;
|
||||
if (!ReadSlave(&AC_cfg)) result = false;
|
||||
} else if (token == "AERODYNAMICS") {
|
||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Aerodynamics" << fgdef << endl;
|
||||
if (!ReadAerodynamics(&AC_cfg)) result = false;
|
||||
} else if (token == "UNDERCARRIAGE") {
|
||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Landing Gear" << fgdef << endl;
|
||||
if (!ReadUndercarriage(&AC_cfg)) result = false;
|
||||
} else if (token == "PROPULSION") {
|
||||
if (debug_lvl > 0) cout << fgcyan << "\n Reading Propulsion" << fgdef << endl;
|
||||
if (!ReadPropulsion(&AC_cfg)) result = false;
|
||||
} else if (token == "FLIGHT_CONTROL") {
|
||||
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;
|
||||
bool result = true;
|
||||
while (element && result) {
|
||||
string element_name = element->GetName();
|
||||
if (element_name == "fileheader" ) result = ReadFileHeader(element);
|
||||
else if (element_name == "slave") result = ReadSlave(element);
|
||||
else if (element_name == "metrics") result = Aircraft->Load(element);
|
||||
else if (element_name == "mass_balance") result = MassBalance->Load(element);
|
||||
else if (element_name == "ground_reactions") result = GroundReactions->Load(element);
|
||||
else if (element_name == "propulsion") result = Propulsion->Load(element);
|
||||
else if (element_name == "autopilot") result = FCS->Load(element);
|
||||
else if (element_name == "flight_control") result = FCS->Load(element);
|
||||
else if (element_name == "aerodynamics") result = Aerodynamics->Load(element);
|
||||
else if (element_name == "input") result = Input->Load(element);
|
||||
else if (element_name == "output") {
|
||||
FGOutput* Output = new FGOutput(this);
|
||||
Output->InitModel();
|
||||
Schedule(Output, 1);
|
||||
Outputs.push_back(Output);
|
||||
result = Output->Load(element);
|
||||
}
|
||||
else {
|
||||
cerr << "Found unexpected subsystem: " << element_name << ", exiting." << endl;
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
element = document->GetNextElement();
|
||||
}
|
||||
|
||||
if (result) {
|
||||
|
@ -487,32 +497,93 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
|||
Debug(3);
|
||||
} else {
|
||||
cerr << fgred
|
||||
<< " FGFDMExec: Failed to load aircraft and/or engine model"
|
||||
<< " JSBSim failed to load aircraft and/or engine model"
|
||||
<< fgdef << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct PropertyCatalogStructure masterPCS;
|
||||
masterPCS.base_string = "";
|
||||
masterPCS.node = (FGPropertyManager*)master;
|
||||
|
||||
BuildPropertyCatalog(&masterPCS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
|
||||
void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
|
||||
{
|
||||
string token = AC_cfg->GetValue();
|
||||
string scratch;
|
||||
string AircraftName;
|
||||
struct PropertyCatalogStructure* pcsNew = new struct PropertyCatalogStructure;
|
||||
int node_idx = 0;
|
||||
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);
|
||||
|
||||
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;
|
||||
scratch = AC_cfg->GetValue("VERSION").c_str();
|
||||
|
||||
CFGVersion = AC_cfg->GetValue("VERSION");
|
||||
Release = AC_cfg->GetValue("RELEASE");
|
||||
CFGVersion = el->GetAttributeValue("version");
|
||||
Release = el->GetAttributeValue("release");
|
||||
|
||||
if (debug_lvl > 0)
|
||||
if (debug_lvl & 1)
|
||||
cout << " Version: " << highint << CFGVersion
|
||||
<< normint << endl;
|
||||
if (CFGVersion != needed_cfg_version) {
|
||||
|
@ -523,10 +594,7 @@ bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Release == "ALPHA" && debug_lvl > 0) {
|
||||
#ifndef _MSC_VER
|
||||
system("banner ALPHA");
|
||||
#endif
|
||||
if (Release == "ALPHA" && (debug_lvl & 1)) {
|
||||
cout << endl << endl
|
||||
<< highint << "This aircraft model is an " << fgred << Release
|
||||
<< reset << highint << " release!!!" << endl << endl << reset
|
||||
|
@ -534,24 +602,33 @@ bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
|
|||
<< " will not fly as expected." << endl << endl
|
||||
<< fgred << highint << "Use this model for development purposes ONLY!!!"
|
||||
<< normint << reset << endl << endl;
|
||||
} else if (Release == "BETA" && debug_lvl > 0) {
|
||||
#ifndef _MSC_VER
|
||||
system("banner BETA");
|
||||
#endif
|
||||
} else if (Release == "BETA" && (debug_lvl & 1)) {
|
||||
cout << endl << endl
|
||||
<< highint << "This aircraft model is a " << fgred << Release
|
||||
<< reset << highint << " release!!!" << endl << endl << reset
|
||||
<< "This aircraft model probably will not fly as expected." << endl << endl
|
||||
<< fgblue << highint << "Use this model for development purposes ONLY!!!"
|
||||
<< 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
|
||||
// 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.back()->exec = new FGFDMExec();
|
||||
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
|
||||
|
||||
|
@ -580,15 +657,15 @@ bool FGFDMExec::ReadSlave(FGConfigFile* AC_cfg)
|
|||
AC_cfg->GetNextConfigLine();
|
||||
while ((token = AC_cfg->GetValue()) != string("/SLAVE")) {
|
||||
*AC_cfg >> token;
|
||||
if (token == "XLOC") { *AC_cfg >> SlaveFDMList.back()->x; }
|
||||
else if (token == "YLOC") { *AC_cfg >> SlaveFDMList.back()->y; }
|
||||
else if (token == "ZLOC") { *AC_cfg >> SlaveFDMList.back()->z; }
|
||||
else if (token == "PITCH") { *AC_cfg >> SlaveFDMList.back()->pitch;}
|
||||
else if (token == "YAW") { *AC_cfg >> SlaveFDMList.back()->yaw; }
|
||||
else if (token == "ROLL") { *AC_cfg >> SlaveFDMList.back()->roll; }
|
||||
if (token == "xloc") { *AC_cfg >> SlaveFDMList.back()->x; }
|
||||
else if (token == "yloc") { *AC_cfg >> SlaveFDMList.back()->y; }
|
||||
else if (token == "zloc") { *AC_cfg >> SlaveFDMList.back()->z; }
|
||||
else if (token == "pitch") { *AC_cfg >> SlaveFDMList.back()->pitch;}
|
||||
else if (token == "yaw") { *AC_cfg >> SlaveFDMList.back()->yaw; }
|
||||
else if (token == "roll") { *AC_cfg >> SlaveFDMList.back()->roll; }
|
||||
else cerr << "Unknown identifier: " << token << " in slave vehicle definition" << endl;
|
||||
}
|
||||
|
||||
*/
|
||||
if (debug_lvl > 0) {
|
||||
cout << " X = " << SlaveFDMList.back()->x << 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;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGTrim* FGFDMExec::GetTrim(void) {
|
||||
FGTrim* FGFDMExec::GetTrim(void)
|
||||
{
|
||||
delete Trim;
|
||||
Trim = new FGTrim(this,tNone);
|
||||
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:
|
||||
// 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 (from == 2) {
|
||||
cout << "================== Frame: " << Frame << " Time: "
|
||||
<< State->Getsim_time() << endl;
|
||||
<< State->Getsim_time() << " dt: " << State->Getdt() << endl;
|
||||
}
|
||||
}
|
||||
if (debug_lvl & 8 ) { // Runtime state variables
|
||||
|
@ -737,3 +817,4 @@ void FGFDMExec::Debug(int from)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,13 +40,16 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGTrim.h"
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGGroundCallback.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include "FGPropagate.h"
|
||||
#include <models/FGModel.h>
|
||||
#include <models/FGOutput.h>
|
||||
#include <models/FGInput.h>
|
||||
#include <initialization/FGTrim.h>
|
||||
#include <initialization/FGInitialCondition.h>
|
||||
#include <FGJSBBase.h>
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include <input_output/FGXMLParse.h>
|
||||
#include <input_output/FGGroundCallback.h>
|
||||
#include <models/FGPropagate.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -74,8 +77,7 @@ CLASS DOCUMENTATION
|
|||
|
||||
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
|
||||
corresponding "ReadXXX()" method is called. From within this method the
|
||||
"Load()" method of that system is called (e.g. LoadFCS).
|
||||
corresponding Load() method is called (e.g. LoadFCS).
|
||||
|
||||
<h4>JSBSim Debugging Directives</h4>
|
||||
|
||||
|
@ -134,17 +136,12 @@ public:
|
|||
|
||||
/** Initializes the sim from the initial condition object and executes
|
||||
each scheduled model without integrating i.e. dt=0.
|
||||
@return true if successful
|
||||
*/
|
||||
@return true if successful */
|
||||
bool RunIC(void);
|
||||
|
||||
/// Freezes the sim
|
||||
void Freeze(void) {frozen = true;}
|
||||
|
||||
/// Resumes the sim
|
||||
void Resume(void) {frozen = false;}
|
||||
|
||||
void SetGroundCallback(FGGroundCallback*);
|
||||
/** Sets the ground callback pointer.
|
||||
@param gc A pointer to a ground callback object. */
|
||||
void SetGroundCallback(FGGroundCallback* gc);
|
||||
|
||||
/** Loads an aircraft model.
|
||||
@param AircraftPath path to the aircraft directory. For instance:
|
||||
|
@ -162,7 +159,6 @@ public:
|
|||
bool LoadModel(string AircraftPath, string EnginePath, string model,
|
||||
bool addModelToPath = true);
|
||||
|
||||
|
||||
/** Loads an aircraft model. The paths to the aircraft and engine
|
||||
config file directories must be set prior to calling this. See
|
||||
below.
|
||||
|
@ -175,37 +171,23 @@ public:
|
|||
@return true if successful*/
|
||||
bool LoadModel(string model, bool addModelToPath = true);
|
||||
|
||||
|
||||
/** Sets the path to the engine config file directories.
|
||||
@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; }
|
||||
|
||||
/** Sets the path to the aircraft config file directories.
|
||||
@param path path to the aircraft directory. For instance:
|
||||
"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; }
|
||||
|
||||
/** 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
|
||||
//@{
|
||||
/// Returns the FGState pointer.
|
||||
inline FGState* GetState(void) {return State;}
|
||||
/// Returns the FGAtmosphere pointer.
|
||||
inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
|
||||
/// Returns the FGFCS pointer.
|
||||
inline FGFCS* GetFCS(void) {return FCS;}
|
||||
/// Returns the FGGroundCallback pointer.
|
||||
inline FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
|
||||
/// Returns the FGPropulsion pointer.
|
||||
inline FGPropulsion* GetPropulsion(void) {return Propulsion;}
|
||||
/// Returns the FGAircraft pointer.
|
||||
|
@ -222,41 +204,100 @@ public:
|
|||
inline FGPropagate* GetPropagate(void) {return Propagate;}
|
||||
/// Returns the FGAuxiliary pointer.
|
||||
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
|
||||
/// Returns the FGOutput pointer.
|
||||
inline FGOutput* GetOutput(void) {return Output;}
|
||||
/// Returns the FGInput pointer.
|
||||
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
|
||||
inline FGInitialCondition* GetIC(void) {return IC;}
|
||||
// Returns a pointer to the FGTrim object
|
||||
FGTrim* GetTrim(void);
|
||||
inline FGTrim* GetTrim(void);
|
||||
//@}
|
||||
|
||||
/// Retrieves the engine path.
|
||||
inline string GetEnginePath(void) {return EnginePath;}
|
||||
/// Retrieves the aircraft path.
|
||||
inline string GetAircraftPath(void) {return AircraftPath;}
|
||||
// /// Retrieves the control path.
|
||||
// inline string GetControlPath(void) {return ControlPath;}
|
||||
|
||||
/// Returns the model name.
|
||||
string GetModelName(void) { return modelName; }
|
||||
|
||||
/// Returns a pointer to the property manager object.
|
||||
FGPropertyManager* GetPropertyManager(void);
|
||||
/// Returns a vector of strings representing the names of all loaded models (future)
|
||||
vector <string> EnumerateFDMs(void);
|
||||
/// Marks this instance of the Exec object as a "slave" object.
|
||||
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:
|
||||
FGModel* FirstModel;
|
||||
|
||||
bool frozen;
|
||||
bool terminate;
|
||||
bool holding;
|
||||
bool Constructing;
|
||||
int Error;
|
||||
unsigned int Frame;
|
||||
unsigned int IdFDM;
|
||||
FGPropertyManager* Root;
|
||||
static unsigned int FDMctr;
|
||||
bool modelLoaded;
|
||||
string modelName;
|
||||
bool IsSlave;
|
||||
static FGPropertyManager *master;
|
||||
FGPropertyManager *instance;
|
||||
vector <string> PropertyCatalog;
|
||||
|
||||
struct slaveData {
|
||||
FGFDMExec* exec;
|
||||
|
@ -279,15 +320,14 @@ private:
|
|||
|
||||
string AircraftPath;
|
||||
string EnginePath;
|
||||
// string ControlPath;
|
||||
|
||||
string CFGVersion;
|
||||
string Release;
|
||||
|
||||
FGGroundCallback* GroundCallback;
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGGroundCallback* GroundCallback;
|
||||
FGPropulsion* Propulsion;
|
||||
FGMassBalance* MassBalance;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
|
@ -296,21 +336,17 @@ private:
|
|||
FGAircraft* Aircraft;
|
||||
FGPropagate* Propagate;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
FGInput* Input;
|
||||
vector <FGOutput*> Outputs;
|
||||
|
||||
FGInitialCondition* IC;
|
||||
FGTrim *Trim;
|
||||
|
||||
vector <slaveData*> SlaveFDMList;
|
||||
|
||||
bool ReadMetrics(FGConfigFile*);
|
||||
bool ReadSlave(FGConfigFile*);
|
||||
bool ReadPropulsion(FGConfigFile*);
|
||||
bool ReadFlightControls(FGConfigFile*);
|
||||
bool ReadAerodynamics(FGConfigFile*);
|
||||
bool ReadUndercarriage(FGConfigFile*);
|
||||
bool ReadPrologue(FGConfigFile*);
|
||||
bool ReadOutput(FGConfigFile*);
|
||||
bool ReadFileHeader(Element*);
|
||||
bool ReadSlave(Element*);
|
||||
bool ReadPrologue(Element*);
|
||||
|
||||
bool Allocate(void);
|
||||
bool DeAllocate(void);
|
||||
|
|
|
@ -76,6 +76,7 @@ const double FGJSBBase::radtodeg = 57.29578;
|
|||
const double FGJSBBase::degtorad = 1.745329E-2;
|
||||
const double FGJSBBase::hptoftlbssec = 550.0;
|
||||
const double FGJSBBase::psftoinhg = 0.014138;
|
||||
const double FGJSBBase::psftopa = 47.88;
|
||||
const double FGJSBBase::fpstokts = 0.592484;
|
||||
const double FGJSBBase::ktstofps = 1.68781;
|
||||
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::lbtoslug = 1.0/slugtolb;
|
||||
|
||||
const string FGJSBBase::needed_cfg_version = "1.65";
|
||||
const string FGJSBBase::JSBSim_version = "0.9.5";
|
||||
const string FGJSBBase::needed_cfg_version = "2.0";
|
||||
const string FGJSBBase::JSBSim_version = "0.9.10.111805";
|
||||
|
||||
std::queue <FGJSBBase::Message*> FGJSBBase::Messages;
|
||||
FGJSBBase::Message FGJSBBase::localMsg;
|
||||
|
|
|
@ -42,18 +42,18 @@ INCLUDES
|
|||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
# include <simgear/constants.h>
|
||||
# include <math.h>
|
||||
# include <queue>
|
||||
# include STL_STRING
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
# ifndef M_PI
|
||||
# define M_PI SG_PI
|
||||
# endif
|
||||
# ifndef M_PI
|
||||
# include <simgear/constants.h>
|
||||
# define M_PI SG_PI
|
||||
# endif
|
||||
|
||||
#else
|
||||
#else // JSBSim section
|
||||
|
||||
# include <queue>
|
||||
# include <string>
|
||||
|
@ -65,13 +65,27 @@ SG_USING_STD(string);
|
|||
|
||||
using std::string;
|
||||
|
||||
# ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
# endif
|
||||
# if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||
# ifndef max
|
||||
# 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
|
||||
|
||||
#if !defined(WIN32) || defined(__GNUC__) || ( defined(_MSC_VER) && (_MSC_VER >= 1400))
|
||||
#if !defined(WIN32) || defined(__GNUC__)
|
||||
using std::max;
|
||||
#endif
|
||||
|
||||
|
@ -92,6 +106,8 @@ CLASS DOCUMENTATION
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** JSBSim Base class.
|
||||
* This class provides universal constants, utility functions, messaging
|
||||
* functions, and enumerated constants to JSBSim.
|
||||
@author Jon S. Berndt
|
||||
@version $Id$
|
||||
*/
|
||||
|
@ -178,23 +194,40 @@ public:
|
|||
@return pointer to a Message structure (or NULL if no mesage) */
|
||||
Message* ProcessMessage(void);
|
||||
//@}
|
||||
|
||||
/** Returns the version number of JSBSim.
|
||||
* @return The version number of JSBSim. */
|
||||
string GetVersion(void) {return JSBSim_version;}
|
||||
|
||||
/// Disables highlighting in the console output.
|
||||
void disableHighLighting(void);
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
return celsius * 1.8 + 32.0;
|
||||
}
|
||||
|
@ -247,6 +280,7 @@ protected:
|
|||
static const double degtorad;
|
||||
static const double hptoftlbssec;
|
||||
static const double psftoinhg;
|
||||
static const double psftopa;
|
||||
static const double fpstokts;
|
||||
static const double ktstofps;
|
||||
static const double inchtoft;
|
||||
|
@ -257,8 +291,8 @@ protected:
|
|||
static const double slugtolb;
|
||||
static const string needed_cfg_version;
|
||||
static const string JSBSim_version;
|
||||
};
|
||||
|
||||
public:
|
||||
/// Moments L, M, N
|
||||
enum {eL = 1, eM, eN };
|
||||
/// Rates P, Q, R
|
||||
|
@ -280,6 +314,8 @@ enum {eLat = 1, eLong, eRad };
|
|||
/// Conversion specifiers
|
||||
enum {inNone = 0, inDegrees, inRadians, inMeters, inFeet };
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#endif
|
||||
|
|
|
@ -36,10 +36,6 @@ HISTORY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
# include <math.h>
|
||||
|
@ -81,7 +77,6 @@ FGState::FGState(FGFDMExec* fdex)
|
|||
Propagate = FDMExec->GetPropagate();
|
||||
Auxiliary = FDMExec->GetAuxiliary();
|
||||
FCS = FDMExec->GetFCS();
|
||||
Output = FDMExec->GetOutput();
|
||||
Atmosphere = FDMExec->GetAtmosphere();
|
||||
Aerodynamics = FDMExec->GetAerodynamics();
|
||||
GroundReactions = FDMExec->GetGroundReactions();
|
||||
|
|
|
@ -59,20 +59,19 @@ INCLUDES
|
|||
#include <string>
|
||||
#include <map>
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGQuaternion.h"
|
||||
#include <initialization/FGInitialCondition.h>
|
||||
#include <math/FGMatrix33.h>
|
||||
#include <math/FGColumnVector3.h>
|
||||
#include <math/FGQuaternion.h>
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGFCS.h"
|
||||
#include "FGPropagate.h"
|
||||
#include "FGAuxiliary.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include "FGOutput.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGPropulsion.h"
|
||||
#include <models/FGAtmosphere.h>
|
||||
#include <models/FGFCS.h>
|
||||
#include <models/FGPropagate.h>
|
||||
#include <models/FGAuxiliary.h>
|
||||
#include <models/FGAerodynamics.h>
|
||||
#include <models/FGAircraft.h>
|
||||
#include <models/FGGroundReactions.h>
|
||||
#include <models/FGPropulsion.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -117,12 +116,16 @@ public:
|
|||
/// Returns the simulation time in seconds.
|
||||
inline double Getsim_time(void) const { return sim_time; }
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
@param cur_time the current time
|
||||
|
@ -136,7 +139,9 @@ public:
|
|||
/** Sets the integration time step for the simulation executive.
|
||||
@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.
|
||||
@return the new simulation time.
|
||||
|
@ -174,7 +179,6 @@ private:
|
|||
|
||||
FGAircraft* Aircraft;
|
||||
FGPropagate* Propagate;
|
||||
FGOutput* Output;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
|
|
|
@ -47,30 +47,35 @@
|
|||
#include <Main/globals.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 <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
|
||||
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() );
|
||||
|
||||
// Register ground callback.
|
||||
|
@ -288,9 +289,6 @@ void FGJSBsim::init()
|
|||
// Explicitly call the superclass's
|
||||
// init method first.
|
||||
|
||||
#ifdef FG_WEATHERCM
|
||||
Atmosphere->UseInternal();
|
||||
#else
|
||||
if (fgGetBool("/environment/params/control-fdm-atmosphere")) {
|
||||
Atmosphere->UseExternal();
|
||||
Atmosphere->SetExTemperature(
|
||||
|
@ -307,7 +305,6 @@ void FGJSBsim::init()
|
|||
} else {
|
||||
Atmosphere->UseInternal();
|
||||
}
|
||||
#endif
|
||||
|
||||
fgic->SetVnorthFpsIC( wind_from_north->getDoubleValue() );
|
||||
fgic->SetVeastFpsIC( wind_from_east->getDoubleValue() );
|
||||
|
@ -339,9 +336,9 @@ void FGJSBsim::init()
|
|||
switch(fgic->GetSpeedSet()) {
|
||||
case setned:
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, " Vn,Ve,Vd= "
|
||||
<< Propagate->GetVel(eNorth) << ", "
|
||||
<< Propagate->GetVel(eEast) << ", "
|
||||
<< Propagate->GetVel(eDown) << " ft/s");
|
||||
<< Propagate->GetVel(FGJSBBase::eNorth) << ", "
|
||||
<< Propagate->GetVel(FGJSBBase::eEast) << ", "
|
||||
<< Propagate->GetVel(FGJSBBase::eDown) << " ft/s");
|
||||
break;
|
||||
case setuvw:
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, " U,V,W= "
|
||||
|
@ -363,11 +360,11 @@ void FGJSBsim::init()
|
|||
stall_warning->setDoubleValue(0);
|
||||
|
||||
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: "
|
||||
<< Propagate->GetEuler(eTht)*RADTODEG << " deg" );
|
||||
<< Propagate->GetEuler(FGJSBBase::eTht)*RADTODEG << " deg" );
|
||||
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: "
|
||||
<< Propagate->GetLocation().GetLatitudeDeg() << " deg" );
|
||||
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
|
||||
// autopilot (and the rest of the sim can use the updated values
|
||||
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->SetMixtureCmd(i, globals->get_controls()->get_mixture(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()) {
|
||||
case FGEngine::etPiston:
|
||||
|
@ -557,6 +549,17 @@ bool FGJSBsim::copy_to_JSBsim()
|
|||
FGRocket* eng = (FGRocket*)Propulsion->GetEngine(i);
|
||||
break;
|
||||
} // 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
|
||||
|
@ -636,18 +639,18 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
|
||||
// Velocities
|
||||
|
||||
_set_Velocities_Local( Propagate->GetVel(eNorth),
|
||||
Propagate->GetVel(eEast),
|
||||
Propagate->GetVel(eDown) );
|
||||
_set_Velocities_Local( Propagate->GetVel(FGJSBBase::eNorth),
|
||||
Propagate->GetVel(FGJSBBase::eEast),
|
||||
Propagate->GetVel(FGJSBBase::eDown) );
|
||||
|
||||
_set_Velocities_Wind_Body( Propagate->GetUVW(1),
|
||||
Propagate->GetUVW(2),
|
||||
Propagate->GetUVW(3) );
|
||||
|
||||
// Make the HUD work ...
|
||||
_set_Velocities_Ground( Propagate->GetVel(eNorth),
|
||||
Propagate->GetVel(eEast),
|
||||
-Propagate->GetVel(eDown) );
|
||||
_set_Velocities_Ground( Propagate->GetVel(FGJSBBase::eNorth),
|
||||
Propagate->GetVel(FGJSBBase::eEast),
|
||||
-Propagate->GetVel(FGJSBBase::eDown) );
|
||||
|
||||
_set_V_rel_wind( Auxiliary->GetVt() );
|
||||
|
||||
|
@ -657,13 +660,13 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
|
||||
_set_V_ground_speed( Auxiliary->GetVground() );
|
||||
|
||||
_set_Omega_Body( Propagate->GetPQR(eP),
|
||||
Propagate->GetPQR(eQ),
|
||||
Propagate->GetPQR(eR) );
|
||||
_set_Omega_Body( Propagate->GetPQR(FGJSBBase::eP),
|
||||
Propagate->GetPQR(FGJSBBase::eQ),
|
||||
Propagate->GetPQR(FGJSBBase::eR) );
|
||||
|
||||
_set_Euler_Rates( Auxiliary->GetEulerRates(ePhi),
|
||||
Auxiliary->GetEulerRates(eTht),
|
||||
Auxiliary->GetEulerRates(ePsi) );
|
||||
_set_Euler_Rates( Auxiliary->GetEulerRates(FGJSBBase::ePhi),
|
||||
Auxiliary->GetEulerRates(FGJSBBase::eTht),
|
||||
Auxiliary->GetEulerRates(FGJSBBase::ePsi) );
|
||||
|
||||
_set_Mach_number( Auxiliary->GetMach() );
|
||||
|
||||
|
@ -674,7 +677,7 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
|
||||
_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;
|
||||
int id;
|
||||
is_valid_m(&t, d, &sd);
|
||||
|
@ -684,9 +687,9 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
_set_Runway_altitude( rwrad - get_Sea_level_radius() );
|
||||
}
|
||||
|
||||
_set_Euler_Angles( Propagate->GetEuler(ePhi),
|
||||
Propagate->GetEuler(eTht),
|
||||
Propagate->GetEuler(ePsi) );
|
||||
_set_Euler_Angles( Propagate->GetEuler(FGJSBBase::ePhi),
|
||||
Propagate->GetEuler(FGJSBBase::eTht),
|
||||
Propagate->GetEuler(FGJSBBase::ePsi) );
|
||||
|
||||
_set_Alpha( Auxiliary->Getalpha() );
|
||||
_set_Beta( Auxiliary->Getbeta() );
|
||||
|
@ -751,6 +754,28 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
globals->get_controls()->set_augmentation(i, eng->GetAugmentation() );
|
||||
} // end FGTurbine code block
|
||||
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:
|
||||
{ // FGElectric code block
|
||||
FGElectric* eng = (FGElectric*)Propulsion->GetEngine(i);
|
||||
|
@ -782,6 +807,7 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
tnode->setDoubleValue("rpm", thruster->GetRPM());
|
||||
tnode->setDoubleValue("pitch", prop->GetPitch());
|
||||
tnode->setDoubleValue("torque", prop->GetTorque());
|
||||
tnode->setBoolValue("feathered", prop->GetFeather());
|
||||
} // end FGPropeller code block
|
||||
break;
|
||||
case FGThruster::ttRotor:
|
||||
|
@ -823,23 +849,32 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
speedbrake_pos_pct->setDoubleValue( FCS->GetDsbPos(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;
|
||||
}
|
||||
|
||||
|
||||
bool FGJSBsim::ToggleDataLogging(void)
|
||||
{
|
||||
return fdmex->GetOutput()->Toggle();
|
||||
// ToDo: handle this properly
|
||||
fdmex->DisableOutput();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FGJSBsim::ToggleDataLogging(bool state)
|
||||
{
|
||||
if (state) {
|
||||
fdmex->GetOutput()->Enable();
|
||||
fdmex->EnableOutput();
|
||||
return true;
|
||||
} else {
|
||||
fdmex->GetOutput()->Disable();
|
||||
fdmex->DisableOutput();
|
||||
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;
|
||||
}
|
||||
|
||||
using namespace JSBSim;
|
||||
// Adding it here will cause a namespace clash in FlightGear -EMH-
|
||||
// using namespace JSBSim;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
|
@ -205,24 +206,21 @@ public:
|
|||
void do_trim(void);
|
||||
void update_ic(void);
|
||||
|
||||
//** Handle a crash of the user aircraft. */
|
||||
void crash_handler();
|
||||
|
||||
private:
|
||||
FGFDMExec *fdmex;
|
||||
FGInitialCondition *fgic;
|
||||
JSBSim::FGFDMExec *fdmex;
|
||||
JSBSim::FGInitialCondition *fgic;
|
||||
bool needTrim;
|
||||
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGPropulsion* Propulsion;
|
||||
FGMassBalance* MassBalance;
|
||||
FGAircraft* Aircraft;
|
||||
FGPropagate* Propagate;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
FGGroundReactions *GroundReactions;
|
||||
JSBSim::FGState* State;
|
||||
JSBSim::FGAtmosphere* Atmosphere;
|
||||
JSBSim::FGFCS* FCS;
|
||||
JSBSim::FGPropulsion* Propulsion;
|
||||
JSBSim::FGMassBalance* MassBalance;
|
||||
JSBSim::FGAircraft* Aircraft;
|
||||
JSBSim::FGPropagate* Propagate;
|
||||
JSBSim::FGAuxiliary* Auxiliary;
|
||||
JSBSim::FGAerodynamics* Aerodynamics;
|
||||
JSBSim::FGGroundReactions *GroundReactions;
|
||||
|
||||
int runcount;
|
||||
double trim_elev;
|
||||
|
@ -266,10 +264,6 @@ private:
|
|||
void init_gear(void);
|
||||
void update_gear(void);
|
||||
|
||||
bool reset_on_crash;
|
||||
bool crashed;
|
||||
string crash_message;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,58 +1,9 @@
|
|||
SUBDIRS = filtersjb
|
||||
|
||||
EXTRA_DIST = Makefile.solo
|
||||
SUBDIRS = initialization models input_output math
|
||||
|
||||
noinst_LIBRARIES = libJSBSim.a
|
||||
|
||||
libJSBSim_a_SOURCES = \
|
||||
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
|
||||
libJSBSim_a_SOURCES = FGFDMExec.cpp FGJSBBase.cpp FGState.cpp JSBSim.cxx
|
||||
|
||||
noinst_HEADERS = FGFDMExec.h FGJSBBase.h FGState.h JSBSim.hxx
|
||||
|
||||
# noinst_PROGRAMS = testJSBsim
|
||||
|
||||
AM_CXXFLAGS = -DFGFS
|
||||
|
||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
||||
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim
|
||||
|
|
|
@ -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 !!!!!!!
|
||||
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include <FGFDMExec.h>
|
||||
#include <models/FGAtmosphere.h>
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGTrim.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGMassBalance.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include <models/FGAircraft.h>
|
||||
#include <models/FGMassBalance.h>
|
||||
#include <models/FGGroundReactions.h>
|
||||
#include <models/FGInertial.h>
|
||||
#include <models/FGAerodynamics.h>
|
||||
#include <math/FGColumnVector3.h>
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning (disable : 4786 4788)
|
||||
|
@ -241,7 +240,7 @@ bool FGTrim::DoTrim(void) {
|
|||
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(false);
|
||||
}
|
||||
|
||||
fdmex->GetOutput()->Disable();
|
||||
fdmex->DisableOutput();
|
||||
|
||||
fgic->SetPRadpsIC(0.0);
|
||||
fgic->SetQRadpsIC(0.0);
|
||||
|
@ -358,7 +357,7 @@ bool FGTrim::DoTrim(void) {
|
|||
for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
||||
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(true);
|
||||
}
|
||||
fdmex->GetOutput()->Enable();
|
||||
fdmex->EnableOutput();
|
||||
return !trim_failed;
|
||||
}
|
||||
|
|
@ -72,9 +72,8 @@ FORWARD DECLARATIONS
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
typedef enum { tLongitudinal, tFull, tGround, tPullup,
|
||||
tCustom, tNone, tTurn
|
||||
} TrimMode;
|
||||
typedef enum { tLongitudinal=0, tFull, tGround, tPullup,
|
||||
tCustom, tTurn, tNone } TrimMode;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
|
@ -36,20 +36,16 @@ INCLUDES
|
|||
# pragma warning (disable : 4786)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include <FGFDMExec.h>
|
||||
#include <models/FGAtmosphere.h>
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGTrimAxis.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGPropulsion.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include <models/FGAircraft.h>
|
||||
#include <models/FGPropulsion.h>
|
||||
#include <models/FGAerodynamics.h>
|
||||
|
||||
|
||||
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]) )
|
||||
name[i]='-';
|
||||
}
|
||||
/*
|
||||
for(i=0;i<name.length();i++) {
|
||||
if( name[i] == '/' )
|
||||
name.erase(i,1);
|
||||
}
|
||||
|
||||
*/
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -75,9 +76,9 @@ FGPropertyManager*
|
|||
FGPropertyManager::GetNode (const string &path, bool create)
|
||||
{
|
||||
SGPropertyNode* node=this->getNode(path.c_str(), create);
|
||||
//if(node == 0)
|
||||
// cout << "FGPropertyManager::GetNode() No node found for "
|
||||
// << path << endl;
|
||||
if (node == 0 && !suppress_warning)
|
||||
cout << "FGPropertyManager::GetNode() No node found for "
|
||||
<< path << endl;
|
||||
return (FGPropertyManager*)node;
|
||||
}
|
||||
|
||||
|
@ -94,7 +95,11 @@ FGPropertyManager::GetNode (const string &relpath, int index, bool create)
|
|||
|
||||
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)
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer),
|
||||
useDefault))
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to a pointer" << endl;
|
||||
if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer), useDefault))
|
||||
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
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,
|
||||
bool useDefault )
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValuePointer<int>(pointer),
|
||||
useDefault))
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to a pointer" << endl;
|
||||
if (!tie(name.c_str(), SGRawValuePointer<int>(pointer), useDefault))
|
||||
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
cout << name << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -286,10 +291,10 @@ void FGPropertyManager::Tie (const string &name, int *pointer,
|
|||
void FGPropertyManager::Tie (const string &name, long *pointer,
|
||||
bool useDefault )
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValuePointer<long>(pointer),
|
||||
useDefault))
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to a pointer" << endl;
|
||||
if (!tie(name.c_str(), SGRawValuePointer<long>(pointer), useDefault))
|
||||
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
cout << name << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -297,21 +302,20 @@ void FGPropertyManager::Tie (const string &name, long *pointer,
|
|||
void FGPropertyManager::Tie (const string &name, float *pointer,
|
||||
bool useDefault )
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValuePointer<float>(pointer),
|
||||
useDefault))
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to a pointer" << endl;
|
||||
if (!tie(name.c_str(), SGRawValuePointer<float>(pointer), useDefault))
|
||||
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
cout << name << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGPropertyManager::Tie (const string &name, double *pointer,
|
||||
bool useDefault)
|
||||
void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValuePointer<double>(pointer),
|
||||
useDefault))
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to a pointer" << endl;
|
||||
if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault))
|
||||
cout << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
cout << name << endl;
|
||||
}
|
||||
|
||||
} // namespace JSBSim
|
|
@ -37,11 +37,13 @@ INCLUDES
|
|||
|
||||
#include <string>
|
||||
#ifdef FGFS
|
||||
#include <simgear/props/props.hxx>
|
||||
# include <simgear/props/props.hxx>
|
||||
#else
|
||||
#include "simgear/props/props.hxx"
|
||||
# include "simgear/props/props.hxx"
|
||||
#endif
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -68,10 +70,13 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGPropertyManager : public SGPropertyNode {
|
||||
class FGPropertyManager : public SGPropertyNode, public FGJSBBase
|
||||
{
|
||||
private:
|
||||
bool suppress_warning;
|
||||
public:
|
||||
/// Constructor
|
||||
FGPropertyManager(void) {}
|
||||
FGPropertyManager(void) {suppress_warning = false;}
|
||||
/// Destructor
|
||||
~FGPropertyManager(void) {}
|
||||
|
||||
|
@ -500,15 +505,12 @@ class FGPropertyManager : public SGPropertyNode {
|
|||
*/
|
||||
|
||||
template <class V> inline void
|
||||
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
|
||||
bool useDefault = true)
|
||||
Tie (const string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true)
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter),
|
||||
useDefault))
|
||||
{
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to functions" << endl;
|
||||
}
|
||||
if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
|
||||
cout << "Failed to tie property " << name << " to functions" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
cout << name << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -527,19 +529,16 @@ class FGPropertyManager : public SGPropertyNode {
|
|||
* @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 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.
|
||||
*/
|
||||
template <class V> inline void Tie (const string &name,
|
||||
int index, V (*getter)(int),
|
||||
void (*setter)(int, V) = 0, bool useDefault = true)
|
||||
template <class V> inline void Tie (const string &name, int index, V (*getter)(int),
|
||||
void (*setter)(int, V) = 0, bool useDefault = true)
|
||||
{
|
||||
if (!tie(name.c_str(),
|
||||
SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
|
||||
{
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to indexed functions" << endl;
|
||||
}
|
||||
if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
|
||||
cout << "Failed to tie property " << name << " to indexed functions" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
cout << name << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -566,12 +565,10 @@ class FGPropertyManager : public SGPropertyNode {
|
|||
Tie (const string &name, T * obj, V (T::*getter)() const,
|
||||
void (T::*setter)(V) = 0, bool useDefault = true)
|
||||
{
|
||||
if (!tie(name.c_str(),
|
||||
SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
|
||||
{
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to object methods" << endl;
|
||||
}
|
||||
if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
|
||||
cout << "Failed to tie property " << name << " to object methods" << endl;
|
||||
else if (debug_lvl & 0x20)
|
||||
cout << name << endl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -594,16 +591,13 @@ class FGPropertyManager : public SGPropertyNode {
|
|||
* discarded; defaults to true.
|
||||
*/
|
||||
template <class T, class V> inline void
|
||||
Tie (const string &name, T * obj, int index,
|
||||
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
|
||||
bool useDefault = true)
|
||||
Tie (const string &name, T * obj, int index, V (T::*getter)(int) const,
|
||||
void (T::*setter)(int, V) = 0, bool useDefault = true)
|
||||
{
|
||||
if (!tie(name.c_str(),
|
||||
SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
|
||||
{
|
||||
cout <<
|
||||
"Failed to tie property " << name << " to indexed object methods" << endl;
|
||||
}
|
||||
if (!tie(name.c_str(), 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 << name << 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
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
# include STL_IOSTREAM
|
||||
|
@ -59,8 +55,8 @@ INCLUDES
|
|||
#endif
|
||||
|
||||
#include "FGScript.h"
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGTrim.h"
|
||||
#include "FGXMLParse.h"
|
||||
#include <initialization/FGTrim.h>
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -95,134 +91,126 @@ FGScript::~FGScript()
|
|||
|
||||
bool FGScript::LoadScript( string script )
|
||||
{
|
||||
FGConfigFile Script(script);
|
||||
string token="";
|
||||
string aircraft="";
|
||||
string initialize="";
|
||||
string prop_name;
|
||||
string aircraft="", initialize="", comparison = "", prop_name="";
|
||||
Element *document=0, *element=0, *run_element=0, *when_element=0;
|
||||
Element *parameter_element=0, *set_element=0;
|
||||
bool result = false;
|
||||
double dt = 0.0;
|
||||
double dt = 0.0, value = 0.0;
|
||||
FGXMLParse script_file_parser;
|
||||
struct condition *newCondition;
|
||||
ifstream script_file(script.c_str());
|
||||
|
||||
if (!Script.IsOpen()) return false;
|
||||
if ( !script_file ) return false;
|
||||
|
||||
Script.GetNextConfigLine();
|
||||
if (Script.GetValue("runscript").length() <= 0) {
|
||||
readXML(script_file, script_file_parser);
|
||||
document = script_file_parser.GetDocument();
|
||||
|
||||
if (document->GetName() != string("runscript")) {
|
||||
cerr << "File: " << script << " is not a script file" << endl;
|
||||
delete FDMExec;
|
||||
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")) {
|
||||
token = Script.GetValue();
|
||||
if (token == "use") {
|
||||
if ((token = Script.GetValue("aircraft")) != string("")) {
|
||||
aircraft = token;
|
||||
result = FDMExec->LoadModel(aircraft);
|
||||
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
|
||||
element = document->FindElement("use");
|
||||
if (element) {
|
||||
aircraft = element->GetAttributeValue("aircraft");
|
||||
if (!aircraft.empty()) {
|
||||
result = FDMExec->LoadModel(aircraft);
|
||||
if (!result) return false;
|
||||
} 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 == "") {
|
||||
cerr << "Aircraft file not loaded in script" << endl;
|
||||
exit(-1);
|
||||
run_element = document->FindElement("run");
|
||||
|
||||
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);
|
||||
|
||||
|
||||
FGInitialCondition *IC=FDMExec->GetIC();
|
||||
if ( ! IC->Load( initialize )) {
|
||||
cerr << "Initialization unsuccessful" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
/* comment this out for conversion capability
|
||||
FGTrim fgt(FDMExec, tFull);
|
||||
if ( !fgt.DoTrim() ) {
|
||||
cout << "Trim Failed" << endl;
|
||||
}
|
||||
fgt.Report();
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -289,18 +277,21 @@ bool FGScript::RunScript(void)
|
|||
iC->StartTime[i] = currentTime;
|
||||
}
|
||||
|
||||
double time_span = currentTime - iC->StartTime[i];
|
||||
double value_span = iC->newValue[i] - iC->OriginalValue[i];
|
||||
|
||||
switch (iC->Action[i]) {
|
||||
case FG_RAMP:
|
||||
newSetValue = (currentTime - iC->StartTime[i])/(iC->TC[i])
|
||||
* (iC->newValue[i] - iC->OriginalValue[i]) + iC->OriginalValue[i];
|
||||
if (newSetValue > iC->newValue[i]) newSetValue = iC->newValue[i];
|
||||
if (time_span <= iC->TC[i])
|
||||
newSetValue = time_span/iC->TC[i] * value_span + iC->OriginalValue[i];
|
||||
else
|
||||
newSetValue = iC->newValue[i];
|
||||
break;
|
||||
case FG_STEP:
|
||||
newSetValue = iC->newValue[i];
|
||||
break;
|
||||
case FG_EXP:
|
||||
newSetValue = (1 - exp(-(currentTime - iC->StartTime[i])/(iC->TC[i])))
|
||||
* (iC->newValue[i] - iC->OriginalValue[i]) + iC->OriginalValue[i];
|
||||
newSetValue = (1 - exp( -time_span/iC->TC[i] )) * value_span + iC->OriginalValue[i];
|
||||
break;
|
||||
default:
|
||||
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
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGfdmSocket.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -54,7 +50,7 @@ CLASS IMPLEMENTATION
|
|||
|
||||
FGfdmSocket::FGfdmSocket(string address, int port)
|
||||
{
|
||||
size = 0;
|
||||
sckt = sckt_in = size = 0;
|
||||
connected = false;
|
||||
|
||||
#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()
|
||||
{
|
||||
#ifndef macintosh
|
||||
if (sckt) shutdown(sckt,2);
|
||||
if (sckt_in) shutdown(sckt_in,2);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
WSACleanup();
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (size == 0) buffer += string(item);
|
|
@ -65,11 +65,14 @@ INCLUDES
|
|||
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <winsock.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -96,21 +99,29 @@ CLASS DECLARATION
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
using std::string;
|
||||
using std::cerr;
|
||||
|
||||
class FGfdmSocket : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGfdmSocket(string, int);
|
||||
FGfdmSocket(int);
|
||||
~FGfdmSocket();
|
||||
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(double);
|
||||
void Append(long);
|
||||
void Clear(void);
|
||||
void Clear(string s);
|
||||
void Close(void);
|
||||
bool GetConnectStatus(void) {return connected;}
|
||||
|
||||
private:
|
||||
int sckt;
|
||||
int sckt_in;
|
||||
int size;
|
||||
struct sockaddr_in scktName;
|
||||
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
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include <FGJSBBase.h>
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGMatrix33.h"
|
||||
|
|
@ -18,10 +18,6 @@ HISTORY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
|
|
@ -113,12 +113,17 @@ public:
|
|||
};
|
||||
|
||||
/** Default initializer.
|
||||
Create a zero matrix. */
|
||||
|
||||
Create a zero matrix.
|
||||
*/
|
||||
FGMatrix33(void);
|
||||
|
||||
/** Copy constructor.
|
||||
|
||||
@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) {
|
||||
Entry(1,1) = M.Entry(1,1);
|
||||
Entry(2,1) = M.Entry(2,1);
|
||||
|
@ -134,6 +139,7 @@ public:
|
|||
}
|
||||
|
||||
/** Initialization by given values.
|
||||
|
||||
@param m11 value of the 1,1 Matrix element.
|
||||
@param m12 value of the 1,2 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 m32 value of the 3,2 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,
|
||||
double m21, double m22, double m23,
|
||||
double m31, double m32, double m33) {
|
||||
|
@ -160,24 +168,30 @@ public:
|
|||
Debug(0);
|
||||
}
|
||||
|
||||
/// Destructor.
|
||||
/** Destructor.
|
||||
*/
|
||||
~FGMatrix33(void) { Debug(1); }
|
||||
|
||||
/** Read access the entries of the matrix.
|
||||
@param row Row index.
|
||||
@param col Column index.
|
||||
|
||||
@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 {
|
||||
return Entry(row, col);
|
||||
}
|
||||
|
||||
/** Write access the entries of the matrix.
|
||||
Note that the indices given in the arguments are unchecked.
|
||||
|
||||
@param row Row index.
|
||||
@param col Column index.
|
||||
|
||||
@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) {
|
||||
return Entry(row, col);
|
||||
}
|
||||
|
@ -186,11 +200,15 @@ public:
|
|||
This function is just a shortcut for the @ref double&
|
||||
operator()(unsigned int row, unsigned int col) function. It is
|
||||
used internally to access the elements in a more convenient way.
|
||||
|
||||
Note that the indices given in the arguments are unchecked.
|
||||
|
||||
@param row Row index.
|
||||
@param col Column index.
|
||||
|
||||
@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 {
|
||||
return data[(col-1)*eRows+row-1];
|
||||
}
|
||||
|
@ -199,27 +217,34 @@ public:
|
|||
This function is just a shortcut for the @ref double&
|
||||
operator()(unsigned int row, unsigned int col) function. It is
|
||||
used internally to access the elements in a more convenient way.
|
||||
|
||||
Note that the indices given in the arguments are unchecked.
|
||||
|
||||
@param row Row index.
|
||||
@param col Column index.
|
||||
|
||||
@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) {
|
||||
return data[(col-1)*eRows+row-1];
|
||||
}
|
||||
|
||||
/** 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; }
|
||||
|
||||
/** 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; }
|
||||
|
||||
/** Transposed matrix.
|
||||
This function only returns the transpose of this matrix. This matrix itself
|
||||
remains unchanged.
|
||||
@return the transposed matrix. */
|
||||
@return the transposed matrix.
|
||||
*/
|
||||
FGMatrix33 Transposed(void) const {
|
||||
return FGMatrix33( Entry(1,1), Entry(2,1), Entry(3,1),
|
||||
Entry(1,2), Entry(2,2), Entry(3,2),
|
||||
|
@ -227,15 +252,18 @@ public:
|
|||
}
|
||||
|
||||
/** Transposes this matrix.
|
||||
This function only transposes this matrix. Nothing is returned. */
|
||||
This function only transposes this matrix. Nothing is returned.
|
||||
*/
|
||||
void T(void);
|
||||
|
||||
/** Initialize the matrix.
|
||||
This function initializes a matrix to all 0.0. */
|
||||
This function initializes a matrix to all 0.0.
|
||||
*/
|
||||
void InitMatrix(void);
|
||||
|
||||
/** 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,
|
||||
double m21, double m22, double m23,
|
||||
double m31, double m32, double m33) {
|
||||
|
@ -251,7 +279,8 @@ public:
|
|||
}
|
||||
|
||||
/** Determinant of the matrix.
|
||||
@return the determinant of the matrix. */
|
||||
@return the determinant of the matrix.
|
||||
*/
|
||||
double Determinant(void) const;
|
||||
|
||||
/** Return if the matrix is invertible.
|
||||
|
@ -259,19 +288,24 @@ public:
|
|||
invertible. This is done by simply computing the determinant and
|
||||
check if it is zero. Note that this test does not cover any
|
||||
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(); }
|
||||
|
||||
/** Return the inverse of the matrix.
|
||||
Computes and returns if the inverse of the matrix. It is computed
|
||||
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
|
||||
with the @ref Invertible() call before. */
|
||||
with the @ref Invertible() call before.
|
||||
*/
|
||||
FGMatrix33 Inverse(void) const;
|
||||
|
||||
/** Assignment operator.
|
||||
|
||||
@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) {
|
||||
data[0] = A.data[0];
|
||||
data[1] = A.data[1];
|
||||
|
@ -286,80 +320,113 @@ public:
|
|||
}
|
||||
|
||||
/** Matrix vector multiplication.
|
||||
|
||||
@param v vector to multiply with.
|
||||
@return matric vector product.
|
||||
|
||||
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;
|
||||
|
||||
/** Matrix subtraction.
|
||||
|
||||
@param B matrix to add to.
|
||||
@return difference of the matrices.
|
||||
|
||||
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;
|
||||
|
||||
/** Matrix addition.
|
||||
|
||||
@param B matrix to add to.
|
||||
@return sum of the matrices.
|
||||
|
||||
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;
|
||||
|
||||
/** Matrix product.
|
||||
|
||||
@param B matrix to add to.
|
||||
@return product of the matrices.
|
||||
|
||||
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;
|
||||
|
||||
/** Multiply the matrix with a scalar.
|
||||
|
||||
@param scalar scalar factor to multiply with.
|
||||
@return scaled matrix.
|
||||
|
||||
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;
|
||||
|
||||
/** Multiply the matrix with 1.0/scalar.
|
||||
|
||||
@param scalar scalar factor to divide through.
|
||||
@return scaled matrix.
|
||||
|
||||
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;
|
||||
|
||||
/** In place matrix subtraction.
|
||||
|
||||
@param B matrix to subtract.
|
||||
@return reference to the current matrix.
|
||||
|
||||
Compute the diffence from the current matrix and the matrix B
|
||||
given in the argument. */
|
||||
given in the argument.
|
||||
*/
|
||||
FGMatrix33& operator-=(const FGMatrix33 &B);
|
||||
|
||||
/** In place matrix addition.
|
||||
|
||||
@param B matrix to add.
|
||||
@return reference to the current matrix.
|
||||
|
||||
Compute the sum of the current matrix and the matrix B
|
||||
given in the argument. */
|
||||
given in the argument.
|
||||
*/
|
||||
FGMatrix33& operator+=(const FGMatrix33 &B);
|
||||
|
||||
/** In place matrix multiplication.
|
||||
|
||||
@param B matrix to multiply with.
|
||||
@return reference to the current matrix.
|
||||
|
||||
Compute the product of the current matrix and the matrix B
|
||||
given in the argument. */
|
||||
given in the argument.
|
||||
*/
|
||||
FGMatrix33& operator*=(const FGMatrix33 &B);
|
||||
|
||||
/** In place matrix scale.
|
||||
|
||||
@param scalar scalar value to multiply with.
|
||||
@return reference to the current matrix.
|
||||
|
||||
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);
|
||||
|
||||
/** In place matrix scale.
|
||||
|
||||
@param scalar scalar value to divide through.
|
||||
@return reference to the current matrix.
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
|
@ -369,24 +436,33 @@ private:
|
|||
};
|
||||
|
||||
/** Scalar multiplication.
|
||||
|
||||
@param scalar scalar value to multiply with.
|
||||
@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) {
|
||||
// use already defined operation.
|
||||
return A*scalar;
|
||||
}
|
||||
|
||||
/** Write matrix to a stream.
|
||||
|
||||
@param os Stream to write to.
|
||||
@param M Matrix to write.
|
||||
Write the matrix to a stream.*/
|
||||
|
||||
Write the matrix to a stream.
|
||||
*/
|
||||
ostream& operator<<(ostream& os, const FGMatrix33& M);
|
||||
|
||||
/** Read matrix from a stream.
|
||||
|
||||
@param os Stream to read from.
|
||||
@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);
|
||||
|
||||
} // 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
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef FGFS
|
||||
# include <math.h>
|
||||
# include <simgear/compiler.h>
|
|
@ -40,10 +40,10 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
#include <FGJSBBase.h>
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
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
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGTable.h"
|
||||
|
||||
#if defined ( sgi ) && !defined( __GNUC__ ) && (_COMPILER_VERSION < 740)
|
||||
#include <iomanip.h>
|
||||
# include <iomanip.h>
|
||||
#else
|
||||
#include <iomanip>
|
||||
# include <iomanip>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
@ -59,50 +55,12 @@ static const char *IdHdr = ID_TABLE;
|
|||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
|
||||
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)
|
||||
FGTable::FGTable(int NRows) : nRows(NRows), nCols(1), PropertyManager(0)
|
||||
{
|
||||
Type = tt1D;
|
||||
colCounter = 0;
|
||||
rowCounter = 1;
|
||||
nTables = 0;
|
||||
|
||||
Data = Allocate();
|
||||
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;
|
||||
colCounter = t.colCounter;
|
||||
rowCounter = t.rowCounter;
|
||||
tableCounter = t.tableCounter;
|
||||
|
||||
nRows = t.nRows;
|
||||
nCols = t.nCols;
|
||||
nTables = t.nTables;
|
||||
dimension = t.dimension;
|
||||
internal = t.internal;
|
||||
|
||||
Tables = t.Tables;
|
||||
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)
|
||||
{
|
||||
Data = new double*[nRows+1];
|
||||
|
@ -152,7 +273,11 @@ double** FGTable::Allocate(void)
|
|||
|
||||
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];
|
||||
if (Data) delete[] Data;
|
||||
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;
|
||||
int r=lastRowIndex;
|
||||
|
@ -205,8 +369,7 @@ double FGTable::GetValue(double key)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
double FGTable::GetValue(double rowKey, double colKey)
|
||||
double FGTable::GetValue(double rowKey, double colKey) const
|
||||
{
|
||||
double rFactor, cFactor, col1temp, col2temp, Value;
|
||||
int r=lastRowIndex;
|
||||
|
@ -215,7 +378,6 @@ double FGTable::GetValue(double rowKey, double colKey)
|
|||
if ( r > 2 && Data[r-1][0] > rowKey ) {
|
||||
while ( Data[r-1][0] > rowKey && r > 2) { r--; }
|
||||
} else if ( Data[r][0] < rowKey ) {
|
||||
// cout << Data[r][0] << endl;
|
||||
while ( r <= nRows && Data[r][0] <= rowKey ) { r++; }
|
||||
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;
|
||||
int r=lastRowIndex;
|
||||
|
@ -259,10 +421,10 @@ double FGTable::GetValue(double rowKey, double colKey, double tableKey)
|
|||
|
||||
if( tableKey <= Data[1][1] ) {
|
||||
lastRowIndex=2;
|
||||
return Tables[0].GetValue(rowKey, colKey);
|
||||
return Tables[0]->GetValue(rowKey, colKey);
|
||||
} else if ( tableKey >= Data[nRows][1] ) {
|
||||
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
|
||||
|
@ -286,19 +448,18 @@ double FGTable::GetValue(double rowKey, double colKey, double tableKey)
|
|||
Factor = 1.0;
|
||||
}
|
||||
|
||||
Value = Factor*(Tables[r-1].GetValue(rowKey, colKey) - Tables[r-2].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);
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTable::operator<<(FGConfigFile& infile)
|
||||
void FGTable::operator<<(stringstream& in_stream)
|
||||
{
|
||||
int startRow=0;
|
||||
int startCol=0;
|
||||
int tableCtr=0;
|
||||
|
||||
if (Type == tt1D || Type == tt3D) startRow = 1;
|
||||
if (Type == tt3D) startCol = 1;
|
||||
|
@ -306,11 +467,7 @@ void FGTable::operator<<(FGConfigFile& infile)
|
|||
for (int r=startRow; r<=nRows; r++) {
|
||||
for (int c=startCol; c<=nCols; c++) {
|
||||
if (r != 0 || c != 0) {
|
||||
infile >> Data[r][c];
|
||||
if (Type == tt3D) {
|
||||
Tables[tableCtr] << infile;
|
||||
tableCtr++;
|
||||
}
|
||||
in_stream >> Data[r][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 startCol=0;
|
||||
|
||||
|
@ -355,11 +511,22 @@ void FGTable::Print(int spaces)
|
|||
ios::fmtflags flags = cout.setf(ios::fixed); // set up output stream
|
||||
#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);
|
||||
for (int r=startRow; r<=nRows; r++) {
|
||||
cout << tabspace;
|
||||
cout << " ";
|
||||
for (int c=startCol; c<=nCols; c++) {
|
||||
if (r == 0 && c == 0) {
|
||||
cout << " ";
|
||||
|
@ -367,7 +534,7 @@ void FGTable::Print(int spaces)
|
|||
cout << Data[r][c] << " ";
|
||||
if (Type == tt3D) {
|
||||
cout << endl;
|
||||
Tables[r-1].Print(spaces);
|
||||
Tables[r-1]->Print();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,8 +38,10 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include "FGParameter.h"
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -53,6 +55,7 @@ FORWARD DECLARATIONS
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
using std::vector;
|
||||
using std::stringstream;
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -199,7 +202,7 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGTable : public FGJSBBase
|
||||
class FGTable : public FGParameter
|
||||
{
|
||||
public:
|
||||
/// Destructor
|
||||
|
@ -209,14 +212,13 @@ public:
|
|||
@param table a const reference to a table.*/
|
||||
FGTable(const FGTable& table);
|
||||
|
||||
/** The constructor for a VECTOR table
|
||||
@param nRows the number of rows in this VECTOR table. */
|
||||
FGTable(int nRows);
|
||||
FGTable(int nRows, int nCols);
|
||||
FGTable(int nRows, int nCols, int numTables);
|
||||
double GetValue(double key);
|
||||
double GetValue(double rowKey, double colKey);
|
||||
double GetValue(double rowKey, double colKey, double TableKey);
|
||||
/// The constructor for a table
|
||||
FGTable (FGPropertyManager* propMan, Element* el);
|
||||
FGTable (int );
|
||||
double GetValue(void) const;
|
||||
double GetValue(double key) const;
|
||||
double GetValue(double rowKey, double colKey) const;
|
||||
double GetValue(double rowKey, double colKey, double TableKey) const;
|
||||
/** Read the table in.
|
||||
Data in the config file should be in matrix format with the row
|
||||
independents as the first column and the column independents in
|
||||
|
@ -239,21 +241,32 @@ public:
|
|||
</pre>
|
||||
*/
|
||||
|
||||
void operator<<(FGConfigFile&);
|
||||
void operator<<(stringstream&);
|
||||
FGTable& operator<<(const double n);
|
||||
FGTable& operator<<(const int n);
|
||||
|
||||
inline double GetElement(int r, int c) {return Data[r][c];}
|
||||
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:
|
||||
enum type {tt1D, tt2D, tt3D} Type;
|
||||
enum axis {eRow=0, eColumn, eTable};
|
||||
bool internal;
|
||||
FGPropertyManager *lookupProperty[3];
|
||||
double** Data;
|
||||
vector <FGTable> Tables;
|
||||
int nRows, nCols, nTables;
|
||||
vector <FGTable*> Tables;
|
||||
int FindNumColumns(string);
|
||||
int nRows, nCols, nTables, dimension;
|
||||
int colCounter, rowCounter, tableCounter;
|
||||
int lastRowIndex, lastColumnIndex, lastTableIndex;
|
||||
mutable int lastRowIndex, lastColumnIndex, lastTableIndex;
|
||||
double** Allocate(void);
|
||||
FGPropertyManager* const PropertyManager;
|
||||
|
||||
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 "FGPropulsion.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -73,76 +73,135 @@ FGMassBalance::FGMassBalance(FGFDMExec* fdmex) : FGModel(fdmex)
|
|||
FGMassBalance::~FGMassBalance()
|
||||
{
|
||||
unbind();
|
||||
PointMasses.clear();
|
||||
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)
|
||||
{
|
||||
double denom, k1, k2, k3, k4, k5, k6;
|
||||
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
|
||||
|
||||
vXYZcg = (Propulsion->GetTanksMoment() + EmptyWeight*vbaseXYZcg
|
||||
+ GetPointMassMoment() ) / Weight;
|
||||
// printf("%s:%i\n", __FILE__, __LINE__);
|
||||
vXYZcg = (Propulsion->GetTanksMoment() + EmptyWeight*vbaseXYZcg
|
||||
+ GetPointMassMoment() ) / Weight;
|
||||
|
||||
// Calculate new total moments of inertia
|
||||
|
||||
// At first it is the base configuration inertia matrix ...
|
||||
mJ = baseJ;
|
||||
// ... with the additional term originating from the parallel axis theorem.
|
||||
mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg );
|
||||
// Then add the contributions from the additional pointmasses.
|
||||
mJ += CalculatePMInertias();
|
||||
mJ += Propulsion->CalculateTankInertias();
|
||||
// At first it is the base configuration inertia matrix ...
|
||||
mJ = baseJ;
|
||||
// ... with the additional term originating from the parallel axis theorem.
|
||||
mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg );
|
||||
// Then add the contributions from the additional pointmasses.
|
||||
mJ += CalculatePMInertias();
|
||||
mJ += Propulsion->CalculateTankInertias();
|
||||
|
||||
Ixx = mJ(1,1);
|
||||
Iyy = mJ(2,2);
|
||||
Izz = mJ(3,3);
|
||||
Ixy = -mJ(1,2);
|
||||
Ixz = -mJ(1,3);
|
||||
Iyz = -mJ(2,3);
|
||||
Ixx = mJ(1,1);
|
||||
Iyy = mJ(2,2);
|
||||
Izz = mJ(3,3);
|
||||
Ixy = -mJ(1,2);
|
||||
Ixz = -mJ(1,3);
|
||||
Iyz = -mJ(2,3);
|
||||
|
||||
// Calculate inertia matrix inverse (ref. Stevens and Lewis, "Flight Control & Simulation")
|
||||
|
||||
k1 = (Iyy*Izz - Iyz*Iyz);
|
||||
k2 = (Iyz*Ixz + Ixy*Izz);
|
||||
k3 = (Ixy*Iyz + Iyy*Ixz);
|
||||
k1 = (Iyy*Izz - Iyz*Iyz);
|
||||
k2 = (Iyz*Ixz + Ixy*Izz);
|
||||
k3 = (Ixy*Iyz + Iyy*Ixz);
|
||||
|
||||
denom = 1.0/(Ixx*k1 - Ixy*k2 - Ixz*k3 );
|
||||
k1 = k1*denom;
|
||||
k2 = k2*denom;
|
||||
k3 = k3*denom;
|
||||
k4 = (Izz*Ixx - Ixz*Ixz)*denom;
|
||||
k5 = (Ixy*Ixz + Iyz*Ixx)*denom;
|
||||
k6 = (Ixx*Iyy - Ixy*Ixy)*denom;
|
||||
denom = 1.0/(Ixx*k1 - Ixy*k2 - Ixz*k3 );
|
||||
k1 = k1*denom;
|
||||
k2 = k2*denom;
|
||||
k3 = k3*denom;
|
||||
k4 = (Izz*Ixx - Ixz*Ixz)*denom;
|
||||
k5 = (Ixy*Ixz + Iyz*Ixx)*denom;
|
||||
k6 = (Ixx*Iyy - Ixy*Ixy)*denom;
|
||||
|
||||
mJinv.InitMatrix( k1, k2, k3,
|
||||
k2, k4, k5,
|
||||
k3, k5, k6 );
|
||||
mJinv.InitMatrix( k1, k2, k3,
|
||||
k2, k4, k5,
|
||||
k3, k5, k6 );
|
||||
|
||||
Debug(2);
|
||||
Debug(0);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGMassBalance::AddPointMass(double weight, double X, double Y, double Z)
|
||||
void FGMassBalance::AddPointMass(Element* el)
|
||||
{
|
||||
PointMassLoc.push_back(FGColumnVector3(X, Y, Z));
|
||||
PointMassWeight.push_back(weight);
|
||||
Element* loc_element = el->FindElement("location");
|
||||
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;
|
||||
|
||||
for (unsigned int i=0; i<PointMassWeight.size(); i++) {
|
||||
PM_total_weight += PointMassWeight[i];
|
||||
for (unsigned int i=0; i<PointMasses.size(); i++) {
|
||||
PM_total_weight += PointMasses[i].Weight;
|
||||
}
|
||||
return PM_total_weight;
|
||||
}
|
||||
|
@ -163,8 +222,8 @@ FGColumnVector3& FGMassBalance::GetPointMassMoment(void)
|
|||
{
|
||||
PointMassCG.InitMatrix();
|
||||
|
||||
for (unsigned int i=0; i<PointMassLoc.size(); i++) {
|
||||
PointMassCG += PointMassWeight[i]*PointMassLoc[i];
|
||||
for (unsigned int i=0; i<PointMasses.size(); i++) {
|
||||
PointMassCG += PointMasses[i].Weight*PointMasses[i].Location;
|
||||
}
|
||||
return PointMassCG;
|
||||
}
|
||||
|
@ -175,13 +234,13 @@ FGMatrix33& FGMassBalance::CalculatePMInertias(void)
|
|||
{
|
||||
unsigned int size;
|
||||
|
||||
size = PointMassLoc.size();
|
||||
size = PointMasses.size();
|
||||
if (size == 0) return pmJ;
|
||||
|
||||
pmJ = FGMatrix33();
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -271,8 +330,23 @@ void FGMassBalance::Debug(int from)
|
|||
if (debug_lvl <= 0) return;
|
||||
|
||||
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
|
|
@ -39,8 +39,9 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include <math/FGColumnVector3.h>
|
||||
#include <math/FGMatrix33.h>
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include <vector>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -73,14 +74,14 @@ public:
|
|||
FGMassBalance(FGFDMExec*);
|
||||
~FGMassBalance();
|
||||
|
||||
bool Load(Element* el);
|
||||
|
||||
bool Run(void);
|
||||
|
||||
inline double GetMass(void) const {return Mass;}
|
||||
inline double GetWeight(void) const {return Weight;}
|
||||
inline double GetEmptyWeight(void) const {return EmptyWeight;}
|
||||
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
|
||||
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 and returns the inertia matrix of a pointmass of mass
|
||||
|
@ -119,17 +120,13 @@ public:
|
|||
inline void SetEmptyWeight(double EW) { EmptyWeight = EW;}
|
||||
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);
|
||||
FGColumnVector3& GetPointMassMoment(void);
|
||||
FGMatrix33& GetJ(void) {return mJ;}
|
||||
FGMatrix33& GetJinv(void) {return mJinv;}
|
||||
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 unbind(void);
|
||||
|
||||
|
@ -145,11 +142,20 @@ private:
|
|||
FGColumnVector3 vXYZtank;
|
||||
FGColumnVector3 vbaseXYZcg;
|
||||
FGColumnVector3 vPMxyz;
|
||||
vector <FGColumnVector3> PointMassLoc;
|
||||
vector <double> PointMassWeight;
|
||||
FGColumnVector3 PointMassCG;
|
||||
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);
|
||||
};
|
||||
}
|
|
@ -51,7 +51,6 @@ INCLUDES
|
|||
#include "FGAircraft.h"
|
||||
#include "FGPropagate.h"
|
||||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -82,7 +81,6 @@ FGModel::FGModel(FGFDMExec* fdmex)
|
|||
Aircraft = 0;
|
||||
Propagate = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
|
||||
//in order for FGModel derived classes to self-bind (that is, call
|
||||
//their bind function in the constructor, the PropertyManager pointer
|
||||
|
@ -117,7 +115,6 @@ bool FGModel::InitModel(void)
|
|||
Aircraft = FDMExec->GetAircraft();
|
||||
Propagate = FDMExec->GetPropagate();
|
||||
Auxiliary = FDMExec->GetAuxiliary();
|
||||
Output = FDMExec->GetOutput();
|
||||
|
||||
if (!State ||
|
||||
!Atmosphere ||
|
||||
|
@ -129,8 +126,7 @@ bool FGModel::InitModel(void)
|
|||
!GroundReactions ||
|
||||
!Aircraft ||
|
||||
!Propagate ||
|
||||
!Auxiliary ||
|
||||
!Output) return(false);
|
||||
!Auxiliary) return(false);
|
||||
else return(true);
|
||||
}
|
||||
|
|
@ -38,8 +38,9 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include <FGJSBBase.h>
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include <input_output/FGXMLElement.h>
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
|
@ -84,8 +85,6 @@ class FGGroundReactions;
|
|||
class FGAircraft;
|
||||
class FGPropagate;
|
||||
class FGAuxiliary;
|
||||
class FGOutput;
|
||||
class FGConfigFile;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
|
@ -109,9 +108,9 @@ public:
|
|||
virtual ~FGModel();
|
||||
|
||||
/** 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*/
|
||||
virtual bool Load(FGConfigFile* Config) {return true;}
|
||||
virtual bool Load(Element* el) {return true;}
|
||||
|
||||
FGModel* NextModel;
|
||||
string Name;
|
||||
|
@ -144,7 +143,6 @@ protected:
|
|||
FGAircraft* Aircraft;
|
||||
FGPropagate* Propagate;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
FGPropertyManager* PropertyManager;
|
||||
};
|
||||
}
|
|
@ -51,6 +51,7 @@ INCLUDES
|
|||
#include "FGAuxiliary.h"
|
||||
#include "FGInertial.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -68,11 +69,10 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
|
|||
sFirstPass = dFirstPass = true;
|
||||
socket = 0;
|
||||
Type = otNone;
|
||||
Filename = "";
|
||||
SubSystems = 0;
|
||||
enabled = true;
|
||||
outputInFileName = "";
|
||||
delimeter = ", ";
|
||||
Filename = "";
|
||||
|
||||
Debug(0);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
|
|||
FGOutput::~FGOutput()
|
||||
{
|
||||
if (socket) delete socket;
|
||||
for (unsigned int i=0; i<OutputProperties.size(); i++) delete OutputProperties[i];
|
||||
OutputProperties.clear();
|
||||
|
||||
Debug(1);
|
||||
}
|
||||
|
@ -91,8 +91,9 @@ FGOutput::~FGOutput()
|
|||
|
||||
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) {
|
||||
SocketOutput();
|
||||
} else if (Type == otCSV || Type == otTab) {
|
||||
|
@ -187,6 +188,8 @@ void FGOutput::DelimitedOutput(string fname)
|
|||
if (SubSystems & ssAtmosphere) {
|
||||
outstream << delimeter;
|
||||
outstream << "Rho" + delimeter;
|
||||
outstream << "SL pressure" + delimeter;
|
||||
outstream << "Ambient pressure" + delimeter;
|
||||
outstream << "NWind" + delimeter + "EWind" + delimeter + "DWind";
|
||||
}
|
||||
if (SubSystems & ssMassProps) {
|
||||
|
@ -281,6 +284,8 @@ void FGOutput::DelimitedOutput(string fname)
|
|||
if (SubSystems & ssAtmosphere) {
|
||||
outstream << delimeter;
|
||||
outstream << Atmosphere->GetDensity() << delimeter;
|
||||
outstream << Atmosphere->GetPressureSL() << delimeter;
|
||||
outstream << Atmosphere->GetPressure() << delimeter;
|
||||
outstream << Atmosphere->GetWindNED().Dump(delimeter);
|
||||
}
|
||||
if (SubSystems & ssMassProps) {
|
||||
|
@ -329,99 +334,220 @@ void FGOutput::DelimitedOutput(string fname)
|
|||
|
||||
void FGOutput::SocketOutput(void)
|
||||
{
|
||||
string asciiData;
|
||||
string asciiData, scratch;
|
||||
|
||||
if (socket == NULL) return;
|
||||
if (!socket->GetConnectStatus()) return;
|
||||
|
||||
socket->Clear();
|
||||
if (sFirstPass) {
|
||||
socket->Append("<LABELS>");
|
||||
socket->Clear("<LABELS>");
|
||||
socket->Append("Time");
|
||||
socket->Append("Altitude");
|
||||
socket->Append("Phi");
|
||||
socket->Append("Tht");
|
||||
socket->Append("Psi");
|
||||
socket->Append("Rho");
|
||||
socket->Append("Vtotal");
|
||||
socket->Append("UBody");
|
||||
socket->Append("VBody");
|
||||
socket->Append("WBody");
|
||||
socket->Append("UAero");
|
||||
socket->Append("VAero");
|
||||
socket->Append("WAero");
|
||||
socket->Append("Vn");
|
||||
socket->Append("Ve");
|
||||
socket->Append("Vd");
|
||||
socket->Append("Udot");
|
||||
socket->Append("Vdot");
|
||||
socket->Append("Wdot");
|
||||
socket->Append("P");
|
||||
socket->Append("Q");
|
||||
socket->Append("R");
|
||||
socket->Append("PDot");
|
||||
socket->Append("QDot");
|
||||
socket->Append("RDot");
|
||||
socket->Append("Fx");
|
||||
socket->Append("Fy");
|
||||
socket->Append("Fz");
|
||||
socket->Append("Latitude (Deg)");
|
||||
socket->Append("Longitude (Deg)");
|
||||
socket->Append("QBar");
|
||||
socket->Append("Alpha");
|
||||
socket->Append("L");
|
||||
socket->Append("M");
|
||||
socket->Append("N");
|
||||
socket->Append("Throttle Position");
|
||||
socket->Append("Left Aileron Position");
|
||||
socket->Append("Right Aileron Position");
|
||||
socket->Append("Elevator Position");
|
||||
socket->Append("Rudder Position");
|
||||
|
||||
if (SubSystems & ssAerosurfaces) {
|
||||
socket->Append("Aileron Command");
|
||||
socket->Append("Elevator Command");
|
||||
socket->Append("Rudder Command");
|
||||
socket->Append("Flap Command");
|
||||
socket->Append("Left Aileron Position");
|
||||
socket->Append("Right Aileron Position");
|
||||
socket->Append("Elevator Position");
|
||||
socket->Append("Rudder Position");
|
||||
socket->Append("Flap Position");
|
||||
}
|
||||
|
||||
if (SubSystems & ssRates) {
|
||||
socket->Append("P");
|
||||
socket->Append("Q");
|
||||
socket->Append("R");
|
||||
socket->Append("PDot");
|
||||
socket->Append("QDot");
|
||||
socket->Append("RDot");
|
||||
}
|
||||
|
||||
if (SubSystems & ssVelocities) {
|
||||
socket->Append("QBar");
|
||||
socket->Append("Vtotal");
|
||||
socket->Append("UBody");
|
||||
socket->Append("VBody");
|
||||
socket->Append("WBody");
|
||||
socket->Append("UAero");
|
||||
socket->Append("VAero");
|
||||
socket->Append("WAero");
|
||||
socket->Append("Vn");
|
||||
socket->Append("Ve");
|
||||
socket->Append("Vd");
|
||||
}
|
||||
if (SubSystems & ssForces) {
|
||||
socket->Append("F_Drag");
|
||||
socket->Append("F_Side");
|
||||
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;
|
||||
socket->Send();
|
||||
}
|
||||
|
||||
socket->Clear();
|
||||
socket->Append(State->Getsim_time());
|
||||
socket->Append(Propagate->Geth());
|
||||
socket->Append(Propagate->GetEuler(ePhi));
|
||||
socket->Append(Propagate->GetEuler(eTht));
|
||||
socket->Append(Propagate->GetEuler(ePsi));
|
||||
socket->Append(Atmosphere->GetDensity());
|
||||
socket->Append(Auxiliary->GetVt());
|
||||
socket->Append(Propagate->GetUVW(eU));
|
||||
socket->Append(Propagate->GetUVW(eV));
|
||||
socket->Append(Propagate->GetUVW(eW));
|
||||
socket->Append(Auxiliary->GetAeroUVW(eU));
|
||||
socket->Append(Auxiliary->GetAeroUVW(eV));
|
||||
socket->Append(Auxiliary->GetAeroUVW(eW));
|
||||
socket->Append(Propagate->GetVel(eNorth));
|
||||
socket->Append(Propagate->GetVel(eEast));
|
||||
socket->Append(Propagate->GetVel(eDown));
|
||||
socket->Append(Propagate->GetUVWdot(eU));
|
||||
socket->Append(Propagate->GetUVWdot(eV));
|
||||
socket->Append(Propagate->GetUVWdot(eW));
|
||||
socket->Append(Propagate->GetPQR(eP));
|
||||
socket->Append(Propagate->GetPQR(eQ));
|
||||
socket->Append(Propagate->GetPQR(eR));
|
||||
socket->Append(Propagate->GetPQRdot(eP));
|
||||
socket->Append(Propagate->GetPQRdot(eQ));
|
||||
socket->Append(Propagate->GetPQRdot(eR));
|
||||
socket->Append(Aircraft->GetForces(eX));
|
||||
socket->Append(Aircraft->GetForces(eY));
|
||||
socket->Append(Aircraft->GetForces(eZ));
|
||||
socket->Append(Propagate->GetLocation().GetLatitudeDeg());
|
||||
socket->Append(Propagate->GetLocation().GetLongitudeDeg());
|
||||
socket->Append(Auxiliary->Getqbar());
|
||||
socket->Append(Auxiliary->Getalpha(inDegrees));
|
||||
socket->Append(Aircraft->GetMoments(eL));
|
||||
socket->Append(Aircraft->GetMoments(eM));
|
||||
socket->Append(Aircraft->GetMoments(eN));
|
||||
socket->Append(FCS->GetThrottlePos(0));
|
||||
socket->Append(FCS->GetDaLPos());
|
||||
socket->Append(FCS->GetDaRPos());
|
||||
socket->Append(FCS->GetDePos());
|
||||
socket->Append(FCS->GetDrPos());
|
||||
|
||||
if (SubSystems & ssAerosurfaces) {
|
||||
socket->Append(FCS->GetDaCmd());
|
||||
socket->Append(FCS->GetDeCmd());
|
||||
socket->Append(FCS->GetDrCmd());
|
||||
socket->Append(FCS->GetDfCmd());
|
||||
socket->Append(FCS->GetDaLPos());
|
||||
socket->Append(FCS->GetDaRPos());
|
||||
socket->Append(FCS->GetDePos());
|
||||
socket->Append(FCS->GetDrPos());
|
||||
socket->Append(FCS->GetDfPos());
|
||||
}
|
||||
if (SubSystems & ssRates) {
|
||||
socket->Append(Propagate->GetPQR(eP));
|
||||
socket->Append(Propagate->GetPQR(eQ));
|
||||
socket->Append(Propagate->GetPQR(eR));
|
||||
socket->Append(Propagate->GetPQRdot(eP));
|
||||
socket->Append(Propagate->GetPQRdot(eQ));
|
||||
socket->Append(Propagate->GetPQRdot(eR));
|
||||
}
|
||||
if (SubSystems & ssVelocities) {
|
||||
socket->Append(Auxiliary->Getqbar());
|
||||
socket->Append(Auxiliary->GetVt());
|
||||
socket->Append(Propagate->GetUVW(eU));
|
||||
socket->Append(Propagate->GetUVW(eV));
|
||||
socket->Append(Propagate->GetUVW(eW));
|
||||
socket->Append(Auxiliary->GetAeroUVW(eU));
|
||||
socket->Append(Auxiliary->GetAeroUVW(eV));
|
||||
socket->Append(Auxiliary->GetAeroUVW(eW));
|
||||
socket->Append(Propagate->GetVel(eNorth));
|
||||
socket->Append(Propagate->GetVel(eEast));
|
||||
socket->Append(Propagate->GetVel(eDown));
|
||||
}
|
||||
if (SubSystems & ssForces) {
|
||||
socket->Append(Aerodynamics->GetvFs()(eDrag));
|
||||
socket->Append(Aerodynamics->GetvFs()(eSide));
|
||||
socket->Append(Aerodynamics->GetvFs()(eLift));
|
||||
socket->Append(Aerodynamics->GetLoD());
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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="";
|
||||
int OutRate = 0;
|
||||
FGConfigFile* Output_cfg;
|
||||
string property;
|
||||
unsigned int port;
|
||||
FGXMLParse output_file_parser;
|
||||
Element *document, *property_element;
|
||||
ifstream* output_file = new ifstream();
|
||||
|
||||
# ifndef macintosh
|
||||
separator = "/";
|
||||
# else
|
||||
separator = ";";
|
||||
string separator = "/";
|
||||
# ifdef macintosh
|
||||
separator = ";";
|
||||
# endif
|
||||
|
||||
name = AC_cfg->GetValue("NAME");
|
||||
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);
|
||||
}
|
||||
|
||||
fname = element->GetAttributeValue("file");
|
||||
if (!fname.empty()) {
|
||||
outputInFileName = FDMExec->GetAircraftPath() + separator
|
||||
output_file_name = FDMExec->GetAircraftPath() + separator
|
||||
+ FDMExec->GetModelName() + separator + fname + ".xml";
|
||||
Output_cfg = new FGConfigFile(outputInFileName);
|
||||
if (!Output_cfg->IsOpen()) {
|
||||
cerr << "Could not open file: " << outputInFileName << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
output_file->open(output_file_name.c_str());
|
||||
readXML(*output_file, output_file_parser);
|
||||
delete output_file;
|
||||
document = output_file_parser.GetDocument();
|
||||
} else {
|
||||
Output_cfg = AC_cfg;
|
||||
document = element;
|
||||
}
|
||||
Output->SetFilename(name);
|
||||
|
||||
while ((token = Output_cfg->GetValue()) != string("/OUTPUT")) {
|
||||
*Output_cfg >> parameter;
|
||||
if (parameter == "RATE_IN_HZ") {
|
||||
*Output_cfg >> OutRate;
|
||||
}
|
||||
if (parameter == "SIMULATION") {
|
||||
*Output_cfg >> parameter;
|
||||
if (parameter == "ON") SubSystems += ssSimulation;
|
||||
}
|
||||
if (parameter == "AEROSURFACES") {
|
||||
*Output_cfg >> parameter;
|
||||
if (parameter == "ON") SubSystems += ssAerosurfaces;
|
||||
}
|
||||
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));
|
||||
}
|
||||
name = document->GetAttributeValue("name");
|
||||
type = document->GetAttributeValue("type");
|
||||
SetType(type);
|
||||
if (!document->GetAttributeValue("port").empty() && type == string("SOCKET")) {
|
||||
port = atoi(document->GetAttributeValue("port").c_str());
|
||||
socket = new FGfdmSocket(name, port);
|
||||
} else {
|
||||
Filename = name;
|
||||
}
|
||||
if (!document->GetAttributeValue("rate").empty()) {
|
||||
OutRate = (int)document->GetAttributeValueAsNumber("rate");
|
||||
} else {
|
||||
OutRate = 1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -583,10 +682,10 @@ void FGOutput::Debug(int from)
|
|||
|
||||
}
|
||||
if (from == 2) {
|
||||
if (outputInFileName.empty())
|
||||
if (output_file_name.empty())
|
||||
cout << " " << "Output parameters read inline" << endl;
|
||||
else
|
||||
cout << " Output parameters read from file: " << outputInFileName << endl;
|
||||
cout << " Output parameters read from file: " << output_file_name << endl;
|
||||
|
||||
if (Filename == "cout" || Filename == "COUT") {
|
||||
scratch = " Log output goes to screen console";
|
|
@ -54,7 +54,8 @@ INCLUDES
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGfdmSocket.h"
|
||||
#include <input_output/FGfdmSocket.h>
|
||||
#include <input_output/FGXMLElement.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -133,13 +134,12 @@ public:
|
|||
void DelimitedOutput(string);
|
||||
void SocketOutput(void);
|
||||
void SocketStatusOutput(string);
|
||||
void SetFilename(string fn) {Filename = fn;}
|
||||
void SetType(string);
|
||||
void SetSubsystems(int tt) {SubSystems = tt;}
|
||||
inline void Enable(void) { enabled = true; }
|
||||
inline void Disable(void) { enabled = false; }
|
||||
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
|
||||
enum eSubSystems {
|
||||
|
@ -161,7 +161,7 @@ public:
|
|||
private:
|
||||
bool sFirstPass, dFirstPass, enabled;
|
||||
int SubSystems;
|
||||
string Filename, outputInFileName, delimeter;
|
||||
string output_file_name, delimeter, Filename;
|
||||
enum {otNone, otCSV, otTab, otSocket, otTerminal, otUnknown} Type;
|
||||
ofstream datafile;
|
||||
FGfdmSocket* socket;
|
|
@ -53,10 +53,6 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
# ifdef SG_HAVE_STD_INCLUDES
|
||||
|
@ -81,12 +77,12 @@ INCLUDES
|
|||
#endif
|
||||
|
||||
#include "FGPropagate.h"
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include <FGState.h>
|
||||
#include <FGFDMExec.h>
|
||||
#include "FGAircraft.h"
|
||||
#include "FGMassBalance.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -157,7 +153,7 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
|
|||
// Compute some derived values.
|
||||
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();
|
||||
|
||||
// Recompute the RunwayRadius level.
|
||||
|
@ -183,6 +179,7 @@ state values for (now + dt).
|
|||
bool FGPropagate::Run(void)
|
||||
{
|
||||
if (FGModel::Run()) return true; // Fast return if we have nothing to do ...
|
||||
if (FDMExec->Holding()) return false;
|
||||
|
||||
RecomputeRunwayRadius();
|
||||
|
||||
|
@ -224,9 +221,11 @@ bool FGPropagate::Run(void)
|
|||
FGColumnVector3 ace = 2.0*omega*ecVel;
|
||||
vUVWdot -= Tl2b*(Tec2l*ace);
|
||||
|
||||
// Centrifugal acceleration.
|
||||
FGColumnVector3 aeec = omega*(omega*VState.vLocation);
|
||||
vUVWdot -= Tl2b*(Tec2l*aeec);
|
||||
if (!GroundReactions->GetWOW()) {
|
||||
// Centrifugal acceleration.
|
||||
FGColumnVector3 aeec = omega*(omega*VState.vLocation);
|
||||
vUVWdot -= Tl2b*(Tec2l*aeec);
|
||||
}
|
||||
|
||||
// Gravitation accel
|
||||
vUVWdot += Tl2b*gAccel;
|
||||
|
@ -257,8 +256,6 @@ bool FGPropagate::Run(void)
|
|||
void FGPropagate::RecomputeRunwayRadius(void)
|
||||
{
|
||||
// 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;
|
||||
FGColumnVector3 dv;
|
||||
FGGroundCallback* gcb = FDMExec->GetGroundCallback();
|
|
@ -38,11 +38,11 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGLocation.h"
|
||||
#include "FGQuaternion.h"
|
||||
#include <models/FGModel.h>
|
||||
#include <math/FGColumnVector3.h>
|
||||
#include <initialization/FGInitialCondition.h>
|
||||
#include <math/FGLocation.h>
|
||||
#include <math/FGQuaternion.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -142,7 +142,6 @@ public:
|
|||
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
|
||||
void SetDistanceAGL(double tt);
|
||||
void SetInitialState(const FGInitialCondition *);
|
||||
|
||||
void RecomputeRunwayRadius(void);
|
||||
|
||||
void bind(void);
|
|
@ -44,16 +44,15 @@ HISTORY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGPropulsion.h"
|
||||
#include "FGRocket.h"
|
||||
#include "FGTurbine.h"
|
||||
#include "FGPiston.h"
|
||||
#include "FGElectric.h"
|
||||
#include "FGPropertyManager.h"
|
||||
#include <models/propulsion/FGRocket.h>
|
||||
#include <models/propulsion/FGTurbine.h>
|
||||
#include <models/propulsion/FGPiston.h>
|
||||
#include <models/propulsion/FGElectric.h>
|
||||
#include <models/propulsion/FGTurboProp.h>
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include <input_output/FGXMLParse.h>
|
||||
#include <math/FGColumnVector3.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -79,8 +78,13 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
|
|||
tankJ.InitMatrix();
|
||||
refuel = false;
|
||||
fuel_freeze = false;
|
||||
|
||||
bind();
|
||||
TotalFuelQuantity = 0.0;
|
||||
IsBound =
|
||||
HavePistonEngine =
|
||||
HaveTurbineEngine =
|
||||
HaveRocketEngine =
|
||||
HaveTurboPropEngine =
|
||||
HaveElectricEngine = false;
|
||||
|
||||
Debug(0);
|
||||
}
|
||||
|
@ -102,6 +106,7 @@ bool FGPropulsion::Run(void)
|
|||
unsigned int i;
|
||||
|
||||
if (FGModel::Run()) return true;
|
||||
if (FDMExec->Holding()) return false;
|
||||
|
||||
double dt = State->Getdt();
|
||||
|
||||
|
@ -114,12 +119,16 @@ bool FGPropulsion::Run(void)
|
|||
vMoments += Engines[i]->GetMoments(); // sum body frame moments
|
||||
}
|
||||
|
||||
TotalFuelQuantity = 0.0;
|
||||
for (i=0; i<numTanks; i++) {
|
||||
Tanks[i]->Calculate( dt * rate );
|
||||
if (Tanks[i]->GetType() == FGTank::ttFUEL) {
|
||||
TotalFuelQuantity += Tanks[i]->GetContents();
|
||||
}
|
||||
}
|
||||
|
||||
if (refuel) DoRefuel( dt * rate );
|
||||
|
||||
|
||||
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 engineFileName, engType;
|
||||
string parameter;
|
||||
string enginePath = FDMExec->GetEnginePath();
|
||||
string aircraftPath = FDMExec->GetAircraftPath();
|
||||
double xLoc, yLoc, zLoc, Pitch, Yaw;
|
||||
string type, engine_filename;
|
||||
int Feed;
|
||||
bool ThrottleAdded = false;
|
||||
FGConfigFile* Cfg_ptr = 0;
|
||||
Element* document;
|
||||
FGXMLParse engine_file_parser;
|
||||
ifstream* engine_file;
|
||||
|
||||
# ifndef macintosh
|
||||
fullpath = enginePath + "/";
|
||||
localpath = aircraftPath + "/Engines/";
|
||||
# else
|
||||
fullpath = enginePath + ";";
|
||||
localpath = aircraftPath + ";Engines;";
|
||||
# endif
|
||||
Debug(2);
|
||||
|
||||
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 (token == "AC_ENGINE") { // ============ READING ENGINES
|
||||
|
||||
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++;
|
||||
if (engine_filename.empty()) {
|
||||
cerr << "Engine definition did not supply an engine file." << endl;
|
||||
return false;
|
||||
}
|
||||
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();
|
||||
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)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -427,6 +436,9 @@ void FGPropulsion::SetMagnetos(int setting)
|
|||
{
|
||||
if (ActiveEngine < 0) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
|
@ -505,15 +517,17 @@ double FGPropulsion::Transfer(int source, int target, double amount)
|
|||
|
||||
void FGPropulsion::DoRefuel(double time_slice)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
double fillrate = 100 * time_slice; // 100 lbs/sec = 6000 lbs/min
|
||||
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 (TanksNotFull) {
|
||||
for (unsigned int i=0; i<numTanks; i++) {
|
||||
for (i=0; i<numTanks; i++) {
|
||||
if (Tanks[i]->GetPctFull() < 99.99)
|
||||
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;
|
||||
for (unsigned int i=0; i<numEngines; i++) {
|
||||
Engines[i]->SetFuelFreeze(f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGPropulsion::bind(void)
|
||||
|
@ -537,44 +551,37 @@ void FGPropulsion::bind(void)
|
|||
typedef double (FGPropulsion::*PMF)(int) const;
|
||||
typedef int (FGPropulsion::*iPMF)(void) const;
|
||||
|
||||
PropertyManager->Tie("propulsion/magneto_cmd", this,
|
||||
(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);
|
||||
IsBound = true;
|
||||
|
||||
PropertyManager->Tie("forces/fbx-prop-lbs", this,1,
|
||||
(PMF)&FGPropulsion::GetForces);
|
||||
PropertyManager->Tie("forces/fby-prop-lbs", this,2,
|
||||
(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);
|
||||
if (HaveTurbineEngine) {
|
||||
PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, true);
|
||||
PropertyManager->Tie("propulsion/cutoff_cmd", this, (iPMF)0, &FGPropulsion::SetCutoff, true);
|
||||
}
|
||||
|
||||
PropertyManager->Tie("propulsion/active_engine", this,
|
||||
(iPMF)&FGPropulsion::GetActiveEngine, &FGPropulsion::SetActiveEngine, true);
|
||||
if (HavePistonEngine) {
|
||||
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)
|
||||
{
|
||||
PropertyManager->Untie("propulsion/magneto_cmd");
|
||||
PropertyManager->Untie("propulsion/starter_cmd");
|
||||
PropertyManager->Untie("propulsion/cutoff_cmd");
|
||||
if (HaveTurbineEngine) {
|
||||
PropertyManager->Untie("propulsion/starter_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("forces/fbx-prop-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");
|
||||
PropertyManager->Untie("propulsion/total-fuel-lbs");
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -601,8 +608,8 @@ void FGPropulsion::Debug(int from)
|
|||
if (debug_lvl <= 0) return;
|
||||
|
||||
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
|
|
@ -43,19 +43,23 @@ INCLUDES
|
|||
# ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <vector>
|
||||
# include <iterator>
|
||||
# include <fstream>
|
||||
# else
|
||||
# include <vector.h>
|
||||
# include <iterator.h>
|
||||
# include <fstream.h>
|
||||
# endif
|
||||
#else
|
||||
# include <vector>
|
||||
# include <iterator>
|
||||
# include <fstream>
|
||||
#endif
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGEngine.h"
|
||||
#include "FGTank.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include <models/propulsion/FGEngine.h>
|
||||
#include <models/propulsion/FGTank.h>
|
||||
#include <math/FGMatrix33.h>
|
||||
#include <input_output/FGXMLElement.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -110,10 +114,9 @@ public:
|
|||
|
||||
/** Loads the propulsion system (engine[s] and tank[s]).
|
||||
Characteristics of the propulsion system are read in from the config file.
|
||||
@param AC_cfg pointer to the config file instance that describes the
|
||||
aircraft being modeled.
|
||||
@param el pointer to an XML element that contains the engine information.
|
||||
@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.
|
||||
inline unsigned int GetNumEngines(void) const {return Engines.size();}
|
||||
|
@ -159,26 +162,24 @@ public:
|
|||
inline double GetMoments(int n) const {return vMoments(n);}
|
||||
|
||||
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);
|
||||
void DoRefuel(double time_slice);
|
||||
|
||||
FGColumnVector3& GetTanksMoment(void);
|
||||
double GetTanksWeight(void);
|
||||
|
||||
inline int GetActiveEngine(void) const
|
||||
{
|
||||
return ActiveEngine;
|
||||
}
|
||||
|
||||
inline int GetActiveEngine(void);
|
||||
ifstream* FindEngineFile(string filename);
|
||||
string FindEngineFullPathname(string engine_filename);
|
||||
inline int GetActiveEngine(void) const {return ActiveEngine;}
|
||||
inline bool GetFuelFreeze(void) {return fuel_freeze;}
|
||||
double GetTotalFuelQuantity(void) const {return TotalFuelQuantity;}
|
||||
|
||||
void SetMagnetos(int setting);
|
||||
void SetStarter(int setting);
|
||||
void SetCutoff(int setting=0);
|
||||
void SetActiveEngine(int engine);
|
||||
void SetFuelFreeze(bool f);
|
||||
void SetFuelFreeze(bool f);
|
||||
FGMatrix33& CalculateTankInertias(void);
|
||||
|
||||
void bind();
|
||||
|
@ -202,6 +203,13 @@ private:
|
|||
FGMatrix33 tankJ;
|
||||
bool refuel;
|
||||
bool fuel_freeze;
|
||||
double TotalFuelQuantity;
|
||||
bool IsBound;
|
||||
bool HavePistonEngine;
|
||||
bool HaveTurbineEngine;
|
||||
bool HaveTurboPropEngine;
|
||||
bool HaveRocketEngine;
|
||||
bool HaveElectricEngine;
|
||||
|
||||
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
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGCondition.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -52,21 +48,13 @@ CLASS IMPLEMENTATION
|
|||
string FGCondition::indent = " ";
|
||||
|
||||
|
||||
FGCondition::FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManager) :
|
||||
PropertyManager(PropertyManager)
|
||||
FGCondition::FGCondition(Element* element, FGPropertyManager* PropertyManager) :
|
||||
PropertyManager(PropertyManager), isGroup(true)
|
||||
{
|
||||
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;
|
||||
string property1, property2, logic;
|
||||
Element* condition_element;
|
||||
|
||||
InitializeConditionals();
|
||||
|
||||
TestParam1 = TestParam2 = 0L;
|
||||
TestValue = 0.0;
|
||||
|
@ -74,31 +62,19 @@ FGCondition::FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManage
|
|||
Logic = elUndef;
|
||||
conditions.clear();
|
||||
|
||||
if (AC_cfg->GetValue("CONDITION_GROUP").empty()) { // define a condition
|
||||
|
||||
*AC_cfg >> property1 >> conditional >> property2;
|
||||
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);
|
||||
}
|
||||
|
||||
isGroup = false;
|
||||
|
||||
} 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();
|
||||
logic = element->GetAttributeValue("logic");
|
||||
if (logic == "OR") Logic = eOR;
|
||||
else if (logic == "AND") Logic = eAND;
|
||||
else { // error
|
||||
cerr << "Unrecognized LOGIC token " << logic << " in switch component: " << logic << endl;
|
||||
}
|
||||
condition_element = element->GetElement();
|
||||
while (condition_element) {
|
||||
conditions.push_back(FGCondition(condition_element, PropertyManager));
|
||||
condition_element = element->GetNextElement();
|
||||
}
|
||||
for (int i=0; i<element->GetNumDataLines(); i++) {
|
||||
conditions.push_back(FGCondition(element->GetDataLine(i), PropertyManager));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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:
|
||||
// unset: In this case (the default) JSBSim would only print
|
|
@ -37,9 +37,10 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "../FGConfigFile.h"
|
||||
#include <map>
|
||||
#include "../FGPropertyManager.h"
|
||||
#include <FGJSBBase.h>
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -59,7 +60,7 @@ CLASS DOCUMENTATION
|
|||
|
||||
/** Encapsulates a condition, which is used in parts of JSBSim including switches
|
||||
*/
|
||||
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -67,16 +68,14 @@ CLASS DECLARATION
|
|||
class FGCondition : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManager);
|
||||
FGCondition(Element* element, FGPropertyManager* PropertyManager);
|
||||
FGCondition(string test, FGPropertyManager* PropertyManager);
|
||||
~FGCondition(void);
|
||||
|
||||
bool Evaluate(void);
|
||||
void PrintCondition(void);
|
||||
void convert(void);
|
||||
|
||||
private:
|
||||
FGConfigFile* AC_cfg;
|
||||
|
||||
enum eComparison {ecUndef=0, eEQ, eNE, eGT, eGE, eLT, eLE};
|
||||
enum eLogic {elUndef=0, eAND, eOR};
|
||||
map <string, eComparison> mComparison;
|
||||
|
@ -87,11 +86,11 @@ private:
|
|||
eComparison Comparison;
|
||||
bool isGroup;
|
||||
string conditional;
|
||||
string property1, property2;
|
||||
|
||||
static string indent;
|
||||
|
||||
vector <FGCondition> conditions;
|
||||
void InitializeConditionals(void);
|
||||
|
||||
void Debug(int from);
|
||||
};
|
|
@ -3,7 +3,7 @@
|
|||
Module: FGDeadBand.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
|
||||
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGDeadBand.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -54,40 +50,19 @@ CLASS IMPLEMENTATION
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGDeadBand::FGDeadBand(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
||||
AC_cfg(AC_cfg)
|
||||
FGDeadBand::FGDeadBand(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||
{
|
||||
Type = AC_cfg->GetValue("TYPE");
|
||||
Name = AC_cfg->GetValue("NAME");
|
||||
AC_cfg->GetNextConfigLine();
|
||||
string token;
|
||||
|
||||
clipmax = clipmin = 0.0;
|
||||
clip = false;
|
||||
gain = 1.0;
|
||||
width = 0.0;
|
||||
|
||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
||||
*AC_cfg >> token;
|
||||
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("width")) {
|
||||
width = element->FindElementValueAsNumber("width");
|
||||
}
|
||||
|
||||
if (element->FindElement("gain")) {
|
||||
gain = element->FindElementValueAsNumber("gain");
|
||||
}
|
||||
|
||||
FGFCSComponent::bind();
|
||||
Debug(0);
|
||||
}
|
||||
|
@ -103,9 +78,7 @@ FGDeadBand::~FGDeadBand()
|
|||
|
||||
bool FGDeadBand::Run(void )
|
||||
{
|
||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
||||
|
||||
Input = InputNodes[0]->getDoubleValue();
|
||||
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||
|
||||
if (Input < -width/2.0) {
|
||||
Output = (Input + width/2.0)*gain;
|
||||
|
@ -115,43 +88,13 @@ bool FGDeadBand::Run(void )
|
|||
Output = 0.0;
|
||||
}
|
||||
|
||||
if (clip) {
|
||||
if (Output > clipmax) Output = clipmax;
|
||||
else if (Output < clipmin) Output = clipmin;
|
||||
}
|
||||
Clip();
|
||||
|
||||
if (IsOutput) SetOutput();
|
||||
|
||||
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:
|
||||
// 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 << " DEADBAND WIDTH: " << width << endl;
|
||||
cout << " GAIN: " << gain << endl;
|
||||
if (clip) cout << " CLIPTO: " << clipmin
|
||||
if (clip) cout << " CLIPTO: " << clipmin
|
||||
<< ", " << clipmax << endl;
|
||||
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Header: FGDeadBand.h
|
||||
Author:
|
||||
Date started:
|
||||
Author: Jon Berndt
|
||||
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
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include "../FGConfigFile.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -81,22 +81,18 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGDeadBand : public FGFCSComponent
|
||||
class FGDeadBand : public FGFCSComponent
|
||||
{
|
||||
public:
|
||||
FGDeadBand(FGFCS* fcs, FGConfigFile* AC_cfg);
|
||||
FGDeadBand(FGFCS* fcs, Element* element);
|
||||
~FGDeadBand();
|
||||
|
||||
bool Run(void);
|
||||
void convert(void);
|
||||
|
||||
private:
|
||||
FGConfigFile* AC_cfg;
|
||||
double width;
|
||||
double clipmax, clipmin;
|
||||
bool clip;
|
||||
double gain;
|
||||
|
||||
|
||||
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 <vector>
|
||||
#include "../FGJSBBase.h"
|
||||
#include "../FGPropertyManager.h"
|
||||
#include <FGJSBBase.h>
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include <input_output/FGXMLElement.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -78,11 +79,10 @@ CLASS DOCUMENTATION
|
|||
- FGDeadBand
|
||||
- FGSummer
|
||||
- FGGradient
|
||||
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id$
|
||||
@see Documentation for the FGFCS class, and for the configuration file class
|
||||
FGConfigFile.
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -93,7 +93,7 @@ class FGFCSComponent : public FGJSBBase
|
|||
{
|
||||
public:
|
||||
/// Constructor
|
||||
FGFCSComponent(FGFCS*);
|
||||
FGFCSComponent(FGFCS* fcs, Element* el);
|
||||
/// Destructor
|
||||
virtual ~FGFCSComponent();
|
||||
|
||||
|
@ -104,22 +104,28 @@ public:
|
|||
inline string GetName(void) const {return Name;}
|
||||
inline string GetType(void) const { return Type; }
|
||||
virtual double GetOutputPct(void) const { return 0; }
|
||||
virtual void convert(void) {};
|
||||
virtual void bind();
|
||||
FGPropertyManager* resolveSymbol(string token);
|
||||
|
||||
|
||||
protected:
|
||||
FGFCS* fcs;
|
||||
FGPropertyManager* PropertyManager;
|
||||
FGPropertyManager* treenode;
|
||||
string Type;
|
||||
string Name;
|
||||
FGPropertyManager* OutputNode;
|
||||
FGPropertyManager* ClipMinPropertyNode;
|
||||
FGPropertyManager* ClipMaxPropertyNode;
|
||||
vector <FGPropertyManager*> InputNodes;
|
||||
vector <float> InputSigns;
|
||||
string Type;
|
||||
string Name;
|
||||
double Input;
|
||||
FGPropertyManager* OutputNode;
|
||||
double Output;
|
||||
double clipmax, clipmin;
|
||||
bool IsOutput;
|
||||
bool clip;
|
||||
|
||||
void Clip(void);
|
||||
virtual void bind();
|
||||
FGPropertyManager* resolveSymbol(string token);
|
||||
|
||||
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
|
||||
Date started: 11/1999
|
||||
|
||||
------------- Copyright (C) 2000 -------------
|
||||
Date started: 6/2005
|
||||
|
||||
------------- Copyright (C) 2005 -------------
|
||||
|
||||
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
|
||||
|
@ -37,87 +37,54 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include "FGFCSFunction.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FCSCOMPONENT;
|
||||
static const char *IdHdr = ID_FCSFUNCTION;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGFCSComponent::FGFCSComponent(FGFCS* _fcs) : fcs(_fcs)
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGFCSFunction::FGFCSFunction(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||
{
|
||||
Type = "";
|
||||
Input = 0.0;
|
||||
Output = 0.0;
|
||||
OutputNode = 0;
|
||||
IsOutput = false;
|
||||
PropertyManager=fcs->GetPropertyManager();
|
||||
treenode = 0;
|
||||
Element *function_element = element->FindElement("function");
|
||||
|
||||
function = new FGFunction(PropertyManager, function_element);
|
||||
|
||||
FGFCSComponent::bind();
|
||||
Debug(0);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGFCSComponent::~FGFCSComponent()
|
||||
FGFCSFunction::~FGFCSFunction()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
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:
|
||||
// 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
|
||||
// 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 & 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 (from == 0) cout << "Instantiated: FGFCSComponent" << endl;
|
||||
if (from == 1) cout << "Destroyed: FGFCSComponent" << endl;
|
||||
if (from == 0) cout << "Instantiated: FGFCSFunction" << endl;
|
||||
if (from == 1) cout << "Destroyed: FGFCSFunction" << endl;
|
||||
}
|
||||
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
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGFilter.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -52,16 +48,10 @@ static const char *IdHdr = ID_FILTER;
|
|||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
||||
AC_cfg(AC_cfg)
|
||||
FGFilter::FGFilter(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||
{
|
||||
string token;
|
||||
double denom;
|
||||
string sOutputIdx;
|
||||
|
||||
Type = AC_cfg->GetValue("TYPE");
|
||||
Name = AC_cfg->GetValue("NAME");
|
||||
AC_cfg->GetNextConfigLine();
|
||||
dt = fcs->GetState()->Getdt();
|
||||
Trigger = 0;
|
||||
|
||||
|
@ -74,37 +64,14 @@ FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
|||
else if (Type == "INTEGRATOR") FilterType = eIntegrator ;
|
||||
else FilterType = eUnknown ;
|
||||
|
||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
||||
*AC_cfg >> token;
|
||||
if (token == "C1") *AC_cfg >> C1;
|
||||
else if (token == "C2") *AC_cfg >> C2;
|
||||
else if (token == "C3") *AC_cfg >> C3;
|
||||
else if (token == "C4") *AC_cfg >> C4;
|
||||
else if (token == "C5") *AC_cfg >> C5;
|
||||
else if (token == "C6") *AC_cfg >> C6;
|
||||
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;
|
||||
if (element->FindElement("c1")) C1 = element->FindElementValueAsNumber("c1");
|
||||
if (element->FindElement("c2")) C2 = element->FindElementValueAsNumber("c2");
|
||||
if (element->FindElement("c3")) C3 = element->FindElementValueAsNumber("c3");
|
||||
if (element->FindElement("c4")) C4 = element->FindElementValueAsNumber("c4");
|
||||
if (element->FindElement("c5")) C5 = element->FindElementValueAsNumber("c5");
|
||||
if (element->FindElement("c6")) C6 = element->FindElementValueAsNumber("c6");
|
||||
if (element->FindElement("trigger")) {
|
||||
Trigger = resolveSymbol(element->FindElementValue("trigger"));
|
||||
}
|
||||
|
||||
Initialize = true;
|
||||
|
@ -157,25 +124,16 @@ FGFilter::~FGFilter()
|
|||
|
||||
bool FGFilter::Run(void)
|
||||
{
|
||||
int test = 0;
|
||||
|
||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
||||
double test = 0.0;
|
||||
|
||||
if (Initialize) {
|
||||
|
||||
PreviousOutput1 = PreviousInput1 = Output = Input;
|
||||
Initialize = false;
|
||||
|
||||
} else if (Trigger != 0) {
|
||||
test = Trigger->getIntValue();
|
||||
if (test < 0) {
|
||||
Input = PreviousInput1 = PreviousInput2 = 0.0;
|
||||
} else {
|
||||
Output = PreviousOutput1 = PreviousOutput2 = 0.0;
|
||||
}
|
||||
|
||||
} else {
|
||||
Input = InputNodes[0]->getDoubleValue();
|
||||
|
||||
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||
switch (FilterType) {
|
||||
case eLag:
|
||||
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
|
||||
|
@ -191,6 +149,12 @@ bool FGFilter::Run(void)
|
|||
Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
|
||||
break;
|
||||
case eIntegrator:
|
||||
if (Trigger != 0) {
|
||||
test = Trigger->getDoubleValue();
|
||||
if (fabs(test) > 0.000001) {
|
||||
Input = PreviousInput1 = PreviousInput2 = 0.0;
|
||||
}
|
||||
}
|
||||
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1;
|
||||
break;
|
||||
case eUnknown:
|
||||
|
@ -204,35 +168,12 @@ bool FGFilter::Run(void)
|
|||
PreviousInput2 = PreviousInput1;
|
||||
PreviousInput1 = Input;
|
||||
|
||||
Clip();
|
||||
if (IsOutput) SetOutput();
|
||||
|
||||
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:
|
||||
// unset: In this case (the default) JSBSim would only print
|
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include "../FGConfigFile.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
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:
|
||||
|
||||
<pre>
|
||||
\<COMPONENT NAME="name" TYPE="type">
|
||||
INPUT \<property>
|
||||
C1 \<value>
|
||||
[C2 \<value>]
|
||||
[C3 \<value>]
|
||||
[C4 \<value>]
|
||||
[C5 \<value>]
|
||||
[C6 \<value>]
|
||||
[OUTPUT \<property>]
|
||||
\</COMPONENT>
|
||||
\<component name="name" type="type">
|
||||
\<input> property \</input>
|
||||
\<c1> value \<c/1>
|
||||
[\<c2> value \<c/2>]
|
||||
[\<c3> value \<c/3>]
|
||||
[\<c4> value \<c/4>]
|
||||
[\<c5> value \<c/5>]
|
||||
[\<c6> value \<c/6>]
|
||||
[\<output> property \<output>]
|
||||
\</component>
|
||||
</pre>
|
||||
|
||||
For a lag filter of the form,
|
||||
<pre>
|
||||
C1
|
||||
------
|
||||
s + C1
|
||||
s + C1
|
||||
</pre>
|
||||
the corresponding filter definition is:
|
||||
<pre>
|
||||
\<COMPONENT NAME="name" TYPE="LAG_FILTER">
|
||||
INPUT \<property>
|
||||
C1 \<value>
|
||||
[OUTPUT \<property>]
|
||||
\</COMPONENT>
|
||||
\<component name="name" type="LAG_FILTER">
|
||||
\<input> property \</input>
|
||||
\<c1> value \<c/1>
|
||||
[\<output> property \<output>]
|
||||
\</component>
|
||||
</pre>
|
||||
As an example, for the specific filter:
|
||||
<pre>
|
||||
600
|
||||
------
|
||||
s + 600
|
||||
s + 600
|
||||
</pre>
|
||||
the corresponding filter definition could be:
|
||||
<pre>
|
||||
\<COMPONENT NAME="LAG_1" TYPE="LAG_FILTER">
|
||||
INPUT aileron_cmd
|
||||
C1 600
|
||||
\</COMPONENT>
|
||||
\<component name="Heading Roll Error Lag" type="LAG_FILTER">
|
||||
\<input> fcs/heading-command \</input>
|
||||
\<c1> 600 \</c1>
|
||||
\</component>
|
||||
</pre>
|
||||
For a lead-lag filter of the form:
|
||||
<pre>
|
||||
C1*s + C2
|
||||
---------
|
||||
C3*s + C4
|
||||
C3*s + C4
|
||||
</pre>
|
||||
The corresponding filter definition is:
|
||||
<pre>
|
||||
\<COMPONENT NAME="name" TYPE="LEAD_LAG_FILTER">
|
||||
INPUT \<property>
|
||||
C1 \<value>
|
||||
C2 \<value>
|
||||
C3 \<value>
|
||||
C4 \<value>
|
||||
[OUTPUT \<property>]
|
||||
\</COMPONENT>
|
||||
\<component name="name" type="LEAD_LAG_FILTER">
|
||||
\<input> property \</input>
|
||||
\<c1> value \<c/1>
|
||||
\<c2> value \<c/2>
|
||||
\<c3> value \<c/3>
|
||||
\<c4> value \<c/4>
|
||||
[\<output> property \<output>]
|
||||
\</component>
|
||||
</pre>
|
||||
For a washout filter of the form:
|
||||
<pre>
|
||||
s
|
||||
------
|
||||
s + C1
|
||||
s + C1
|
||||
</pre>
|
||||
The corresponding filter definition is:
|
||||
<pre>
|
||||
\<COMPONENT NAME="name" TYPE="WASHOUT_FILTER">
|
||||
INPUT \<property>
|
||||
C1 \<value>
|
||||
[OUTPUT \<property>]
|
||||
\</COMPONENT>
|
||||
\<component name="name" type="WASHOUT_FILTER">
|
||||
\<input> property \</input>
|
||||
\<c1> value \</c1>
|
||||
[\<output> property \<output>]
|
||||
\</component>
|
||||
</pre>
|
||||
For a second order filter of the form:
|
||||
<pre>
|
||||
|
@ -140,16 +140,16 @@ C4*s^2 + C5*s + C6
|
|||
</pre>
|
||||
The corresponding filter definition is:
|
||||
<pre>
|
||||
\<COMPONENT NAME="name" TYPE="SECOND_ORDER_FILTER">
|
||||
INPUT \<property>
|
||||
C1 \<value>
|
||||
C2 \<value>
|
||||
C3 \<value>
|
||||
C4 \<value>
|
||||
C5 \<value>
|
||||
C6 \<value>
|
||||
[OUTPUT \<property>]
|
||||
\</COMPONENT>
|
||||
\<component name="name" type="SECOND_ORDER_FILTER">
|
||||
\<input> property \</input>
|
||||
\<c1> value \<c/1>
|
||||
\<c2> value \<c/2>
|
||||
\<c3> value \<c/3>
|
||||
\<c4> value \<c/4>
|
||||
\<c5> value \<c/5>
|
||||
\<c6> value \<c/6>
|
||||
[\<output> property \<output>]
|
||||
\</component>
|
||||
</pre>
|
||||
For an integrator of the form:
|
||||
<pre>
|
||||
|
@ -159,35 +159,35 @@ For an integrator of the form:
|
|||
</pre>
|
||||
The corresponding filter definition is:
|
||||
<pre>
|
||||
\<COMPONENT NAME="name" TYPE="INTEGRATOR">
|
||||
INPUT \<property>
|
||||
C1 \<value>
|
||||
[OUTPUT \<property>]
|
||||
[TRIGGER \<property>]
|
||||
\</COMPONENT>
|
||||
\<component name="name" type="INTEGRATOR">
|
||||
\<input> property \</input>
|
||||
\<c1> value \<c/1>
|
||||
[\<trigger> property \</trigger>]
|
||||
[\<output> property \<output>]
|
||||
\</component>
|
||||
</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:
|
||||
- -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
|
||||
- +1 (or simply greater than zero), all previous outputs (only) will be set to 0.0
|
||||
- 0: no action is taken - the output is calculated normally
|
||||
- not 0: (or simply greater than zero), all current and previous inputs will
|
||||
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
|
||||
output, such as the elevator, or speedbrake, etc.
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGFilter : public FGFCSComponent
|
||||
class FGFilter : public FGFCSComponent
|
||||
{
|
||||
public:
|
||||
FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg);
|
||||
FGFilter(FGFCS* fcs, Element* element);
|
||||
~FGFilter();
|
||||
|
||||
bool Run (void);
|
||||
|
@ -195,7 +195,6 @@ public:
|
|||
/** When true, causes previous values to be set to current values. This
|
||||
is particularly useful for first pass. */
|
||||
bool Initialize;
|
||||
void convert(void);
|
||||
|
||||
enum {eLag, eLeadLag, eOrder2, eWashout, eIntegrator, eUnknown} FilterType;
|
||||
|
||||
|
@ -216,7 +215,6 @@ private:
|
|||
double PreviousInput2;
|
||||
double PreviousOutput1;
|
||||
double PreviousOutput2;
|
||||
FGConfigFile* AC_cfg;
|
||||
FGPropertyManager* Trigger;
|
||||
void Debug(int from);
|
||||
};
|
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGGain.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -52,81 +48,74 @@ static const char *IdHdr = ID_GAIN;
|
|||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
|
||||
FGGain::FGGain(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
||||
AC_cfg(AC_cfg)
|
||||
FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||
{
|
||||
string token;
|
||||
string strScheduledBy;
|
||||
string sOutputIdx;
|
||||
|
||||
State = fcs->GetState();
|
||||
Element *scale_element, *zero_centered;
|
||||
string strScheduledBy, gain_string, sZeroCentered;
|
||||
|
||||
GainPropertyNode = 0;
|
||||
Gain = 1.000;
|
||||
Rows = 0;
|
||||
Min = Max = 0.0;
|
||||
OutputPct = 0;
|
||||
invert = false;
|
||||
ScheduledBy = 0;
|
||||
clip = false;
|
||||
clipmin = clipmax = 0.0;
|
||||
Table = 0;
|
||||
InMin = -1.0;
|
||||
InMax = 1.0;
|
||||
OutMin = OutMax = 0.0;
|
||||
|
||||
Type = AC_cfg->GetValue("TYPE");
|
||||
Name = AC_cfg->GetValue("NAME");
|
||||
AC_cfg->GetNextConfigLine();
|
||||
if (Type == "PURE_GAIN") {
|
||||
if ( !element->FindElement("gain") ) {
|
||||
cout << highint << " No GAIN specified (default: 1.0)" << normint << endl;
|
||||
}
|
||||
}
|
||||
|
||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
||||
*AC_cfg >> token;
|
||||
if (token == "INPUT") {
|
||||
*AC_cfg >> token;
|
||||
|
||||
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 );
|
||||
if ( element->FindElement("gain") ) {
|
||||
gain_string = element->FindElementValue("gain");
|
||||
if (gain_string.find_first_not_of("+-.0123456789") != string::npos) { // property
|
||||
GainPropertyNode = PropertyManager->GetNode(gain_string);
|
||||
} else {
|
||||
AC_cfg->ResetLineIndexToZero();
|
||||
*Table << *AC_cfg;
|
||||
Gain = element->FindElementValueAsNumber("gain");
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
if (Type == "AEROSURFACE_SCALE")
|
||||
treenode->Tie( "output-norm", this, &FGGain::GetOutputPct );
|
||||
|
||||
Debug(0);
|
||||
}
|
||||
|
@ -143,12 +132,10 @@ FGGain::~FGGain()
|
|||
bool FGGain::Run(void )
|
||||
{
|
||||
double SchedGain = 1.0;
|
||||
double LookupVal = 0;
|
||||
|
||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
||||
Input = InputNodes[0]->getDoubleValue();
|
||||
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||
|
||||
if (invert) Input = -Input;
|
||||
if (GainPropertyNode != 0) Gain = GainPropertyNode->getDoubleValue();
|
||||
|
||||
if (Type == "PURE_GAIN") { // PURE_GAIN
|
||||
|
||||
|
@ -156,72 +143,32 @@ bool FGGain::Run(void )
|
|||
|
||||
} else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
|
||||
|
||||
LookupVal = ScheduledBy->getDoubleValue();
|
||||
SchedGain = Table->GetValue(LookupVal);
|
||||
SchedGain = Table->GetValue();
|
||||
Output = Gain * SchedGain * Input;
|
||||
|
||||
} else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
|
||||
|
||||
OutputPct = Input;
|
||||
if (Input >= 0.0) Output = Input * Max;
|
||||
else Output = Input * -Min;
|
||||
if (ZeroCentered) {
|
||||
if (Input == 0.0) {
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
if (clip) {
|
||||
if (Output > clipmax) Output = clipmax;
|
||||
else if (Output < clipmin) Output = clipmin;
|
||||
}
|
||||
|
||||
Clip();
|
||||
if (IsOutput) SetOutput();
|
||||
|
||||
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:
|
||||
// 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 (from == 0) { // Constructor
|
||||
if (invert)
|
||||
if (InputSigns[0] < 0)
|
||||
cout << " INPUT: -" << InputNodes[0]->getName() << endl;
|
||||
else
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
|
||||
cout << " GAIN: " << Gain << endl;
|
||||
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
||||
cout << " MIN: " << Min << endl;
|
||||
cout << " MAX: " << Max << endl;
|
||||
if (ScheduledBy != 0) {
|
||||
cout << " Scheduled by parameter: " << ScheduledBy->getName() << endl;
|
||||
if (Type == "AEROSURFACE_SCALE") {
|
||||
cout << " In/Out Mapping:" << endl;
|
||||
cout << " Input MIN: " << InMin << 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();
|
||||
}
|
||||
}
|
|
@ -46,8 +46,8 @@ INCLUDES
|
|||
#endif
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include "../FGConfigFile.h"
|
||||
#include "../FGTable.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include <math/FGTable.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -71,11 +71,11 @@ CLASS DOCUMENTATION
|
|||
The gain component merely multiplies the input by a gain. The form of the
|
||||
gain component specification is:
|
||||
<pre>
|
||||
\<COMPONENT NAME="name" TYPE="PURE_GAIN">
|
||||
INPUT \<property>
|
||||
GAIN \<value>
|
||||
[OUTPUT \<property>]
|
||||
\</COMPONENT>
|
||||
\<component name="name" type="PURE_GAIN">
|
||||
\<input> property \</input>
|
||||
\<gain> value \</gain>
|
||||
[\<output> property \</output>]
|
||||
\</component>
|
||||
</pre>
|
||||
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.
|
||||
|
@ -169,24 +169,18 @@ CLASS DECLARATION
|
|||
class FGGain : public FGFCSComponent
|
||||
{
|
||||
public:
|
||||
FGGain(FGFCS* fcs, FGConfigFile* AC_cfg);
|
||||
FGGain(FGFCS* fcs, Element* element);
|
||||
~FGGain();
|
||||
|
||||
double GetOutputPct() const { return OutputPct; }
|
||||
void convert(void);
|
||||
bool Run (void);
|
||||
|
||||
private:
|
||||
FGConfigFile* AC_cfg;
|
||||
FGTable* Table;
|
||||
FGState* State;
|
||||
FGPropertyManager* GainPropertyNode;
|
||||
double Gain;
|
||||
double Min, Max;
|
||||
double clipmin, clipmax;
|
||||
double OutputPct;
|
||||
bool invert, clip;
|
||||
double InMin, InMax, OutMin, OutMax;
|
||||
int Rows;
|
||||
FGPropertyManager* ScheduledBy;
|
||||
bool ZeroCentered;
|
||||
|
||||
void Debug(int from);
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Module: FGGradient.cpp
|
||||
Author:
|
||||
Date started:
|
||||
|
||||
Author:
|
||||
Date started:
|
||||
|
||||
------------- Copyright (C) 2000 -------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FGGradient.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
@ -53,12 +49,8 @@ CLASS IMPLEMENTATION
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
|
||||
FGGradient::FGGradient(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
||||
AC_cfg(AC_cfg)
|
||||
FGGradient::FGGradient(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||
{
|
||||
Type = AC_cfg->GetValue("TYPE");
|
||||
Name = AC_cfg->GetValue("NAME");
|
||||
|
||||
FGFCSComponent::bind();
|
||||
|
||||
Debug(0);
|
||||
|
@ -75,8 +67,6 @@ FGGradient::~FGGradient()
|
|||
|
||||
bool FGGradient::Run(void )
|
||||
{
|
||||
FGFCSComponent::Run(); // call the base class for initialization of Input
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include "../FGConfigFile.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -68,13 +68,12 @@ CLASS DECLARATION
|
|||
class FGGradient : public FGFCSComponent
|
||||
{
|
||||
public:
|
||||
FGGradient(FGFCS* fcs, FGConfigFile* AC_cfg);
|
||||
FGGradient(FGFCS* fcs, Element* element);
|
||||
~FGGradient();
|
||||
|
||||
bool Run (void);
|
||||
|
||||
private:
|
||||
FGConfigFile* AC_cfg;
|
||||
void Debug(int from);
|
||||
};
|
||||
}
|
|
@ -37,10 +37,6 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
|
@ -55,57 +51,39 @@ static const char *IdHdr = ID_FLAPS;
|
|||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGKinemat::FGKinemat(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
||||
AC_cfg(AC_cfg)
|
||||
FGKinemat::FGKinemat(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||
{
|
||||
string token,sOutputIdx;
|
||||
Element *traverse_element, *setting_element;
|
||||
double tmpDetent;
|
||||
double tmpTime;
|
||||
|
||||
Detents.clear();
|
||||
TransitionTimes.clear();
|
||||
|
||||
OutputPct=0;
|
||||
Output = OutputPct = 0;
|
||||
DoScale = true;
|
||||
|
||||
Type = AC_cfg->GetValue("TYPE");
|
||||
Name = AC_cfg->GetValue("NAME");
|
||||
AC_cfg->GetNextConfigLine();
|
||||
if (element->FindElement("noscale")) DoScale = false;
|
||||
|
||||
while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
|
||||
*AC_cfg >> token;
|
||||
if (token == "INPUT") {
|
||||
token = AC_cfg->GetValue("INPUT");
|
||||
if( InputNodes.size() > 0 ) {
|
||||
cerr << "Kinemat can only accept one input" << endl;
|
||||
} else {
|
||||
*AC_cfg >> token;
|
||||
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;
|
||||
}
|
||||
traverse_element = element->FindElement("traverse");
|
||||
setting_element = traverse_element->FindElement("setting");
|
||||
while (setting_element) {
|
||||
tmpDetent = setting_element->FindElementValueAsNumber("position");
|
||||
tmpTime = setting_element->FindElementValueAsNumber("time");
|
||||
Detents.push_back(tmpDetent);
|
||||
TransitionTimes.push_back(tmpTime);
|
||||
setting_element = traverse_element->FindNextElement("setting");
|
||||
}
|
||||
NumDetents = Detents.size();
|
||||
|
||||
if (NumDetents <= 1) {
|
||||
cerr << "Kinematic component " << Name
|
||||
<< " must have more than 1 setting element" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
FGFCSComponent::bind();
|
||||
treenode->Tie("output-norm", this, &FGKinemat::GetOutputPct );
|
||||
// treenode->Tie("output-norm", this, &FGKinemat::GetOutputPct );
|
||||
|
||||
Debug(0);
|
||||
}
|
||||
|
@ -123,11 +101,11 @@ bool FGKinemat::Run(void )
|
|||
{
|
||||
double dt = fcs->GetState()->Getdt();
|
||||
|
||||
Input = InputNodes[0]->getDoubleValue();
|
||||
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||
|
||||
if (DoScale) Input *= Detents[NumDetents-1];
|
||||
|
||||
Output = OutputNode->getDoubleValue();
|
||||
if (IsOutput) Output = OutputNode->getDoubleValue();
|
||||
|
||||
if (Input < Detents[0])
|
||||
Input = Detents[0];
|
||||
|
@ -177,35 +155,12 @@ bool FGKinemat::Run(void )
|
|||
|
||||
OutputPct = (Output-Detents[0])/(Detents[NumDetents-1]-Detents[0]);
|
||||
|
||||
Clip();
|
||||
if (IsOutput) SetOutput();
|
||||
|
||||
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:
|
||||
// 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